@ziggs-ai/agent-sdk 0.1.11 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +41 -2
- package/dist/AgentHost.d.ts +201 -0
- package/dist/AgentHost.js +652 -0
- package/dist/adapters/AnthropicAdapter.d.ts +39 -0
- package/dist/adapters/AnthropicAdapter.js +200 -0
- package/dist/adapters/McpAdapter.d.ts +199 -0
- package/dist/adapters/McpAdapter.js +468 -0
- package/dist/adapters/OpenAIAdapter.d.ts +26 -0
- package/dist/adapters/OpenAIAdapter.js +158 -0
- package/dist/adapters/index.js +2 -0
- package/dist/agent/Agent.d.ts +78 -0
- package/dist/agent/Agent.js +58 -0
- package/dist/agent/ClaudeSdkAgent.d.ts +38 -0
- package/dist/agent/ClaudeSdkAgent.js +322 -0
- package/dist/agent/claudeCognition.d.ts +67 -0
- package/dist/agent/claudeCognition.js +103 -0
- package/dist/agent/claudeSdkProtocol.d.ts +11 -0
- package/dist/agent/claudeSdkProtocol.js +27 -0
- package/dist/agent/claudeSdkTools.d.ts +19 -0
- package/dist/agent/claudeSdkTools.js +57 -0
- package/dist/agent/hostedAgentConnection.d.ts +15 -0
- package/dist/agent/hostedAgentConnection.js +29 -0
- package/dist/agent/toolManagerToSdkMcp.d.ts +12 -0
- package/dist/agent/toolManagerToSdkMcp.js +123 -0
- package/dist/brain/index.d.ts +50 -0
- package/dist/brain/index.js +45 -0
- package/dist/cognition/validateContext.d.ts +11 -0
- package/dist/cognition/validateContext.js +117 -0
- package/dist/context/applyEffects.d.ts +2 -0
- package/dist/context/applyEffects.js +89 -0
- package/dist/context/batch.d.ts +2 -0
- package/dist/context/batch.js +18 -0
- package/dist/context/classifyEnvelope.d.ts +1 -0
- package/dist/context/classifyEnvelope.js +58 -0
- package/dist/context/routingLabels.d.ts +4 -0
- package/dist/context/routingLabels.js +48 -0
- package/dist/defineAgent.d.ts +14 -0
- package/dist/defineAgent.js +68 -0
- package/dist/formatters/AgreementFormatter.d.ts +18 -0
- package/dist/formatters/AgreementFormatter.js +130 -0
- package/dist/formatters/HistoryFormatter.d.ts +26 -0
- package/dist/formatters/HistoryFormatter.js +173 -0
- package/dist/formatters/index.js +2 -0
- package/{src/index.ts → dist/index.d.ts} +13 -53
- package/dist/index.js +66 -0
- package/dist/ingress/normalizeIncoming.d.ts +65 -0
- package/dist/ingress/normalizeIncoming.js +88 -0
- package/dist/memory/MemoryStore.d.ts +55 -0
- package/dist/memory/MemoryStore.js +78 -0
- package/dist/pricing/fleetDefaults.d.ts +46 -0
- package/dist/pricing/fleetDefaults.js +168 -0
- package/dist/pricing/fleetEvalFree.d.ts +7 -0
- package/dist/pricing/fleetEvalFree.js +24 -0
- package/dist/pricing/fleetFreeTierA.gen.d.ts +6 -0
- package/{src/pricing/fleetFreeTierA.gen.ts → dist/pricing/fleetFreeTierA.gen.js} +5 -6
- package/dist/pricing/fleetTierByAgentId.gen.d.ts +7 -0
- package/dist/pricing/fleetTierByAgentId.gen.js +768 -0
- package/dist/runtime/AgentMachine.d.ts +143 -0
- package/dist/runtime/AgentMachine.js +400 -0
- package/dist/runtime/PromptBuilder.d.ts +96 -0
- package/dist/runtime/PromptBuilder.js +439 -0
- package/dist/runtime/bootstrapCtx.d.ts +18 -0
- package/dist/runtime/bootstrapCtx.js +37 -0
- package/dist/runtime/buildOutcome.d.ts +68 -0
- package/dist/runtime/buildOutcome.js +464 -0
- package/dist/runtime/defaults.d.ts +54 -0
- package/dist/runtime/defaults.js +47 -0
- package/dist/runtime/deriveRespondsToProposals.d.ts +9 -0
- package/dist/runtime/deriveRespondsToProposals.js +38 -0
- package/dist/runtime/kickoff.d.ts +15 -0
- package/dist/runtime/kickoff.js +112 -0
- package/dist/runtime/runMechanical.d.ts +25 -0
- package/dist/runtime/runMechanical.js +74 -0
- package/dist/runtime/runTurn.d.ts +63 -0
- package/dist/runtime/runTurn.js +800 -0
- package/dist/runtime/validateWorkflow.d.ts +17 -0
- package/dist/runtime/validateWorkflow.js +209 -0
- package/dist/server/ConnectionPool.d.ts +68 -0
- package/dist/server/ConnectionPool.js +166 -0
- package/dist/server/EventQueue.d.ts +33 -0
- package/dist/server/EventQueue.js +98 -0
- package/dist/server/InboxCatchUp.d.ts +24 -0
- package/dist/server/InboxCatchUp.js +213 -0
- package/dist/server/OutboxBuffer.d.ts +33 -0
- package/dist/server/OutboxBuffer.js +68 -0
- package/dist/server/SeenMessages.d.ts +13 -0
- package/dist/server/SeenMessages.js +31 -0
- package/dist/server/StateTimers.d.ts +34 -0
- package/dist/server/StateTimers.js +70 -0
- package/dist/server/ZiggsEffectHandler.d.ts +79 -0
- package/dist/server/ZiggsEffectHandler.js +319 -0
- package/dist/server/agreements/AgreementService.d.ts +50 -0
- package/dist/server/agreements/AgreementService.js +85 -0
- package/dist/server/createHealthServer.d.ts +7 -0
- package/dist/server/createHealthServer.js +75 -0
- package/dist/server/proactive/ProactiveTrigger.d.ts +33 -0
- package/dist/server/proactive/ProactiveTrigger.js +71 -0
- package/dist/server/runLauncher.d.ts +28 -0
- package/dist/server/runLauncher.js +93 -0
- package/dist/server/tasks/TaskService.d.ts +25 -0
- package/dist/server/tasks/TaskService.js +103 -0
- package/dist/server/tasks/index.js +1 -0
- package/dist/server/telemetryIngest.d.ts +24 -0
- package/dist/server/telemetryIngest.js +62 -0
- package/dist/server/tools/index.d.ts +24 -0
- package/{src/server/tools/index.ts → dist/server/tools/index.js} +4 -24
- package/dist/server/tools/tier1/protocolRunner.d.ts +39 -0
- package/dist/server/tools/tier1/protocolRunner.js +288 -0
- package/dist/server/tools/tier1/protocolTools.d.ts +12 -0
- package/dist/server/tools/tier1/protocolTools.js +37 -0
- package/dist/server/tools/tier2/connectionTools.d.ts +4 -0
- package/dist/server/tools/tier2/connectionTools.js +63 -0
- package/dist/server/tools/tier2/contextTools.d.ts +4 -0
- package/dist/server/tools/tier2/contextTools.js +46 -0
- package/dist/server/tools/tier2/discoveryTools.d.ts +4 -0
- package/dist/server/tools/tier2/discoveryTools.js +25 -0
- package/dist/server/tools/tier2/marketplaceTools.d.ts +3 -0
- package/dist/server/tools/tier2/marketplaceTools.js +22 -0
- package/dist/server/tools/tier2/paymentTools.d.ts +12 -0
- package/dist/server/tools/tier2/paymentTools.js +165 -0
- package/dist/server/ziggsconnect/ZiggsConnectClient.d.ts +35 -0
- package/dist/server/ziggsconnect/ZiggsConnectClient.js +95 -0
- package/dist/server/ziggscontext/ZiggsContextClient.d.ts +48 -0
- package/dist/server/ziggscontext/ZiggsContextClient.js +90 -0
- package/dist/server/ziggspay/ZiggsPayClient.d.ts +82 -0
- package/dist/server/ziggspay/ZiggsPayClient.js +188 -0
- package/dist/shared/ids.d.ts +1 -0
- package/dist/shared/ids.js +3 -0
- package/dist/shared/runtimeLog.d.ts +18 -0
- package/dist/shared/runtimeLog.js +68 -0
- package/dist/shared/types.d.ts +22 -0
- package/dist/shared/types.js +23 -0
- package/dist/tasks/protocolRegistry.d.ts +16 -0
- package/dist/tasks/protocolRegistry.js +20 -0
- package/dist/tools/ToolManager.d.ts +12 -0
- package/dist/tools/ToolManager.js +74 -0
- package/dist/tools/ToolProvider.d.ts +6 -0
- package/dist/tools/ToolProvider.js +21 -0
- package/dist/tools/defineTool.d.ts +27 -0
- package/dist/tools/defineTool.js +62 -0
- package/{src/tools/index.ts → dist/tools/index.d.ts} +0 -1
- package/dist/tools/index.js +6 -0
- package/dist/tools/recordReport.d.ts +41 -0
- package/dist/tools/recordReport.js +30 -0
- package/dist/types.d.ts +466 -0
- package/dist/types.js +7 -0
- package/dist/utils/jsonExtractor.d.ts +2 -0
- package/dist/utils/jsonExtractor.js +111 -0
- package/package.json +17 -7
- package/src/AgentHost.ts +0 -545
- package/src/adapters/AnthropicAdapter.ts +0 -206
- package/src/adapters/McpAdapter.ts +0 -348
- package/src/adapters/OpenAIAdapter.ts +0 -187
- package/src/agent/Agent.ts +0 -104
- package/src/cognition/validateContext.ts +0 -95
- package/src/context/applyEffects.ts +0 -80
- package/src/context/batch.ts +0 -19
- package/src/context/classifyEnvelope.ts +0 -38
- package/src/context/routingLabels.ts +0 -46
- package/src/defineAgent.ts +0 -70
- package/src/formatters/AgreementFormatter.ts +0 -111
- package/src/formatters/HistoryFormatter.ts +0 -172
- package/src/ingress/normalizeIncoming.ts +0 -162
- package/src/memory/MemoryStore.ts +0 -104
- package/src/pricing/fleetDefaults.ts +0 -225
- package/src/pricing/fleetEvalFree.ts +0 -24
- package/src/pricing/fleetTierByAgentId.gen.ts +0 -775
- package/src/runtime/AgentMachine.ts +0 -402
- package/src/runtime/PromptBuilder.ts +0 -485
- package/src/runtime/buildOutcome.ts +0 -563
- package/src/runtime/defaults.ts +0 -75
- package/src/runtime/kickoff.ts +0 -117
- package/src/runtime/runTurn.ts +0 -813
- package/src/runtime/validateWorkflow.ts +0 -202
- package/src/server/ConnectionPool.ts +0 -206
- package/src/server/EventQueue.ts +0 -133
- package/src/server/InboxCatchUp.ts +0 -254
- package/src/server/OutboxBuffer.ts +0 -90
- package/src/server/SeenMessages.ts +0 -27
- package/src/server/StateTimers.ts +0 -85
- package/src/server/ZiggsEffectHandler.ts +0 -418
- package/src/server/agreements/AgreementService.ts +0 -118
- package/src/server/createHealthServer.ts +0 -85
- package/src/server/proactive/ProactiveTrigger.ts +0 -83
- package/src/server/runLauncher.ts +0 -146
- package/src/server/tasks/TaskService.ts +0 -110
- package/src/server/telemetryIngest.ts +0 -91
- package/src/server/tools/tier1/protocolRunner.ts +0 -144
- package/src/server/tools/tier1/protocolTools.ts +0 -99
- package/src/server/tools/tier2/connectionTools.ts +0 -75
- package/src/server/tools/tier2/contextTools.ts +0 -63
- package/src/server/tools/tier2/discoveryTools.ts +0 -34
- package/src/server/tools/tier2/marketplaceTools.ts +0 -27
- package/src/server/tools/tier2/paymentTools.ts +0 -170
- package/src/server/ziggsconnect/ZiggsConnectClient.ts +0 -126
- package/src/server/ziggscontext/ZiggsContextClient.ts +0 -129
- package/src/server/ziggspay/ZiggsPayClient.ts +0 -193
- package/src/shared/ids.ts +0 -3
- package/src/shared/runtimeLog.ts +0 -72
- package/src/shared/types.ts +0 -29
- package/src/tasks/protocolRegistry.ts +0 -25
- package/src/tools/ToolManager.ts +0 -95
- package/src/tools/ToolProvider.ts +0 -19
- package/src/tools/defineTool.ts +0 -90
- package/src/tools/recordReport.ts +0 -82
- package/src/types.ts +0 -456
- package/src/utils/jsonExtractor.ts +0 -100
- /package/{src/adapters/index.ts → dist/adapters/index.d.ts} +0 -0
- /package/{src/formatters/index.ts → dist/formatters/index.d.ts} +0 -0
- /package/{src/server/tasks/index.ts → dist/server/tasks/index.d.ts} +0 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import { applyFleetCounterPricing, applyFleetPricingForProtocol, } from '../../../pricing/fleetDefaults.js';
|
|
2
|
+
// Map legacy task-state aliases onto the canonical set.
|
|
3
|
+
function normalizeState(state) {
|
|
4
|
+
if (state === 'done')
|
|
5
|
+
return 'completed';
|
|
6
|
+
if (state === 'error')
|
|
7
|
+
return 'failed';
|
|
8
|
+
return state;
|
|
9
|
+
}
|
|
10
|
+
// ZIG-793: the `plan` tool-schema is underspecified (`plan: {type:'object'}`,
|
|
11
|
+
// `planReviewTiming: 'string'`), so the LLM emits steps missing stepId/order and an
|
|
12
|
+
// out-of-enum planReviewTiming, which the backend DTO rejects. Normalize in-place here
|
|
13
|
+
// so every op (propose / subcontract / counter / task-spawn) sends a valid plan.
|
|
14
|
+
function normalizePlanInPlace(payload) {
|
|
15
|
+
const plan = payload.plan;
|
|
16
|
+
if (plan && Array.isArray(plan.steps)) {
|
|
17
|
+
plan.steps = plan.steps.map((s, i) => {
|
|
18
|
+
const step = s && typeof s === 'object'
|
|
19
|
+
? s
|
|
20
|
+
: { description: String(s) };
|
|
21
|
+
return {
|
|
22
|
+
...step,
|
|
23
|
+
stepId: typeof step.stepId === 'string' && step.stepId ? step.stepId : `step-${i + 1}`,
|
|
24
|
+
order: typeof step.order === 'number' ? step.order : i,
|
|
25
|
+
description: typeof step.description === 'string'
|
|
26
|
+
? step.description
|
|
27
|
+
: String(step.description ?? ''),
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
if (payload.planReviewTiming !== undefined &&
|
|
32
|
+
payload.planReviewTiming !== 'with_proposal' &&
|
|
33
|
+
payload.planReviewTiming !== 'before_execution') {
|
|
34
|
+
payload.planReviewTiming = 'with_proposal';
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export async function dispatchProtocolOp(services, payload, chatId, agents = [], actingAgentId = null) {
|
|
38
|
+
if (!payload?.operation)
|
|
39
|
+
return null;
|
|
40
|
+
normalizePlanInPlace(payload);
|
|
41
|
+
const { operation } = payload;
|
|
42
|
+
const { agreementService, taskService } = services;
|
|
43
|
+
const actorId = actingAgentId?.trim() || null;
|
|
44
|
+
switch (operation) {
|
|
45
|
+
case 'agreement-propose':
|
|
46
|
+
return proposeAgreement(services, payload, chatId, agents, actorId);
|
|
47
|
+
case 'agreement-subcontract':
|
|
48
|
+
return subcontractAgreement(services, payload, chatId, agents, actorId);
|
|
49
|
+
case 'agreement-respond':
|
|
50
|
+
if (!payload.agreementId || !payload.action)
|
|
51
|
+
return null;
|
|
52
|
+
return agreementService.respond(payload.agreementId, payload.action);
|
|
53
|
+
case 'agreement-counter-proposal':
|
|
54
|
+
if (!payload.agreementId)
|
|
55
|
+
return null;
|
|
56
|
+
{
|
|
57
|
+
const counterPayload = actorId != null
|
|
58
|
+
? applyFleetCounterPricing(payload, actorId)
|
|
59
|
+
: payload;
|
|
60
|
+
return agreementService.counter(payload.agreementId, {
|
|
61
|
+
price: counterPayload.price,
|
|
62
|
+
agreementDescription: counterPayload.agreementDescription,
|
|
63
|
+
expiresAt: counterPayload.expiresAt,
|
|
64
|
+
lifecycle: counterPayload.lifecycle,
|
|
65
|
+
maxExecutions: counterPayload.maxExecutions,
|
|
66
|
+
description: counterPayload.description,
|
|
67
|
+
plan: counterPayload.plan,
|
|
68
|
+
planReviewTiming: counterPayload.planReviewTiming,
|
|
69
|
+
requireMidWorkPlanAck: counterPayload.requireMidWorkPlanAck,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
case 'agreement-check-proposal':
|
|
73
|
+
if (!payload.agreementId)
|
|
74
|
+
return null;
|
|
75
|
+
return agreementService.getStatus(payload.agreementId);
|
|
76
|
+
case 'agreement-revoke':
|
|
77
|
+
if (!payload.agreementId)
|
|
78
|
+
return null;
|
|
79
|
+
return agreementService.revoke(payload.agreementId);
|
|
80
|
+
case 'agreement-fulfill':
|
|
81
|
+
if (!payload.agreementId)
|
|
82
|
+
return null;
|
|
83
|
+
return agreementService.fulfill(payload.agreementId);
|
|
84
|
+
case 'task-spawn': {
|
|
85
|
+
if (!payload.agreementId || !payload.description)
|
|
86
|
+
return null;
|
|
87
|
+
let spawnAgreementId = payload.agreementId;
|
|
88
|
+
const ags = await agreementsInChat(services, chatId);
|
|
89
|
+
// b2 (ZIG-832): if the assignee is not a party on the cited agreement,
|
|
90
|
+
// redirect the spawn to the ACTIVE sub-agreement (same root) where the
|
|
91
|
+
// assignee IS the provider — the orchestrator often cites the top-level
|
|
92
|
+
// hire, which the backend rejects with "assignee not a party".
|
|
93
|
+
// ZIG-858: also redirect when the cited agreement is no longer active —
|
|
94
|
+
// a count-bound sub fulfills after its quota (default 1), and the LLM
|
|
95
|
+
// keeps citing that now-terminal sub for the next spawn even when a
|
|
96
|
+
// fresh active sub for the same executor exists.
|
|
97
|
+
if (payload.assigneeId) {
|
|
98
|
+
const cited = ags.find((a) => a.agreementId === payload.agreementId);
|
|
99
|
+
if (cited && (!agIsParty(cited, payload.assigneeId) || !agIsActiveStatus(cited))) {
|
|
100
|
+
const root = cited.rootAgreementId || payload.agreementId;
|
|
101
|
+
const sub = ags.find((a) => agIsActiveStatus(a) && agIsProvider(a, payload.assigneeId) &&
|
|
102
|
+
(a.rootAgreementId === root || a.parentAgreementId === payload.agreementId ||
|
|
103
|
+
a.parentAgreementId === root));
|
|
104
|
+
if (sub?.agreementId)
|
|
105
|
+
spawnAgreementId = sub.agreementId;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Safety guard (ZIG-832, B): a spawn against an agreement that is not active,
|
|
109
|
+
// or whose assignee is not a party on it, hard-400s at the backend AND makes
|
|
110
|
+
// the worker invent a "connection needed" message. That happens when the
|
|
111
|
+
// orchestrator spawns before its sub-agreement is subcontracted/approved.
|
|
112
|
+
// Skip GRACEFULLY instead — the sub-agreement's activation event will wake
|
|
113
|
+
// the orchestrator to spawn correctly on a later turn, no 400, no cascade.
|
|
114
|
+
const target = ags.find((a) => a.agreementId === spawnAgreementId);
|
|
115
|
+
// ZIG-858: a TERMINAL target is not the same as a not-yet-active one — no
|
|
116
|
+
// activation event will ever arrive, so the "wait for a later turn" skip
|
|
117
|
+
// below would stall the run. Tell the caller the actionable next step:
|
|
118
|
+
// subcontract a fresh sub for this executor, then spawn under it.
|
|
119
|
+
if (target && TERMINAL_STATUS.has(String(target.status))) {
|
|
120
|
+
return {
|
|
121
|
+
ok: false,
|
|
122
|
+
skipped: 'spawn-target-terminal',
|
|
123
|
+
reason: `agreement ${spawnAgreementId} is ${target.status} (terminal — its quota or term is exhausted). Subcontract a new sub-agreement to ${payload.assigneeId ?? 'the executor'}, then spawn this task under that new agreement.`,
|
|
124
|
+
agreementId: spawnAgreementId,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
const notReady = (target && !agIsActiveStatus(target)) ||
|
|
128
|
+
(!!payload.assigneeId && target && !agIsParty(target, payload.assigneeId));
|
|
129
|
+
if (notReady) {
|
|
130
|
+
return {
|
|
131
|
+
ok: false,
|
|
132
|
+
skipped: 'spawn-target-not-ready',
|
|
133
|
+
reason: target && !agIsActiveStatus(target)
|
|
134
|
+
? `agreement ${spawnAgreementId} is ${target?.status ?? 'unknown'} (not active yet)`
|
|
135
|
+
: `assignee is not a party on ${spawnAgreementId} yet — subcontract to it first`,
|
|
136
|
+
agreementId: spawnAgreementId,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
return taskService.spawnUnderAgreement(spawnAgreementId, {
|
|
140
|
+
description: payload.description,
|
|
141
|
+
parentTaskId: payload.parentTaskId,
|
|
142
|
+
plan: payload.plan,
|
|
143
|
+
planReviewTiming: payload.planReviewTiming,
|
|
144
|
+
requireMidWorkPlanAck: payload.requireMidWorkPlanAck,
|
|
145
|
+
assigneeId: payload.assigneeId,
|
|
146
|
+
inputArtifactIds: Array.isArray(payload.inputArtifactIds)
|
|
147
|
+
? payload.inputArtifactIds
|
|
148
|
+
: undefined,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
case 'task-update':
|
|
152
|
+
if (!payload.taskId || !payload.status)
|
|
153
|
+
return null;
|
|
154
|
+
return taskService.updateState(payload.taskId, normalizeState(payload.status), payload.result);
|
|
155
|
+
case 'task-update-plan-step':
|
|
156
|
+
if (!payload.taskId)
|
|
157
|
+
throw new Error('task-update-plan-step requires `taskId`');
|
|
158
|
+
if (!payload.stepId)
|
|
159
|
+
throw new Error('task-update-plan-step requires `stepId`');
|
|
160
|
+
if (!payload.status)
|
|
161
|
+
throw new Error('task-update-plan-step requires `status`');
|
|
162
|
+
// ZIG-793: a plan-step tick is cosmetic progress. Worker subtasks usually
|
|
163
|
+
// have NO plan (only the orchestrator's job task does), and the LLM may tick
|
|
164
|
+
// a stepId that isn't in the plan — the backend 400s on both. That must never
|
|
165
|
+
// hard-fail the tool → fail the task → wake-loop. Make it best-effort.
|
|
166
|
+
try {
|
|
167
|
+
return await taskService.updatePlanStep(payload.taskId, payload.stepId, payload.status, payload.result);
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
return { ok: false, skipped: 'plan-step-not-updatable', stepId: payload.stepId };
|
|
171
|
+
}
|
|
172
|
+
default:
|
|
173
|
+
throw new Error(`Unknown protocol operation: ${operation}`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
async function proposeAgreement(services, payload, chatId, _agents, actingAgentId) {
|
|
177
|
+
if (!payload.description)
|
|
178
|
+
throw new Error('agreement-propose requires `description`');
|
|
179
|
+
if (!payload.proposedTo)
|
|
180
|
+
throw new Error('agreement-propose requires `proposedTo` (userId or agentId). To spawn a task under an existing agreement, use `task_spawn` instead.');
|
|
181
|
+
const isBroadcast = payload.proposedTo === 'everyone' || payload.proposedTo === 'org';
|
|
182
|
+
if (!isBroadcast && !payload.providerId) {
|
|
183
|
+
throw new Error('agreement-propose requires `providerId` — name who does the work: your own id (you are offering to work) or the proposedTo id (you are commissioning the recipient).');
|
|
184
|
+
}
|
|
185
|
+
if (isBroadcast && payload.providerId) {
|
|
186
|
+
throw new Error('agreement-propose forbids `providerId` on a broadcast — the claiming agent fills the open side.');
|
|
187
|
+
}
|
|
188
|
+
const priced = applyFleetPricingForProtocol('agreement-propose', payload, actingAgentId);
|
|
189
|
+
const { operation: _op, ...fields } = priced;
|
|
190
|
+
return services.agreementService.propose({ ...fields, chatId });
|
|
191
|
+
}
|
|
192
|
+
// ── ZIG-832: deterministic sub-agreement resolution ─────────────────────────
|
|
193
|
+
// The orchestrator delegates one task per worker, but the LLM inconsistently
|
|
194
|
+
// (a) re-subcontracts the same worker (duplicate sub-agreements) and (b)
|
|
195
|
+
// task_spawns a worker under the TOP-LEVEL hire — where the worker is not a
|
|
196
|
+
// party — instead of under that worker's sub-agreement, which the backend
|
|
197
|
+
// rejects with 400 "assignee is not a party". Both are made deterministic here
|
|
198
|
+
// using the chat's existing agreements.
|
|
199
|
+
const TERMINAL_STATUS = new Set(['fulfilled', 'cancelled', 'refunded', 'rejected']);
|
|
200
|
+
async function agreementsInChat(services, chatId) {
|
|
201
|
+
if (!chatId)
|
|
202
|
+
return [];
|
|
203
|
+
try {
|
|
204
|
+
const snap = await services.contextReadClient.snapshot(chatId, { maxMessages: 1 });
|
|
205
|
+
const ags = snap.agreements;
|
|
206
|
+
return Array.isArray(ags) ? ags : [];
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
return [];
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
function agIsProvider(a, agentId) {
|
|
213
|
+
const p = a.parties ?? {};
|
|
214
|
+
return p['provider'] === agentId || p['providerAgent'] === agentId || a['providerId'] === agentId;
|
|
215
|
+
}
|
|
216
|
+
function agIsParty(a, agentId) {
|
|
217
|
+
const p = a.parties ?? {};
|
|
218
|
+
return ['provider', 'providerAgent', 'payer', 'proposedTo', 'creator', 'creatorAgent']
|
|
219
|
+
.some((k) => p[k] === agentId);
|
|
220
|
+
}
|
|
221
|
+
function agActive(a) {
|
|
222
|
+
return !a.status || !TERMINAL_STATUS.has(String(a.status));
|
|
223
|
+
}
|
|
224
|
+
// Spawnable = actually ACTIVE. A freshly-subcontracted sub is `draft` until its
|
|
225
|
+
// counterparty auto-approves; spawning under a draft (or citing an agreement the
|
|
226
|
+
// assignee isn't a party on) 400s and cascades into a bogus worker "connection
|
|
227
|
+
// needed" message. We treat only 'active' as spawnable (ZIG-832).
|
|
228
|
+
function agIsActiveStatus(a) {
|
|
229
|
+
return String(a.status ?? '') === 'active';
|
|
230
|
+
}
|
|
231
|
+
async function subcontractAgreement(services, payload, chatId, _agents, actingAgentId) {
|
|
232
|
+
if (!payload.description || !payload.executorId)
|
|
233
|
+
return null;
|
|
234
|
+
// b1 (ZIG-832): idempotent subcontract — if a non-terminal sub-agreement for
|
|
235
|
+
// this executor already exists under the same parent, reuse it instead of
|
|
236
|
+
// creating a duplicate (which bloats the chain and blocks the fulfill cascade).
|
|
237
|
+
if (chatId) {
|
|
238
|
+
const parent = payload.parentAgreementId;
|
|
239
|
+
const existing = (await agreementsInChat(services, chatId)).find((a) => agActive(a) && agIsProvider(a, payload.executorId) &&
|
|
240
|
+
(!parent || a.parentAgreementId === parent || a.rootAgreementId === parent));
|
|
241
|
+
if (existing?.agreementId)
|
|
242
|
+
return existing;
|
|
243
|
+
}
|
|
244
|
+
const priced = applyFleetPricingForProtocol('agreement-subcontract', payload, actingAgentId);
|
|
245
|
+
const { operation: _op, ...fields } = priced;
|
|
246
|
+
// ZIG-832: a subcontract must carry a working close condition, or it hangs
|
|
247
|
+
// 'active' forever — and because the backend only auto-fulfills a parent hire
|
|
248
|
+
// once every child sub-agreement is terminal (the fulfill cascade), one
|
|
249
|
+
// never-closing child leaves the whole engagement open. Deciding lifecycle is
|
|
250
|
+
// left to the model, which under load (context bloat, competing wakes) emits
|
|
251
|
+
// incomplete terms — e.g. time-bound with no expiresAt and no maxExecutions —
|
|
252
|
+
// that never reach fulfillment. Make the common single-delegated-task case
|
|
253
|
+
// deterministic: if the caller gave neither a real quota nor a real deadline,
|
|
254
|
+
// treat it as one count-bound execution so completing that task closes the
|
|
255
|
+
// sub — which then cascades the parent closed. A genuinely durable subcontract
|
|
256
|
+
// still opts out by setting maxExecutions>1 or a time-bound expiresAt.
|
|
257
|
+
const f = fields;
|
|
258
|
+
// ZIG-858: repair incomplete terms instead of clobbering them. The model
|
|
259
|
+
// often emits a real quota or deadline but gets the envelope wrong — a
|
|
260
|
+
// numeric-string maxExecutions, or a quota/deadline with the lifecycle field
|
|
261
|
+
// missing or mismatched. The old check treated all of those as "no close
|
|
262
|
+
// condition" and forced count-bound/1, silently discarding the stated intent
|
|
263
|
+
// (e.g. maxExecutions=2 → 1, so the sub fulfills one task early and the next
|
|
264
|
+
// spawn under it fails).
|
|
265
|
+
if (typeof f.maxExecutions === 'string' && f.maxExecutions.trim() !== '' && Number.isFinite(Number(f.maxExecutions))) {
|
|
266
|
+
f.maxExecutions = Number(f.maxExecutions);
|
|
267
|
+
}
|
|
268
|
+
const hasQuota = typeof f.maxExecutions === 'number' && f.maxExecutions > 0;
|
|
269
|
+
const hasDeadline = typeof f.expiresAt === 'string' && f.expiresAt.length > 0;
|
|
270
|
+
if (f.lifecycle === 'count-bound' && hasQuota) {
|
|
271
|
+
// coherent as stated
|
|
272
|
+
}
|
|
273
|
+
else if (f.lifecycle === 'time-bound' && hasDeadline) {
|
|
274
|
+
// coherent as stated
|
|
275
|
+
}
|
|
276
|
+
else if (hasQuota) {
|
|
277
|
+
f.lifecycle = 'count-bound'; // quota given, lifecycle missing/mismatched — keep the quota
|
|
278
|
+
}
|
|
279
|
+
else if (hasDeadline) {
|
|
280
|
+
f.lifecycle = 'time-bound'; // deadline given, lifecycle missing/mismatched — keep the deadline
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
// no usable close condition at all — the deterministic single-task default
|
|
284
|
+
f.lifecycle = 'count-bound';
|
|
285
|
+
f.maxExecutions = 1;
|
|
286
|
+
}
|
|
287
|
+
return services.agreementService.delegate({ ...fields, chatId });
|
|
288
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ToolDefinition } from '../../../tools/defineTool.js';
|
|
2
|
+
export declare const agreementProposeTool: ToolDefinition;
|
|
3
|
+
export declare const agreementSubcontractTool: ToolDefinition;
|
|
4
|
+
export declare const agreementRespondTool: ToolDefinition;
|
|
5
|
+
export declare const taskUpdateTool: ToolDefinition;
|
|
6
|
+
export declare const agreementCounterProposalTool: ToolDefinition;
|
|
7
|
+
export declare const agreementCheckProposalTool: ToolDefinition;
|
|
8
|
+
export declare const agreementRevokeTool: ToolDefinition;
|
|
9
|
+
export declare const agreementFulfillTool: ToolDefinition;
|
|
10
|
+
export declare const taskUpdatePlanStepTool: ToolDefinition;
|
|
11
|
+
export declare const taskSpawnTool: ToolDefinition;
|
|
12
|
+
export declare const PROTOCOL_TOOLS: ToolDefinition[];
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { defineTool } from '../../../tools/defineTool.js';
|
|
2
|
+
import { dispatchProtocolOp } from './protocolRunner.js';
|
|
3
|
+
function handlerFor(operation) {
|
|
4
|
+
return async (args, ctx) => {
|
|
5
|
+
const c = ctx;
|
|
6
|
+
if (!c.taskService)
|
|
7
|
+
throw new Error('taskService missing from tool context (expected when running under Agent)');
|
|
8
|
+
if (!c.agreementService)
|
|
9
|
+
throw new Error('agreementService missing from tool context (expected when running under Agent)');
|
|
10
|
+
if (!c.contextReadClient)
|
|
11
|
+
throw new Error('contextReadClient missing from tool context (expected when running under Agent)');
|
|
12
|
+
const result = await dispatchProtocolOp({
|
|
13
|
+
taskService: c.taskService,
|
|
14
|
+
agreementService: c.agreementService,
|
|
15
|
+
contextReadClient: c.contextReadClient,
|
|
16
|
+
}, { operation, ...args }, c.chatId ?? null, c.agents ?? [], typeof c.agentId === 'string' ? c.agentId : null);
|
|
17
|
+
if (result == null)
|
|
18
|
+
throw new Error(`Operation ${operation} returned no result`);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export const agreementProposeTool = defineTool('agreement_propose', { description: { type: 'string', required: true }, proposedTo: { type: 'string', required: true }, engagementKind: { type: 'string', enum: ['hire', 'service'], description: 'Contract type. Defaults to service when omitted.' }, parentAgreementId: 'string', parentTaskId: 'string', providerId: { type: 'string', description: 'Who does the work — required on direct proposals, forbidden on broadcasts (the claiming agent fills the open side). Pass your own id when YOU are offering to do the work, or the proposedTo id when you are commissioning the RECIPIENT. Naming any other third party requires that party to have a matching published offer. The payer is always derived as the non-providing side.' }, price: 'number', lifecycle: 'string', expiresAt: 'string', maxExecutions: 'number', agreementDescription: 'string', plan: { type: 'object' }, planReviewTiming: 'string', requireMidWorkPlanAck: 'boolean' }, handlerFor('agreement-propose'), { description: 'Propose a contract to a user, agent, or as an open broadcast. Direction is stated, never guessed: providerId = your own id ("I work, you pay") or providerId = proposedTo ("you work, I pay"). Required on direct proposals; omit it only for a broadcast — proposedTo="everyone" (fully public — any agent may claim) or proposedTo="org" (scoped to your org). engagementKind defaults to service.', isAgreementCreation: true });
|
|
23
|
+
export const agreementSubcontractTool = defineTool('agreement_subcontract', { description: { type: 'string', required: true }, executorId: { type: 'string', required: true }, parentAgreementId: { type: 'string', required: true }, parentTaskId: 'string', payerId: 'string', price: 'number', lifecycle: 'string', expiresAt: 'string', maxExecutions: 'number', agreementDescription: 'string', plan: { type: 'object' }, planReviewTiming: 'string', requireMidWorkPlanAck: 'boolean' }, handlerFor('agreement-subcontract'), { description: 'Delegate work to another agent under an existing parent agreement. Requires parentAgreementId.', isAgreementCreation: true });
|
|
24
|
+
export const agreementRespondTool = defineTool('agreement_respond', { agreementId: { type: 'string', required: true }, action: { type: 'string', required: true, enum: ['approve', 'reject'] } }, handlerFor('agreement-respond'), { description: 'Approve or reject a pending agreement proposal.' });
|
|
25
|
+
export const taskUpdateTool = defineTool('task_update', { taskId: { type: 'string', required: true }, status: { type: 'string', required: true, enum: ['completed', 'failed', 'cancelled'] }, result: 'string' }, handlerFor('task-update'), { description: 'Transition a task to completed, failed, or cancelled. Include a result string for completed tasks.' });
|
|
26
|
+
export const agreementCounterProposalTool = defineTool('agreement_counter_proposal', { agreementId: { type: 'string', required: true }, price: 'number', agreementDescription: 'string', expiresAt: 'string', lifecycle: 'string', maxExecutions: 'number', description: 'string', plan: { type: 'object' }, planReviewTiming: 'string', requireMidWorkPlanAck: 'boolean' }, handlerFor('agreement-counter-proposal'), { description: 'Counter a pending proposal with revised terms instead of approving or rejecting. Check status first with agreement_check_proposal.' });
|
|
27
|
+
export const agreementCheckProposalTool = defineTool('agreement_check_proposal', { agreementId: { type: 'string', required: true } }, handlerFor('agreement-check-proposal'), { description: 'Read the current proposal status for an agreement (pending, approved, rejected, countered, expired).' });
|
|
28
|
+
export const agreementRevokeTool = defineTool('agreement_revoke', { agreementId: { type: 'string', required: true } }, handlerFor('agreement-revoke'), { description: 'Revoke a pending proposal you created so it can no longer be approved. Use when the user has clearly moved on to a different request before responding to the previous proposal card.' });
|
|
29
|
+
export const agreementFulfillTool = defineTool('agreement_fulfill', { agreementId: { type: 'string', required: true } }, handlerFor('agreement-fulfill'), { description: 'Mark an agreement you provide as fulfilled (complete) once its work is delivered — closes the engagement so it no longer reads as in-progress. Use on your hire after the final deliverable is done and delivered to the human.' });
|
|
30
|
+
export const taskUpdatePlanStepTool = defineTool('task_update_plan_step', { taskId: { type: 'string', required: true }, stepId: { type: 'string', required: true }, status: { type: 'string', required: true }, result: 'string' }, handlerFor('task-update-plan-step'), { description: "Update the status of a single step within a task's plan." });
|
|
31
|
+
export const taskSpawnTool = defineTool('task_spawn', { agreementId: { type: 'string', required: true }, description: { type: 'string', required: true }, parentTaskId: 'string', assigneeId: { type: 'string', description: 'Explicitly hand this task to one specific agent (e.g. a worker your orchestrator selected via agent search) instead of leaving it unassigned. Must be a party on the agreement (payer, provider, creator, or creator agent).' }, inputArtifactIds: { type: 'array', items: { type: 'string' }, description: 'ZIG-734: prior-step output artifact handles for structured input links.' }, plan: { type: 'object' }, planReviewTiming: 'string', requireMidWorkPlanAck: 'boolean' }, handlerFor('task-spawn'), { description: 'Spawn a new task under an existing approved agreement. Use when the contract is already in place. Pass assigneeId to delegate the task to a specific agent rather than leaving it open.' });
|
|
32
|
+
export const PROTOCOL_TOOLS = [
|
|
33
|
+
agreementProposeTool, agreementSubcontractTool,
|
|
34
|
+
agreementRespondTool, agreementCounterProposalTool, agreementCheckProposalTool, agreementRevokeTool,
|
|
35
|
+
agreementFulfillTool,
|
|
36
|
+
taskSpawnTool, taskUpdateTool, taskUpdatePlanStepTool,
|
|
37
|
+
];
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { defineTool } from '../../../tools/defineTool.js';
|
|
2
|
+
import { ZiggsConnectClient } from '../../ziggsconnect/ZiggsConnectClient.js';
|
|
3
|
+
function clientFor(ctx) {
|
|
4
|
+
const operatorKey = ctx?.['operatorKey'];
|
|
5
|
+
if (!operatorKey)
|
|
6
|
+
throw new Error('operatorKey missing from tool context');
|
|
7
|
+
return new ZiggsConnectClient({
|
|
8
|
+
operatorKey,
|
|
9
|
+
actAsAgentId: ctx?.['agentId'] || undefined,
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
function rethrowWithContext(error, prefix) {
|
|
13
|
+
const e = error;
|
|
14
|
+
const wrapped = new Error(`${prefix}: ${e.message}`);
|
|
15
|
+
if (e.status !== undefined)
|
|
16
|
+
wrapped.status = e.status;
|
|
17
|
+
if (e.body !== undefined)
|
|
18
|
+
wrapped.body = e.body;
|
|
19
|
+
wrapped['cause'] = error;
|
|
20
|
+
throw wrapped;
|
|
21
|
+
}
|
|
22
|
+
export const connectionProxyTool = defineTool('connection_proxy', {
|
|
23
|
+
connectionId: { type: 'string', required: true },
|
|
24
|
+
grantId: { type: 'string', required: true },
|
|
25
|
+
action: { type: 'string', required: true },
|
|
26
|
+
payload: { type: 'object' },
|
|
27
|
+
}, async (args, ctx) => {
|
|
28
|
+
if (!args['connectionId'])
|
|
29
|
+
throw new Error('connectionId is required');
|
|
30
|
+
if (!args['grantId'])
|
|
31
|
+
throw new Error('grantId is required');
|
|
32
|
+
if (!args['action'])
|
|
33
|
+
throw new Error('action is required');
|
|
34
|
+
try {
|
|
35
|
+
const result = await clientFor(ctx).proxy({
|
|
36
|
+
connectionId: args['connectionId'],
|
|
37
|
+
grantId: args['grantId'],
|
|
38
|
+
action: args['action'],
|
|
39
|
+
payload: args['payload'],
|
|
40
|
+
});
|
|
41
|
+
return { status: 'ok', result };
|
|
42
|
+
}
|
|
43
|
+
catch (e) {
|
|
44
|
+
rethrowWithContext(e, 'Connection proxy failed');
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
export const connectionListGrantsTool = defineTool('connection_list_grants', { connectionId: { type: 'string', required: true } }, async (args, ctx) => {
|
|
48
|
+
if (!args['connectionId'])
|
|
49
|
+
throw new Error('connectionId is required');
|
|
50
|
+
try {
|
|
51
|
+
const grants = await clientFor(ctx).listGrants({
|
|
52
|
+
connectionId: args['connectionId'],
|
|
53
|
+
});
|
|
54
|
+
return { grants: grants || [] };
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
rethrowWithContext(e, 'Failed to list connection grants');
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
export const CONNECTION_TOOLS = [
|
|
61
|
+
connectionProxyTool,
|
|
62
|
+
connectionListGrantsTool,
|
|
63
|
+
];
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { defineTool } from '../../../tools/defineTool.js';
|
|
2
|
+
import { ZiggsContextClient } from '../../ziggscontext/ZiggsContextClient.js';
|
|
3
|
+
function clientFor(ctx) {
|
|
4
|
+
const operatorKey = ctx?.['operatorKey'];
|
|
5
|
+
if (!operatorKey)
|
|
6
|
+
throw new Error('operatorKey missing from tool context');
|
|
7
|
+
return new ZiggsContextClient({
|
|
8
|
+
operatorKey,
|
|
9
|
+
actAsAgentId: ctx?.['agentId'] || undefined,
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
export const contextDiscoverTool = defineTool('context_discover', {}, async (_args, ctx) => clientFor(ctx).discover(), {
|
|
13
|
+
description: 'List every context grant this agent holds, as scope descriptors — grantId, scope, temporal, watermarkAt, expiresAt (no message or artifact content).',
|
|
14
|
+
});
|
|
15
|
+
export const contextDelegateTool = defineTool('context_delegate', {
|
|
16
|
+
parentGrantId: { type: 'string', required: true },
|
|
17
|
+
holderId: { type: 'string', required: true },
|
|
18
|
+
scopeKind: { type: 'string', required: true },
|
|
19
|
+
scopeId: { type: 'string', required: true },
|
|
20
|
+
temporal: { type: 'string', required: true },
|
|
21
|
+
expiresAt: 'string',
|
|
22
|
+
watermarkAt: 'string',
|
|
23
|
+
}, async (args, ctx) => {
|
|
24
|
+
const temporal = args['temporal'];
|
|
25
|
+
if (temporal !== 'from-now' && temporal !== 'from-start') {
|
|
26
|
+
throw new Error('temporal must be from-now or from-start');
|
|
27
|
+
}
|
|
28
|
+
const scopeKind = args['scopeKind'];
|
|
29
|
+
if (scopeKind !== 'chat' && scopeKind !== 'agreement' && scopeKind !== 'org') {
|
|
30
|
+
throw new Error('scopeKind must be chat, agreement, or org');
|
|
31
|
+
}
|
|
32
|
+
return clientFor(ctx).delegate({
|
|
33
|
+
parentGrantId: args['parentGrantId'],
|
|
34
|
+
holderId: args['holderId'],
|
|
35
|
+
scope: { kind: scopeKind, id: args['scopeId'] },
|
|
36
|
+
temporal,
|
|
37
|
+
expiresAt: args['expiresAt'] ?? undefined,
|
|
38
|
+
watermarkAt: args['watermarkAt'],
|
|
39
|
+
});
|
|
40
|
+
}, {
|
|
41
|
+
description: 'Delegate a narrower child context grant (tighter scope, shorter expiry, or from-now). Holder-only.',
|
|
42
|
+
});
|
|
43
|
+
export const CONTEXT_TOOLS = [
|
|
44
|
+
contextDiscoverTool,
|
|
45
|
+
contextDelegateTool,
|
|
46
|
+
];
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { defineTool } from '../../../tools/defineTool.js';
|
|
2
|
+
import { AgentSearchClient } from '@ziggs-ai/api-client';
|
|
3
|
+
function clientFor(ctx) {
|
|
4
|
+
const operatorKey = ctx?.['operatorKey'];
|
|
5
|
+
const agentId = ctx?.['agentId'];
|
|
6
|
+
if (!operatorKey)
|
|
7
|
+
throw new Error('operatorKey missing from tool context');
|
|
8
|
+
if (!agentId)
|
|
9
|
+
throw new Error('agentId missing from tool context');
|
|
10
|
+
return new AgentSearchClient(operatorKey, agentId);
|
|
11
|
+
}
|
|
12
|
+
export const agentSearchTool = defineTool('agent_search', { query: { type: 'string', required: true }, limit: 'number' }, async (args, ctx) => {
|
|
13
|
+
if (!args['query'])
|
|
14
|
+
throw new Error('query is required');
|
|
15
|
+
const options = {};
|
|
16
|
+
if (typeof args['limit'] === 'number')
|
|
17
|
+
options.limit = args['limit'];
|
|
18
|
+
return clientFor(ctx).searchAgents(args['query'], options);
|
|
19
|
+
}, { description: 'Search for agents by capability, name, or description. Returns ranked results with relevance scores. Use before agreement_propose or agreement_subcontract to discover the right agent for a job.', isGenericFallback: true });
|
|
20
|
+
export const agentGetTool = defineTool('agent_get', { agentId: { type: 'string', required: true } }, async (args, ctx) => {
|
|
21
|
+
if (!args['agentId'])
|
|
22
|
+
throw new Error('agentId is required');
|
|
23
|
+
return clientFor(ctx).getAgentById(args['agentId']);
|
|
24
|
+
}, { description: 'Fetch the full profile of a specific agent by ID. Use to confirm capabilities and terms before proposing an agreement.' });
|
|
25
|
+
export const DISCOVERY_TOOLS = [agentSearchTool, agentGetTool];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { defineTool } from '../../../tools/defineTool.js';
|
|
2
|
+
import { pullQuests } from '@ziggs-ai/api-client';
|
|
3
|
+
// Read-only marketplace access. Publishing an open quest is NOT here: it is the
|
|
4
|
+
// tier-1 protocol verb agreement_propose({ proposedTo: "everyone" | "org" }).
|
|
5
|
+
// This feed already returns only quests the caller may see — org-scoped quests
|
|
6
|
+
// appear here only for members of the quest's org (filtered server-side).
|
|
7
|
+
export const marketplaceViewTool = defineTool('marketplace_view', { limit: 'number', since: 'string' }, async (args, ctx) => {
|
|
8
|
+
const operatorKey = ctx?.['operatorKey'];
|
|
9
|
+
const agentId = ctx?.['agentId'];
|
|
10
|
+
if (!operatorKey)
|
|
11
|
+
throw new Error('operatorKey missing from tool context');
|
|
12
|
+
if (!agentId)
|
|
13
|
+
throw new Error('agentId missing from tool context');
|
|
14
|
+
const options = {
|
|
15
|
+
limit: typeof args['limit'] === 'number' ? args['limit'] : 20,
|
|
16
|
+
};
|
|
17
|
+
if (args['since'])
|
|
18
|
+
options.since = args['since'];
|
|
19
|
+
const quests = await pullQuests(options, { operatorKey, agentId });
|
|
20
|
+
return { quests, count: quests.length };
|
|
21
|
+
}, { description: 'Browse open quests on the marketplace — work buyers have broadcast to willing agents. Returns public quests plus any org-scoped quests in your org. To claim a quest, use agreement_respond on the returned agreementId. To publish your own, use agreement_propose({ proposedTo: "everyone" }) for a public quest or proposedTo: "org" to keep it inside your org.' });
|
|
22
|
+
export const MARKETPLACE_TOOLS = [marketplaceViewTool];
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ToolDefinition } from '../../../tools/defineTool.js';
|
|
2
|
+
export declare const paymentBalanceTool: ToolDefinition;
|
|
3
|
+
export declare const paymentTransferTool: ToolDefinition;
|
|
4
|
+
export declare const paymentWaitForApprovalTool: ToolDefinition;
|
|
5
|
+
export declare const paymentResolveWalletTool: ToolDefinition;
|
|
6
|
+
export declare const paymentHoldTool: ToolDefinition;
|
|
7
|
+
export declare const paymentReleaseTool: ToolDefinition;
|
|
8
|
+
export declare const paymentIssueGrantTool: ToolDefinition;
|
|
9
|
+
export declare const paymentAttenuateGrantTool: ToolDefinition;
|
|
10
|
+
export declare const paymentRevokeGrantTool: ToolDefinition;
|
|
11
|
+
export declare const paymentListGrantsTool: ToolDefinition;
|
|
12
|
+
export declare const PAYMENT_TOOLS: ToolDefinition[];
|