@ziggs-ai/api-client 0.1.25 → 0.1.26
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/http/AgreementClient.d.ts +16 -1
- package/dist/http/AgreementClient.js +21 -0
- package/dist/http/ContextGrantsClient.d.ts +12 -15
- package/dist/http/MessagesClient.js +5 -1
- package/dist/http/TaskClient.js +32 -1
- package/dist/http/grants.d.ts +39 -0
- package/dist/http/grants.js +4 -0
- package/dist/http/index.d.ts +2 -0
- package/dist/http/index.js +1 -0
- package/dist/websocket/WebSocketClient.d.ts +6 -0
- package/package.json +1 -1
|
@@ -17,7 +17,12 @@ export interface ProposeTerms {
|
|
|
17
17
|
agreementDescription?: string;
|
|
18
18
|
parentAgreementId?: string;
|
|
19
19
|
parentTaskId?: string;
|
|
20
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Who does the work. Required on direct proposals (your own id = you offer;
|
|
22
|
+
* the proposedTo id = you commission the recipient); forbidden on
|
|
23
|
+
* broadcasts. The payer is always derived server-side as the non-providing
|
|
24
|
+
* side — there is no payer input.
|
|
25
|
+
*/
|
|
21
26
|
providerId?: string;
|
|
22
27
|
plan?: unknown;
|
|
23
28
|
planReviewTiming?: PlanReviewTiming;
|
|
@@ -146,6 +151,12 @@ export declare function revokeAgreement(agreementId: string, creds: Creds): Prom
|
|
|
146
151
|
ok: boolean;
|
|
147
152
|
agreement: Agreement;
|
|
148
153
|
}>;
|
|
154
|
+
/** ZIG-832: mark an agreement fulfilled (complete). A provider closing its own
|
|
155
|
+
* delivered work — party-gated server-side. */
|
|
156
|
+
export declare function fulfillAgreement(agreementId: string, creds: Creds): Promise<{
|
|
157
|
+
ok: boolean;
|
|
158
|
+
agreement: Agreement;
|
|
159
|
+
}>;
|
|
149
160
|
/**
|
|
150
161
|
* Claim an open agreement (ZIG-524 phase 2 / ZIG-525):
|
|
151
162
|
* - open link invite (`engagementKind: link`, proposedTo everyone)
|
|
@@ -200,6 +211,10 @@ export declare class AgreementClient {
|
|
|
200
211
|
ok: boolean;
|
|
201
212
|
agreement: Agreement;
|
|
202
213
|
}>;
|
|
214
|
+
fulfill(id: string): Promise<{
|
|
215
|
+
ok: boolean;
|
|
216
|
+
agreement: Agreement;
|
|
217
|
+
}>;
|
|
203
218
|
claimAgreement(id: string): Promise<{
|
|
204
219
|
ok: boolean;
|
|
205
220
|
agreement: Agreement;
|
|
@@ -370,6 +370,26 @@ export async function revokeAgreement(agreementId, creds) {
|
|
|
370
370
|
}
|
|
371
371
|
return data;
|
|
372
372
|
}
|
|
373
|
+
/** ZIG-832: mark an agreement fulfilled (complete). A provider closing its own
|
|
374
|
+
* delivered work — party-gated server-side. */
|
|
375
|
+
export async function fulfillAgreement(agreementId, creds) {
|
|
376
|
+
if (!agreementId)
|
|
377
|
+
throw new Error('agreementId is required to fulfill');
|
|
378
|
+
assertCreds(creds, 'agreement fulfillment');
|
|
379
|
+
const res = await fetch(`${getAgreementBaseUrl()}/${encodeURIComponent(agreementId)}/fulfill`, {
|
|
380
|
+
method: 'POST',
|
|
381
|
+
headers: buildHeaders(creds),
|
|
382
|
+
});
|
|
383
|
+
if (!res.ok) {
|
|
384
|
+
const body = await res.text().catch(() => '');
|
|
385
|
+
throwApiError(res, body, `Agreement fulfillment failed: ${res.status} ${res.statusText}`);
|
|
386
|
+
}
|
|
387
|
+
const data = await res.json().catch(() => null);
|
|
388
|
+
if (!data?.['agreement']) {
|
|
389
|
+
throw new Error('Invalid response: expected { ok, agreement } from POST /agreements/:id/fulfill');
|
|
390
|
+
}
|
|
391
|
+
return data;
|
|
392
|
+
}
|
|
373
393
|
/**
|
|
374
394
|
* Claim an open agreement (ZIG-524 phase 2 / ZIG-525):
|
|
375
395
|
* - open link invite (`engagementKind: link`, proposedTo everyone)
|
|
@@ -596,6 +616,7 @@ export class AgreementClient {
|
|
|
596
616
|
get(id) { return getAgreement(id, this.creds); }
|
|
597
617
|
create(data) { return createAgreement(data, this.creds); }
|
|
598
618
|
revoke(id) { return revokeAgreement(id, this.creds); }
|
|
619
|
+
fulfill(id) { return fulfillAgreement(id, this.creds); }
|
|
599
620
|
claimAgreement(id) { return claimAgreement(id, this.creds); }
|
|
600
621
|
listByChat(chatId) { return getAgreementsByChat(chatId, this.creds); }
|
|
601
622
|
linkToChat(id, chatId, linkType) { return linkAgreementToChat(id, chatId, linkType ?? 'mention', this.creds); }
|
|
@@ -1,23 +1,20 @@
|
|
|
1
1
|
import 'dotenv/config';
|
|
2
|
+
import type { GrantView } from './grants.js';
|
|
2
3
|
export type ContextGrantScopeKind = 'chat' | 'agreement' | 'org';
|
|
3
4
|
export type ContextTemporal = 'from-now' | 'from-start';
|
|
4
5
|
export interface ContextGrantScope {
|
|
5
6
|
kind: ContextGrantScopeKind;
|
|
6
7
|
id: string;
|
|
7
8
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
expiresAt: string | null;
|
|
18
|
-
revoked: boolean;
|
|
19
|
-
createdAt: string;
|
|
20
|
-
}
|
|
9
|
+
/**
|
|
10
|
+
* @deprecated ZIG-646 — context grants now serialise to the canonical
|
|
11
|
+
* {@link GrantView} like every other rail. This alias previously declared a
|
|
12
|
+
* flat `scopeKind`/`scopeId` + `revoked` shape that the backend never actually
|
|
13
|
+
* emitted (it sends nested `scope: { kind, id }` and folds temporal/watermark
|
|
14
|
+
* into `caveats`), so reads like `record.scopeKind` were always `undefined`.
|
|
15
|
+
* Use `GrantView`; this remains only so existing name-imports keep resolving.
|
|
16
|
+
*/
|
|
17
|
+
export type ContextGrantRecord = GrantView;
|
|
21
18
|
export interface IssueContextGrantInput {
|
|
22
19
|
holderId: string;
|
|
23
20
|
scope: ContextGrantScope;
|
|
@@ -36,7 +33,7 @@ export interface DelegateContextGrantInput {
|
|
|
36
33
|
* approves — no grant is minted until then. */
|
|
37
34
|
export type DelegateContextGrantResult = {
|
|
38
35
|
status: 'granted';
|
|
39
|
-
grant:
|
|
36
|
+
grant: GrantView;
|
|
40
37
|
} | {
|
|
41
38
|
status: 'pending_approval';
|
|
42
39
|
agreementId: string;
|
|
@@ -54,7 +51,7 @@ export declare class ContextGrantsClient {
|
|
|
54
51
|
* @param agentId Required for fleet keys (sent as X-Agent-Id). Omit for agent-scoped keys.
|
|
55
52
|
*/
|
|
56
53
|
constructor(operatorKey: string, agentId?: string, baseUrl?: string);
|
|
57
|
-
issueGrant(input: IssueContextGrantInput): Promise<
|
|
54
|
+
issueGrant(input: IssueContextGrantInput): Promise<GrantView>;
|
|
58
55
|
delegateGrant(parentGrantId: string, input: DelegateContextGrantInput): Promise<DelegateContextGrantResult>;
|
|
59
56
|
revokeGrant(grantId: string): Promise<{
|
|
60
57
|
status: string;
|
|
@@ -35,7 +35,11 @@ export class MessagesClient {
|
|
|
35
35
|
const res = await fetch(url.toString(), { headers: this._headers() });
|
|
36
36
|
if (!res.ok) {
|
|
37
37
|
const body = await res.text().catch(() => '');
|
|
38
|
-
|
|
38
|
+
const err = new Error(`MessagesClient.list ${res.status} ${res.statusText} ${body.slice(0, 200)}`);
|
|
39
|
+
// Callers branch on the HTTP status (404 = chat deleted/not visible)
|
|
40
|
+
// without parsing the message string.
|
|
41
|
+
err.status = res.status;
|
|
42
|
+
throw err;
|
|
39
43
|
}
|
|
40
44
|
return (await res.json());
|
|
41
45
|
}
|
package/dist/http/TaskClient.js
CHANGED
|
@@ -117,7 +117,38 @@ export async function getActiveTasksForAgent(agentId, creds) {
|
|
|
117
117
|
throwApiError(res, body, `Get active tasks for agent failed: ${res.status} ${res.statusText}`);
|
|
118
118
|
}
|
|
119
119
|
const data = await res.json().catch(() => null);
|
|
120
|
-
|
|
120
|
+
const fromAgent = Array.isArray(data?.['tasks']) ? data['tasks'] : [];
|
|
121
|
+
if (fromAgent.length > 0)
|
|
122
|
+
return fromAgent;
|
|
123
|
+
// Fallback when /agents/:id/tasks is empty but party-agreement tasks exist (ZIG-802).
|
|
124
|
+
return getActiveTasksForAgentViaPartyAgreements(agentId, creds);
|
|
125
|
+
}
|
|
126
|
+
async function getActiveTasksForAgentViaPartyAgreements(agentId, creds) {
|
|
127
|
+
const { listAgreements } = await import('./AgreementClient.js');
|
|
128
|
+
const agreements = await listAgreements({ status: 'active' }, creds);
|
|
129
|
+
const partyIds = agreements
|
|
130
|
+
.filter((a) => {
|
|
131
|
+
const p = a.parties ?? {};
|
|
132
|
+
return (p.provider === agentId ||
|
|
133
|
+
p.providerAgent === agentId ||
|
|
134
|
+
p.creator === agentId ||
|
|
135
|
+
p.payer === agentId);
|
|
136
|
+
})
|
|
137
|
+
.map((a) => a.agreementId)
|
|
138
|
+
.filter(Boolean);
|
|
139
|
+
if (partyIds.length === 0)
|
|
140
|
+
return [];
|
|
141
|
+
const lists = await Promise.all(partyIds.map(async (aid) => {
|
|
142
|
+
const url = new URL(`${getBackendUrl()}/agreements/${encodeURIComponent(aid)}/tasks`);
|
|
143
|
+
url.searchParams.set('state', 'active');
|
|
144
|
+
const res = await fetch(url.toString(), { method: 'GET', headers: buildHeaders(creds) });
|
|
145
|
+
if (!res.ok)
|
|
146
|
+
return [];
|
|
147
|
+
const data = await res.json().catch(() => null);
|
|
148
|
+
return Array.isArray(data?.['tasks']) ? data['tasks'] : [];
|
|
149
|
+
}));
|
|
150
|
+
const merged = lists.flat();
|
|
151
|
+
return merged.filter((t) => !t.assigneeId || t.assigneeId === agentId);
|
|
121
152
|
}
|
|
122
153
|
// Backend deliberately has no `/chats/:id/tasks` route — it's composable
|
|
123
154
|
// from links → per-agreement tasks. We do the composition here so callers
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ZIG-646: the one grant shape the backend presents on the wire, mirrored for
|
|
3
|
+
* SDK consumers. Context, connection, and payment grants all serialise to this
|
|
4
|
+
* exact object (see backend `src/grants/grant-view.ts`), so a caller reads one
|
|
5
|
+
* shape to answer "what grants exist, and are they live?" regardless of rail.
|
|
6
|
+
*
|
|
7
|
+
* `scope.kind` names the rail's resource: context grants keep chat/agreement/org;
|
|
8
|
+
* a connection grant is `connection` + connectionId; a payment grant is
|
|
9
|
+
* `wallet` + the root wallet id. A grant's bounds are its `caveats` — for
|
|
10
|
+
* context grants (which have no caveat column) the temporal mode and read
|
|
11
|
+
* watermark are presented as `temporal` / `watermark_at` caveats.
|
|
12
|
+
*/
|
|
13
|
+
export type GrantHealth = 'active' | 'expired' | 'revoked';
|
|
14
|
+
export type GrantScopeKind = 'chat' | 'agreement' | 'org' | 'connection' | 'wallet';
|
|
15
|
+
export interface GrantScopeView {
|
|
16
|
+
kind: GrantScopeKind;
|
|
17
|
+
id: string;
|
|
18
|
+
}
|
|
19
|
+
export interface GrantCaveatView {
|
|
20
|
+
type: string;
|
|
21
|
+
value: unknown;
|
|
22
|
+
}
|
|
23
|
+
export interface GrantView {
|
|
24
|
+
grantId: string;
|
|
25
|
+
issuerId: string;
|
|
26
|
+
holderId: string;
|
|
27
|
+
parentGrantId: string | null;
|
|
28
|
+
agreementId: string | null;
|
|
29
|
+
scope: GrantScopeView;
|
|
30
|
+
caveats: GrantCaveatView[];
|
|
31
|
+
revoked: boolean;
|
|
32
|
+
/** ISO-8601, or null for no expiry. */
|
|
33
|
+
expiresAt: string | null;
|
|
34
|
+
/** ISO-8601. */
|
|
35
|
+
createdAt: string;
|
|
36
|
+
health: GrantHealth;
|
|
37
|
+
}
|
|
38
|
+
/** Value of the first caveat of `type` on a grant, or undefined. */
|
|
39
|
+
export declare function grantCaveat(grant: GrantView, type: string): unknown | undefined;
|
package/dist/http/index.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ export { ContextDiscoveryClient } from './ContextDiscoveryClient.js';
|
|
|
14
14
|
export type { ContextReachDescriptor } from './ContextDiscoveryClient.js';
|
|
15
15
|
export { ContextGrantsClient } from './ContextGrantsClient.js';
|
|
16
16
|
export type { ContextGrantRecord, ContextGrantScope, ContextGrantScopeKind, ContextTemporal, IssueContextGrantInput, DelegateContextGrantInput, } from './ContextGrantsClient.js';
|
|
17
|
+
export { grantCaveat } from './grants.js';
|
|
18
|
+
export type { GrantView, GrantScopeKind, GrantScopeView, GrantCaveatView, GrantHealth, } from './grants.js';
|
|
17
19
|
export { AgentSearchClient } from './AgentSearchClient.js';
|
|
18
20
|
export { TelemetryClient } from './TelemetryClient.js';
|
|
19
21
|
export { InboxClient } from './InboxClient.js';
|
package/dist/http/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export { ScopeClient } from './ScopeClient.js';
|
|
|
8
8
|
export { ContextReadClient } from './ContextReadClient.js';
|
|
9
9
|
export { ContextDiscoveryClient } from './ContextDiscoveryClient.js';
|
|
10
10
|
export { ContextGrantsClient } from './ContextGrantsClient.js';
|
|
11
|
+
export { grantCaveat } from './grants.js';
|
|
11
12
|
export { AgentSearchClient } from './AgentSearchClient.js';
|
|
12
13
|
export { TelemetryClient } from './TelemetryClient.js';
|
|
13
14
|
export { InboxClient } from './InboxClient.js';
|
|
@@ -27,6 +27,12 @@ export interface ResourceEvent {
|
|
|
27
27
|
taskId?: string;
|
|
28
28
|
change?: 'created' | 'updated' | 'state-changed';
|
|
29
29
|
reason?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Principal whose action produced the event, when the backend knows it.
|
|
32
|
+
* Hosts drop events the receiving agent itself caused — its own writes
|
|
33
|
+
* aren't news to it.
|
|
34
|
+
*/
|
|
35
|
+
actorId?: string;
|
|
30
36
|
}
|
|
31
37
|
export type ResourceEventHandler = (event: ResourceEvent) => void | Promise<void>;
|
|
32
38
|
export interface SendOptions {
|