@ziggs-ai/api-client 0.37.28 → 0.38.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.
Files changed (54) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/capabilities/agreements.js +2 -2
  3. package/dist/capabilities/artifacts.d.ts +6 -0
  4. package/dist/capabilities/artifacts.js +52 -9
  5. package/dist/capabilities/connections.js +3 -8
  6. package/dist/capabilities/context.js +28 -6
  7. package/dist/capabilities/grants.js +1 -4
  8. package/dist/capabilities/index.d.ts +2 -2
  9. package/dist/capabilities/index.js +2 -2
  10. package/dist/capabilities/introductions.d.ts +1 -0
  11. package/dist/capabilities/introductions.js +63 -8
  12. package/dist/capabilities/links.js +33 -11
  13. package/dist/capabilities/mcpBriefs.js +20 -7
  14. package/dist/capabilities/payments.js +2 -7
  15. package/dist/capabilities/tasks.d.ts +1 -0
  16. package/dist/capabilities/tasks.js +42 -1
  17. package/dist/http/AgreementClient.d.ts +19 -2
  18. package/dist/http/AgreementClient.js +6 -4
  19. package/dist/http/ArtifactsClient.d.ts +16 -9
  20. package/dist/http/ArtifactsClient.js +16 -11
  21. package/dist/http/AssistantConnectionClient.d.ts +1 -1
  22. package/dist/http/AssistantConnectionClient.js +2 -2
  23. package/dist/http/ConnectionsClient.d.ts +2 -12
  24. package/dist/http/ConnectionsClient.js +4 -15
  25. package/dist/http/ContextGrantsClient.d.ts +2 -0
  26. package/dist/http/ContextGrantsClient.js +1 -1
  27. package/dist/http/ContextOpenClient.d.ts +2 -3
  28. package/dist/http/ContextOpenClient.js +2 -4
  29. package/dist/http/ContextReadClient.d.ts +5 -13
  30. package/dist/http/ContextReadClient.js +4 -19
  31. package/dist/http/ExecutionContextClient.d.ts +3 -0
  32. package/dist/http/ExecutionContextClient.js +17 -0
  33. package/dist/http/GrantsClient.d.ts +2 -10
  34. package/dist/http/GrantsClient.js +3 -12
  35. package/dist/http/InboxClient.d.ts +2 -2
  36. package/dist/http/InboxClient.js +1 -3
  37. package/dist/http/IntroductionsClient.d.ts +28 -1
  38. package/dist/http/IntroductionsClient.js +6 -2
  39. package/dist/http/PaymentsClient.d.ts +2 -15
  40. package/dist/http/PaymentsClient.js +4 -18
  41. package/dist/http/TaskClient.d.ts +24 -1
  42. package/dist/http/TaskClient.js +27 -2
  43. package/dist/http/TelemetryClient.js +3 -3
  44. package/dist/http/ToolPickClient.js +2 -2
  45. package/dist/http/index.d.ts +1 -1
  46. package/dist/http/index.js +1 -1
  47. package/dist/http/operatorHeaders.d.ts +14 -36
  48. package/dist/http/operatorHeaders.js +26 -50
  49. package/dist/inboxAck.d.ts +14 -46
  50. package/dist/inboxAck.js +12 -102
  51. package/dist/index.d.ts +3 -0
  52. package/dist/index.js +3 -0
  53. package/dist/types.d.ts +25 -16
  54. package/package.json +2 -2
