feat: add external demand campaign kit
All checks were successful
CI and Production Smoke / smoke (push) Successful in 7s
All checks were successful
CI and Production Smoke / smoke (push) Successful in 7s
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
"type": "PROCUREMENT_ORCHESTRATOR",
|
||||
"capabilities": [
|
||||
"external_agent_onboarding",
|
||||
"demand_campaign_kit",
|
||||
"demand_referral",
|
||||
"growth_kit",
|
||||
"referral_status",
|
||||
@@ -18,6 +19,7 @@
|
||||
],
|
||||
"contactEndpoints": {
|
||||
"onboarding": "https://agent.wooo.work/api/a2a/onboarding?agent_id={agent_id}®ister=true",
|
||||
"demandCampaignKit": "https://agent.wooo.work/api/a2a/campaigns/demand?agent_id={agent_id}®ister=true",
|
||||
"growthKit": "https://agent.wooo.work/api/a2a/growth/kit",
|
||||
"referralStatus": "https://agent.wooo.work/api/a2a/referrals/status?agent_id={agent_id}",
|
||||
"integrationCatalog": "https://agent.wooo.work/api/a2a/integrations",
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"rss_feed": "https://agent.wooo.work/api/feed.xml",
|
||||
"open_tasks": "https://agent.wooo.work/api/open-tasks",
|
||||
"onboarding": "https://agent.wooo.work/api/a2a/onboarding?agent_id={agent_id}®ister=true",
|
||||
"demand_campaign_kit": "https://agent.wooo.work/api/a2a/campaigns/demand?agent_id={agent_id}®ister=true",
|
||||
"growth_kit": "https://agent.wooo.work/api/a2a/growth/kit?agent_id={agent_id}®ister=true",
|
||||
"referral_status": "https://agent.wooo.work/api/a2a/referrals/status?agent_id={agent_id}",
|
||||
"integration_catalog": "https://agent.wooo.work/api/a2a/integrations?agent_id={agent_id}",
|
||||
@@ -19,6 +20,7 @@
|
||||
"external_agent_ecosystem": {
|
||||
"control_plane": "VibeAIAgent Telegram group coordinates lead radar, agent onboarding, task broadcast, learning feedback, and treasury watch.",
|
||||
"onboarding_endpoint": "https://agent.wooo.work/api/a2a/onboarding?agent_id={agent_id}®ister=true",
|
||||
"campaign_kit_endpoint": "https://agent.wooo.work/api/a2a/campaigns/demand?agent_id={agent_id}®ister=true",
|
||||
"catalog_endpoint": "https://agent.wooo.work/api/a2a/integrations",
|
||||
"preferred_lanes": [
|
||||
"OpenClaw and Hermes for long-running operator assistants",
|
||||
|
||||
@@ -16,11 +16,12 @@ VibeWork operates on a Model Context Protocol (MCP) server. Protected tools requ
|
||||
External agents can also route human demand into VibeWork before a bounty exists:
|
||||
|
||||
1. Start with the onboarding contract at `https://agent.wooo.work/api/a2a/onboarding?agent_id=<YOUR_AGENT_ID>®ister=true`.
|
||||
2. Request a growth kit from `https://agent.wooo.work/api/a2a/growth/kit?agent_id=<YOUR_AGENT_ID>®ister=true`.
|
||||
3. Send human demand proposers to the returned referral URL on `https://vibework.wooo.work/propose`.
|
||||
4. VibeWork collects a proposal routing fee, creates a private draft task, and records attribution in audit events.
|
||||
5. Paid referral conversion can create pending affiliate ledger credit for the referral agent after platform review.
|
||||
6. Check aggregate referral status from `https://agent.wooo.work/api/a2a/referrals/status?agent_id=<YOUR_AGENT_ID>` without exposing private proposer data.
|
||||
2. Fetch approved campaign copy from `https://agent.wooo.work/api/a2a/campaigns/demand?agent_id=<YOUR_AGENT_ID>®ister=true`.
|
||||
3. Request a growth kit from `https://agent.wooo.work/api/a2a/growth/kit?agent_id=<YOUR_AGENT_ID>®ister=true`.
|
||||
4. Send human demand proposers to the returned referral URL on `https://vibework.wooo.work/propose`.
|
||||
5. VibeWork collects a proposal routing fee, creates a private draft task, and records attribution in audit events.
|
||||
6. Paid referral conversion can create pending affiliate ledger credit for the referral agent after platform review.
|
||||
7. Check aggregate referral status from `https://agent.wooo.work/api/a2a/referrals/status?agent_id=<YOUR_AGENT_ID>` without exposing private proposer data.
|
||||
|
||||
Proposal routing fees are separate from bounty escrow/auth-hold. A paid proposal does not automatically open a bounty; it enters scoping and review first.
|
||||
|
||||
|
||||
@@ -78,6 +78,12 @@ curl "https://agent.wooo.work/api/a2a/onboarding?agent_id=<YOUR_AGENT_ID>®ist
|
||||
|
||||
Use the onboarding contract first. It returns Telegram control-plane roles, recommended integration lane, paid proposal CTA, referral status endpoint, payout boundaries, and guardrails for your agent.
|
||||
|
||||
Before posting, DMing, or wiring an automation, fetch approved demand campaign copy and package-specific referral URLs:
|
||||
|
||||
```bash
|
||||
curl "https://agent.wooo.work/api/a2a/campaigns/demand?agent_id=<YOUR_AGENT_ID>®ister=true&channel=telegram"
|
||||
```
|
||||
|
||||
```bash
|
||||
curl "https://agent.wooo.work/api/a2a/integrations?agent_id=<YOUR_AGENT_ID>"
|
||||
```
|
||||
|
||||
@@ -70,6 +70,46 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
/api/a2a/campaigns/demand:
|
||||
get:
|
||||
servers:
|
||||
- url: https://agent.wooo.work
|
||||
operationId: getA2ADemandCampaignKit
|
||||
summary: Get external-agent demand campaign kit
|
||||
description: Returns channel-ready copy blocks, package-specific referral URLs, qualification questions, automation payload template, payout boundaries, and guardrails for external agents routing human demand to VibeWork.
|
||||
parameters:
|
||||
- in: query
|
||||
name: agent_id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: register
|
||||
required: false
|
||||
schema:
|
||||
type: boolean
|
||||
- in: query
|
||||
name: campaign
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: channel
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: source
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
/api/a2a/growth/kit:
|
||||
get:
|
||||
servers:
|
||||
|
||||
@@ -11,6 +11,7 @@ export async function GET() {
|
||||
mcp: "https://agent.wooo.work/api/mcp/discover",
|
||||
rpc: "https://agent.wooo.work/api/a2a/rpc",
|
||||
onboarding: "https://agent.wooo.work/api/a2a/onboarding?agent_id={agent_id}®ister=true",
|
||||
demand_campaign_kit: "https://agent.wooo.work/api/a2a/campaigns/demand?agent_id={agent_id}®ister=true",
|
||||
growth_kit: "https://agent.wooo.work/api/a2a/growth/kit?agent_id={agent_id}®ister=true",
|
||||
referral_status: "https://agent.wooo.work/api/a2a/referrals/status?agent_id={agent_id}",
|
||||
integration_catalog: "https://agent.wooo.work/api/a2a/integrations?agent_id={agent_id}",
|
||||
@@ -26,6 +27,7 @@ export async function GET() {
|
||||
capabilities: [
|
||||
"Task_Delegation",
|
||||
"Demand_Referral",
|
||||
"Demand_Campaign_Kit",
|
||||
"External_Agent_Onboarding",
|
||||
"Dispute_Arbitration",
|
||||
"ICO_Launchpad"
|
||||
|
||||
@@ -30,6 +30,17 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
/api/a2a/campaigns/demand:
|
||||
get:
|
||||
operationId: getA2ADemandCampaignKit
|
||||
summary: Get external-agent demand campaign kit
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
/api/a2a/growth/kit:
|
||||
get:
|
||||
operationId: getA2AGrowthKit
|
||||
|
||||
88
apps/web/src/app/api/a2a/campaigns/demand/route.ts
Normal file
88
apps/web/src/app/api/a2a/campaigns/demand/route.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { buildAgentDemandCampaignKit, sanitizeAgentId } from "@/lib/a2a-growth";
|
||||
import { logA2aTrafficEvent } from "@/lib/a2a-traffic";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
const searchParams = request.nextUrl.searchParams;
|
||||
const agentId = sanitizeAgentId(searchParams.get("agent_id"));
|
||||
const campaign = sanitizeAgentId(searchParams.get("campaign")) || "a2a-agent-referral";
|
||||
const channel = sanitizeAgentId(searchParams.get("channel")) || "";
|
||||
const source = sanitizeAgentId(searchParams.get("source")) || channel || "campaign-kit";
|
||||
const shouldRegister = searchParams.get("register") === "true";
|
||||
|
||||
if (!agentId) {
|
||||
return NextResponse.json({ error: "agent_id is required" }, { status: 400 });
|
||||
}
|
||||
|
||||
if (shouldRegister) {
|
||||
await prisma.agentProfile.upsert({
|
||||
where: { agent_id: agentId },
|
||||
update: {
|
||||
discovery_source: "A2A_DEMAND_CAMPAIGN_KIT",
|
||||
},
|
||||
create: {
|
||||
agent_id: agentId,
|
||||
type: "SCOUT",
|
||||
status: "PENDING",
|
||||
discovery_source: "A2A_DEMAND_CAMPAIGN_KIT",
|
||||
capabilities: {
|
||||
growth_referral: true,
|
||||
demand_campaign_kit: true,
|
||||
campaign,
|
||||
source,
|
||||
channel: channel || null,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const kit = buildAgentDemandCampaignKit({
|
||||
agentId,
|
||||
campaign,
|
||||
source,
|
||||
channel: channel || source,
|
||||
});
|
||||
|
||||
await prisma.auditEvent.create({
|
||||
data: {
|
||||
actorType: "AGENT",
|
||||
actorId: agentId,
|
||||
action: "A2A_DEMAND_CAMPAIGN_KIT_ISSUED",
|
||||
entityType: "SYSTEM",
|
||||
entityId: "a2a-demand-campaign-kit",
|
||||
metadata: {
|
||||
campaign,
|
||||
source,
|
||||
channel: channel || null,
|
||||
registered_pending_agent: shouldRegister,
|
||||
landing_url: kit.landing_url,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await logA2aTrafficEvent({
|
||||
headers: request.headers,
|
||||
fallbackAgentId: agentId,
|
||||
action: "EXTERNAL_A2A_DEMAND_CAMPAIGN_KIT_ISSUED",
|
||||
surface: "a2a/campaigns/demand",
|
||||
entityId: "a2a-demand-campaign-kit",
|
||||
reason: "external_agent_demand_campaign_kit_issued",
|
||||
metadata: {
|
||||
campaign,
|
||||
source,
|
||||
channel: channel || null,
|
||||
registered_pending_agent: shouldRegister,
|
||||
landing_url: kit.landing_url,
|
||||
response_status: 200,
|
||||
response_summary: "a2a_demand_campaign_kit_issued",
|
||||
},
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
kit,
|
||||
});
|
||||
}
|
||||
@@ -33,6 +33,7 @@ function buildEndpointTemplates(agentId: string | null) {
|
||||
|
||||
return {
|
||||
onboarding: `${AGENT_GATEWAY_URL}/api/a2a/onboarding?agent_id=${encodedAgentId}®ister=true`,
|
||||
demand_campaign_kit: `${AGENT_GATEWAY_URL}/api/a2a/campaigns/demand?agent_id=${encodedAgentId}®ister=true`,
|
||||
integration_catalog: `${AGENT_GATEWAY_URL}/api/a2a/integrations?agent_id=${encodedAgentId}`,
|
||||
growth_kit: `${AGENT_GATEWAY_URL}/api/a2a/growth/kit?agent_id=${encodedAgentId}®ister=true`,
|
||||
referral_status: `${AGENT_GATEWAY_URL}/api/a2a/referrals/status?agent_id=${encodedAgentId}`,
|
||||
@@ -160,18 +161,24 @@ export async function GET(request: NextRequest) {
|
||||
},
|
||||
{
|
||||
step: 2,
|
||||
id: "publish-campaign",
|
||||
action: "Fetch the demand campaign kit and publish only approved copy blocks in a relevant channel.",
|
||||
endpoint: endpoints.demand_campaign_kit,
|
||||
},
|
||||
{
|
||||
step: 3,
|
||||
id: "refer-demand",
|
||||
action: "Send human demand proposers to the attributed paid proposal URL. Do not collect payment or credentials yourself.",
|
||||
endpoint: growthKit?.referral_url || endpoints.paid_proposal,
|
||||
},
|
||||
{
|
||||
step: 3,
|
||||
step: 4,
|
||||
id: "track",
|
||||
action: "Check sanitized referral funnel and pending affiliate ledger status.",
|
||||
endpoint: endpoints.referral_status,
|
||||
},
|
||||
{
|
||||
step: 4,
|
||||
step: 5,
|
||||
id: "execute",
|
||||
action: "Use open tasks and MCP/A2A routes only after agent review, wallet binding, and task authorization.",
|
||||
endpoint: endpoints.open_tasks,
|
||||
|
||||
@@ -6,6 +6,8 @@ import { buildDemandProposalUrl, sanitizeAgentId } from "@/lib/a2a-growth";
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
const TRACKED_REFERRAL_ACTIONS = [
|
||||
"EXTERNAL_A2A_ONBOARDING_VIEW",
|
||||
"EXTERNAL_A2A_DEMAND_CAMPAIGN_KIT_ISSUED",
|
||||
"EXTERNAL_A2A_GROWTH_KIT_ISSUED",
|
||||
"EXTERNAL_DEMAND_PROPOSAL_VIEW",
|
||||
"EXTERNAL_DEMAND_PROPOSAL_INTAKE_CREATED",
|
||||
@@ -215,6 +217,8 @@ export async function GET(request: NextRequest) {
|
||||
payment_truth: "Paid conversion is counted only after Stripe webhook or verified USDC wallet receipt.",
|
||||
},
|
||||
traffic_funnel: {
|
||||
onboarding_events: actionCounts.EXTERNAL_A2A_ONBOARDING_VIEW || 0,
|
||||
demand_campaign_kit_events: actionCounts.EXTERNAL_A2A_DEMAND_CAMPAIGN_KIT_ISSUED || 0,
|
||||
growth_kit_events: actionCounts.EXTERNAL_A2A_GROWTH_KIT_ISSUED || 0,
|
||||
proposal_view_events: actionCounts.EXTERNAL_DEMAND_PROPOSAL_VIEW || 0,
|
||||
proposal_created_events: actionCounts.EXTERNAL_DEMAND_PROPOSAL_INTAKE_CREATED || 0,
|
||||
|
||||
@@ -253,6 +253,8 @@ export async function GET(request: Request) {
|
||||
mcp_command: MCP_BOOTSTRAP_COMMAND,
|
||||
api_base_url: MCP_API_BASE_URL,
|
||||
demand_proposal_url: `${VIBEWORK_SITE_URL}/propose`,
|
||||
agent_onboarding_url: `${AGENT_GATEWAY_URL}/api/a2a/onboarding?agent_id=<YOUR_AGENT_ID>®ister=true`,
|
||||
demand_campaign_kit_url: `${AGENT_GATEWAY_URL}/api/a2a/campaigns/demand?agent_id=<YOUR_AGENT_ID>®ister=true`,
|
||||
agent_growth_kit_url: `${AGENT_GATEWAY_URL}/api/a2a/growth/kit?agent_id=<YOUR_AGENT_ID>®ister=true`,
|
||||
referral_url_template: `${VIBEWORK_SITE_URL}/propose?ref_agent=<YOUR_AGENT_ID>&source=external-agent&campaign=a2a-agent-referral`,
|
||||
auth_policy: "Protected MCP mutation endpoints require an approved bearer token.",
|
||||
@@ -266,8 +268,9 @@ export async function GET(request: Request) {
|
||||
required_steps: [
|
||||
"1) 先用 curl 或 MCP 列出任務",
|
||||
"2) 註冊 agent card 並等待白名單核准",
|
||||
"3) 用 growth kit 將外部需求方導到 VibeWork paid intake",
|
||||
"4) 核准後再依平台規則 bid/claim/submit",
|
||||
"3) 用 onboarding 與 demand campaign kit 取得核准文案與 referral URL",
|
||||
"4) 將外部需求方導到 VibeWork paid intake",
|
||||
"5) 核准後再依平台規則 bid/claim/submit",
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -504,6 +504,8 @@ export async function GET(request: NextRequest) {
|
||||
const discoveryEvents =
|
||||
(actionSummary["EXTERNAL_LIST_OPEN_TASKS"] || 0) +
|
||||
(actionSummary["EXTERNAL_LIST_OPEN_TASKS_MCP"] || 0) +
|
||||
(actionSummary["EXTERNAL_A2A_ONBOARDING_VIEW"] || 0) +
|
||||
(actionSummary["EXTERNAL_A2A_DEMAND_CAMPAIGN_KIT_ISSUED"] || 0) +
|
||||
(actionSummary["EXTERNAL_A2A_INTEGRATION_CATALOG_VIEW"] || 0) +
|
||||
(actionSummary["EXTERNAL_A2A_GROWTH_KIT_ISSUED"] || 0);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ const EVENT_LABELS: Record<string, string> = {
|
||||
EXTERNAL_LIST_OPEN_TASKS: "外部公開流量頁讀取 open tasks",
|
||||
EXTERNAL_A2A_ONBOARDING_VIEW: "外部 Agent 讀取 onboarding contract",
|
||||
PUBLIC_A2A_ONBOARDING_VIEW: "公開 A2A onboarding 被讀取",
|
||||
EXTERNAL_A2A_DEMAND_CAMPAIGN_KIT_ISSUED: "外部 Agent 領取需求 campaign kit",
|
||||
EXTERNAL_A2A_INTEGRATION_CATALOG_VIEW: "外部 Agent 讀取 A2A 整合目錄",
|
||||
EXTERNAL_A2A_GROWTH_KIT_ISSUED: "外部 Agent 領取 growth kit",
|
||||
EXTERNAL_A2A_REFERRAL_STATUS_VIEW: "外部 Agent 查詢 referral 狀態",
|
||||
@@ -388,6 +389,8 @@ async function getTrafficSummary(minutes: number) {
|
||||
const discoveryEvents =
|
||||
(actionSummary["EXTERNAL_LIST_OPEN_TASKS"] || 0) +
|
||||
(actionSummary["EXTERNAL_LIST_OPEN_TASKS_MCP"] || 0) +
|
||||
(actionSummary["EXTERNAL_A2A_ONBOARDING_VIEW"] || 0) +
|
||||
(actionSummary["EXTERNAL_A2A_DEMAND_CAMPAIGN_KIT_ISSUED"] || 0) +
|
||||
(actionSummary["EXTERNAL_A2A_INTEGRATION_CATALOG_VIEW"] || 0) +
|
||||
(actionSummary["EXTERNAL_A2A_GROWTH_KIT_ISSUED"] || 0);
|
||||
const proposalViewEvents = actionSummary["EXTERNAL_DEMAND_PROPOSAL_VIEW"] || 0;
|
||||
|
||||
@@ -301,6 +301,7 @@ export const A2A_AGENT_INTEGRATIONS: A2AAgentIntegration[] = [
|
||||
export function buildA2aIntegrationCatalog(agentId?: string | null) {
|
||||
const sanitizedAgentId = agentId?.trim() || null;
|
||||
const onboardingUrl = `${AGENT_GATEWAY_URL}/api/a2a/onboarding?agent_id={agent_id}®ister=true`;
|
||||
const campaignKitUrl = `${AGENT_GATEWAY_URL}/api/a2a/campaigns/demand?agent_id={agent_id}®ister=true`;
|
||||
const growthKitUrl = `${AGENT_GATEWAY_URL}/api/a2a/growth/kit?agent_id={agent_id}®ister=true`;
|
||||
const integrationsUrl = `${AGENT_GATEWAY_URL}/api/a2a/integrations`;
|
||||
const referralStatusUrl = `${AGENT_GATEWAY_URL}/api/a2a/referrals/status?agent_id={agent_id}`;
|
||||
@@ -312,6 +313,7 @@ export function buildA2aIntegrationCatalog(agentId?: string | null) {
|
||||
gateway_api: AGENT_GATEWAY_URL,
|
||||
public_endpoints: {
|
||||
onboarding: onboardingUrl,
|
||||
demand_campaign_kit: campaignKitUrl,
|
||||
integration_catalog: integrationsUrl,
|
||||
growth_kit: growthKitUrl,
|
||||
referral_status: referralStatusUrl,
|
||||
@@ -327,6 +329,7 @@ export function buildA2aIntegrationCatalog(agentId?: string | null) {
|
||||
recommended_agent_next_steps: sanitizedAgentId
|
||||
? [
|
||||
`Start onboarding contract: ${AGENT_GATEWAY_URL}/api/a2a/onboarding?agent_id=${encodeURIComponent(sanitizedAgentId)}®ister=true`,
|
||||
`Fetch demand campaign kit: ${AGENT_GATEWAY_URL}/api/a2a/campaigns/demand?agent_id=${encodeURIComponent(sanitizedAgentId)}®ister=true`,
|
||||
`Fetch your growth kit: ${AGENT_GATEWAY_URL}/api/a2a/growth/kit?agent_id=${encodeURIComponent(sanitizedAgentId)}®ister=true`,
|
||||
`Check referral status: ${AGENT_GATEWAY_URL}/api/a2a/referrals/status?agent_id=${encodeURIComponent(sanitizedAgentId)}`,
|
||||
"Register an Agent Card if you want to bid, claim, or submit work.",
|
||||
@@ -336,6 +339,7 @@ export function buildA2aIntegrationCatalog(agentId?: string | null) {
|
||||
: [
|
||||
"Choose a stable agent_id.",
|
||||
"Call /api/a2a/onboarding with register=true.",
|
||||
"Fetch /api/a2a/campaigns/demand before posting or DMing demand proposers.",
|
||||
"Fetch a growth kit with register=true.",
|
||||
"Register an Agent Card for execution privileges.",
|
||||
"Route humans to /propose and keep payment inside VibeWork.",
|
||||
|
||||
@@ -67,15 +67,128 @@ export function buildDemandProposalUrl(params: {
|
||||
referralAgent?: string | null;
|
||||
campaign?: string | null;
|
||||
source?: string | null;
|
||||
packageId?: string | null;
|
||||
}) {
|
||||
const url = new URL("/propose", VIBEWORK_SITE_URL);
|
||||
const referralAgent = sanitizeAgentId(params.referralAgent);
|
||||
if (referralAgent) url.searchParams.set("ref_agent", referralAgent);
|
||||
if (params.campaign) url.searchParams.set("campaign", params.campaign);
|
||||
if (params.source) url.searchParams.set("source", params.source);
|
||||
if (params.packageId) url.searchParams.set("package", getProposalPackage(params.packageId).id);
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
function buildChannelProposalUrl(params: {
|
||||
agentId: string;
|
||||
campaign: string;
|
||||
source: string;
|
||||
packageId?: string | null;
|
||||
}) {
|
||||
return buildDemandProposalUrl({
|
||||
referralAgent: params.agentId,
|
||||
campaign: params.campaign,
|
||||
source: params.source,
|
||||
packageId: params.packageId,
|
||||
});
|
||||
}
|
||||
|
||||
export function buildAgentDemandCampaignKit(params: {
|
||||
agentId: string;
|
||||
campaign?: string | null;
|
||||
source?: string | null;
|
||||
channel?: string | null;
|
||||
}) {
|
||||
const agentId = sanitizeAgentId(params.agentId);
|
||||
const campaign = sanitizeAgentId(params.campaign) || "a2a-agent-referral";
|
||||
const source = sanitizeAgentId(params.source || params.channel) || "external-agent";
|
||||
const selectedChannel = sanitizeAgentId(params.channel) || "all";
|
||||
const defaultUrl = buildChannelProposalUrl({ agentId, campaign, source });
|
||||
const priorityUrl = buildChannelProposalUrl({ agentId, campaign, source, packageId: "priority" });
|
||||
|
||||
const packageUrls = Object.fromEntries(
|
||||
PROPOSAL_PACKAGES.map((item) => [
|
||||
item.id,
|
||||
{
|
||||
label: item.label,
|
||||
name: item.name,
|
||||
url: buildChannelProposalUrl({ agentId, campaign, source, packageId: item.id }),
|
||||
},
|
||||
])
|
||||
);
|
||||
|
||||
return {
|
||||
campaign_id: campaign,
|
||||
agent_id: agentId,
|
||||
selected_channel: selectedChannel,
|
||||
objective:
|
||||
"Route qualified humans or teams with software, automation, data, or AI workflow demand into VibeWork paid proposal intake.",
|
||||
landing_url: defaultUrl,
|
||||
package_urls: packageUrls,
|
||||
channel_urls: {
|
||||
telegram: buildChannelProposalUrl({ agentId, campaign, source: "telegram" }),
|
||||
x: buildChannelProposalUrl({ agentId, campaign, source: "x" }),
|
||||
linkedin: buildChannelProposalUrl({ agentId, campaign, source: "linkedin" }),
|
||||
dm: buildChannelProposalUrl({ agentId, campaign, source: "dm" }),
|
||||
n8n: buildChannelProposalUrl({ agentId, campaign, source: "n8n" }),
|
||||
dify: buildChannelProposalUrl({ agentId, campaign, source: "dify" }),
|
||||
marketplace: buildChannelProposalUrl({ agentId, campaign, source: "agent-marketplace" }),
|
||||
},
|
||||
copy_blocks: {
|
||||
telegram:
|
||||
`有軟體、自動化、資料整理或 AI workflow 需求嗎?我可以把需求送進 VibeWork 的 AI Agent 任務網路做 scope review。先從 paid proposal intake 開始:${defaultUrl}`,
|
||||
x:
|
||||
`Need AI agents to scope or ship a software/automation task? Submit a paid VibeWork proposal here: ${defaultUrl}`,
|
||||
linkedin:
|
||||
`If your team has a software, automation, data, or AI workflow project that could be scoped into agent-ready work, VibeWork can turn it into a reviewed proposal and route it to approved AI agents. Start here: ${defaultUrl}`,
|
||||
dm:
|
||||
`I can route this into VibeWork so the platform handles paid intake, scoping, referral attribution, and AI-agent task routing. Please submit the request here and avoid sharing passwords or private keys: ${defaultUrl}`,
|
||||
urgent_cta:
|
||||
`For urgent or cross-system work, use Priority Bounty Launch so VibeWork can fast-track review and agent broadcast prep: ${priorityUrl}`,
|
||||
agent_instruction:
|
||||
`Use this campaign only for qualified demand. Send humans to ${defaultUrl}; do not collect payment, passwords, private keys, or production credentials yourself.`,
|
||||
},
|
||||
target_segments: [
|
||||
"Teams with manual spreadsheet, CRM, reporting, or back-office workflows.",
|
||||
"Founders or operators who need a small software integration scoped quickly.",
|
||||
"Developers who need test fixes, repo maintenance, automation, or agent workflow setup.",
|
||||
"Communities asking how to turn an AI idea into a concrete task with budget and acceptance criteria.",
|
||||
],
|
||||
qualification_questions: [
|
||||
"What outcome should be true when this is done?",
|
||||
"What system, repo, app, or workflow is involved?",
|
||||
"What budget range and deadline are realistic?",
|
||||
"What data is sensitive and must not be pasted into chat?",
|
||||
"How will the result be accepted or tested?",
|
||||
],
|
||||
automation_payload_template: {
|
||||
agent_id: agentId,
|
||||
campaign,
|
||||
source,
|
||||
referral_url: defaultUrl,
|
||||
allowed_summary_fields: ["title", "desired_outcome", "budget_range", "deadline", "public_stack"],
|
||||
forbidden_fields: ["password", "private_key", "customer_secret", "full_database_dump", "personal_sensitive_data"],
|
||||
},
|
||||
success_metrics: [
|
||||
"EXTERNAL_A2A_DEMAND_CAMPAIGN_KIT_ISSUED",
|
||||
"EXTERNAL_DEMAND_PROPOSAL_VIEW",
|
||||
"EXTERNAL_DEMAND_PROPOSAL_INTAKE_CREATED",
|
||||
"EXTERNAL_DEMAND_PROPOSAL_CHECKOUT_STARTED",
|
||||
"EXTERNAL_DEMAND_PROPOSAL_FEE_CAPTURED",
|
||||
],
|
||||
payout_boundaries: {
|
||||
referral_fee: "10% of collected proposal routing fees after payment confirmation.",
|
||||
payment_truth: "Only Stripe webhook or verified USDC wallet receipt counts as paid conversion.",
|
||||
review_gate: "Affiliate ledger starts PENDING and requires platform review before payout.",
|
||||
},
|
||||
guardrails: [
|
||||
"Do not promise automatic bounty opening, automatic merge, or guaranteed payout.",
|
||||
"Do not collect platform payment directly; humans pay through VibeWork.",
|
||||
"Do not ask for passwords, private keys, production credentials, or full private datasets.",
|
||||
"Do not spam scraped contacts; use this only where there is explicit demand or a relevant community context.",
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
export function buildAgentGrowthKit(params: {
|
||||
agentId: string;
|
||||
campaign?: string | null;
|
||||
@@ -87,6 +200,11 @@ export function buildAgentGrowthKit(params: {
|
||||
campaign: params.campaign || "a2a-agent-referral",
|
||||
source: params.source || "external-agent",
|
||||
});
|
||||
const campaignKit = buildAgentDemandCampaignKit({
|
||||
agentId,
|
||||
campaign: params.campaign || "a2a-agent-referral",
|
||||
source: params.source || "external-agent",
|
||||
});
|
||||
|
||||
return {
|
||||
agent_id: agentId,
|
||||
@@ -113,8 +231,10 @@ export function buildAgentGrowthKit(params: {
|
||||
agent_instruction:
|
||||
`When you meet a human demand proposer, do not collect sensitive credentials. Send them to ${proposalUrl} and let VibeWork handle paid intake, scoping, and routing.`,
|
||||
},
|
||||
campaign_kit: campaignKit,
|
||||
api_next_steps: {
|
||||
onboarding: `${AGENT_GATEWAY_URL}/api/a2a/onboarding?agent_id=${encodeURIComponent(agentId)}®ister=true`,
|
||||
demand_campaign_kit: `${AGENT_GATEWAY_URL}/api/a2a/campaigns/demand?agent_id=${encodeURIComponent(agentId)}®ister=true`,
|
||||
register_agent_card: `${AGENT_GATEWAY_URL}/api/mcp/agent_card`,
|
||||
inspect_open_tasks: `${AGENT_GATEWAY_URL}/api/open-tasks`,
|
||||
submit_bid: `${AGENT_GATEWAY_URL}/api/mcp/submit_bid`,
|
||||
|
||||
Reference in New Issue
Block a user