@ziggs-ai/agent-sdk 0.1.9 → 0.1.11
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/package.json +3 -2
- package/src/AgentHost.ts +54 -4
- package/src/adapters/AnthropicAdapter.ts +206 -0
- package/src/adapters/McpAdapter.ts +177 -32
- package/src/adapters/OpenAIAdapter.ts +11 -6
- package/src/adapters/index.ts +1 -0
- package/src/agent/Agent.ts +3 -0
- package/src/defineAgent.ts +13 -5
- package/src/index.ts +4 -1
- package/src/pricing/fleetTierByAgentId.gen.ts +53 -1
- package/src/runtime/AgentMachine.ts +50 -12
- package/src/runtime/PromptBuilder.ts +20 -1
- package/src/runtime/buildOutcome.ts +51 -6
- package/src/runtime/kickoff.ts +117 -0
- package/src/runtime/runTurn.ts +173 -56
- package/src/runtime/validateWorkflow.ts +26 -5
- package/src/server/ConnectionPool.ts +56 -5
- package/src/server/StateTimers.ts +85 -0
- package/src/server/ZiggsEffectHandler.ts +10 -1
- package/src/server/tasks/TaskService.ts +13 -2
- package/src/server/tools/index.ts +1 -1
- package/src/server/tools/tier1/protocolRunner.ts +10 -1
- package/src/server/tools/tier1/protocolTools.ts +1 -1
- package/src/server/tools/tier2/paymentTools.ts +2 -25
- package/src/types.ts +56 -7
|
@@ -32,6 +32,7 @@ interface ProtocolPayload {
|
|
|
32
32
|
parentAgreementId?: string;
|
|
33
33
|
parentTaskId?: string;
|
|
34
34
|
taskId?: string;
|
|
35
|
+
stepId?: string;
|
|
35
36
|
assigneeId?: string;
|
|
36
37
|
status?: string;
|
|
37
38
|
result?: unknown;
|
|
@@ -97,12 +98,20 @@ export async function dispatchProtocolOp(
|
|
|
97
98
|
planReviewTiming: payload.planReviewTiming,
|
|
98
99
|
requireMidWorkPlanAck: payload.requireMidWorkPlanAck,
|
|
99
100
|
assigneeId: payload.assigneeId,
|
|
101
|
+
inputArtifactIds: Array.isArray(payload.inputArtifactIds)
|
|
102
|
+
? (payload.inputArtifactIds as string[])
|
|
103
|
+
: undefined,
|
|
100
104
|
});
|
|
101
105
|
case 'task-update':
|
|
102
106
|
if (!payload.taskId || !payload.status) return null;
|
|
103
107
|
return taskService.updateState(payload.taskId, normalizeState(payload.status) as Parameters<typeof taskService.updateState>[1], payload.result);
|
|
108
|
+
case 'task-update-plan-step':
|
|
109
|
+
if (!payload.taskId) throw new Error('task-update-plan-step requires `taskId`');
|
|
110
|
+
if (!payload.stepId) throw new Error('task-update-plan-step requires `stepId`');
|
|
111
|
+
if (!payload.status) throw new Error('task-update-plan-step requires `status`');
|
|
112
|
+
return taskService.updatePlanStep(payload.taskId, payload.stepId, payload.status, payload.result);
|
|
104
113
|
default:
|
|
105
|
-
|
|
114
|
+
throw new Error(`Unknown protocol operation: ${operation}`);
|
|
106
115
|
}
|
|
107
116
|
}
|
|
108
117
|
|
|
@@ -87,7 +87,7 @@ export const taskUpdatePlanStepTool: ToolDefinition = defineTool(
|
|
|
87
87
|
|
|
88
88
|
export const taskSpawnTool: ToolDefinition = defineTool(
|
|
89
89
|
'task_spawn',
|
|
90
|
-
{ 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).' }, plan: { type: 'object' }, planReviewTiming: 'string', requireMidWorkPlanAck: 'boolean' },
|
|
90
|
+
{ 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' },
|
|
91
91
|
handlerFor('task-spawn'),
|
|
92
92
|
{ 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.' },
|
|
93
93
|
);
|
|
@@ -121,14 +121,8 @@ export const paymentIssueGrantTool: ToolDefinition = defineTool('payment_issue_g
|
|
|
121
121
|
issueGrantHandler,
|
|
122
122
|
);
|
|
123
123
|
|
|
124
|
-
/** @deprecated Use payment_issue_grant */
|
|
125
|
-
export const paymentIssueTokenTool: ToolDefinition = defineTool('payment_issue_token',
|
|
126
|
-
{ holderId: { type: 'string', required: true }, maxAmount: 'number', dailyBudget: 'number', allowedRecipients: ['string'], expiresInSeconds: 'number' },
|
|
127
|
-
issueGrantHandler,
|
|
128
|
-
);
|
|
129
|
-
|
|
130
124
|
const attenuateGrantHandler = async (args: AnyObj, ctx: Ctx) => {
|
|
131
|
-
const grantId =
|
|
125
|
+
const grantId = args['grantId'] as string;
|
|
132
126
|
if (!grantId) throw new Error('grantId is required');
|
|
133
127
|
if (!args['holderId']) throw new Error('holderId is required');
|
|
134
128
|
try {
|
|
@@ -144,14 +138,8 @@ export const paymentAttenuateGrantTool: ToolDefinition = defineTool('payment_att
|
|
|
144
138
|
attenuateGrantHandler,
|
|
145
139
|
);
|
|
146
140
|
|
|
147
|
-
/** @deprecated Use payment_attenuate_grant */
|
|
148
|
-
export const paymentAttenuateTokenTool: ToolDefinition = defineTool('payment_attenuate_token',
|
|
149
|
-
{ tokenId: { type: 'string', required: true }, holderId: { type: 'string', required: true }, maxAmount: 'number', dailyBudget: 'number', allowedRecipients: ['string'], expiresInSeconds: 'number' },
|
|
150
|
-
attenuateGrantHandler,
|
|
151
|
-
);
|
|
152
|
-
|
|
153
141
|
const revokeGrantHandler = async (args: AnyObj, ctx: Ctx) => {
|
|
154
|
-
const grantId =
|
|
142
|
+
const grantId = args['grantId'] as string;
|
|
155
143
|
if (!grantId) throw new Error('grantId is required');
|
|
156
144
|
try {
|
|
157
145
|
const result = await clientFor(ctx).revokeGrant(grantId) as AnyObj;
|
|
@@ -164,12 +152,6 @@ export const paymentRevokeGrantTool: ToolDefinition = defineTool('payment_revoke
|
|
|
164
152
|
revokeGrantHandler,
|
|
165
153
|
);
|
|
166
154
|
|
|
167
|
-
/** @deprecated Use payment_revoke_grant */
|
|
168
|
-
export const paymentRevokeTokenTool: ToolDefinition = defineTool('payment_revoke_token',
|
|
169
|
-
{ tokenId: { type: 'string', required: true } },
|
|
170
|
-
revokeGrantHandler,
|
|
171
|
-
);
|
|
172
|
-
|
|
173
155
|
const listGrantsHandler = async (_args: AnyObj, ctx: Ctx) => {
|
|
174
156
|
try {
|
|
175
157
|
const result = await clientFor(ctx).listGrants();
|
|
@@ -181,11 +163,6 @@ export const paymentListGrantsTool: ToolDefinition = defineTool('payment_list_gr
|
|
|
181
163
|
listGrantsHandler,
|
|
182
164
|
);
|
|
183
165
|
|
|
184
|
-
/** @deprecated Use payment_list_grants */
|
|
185
|
-
export const paymentListTokensTool: ToolDefinition = defineTool('payment_list_tokens', {},
|
|
186
|
-
listGrantsHandler,
|
|
187
|
-
);
|
|
188
|
-
|
|
189
166
|
export const PAYMENT_TOOLS: ToolDefinition[] = [
|
|
190
167
|
paymentBalanceTool, paymentTransferTool, paymentWaitForApprovalTool,
|
|
191
168
|
paymentHoldTool, paymentReleaseTool, paymentResolveWalletTool,
|
package/src/types.ts
CHANGED
|
@@ -26,6 +26,10 @@ export interface TaskRef {
|
|
|
26
26
|
state?: string;
|
|
27
27
|
description?: string;
|
|
28
28
|
parentTaskId?: string;
|
|
29
|
+
executorId?: string;
|
|
30
|
+
assigneeId?: string | null;
|
|
31
|
+
/** Work product set by task_update (safeJsonStringify'd string on the wire). */
|
|
32
|
+
result?: unknown;
|
|
29
33
|
proposal?: { status?: 'pending' | 'approved' | 'rejected' | 'cancelled' };
|
|
30
34
|
proposedToIsYou?: boolean;
|
|
31
35
|
providerIsYou?: boolean;
|
|
@@ -43,7 +47,7 @@ export interface ProposalRef {
|
|
|
43
47
|
export type OutcomeKind =
|
|
44
48
|
| 'enter'
|
|
45
49
|
| 'wait'
|
|
46
|
-
| 'timeout'
|
|
50
|
+
| 'state-timeout'
|
|
47
51
|
| 'message-sent'
|
|
48
52
|
| 'message-received'
|
|
49
53
|
| 'task-assigned'
|
|
@@ -59,7 +63,7 @@ export type OutcomeKind =
|
|
|
59
63
|
export type Outcome =
|
|
60
64
|
| { kind: 'enter' }
|
|
61
65
|
| { kind: 'wait' }
|
|
62
|
-
| { kind: 'timeout' }
|
|
66
|
+
| { kind: 'state-timeout'; state: string; waitedMs: number }
|
|
63
67
|
| { kind: 'message-sent'; text?: string; receiverId?: string }
|
|
64
68
|
| { kind: 'message-received'; text?: string; senderId?: string; senderType?: string }
|
|
65
69
|
| { kind: 'task-assigned'; task: TaskRef }
|
|
@@ -67,7 +71,20 @@ export type Outcome =
|
|
|
67
71
|
| { kind: 'task-closed'; status: 'completed' | 'failed'; result?: unknown }
|
|
68
72
|
| { kind: 'subtask-finished'; status: 'completed' | 'failed'; task: TaskRef; result?: unknown }
|
|
69
73
|
| { kind: 'proposal-made'; proposal: ProposalRef }
|
|
70
|
-
| {
|
|
74
|
+
| {
|
|
75
|
+
kind: 'proposal-resolved';
|
|
76
|
+
action: 'approve' | 'reject';
|
|
77
|
+
proposal: ProposalRef;
|
|
78
|
+
/**
|
|
79
|
+
* True when THIS agent made the proposal being resolved. Computed in
|
|
80
|
+
* AgentMachine._handleFrame by matching proposal.agreementId against
|
|
81
|
+
* ctx.pendingProposalAgreementId BEFORE applyOutcomeToCtx clears it —
|
|
82
|
+
* wire frames carry no trustworthy proposer field (agreement_lifecycle
|
|
83
|
+
* drops `parties` at ingress, and parties.creator is a principal id,
|
|
84
|
+
* not an agentId). Drives the injected agreement-kickoff default.
|
|
85
|
+
*/
|
|
86
|
+
proposedByMe: boolean;
|
|
87
|
+
}
|
|
71
88
|
| { kind: 'tool-result'; tool: string; result: unknown }
|
|
72
89
|
| {
|
|
73
90
|
kind: 'error';
|
|
@@ -109,11 +126,26 @@ export interface ToolResultEntry {
|
|
|
109
126
|
error?: string;
|
|
110
127
|
}
|
|
111
128
|
|
|
129
|
+
export interface PendingSubtask {
|
|
130
|
+
/** Executor the task was placed with; null only when the spawn result carried
|
|
131
|
+
* no executor identity (open/broadcast agreement task not yet claimed). */
|
|
132
|
+
agentId: string | null;
|
|
133
|
+
spawnedAt: number;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export interface CollectedSubtaskResult {
|
|
137
|
+
taskId: string;
|
|
138
|
+
agentId: string | null;
|
|
139
|
+
status: 'completed' | 'failed';
|
|
140
|
+
/** task.result from the finishing event; null when the event carried none. */
|
|
141
|
+
result: unknown;
|
|
142
|
+
}
|
|
143
|
+
|
|
112
144
|
/**
|
|
113
145
|
* Per-lane runtime state. Outcome is "what just happened"; Ctx is "what I know."
|
|
114
146
|
*
|
|
115
147
|
* Persistent identifiers (activeAgreementId, pendingProposalAgreementId,
|
|
116
|
-
*
|
|
148
|
+
* pendingSubtasks) survive across outcomes — they're the memory of which
|
|
117
149
|
* agreement the agent is currently bound to and which subtasks it's awaiting.
|
|
118
150
|
*/
|
|
119
151
|
export interface Ctx {
|
|
@@ -124,7 +156,10 @@ export interface Ctx {
|
|
|
124
156
|
activeTaskId: string | null;
|
|
125
157
|
pendingProposalAgreementId: string | null;
|
|
126
158
|
delegatedAgreementIds: string[];
|
|
127
|
-
|
|
159
|
+
/** Durable barrier for orchestration: every spawned-but-unfinished subtask, keyed by taskId. */
|
|
160
|
+
pendingSubtasks: Record<string, PendingSubtask>;
|
|
161
|
+
/** Every finished subtask of the current engagement, arrival order. Synthesis prompts render ALL of these. */
|
|
162
|
+
collectedResults: CollectedSubtaskResult[];
|
|
128
163
|
|
|
129
164
|
// Per-turn working memory
|
|
130
165
|
toolResults: ToolResultEntry[];
|
|
@@ -182,6 +217,17 @@ export interface Transition {
|
|
|
182
217
|
|
|
183
218
|
export interface ParkedState {
|
|
184
219
|
kind: 'parked';
|
|
220
|
+
/**
|
|
221
|
+
* Liveness timer. When the machine settles in this state and no event
|
|
222
|
+
* arrives on the lane within timeoutMs, the host wakes the lane with a
|
|
223
|
+
* { kind: 'state-timeout', state, waitedMs } outcome so a transition can
|
|
224
|
+
* route to a recovery/nudge state. If no transition matches, the machine
|
|
225
|
+
* parks loudly (runtimeLog.error) and the timer is NOT re-armed. Countdown
|
|
226
|
+
* starts when the tick settles and resets on any event for the lane.
|
|
227
|
+
* In-memory only: lost on process restart; re-armed by the next real event
|
|
228
|
+
* that ticks the lane.
|
|
229
|
+
*/
|
|
230
|
+
timeoutMs?: number;
|
|
185
231
|
transitions: Transition[];
|
|
186
232
|
}
|
|
187
233
|
|
|
@@ -389,11 +435,14 @@ export interface DefineAgentInput {
|
|
|
389
435
|
|
|
390
436
|
/**
|
|
391
437
|
* Frozen output of defineAgent. Consumed directly by AgentHost / createAgent.
|
|
392
|
-
*
|
|
393
|
-
*
|
|
438
|
+
* defineAgent injects ONE default: the agreement-kickoff state `kickingOff`
|
|
439
|
+
* plus a last-position transition into it, added to states that don't already
|
|
440
|
+
* handle a proposer-side proposal-resolved/approve outcome (runtime/kickoff.ts).
|
|
441
|
+
* `wait` defaults remain the author's visible spread of `thinkingDefaults`.
|
|
394
442
|
*/
|
|
395
443
|
export interface AgentConfig {
|
|
396
444
|
openaiKey: string | undefined;
|
|
445
|
+
anthropicKey: string | undefined;
|
|
397
446
|
operatorKey?: string;
|
|
398
447
|
agentId: string;
|
|
399
448
|
description: string;
|