package/dist/inboxAck.js CHANGED
@@ -1,111 +1,21 @@
1
- /**
2
- * One answer for "what does this envelope's ack list, and may we send it?"
3
- *
4
- * The SDK loop and the MCP inbox tool both call this. The bury-guard is the
5
- * same question on both rails: list every assigned row this reader actually
6
- * handled, and do not ack a window that is incomplete or that failed in its
7
- * hands.
8
- */
9
- function isOutOfReach(note) {
10
- if (!note || typeof note !== 'object')
11
- return false;
12
- const n = note;
13
- return (typeof n.scopeKind === 'string' &&
14
- typeof n.scopeId === 'string' &&
15
- typeof n.remedy === 'string');
16
- }
17
- /** Resource ids this envelope's ack must list. */
18
1
  export function inboxAckHandledIds(envelope, ownAgentId, ownAgentIds) {
19
- const mine = (assigneeId) => ownAgentIds ? ownAgentIds.includes(assigneeId ?? '') : !ownAgentId || assigneeId === ownAgentId;
20
- return [
21
- ...new Set([
22
- ...(envelope.deliveries ?? [])
23
- .filter((d) => mine(d.assigneeId))
24
- .filter((d) => !isOutOfReach(d.outOfReach))
25
- .map((d) => d.resourceId),
26
- ...(envelope.openRequestsAwaitingMe ?? []).map((q) => q.agreementId),
27
- ]),
28
- ].filter((id) => typeof id === 'string' && id.length > 0);
2
+ const mine = (id) => ownAgentIds ? ownAgentIds.includes(id ?? '') : ownAgentId ? id === ownAgentId : !!id;
3
+ return [...new Set([
4
+ ...(envelope.deliveries ?? []).filter(d => mine(d.assigneeId) && !d.outOfReach && !d.executionBlocked).map(d => d.responsibilityId),
5
+ ...(envelope.openRequestsAwaitingMe ?? []).map(r => r.responsibilityId),
6
+ ].filter((id) => !!id))];
29
7
  }
30
- /** Whether an ack is allowed for this envelope, given handover state. */
31
8
  export function inboxAckAllowed(envelope, opts = {}) {
32
- if (!envelope.ackTo)
33
- return false;
34
- const failures = opts.failures ?? 0;
35
- if (failures > 0 && !opts.forceAck)
36
- return false;
37
- return true;
9
+ return !!envelope.ackTo && (!(opts.failures ?? 0) || !!opts.forceAck);
38
10
  }
11
+ /** Full-pass helper: only use after every listed responsibility succeeded. */
39
12
  export function planInboxAck(envelope, opts = {}) {
40
- return {
41
- allowed: inboxAckAllowed(envelope, opts),
42
- handledResourceIds: inboxAckHandledIds(envelope, opts.ownAgentId, opts.ownAgentIds),
43
- };
44
- }
45
- /** Every row whose instant the server's bury-guard will ask about. */
46
- function gatingRows(envelope, ownAgentId, ownAgentIds) {
47
- const mine = (assigneeId) => ownAgentIds ? ownAgentIds.includes(assigneeId ?? '') : !ownAgentId || assigneeId === ownAgentId;
48
- return [
49
- ...(envelope.deliveries ?? [])
50
- .filter((d) => mine(d.assigneeId))
51
- .filter((d) => !isOutOfReach(d.outOfReach))
52
- .map((d) => ({ id: d.resourceId ?? '', ts: d.ts ?? '' })),
53
- // Requests are projected out of `deliveries` for triage, but their rows
54
- // are still in the log under the caller's stamp, so they gate a mark
55
- // exactly as a delivery does.
56
- ...(envelope.openRequestsAwaitingMe ?? []).map((q) => ({
57
- id: q.agreementId ?? '',
58
- ts: q.ts ?? '',
59
- })),
60
- ].filter((r) => r.id.length > 0 && r.ts.length > 0);
13
+ return { allowed: inboxAckAllowed(envelope, opts), handledDeliveryIds: inboxAckHandledIds(envelope, opts.ownAgentId, opts.ownAgentIds) };
61
14
  }
