@ziggs-ai/api-client 0.37.27 → 0.38.0
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/CHANGELOG.md +10 -0
- package/dist/capabilities/artifacts.js +9 -9
- package/dist/capabilities/connections.js +3 -8
- package/dist/capabilities/context.js +15 -4
- package/dist/capabilities/grants.js +1 -4
- package/dist/capabilities/introductions.js +13 -12
- package/dist/capabilities/mcpBriefs.js +10 -1
- package/dist/capabilities/payments.js +2 -7
- package/dist/http/AgreementClient.d.ts +10 -2
- package/dist/http/AgreementClient.js +6 -4
- package/dist/http/ArtifactsClient.d.ts +2 -9
- package/dist/http/ArtifactsClient.js +3 -11
- package/dist/http/AssistantConnectionClient.d.ts +1 -1
- package/dist/http/AssistantConnectionClient.js +2 -2
- package/dist/http/ConnectionsClient.d.ts +2 -12
- package/dist/http/ConnectionsClient.js +4 -15
- package/dist/http/ContextGrantsClient.d.ts +1 -0
- package/dist/http/ContextGrantsClient.js +1 -1
- package/dist/http/ContextOpenClient.d.ts +2 -3
- package/dist/http/ContextOpenClient.js +2 -4
- package/dist/http/ContextReadClient.d.ts +5 -13
- package/dist/http/ContextReadClient.js +4 -19
- package/dist/http/ExecutionContextClient.d.ts +3 -0
- package/dist/http/ExecutionContextClient.js +17 -0
- package/dist/http/GrantsClient.d.ts +2 -10
- package/dist/http/GrantsClient.js +3 -12
- package/dist/http/InboxClient.d.ts +2 -2
- package/dist/http/InboxClient.js +1 -3
- package/dist/http/IntroductionsClient.d.ts +21 -1
- package/dist/http/PaymentsClient.d.ts +2 -15
- package/dist/http/PaymentsClient.js +4 -18
- package/dist/http/SessionsClient.d.ts +34 -0
- package/dist/http/SessionsClient.js +72 -0
- package/dist/http/TelemetryClient.js +3 -3
- package/dist/http/ToolPickClient.js +2 -2
- package/dist/http/index.d.ts +3 -1
- package/dist/http/index.js +2 -1
- package/dist/http/operatorHeaders.d.ts +14 -36
- package/dist/http/operatorHeaders.js +26 -50
- package/dist/inboxAck.d.ts +14 -46
- package/dist/inboxAck.js +12 -102
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/types.d.ts +15 -16
- package/package.json +2 -2
package/dist/inboxAck.d.ts
CHANGED
|
@@ -1,70 +1,38 @@
|
|
|
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
|
-
*/
|
|
1
|
+
/** Observation and handling are independent. Only explicit responsibility IDs settle work. */
|
|
9
2
|
export interface InboxAckEnvelope {
|
|
10
3
|
ackTo?: string | null;
|
|
11
4
|
deliveries?: ReadonlyArray<{
|
|
12
5
|
resourceId?: string | null;
|
|
6
|
+
responsibilityId?: string | null;
|
|
13
7
|
assigneeId?: string | null;
|
|
14
8
|
outOfReach?: unknown;
|
|
15
|
-
|
|
9
|
+
executionBlocked?: unknown;
|
|
16
10
|
ts?: string | null;
|
|
17
|
-
/** Mark covering this row and everything before it in this window. */
|
|
18
11
|
ackTo?: string | null;
|
|
19
12
|
}>;
|
|
20
13
|
openRequestsAwaitingMe?: ReadonlyArray<{
|
|
21
14
|
agreementId?: string | null;
|
|
15
|
+
responsibilityId?: string | null;
|
|
22
16
|
ts?: string | null;
|
|
23
17
|
}>;
|
|
24
18
|
}
|
|
25
|
-
export interface InboxAckDecision {
|
|
26
|
-
/** True when this envelope may be acknowledged. */
|
|
27
|
-
allowed: boolean;
|
|
28
|
-
handledResourceIds: string[];
|
|
29
|
-
}
|
|
30
19
|
export interface PlanInboxAckOptions {
|
|
31
|
-
/**
|
|
32
|
-
* Rows whose `assigneeId` equals this are mine. Empty or omitted: every
|
|
33
|
-
* delivery counts (the MCP tool with no configured self id).
|
|
34
|
-
*/
|
|
35
20
|
ownAgentId?: string;
|
|
36
21
|
ownAgentIds?: readonly string[];
|
|
37
|
-
/** Failed handovers hold the watermark unless `forceAck`. */
|
|
38
22
|
failures?: number;
|
|
39
23
|
forceAck?: boolean;
|
|
40
24
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
export declare function planInboxAck(envelope: InboxAckEnvelope, opts?: PlanInboxAckOptions): InboxAckDecision;
|
|
46
|
-
/** How far a reader may ack right now, mid-pass. */
|
|
25
|
+
export interface InboxAckDecision {
|
|
26
|
+
allowed: boolean;
|
|
27
|
+
handledDeliveryIds: string[];
|
|
28
|
+
}
|
|
47
29
|
export interface InboxAckStep {
|
|
48
|
-
/** A row's own token — never one the client made up. */
|
|
49
30
|
ackTo: string;
|
|
50
|
-
|
|
31
|
+
handledDeliveryIds: string[];
|
|
51
32
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
* which is long enough for the stand-in's 90s takeover to elapse while the
|
|
58
|
-
* agent is still working. This lets the reader give the mark back in steps.
|
|
59
|
-
*
|
|
60
|
-
* The stopping point is a global instant, NOT the reader's current unit of
|
|
61
|
-
* work. A mark advances every source it names at once, so acking after one
|
|
62
|
-
* chat fold would bury an older row from a different chat — the guard would
|
|
63
|
-
* refuse it, correctly. So: walk the instants the server minted a token for,
|
|
64
|
-
* and stop at the last one where everything at or before it is handled.
|
|
65
|
-
* Anything else is either refused or a bug.
|
|
66
|
-
*
|
|
67
|
-
* Returns null when the server minted no per-row tokens, which is how an older
|
|
68
|
-
* backend is handled: the caller keeps its single end-of-pass ack.
|
|
69
|
-
*/
|
|
33
|
+
export declare function inboxAckHandledIds(envelope: InboxAckEnvelope, ownAgentId?: string, ownAgentIds?: readonly string[]): string[];
|
|
34
|
+
export declare function inboxAckAllowed(envelope: InboxAckEnvelope, opts?: PlanInboxAckOptions): boolean;
|
|
35
|
+
/** Full-pass helper: only use after every listed responsibility succeeded. */
|
|
36
|
+
export declare function planInboxAck(envelope: InboxAckEnvelope, opts?: PlanInboxAckOptions): InboxAckDecision;
|
|
37
|
+
/** Successful jobs can be handled in any order, even when another job failed. */
|
|
70
38
|
export declare function planPartialInboxAck(envelope: InboxAckEnvelope, handled: ReadonlySet<string>, opts?: PlanInboxAckOptions): InboxAckStep | null;
|
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 = (
|
|
20
|
-
return [
|
|
21
|
-
|
|
22
|
-
...(envelope.
|
|
23
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
@@ -380,6 +367,8 @@ export interface InboxChatNews {
|
|
|
380
367
|
latestAt: string;
|
|
381
368
|
}
|
|
382
369
|
export interface InboxProposalRef {
|
|
370
|
+
executionContext?: import('@ziggs-ai/contracts').WorkExecutionContext;
|
|
371
|
+
executionBlocked?: import('@ziggs-ai/contracts').ExecutionBlock;
|
|
383
372
|
agreementId: string;
|
|
384
373
|
title: string;
|
|
385
374
|
proposedAt: string | null;
|
|
@@ -441,6 +430,8 @@ export interface InboxHumanAttention {
|
|
|
441
430
|
* agreement (or self-assigned) reached nobody.
|
|
442
431
|
*/
|
|
443
432
|
export interface InboxTaskRef {
|
|
433
|
+
executionContext?: import('@ziggs-ai/contracts').WorkExecutionContext;
|
|
434
|
+
executionBlocked?: import('@ziggs-ai/contracts').ExecutionBlock;
|
|
444
435
|
taskId: string;
|
|
445
436
|
agreementId: string | null;
|
|
446
437
|
title: string;
|
|
@@ -488,7 +479,7 @@ export interface InboxEnvelope extends InboxRequestChannel {
|
|
|
488
479
|
/** This agent's ASSIGNED chat mail, folded by chat. */
|
|
489
480
|
chats: InboxChatNews[];
|
|
490
481
|
/**
|
|
491
|
-
* Opaque watermark bundle. Pass to `ack(upTo, {
|
|
482
|
+
* Opaque watermark bundle. Pass to `ack(upTo, { handledDeliveryIds })`
|
|
492
483
|
* VERBATIM after acting — never construct or parse one; the per-mailbox
|
|
493
484
|
* positions live inside the value. Null when there is nothing to ack. Ack
|
|
494
485
|
* after acting, not after reading: a crash in between redelivers. Listing
|
|
@@ -510,6 +501,14 @@ export interface InboxEnvelope extends InboxRequestChannel {
|
|
|
510
501
|
export interface InboxAckResult {
|
|
511
502
|
/** Where the watermark now sits. Monotonic — a rewind is a no-op, not an error. */
|
|
512
503
|
ackedUpTo: string | null;
|
|
504
|
+
/**
|
|
505
|
+
* Handled ids the server left pending: assigned to you, but the work became
|
|
506
|
+
* unreadable or blocked before the ack. Every other id in the ack settled.
|
|
507
|
+
*/
|
|
508
|
+
refusedDeliveryIds?: Array<{
|
|
509
|
+
id: string;
|
|
510
|
+
reason: string;
|
|
511
|
+
}>;
|
|
513
512
|
}
|
|
514
513
|
/**
|
|
515
514
|
* 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.
|
|
3
|
+
"version": "0.38.0",
|
|
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.
|
|
34
|
+
"@ziggs-ai/contracts": "^0.32.0",
|
|
35
35
|
"socket.io-client": "^4.7.0"
|
|
36
36
|
},
|
|
37
37
|
"keywords": [
|