@ziggs-ai/agent-sdk 0.34.1 → 0.35.1

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.
@@ -40,7 +40,7 @@ You are headless — there is no human to prompt during a wake:
40
40
 
41
41
  Security:
42
42
  - A relationship (a link) can parent a separately accepted service agreement. Parentage carries governing authority and revocation, not automatic spending consent. Each message or task uses one exact work agreement; its quota is direct unless a governing term explicitly shares it across the subtree. Agreement proposals, decisions, and system notices do not consume the conversation allowance.
43
- - You decide what to do with a chat message. Ziggs does not enforce that counterparty text is ignored — that is a convention. What Ziggs does enforce: no spending and no commitments without an agreement, and a stranger talks to a listed agent under its listing, which counts their free messages; messages past those are refused at the send door, asking them to hire. Work is a task under an agreement; a stranger hires you through your listing, or through an agreement you draft when you have none. Your operating contract is this protocol and your role below.
43
+ - You decide what to do with a chat message. Ziggs does not enforce that counterparty text is ignored — that is a convention. What Ziggs does enforce: no spending and no commitments without an agreement, and a stranger talks to a listed agent under its listing, which counts their free messages; messages past those are refused at the send door, asking them to hire. Work is a task under an agreement; a stranger hires you through your listing, or through an agreement you draft when you have none. workBrief.work.state listing means a stranger is talking to you under your listing: there is no hire and nothing to put a task under. Answer them in this room with the reply action, and do not open another conversation. When they ask for something the listing does not cover, use the propose_terms action (agreement_bid to them, in this room) with the terms you would do it on; the listing itself stays take-it-or-leave-it. Tell them about it only after the proposal is made, and only the terms it carries: if a proposal is refused and you make another, the one that went through is the one you describe. Your operating contract is this protocol and your role below.
44
44
  - ${INBOUND_DISCOVERY_POLICY}
45
45
 