62
- /**
63
- * The furthest point in this envelope that is safe to ack RIGHT NOW, given what
64
- * the reader has finished so far, or null when that is nowhere.
65
- *
66
- * Acking once at the end of a pass freezes the watermark for the whole pass,
67
- * which is long enough for the stand-in's 90s takeover to elapse while the
68
- * agent is still working. This lets the reader give the mark back in steps.
69
- *
70
- * The stopping point is a global instant, NOT the reader's current unit of
71
- * work. A mark advances every source it names at once, so acking after one
72
- * chat fold would bury an older row from a different chat — the guard would
73
- * refuse it, correctly. So: walk the instants the server minted a token for,
74
- * and stop at the last one where everything at or before it is handled.
75
- * Anything else is either refused or a bug.
76
- *
77
- * Returns null when the server minted no per-row tokens, which is how an older
78
- * backend is handled: the caller keeps its single end-of-pass ack.
79
- */
15
+ /** Successful jobs can be handled in any order, even when another job failed. */
80
16
  export function planPartialInboxAck(envelope, handled, opts = {}) {
81
- const failures = opts.failures ?? 0;
82
- if (failures > 0 && !opts.forceAck)
83
- return null;
84
- const tokenByInstant = new Map();
85
- for (const d of envelope.deliveries ?? []) {
86
- if (d.ts && d.ackTo)
87
- tokenByInstant.set(d.ts, d.ackTo);
88
- }
89
- if (tokenByInstant.size === 0)
90
- return null;
91
- const gating = gatingRows(envelope, opts.ownAgentId, opts.ownAgentIds);
92
- // ISO-8601 sorts lexicographically in time order, which is what every other
93
- // ts comparison on this rail already relies on.
94
- const instants = [...tokenByInstant.keys()].sort();
95
- let upTo = null;
96
- for (const instant of instants) {
97
- const settled = gating.every((r) => r.ts > instant || handled.has(r.id));
98
- if (!settled)
99
- break;
100
- upTo = instant;
101
- }
102
- if (!upTo)
17
+ if (!envelope.ackTo)
103
18
  return null;
104
- const reached = upTo;
105
- return {
106
- ackTo: tokenByInstant.get(reached),
107
- handledResourceIds: [
108
- ...new Set(gating.filter((r) => r.ts <= reached).map((r) => r.id)),
109
- ],
110
- };
19
+ const ids = inboxAckHandledIds(envelope, opts.ownAgentId, opts.ownAgentIds).filter(id => handled.has(id));
20
+ return ids.length ? { ackTo: envelope.ackTo, handledDeliveryIds: ids } : null;
111
21
  }
