@ziggs-ai/agent-sdk 0.42.2 → 0.43.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.
Files changed (84) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +1 -1
  3. package/dist/Agent.d.ts +21 -8
  4. package/dist/Agent.js +173 -97
  5. package/dist/brain/ClaudeBrain.d.ts +0 -1
  6. package/dist/brain/ClaudeBrain.js +18 -42
  7. package/dist/brain/claudeCognition.js +5 -6
  8. package/dist/brain/claudeSdkProtocol.js +9 -9
  9. package/dist/brain/claudeSdkTools.d.ts +3 -3
  10. package/dist/brain/claudeSdkTools.js +37 -133
  11. package/dist/brain/hostedToolSurface.js +1 -1
  12. package/dist/brain/standingOfferNotice.d.ts +0 -2
  13. package/dist/brain/standingOfferNotice.js +1 -21
  14. package/dist/brain/toolManagerToSdkMcp.js +1 -1
  15. package/dist/brain/wakeGate.d.ts +3 -1
  16. package/dist/brain/wakeGate.js +6 -0
  17. package/dist/index.d.ts +4 -3
  18. package/dist/index.js +4 -3
  19. package/dist/ingress/normalizeIncoming.d.ts +5 -3
  20. package/dist/ingress/normalizeIncoming.js +9 -8
  21. package/dist/mcp/createMcpAgent.d.ts +15 -0
  22. package/dist/mcp/createMcpAgent.js +47 -11
  23. package/dist/memory/MemoryStore.d.ts +1 -1
  24. package/dist/memory/MemoryStore.js +1 -6
  25. package/dist/platform/ConnectionPool.js +1 -1
  26. package/dist/platform/OutboxBuffer.d.ts +2 -2
  27. package/dist/platform/OutboxBuffer.js +17 -17
  28. package/dist/platform/StateTimers.d.ts +3 -1
  29. package/dist/platform/StateTimers.js +4 -3
  30. package/dist/platform/WakeLedger.d.ts +10 -6
  31. package/dist/platform/WakeLedger.js +16 -9
  32. package/dist/platform/ZiggsEffectHandler.d.ts +18 -4
  33. package/dist/platform/ZiggsEffectHandler.js +86 -55
  34. package/dist/platform/agreements/AgreementService.d.ts +1 -3
  35. package/dist/platform/agreements/AgreementService.js +1 -7
  36. package/dist/platform/inboxLoop.d.ts +3 -9
  37. package/dist/platform/inboxLoop.js +151 -158
  38. package/dist/platform/polls/PollKind.d.ts +13 -16
  39. package/dist/platform/polls/PollKind.js +4 -4
  40. package/dist/platform/polls/PollRunner.d.ts +3 -20
  41. package/dist/platform/polls/PollRunner.js +13 -15
  42. package/dist/platform/polls/declaredPollRunner.d.ts +1 -1
  43. package/dist/platform/polls/declaredPollRunner.js +1 -1
  44. package/dist/platform/tasks/TaskService.d.ts +4 -3
  45. package/dist/platform/tasks/TaskService.js +1 -4
  46. package/dist/platform/telemetryIngest.js +4 -4
  47. package/dist/platform/tools/index.d.ts +0 -1
  48. package/dist/platform/tools/index.js +0 -3
  49. package/dist/platform/tools/tier1/protocolRunner.d.ts +1 -1
  50. package/dist/platform/tools/tier1/protocolRunner.js +24 -17
  51. package/dist/platform/tools/tier1/protocolTools.js +2 -2
  52. package/dist/platform/tools/tier1/wakeTools.d.ts +1 -1
  53. package/dist/platform/tools/tier1/wakeTools.js +2 -1
  54. package/dist/platform/tools/tier2/mcpConnectionTools.js +1 -1
  55. package/dist/runtime/AgentMachine.d.ts +2 -2
  56. package/dist/runtime/AgentMachine.js +4 -5
  57. package/dist/runtime/PromptBuilder.d.ts +1 -1
  58. package/dist/runtime/PromptBuilder.js +5 -4
  59. package/dist/runtime/buildOutcome.d.ts +1 -1
  60. package/dist/runtime/deliveryWriteKeys.d.ts +1 -1
  61. package/dist/runtime/deliveryWriteKeys.js +1 -1
  62. package/dist/runtime/kickoff.d.ts +14 -43
  63. package/dist/runtime/kickoff.js +22 -178
  64. package/dist/runtime/messageCommand.d.ts +9 -0
  65. package/dist/runtime/messageCommand.js +23 -0
  66. package/dist/runtime/requiredContext.d.ts +6 -0
  67. package/dist/runtime/requiredContext.js +23 -0
  68. package/dist/runtime/runTurn.js +31 -106
  69. package/dist/runtime/taskIntake.js +8 -22
  70. package/dist/runtime/wakeEffects.d.ts +3 -12
  71. package/dist/runtime/wakeEffects.js +17 -48
  72. package/dist/runtime/wakeOutcome.js +1 -1
  73. package/dist/skills/createSkillAgent.js +12 -1
  74. package/dist/tools/capabilityAdapter.js +1 -1
  75. package/dist/tools/recordReport.d.ts +1 -1
  76. package/dist/tools/recordReport.js +3 -3
  77. package/dist/tools/toolCreds.d.ts +1 -1
  78. package/dist/tools/toolCreds.js +4 -2
  79. package/dist/types.d.ts +17 -27
  80. package/package.json +3 -3
  81. package/dist/platform/tools/tier2/chatTools.d.ts +0 -3
  82. package/dist/platform/tools/tier2/chatTools.js +0 -7
  83. package/dist/probeChat.d.ts +0 -10
  84. package/dist/probeChat.js +0 -12
