@ziggs-ai/agent-sdk 0.2.1 → 0.2.2
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/dist/AgentHost.d.ts +9 -0
- package/dist/AgentHost.js +2 -0
- package/dist/adapters/McpAdapter.js +14 -13
- package/dist/agent/ClaudeSdkAgent.d.ts +5 -0
- package/dist/agent/ClaudeSdkAgent.js +12 -2
- package/dist/agent/claudeCognition.d.ts +7 -0
- package/dist/agent/claudeCognition.js +38 -7
- package/dist/agent/claudeSdkTools.js +17 -2
- package/dist/index.d.ts +2 -5
- package/dist/index.js +10 -4
- package/dist/server/tools/index.d.ts +7 -3
- package/dist/server/tools/index.js +13 -3
- package/dist/server/tools/tier2/artifactTools.d.ts +3 -0
- package/dist/server/tools/tier2/artifactTools.js +82 -0
- package/dist/server/tools/tier2/chatTools.d.ts +3 -0
- package/dist/server/tools/tier2/chatTools.js +37 -0
- package/dist/server/tools/tier2/connectionTools.d.ts +1 -0
- package/dist/server/tools/tier2/connectionTools.js +52 -5
- package/dist/server/tools/tier2/contextTools.d.ts +4 -2
- package/dist/server/tools/tier2/contextTools.js +105 -12
- package/dist/server/tools/tier2/grantsTools.d.ts +3 -0
- package/dist/server/tools/tier2/grantsTools.js +81 -0
- package/dist/server/tools/tier2/linkTools.d.ts +7 -0
- package/dist/server/tools/tier2/linkTools.js +156 -0
- package/dist/server/tools/tier2/paymentTools.d.ts +0 -1
- package/dist/server/tools/tier2/paymentTools.js +9 -13
- package/package.json +2 -2
- package/dist/server/ziggsconnect/ZiggsConnectClient.d.ts +0 -35
- package/dist/server/ziggsconnect/ZiggsConnectClient.js +0 -95
- package/dist/server/ziggscontext/ZiggsContextClient.d.ts +0 -53
- package/dist/server/ziggscontext/ZiggsContextClient.js +0 -124
- package/dist/server/ziggspay/ZiggsPayClient.d.ts +0 -82
- package/dist/server/ziggspay/ZiggsPayClient.js +0 -203
package/dist/AgentHost.d.ts
CHANGED
|
@@ -75,6 +75,15 @@ export interface AgentHostOptions {
|
|
|
75
75
|
cognition?: CognitionKind;
|
|
76
76
|
/** Max agentic turns per Claude SDK wake. Default 30. */
|
|
77
77
|
claudeMaxTurns?: number;
|
|
78
|
+
/**
|
|
79
|
+
* ZIG-860: claude-sdk agents resume their transcript across wakes by default,
|
|
80
|
+
* so per-wake input grows monotonically on a long lane. When true, each wake
|
|
81
|
+
* starts a fresh Claude session — the protocol is backend-authoritative (the
|
|
82
|
+
* brain re-reads via ziggs_context_snapshot / the wake event), so the
|
|
83
|
+
* transcript is convenience memory, not source of truth. Ideal for
|
|
84
|
+
* step-driven orchestrators whose every wake already carries what it needs.
|
|
85
|
+
*/
|
|
86
|
+
claudeStatelessPerWake?: boolean;
|
|
78
87
|
services?: AgentServices;
|
|
79
88
|
workflow?: Workflow;
|
|
80
89
|
states?: Workflow['states'];
|
package/dist/AgentHost.js
CHANGED
|
@@ -144,6 +144,7 @@ export class AgentHost {
|
|
|
144
144
|
brain: resolved.brain,
|
|
145
145
|
cognition: resolved.cognition ?? 'fsm',
|
|
146
146
|
claudeMaxTurns: resolved.claudeMaxTurns,
|
|
147
|
+
claudeStatelessPerWake: resolved.claudeStatelessPerWake,
|
|
147
148
|
};
|
|
148
149
|
this.inboxCatchUpEnabled = options.inboxCatchUp !== false;
|
|
149
150
|
this.sessionResolver = options.sessionResolver || DEFAULT_SESSION_RESOLVER;
|
|
@@ -247,6 +248,7 @@ export class AgentHost {
|
|
|
247
248
|
// eff({ kind: 'tool-call' }) → the shared executor, which sources those
|
|
248
249
|
// services from the effect handler's deps like the FSM path (ZIG-775).
|
|
249
250
|
maxTurns: this.options.claudeMaxTurns,
|
|
251
|
+
statelessPerWake: this.options.claudeStatelessPerWake,
|
|
250
252
|
})
|
|
251
253
|
: new Agent({
|
|
252
254
|
workflow,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
2
2
|
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
3
3
|
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
4
|
+
import { ConnectionsClient } from '@ziggs-ai/api-client';
|
|
4
5
|
import { AgentHost } from '../AgentHost.js';
|
|
5
6
|
import { thinkingDefaults } from '../runtime/defaults.js';
|
|
6
7
|
/**
|
|
@@ -368,21 +369,21 @@ export async function createMcpAgent(options) {
|
|
|
368
369
|
if (!transportConfig.serverUrl)
|
|
369
370
|
return null;
|
|
370
371
|
const operatorKey = transportConfig.operatorKey || process.env.ZIGGS_OPERATOR_KEY;
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
authorization: `Bearer ${operatorKey}`,
|
|
376
|
-
'x-agent-id': agentId,
|
|
377
|
-
'x-on-behalf-of-user': userId,
|
|
378
|
-
},
|
|
379
|
-
body: JSON.stringify({
|
|
372
|
+
if (!operatorKey)
|
|
373
|
+
return null;
|
|
374
|
+
try {
|
|
375
|
+
const body = await new ConnectionsClient(operatorKey, agentId, backendBase).requestMcpConnection({
|
|
380
376
|
serverUrl: transportConfig.serverUrl,
|
|
381
377
|
tools: tools.map(t => t.name),
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
378
|
+
onBehalfOfUserId: userId,
|
|
379
|
+
});
|
|
380
|
+
return (body?.request?.requestId) ?? null;
|
|
381
|
+
}
|
|
382
|
+
catch {
|
|
383
|
+
// Best-effort: the backend dedups pending requests and the caller falls
|
|
384
|
+
// back to a plain Connections-page link when there's no requestId.
|
|
385
|
+
return null;
|
|
386
|
+
}
|
|
386
387
|
};
|
|
387
388
|
const caller = async (name, args, context) => {
|
|
388
389
|
const userId = typeof context.senderId === 'string' ? context.senderId : undefined;
|
|
@@ -13,6 +13,10 @@ export interface ClaudeSdkAgentOptions {
|
|
|
13
13
|
operatorKey: string;
|
|
14
14
|
agentId: string;
|
|
15
15
|
maxTurns?: number;
|
|
16
|
+
/** ZIG-860: when true, never resume the prior Claude session — each wake is a
|
|
17
|
+
* fresh transcript. Keeps per-wake input flat on step-driven orchestrators
|
|
18
|
+
* whose wakes already carry their state. */
|
|
19
|
+
statelessPerWake?: boolean;
|
|
16
20
|
/** Injectable for tests. Defaults to @anthropic-ai/claude-agent-sdk query(). */
|
|
17
21
|
queryFn?: typeof query;
|
|
18
22
|
}
|
|
@@ -32,6 +36,7 @@ export declare class ClaudeSdkAgent {
|
|
|
32
36
|
private operatorKey;
|
|
33
37
|
private agentId;
|
|
34
38
|
private maxTurns;
|
|
39
|
+
private statelessPerWake;
|
|
35
40
|
private queryFn;
|
|
36
41
|
constructor(opts: ClaudeSdkAgentOptions);
|
|
37
42
|
tick({ event, ctx, state, identity, eff }: TickInput): Promise<TickOutput>;
|
|
@@ -141,6 +141,7 @@ export class ClaudeSdkAgent {
|
|
|
141
141
|
operatorKey;
|
|
142
142
|
agentId;
|
|
143
143
|
maxTurns;
|
|
144
|
+
statelessPerWake;
|
|
144
145
|
queryFn;
|
|
145
146
|
constructor(opts) {
|
|
146
147
|
if (!opts.workflow?.states)
|
|
@@ -158,6 +159,7 @@ export class ClaudeSdkAgent {
|
|
|
158
159
|
this.operatorKey = opts.operatorKey;
|
|
159
160
|
this.agentId = opts.agentId;
|
|
160
161
|
this.maxTurns = opts.maxTurns ?? DEFAULT_MAX_TURNS;
|
|
162
|
+
this.statelessPerWake = opts.statelessPerWake ?? false;
|
|
161
163
|
this.queryFn = opts.queryFn ?? query;
|
|
162
164
|
}
|
|
163
165
|
async tick({ event, ctx, state, identity, eff }) {
|
|
@@ -248,7 +250,10 @@ export class ClaudeSdkAgent {
|
|
|
248
250
|
if (line)
|
|
249
251
|
runtimeLog.warn('ClaudeSdkAgent', `stderr session=${identity.sessionId}: ${line}`);
|
|
250
252
|
},
|
|
251
|
-
|
|
253
|
+
// ZIG-860: stateless-per-wake never resumes — each wake is a fresh
|
|
254
|
+
// transcript, so per-wake input stays flat instead of replaying the
|
|
255
|
+
// whole lane history every turn.
|
|
256
|
+
resume: this.statelessPerWake ? undefined : nextCtx.claudeSessionId,
|
|
252
257
|
});
|
|
253
258
|
let metrics = { llmCalls: 0, tokens: { total: 0, input: 0, output: 0, cacheRead: 0, cacheCreation: 0 } };
|
|
254
259
|
let sessionId = nextCtx.claudeSessionId;
|
|
@@ -298,7 +303,12 @@ export class ClaudeSdkAgent {
|
|
|
298
303
|
runtimeLog.warn('ClaudeSdkAgent', `query failed session=${identity.sessionId}: ${err.message}`);
|
|
299
304
|
throw err;
|
|
300
305
|
}
|
|
301
|
-
|
|
306
|
+
// Stateless-per-wake keeps no session id — clear any carried over from the
|
|
307
|
+
// prior ctx so the next wake starts fresh too (ZIG-860). Otherwise remember
|
|
308
|
+
// this wake's session for resume.
|
|
309
|
+
if (this.statelessPerWake)
|
|
310
|
+
nextCtx.claudeSessionId = undefined;
|
|
311
|
+
else if (sessionId)
|
|
302
312
|
nextCtx.claudeSessionId = sessionId;
|
|
303
313
|
// ZIG-816: bound resumed-transcript growth. `metrics.tokens.input` is the
|
|
304
314
|
// wake's billable input off the result message (dominated by the resumed
|
|
@@ -63,5 +63,12 @@ export declare function summarizeContext(snap: Record<string, unknown> | null |
|
|
|
63
63
|
* Turn a Ziggs wake event + context digest into the user prompt that starts a
|
|
64
64
|
* Claude-brain turn. The agent's standing instructions come from its system
|
|
65
65
|
* prompt (protocol + role); this is just "here's what woke you, go handle it."
|
|
66
|
+
*
|
|
67
|
+
* ZIG-880: EventQueue coalesces events that arrive while the lane is busy into
|
|
68
|
+
* a `{type:'batch', events:[...]}` frame. The FSM path unwraps those
|
|
69
|
+
* (PromptBuilder), but this path used to render just "Event type: batch" —
|
|
70
|
+
* every payload inside (including task results) was invisible to the model,
|
|
71
|
+
* stalling delegation pipelines whose notifications share one chat lane.
|
|
72
|
+
* Render each batched event in order instead.
|
|
66
73
|
*/
|
|
67
74
|
export declare function buildClaudeEventPrompt(event: RawEvent | undefined, contextSummary: string): string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getBatchEvents } from '../context/batch.js';
|
|
1
2
|
const DEFAULT_CLAUDE_MODEL = 'claude-sonnet-4-6';
|
|
2
3
|
/**
|
|
3
4
|
* Pick the Claude model for a Claude-brain wake. The brain must run a `claude-*`
|
|
@@ -67,13 +68,8 @@ export function summarizeContext(snap) {
|
|
|
67
68
|
const users = Array.isArray(snap.users) ? snap.users.length : 0;
|
|
68
69
|
return `history=${history} messages, agreements=${agreements}, users=${users}`;
|
|
69
70
|
}
|
|
70
|
-
/**
|
|
71
|
-
|
|
72
|
-
* Claude-brain turn. The agent's standing instructions come from its system
|
|
73
|
-
* prompt (protocol + role); this is just "here's what woke you, go handle it."
|
|
74
|
-
*/
|
|
75
|
-
export function buildClaudeEventPrompt(event, contextSummary) {
|
|
76
|
-
const lines = ['You received a new Ziggs event. Handle it per your protocol.'];
|
|
71
|
+
/** Render ONE event's fields into prompt lines (shared by single and batch frames). */
|
|
72
|
+
function renderEventLines(event, lines) {
|
|
77
73
|
if (event?.type)
|
|
78
74
|
lines.push(`Event type: ${event.type}`);
|
|
79
75
|
if (event?.text)
|
|
@@ -94,6 +90,41 @@ export function buildClaudeEventPrompt(event, contextSummary) {
|
|
|
94
90
|
lines.push(`Agreement: ${result.agreementId}`);
|
|
95
91
|
if (typeof result.state === 'string')
|
|
96
92
|
lines.push(`Task state: ${result.state}`);
|
|
93
|
+
// ZIG-860: surface the task's RESULT payload too. Completion notifies now
|
|
94
|
+
// pin it (backend), and an orchestrator consuming a worker's output has no
|
|
95
|
+
// task-read tool — without this line the step outcome never reaches the
|
|
96
|
+
// model and a chained pipeline stalls right after its first task.
|
|
97
|
+
if (result.result != null) {
|
|
98
|
+
const payload = typeof result.result === 'string' ? result.result : JSON.stringify(result.result);
|
|
99
|
+
const MAX = 12_000;
|
|
100
|
+
lines.push(`Task result: ${payload.length > MAX ? `${payload.slice(0, MAX)} …[truncated ${payload.length - MAX} chars]` : payload}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Turn a Ziggs wake event + context digest into the user prompt that starts a
|
|
106
|
+
* Claude-brain turn. The agent's standing instructions come from its system
|
|
107
|
+
* prompt (protocol + role); this is just "here's what woke you, go handle it."
|
|
108
|
+
*
|
|
109
|
+
* ZIG-880: EventQueue coalesces events that arrive while the lane is busy into
|
|
110
|
+
* a `{type:'batch', events:[...]}` frame. The FSM path unwraps those
|
|
111
|
+
* (PromptBuilder), but this path used to render just "Event type: batch" —
|
|
112
|
+
* every payload inside (including task results) was invisible to the model,
|
|
113
|
+
* stalling delegation pipelines whose notifications share one chat lane.
|
|
114
|
+
* Render each batched event in order instead.
|
|
115
|
+
*/
|
|
116
|
+
export function buildClaudeEventPrompt(event, contextSummary) {
|
|
117
|
+
const lines = ['You received a new Ziggs event. Handle it per your protocol.'];
|
|
118
|
+
const batched = getBatchEvents(event);
|
|
119
|
+
if (event && batched.length > 1) {
|
|
120
|
+
lines.push(`This wake carries ${batched.length} coalesced events (oldest first). Handle them together — act once per distinct piece of work, not once per notification.`);
|
|
121
|
+
batched.forEach((e, i) => {
|
|
122
|
+
lines.push('', `— Event ${i + 1} of ${batched.length} —`);
|
|
123
|
+
renderEventLines(e, lines);
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
renderEventLines(event, lines);
|
|
97
128
|
}
|
|
98
129
|
if (contextSummary) {
|
|
99
130
|
lines.push('', 'Session context snapshot:', contextSummary);
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { defineTool } from '../tools/defineTool.js';
|
|
3
|
+
import { listGrantsTool } from '../server/tools/tier2/grantsTools.js';
|
|
4
|
+
// ZIG-860: default message-history cap. An uncapped snapshot returns the whole
|
|
5
|
+
// chat — in a delegation chat that accumulates notification rows, every wake's
|
|
6
|
+
// snapshot ballooned (observed 35–47k input tokens/wake, ~205k/run). 12 recent
|
|
7
|
+
// messages cover "what woke me and what was just said"; the model can pass a
|
|
8
|
+
// larger maxMessages explicitly when it genuinely needs deeper history.
|
|
9
|
+
const DEFAULT_SNAPSHOT_MAX_MESSAGES = 12;
|
|
3
10
|
// Named distinctly from ziggs-mcp's per-type `ziggs_read_context`: this is the
|
|
4
11
|
// one-shot aggregate snapshot (grant-fenced server-side), not a cursored read.
|
|
5
12
|
export const ziggsContextSnapshotTool = defineTool('ziggs_context_snapshot', {
|
|
6
13
|
chatId: { type: 'string', description: 'Chat/session id. Defaults to the current lane session.' },
|
|
7
|
-
maxMessages: { type: 'number', description:
|
|
14
|
+
maxMessages: { type: 'number', description: `Message history cap (default ${DEFAULT_SNAPSHOT_MAX_MESSAGES}). Pass a larger value when you need deeper history.` },
|
|
8
15
|
}, async (args, ctx) => {
|
|
9
16
|
const c = ctx;
|
|
10
17
|
if (!c.eff)
|
|
@@ -15,7 +22,9 @@ export const ziggsContextSnapshotTool = defineTool('ziggs_context_snapshot', {
|
|
|
15
22
|
return c.eff({
|
|
16
23
|
kind: 'read-context',
|
|
17
24
|
sessionId,
|
|
18
|
-
opts:
|
|
25
|
+
opts: {
|
|
26
|
+
maxMessages: args.maxMessages != null ? Number(args.maxMessages) : DEFAULT_SNAPSHOT_MAX_MESSAGES,
|
|
27
|
+
},
|
|
19
28
|
});
|
|
20
29
|
}, { description: 'Read the chat snapshot: history, agreements, agents, and users for a session.' });
|
|
21
30
|
export const ziggsSendMessageTool = defineTool('ziggs_send_message', {
|
|
@@ -51,7 +60,13 @@ export const ziggsSendMessageTool = defineTool('ziggs_send_message', {
|
|
|
51
60
|
// Inbox read/ack are deliberately NOT here: the host owns the pull/watermark
|
|
52
61
|
// cycle (InboxCatchUp on connect). A brain-side ack raced the host's and the
|
|
53
62
|
// mandatory per-wake inbox poll fed the tool-operation echo loop (ZIG-759).
|
|
63
|
+
//
|
|
64
|
+
// list_grants IS here (ZIG-893): the hosted agent must always be able to answer
|
|
65
|
+
// "what grants of mine do you hold?" across every rail — the 2026-07-20 incident
|
|
66
|
+
// was a hosted agent with no grant-read tool telling its principal that lookup
|
|
67
|
+
// doesn't exist. It reads operatorKey/agentId straight off the tool context.
|
|
54
68
|
export const CLAUDE_SDK_TOOLS = [
|
|
55
69
|
ziggsContextSnapshotTool,
|
|
56
70
|
ziggsSendMessageTool,
|
|
71
|
+
listGrantsTool,
|
|
57
72
|
];
|
package/dist/index.d.ts
CHANGED
|
@@ -51,11 +51,8 @@ export { OpenAIAdapter } from './adapters/OpenAIAdapter.js';
|
|
|
51
51
|
export { extractJSON, safeParseJSON } from './utils/jsonExtractor.js';
|
|
52
52
|
export { HistoryFormatter, historyFormatter, AgreementFormatter, agreementFormatter } from './formatters/index.js';
|
|
53
53
|
export { ProactiveTrigger } from './server/proactive/ProactiveTrigger.js';
|
|
54
|
-
export {
|
|
55
|
-
export {
|
|
56
|
-
export { ZiggsContextClient } from './server/ziggscontext/ZiggsContextClient.js';
|
|
57
|
-
export type { ZiggsContextClientOptions, ContextReachDescriptor, DelegateContextGrantParams, } from './server/ziggscontext/ZiggsContextClient.js';
|
|
58
|
-
export { PROTOCOL_TOOLS, agreementProposeTool, agreementSubcontractTool, agreementRespondTool, agreementCounterProposalTool, agreementCheckProposalTool, taskSpawnTool, taskUpdateTool, taskUpdatePlanStepTool, dispatchProtocolOp, PAYMENT_TOOLS, paymentBalanceTool, paymentTransferTool, paymentHoldTool, paymentReleaseTool, paymentResolveWalletTool, CONNECTION_TOOLS, connectionProxyTool, connectionListGrantsTool, DISCOVERY_TOOLS, agentSearchTool, agentGetTool, MARKETPLACE_TOOLS, marketplaceViewTool, } from './server/tools/index.js';
|
|
54
|
+
export { PROTOCOL_TOOLS, agreementProposeTool, agreementSubcontractTool, agreementRespondTool, agreementCounterProposalTool, agreementCheckProposalTool, taskSpawnTool, taskUpdateTool, taskUpdatePlanStepTool, dispatchProtocolOp, PAYMENT_TOOLS, paymentBalanceTool, paymentTransferTool, paymentHoldTool, paymentReleaseTool, paymentResolveWalletTool, CONNECTION_TOOLS, connectionProxyTool, connectionListGrantsTool, requestConnectionTool, DISCOVERY_TOOLS, agentSearchTool, agentGetTool, MARKETPLACE_TOOLS, marketplaceViewTool, CONTEXT_TOOLS, contextReadTool, contextDelegateTool, contextExpandReachTool, contextDiscoverGrantableTool, GRANTS_TOOLS, listGrantsTool, LINK_TOOLS, requestLinkTool, createLinkInviteTool, claimLinkInviteTool, listLinksTool, revokeLinkTool, ARTIFACT_TOOLS, recordArtifactTool, CHAT_TOOLS, openConversationTool, } from './server/tools/index.js';
|
|
55
|
+
export { CLAUDE_SDK_TOOLS } from './agent/claudeSdkTools.js';
|
|
59
56
|
export { PROTOCOL_TOOL_NAMES, PROTOCOL_TOOL_TO_OPERATION, mapProtocolToolToOperation, isProtocolToolName } from './tasks/protocolRegistry.js';
|
|
60
57
|
export { InMemoryStore, FileMemoryStore } from './memory/MemoryStore.js';
|
|
61
58
|
export type { MemoryStore } from './memory/MemoryStore.js';
|
package/dist/index.js
CHANGED
|
@@ -44,16 +44,22 @@ export { OpenAIAdapter } from './adapters/OpenAIAdapter.js';
|
|
|
44
44
|
export { extractJSON, safeParseJSON } from './utils/jsonExtractor.js';
|
|
45
45
|
export { HistoryFormatter, historyFormatter, AgreementFormatter, agreementFormatter } from './formatters/index.js';
|
|
46
46
|
export { ProactiveTrigger } from './server/proactive/ProactiveTrigger.js';
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
// ZIG-894 — the hand-rolled ZiggsPayClient / ZiggsConnectClient were deleted;
|
|
48
|
+
// payment and connection tools now use @ziggs-ai/api-client's PaymentsClient /
|
|
49
|
+
// ConnectionsClient, the same clients ziggs-mcp uses.
|
|
50
|
+
// ZIG-869 — the hand-rolled ZiggsContextClient was deleted; context tools now
|
|
51
|
+
// use the same @ziggs-ai/api-client clients as ziggs-mcp (GrantsClient /
|
|
52
|
+
// ContextGrantsClient / ContextReadClient). Grant/reach types live there.
|
|
50
53
|
// All agent tool bundles live under server/tools/ (tier1 = protocol grammar,
|
|
51
54
|
// tier2 = opt-in HTTP capability bundles). Single home: server/tools/index.ts.
|
|
52
55
|
export {
|
|
53
56
|
// Tier 1 — protocol grammar (framework-managed via taskTools).
|
|
54
57
|
PROTOCOL_TOOLS, agreementProposeTool, agreementSubcontractTool, agreementRespondTool, agreementCounterProposalTool, agreementCheckProposalTool, taskSpawnTool, taskUpdateTool, taskUpdatePlanStepTool, dispatchProtocolOp,
|
|
55
58
|
// Tier 2 — opt-in capability bundles (spread into `tools:`).
|
|
56
|
-
PAYMENT_TOOLS, paymentBalanceTool, paymentTransferTool, paymentHoldTool, paymentReleaseTool, paymentResolveWalletTool, CONNECTION_TOOLS, connectionProxyTool, connectionListGrantsTool, DISCOVERY_TOOLS, agentSearchTool, agentGetTool, MARKETPLACE_TOOLS, marketplaceViewTool, } from './server/tools/index.js';
|
|
59
|
+
PAYMENT_TOOLS, paymentBalanceTool, paymentTransferTool, paymentHoldTool, paymentReleaseTool, paymentResolveWalletTool, CONNECTION_TOOLS, connectionProxyTool, connectionListGrantsTool, requestConnectionTool, DISCOVERY_TOOLS, agentSearchTool, agentGetTool, MARKETPLACE_TOOLS, marketplaceViewTool, CONTEXT_TOOLS, contextReadTool, contextDelegateTool, contextExpandReachTool, contextDiscoverGrantableTool, GRANTS_TOOLS, listGrantsTool, LINK_TOOLS, requestLinkTool, createLinkInviteTool, claimLinkInviteTool, listLinksTool, revokeLinkTool, ARTIFACT_TOOLS, recordArtifactTool, CHAT_TOOLS, openConversationTool, } from './server/tools/index.js';
|
|
60
|
+
// The always-on toolset for the hosted Claude cognition (ZIG-903 parity guard
|
|
61
|
+
// reads this as part of the real SDK registry).
|
|
62
|
+
export { CLAUDE_SDK_TOOLS } from './agent/claudeSdkTools.js';
|
|
57
63
|
export { PROTOCOL_TOOL_NAMES, PROTOCOL_TOOL_TO_OPERATION, mapProtocolToolToOperation, isProtocolToolName } from './tasks/protocolRegistry.js';
|
|
58
64
|
export { InMemoryStore, FileMemoryStore } from './memory/MemoryStore.js';
|
|
59
65
|
export { classifyIncomingEvent } from './context/classifyEnvelope.js';
|
|
@@ -19,6 +19,10 @@ export { PROTOCOL_TOOLS, agreementProposeTool, agreementSubcontractTool, agreeme
|
|
|
19
19
|
export { dispatchProtocolOp } from './tier1/protocolRunner.js';
|
|
20
20
|
export { DISCOVERY_TOOLS, agentSearchTool, agentGetTool } from './tier2/discoveryTools.js';
|
|
21
21
|
export { MARKETPLACE_TOOLS, marketplaceViewTool } from './tier2/marketplaceTools.js';
|
|
22
|
-
export { PAYMENT_TOOLS, paymentBalanceTool, paymentTransferTool, paymentWaitForApprovalTool, paymentHoldTool, paymentReleaseTool, paymentResolveWalletTool, paymentIssueGrantTool, paymentAttenuateGrantTool, paymentRevokeGrantTool,
|
|
23
|
-
export { CONNECTION_TOOLS, connectionProxyTool, connectionListGrantsTool, } from './tier2/connectionTools.js';
|
|
24
|
-
export { CONTEXT_TOOLS,
|
|
22
|
+
export { PAYMENT_TOOLS, paymentBalanceTool, paymentTransferTool, paymentWaitForApprovalTool, paymentHoldTool, paymentReleaseTool, paymentResolveWalletTool, paymentIssueGrantTool, paymentAttenuateGrantTool, paymentRevokeGrantTool, } from './tier2/paymentTools.js';
|
|
23
|
+
export { CONNECTION_TOOLS, connectionProxyTool, connectionListGrantsTool, requestConnectionTool, } from './tier2/connectionTools.js';
|
|
24
|
+
export { CONTEXT_TOOLS, contextReadTool, contextDelegateTool, contextExpandReachTool, contextDiscoverGrantableTool, } from './tier2/contextTools.js';
|
|
25
|
+
export { GRANTS_TOOLS, listGrantsTool } from './tier2/grantsTools.js';
|
|
26
|
+
export { LINK_TOOLS, requestLinkTool, createLinkInviteTool, claimLinkInviteTool, listLinksTool, revokeLinkTool, } from './tier2/linkTools.js';
|
|
27
|
+
export { ARTIFACT_TOOLS, recordArtifactTool } from './tier2/artifactTools.js';
|
|
28
|
+
export { CHAT_TOOLS, openConversationTool } from './tier2/chatTools.js';
|
|
@@ -21,6 +21,16 @@ export { dispatchProtocolOp } from './tier1/protocolRunner.js';
|
|
|
21
21
|
// ── Tier 2: capability bundles ──────────────────────────────────────────────
|
|
22
22
|
export { DISCOVERY_TOOLS, agentSearchTool, agentGetTool } from './tier2/discoveryTools.js';
|
|
23
23
|
export { MARKETPLACE_TOOLS, marketplaceViewTool } from './tier2/marketplaceTools.js';
|
|
24
|
-
export { PAYMENT_TOOLS, paymentBalanceTool, paymentTransferTool, paymentWaitForApprovalTool, paymentHoldTool, paymentReleaseTool, paymentResolveWalletTool, paymentIssueGrantTool, paymentAttenuateGrantTool, paymentRevokeGrantTool,
|
|
25
|
-
export { CONNECTION_TOOLS, connectionProxyTool, connectionListGrantsTool, } from './tier2/connectionTools.js';
|
|
26
|
-
export { CONTEXT_TOOLS,
|
|
24
|
+
export { PAYMENT_TOOLS, paymentBalanceTool, paymentTransferTool, paymentWaitForApprovalTool, paymentHoldTool, paymentReleaseTool, paymentResolveWalletTool, paymentIssueGrantTool, paymentAttenuateGrantTool, paymentRevokeGrantTool, } from './tier2/paymentTools.js';
|
|
25
|
+
export { CONNECTION_TOOLS, connectionProxyTool, connectionListGrantsTool, requestConnectionTool, } from './tier2/connectionTools.js';
|
|
26
|
+
export { CONTEXT_TOOLS, contextReadTool, contextDelegateTool, contextExpandReachTool, contextDiscoverGrantableTool, } from './tier2/contextTools.js';
|
|
27
|
+
// ZIG-893: one grant lister across every rail (retires context_discover +
|
|
28
|
+
// payment_list_grants). Always-available on the hosted agent — see CLAUDE_SDK_TOOLS.
|
|
29
|
+
export { GRANTS_TOOLS, listGrantsTool } from './tier2/grantsTools.js';
|
|
30
|
+
// ZIG-898: links (agreements with engagementKind 'link') — cross-org reach.
|
|
31
|
+
export { LINK_TOOLS, requestLinkTool, createLinkInviteTool, claimLinkInviteTool, listLinksTool, revokeLinkTool, } from './tier2/linkTools.js';
|
|
32
|
+
// ZIG-899: deliberate artifact recording (the model decides "record this").
|
|
33
|
+
export { ARTIFACT_TOOLS, recordArtifactTool } from './tier2/artifactTools.js';
|
|
34
|
+
// ZIG-900 decision: open_conversation only — chat listing stays a context-rail
|
|
35
|
+
// read (list_grants scopeKind=chat), no duplicate lister (ZIG-626 rule).
|
|
36
|
+
export { CHAT_TOOLS, openConversationTool } from './tier2/chatTools.js';
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { defineTool } from '../../../tools/defineTool.js';
|
|
2
|
+
import { ArtifactsClient } from '@ziggs-ai/api-client';
|
|
3
|
+
/**
|
|
4
|
+
* ZIG-899 — deliberate artifact recording on the SDK surface, same base name
|
|
5
|
+
* as ziggs-mcp's ziggs_record_artifact. Until now artifacts were written only
|
|
6
|
+
* as a host-side effect (recordReport / record-event); the model could not
|
|
7
|
+
* decide "this is a deliverable, record it" — which is exactly what the
|
|
8
|
+
* delegate protocol tells agents to do for heavy results. Rides
|
|
9
|
+
* ArtifactsClient.writeStrict (fail loudly, return the artifactId) — the same
|
|
10
|
+
* wire call as the MCP tool.
|
|
11
|
+
*/
|
|
12
|
+
function creds(ctx) {
|
|
13
|
+
const operatorKey = ctx?.['operatorKey'];
|
|
14
|
+
const agentId = ctx?.['agentId'];
|
|
15
|
+
if (!operatorKey)
|
|
16
|
+
throw new Error('operatorKey missing from tool context');
|
|
17
|
+
if (!agentId)
|
|
18
|
+
throw new Error('agentId missing from tool context');
|
|
19
|
+
return { operatorKey, agentId };
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* ZIG-560 teaching carried over from the MCP tool: name the result slot on the
|
|
23
|
+
* success path so an agent finds the right move unaided — reworded to the SDK
|
|
24
|
+
* task grammar (task_update carries the terminal result on this surface).
|
|
25
|
+
*/
|
|
26
|
+
function reportingHint(contentType, taskId) {
|
|
27
|
+
if (contentType === 'result') {
|
|
28
|
+
return taskId
|
|
29
|
+
? 'Recorded as a task-bound result artifact. Close the task by setting its terminal result with task_update.'
|
|
30
|
+
: 'Recorded as a result artifact, but not bound to a task — pass taskId to bind it, then close the task with task_update.';
|
|
31
|
+
}
|
|
32
|
+
return 'Reporting finished work? Record it with content_type=result bound to the task (taskId), then close the task with task_update — chat messages are conversation only.';
|
|
33
|
+
}
|
|
34
|
+
export const recordArtifactTool = defineTool('record_artifact', {
|
|
35
|
+
text: { type: 'string', required: true, description: 'Artifact body' },
|
|
36
|
+
visibility: {
|
|
37
|
+
type: 'string',
|
|
38
|
+
required: true,
|
|
39
|
+
enum: ['chat', 'agent-private'],
|
|
40
|
+
description: 'chat = visible to scope parties; agent-private = your eyes only',
|
|
41
|
+
},
|
|
42
|
+
chatId: { type: 'string', description: 'Target chat (xor agreementId)' },
|
|
43
|
+
agreementId: { type: 'string', description: 'Target agreement (xor chatId)' },
|
|
44
|
+
taskId: {
|
|
45
|
+
type: 'string',
|
|
46
|
+
description: 'Optional task — creates a TaskArtifactLink alongside the primary scope link',
|
|
47
|
+
},
|
|
48
|
+
content_type: { type: 'string', description: 'Default text; use result for a finished deliverable' },
|
|
49
|
+
}, async (args, ctx) => {
|
|
50
|
+
const chatId = args['chatId'];
|
|
51
|
+
const agreementId = args['agreementId'];
|
|
52
|
+
if ((chatId && agreementId) || (!chatId && !agreementId)) {
|
|
53
|
+
throw new Error('Pass exactly one of chatId or agreementId');
|
|
54
|
+
}
|
|
55
|
+
const visibility = args['visibility'];
|
|
56
|
+
if (visibility !== 'chat' && visibility !== 'agent-private') {
|
|
57
|
+
throw new Error('visibility must be chat or agent-private');
|
|
58
|
+
}
|
|
59
|
+
const contentType = args['content_type'];
|
|
60
|
+
const taskId = args['taskId'];
|
|
61
|
+
const { operatorKey, agentId } = creds(ctx);
|
|
62
|
+
const { artifactId } = await new ArtifactsClient(operatorKey, agentId).writeStrict({
|
|
63
|
+
text: args['text'],
|
|
64
|
+
visibility,
|
|
65
|
+
chatId,
|
|
66
|
+
agreementId,
|
|
67
|
+
taskId,
|
|
68
|
+
content_type: contentType,
|
|
69
|
+
});
|
|
70
|
+
return {
|
|
71
|
+
ok: true,
|
|
72
|
+
artifactId,
|
|
73
|
+
visibility,
|
|
74
|
+
chatId,
|
|
75
|
+
agreementId,
|
|
76
|
+
taskId,
|
|
77
|
+
reportingHint: reportingHint(contentType, taskId),
|
|
78
|
+
};
|
|
79
|
+
}, {
|
|
80
|
+
description: 'Write an artifact to a chat or agreement scope. Set visibility explicitly. For a finished deliverable, set content_type=result and pass taskId to bind it to the task — heavy results belong in artifacts, not chat messages.',
|
|
81
|
+
});
|
|
82
|
+
export const ARTIFACT_TOOLS = [recordArtifactTool];
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { defineTool } from '../../../tools/defineTool.js';
|
|
2
|
+
import { openConversation } from '@ziggs-ai/api-client';
|
|
3
|
+
/**
|
|
4
|
+
* ZIG-900 — the decided chat surface for hosted agents: open_conversation
|
|
5
|
+
* only, same base name as MCP's ziggs_open_conversation. There is deliberately
|
|
6
|
+
* NO chat-listing tool on the SDK: agents read context only via held grants
|
|
7
|
+
* (ZIG-425) and chat membership auto-mints a chat grant (ZIG-428/426), so
|
|
8
|
+
* "what chats can I see" is already answered by list_grants scopeKind=chat —
|
|
9
|
+
* adding a lister would duplicate a context-family read (ZIG-626 rule).
|
|
10
|
+
*/
|
|
11
|
+
function creds(ctx) {
|
|
12
|
+
const operatorKey = ctx?.['operatorKey'];
|
|
13
|
+
const agentId = ctx?.['agentId'];
|
|
14
|
+
if (!operatorKey)
|
|
15
|
+
throw new Error('operatorKey missing from tool context');
|
|
16
|
+
if (!agentId)
|
|
17
|
+
throw new Error('agentId missing from tool context');
|
|
18
|
+
return { operatorKey, agentId };
|
|
19
|
+
}
|
|
20
|
+
export const openConversationTool = defineTool('open_conversation', {
|
|
21
|
+
participantId: {
|
|
22
|
+
type: 'string',
|
|
23
|
+
required: true,
|
|
24
|
+
description: 'User or agent id to converse with (from agent_search — do not guess ids)',
|
|
25
|
+
},
|
|
26
|
+
}, async (args, ctx) => {
|
|
27
|
+
if (!args['participantId'])
|
|
28
|
+
throw new Error('participantId is required');
|
|
29
|
+
const { chatId } = await openConversation(args['participantId'], creds(ctx));
|
|
30
|
+
return {
|
|
31
|
+
chatId,
|
|
32
|
+
note: 'Conversation is open (or reused). Your membership auto-mints a chat grant, so the chat also appears in list_grants scopeKind=chat for context reads.',
|
|
33
|
+
};
|
|
34
|
+
}, {
|
|
35
|
+
description: 'Open or reuse a chat with a user or agent participant. To reach an agent in ANOTHER org, establish a link first — request_link (if you have its agent id) or create_link_invite (if you do not), approved/claimed — otherwise this fails with AGENT_NOT_PUBLISHED. To list chats you can already read, use list_grants scopeKind=chat.',
|
|
36
|
+
});
|
|
37
|
+
export const CHAT_TOOLS = [openConversationTool];
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ToolDefinition } from '../../../tools/defineTool.js';
|
|
2
2
|
export declare const connectionProxyTool: ToolDefinition;
|
|
3
3
|
export declare const connectionListGrantsTool: ToolDefinition;
|
|
4
|
+
export declare const requestConnectionTool: ToolDefinition;
|
|
4
5
|
export declare const CONNECTION_TOOLS: ToolDefinition[];
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { defineTool } from '../../../tools/defineTool.js';
|
|
2
|
-
import {
|
|
2
|
+
import { ConnectionsClient } from '@ziggs-ai/api-client';
|
|
3
3
|
function clientFor(ctx) {
|
|
4
4
|
const operatorKey = ctx?.['operatorKey'];
|
|
5
5
|
if (!operatorKey)
|
|
6
6
|
throw new Error('operatorKey missing from tool context');
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
// BACKEND_URL / ZIGGS_BACKEND_URL are the SDK runner's overrides; the shared
|
|
8
|
+
// client defaults to HTTP_URL (api-client convention) when neither is set.
|
|
9
|
+
const baseUrl = process.env.BACKEND_URL || process.env.ZIGGS_BACKEND_URL || undefined;
|
|
10
|
+
return new ConnectionsClient(operatorKey, ctx?.['agentId'] || undefined, baseUrl);
|
|
11
11
|
}
|
|
12
12
|
function rethrowWithContext(error, prefix) {
|
|
13
13
|
const e = error;
|
|
@@ -57,7 +57,54 @@ export const connectionListGrantsTool = defineTool('connection_list_grants', { c
|
|
|
57
57
|
rethrowWithContext(e, 'Failed to list connection grants');
|
|
58
58
|
}
|
|
59
59
|
});
|
|
60
|
+
export const requestConnectionTool = defineTool('request_connection', {
|
|
61
|
+
chatId: {
|
|
62
|
+
type: 'string',
|
|
63
|
+
required: true,
|
|
64
|
+
description: 'The chat you are working in — the consent card is opened there',
|
|
65
|
+
},
|
|
66
|
+
serverUrl: { type: 'string', required: true, description: 'Remote MCP server URL (https)' },
|
|
67
|
+
tools: {
|
|
68
|
+
type: 'array',
|
|
69
|
+
items: { type: 'string' },
|
|
70
|
+
required: true,
|
|
71
|
+
description: "Tool names you want — become the grant's allowed_actions caveats",
|
|
72
|
+
},
|
|
73
|
+
reason: {
|
|
74
|
+
type: 'string',
|
|
75
|
+
description: 'Plain-language reason shown to the human deciding',
|
|
76
|
+
},
|
|
77
|
+
}, async (args, ctx) => {
|
|
78
|
+
if (!args['chatId'])
|
|
79
|
+
throw new Error('chatId is required');
|
|
80
|
+
if (!args['serverUrl'])
|
|
81
|
+
throw new Error('serverUrl is required');
|
|
82
|
+
const tools = args['tools'];
|
|
83
|
+
if (!Array.isArray(tools) || tools.length === 0) {
|
|
84
|
+
throw new Error('tools must be a non-empty array of tool names');
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
const result = await clientFor(ctx).requestMcpConnection({
|
|
88
|
+
chatId: args['chatId'],
|
|
89
|
+
serverUrl: args['serverUrl'],
|
|
90
|
+
tools: tools,
|
|
91
|
+
reason: args['reason'],
|
|
92
|
+
});
|
|
93
|
+
return {
|
|
94
|
+
ok: true,
|
|
95
|
+
...result,
|
|
96
|
+
note: 'A connection-consent card is now in the chat awaiting your principal — they approve it right there (ZIG-798 flow). ' +
|
|
97
|
+
'Once approved, the connection + grant appear in list_grants (scopeKind=connection) / connection_list_grants for connection_proxy.',
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
catch (e) {
|
|
101
|
+
rethrowWithContext(e, 'Connection request failed');
|
|
102
|
+
}
|
|
103
|
+
}, {
|
|
104
|
+
description: 'Ask your principal (the human) to connect a remote MCP server and grant you the listed tools. Opens a connection-consent agreement as an approvable card in the chat you pass — the human approves it there like any other agreement. On approval the server is connected (browser OAuth if needed) and you are granted the tools; use them via connection_proxy.',
|
|
105
|
+
});
|
|
60
106
|
export const CONNECTION_TOOLS = [
|
|
61
107
|
connectionProxyTool,
|
|
62
108
|
connectionListGrantsTool,
|
|
109
|
+
requestConnectionTool,
|
|
63
110
|
];
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { type ToolDefinition } from '../../../tools/defineTool.js';
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const contextReadTool: ToolDefinition;
|
|
3
3
|
export declare const contextDelegateTool: ToolDefinition;
|
|
4
|
-
export declare const
|
|
4
|
+
export declare const contextExpandReachTool: ToolDefinition;
|
|
5
|
+
export declare const contextDiscoverGrantableTool: ToolDefinition;
|
|
6
|
+
export declare const CONTEXT_TOOLS: readonly [ToolDefinition, ToolDefinition, ToolDefinition, ToolDefinition];
|