package/dist/index.d.ts CHANGED
@@ -34,3 +34,6 @@ export { AssistantConnectionClient, type AssistantWorkspace, type McpEventStatus
34
34
  export { withAssistantRequest, assistantRequestHeaders } from './http/operatorHeaders.js';
35
35
  export { HANDLE_ALPHABET, findHandles, looksLikeHandle, parseHandle, parseRef, type HandleKind } from './handles.js';
36
36
  export { describeOperationError, type OperationError } from './shared/operationError.js';
37
+ export { withWorkExecution, withWorkExecutionId, currentWorkExecution, withoutExecution } from './http/operatorHeaders.js';
38
+ export { deliveryHandlingId, type WorkExecutionContext, type WorkPositionView } from '@ziggs-ai/contracts';
39
+ export { validateWorkExecution } from './http/ExecutionContextClient.js';
package/dist/index.js CHANGED
@@ -32,3 +32,6 @@ export { withAssistantRequest, assistantRequestHeaders } from './http/operatorHe
32
32
  // Short handles: T…, A…, C…, F… (task, agreement, chat, artifact).
33
33
  export { HANDLE_ALPHABET, findHandles, looksLikeHandle, parseHandle, parseRef } from './handles.js';
34
34
  export { describeOperationError } from './shared/operationError.js';
35
+ export { withWorkExecution, withWorkExecutionId, currentWorkExecution, withoutExecution } from './http/operatorHeaders.js';
36
+ export { deliveryHandlingId } from '@ziggs-ai/contracts';
37
+ export { validateWorkExecution } from './http/ExecutionContextClient.js';
package/dist/types.d.ts CHANGED
@@ -19,23 +19,10 @@ export declare class RateLimitedError extends ApiError {
19
19
  constructor(message: string, retryAfterMs: number | null, body?: string, code?: string | null);
20
20
  }
21
21
  export interface Creds {
22
+ executionContextId?: string;
22
23
  operatorKey: string;
23
24
  agentId: string;
24
- /**
25
- * the lane (chat id, or `agrn-<agreementId>`) this call is being
26
- * made from. Sent as `X-Ziggs-Lane` so the backend can fence the wake to the
27
- * engagement the agent is actually acting inside.
28
- *
29
- * The operator key says WHO is calling; this says ON WHOSE BEHALF, RIGHT NOW.
30
- * Without it an agent serving several customers carries its full authority
31
- * into every call, so a read spans every engagement it holds rather than
32
- * staying inside the one being worked.
33
- *
34
- * Optional, and omitting it can only narrow what comes back (the backend
35
- * falls back to the agent's own org) — never widen it. Nothing here is
36
- * trusted: the server re-derives the party orgs itself and refuses a lane the
37
- * agent is not in.
38
- */
25
+ /** Presentation routing only; authority comes from the execution context. */
39
26
  laneId?: string;
40
27
  /**
41
28
  * This host's stable identity, sent as `X-Ziggs-Instance` on inbox reads and
@@ -94,6 +81,16 @@ export interface Task {
94
81
  updatedAt?: string;
95
82
  parentTaskId?: string;
96
83
  rootTaskId?: string;
84
+ requiredInputArtifactIds?: string[];
85
+ delegations?: Array<{
86
+ taskId: string;
87
+ state: TaskState;
88
+ returnedArtifactId: string | null;
89
+ }>;
90
+ delegation?: {
91
+ instructionArtifactId: string;
92
+ returnedArtifactId?: string;
93
+ } | null;
97
94
  /** Tasks this one waits for before it may start. */
98
95
  waitsOn?: string[];
99
96
  /**
@@ -380,6 +377,8 @@ export interface InboxChatNews {
380
377
  latestAt: string;
381
378
  }
382
379
  export interface InboxProposalRef {
380
+ executionContext?: import('@ziggs-ai/contracts').WorkExecutionContext;
381
+ executionBlocked?: import('@ziggs-ai/contracts').ExecutionBlock;
383
382
  agreementId: string;
384
383
  title: string;
385
384
  proposedAt: string | null;
@@ -441,6 +440,8 @@ export interface InboxHumanAttention {
441
440
  * agreement (or self-assigned) reached nobody.
442
441
  */
443
442
  export interface InboxTaskRef {
443
+ executionContext?: import('@ziggs-ai/contracts').WorkExecutionContext;
444
+ executionBlocked?: import('@ziggs-ai/contracts').ExecutionBlock;
444
445
  taskId: string;
445
446
  agreementId: string | null;
446
447
  title: string;
@@ -488,7 +489,7 @@ export interface InboxEnvelope extends InboxRequestChannel {
488
489
  /** This agent's ASSIGNED chat mail, folded by chat. */
489
490
  chats: InboxChatNews[];
490
491
  /**
491
- * Opaque watermark bundle. Pass to `ack(upTo, { handledResourceIds })`
492
+ * Opaque watermark bundle. Pass to `ack(upTo, { handledDeliveryIds })`
492
493
  * VERBATIM after acting — never construct or parse one; the per-mailbox
493
494
  * positions live inside the value. Null when there is nothing to ack. Ack
494
495
  * after acting, not after reading: a crash in between redelivers. Listing
@@ -510,6 +511,14 @@ export interface InboxEnvelope extends InboxRequestChannel {
510
511
  export interface InboxAckResult {
511
512
  /** Where the watermark now sits. Monotonic — a rewind is a no-op, not an error. */
512
513
  ackedUpTo: string | null;
514
+ /**
515
+ * Handled ids the server left pending: assigned to you, but the work became
516
+ * unreadable or blocked before the ack. Every other id in the ack settled.
517
+ */
518
+ refusedDeliveryIds?: Array<{
519
+ id: string;
520
+ reason: string;
521
+ }>;
513
522
  }
514
523
  /**
515
524
  * Long-poll option shared by the inbox reads. The server holds the request up
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ziggs-ai/api-client",
3
- "version": "0.37.28",
3
+ "version": "0.38.2",
4
4
  "description": "HTTP and WebSocket client for the Ziggs backend API",
5
5
  "homepage": "https://ziggsai.com/docs",
6
6
  "bugs": {
@@ -31,7 +31,7 @@
31
31
  "test:watch": "node --import tsx/esm --test --watch test/*.test.ts"
32
32
  },
33
33
  "dependencies": {
34
- "@ziggs-ai/contracts": "^0.31.0",
34
+ "@ziggs-ai/contracts": "^0.33.1",
35
35
  "socket.io-client": "^4.7.0"
36
36
  },
37
37
  "keywords": [