@@ -1,53 +1,77 @@
1
+ import { MessageRecordsClient } from '@ziggs-ai/api-client';
1
2
  import { OutboxBuffer } from './OutboxBuffer.js';
2
3
  import { runtimeLog } from '../shared/runtimeLog.js';
4
+ import { resolveBackendUrl } from '../shared/backendUrl.js';
3
5
  import { toolFailureText } from '../brain/toolFailureText.js';
4
6
  import { ExecutionRefusal, executionControllers } from '../runtime/executionController.js';
5
- import { artifactScopeForSession } from '@ziggs-ai/api-client';
7
+ import { assertRequiredContext } from '../runtime/requiredContext.js';
8
+ import { artifactScope } from '@ziggs-ai/api-client';
6
9
  import { buildLlmIngestPayload, buildToolIngestPayload, isTelemetryIngestEnabled, sendTelemetry, } from './telemetryIngest.js';
7
10
  const CONTEXT_CACHE_MAX = 256;
8
- /**
9
- * Compose a `ContextSnapshot` for a chatId via the grant-fenced aggregate read
10
- * (`GET /context/snapshot`, follow-up). The backend assembles history +
11
- * agreements + roster through the same `assertScopeAccess` + temporal fence as
12
- * the per-type context reads, and annotates `*IsYou` / self server-side against
13
- * the acting agent. This function only preserves the never-throw/degrade
14
- * contract that the cognition code depends on — the shape is unchanged.
15
- */
16
- const emptySnapshot = (agentId, chatMissing = false) => ({
11
+ /** Said in place of a read when nothing selects one. Not a failure: the wake can still act on explicit resources. */
12
+ const NO_CONTEXT = 'This wake selects no message, artifact or work. Name an exact message, artifact, task or agreement before reading context.';
13
+ /** Required work context and optional messaging inputs share the same access
14
+ * checks, but are fetched independently. */
15
+ const emptySnapshot = (agentId) => ({
17
16
  history: [],
18
17
  agreements: [],
19
18
  users: [],
20
19
  agents: [{ agentId, role: 'self', isYou: true, kind: 'agent' }],
21
20
  latestSequence: null,
22
- ...(chatMissing ? { chatMissing: true } : {}),
23
21
  });
24
- async function buildSnapshot(deps, chatId, agentId, opts = {}) {
22
+ async function buildSnapshot(deps, agentId, opts = {}) {
25
23
  try {
26
- // Server returns 200 + chatMissing:true for a deleted chat, so its
27
- // annotations (roster, *IsYou, self) are already applied — pass through.
28
- // Read as this wake: the session is the lane, the way its tool calls are
29
- // sent. Without it a room filed in another workspace — a stranger's room
30
- // with a listed agent — reads as missing and the wake is skipped.
31
- const reader = deps.contextReadClient;
32
- const snap = await reader.snapshot(chatId, {
33
- maxMessages: opts.limit,
34
- ...opts.workScope,
24
+ const scope = opts.workScope;
25
+ const via = opts.via ?? (scope?.taskId ? `task:${scope.taskId}` : scope?.agreementId ? `agreement:${scope.agreementId}` : scope?.messageId ? `message:${scope.messageId}` : scope?.artifactId ? `artifact:${scope.artifactId}` : undefined);
26
+ if (!via)
27
+ throw new Error('Context requires an explicit message, artifact, task or agreement');
28
+ const agreementId = scope?.agreementId ?? (via.startsWith('agreement:') ? via.slice('agreement:'.length) : undefined);
29
+ const messageId = scope?.messageId ?? (via.startsWith('message:') ? via.slice('message:'.length) : undefined);
30
+ // Select the work independently of its triggering message. A message is
31
+ // the snapshot entry only when it is the selected resource itself.
32
+ const snap = await deps.contextReadClient.snapshot({
33
+ via, maxMessages: opts.limit,
34
+ ...(agreementId ? { agreementId } : {}),
35
+ ...(scope?.artifactId ? { artifactId: scope.artifactId } : {}),
35
36
  });
36
- // Built rather than cast: the roster rows are typed on both sides now (they
37
- // carry the declared participant kind), and only `history` is loose on the
38
- // wire, so a whole-object cast would be asserting past the one field that
39
- // actually needs it.
40
- return { ...snap, history: snap.history };
37
+ assertRequiredContext(snap);
38
+ const messages = new MessageRecordsClient(deps.operatorKey, agentId, resolveBackendUrl());
39
+ const trigger = messageId ? await messages.get(messageId) : undefined;
40
+ if (trigger && agreementId && trigger.mandate?.agreementId !== agreementId)
41
+ throw Object.assign(new Error('Trigger belongs to different work'), { status: 403 });
42
+ if (trigger && opts.workScope?.taskId && trigger.mandate?.taskId !== opts.workScope.taskId)
43
+ throw Object.assign(new Error('Trigger belongs to different task work'), { status: 403 });
44
+ const present = (m) => ({ messageId: m.messageId, text: m.content.text, entryType: 'message', timestamp: Date.parse(m.timestamp), sender: { id: m.sender.isSelf ? agentId : m.sender.ref, type: m.sender.kind }, receiver: { id: m.recipients[0]?.ref } });
45
+ const required = trigger ? [present(trigger)] : [];
46
+ const context = { ...snap, messageRecord: trigger, messageMandate: agreementId ? { agreementId, ...(opts.workScope?.taskId ? { taskId: opts.workScope.taskId } : {}) } : trigger?.mandate ?? undefined };
47
+ if (trigger || agreementId) {
48
+ if (opts.includeHistory === true) {
49
+ try {
50
+ const page = agreementId ? await messages.list({ agreementId, taskId: opts.workScope?.taskId, limit: Math.min(opts.limit ?? 12, 30) }) : await messages.replies(trigger.messageId, { limit: Math.min(opts.limit ?? 12, 30) });
51
+ const history = page.messages.map(present);
52
+ if (trigger && !page.messages.some(m => m.messageId === trigger.messageId))
53
+ history.unshift(present(trigger));
54
+ return { ...context, history };
55
+ }
56
+ catch (error) {
57
+ const refusal = error;
58
+ if (refusal.status === 401 || refusal.code?.startsWith('EXECUTION_'))
59
+ throw error;
60
+ return { ...context, history: required, historyUnavailable: true };
61
+ }
62
+ }
63
+ return { ...context, history: required };
64
+ }
65
+ return { ...snap, history: snap.history.map(present) };
41
66
  }
42
67
  catch (err) {
43
- // Defensive: server normally signals a dead chat as 200 + chatMissing, but
44
- // a raw 404 degrades the same way so message wakes still skip it.
68
+ // A refused/missing exact resource is required context failure.
45
69
  const status = err?.status;
46
70
  // 403 = exists but this agent has no grant. Same as deleted:
47
71
  // no world to act in. Leaving it as an empty snapshot used to run a
48
72
  // full turn against refusals.
49
73
  if (status === 404 || status === 403) {
50
- return { ...emptySnapshot(agentId, true), unavailable: true, work: { minimumComplete: false, authorization: { active: false }, instruction: 'Required context is unavailable. Do not start work without verified scope and access.' } };
74
+ return { ...emptySnapshot(agentId), unavailable: true, work: { minimumComplete: false, authorization: { active: false }, instruction: 'Required context is unavailable. Do not start work without verified scope and access.' } };
51
75
  }
52
76
  runtimeLog.warn('ZiggsEffectHandler', `snapshot fetch failed: ${err?.message ?? err}`);
53
77
  return { ...emptySnapshot(agentId), unavailable: true, work: { minimumComplete: false, authorization: { active: false }, instruction: 'Context read failed. Retry or request access before acting; an empty packet is not permission.' } };
@@ -85,15 +109,18 @@ function previewToolArgs(args) {
85
109
  * Chat timeline: `Message.tsx` parses `entryType: artifact`, `contentType: operation` with
86
110
  * `operation_*:{json}` where json includes `state` and `tool`.
87
111
  */
88
- async function emitToolOperationArtifact(client, sessionId, phase, payload, idempotencyKey, serviceAgreementId, taskId) {
112
+ async function emitToolOperationArtifact(client, addressId, phase, payload, idempotencyKey, serviceAgreementId, taskId) {
113
+ // Operation history belongs to selected work or an explicit conversation.
114
+ // An unbound processing lane must not accumulate shared private context.
115
+ if (!addressId && !serviceAgreementId && !taskId)
116
+ return;
89
117
  const prefix = phase === 'started' ? 'operation_started' : phase === 'completed' ? 'operation_completed' : 'operation_error';
90
118
  const text = `${prefix}:${JSON.stringify(payload)}`;
91
119
  try {
92
120
  await client.write({
93
- // an agreement lane (`agrn-…`) is a routing key, not a chat —
94
- // passing it as chatId asked the backend to write into a chat that does
95
- // not exist and 403'd every breadcrumb on agreement-lane work.
96
- ...artifactScopeForSession(sessionId),
121
+ // The wake's own conversation or work. A processing lane is a routing
122
+ // key, never a chat: a breadcrumb with neither is refused here.
123
+ ...artifactScope({ agreementId: serviceAgreementId }),
97
124
  text,
98
125
  contentType: 'operation',
99
126
  visibility: 'agent-private',
@@ -119,12 +146,15 @@ async function emitToolOperationArtifact(client, sessionId, phase, payload, idem
119
146
  * side effects — that is the whole point of funneling both paths here.
120
147
  *
121
148
  * `eff` is threaded into the tool context so eff-backed tools
122
- * (`context_snapshot`, `chat_send`) resolve through this same path
149
+ * (`context_snapshot`, `message_send`) resolve through this same path
123
150
  * regardless of which cognition invoked them.
124
151
  */
125
152
  export async function executeToolWithSideEffects(deps, eff, effect, roster) {
126
153
  const toolT0 = Date.now();
127
154
  let args = effect.args || {};
155
+ // The wake's explicit conversation, when it has one. The effect's session
156
+ // is the processing lane, which routes effects and is never an address.
157
+ const addressId = deps.conversationFor?.(effect.sessionId)?.addressId;
128
158
  const controller = executionControllers.getStore();
129
159
  let binding;
130
160
  let argsPreview;
@@ -142,7 +172,7 @@ export async function executeToolWithSideEffects(deps, eff, effect, roster) {
142
172
  args = Object.fromEntries(Object.entries(args).filter(([key]) => key !== 'taskId'));
143
173
  }
144
174
  argsPreview = previewToolArgs(args);
145
- void emitToolOperationArtifact(deps.artifactsClient, effect.sessionId, 'started', {
175
+ void emitToolOperationArtifact(deps.artifactsClient, addressId, 'started', {
146
176
  state: 'started',
147
177
  tool: effect.name,
148
178
  ...(argsPreview ? { args: argsPreview } : {}),
@@ -166,7 +196,8 @@ export async function executeToolWithSideEffects(deps, eff, effect, roster) {
166
196
  const result = await deps.toolManager.executeTool(effect.name, args, {
167
197
  operatorKey: deps.operatorKey,
168
198
  agentId: deps.agentId,
169
- chatId: effect.sessionId,
199
+ ...(addressId ? { addressId } : {}),
200
+ sessionId: effect.sessionId,
170
201
  taskService: deps.taskService,
171
202
  agreementService: deps.agreementService,
172
203
  contextReadClient: deps.contextReadClient,
@@ -195,7 +226,7 @@ export async function executeToolWithSideEffects(deps, eff, effect, roster) {
195
226
  // One clip per tool call: this is a full JSON.stringify of the untruncated
196
227
  // result, and the artifact body and the idempotency key want the same string.
197
228
  const clipped = clipForOperationArtifact(result);
198
- void emitToolOperationArtifact(deps.artifactsClient, effect.sessionId, 'completed', {
229
+ void emitToolOperationArtifact(deps.artifactsClient, addressId, 'completed', {
199
230
  state: 'completed',
200
231
  tool: effect.name,
201
232
  result: clipped,
@@ -213,7 +244,7 @@ export async function executeToolWithSideEffects(deps, eff, effect, roster) {
213
244
  catch (error) {
214
245
  const errMsg = toolFailureText(error);
215
246
  runtimeLog.warn('ZiggsEffectHandler', `tool-call "${effect.name}" failed: ${errMsg}`);
216
- void emitToolOperationArtifact(deps.artifactsClient, effect.sessionId, 'error', {
247
+ void emitToolOperationArtifact(deps.artifactsClient, addressId, 'error', {
217
248
  state: 'failed',
218
249
  tool: effect.name,
219
250
  error: errMsg,
@@ -265,7 +296,17 @@ export function createZiggsEffectHandler(deps) {
265
296
  // the per-type reads. Every producer — ClaudeBrain.tick, runTurn,
266
297
  // and the on-demand context_snapshot tool — routes through here.
267
298
  const scopes = effect.opts?.workScopes ?? [];
268
- const packets = await Promise.all((scopes.length ? scopes : [undefined]).map(workScope => buildSnapshot(deps, effect.sessionId, deps.agentId, { limit: effect.opts?.maxMessages, workScope })));
299
+ const destination = deps.conversationFor?.(effect.sessionId);
300
+ const defaultScope = destination ? { agreementId: destination.agreementId, taskId: destination.taskId, messageId: destination.message?.messageId } : undefined;
301
+ const selects = (scope) => !!(effect.opts?.via || scope?.agreementId || scope?.taskId || scope?.messageId);
302
+ if (!scopes.length && !selects(defaultScope)) {
303
+ const none = { ...emptySnapshot(deps.agentId), work: { instruction: NO_CONTEXT } };
304
+ cachePut(effect.sessionId, none);
305
+ return none;
306
+ }
307
+ // An explicit resource read never inherits another wake's work selection.
308
+ const selectedScopes = scopes.length ? scopes : [effect.opts?.via ? undefined : defaultScope];
309
+ const packets = await Promise.all(selectedScopes.map(workScope => buildSnapshot(deps, deps.agentId, { limit: effect.opts?.maxMessages, workScope, via: effect.opts?.via, includeHistory: effect.opts?.includeHistory })));
269
310
  const snap = packets.length === 1 ? packets[0] : {
270
311
  ...emptySnapshot(deps.agentId),
271
312
  work: { contexts: packets.map(p => ({ ...p.work, workBrief: p.workBrief, agreements: p.agreements, history: p.history, artifacts: p.artifacts })),
@@ -336,33 +377,23 @@ export function createZiggsEffectHandler(deps) {
336
377
  });
337
378
  }
338
379
  case 'send-message': {
339
- const sent = await deps.messageSender(effect.text, effect.receiverId, effect.sessionId, effect.messageId, effect.conversationAgreementId, effect.underAgreementId, effect.taskId, effect.sources);
340
- outbox.track(effect.sessionId, { text: effect.text, receiverId: effect.receiverId });
341
- // Carry the send's own report back to whoever asked for the send. A
342
- // sender that cannot see where its message went cannot tell a delivered
343
- // answer from a dropped one, which is the whole failure here.
344
- const report = (sent ?? {});
345
- return {
346
- ok: true,
347
- ...(report.chatId ? { chatId: report.chatId } : {}),
348
- ...(report.messageId ? { messageId: report.messageId } : {}),
349
- ...(report.delivered ? { delivered: report.delivered } : {}),
350
- ...(report.to ? { to: report.to } : {}),
351
- };
380
+ const sent = await deps.messageSender(effect.command);
381
+ outbox.track(effect.sessionId, { text: effect.command.content.text, receiverId: sent.message.recipients[0]?.ref });
382
+ return { ...sent, ok: true };
352
383
  }
353
384
  case 'record-event': {
354
385
  // Routes through ArtifactsClient as an agent-private artifact —
355
386
  // visible to this agent across turns, not to other chat parties.
356
387
  try {
357
388
  if (effect.entry.kind === 'thought' && typeof effect.entry.text === 'string') {
358
- await deps.artifactsClient.recordThought(effect.sessionId, effect.entry.text, {
389
+ await deps.artifactsClient.recordThought(effect.entry.text, {
359
390
  idempotencyKey: effect.idempotencyKey,
360
391
  serviceAgreementId: effect.serviceAgreementId,
361
392
  });
362
393
  }
363
394
  else {
364
395
  await deps.artifactsClient.write({
365
- ...artifactScopeForSession(effect.sessionId),
396
+ ...artifactScope({ agreementId: effect.serviceAgreementId }),
366
397
  text: JSON.stringify(effect.entry),
367
398
  contentType: String(effect.entry.kind ?? 'event'),
368
399
  visibility: 'agent-private',
@@ -1,4 +1,4 @@
1
- import { type Agreement, type ClaimedKind, type ClaimOptions, type ProposeAgreementData, type ProposeDirectInput, type ProposeBroadcastInput, type PublishOfferPayload, type UnifiedProposeInput, type ProposeShape, type DelegateAgreementData, type CounterAgreementData, type CreateLinkBody, type CreateLinkResult, type ListAgreementsFilters, type GetMyAgreementsFilters, type ChatLinkType, type ArtifactLinkType } from '@ziggs-ai/api-client';
1
+ import { type Agreement, type ClaimedKind, type ClaimOptions, type ProposeAgreementData, type ProposeDirectInput, type ProposeBroadcastInput, type PublishOfferPayload, type UnifiedProposeInput, type ProposeShape, type DelegateAgreementData, type CounterAgreementData, type CreateLinkBody, type CreateLinkResult, type ListAgreementsFilters, type GetMyAgreementsFilters, type ArtifactLinkType } from '@ziggs-ai/api-client';
2
2
  export declare class AgreementService {
3
3
  private creds;
4
4
  constructor(operatorKey: string, agentId: string);
@@ -79,8 +79,6 @@ export declare class AgreementService {
79
79
  ok: boolean;
80
80
  agreement: Agreement;
81
81
  }>;
82
- linkToChat(agreementId: string, chatId: string, linkType?: ChatLinkType): Promise<unknown | null>;
83
- getChats(agreementId: string): Promise<unknown[]>;
84
82
  linkArtifact(agreementId: string, artifactId: string, linkType?: ArtifactLinkType): Promise<unknown | null>;
85
83
  getArtifacts(agreementId: string): Promise<unknown[]>;
86
84
  }
@@ -1,4 +1,4 @@
1
- import { proposeAgreement, proposeBroadcast as proposeBroadcastApi, delegateAgreement, respondToAgreement, counterAgreement, claimOpenAgreement, proposeUnified, getAgreementStatus, listAgreements, getMyAgreements, getAgreement, publishOffer as publishOfferApi, createLink, revokeAgreement, fulfillAgreement, linkAgreementToChat, getChatsForAgreement, linkArtifactToAgreement, getArtifactsForAgreement, } from '@ziggs-ai/api-client';
1
+ import { proposeAgreement, proposeBroadcast as proposeBroadcastApi, delegateAgreement, respondToAgreement, counterAgreement, claimOpenAgreement, proposeUnified, getAgreementStatus, listAgreements, getMyAgreements, getAgreement, publishOffer as publishOfferApi, createLink, revokeAgreement, fulfillAgreement, linkArtifactToAgreement, getArtifactsForAgreement, } from '@ziggs-ai/api-client';
2
2
  export class AgreementService {
3
3
  creds;
4
4
  constructor(operatorKey, agentId) {
@@ -105,12 +105,6 @@ export class AgreementService {
105
105
  fulfill(agreementId) {
106
106
  return fulfillAgreement(agreementId, this.creds);
107
107
  }
108
- linkToChat(agreementId, chatId, linkType = 'mention') {
109
- return linkAgreementToChat(agreementId, chatId, linkType, this.creds);
110
- }
111
- getChats(agreementId) {
112
- return getChatsForAgreement(agreementId, this.creds);
113
- }
114
108
  linkArtifact(agreementId, artifactId, linkType = 'produced') {
115
109
  return linkArtifactToAgreement(agreementId, artifactId, linkType, this.creds);
116
110
  }
@@ -1,5 +1,6 @@
1
- import { type InboxChatNews, type InboxRequestRef, type InboxTaskRef, type Creds } from '@ziggs-ai/api-client';
1
+ import { type InboxRequestRef, type InboxTaskRef, type Creds } from '@ziggs-ai/api-client';
2
2
  import { SeenMessages } from './SeenMessages.js';
3
+ import type { TaskInputRef } from '../types.js';
3
4
  /**
4
5
  * Per-agent inbox long-poll loop (delivery law, phase 4). This is the ONLY way
5
6
  * a hosted agent consumes: `GET /inbox?wait=` → grant-fenced reads of what was
@@ -25,7 +26,7 @@ export interface InboxLoopDeps {
25
26
  * own task channel, so work reaches the agent even when no chat row exists
26
27
  * for it (chat-less agreement, self-assigned task).
27
28
  */
28
- onTask?: (task: InboxTaskRef) => Promise<void>;
29
+ onTask?: (task: InboxTaskRef, inputs: TaskInputRef[]) => Promise<void>;
29
30
  /**
30
31
  * A marketplace request doorbell. The host MUST triage with a plain
31
32
  * string compare and return without an LLM wake on miss — otherwise every
@@ -62,13 +63,6 @@ export interface InboxPassResult {
62
63
  */
63
64
  blocked: number;
64
65
  }
65
- /**
66
- * A capability probe waits on a `probe_*` chat reply, not inbox ack. Act
67
- * those rooms before leftover mail so a standing host answers the gate
68
- * even when the envelope also carries older chats. The prefix only orders
69
- * the wake — it does not buy a canned answer.
70
- */
71
- export declare function chatsInWakeOrder(chats: InboxChatNews[]): InboxChatNews[];
72
66
  /**
73
67
  * One long-poll pass: hold up to `waitSeconds` for new inbox content, then read
74
68
  * the deltas, deliver them into the host, and ack. Returns what it delivered.