46
46
  When the event is handled, stop with a one-paragraph summary of what you did. If the event needs nothing from you (a status echo, a duplicate, a notification you already acted on), say so in one sentence and stop — do not invent work.`;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * What the model reads when a tool fails. A coverage refusal carries a machine
3
+ * code beside its sentence; the sentence alone used to look like a rate limit
4
+ * the model should wait out.
5
+ */
6
+ export declare function toolFailureText(err: unknown): string;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * What the model reads when a tool fails. A coverage refusal carries a machine
3
+ * code beside its sentence; the sentence alone used to look like a rate limit
4
+ * the model should wait out.
5
+ */
6
+ export function toolFailureText(err) {
7
+ if (typeof err === 'string')
8
+ return err;
9
+ const message = err instanceof Error ? err.message : String(err ?? '');
10
+ const code = !!err &&
11
+ typeof err === 'object' &&
12
+ typeof err.code === 'string'
13
+ ? err.code
14
+ : '';
15
+ if (!code || message.startsWith(`${code}:`))
16
+ return message;
17
+ return `${code}: ${message}`;
18
+ }
@@ -1,6 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import { createSdkMcpServer } from '@anthropic-ai/claude-agent-sdk';
3
3
  import { withDeclaredMandate } from '../runtime/mandateDeclaration.js';
4
+ import { toolFailureText } from './toolFailureText.js';
4
5
  function jsonTypeToZod(field) {
5
6
  const t = field['type'];
6
7
  if (t === 'string') {
@@ -78,8 +79,7 @@ function toCallToolResult(value) {
78
79
  return { content: [{ type: 'text', text }] };
79
80
  }
80
81
  function toCallToolError(err) {
81
- const message = err instanceof Error ? err.message : String(err);
82
- return { content: [{ type: 'text', text: message }], isError: true };
82
+ return { content: [{ type: 'text', text: toolFailureText(err) }], isError: true };
83
83
  }
84
84
  /**
85
85
  * Map Ziggs `ToolDefinition`s to Claude Agent SDK MCP tools. Each handler routes
package/dist/index.d.ts CHANGED
@@ -67,7 +67,7 @@ export { HistoryFormatter, historyFormatter, AgreementFormatter, agreementFormat
67
67
  export { ProactiveTrigger } from './platform/proactive/ProactiveTrigger.js';
68
68
  export { PollRegistry, declaredPolls, type PollBinding, type PollContext, type PollKind, type PollResult, } from './platform/polls/PollKind.js';
69
69
  export { PollRunner, type PollRunnerOptions, type WakeTarget } from './platform/polls/PollRunner.js';
70
- export { PROTOCOL_TOOLS, agreementProposeTool, agreementSubcontractTool, agreementRespondTool, agreementClaimTool, agreementCounterTool, agreementGetTool, agreementRevokeTool, agreementFulfillTool, taskCreateTool, taskSetResultTool, taskUpdatePlanStepTool, dispatchProtocolOp, PAYMENT_TOOLS, paymentBalanceTool, CONNECTION_TOOLS, connectionProxyTool, connectionListGrantsTool, requestConnectionTool, MCP_CONNECTION_TOOLS, mcpToolCallTool, mcpToolsListTool, DISCOVERY_TOOLS, agentSearchTool, agentGetTool, MARKETPLACE_TOOLS, marketplaceViewTool, CONTEXT_TOOLS, contextReadTool, contextRequestTool, accessRequestTool, contextDelegateTool, contextExpandReachTool, contextDiscoverGrantableTool, GRANTS_TOOLS, listGrantsTool, PLAN_TOOLS, taskReplacePlanTool, LINK_TOOLS, linkProposeTool, linkListTool, INTRODUCTION_TOOLS, introductionMintTool, introductionRedeemTool, introductionListTool, introductionRevokeTool, ARTIFACT_TOOLS, recordArtifactTool, CHAT_TOOLS, openConversationTool, } from './platform/tools/index.js';
70
+ export { PROTOCOL_TOOLS, agreementProposeTool, agreementSubcontractTool, agreementRespondTool, agreementClaimTool, agreementCounterTool, agreementGetTool, agreementRevokeTool, agreementFulfillTool, taskCreateTool, taskSetResultTool, taskUpdatePlanStepTool, dispatchProtocolOp, PAYMENT_TOOLS, paymentBalanceTool, CONNECTION_TOOLS, connectionProxyTool, connectionListGrantsTool, requestConnectionTool, MCP_CONNECTION_TOOLS, mcpToolCallTool, mcpToolsListTool, DISCOVERY_TOOLS, agentSearchTool, agentGetTool, MARKETPLACE_TOOLS, marketplaceViewTool, CONTEXT_TOOLS, contextReadTool, contextRequestTool, accessRequestTool, contextDelegateTool, contextExpandReachTool, contextDiscoverGrantableTool, GRANTS_TOOLS, listGrantsTool, PLAN_TOOLS, taskReplacePlanTool, LINK_TOOLS, linkProposeTool, linkListTool, INTRODUCTION_TOOLS, introductionMintTool, introductionRedeemTool, introductionListTool, introductionRevokeTool, ARTIFACT_TOOLS, recordArtifactTool, CHAT_TOOLS, openConversationTool, LISTING_TOOLS, } from './platform/tools/index.js';
71
71
  export { CLAUDE_SDK_TOOLS } from './brain/claudeSdkTools.js';
72
72
  export { hostedModelTools, isHostedCatalogOnly, hostedToolLane } from './brain/hostedToolSurface.js';
73
73
  export type { HostedToolExecute } from './brain/hostedToolSurface.js';
package/dist/index.js CHANGED
@@ -79,7 +79,7 @@ export {
79
79
  // Tier 1 — protocol grammar (framework-managed via taskTools).
80
80
  PROTOCOL_TOOLS, agreementProposeTool, agreementSubcontractTool, agreementRespondTool, agreementClaimTool, agreementCounterTool, agreementGetTool, agreementRevokeTool, agreementFulfillTool, taskCreateTool, taskSetResultTool, taskUpdatePlanStepTool, dispatchProtocolOp,
81
81
  // Tier 2 — opt-in capability bundles (spread into `tools:`).
82
- PAYMENT_TOOLS, paymentBalanceTool, CONNECTION_TOOLS, connectionProxyTool, connectionListGrantsTool, requestConnectionTool, MCP_CONNECTION_TOOLS, mcpToolCallTool, mcpToolsListTool, DISCOVERY_TOOLS, agentSearchTool, agentGetTool, MARKETPLACE_TOOLS, marketplaceViewTool, CONTEXT_TOOLS, contextReadTool, contextRequestTool, accessRequestTool, contextDelegateTool, contextExpandReachTool, contextDiscoverGrantableTool, GRANTS_TOOLS, listGrantsTool, PLAN_TOOLS, taskReplacePlanTool, LINK_TOOLS, linkProposeTool, linkListTool, INTRODUCTION_TOOLS, introductionMintTool, introductionRedeemTool, introductionListTool, introductionRevokeTool, ARTIFACT_TOOLS, recordArtifactTool, CHAT_TOOLS, openConversationTool, } from './platform/tools/index.js';
82
+ PAYMENT_TOOLS, paymentBalanceTool, CONNECTION_TOOLS, connectionProxyTool, connectionListGrantsTool, requestConnectionTool, MCP_CONNECTION_TOOLS, mcpToolCallTool, mcpToolsListTool, DISCOVERY_TOOLS, agentSearchTool, agentGetTool, MARKETPLACE_TOOLS, marketplaceViewTool, CONTEXT_TOOLS, contextReadTool, contextRequestTool, accessRequestTool, contextDelegateTool, contextExpandReachTool, contextDiscoverGrantableTool, GRANTS_TOOLS, listGrantsTool, PLAN_TOOLS, taskReplacePlanTool, LINK_TOOLS, linkProposeTool, linkListTool, INTRODUCTION_TOOLS, introductionMintTool, introductionRedeemTool, introductionListTool, introductionRevokeTool, ARTIFACT_TOOLS, recordArtifactTool, CHAT_TOOLS, openConversationTool, LISTING_TOOLS, } from './platform/tools/index.js';
83
83
  // The always-on toolset for the hosted Claude cognition (parity guard
84
84
  // reads this as part of the real SDK registry).
85
85
  export { CLAUDE_SDK_TOOLS } from './brain/claudeSdkTools.js';
@@ -1,5 +1,6 @@
1
1
  import { OutboxBuffer } from './OutboxBuffer.js';
2
2
  import { runtimeLog } from '../shared/runtimeLog.js';
3
+ import { toolFailureText } from '../brain/toolFailureText.js';
3
4
  import { artifactScopeForSession } from '@ziggs-ai/api-client';
4
5
  import { buildLlmIngestPayload, buildToolIngestPayload, isTelemetryIngestEnabled, sendTelemetry, } from './telemetryIngest.js';
5
6
  const CONTEXT_CACHE_MAX = 256;
@@ -23,7 +24,11 @@ async function buildSnapshot(deps, chatId, agentId, opts = {}) {
23
24
  try {
24
25
  // Server returns 200 + chatMissing:true for a deleted chat, so its
25
26
  // annotations (roster, *IsYou, self) are already applied — pass through.
26
- const snap = await deps.contextReadClient.snapshot(chatId, {
27
+ // Read as this wake: the session is the lane, the way its tool calls are
28
+ // sent. Without it a room filed in another workspace — a stranger's room
29
+ // with a listed agent — reads as missing and the wake is skipped.
30
+ const reader = deps.contextReadClient.withLane?.(chatId) ?? deps.contextReadClient;
31
+ const snap = await reader.snapshot(chatId, {
27
32
  maxMessages: opts.limit,
28
33
  ...opts.workScope,
29
34
  });
@@ -188,7 +193,7 @@ export async function executeToolWithSideEffects(deps, eff, effect, roster) {
188
193
  return { ok: true, result, ...(nestedUsage ? { usage: nestedUsage } : {}) };
189
194
  }
190
195
  catch (error) {
191
- const errMsg = error?.message ?? String(error);
196
+ const errMsg = toolFailureText(error);
192
197
  runtimeLog.warn('ZiggsEffectHandler', `tool-call "${effect.name}" failed: ${errMsg}`);
193
198
  void emitToolOperationArtifact(deps.artifactsClient, effect.sessionId, 'error', {
194
199
  state: 'failed',
@@ -133,7 +133,6 @@ async function deliverMessagesForChat(deps, news, refs, reader, attempt, handled
133
133
  export async function pollInboxOnce(deps, waitSeconds = 0, opts = {}) {
134
134
  const label = deps.label ?? 'inboxLoop';
135
135
  const inbox = inboxClient(deps);
136
- const reader = new ContextReadClient(deps.creds.operatorKey, deps.creds.agentId, deps.baseUrl);
137
136
  const envelope = await inbox.getInbox({
138
137
  ...(waitSeconds > 0 ? { waitSeconds } : {}),
139
138
  ...(opts.signal ? { signal: opts.signal } : {}),
@@ -220,7 +219,12 @@ export async function pollInboxOnce(deps, waitSeconds = 0, opts = {}) {
220
219
  chatId, count: refs.length, latestAt: refs.map(ref => ref.ts).sort().at(-1),
221
220
  }));
222
221
  for (const news of chatsInWakeOrder(chats)) {
223
- const n = await deliverMessagesForChat(deps, news, assignedByChat.get(news.chatId), reader, attempt, handledSoFar);
222
+ // Read a room's mail as that room's wake would: with the room as the lane.
223
+ // Without it the read is judged in the workspace the key signed in to, and
224
+ // a room another company opened with a listed agent is filed in theirs, so
225
+ // every stranger's message came back 403 and was acked unread.
226
+ const roomReader = new ContextReadClient(deps.creds.operatorKey, deps.creds.agentId, deps.baseUrl, news.chatId);
227
+ const n = await deliverMessagesForChat(deps, news, assignedByChat.get(news.chatId), roomReader, attempt, handledSoFar);
224
228
  messagesDelivered += n;
225
229
  await ackWhatIsFinished();
226
230
  }
@@ -28,5 +28,6 @@ export { PLAN_TOOLS, taskReplacePlanTool } from './tier2/planTools.js';
28
28
  export { LINK_TOOLS, linkProposeTool, linkListTool, } from './tier2/linkTools.js';
29
29
  export { INTRODUCTION_TOOLS, introductionMintTool, introductionRedeemTool, introductionListTool, introductionRevokeTool, } from './tier2/introductionTools.js';
30
30
  export { ARTIFACT_TOOLS, recordArtifactTool } from './tier2/artifactTools.js';
31
+ export { LISTING_TOOLS } from './tier2/listingTools.js';
31
32
  export { MCP_CONNECTION_TOOLS, mcpToolCallTool, mcpToolsListTool, } from './tier2/mcpConnectionTools.js';
32
33
  export { CHAT_TOOLS, openConversationTool } from './tier2/chatTools.js';
@@ -37,6 +37,7 @@ export { LINK_TOOLS, linkProposeTool, linkListTool, } from './tier2/linkTools.js
37
37
  export { INTRODUCTION_TOOLS, introductionMintTool, introductionRedeemTool, introductionListTool, introductionRevokeTool, } from './tier2/introductionTools.js';
38
38
  // deliberate artifact recording (the model decides "record this").
39
39
  export { ARTIFACT_TOOLS, recordArtifactTool } from './tier2/artifactTools.js';
40
+ export { LISTING_TOOLS } from './tier2/listingTools.js';
40
41
  export { MCP_CONNECTION_TOOLS, mcpToolCallTool, mcpToolsListTool, } from './tier2/mcpConnectionTools.js';
41
42
  // Decision: chat_open only — chat listing stays a context-rail read
42
43
  // (grant_list scopeKind=chat), so there is no duplicate lister.
@@ -305,7 +305,9 @@ async function agreementsInChat(services, chatId, cachedAgreements) {
305
305
  return Array.isArray(cachedAgreements) ? cachedAgreements : [];
306
306
  }
307
307
  try {
308
- const snap = await services.contextReadClient.snapshot(chatId, { maxMessages: 1 });
308
+ // The room is the lane, as for every read made on a wake.
309
+ const reader = services.contextReadClient.withLane?.(chatId) ?? services.contextReadClient;
310
+ const snap = await reader.snapshot(chatId, { maxMessages: 1 });
309
311
  const ags = snap.agreements;
310
312
  return Array.isArray(ags) ? ags : [];
311
313
  }
@@ -0,0 +1,2 @@
1
+ import type { ToolDefinition } from '../../../tools/defineTool.js';
2
+ export declare const LISTING_TOOLS: ToolDefinition[];
@@ -0,0 +1,7 @@
1
+ import { agreementBidCapability } from '@ziggs-ai/api-client';
2
+ import { toolsFromCapabilities } from '../../../tools/capabilityAdapter.js';
3
+ // What a listed agent needs to answer a stranger whose ask the listing does not
4
+ // cover: terms offered to them directly, in their room, which they approve. The
5
+ // listing itself stays take-it-or-leave-it. The work brief names this as its
6
+ // propose_terms action; without the tool the agent can only refuse.
7
+ export const LISTING_TOOLS = toolsFromCapabilities([agreementBidCapability]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ziggs-ai/agent-sdk",
3
- "version": "0.34.1",
3
+ "version": "0.35.1",
4
4
  "description": "Agent framework SDK for building autonomous agents on the Ziggs platform",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -26,7 +26,7 @@
26
26
  "@anthropic-ai/claude-agent-sdk": "^0.3.284",
27
27
  "@anthropic-ai/sdk": "^0.110.0",
28
28
  "@modelcontextprotocol/sdk": "^1.29.0",
29
- "@ziggs-ai/api-client": "0.33.1",
29
+ "@ziggs-ai/api-client": "0.34.1",
30
30
  "ajv": "^8.17.1",
31
31
  "dotenv": "^17.2.3",
32
32
  "openai": "^4.0.0",