@ziggs-ai/api-client 0.10.4 → 0.11.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/dist/capabilities/agreementVerbs.d.ts +2 -2
- package/dist/capabilities/agreementVerbs.js +19 -19
- package/dist/capabilities/agreements.d.ts +1 -1
- package/dist/capabilities/agreements.js +5 -5
- package/dist/capabilities/artifacts.d.ts +4 -2
- package/dist/capabilities/artifacts.js +168 -33
- package/dist/capabilities/chat.d.ts +2 -3
- package/dist/capabilities/chat.js +5 -6
- package/dist/capabilities/connections.js +1 -1
- package/dist/capabilities/context.js +3 -0
- package/dist/capabilities/grants.d.ts +7 -6
- package/dist/capabilities/grants.js +9 -8
- package/dist/capabilities/index.d.ts +2 -2
- package/dist/capabilities/index.js +2 -2
- package/dist/capabilities/links.d.ts +1 -1
- package/dist/capabilities/links.js +5 -7
- package/dist/capabilities/marketplace.js +20 -14
- package/dist/capabilities/payments.d.ts +24 -8
- package/dist/capabilities/payments.js +28 -392
- package/dist/capabilities/proposeProviderId.d.ts +1 -1
- package/dist/capabilities/proposeProviderId.js +1 -1
- package/dist/http/AgreementClient.d.ts +24 -19
- package/dist/http/AgreementClient.js +22 -14
- package/dist/http/ChatClient.d.ts +1 -0
- package/dist/http/ChatClient.js +4 -1
- package/dist/http/ConnectionsClient.js +12 -1
- package/dist/http/ContextGrantsClient.d.ts +15 -1
- package/dist/http/ContextGrantsClient.js +2 -0
- package/dist/http/ContextReadClient.d.ts +14 -5
- package/dist/http/GrantsClient.d.ts +14 -0
- package/dist/http/GrantsClient.js +18 -2
- package/dist/http/MarketplaceClient.d.ts +6 -6
- package/dist/http/MarketplaceClient.js +11 -11
- package/dist/http/TaskClient.d.ts +5 -0
- package/dist/http/TaskClient.js +2 -0
- package/dist/http/agreementFlows.d.ts +4 -4
- package/dist/http/agreementFlows.js +9 -10
- package/dist/http/grants.d.ts +28 -0
- package/dist/http/index.d.ts +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/types.d.ts +44 -15
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type Creds, type Agreement, type EngagementKind, type BroadcastAudience } from '../types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Shared proposal terms. When `engagementKind` is omitted the server defaults to `service`.
|
|
4
|
-
* For an open buyer-broadcast
|
|
4
|
+
* For an open buyer-broadcast request, set `proposedTo` to a broadcast sentinel —
|
|
5
5
|
* `OPEN_AGREEMENT_TARGET` (`"everyone"`, fully public) or `ORG_AGREEMENT_TARGET`
|
|
6
6
|
* (`"org"`, scoped to your org). Prefer `proposeBroadcast({ audience })` over
|
|
7
7
|
* setting `proposedTo` by hand.
|
|
@@ -79,7 +79,7 @@ export declare function proposeAgreement(proposalData: ProposeDirectInput, creds
|
|
|
79
79
|
/** Propose a contract to one party (user or agent). Server defaults `engagementKind` to `service`. */
|
|
80
80
|
export declare function proposeDirectTo(input: ProposeDirectInput, creds: Creds): Promise<Agreement>;
|
|
81
81
|
/**
|
|
82
|
-
* Propose an open
|
|
82
|
+
* Propose an open request. `audience` ('everyone' default | 'org') picks the
|
|
83
83
|
* broadcast sentinel written to `proposedTo`. Server defaults `engagementKind`
|
|
84
84
|
* to `service`.
|
|
85
85
|
*/
|
|
@@ -146,7 +146,7 @@ export declare function resolveMyPendingApprovalPartyId(agreement: Agreement, op
|
|
|
146
146
|
*
|
|
147
147
|
* `partyId` MUST match the authenticated actor (`actor.id === partyId`): owner
|
|
148
148
|
* principal when approving as human, delegate agent id when impersonating.
|
|
149
|
-
* Canonical for hire, service, link, and
|
|
149
|
+
* Canonical for hire, service, link, and request proposals.
|
|
150
150
|
*/
|
|
151
151
|
export declare function approveAgreementAsParty(agreementId: string, partyId: string, status: 'approved' | 'rejected', creds: Creds): Promise<Agreement>;
|
|
152
152
|
export interface CounterAgreementData {
|
|
@@ -181,21 +181,26 @@ export interface GetMyAgreementsFilters {
|
|
|
181
181
|
export declare function getMyAgreements(filters: GetMyAgreementsFilters | undefined, creds: Creds): Promise<Agreement[]>;
|
|
182
182
|
/** One agreement, shaped: a link comes back as its summary. */
|
|
183
183
|
export declare function getAgreement(agreementId: string, creds: Creds): Promise<Agreement | null>;
|
|
184
|
-
export interface
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
price?: number;
|
|
189
|
-
lifecycle?: string;
|
|
190
|
-
expiresAt?: string;
|
|
191
|
-
maxExecutions?: number;
|
|
184
|
+
export interface CreateLinkBody {
|
|
185
|
+
/** Target agent for a direct link. Omit for an open, claimable invite. */
|
|
186
|
+
targetAgentId?: string;
|
|
187
|
+
/** Message shown to whoever is asked to approve or claim it. */
|
|
192
188
|
description?: string;
|
|
193
|
-
|
|
194
|
-
/** Link invites only: how many people may claim this one link. Default 1. */
|
|
189
|
+
/** Open invites only: how many people may claim this one link. Default 1. */
|
|
195
190
|
maxClaims?: number;
|
|
196
|
-
|
|
191
|
+
/** Which of the caller's own agents stands on their side of the link. */
|
|
192
|
+
asAgentId?: string;
|
|
197
193
|
}
|
|
198
|
-
|
|
194
|
+
/**
|
|
195
|
+
* Create a trust link — a direct proposal to one agent, or an open invite.
|
|
196
|
+
*
|
|
197
|
+
* This posts to `POST /agreements/links`. It used to post to `POST /agreements`,
|
|
198
|
+
* which also created work agreements inline and skipped the gates the proposal
|
|
199
|
+
* and marketplace paths run. Work agreements go through `proposeAgreement`
|
|
200
|
+
* (`POST /agreements/proposals`) and the marketplace claim routes; this rail
|
|
201
|
+
* carries links and nothing else.
|
|
202
|
+
*/
|
|
203
|
+
export declare function createLink(body: CreateLinkBody, creds: Creds): Promise<{
|
|
199
204
|
ok: boolean;
|
|
200
205
|
agreement: Agreement;
|
|
201
206
|
}>;
|
|
@@ -210,12 +215,12 @@ export declare function fulfillAgreement(agreementId: string, creds: Creds): Pro
|
|
|
210
215
|
agreement: Agreement;
|
|
211
216
|
}>;
|
|
212
217
|
/** What an open-broadcast claim resolved to. ⚠️ Mirrors the server; it is authoritative. */
|
|
213
|
-
export type ClaimedKind = 'link' | 'offer' | '
|
|
218
|
+
export type ClaimedKind = 'link' | 'offer' | 'request' | 'hand-off';
|
|
214
219
|
/**
|
|
215
220
|
* Claim an open agreement. Three shapes are claimable:
|
|
216
221
|
* - open link invite (`engagementKind: link`, proposedTo everyone)
|
|
217
|
-
* - open broadcast
|
|
218
|
-
* - org-scoped broadcast
|
|
222
|
+
* - open broadcast request (proposedTo 'everyone', status open)
|
|
223
|
+
* - org-scoped broadcast request (proposedTo 'org') — the server rejects the
|
|
219
224
|
* claim with 403 if the caller is not a member of the agreement's orgId
|
|
220
225
|
*
|
|
221
226
|
* POST /agreements/:id/claim — canonical; no partyId in body.
|
|
@@ -262,7 +267,7 @@ export declare class AgreementClient {
|
|
|
262
267
|
list(filters?: ListAgreementsFilters): Promise<Agreement[]>;
|
|
263
268
|
listMine(filters?: GetMyAgreementsFilters): Promise<Agreement[]>;
|
|
264
269
|
get(id: string): Promise<Agreement | null>;
|
|
265
|
-
|
|
270
|
+
createLink(data: CreateLinkBody): Promise<{
|
|
266
271
|
ok: boolean;
|
|
267
272
|
agreement: Agreement;
|
|
268
273
|
}>;
|
|
@@ -103,7 +103,7 @@ export async function proposeDirectTo(input, creds) {
|
|
|
103
103
|
return proposeAgreement(input, creds);
|
|
104
104
|
}
|
|
105
105
|
/**
|
|
106
|
-
* Propose an open
|
|
106
|
+
* Propose an open request. `audience` ('everyone' default | 'org') picks the
|
|
107
107
|
* broadcast sentinel written to `proposedTo`. Server defaults `engagementKind`
|
|
108
108
|
* to `service`.
|
|
109
109
|
*/
|
|
@@ -172,7 +172,7 @@ export async function respondToAgreement(agreementId, action, creds, opts = {})
|
|
|
172
172
|
const proposedTo = agreement.parties?.proposedTo;
|
|
173
173
|
if (isBroadcastTarget(proposedTo) || isBroadcastTarget(agreement.parties?.payer)) {
|
|
174
174
|
// respond is approve/reject on DIRECT proposals only. An open
|
|
175
|
-
// broadcast (
|
|
175
|
+
// broadcast (request, standing offer, link invite) has no per-recipient
|
|
176
176
|
// approval slot — a BYSTANDER can neither approve nor reject it
|
|
177
177
|
//; their move is to claim it, which has its own verb.
|
|
178
178
|
//
|
|
@@ -232,7 +232,7 @@ export function resolveMyPendingApprovalPartyId(agreement, opts) {
|
|
|
232
232
|
*
|
|
233
233
|
* `partyId` MUST match the authenticated actor (`actor.id === partyId`): owner
|
|
234
234
|
* principal when approving as human, delegate agent id when impersonating.
|
|
235
|
-
* Canonical for hire, service, link, and
|
|
235
|
+
* Canonical for hire, service, link, and request proposals.
|
|
236
236
|
*/
|
|
237
237
|
export async function approveAgreementAsParty(agreementId, partyId, status, creds) {
|
|
238
238
|
if (!agreementId)
|
|
@@ -406,23 +406,31 @@ export async function getAgreement(agreementId, creds) {
|
|
|
406
406
|
const agreement = await getAgreementDocument(agreementId, creds);
|
|
407
407
|
return agreement ? shapeAgreement(agreement) : null;
|
|
408
408
|
}
|
|
409
|
-
|
|
409
|
+
/**
|
|
410
|
+
* Create a trust link — a direct proposal to one agent, or an open invite.
|
|
411
|
+
*
|
|
412
|
+
* This posts to `POST /agreements/links`. It used to post to `POST /agreements`,
|
|
413
|
+
* which also created work agreements inline and skipped the gates the proposal
|
|
414
|
+
* and marketplace paths run. Work agreements go through `proposeAgreement`
|
|
415
|
+
* (`POST /agreements/proposals`) and the marketplace claim routes; this rail
|
|
416
|
+
* carries links and nothing else.
|
|
417
|
+
*/
|
|
418
|
+
export async function createLink(body, creds) {
|
|
410
419
|
if (!body)
|
|
411
|
-
throw new Error('Body is required for
|
|
412
|
-
assertCreds(creds, '
|
|
413
|
-
|
|
414
|
-
const res = await fetch(getAgreementBaseUrl(), {
|
|
420
|
+
throw new Error('Body is required for link creation');
|
|
421
|
+
assertCreds(creds, 'link creation');
|
|
422
|
+
const res = await fetch(`${getAgreementBaseUrl()}/links`, {
|
|
415
423
|
method: 'POST',
|
|
416
424
|
headers: buildHeaders(creds),
|
|
417
425
|
body: JSON.stringify(body),
|
|
418
426
|
});
|
|
419
427
|
if (!res.ok) {
|
|
420
428
|
const responseBody = await res.text().catch(() => '');
|
|
421
|
-
throwApiError(res, responseBody, `
|
|
429
|
+
throwApiError(res, responseBody, `Link creation failed: ${res.status} ${res.statusText}`);
|
|
422
430
|
}
|
|
423
431
|
const data = await res.json().catch(() => null);
|
|
424
432
|
if (!data?.['agreement']) {
|
|
425
|
-
throw new Error('Invalid response: expected { ok, agreement } from POST /agreements');
|
|
433
|
+
throw new Error('Invalid response: expected { ok, agreement } from POST /agreements/links');
|
|
426
434
|
}
|
|
427
435
|
const envelope = data;
|
|
428
436
|
return { ...envelope, agreement: shapeAgreement(envelope.agreement) };
|
|
@@ -472,8 +480,8 @@ export async function fulfillAgreement(agreementId, creds) {
|
|
|
472
480
|
/**
|
|
473
481
|
* Claim an open agreement. Three shapes are claimable:
|
|
474
482
|
* - open link invite (`engagementKind: link`, proposedTo everyone)
|
|
475
|
-
* - open broadcast
|
|
476
|
-
* - org-scoped broadcast
|
|
483
|
+
* - open broadcast request (proposedTo 'everyone', status open)
|
|
484
|
+
* - org-scoped broadcast request (proposedTo 'org') — the server rejects the
|
|
477
485
|
* claim with 403 if the caller is not a member of the agreement's orgId
|
|
478
486
|
*
|
|
479
487
|
* POST /agreements/:id/claim — canonical; no partyId in body.
|
|
@@ -493,7 +501,7 @@ export async function claimAgreement(agreementId, creds) {
|
|
|
493
501
|
}
|
|
494
502
|
// the route reports which kind of broadcast this turned out to be.
|
|
495
503
|
// A caller cannot work it out from the row — post-claim no sentinel is left,
|
|
496
|
-
// and a
|
|
504
|
+
// and a request (you do the work) reads the same shape as a standing offer (you
|
|
497
505
|
// pay for it) unless you know which slot you landed in.
|
|
498
506
|
const envelope = data;
|
|
499
507
|
return { ...envelope, agreement: shapeAgreement(envelope.agreement) };
|
|
@@ -683,7 +691,7 @@ export class AgreementClient {
|
|
|
683
691
|
list(filters) { return listAgreements(filters, this.creds); }
|
|
684
692
|
listMine(filters) { return getMyAgreements(filters, this.creds); }
|
|
685
693
|
get(id) { return getAgreement(id, this.creds); }
|
|
686
|
-
|
|
694
|
+
createLink(data) { return createLink(data, this.creds); }
|
|
687
695
|
revoke(id) { return revokeAgreement(id, this.creds); }
|
|
688
696
|
fulfill(id) { return fulfillAgreement(id, this.creds); }
|
|
689
697
|
claimAgreement(id) { return claimAgreement(id, this.creds); }
|
|
@@ -21,6 +21,7 @@ export interface SendChatMessageInput {
|
|
|
21
21
|
* Recipient id. Optional: when omitted, the backend infers the
|
|
22
22
|
* receiver if the chat has exactly one other member (one agent, or one
|
|
23
23
|
* other human). Provide it explicitly in chats with multiple members.
|
|
24
|
+
* Sent on the wire as `{ id }`; the SDK still takes a string.
|
|
24
25
|
*/
|
|
25
26
|
receiverId?: string;
|
|
26
27
|
text: string;
|
package/dist/http/ChatClient.js
CHANGED
|
@@ -93,7 +93,10 @@ export async function sendChatMessage(input, creds) {
|
|
|
93
93
|
text: input.text,
|
|
94
94
|
entryType,
|
|
95
95
|
contentType,
|
|
96
|
-
|
|
96
|
+
// Canonical wire shape is `{ id, type? }`; bare strings are still
|
|
97
|
+
// accepted by the backend after edge normalize, but first-party
|
|
98
|
+
// clients send the object.
|
|
99
|
+
receiver: input.receiverId ? { id: input.receiverId } : undefined,
|
|
97
100
|
underAgreementId: input.underAgreementId,
|
|
98
101
|
}),
|
|
99
102
|
});
|
|
@@ -93,10 +93,21 @@ export class ConnectionsClient {
|
|
|
93
93
|
async listForHolder() {
|
|
94
94
|
const grantsClient = new GrantsClient(this.operatorKey, this.agentId, this.baseUrl);
|
|
95
95
|
// All pages of the agent's live connection grants (not just the first page).
|
|
96
|
-
const items = await grantsClient.
|
|
96
|
+
const { items, unreadableRails } = await grantsClient.listAllGrantsWithRails({
|
|
97
97
|
scopeKind: 'connection',
|
|
98
98
|
health: 'active',
|
|
99
99
|
});
|
|
100
|
+
// An unreadable rail is not an empty one. Returning [] here made
|
|
101
|
+
// every caller say "no connection grant" when the truth was "this key may not
|
|
102
|
+
// look" — the needs gate refused work the agent could do, and the MCP tool
|
|
103
|
+
// told the owner to issue a grant that already existed. Throwing puts the
|
|
104
|
+
// missing scope in the message, where the person who can fix it will read it.
|
|
105
|
+
const railBlocked = unreadableRails.find((r) => r.rail === 'connection');
|
|
106
|
+
if (railBlocked && items.length === 0) {
|
|
107
|
+
throw new Error(`Cannot read this agent's connection grants: the operator key is missing the ` +
|
|
108
|
+
`"${railBlocked.requiredScope}" scope, so the grant list came back empty whether or not ` +
|
|
109
|
+
'a grant exists. Re-mint the key with that scope (the "launcher-mcp-broker" preset includes it).');
|
|
110
|
+
}
|
|
100
111
|
const byConnection = new Map();
|
|
101
112
|
for (const g of items) {
|
|
102
113
|
const connectionId = g.scope.id;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { GrantView } from './grants.js';
|
|
1
|
+
import type { GrantAccessKind, GrantHolderKind, GrantView } from './grants.js';
|
|
2
2
|
/**
|
|
3
3
|
* added `artifact` — the narrowest context scope: one specific artifact,
|
|
4
4
|
* shared without sharing any chat or agreement it sits in. Still the context
|
|
@@ -21,12 +21,26 @@ export interface ContextGrantScope {
|
|
|
21
21
|
export type ContextGrantRecord = GrantView;
|
|
22
22
|
export interface IssueContextGrantInput {
|
|
23
23
|
holderId: string;
|
|
24
|
+
/**
|
|
25
|
+
* What kind of principal the holder is: a person, an organization, or an
|
|
26
|
+
* agent. Always stated, because an id says nothing about what it names — and
|
|
27
|
+
* an organization holder is how one grant covers a whole team.
|
|
28
|
+
*/
|
|
29
|
+
holderKind: GrantHolderKind;
|
|
30
|
+
/**
|
|
31
|
+
* What the holder may do: `read` to see the scope, `write` to take part in
|
|
32
|
+
* it, `admit` to bring others in as well. Defaults to `write`.
|
|
33
|
+
*/
|
|
34
|
+
kind?: GrantAccessKind;
|
|
24
35
|
scope: ContextGrantScope;
|
|
25
36
|
temporal?: ContextTemporal;
|
|
26
37
|
expiresAt?: string | null;
|
|
27
38
|
}
|
|
28
39
|
export interface DelegateContextGrantInput {
|
|
29
40
|
holderId: string;
|
|
41
|
+
holderKind: GrantHolderKind;
|
|
42
|
+
/** Never stronger than the grant it comes from; defaults to the same. */
|
|
43
|
+
kind?: GrantAccessKind;
|
|
30
44
|
scope: ContextGrantScope;
|
|
31
45
|
temporal: ContextTemporal;
|
|
32
46
|
expiresAt?: string | null;
|
|
@@ -43,17 +43,26 @@ export interface ContextReadEnvelope<T = unknown> {
|
|
|
43
43
|
latestSequence?: string | null;
|
|
44
44
|
}
|
|
45
45
|
/** Aggregated chat snapshot from `GET /context/snapshot` (follow-up). */
|
|
46
|
+
/**
|
|
47
|
+
* One participant on the snapshot roster. `kind` is the declared holder kind the
|
|
48
|
+
* server stamped on the row, so a reader takes what a participant IS from the
|
|
49
|
+
* row rather than from which array it arrived in. Optional so a backend that
|
|
50
|
+
* predates it still parses.
|
|
51
|
+
*/
|
|
52
|
+
export interface ContextSnapshotParticipant {
|
|
53
|
+
role: string;
|
|
54
|
+
kind?: string;
|
|
55
|
+
isYou?: boolean;
|
|
56
|
+
[key: string]: unknown;
|
|
57
|
+
}
|
|
46
58
|
export interface ContextSnapshotResult {
|
|
47
59
|
history: unknown[];
|
|
48
60
|
agreements: unknown[];
|
|
49
|
-
agents: Array<{
|
|
61
|
+
agents: Array<ContextSnapshotParticipant & {
|
|
50
62
|
agentId: string;
|
|
51
|
-
role: string;
|
|
52
|
-
isYou: boolean;
|
|
53
63
|
}>;
|
|
54
|
-
users: Array<{
|
|
64
|
+
users: Array<ContextSnapshotParticipant & {
|
|
55
65
|
userId: string;
|
|
56
|
-
role: string;
|
|
57
66
|
}>;
|
|
58
67
|
latestSequence?: string | null;
|
|
59
68
|
chatMissing?: boolean;
|
|
@@ -66,4 +66,18 @@ export declare class GrantsClient {
|
|
|
66
66
|
* truncated. `maxPages` bounds the loop as a runaway guard.
|
|
67
67
|
*/
|
|
68
68
|
listAllGrants(query?: Omit<ListGrantsQuery, 'cursor'>, maxPages?: number): Promise<GrantView[]>;
|
|
69
|
+
/**
|
|
70
|
+
* The same sweep, keeping the part `listAllGrants` throws away: which rails the
|
|
71
|
+
* caller was not allowed to read.
|
|
72
|
+
*
|
|
73
|
+
* The distinction is not cosmetic. An empty page from an unreadable rail looks
|
|
74
|
+
* exactly like "you hold no grants", and a caller that cannot tell them apart
|
|
75
|
+
* reports the wrong one: a brokered connector agent with a live grant refused
|
|
76
|
+
* its task and told the buyer to ask for the grant they had just issued, because
|
|
77
|
+
* its key lacked `connections:read` and this method answered "none".
|
|
78
|
+
*/
|
|
79
|
+
listAllGrantsWithRails(query?: Omit<ListGrantsQuery, 'cursor'>, maxPages?: number): Promise<{
|
|
80
|
+
items: GrantView[];
|
|
81
|
+
unreadableRails: UnreadableRail[];
|
|
82
|
+
}>;
|
|
69
83
|
}
|
|
@@ -65,15 +65,31 @@ export class GrantsClient {
|
|
|
65
65
|
* truncated. `maxPages` bounds the loop as a runaway guard.
|
|
66
66
|
*/
|
|
67
67
|
async listAllGrants(query = {}, maxPages = 50) {
|
|
68
|
+
return (await this.listAllGrantsWithRails(query, maxPages)).items;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* The same sweep, keeping the part `listAllGrants` throws away: which rails the
|
|
72
|
+
* caller was not allowed to read.
|
|
73
|
+
*
|
|
74
|
+
* The distinction is not cosmetic. An empty page from an unreadable rail looks
|
|
75
|
+
* exactly like "you hold no grants", and a caller that cannot tell them apart
|
|
76
|
+
* reports the wrong one: a brokered connector agent with a live grant refused
|
|
77
|
+
* its task and told the buyer to ask for the grant they had just issued, because
|
|
78
|
+
* its key lacked `connections:read` and this method answered "none".
|
|
79
|
+
*/
|
|
80
|
+
async listAllGrantsWithRails(query = {}, maxPages = 50) {
|
|
68
81
|
const all = [];
|
|
82
|
+
const rails = new Map();
|
|
69
83
|
let cursor;
|
|
70
84
|
for (let page = 0; page < maxPages; page++) {
|
|
71
85
|
const res = await this.listGrants({ ...query, cursor });
|
|
72
86
|
all.push(...res.items);
|
|
87
|
+
for (const rail of res.unreadableRails ?? [])
|
|
88
|
+
rails.set(rail.rail, rail);
|
|
73
89
|
if (!res.nextCursor)
|
|
74
|
-
|
|
90
|
+
break;
|
|
75
91
|
cursor = res.nextCursor;
|
|
76
92
|
}
|
|
77
|
-
return all;
|
|
93
|
+
return { items: all, unreadableRails: [...rails.values()] };
|
|
78
94
|
}
|
|
79
95
|
}
|
|
@@ -24,7 +24,7 @@ export interface PullOffersOptions {
|
|
|
24
24
|
}
|
|
25
25
|
export declare function pullOffers(options: PullOffersOptions | undefined, creds: Creds): Promise<Agreement[]>;
|
|
26
26
|
export declare function claimOffer(agreementId: string, creds: Creds): Promise<Agreement>;
|
|
27
|
-
export interface
|
|
27
|
+
export interface PublishRequestPayload {
|
|
28
28
|
/** See PublishOfferPayload.billing. */
|
|
29
29
|
billing?: 'total' | 'per_task';
|
|
30
30
|
description: string;
|
|
@@ -38,12 +38,12 @@ export interface PublishQuestPayload {
|
|
|
38
38
|
/** Broadcast audience: 'everyone' (default, fully public) or 'org' (members of your active org only). */
|
|
39
39
|
audience?: BroadcastAudience;
|
|
40
40
|
}
|
|
41
|
-
export declare function
|
|
42
|
-
export interface
|
|
41
|
+
export declare function publishRequest(payload: PublishRequestPayload, creds: Creds): Promise<Agreement>;
|
|
42
|
+
export interface PullRequestsOptions {
|
|
43
43
|
limit?: number;
|
|
44
44
|
since?: string;
|
|
45
45
|
}
|
|
46
|
-
export declare function
|
|
46
|
+
export declare function pullRequests(options: PullRequestsOptions | undefined, creds: Creds): Promise<Agreement[]>;
|
|
47
47
|
export declare class MarketplaceClient {
|
|
48
48
|
private creds;
|
|
49
49
|
/**
|
|
@@ -54,6 +54,6 @@ export declare class MarketplaceClient {
|
|
|
54
54
|
publishOffer(payload: PublishOfferPayload): Promise<Agreement>;
|
|
55
55
|
pullOffers(options?: PullOffersOptions): Promise<Agreement[]>;
|
|
56
56
|
claimOffer(agreementId: string): Promise<Agreement>;
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
publishRequest(payload: PublishRequestPayload): Promise<Agreement>;
|
|
58
|
+
pullRequests(options?: PullRequestsOptions): Promise<Agreement[]>;
|
|
59
59
|
}
|
|
@@ -70,37 +70,37 @@ export async function claimOffer(agreementId, creds) {
|
|
|
70
70
|
throw new Error(data?.['error'] || 'Claim failed');
|
|
71
71
|
return shapeAgreement(data['offer']);
|
|
72
72
|
}
|
|
73
|
-
export async function
|
|
74
|
-
assertCreds(creds, '
|
|
75
|
-
const res = await fetch(`${getMarketplaceBaseUrl()}/
|
|
73
|
+
export async function publishRequest(payload, creds) {
|
|
74
|
+
assertCreds(creds, 'request publish');
|
|
75
|
+
const res = await fetch(`${getMarketplaceBaseUrl()}/requests/publish`, {
|
|
76
76
|
method: 'POST',
|
|
77
77
|
headers: buildHeaders(creds),
|
|
78
78
|
body: JSON.stringify(payload || {}),
|
|
79
79
|
});
|
|
80
80
|
if (!res.ok) {
|
|
81
81
|
const body = await res.text().catch(() => '');
|
|
82
|
-
throwApiError(res, body, `
|
|
82
|
+
throwApiError(res, body, `Request publish failed: ${res.status}`);
|
|
83
83
|
}
|
|
84
84
|
const data = await res.json().catch(() => null);
|
|
85
85
|
if (!data?.['agreement'])
|
|
86
|
-
throw new Error('
|
|
86
|
+
throw new Error('Request publish returned no agreement');
|
|
87
87
|
return shapeAgreement(data['agreement']);
|
|
88
88
|
}
|
|
89
|
-
export async function
|
|
90
|
-
assertCreds(creds, '
|
|
89
|
+
export async function pullRequests(options, creds) {
|
|
90
|
+
assertCreds(creds, 'request pull');
|
|
91
91
|
const params = new URLSearchParams();
|
|
92
92
|
if (options?.limit != null)
|
|
93
93
|
params.set('limit', String(options.limit));
|
|
94
94
|
if (options?.since)
|
|
95
95
|
params.set('since', options.since);
|
|
96
96
|
const qs = params.toString();
|
|
97
|
-
const res = await fetch(`${getMarketplaceBaseUrl()}/
|
|
97
|
+
const res = await fetch(`${getMarketplaceBaseUrl()}/requests${qs ? `?${qs}` : ''}`, {
|
|
98
98
|
method: 'GET',
|
|
99
99
|
headers: buildHeaders(creds),
|
|
100
100
|
});
|
|
101
101
|
if (!res.ok) {
|
|
102
102
|
const body = await res.text().catch(() => '');
|
|
103
|
-
throwApiError(res, body, `
|
|
103
|
+
throwApiError(res, body, `Request pull failed: ${res.status}`);
|
|
104
104
|
}
|
|
105
105
|
const data = await res.json().catch(() => null);
|
|
106
106
|
return data?.['agreements'] ?? [];
|
|
@@ -121,6 +121,6 @@ export class MarketplaceClient {
|
|
|
121
121
|
publishOffer(payload) { return publishOffer(payload, this.creds); }
|
|
122
122
|
pullOffers(options) { return pullOffers(options, this.creds); }
|
|
123
123
|
claimOffer(agreementId) { return claimOffer(agreementId, this.creds); }
|
|
124
|
-
|
|
125
|
-
|
|
124
|
+
publishRequest(payload) { return publishRequest(payload, this.creds); }
|
|
125
|
+
pullRequests(options) { return pullRequests(options, this.creds); }
|
|
126
126
|
}
|
|
@@ -86,6 +86,11 @@ export interface ListTasksOptions {
|
|
|
86
86
|
limit?: number;
|
|
87
87
|
/** Filter to tasks assigned to this id. */
|
|
88
88
|
assignedTo?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Filter to tasks CREATED by this id — what the caller handed out, as
|
|
91
|
+
* opposed to what was handed to it.
|
|
92
|
+
*/
|
|
93
|
+
createdBy?: string;
|
|
89
94
|
}
|
|
90
95
|
export interface ListTasksResult {
|
|
91
96
|
tasks: Task[];
|
package/dist/http/TaskClient.js
CHANGED
|
@@ -345,6 +345,8 @@ export async function listTasks(options = {}, creds) {
|
|
|
345
345
|
url.searchParams.set('limit', String(options.limit));
|
|
346
346
|
if (options.assignedTo)
|
|
347
347
|
url.searchParams.set('assignedTo', options.assignedTo);
|
|
348
|
+
if (options.createdBy)
|
|
349
|
+
url.searchParams.set('createdBy', options.createdBy);
|
|
348
350
|
const res = await fetch(url.toString(), {
|
|
349
351
|
method: 'GET',
|
|
350
352
|
headers: buildHeaders(creds),
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { type ClaimedKind, type ProposeTerms } from './AgreementClient.js';
|
|
2
2
|
import { type Agreement, type Creds, type EngagementKind } from '../types.js';
|
|
3
3
|
/**
|
|
4
|
-
* one propose grammar. Direct, broadcast (
|
|
4
|
+
* one propose grammar. Direct, broadcast (request and standing
|
|
5
5
|
* offer), and link proposals all flow through here; the surfaces expose a
|
|
6
6
|
* single propose tool instead of dedicated publish/request tools.
|
|
7
7
|
*
|
|
8
8
|
* Routing:
|
|
9
9
|
* - engagementKind 'link' → POST /agreements (link proposal / open invite)
|
|
10
10
|
* - proposedTo 'everyone' | 'org', providerId = self → seller-broadcast standing offer
|
|
11
|
-
* - proposedTo 'everyone' | 'org', no providerId → buyer-broadcast
|
|
11
|
+
* - proposedTo 'everyone' | 'org', no providerId → buyer-broadcast request
|
|
12
12
|
* - anything else → direct proposal
|
|
13
13
|
*/
|
|
14
14
|
export interface UnifiedProposeInput extends ProposeTerms {
|
|
@@ -17,13 +17,13 @@ export interface UnifiedProposeInput extends ProposeTerms {
|
|
|
17
17
|
chatId?: string;
|
|
18
18
|
engagementKind?: EngagementKind;
|
|
19
19
|
}
|
|
20
|
-
export type ProposeShape = 'direct' | '
|
|
20
|
+
export type ProposeShape = 'direct' | 'request' | 'offer' | 'link';
|
|
21
21
|
export declare function proposeUnified(input: UnifiedProposeInput, creds: Creds): Promise<{
|
|
22
22
|
agreement: Agreement;
|
|
23
23
|
shape: ProposeShape;
|
|
24
24
|
}>;
|
|
25
25
|
/**
|
|
26
|
-
* one claim verb for any open broadcast: link invite,
|
|
26
|
+
* one claim verb for any open broadcast: link invite, request,
|
|
27
27
|
* hand-off, or standing offer.
|
|
28
28
|
*
|
|
29
29
|
* One request. This used to read the agreement first to decide which endpoint to
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createLink, claimAgreement, proposeBroadcast, proposeDirectTo, } from './AgreementClient.js';
|
|
2
2
|
import { publishOffer } from './MarketplaceClient.js';
|
|
3
3
|
import { isBroadcastTarget, } from '../types.js';
|
|
4
4
|
export async function proposeUnified(input, creds) {
|
|
@@ -9,9 +9,8 @@ export async function proposeUnified(input, creds) {
|
|
|
9
9
|
// A link is an agreement, proposed to one agent (providerId) or opened as
|
|
10
10
|
// an invite (proposedTo 'everyone'); no chat, no money.
|
|
11
11
|
const target = isBroadcastTarget(proposedTo) ? undefined : proposedTo;
|
|
12
|
-
const { agreement } = await
|
|
13
|
-
|
|
14
|
-
...(target ? { providerId: target } : {}),
|
|
12
|
+
const { agreement } = await createLink({
|
|
13
|
+
...(target ? { targetAgentId: target } : {}),
|
|
15
14
|
...(terms.description ? { description: terms.description } : {}),
|
|
16
15
|
}, creds);
|
|
17
16
|
return { agreement, shape: 'link' };
|
|
@@ -33,16 +32,16 @@ export async function proposeUnified(input, creds) {
|
|
|
33
32
|
return { agreement, shape: 'offer' };
|
|
34
33
|
}
|
|
35
34
|
if (providerId) {
|
|
36
|
-
throw new Error('On a broadcast, providerId must be your own agent id (a standing offer: you work, the claimer pays) or omitted (a
|
|
35
|
+
throw new Error('On a broadcast, providerId must be your own agent id (a standing offer: you work, the claimer pays) or omitted (a request: the claimer works, you pay). A third-party providerId is not broadcastable.');
|
|
37
36
|
}
|
|
38
|
-
// Buyer-broadcast: the claimer works, your side pays — an open
|
|
37
|
+
// Buyer-broadcast: the claimer works, your side pays — an open request.
|
|
39
38
|
const agreement = await proposeBroadcast({
|
|
40
39
|
...terms,
|
|
41
40
|
chatId: chatId ?? '',
|
|
42
41
|
engagementKind: engagementKind ?? 'service',
|
|
43
42
|
audience,
|
|
44
43
|
}, creds);
|
|
45
|
-
return { agreement, shape: '
|
|
44
|
+
return { agreement, shape: 'request' };
|
|
46
45
|
}
|
|
47
46
|
if (!chatId)
|
|
48
47
|
throw new Error('chatId is required on a direct proposal');
|
|
@@ -56,7 +55,7 @@ export async function proposeUnified(input, creds) {
|
|
|
56
55
|
return { agreement, shape: 'direct' };
|
|
57
56
|
}
|
|
58
57
|
/**
|
|
59
|
-
* one claim verb for any open broadcast: link invite,
|
|
58
|
+
* one claim verb for any open broadcast: link invite, request,
|
|
60
59
|
* hand-off, or standing offer.
|
|
61
60
|
*
|
|
62
61
|
* One request. This used to read the agreement first to decide which endpoint to
|
|
@@ -74,6 +73,6 @@ export async function claimOpenAgreement(agreementId, creds) {
|
|
|
74
73
|
throw new Error('agreementId is required');
|
|
75
74
|
const { agreement, kind } = await claimAgreement(agreementId, creds);
|
|
76
75
|
// A server that has not shipped the `kind` field yet still claims correctly;
|
|
77
|
-
// '
|
|
78
|
-
return { agreement, kind: kind ?? '
|
|
76
|
+
// 'request' is the shape the route has always handled.
|
|
77
|
+
return { agreement, kind: kind ?? 'request' };
|
|
79
78
|
}
|
package/dist/http/grants.d.ts
CHANGED
|
@@ -11,6 +11,23 @@
|
|
|
11
11
|
* watermark are presented as `temporal` / `watermark_at` caveats.
|
|
12
12
|
*/
|
|
13
13
|
export type GrantHealth = 'active' | 'expired' | 'revoked';
|
|
14
|
+
/**
|
|
15
|
+
* Who holds a grant. Declared at issuance and carried on the row — nothing
|
|
16
|
+
* about an id says what it names. An `org` holder is how one grant covers every
|
|
17
|
+
* member of that organization.
|
|
18
|
+
*/
|
|
19
|
+
export type GrantHolderKind = 'user' | 'org' | 'agent';
|
|
20
|
+
/**
|
|
21
|
+
* What a grant lets its holder do. `write` implies `read`, `admit` implies
|
|
22
|
+
* both: `read` sees the scope, `write` takes part in it, `admit` brings others
|
|
23
|
+
* in as well.
|
|
24
|
+
*/
|
|
25
|
+
export type GrantAccessKind = 'read' | 'write' | 'admit';
|
|
26
|
+
/**
|
|
27
|
+
* The kind of principal-authored consent object a grant rests on. Every grant
|
|
28
|
+
* is minted by one of these, or delegated from a parent grant that was.
|
|
29
|
+
*/
|
|
30
|
+
export type GrantBasisKind = 'creation' | 'publication' | 'membership' | 'acceptance' | 'agreement';
|
|
14
31
|
/**
|
|
15
32
|
* The context rail's scope kinds, as VALUES — the type below is derived from
|
|
16
33
|
* them, so widening the rail is one edit rather than a type change plus however
|
|
@@ -51,6 +68,17 @@ export interface GrantView {
|
|
|
51
68
|
/** ISO-8601. */
|
|
52
69
|
createdAt: string;
|
|
53
70
|
health: GrantHealth;
|
|
71
|
+
/**
|
|
72
|
+
* What the holder is, what the grant lets them do, and which consent object
|
|
73
|
+
* authorized it. Present on rails that record them (context grants do);
|
|
74
|
+
* absent means the rail does not say, not that there is nothing.
|
|
75
|
+
*/
|
|
76
|
+
holderKind?: GrantHolderKind;
|
|
77
|
+
access?: GrantAccessKind;
|
|
78
|
+
basis?: {
|
|
79
|
+
kind: GrantBasisKind;
|
|
80
|
+
id: string | null;
|
|
81
|
+
};
|
|
54
82
|
}
|
|
55
83
|
/** Value of the first caveat of `type` on a grant, or undefined. */
|
|
56
84
|
export declare function grantCaveat(grant: GrantView, type: string): unknown | undefined;
|
package/dist/http/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export type { ListMessagesOptions, ListMessagesResult } from './MessagesClient.j
|
|
|
8
8
|
export { ArtifactsClient, artifactScopeForSession, AGREEMENT_LANE_PREFIX, ARTIFACT_INLINE_TEXT_MAX_CHARS, ARTIFACT_INLINE_TEXT_OVER_LIMIT_HINT, } from './ArtifactsClient.js';
|
|
9
9
|
export type { ArtifactVisibility, ListArtifactsOptions, ListArtifactsQuery, ListArtifactsResult, WriteArtifactInput, } from './ArtifactsClient.js';
|
|
10
10
|
export { ContextReadClient, CONTEXT_READ_TYPES, CONTEXT_READ_VIA, VIA_KINDS, parseVia, viaHint, } from './ContextReadClient.js';
|
|
11
|
-
export type { ContextReadType, ContextReadQuery, ContextReadEnvelope, ContextSnapshotResult, ViaKind, } from './ContextReadClient.js';
|
|
11
|
+
export type { ContextReadType, ContextReadQuery, ContextReadEnvelope, ContextSnapshotResult, ContextSnapshotParticipant, ViaKind, } from './ContextReadClient.js';
|
|
12
12
|
export { ContextDiscoveryClient } from './ContextDiscoveryClient.js';
|
|
13
13
|
export type { DiscoverableItem } from './ContextDiscoveryClient.js';
|
|
14
14
|
export { GrantsClient } from './GrantsClient.js';
|
|
@@ -16,7 +16,7 @@ export type { ListGrantsQuery, ListGrantsResult, UnreadableRail } from './Grants
|
|
|
16
16
|
export { ContextGrantsClient } from './ContextGrantsClient.js';
|
|
17
17
|
export type { ContextGrantRecord, ContextGrantScope, ContextGrantScopeKind, ContextTemporal, IssueContextGrantInput, DelegateContextGrantInput, DelegateContextGrantResult, ReachEntry, GrantReachResult, } from './ContextGrantsClient.js';
|
|
18
18
|
export { grantCaveat, CONTEXT_GRANT_SCOPE_KINDS, GRANT_SCOPE_KINDS, } from './grants.js';
|
|
19
|
-
export type { GrantView, GrantScopeKind, GrantScopeView, GrantCaveatView, GrantHealth, } from './grants.js';
|
|
19
|
+
export type { GrantView, GrantScopeKind, GrantScopeView, GrantCaveatView, GrantHealth, GrantHolderKind, GrantAccessKind, GrantBasisKind, } from './grants.js';
|
|
20
20
|
export { PaymentsClient } from './PaymentsClient.js';
|
|
21
21
|
export type { PaymentsError, WalletBalance, WalletRef, PaymentTransactionView, TransferResult, HoldResult, ReleaseResult, PaymentGrantView, PaymentGrantEnvelope, RevokeGrantResult, PaymentApproval, WaitForApprovalResult, } from './PaymentsClient.js';
|
|
22
22
|
export { ConnectionsClient, assertNoLeakedConnectionSecret, } from './ConnectionsClient.js';
|
package/dist/index.d.ts
CHANGED
|
@@ -11,5 +11,5 @@ export { runtimeLog, resetRuntimeLogLevelCache } from './shared/runtimeLog.js';
|
|
|
11
11
|
export { RateLimitedError, isRateLimited, parseRetryAfterMs, pollSurfaceError, } from './shared/rateLimit.js';
|
|
12
12
|
export { parseErrorMessage, parseErrorCode, throwApiError, } from './shared/apiError.js';
|
|
13
13
|
export { ApiError } from './types.js';
|
|
14
|
-
export type { Creds, Task, TaskState, PlanStep, PlanStepStatus, Agreement, EngagementKind, BroadcastAudience, EntryType, ContentType, MessageMetadata, MessageHandler, InboxDeliveryKind, InboxDeliveryRef, InboxChatNews, InboxProposalRef, InboxTaskRef,
|
|
14
|
+
export type { Creds, Task, TaskState, PlanStep, PlanStepStatus, Agreement, EngagementKind, BroadcastAudience, EntryType, ContentType, MessageMetadata, MessageHandler, InboxDeliveryKind, InboxDeliveryRef, InboxChatNews, InboxProposalRef, InboxTaskRef, InboxRequestRef, InboxConnectionRequestRef, InboxHumanAttention, InboxEnvelope, InboxAckResult, InboxReadOptions, } from './types.js';
|
|
15
15
|
export type { ProposeTerms, ProposeDirectInput, ProposeBroadcastInput, ProposeAgreementData, } from './http/AgreementClient.js';
|