@ziggs-ai/api-client 0.36.0 → 0.36.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.
- package/dist/capabilities/links.js +1 -15
- package/dist/capabilities/marketplace.d.ts +32 -0
- package/dist/capabilities/marketplace.js +22 -5
- package/dist/http/AssistantConnectionClient.js +4 -0
- package/dist/http/InboxClient.d.ts +7 -1
- package/dist/http/InboxClient.js +11 -1
- package/dist/http/MarketplaceClient.d.ts +10 -0
- package/dist/http/MarketplaceClient.js +11 -1
- package/dist/http/PaymentsClient.d.ts +4 -0
- package/dist/http/PaymentsClient.js +6 -1
- package/dist/types.d.ts +12 -0
- package/package.json +1 -1
|
@@ -1,24 +1,10 @@
|
|
|
1
|
-
import { resolveWebAppOrigin
|
|
1
|
+
import { resolveWebAppOrigin } from '../utils/appUrls.js';
|
|
2
2
|
import { createLink, listAgreements } from '../http/AgreementClient.js';
|
|
3
3
|
import { nextCall } from './nextCall.js';
|
|
4
4
|
import { fullCreds } from './types.js';
|
|
5
5
|
export function webAppOrigin(env) {
|
|
6
6
|
return resolveWebAppOrigin(env.webUrl);
|
|
7
7
|
}
|
|
8
|
-
/**
|
|
9
|
-
* The one thing an invite travels as: `/connect/<inviteId>`.
|
|
10
|
-
*
|
|
11
|
-
* There used to be two forms — this URL plus a block of instructions to paste
|
|
12
|
-
* into the recipient's assistant — and the caller had to explain which was
|
|
13
|
-
* which and pick per recipient. That block now lives on the page itself, which
|
|
14
|
-
* is public and server-rendered: a person reads it, and an assistant handed the
|
|
15
|
-
* same URL fetches it and finds the MCP server address, the claim tool and the
|
|
16
|
-
* invite id in the markup. One link, both readers, nothing to keep in step
|
|
17
|
-
* across two repos.
|
|
18
|
-
*/
|
|
19
|
-
function inviteShareUrl(env, agreementId) {
|
|
20
|
-
return connectInviteAppUrl(webAppOrigin(env), agreementId);
|
|
21
|
-
}
|
|
22
8
|
/**
|
|
23
9
|
* A link is reach-only — the follow-up move differs by surface tool names.
|
|
24
10
|
*
|
|
@@ -1,4 +1,36 @@
|
|
|
1
1
|
import { type CapabilityDefinition } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* One listing, as a browser needs to read it.
|
|
4
|
+
*
|
|
5
|
+
* A whole agreement document is around 30 fields and ~2KB per row, so a default
|
|
6
|
+
* page of 20 is 40KB of context spent mostly on storage bookkeeping — internal
|
|
7
|
+
* versioning, content hashes, write provenance, approval and lane bookkeeping —
|
|
8
|
+
* none of which helps anyone decide whether to claim. This projection is what the
|
|
9
|
+
* decision actually needs: what the work is, who does it, what it costs, on what
|
|
10
|
+
* terms, and the id to claim it with.
|
|
11
|
+
*
|
|
12
|
+
* Deliberately no `raw` escape hatch. The full document is one `agreement_get`
|
|
13
|
+
* away for the row you chose, and an escape hatch here would just restore the
|
|
14
|
+
* cost for every row you did not.
|
|
15
|
+
*/
|
|
16
|
+
export declare function toListingRow(a: Record<string, any>, kind: 'request' | 'offer'): {
|
|
17
|
+
createdAt: any;
|
|
18
|
+
requiredConnections?: any;
|
|
19
|
+
payer?: any;
|
|
20
|
+
provider?: any;
|
|
21
|
+
providerAgent?: any;
|
|
22
|
+
maxExecutions?: any;
|
|
23
|
+
conversationAllowance?: any;
|
|
24
|
+
expiresAt?: any;
|
|
25
|
+
engagementKind: any;
|
|
26
|
+
lifecycle: any;
|
|
27
|
+
billing?: any;
|
|
28
|
+
agreementId: any;
|
|
29
|
+
kind: "request" | "offer";
|
|
30
|
+
description: any;
|
|
31
|
+
price: any;
|
|
32
|
+
priceUnit: string;
|
|
33
|
+
};
|
|
2
34
|
/**
|
|
3
35
|
* the marketplace read on both surfaces. Publishing and claiming
|
|
4
36
|
* ride the agreement grammar (propose-with-audience / agreement_claim); this
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { marketplaceFormation } from '../engagementGuide.js';
|
|
2
|
-
import {
|
|
2
|
+
import { pullOffersPage, pullRequests } from '../http/MarketplaceClient.js';
|
|
3
3
|
import { fullCreds } from './types.js';
|
|
4
4
|
import { nextCall } from './nextCall.js';
|
|
5
5
|
import { LIST_FIELDS_PARAM, parseListFields, pickListedRows } from './listedFields.js';
|
|
@@ -29,7 +29,7 @@ const named = (id) => typeof id === 'string' && id && !BROADCASTS.has(id) ? id :
|
|
|
29
29
|
* away for the row you chose, and an escape hatch here would just restore the
|
|
30
30
|
* cost for every row you did not.
|
|
31
31
|
*/
|
|
32
|
-
function toListingRow(a, kind) {
|
|
32
|
+
export function toListingRow(a, kind) {
|
|
33
33
|
const terms = a?.terms ?? {};
|
|
34
34
|
const parties = a?.parties ?? {};
|
|
35
35
|
const requiredConnections = terms.requiredConnections ?? [];
|
|
@@ -38,6 +38,7 @@ function toListingRow(a, kind) {
|
|
|
38
38
|
kind,
|
|
39
39
|
description: terms.description ?? '',
|
|
40
40
|
price: a?.money?.price ?? 0,
|
|
41
|
+
priceUnit: 'hundredths of a point',
|
|
41
42
|
// What that price MEANS: a whole-engagement total, or a rate charged per
|
|
42
43
|
// completed task. Omitting it left a metered standing hire indistinguishable
|
|
43
44
|
// from a flat-priced one at the moment a caller decides to claim, and
|
|
@@ -93,10 +94,13 @@ export const marketplaceViewCapability = {
|
|
|
93
94
|
limit: typeof args['limit'] === 'number' ? args['limit'] : 20,
|
|
94
95
|
...(args['since'] ? { since: args['since'] } : {}),
|
|
95
96
|
};
|
|
96
|
-
const [requests,
|
|
97
|
+
const [requests, offerPage] = await Promise.all([
|
|
97
98
|
kind === 'offers' ? Promise.resolve([]) : pullRequests(options, creds),
|
|
98
|
-
kind === 'requests'
|
|
99
|
+
kind === 'requests'
|
|
100
|
+
? Promise.resolve({ offers: [], total: null, hasMore: false })
|
|
101
|
+
: pullOffersPage(options, creds),
|
|
99
102
|
]);
|
|
103
|
+
const offers = offerPage.offers;
|
|
100
104
|
const fields = parseListFields(args['fields']);
|
|
101
105
|
const requestRows = pickListedRows(requests.map((q) => toListingRow(q, 'request')), fields);
|
|
102
106
|
const offerRows = pickListedRows(offers.map((o) => toListingRow(o, 'offer')), fields);
|
|
@@ -109,7 +113,20 @@ export const marketplaceViewCapability = {
|
|
|
109
113
|
? { requests: requestRows, requestCount: requests.length }
|
|
110
114
|
: {}),
|
|
111
115
|
...(kind !== 'requests'
|
|
112
|
-
? {
|
|
116
|
+
? {
|
|
117
|
+
offers: offerRows,
|
|
118
|
+
offerCount: offers.length,
|
|
119
|
+
// The board is capped: say so only when more exist, so the count
|
|
120
|
+
// above is never read as all of them.
|
|
121
|
+
...(offerPage.hasMore
|
|
122
|
+
? {
|
|
123
|
+
moreOffers: {
|
|
124
|
+
total: offerPage.total,
|
|
125
|
+
note: 'More listings exist than this read returned. Read again with a larger limit (at most 100) or narrow with since.',
|
|
126
|
+
},
|
|
127
|
+
}
|
|
128
|
+
: {}),
|
|
129
|
+
}
|
|
113
130
|
: {}),
|
|
114
131
|
engagement,
|
|
115
132
|
// Claiming is the move after browsing, and the id is in the row the
|
|
@@ -22,6 +22,10 @@ export class AssistantConnectionClient {
|
|
|
22
22
|
Authorization: `Bearer ${this.creds.operatorKey}`,
|
|
23
23
|
'Content-Type': 'application/json',
|
|
24
24
|
'X-Ziggs-Instance': hostIdentity(this.creds.instanceId),
|
|
25
|
+
...(this.creds.clientSessionId ? { 'X-Ziggs-Session': this.creds.clientSessionId } : {}),
|
|
26
|
+
...(this.creds.workspaceIds ? { 'X-Ziggs-Workspaces': this.creds.workspaceIds } : {}),
|
|
27
|
+
...(this.creds.app ? { 'X-Ziggs-App': this.creds.app } : {}),
|
|
28
|
+
...(this.creds.sessionName ? { 'X-Ziggs-Session-Name': this.creds.sessionName } : {}),
|
|
25
29
|
},
|
|
26
30
|
...(body === undefined ? {} : { body: JSON.stringify(body) }),
|
|
27
31
|
});
|
|
@@ -9,6 +9,7 @@ export declare class InboxClient {
|
|
|
9
9
|
private readonly agentId?;
|
|
10
10
|
private readonly baseUrl;
|
|
11
11
|
private readonly instanceId;
|
|
12
|
+
private readonly session?;
|
|
12
13
|
/**
|
|
13
14
|
* @param operatorKey Agent-scoped or fleet operator key.
|
|
14
15
|
* @param agentId Required for fleet keys (sent as X-Agent-Id). Omit for agent-scoped keys.
|
|
@@ -17,7 +18,12 @@ export declare class InboxClient {
|
|
|
17
18
|
* process is not its host (the CLI, one hosted-MCP connection among many)
|
|
18
19
|
* must pass its own; everything long-lived omits it.
|
|
19
20
|
*/
|
|
20
|
-
constructor(operatorKey: string, agentId?: string, baseUrl?: string, instanceId?: string
|
|
21
|
+
constructor(operatorKey: string, agentId?: string, baseUrl?: string, instanceId?: string, session?: {
|
|
22
|
+
clientSessionId?: string;
|
|
23
|
+
workspaceIds?: string;
|
|
24
|
+
app?: string;
|
|
25
|
+
sessionName?: string;
|
|
26
|
+
});
|
|
21
27
|
private headers;
|
|
22
28
|
private inboxUrl;
|
|
23
29
|
/** Read without acquiring worker ownership or recording receipts. */
|
package/dist/http/InboxClient.js
CHANGED
|
@@ -12,6 +12,7 @@ export class InboxClient {
|
|
|
12
12
|
agentId;
|
|
13
13
|
baseUrl;
|
|
14
14
|
instanceId;
|
|
15
|
+
session;
|
|
15
16
|
/**
|
|
16
17
|
* @param operatorKey Agent-scoped or fleet operator key.
|
|
17
18
|
* @param agentId Required for fleet keys (sent as X-Agent-Id). Omit for agent-scoped keys.
|
|
@@ -20,13 +21,14 @@ export class InboxClient {
|
|
|
20
21
|
* process is not its host (the CLI, one hosted-MCP connection among many)
|
|
21
22
|
* must pass its own; everything long-lived omits it.
|
|
22
23
|
*/
|
|
23
|
-
constructor(operatorKey, agentId, baseUrl, instanceId) {
|
|
24
|
+
constructor(operatorKey, agentId, baseUrl, instanceId, session) {
|
|
24
25
|
if (!operatorKey)
|
|
25
26
|
throw new Error('InboxClient: operatorKey is required');
|
|
26
27
|
this.operatorKey = operatorKey;
|
|
27
28
|
this.agentId = agentId;
|
|
28
29
|
this.baseUrl = baseUrl || getBackendUrl();
|
|
29
30
|
this.instanceId = hostIdentity(instanceId);
|
|
31
|
+
this.session = session;
|
|
30
32
|
}
|
|
31
33
|
headers() {
|
|
32
34
|
const headers = {
|
|
@@ -38,6 +40,14 @@ export class InboxClient {
|
|
|
38
40
|
};
|
|
39
41
|
if (this.agentId)
|
|
40
42
|
headers['X-Agent-Id'] = this.agentId;
|
|
43
|
+
if (this.session?.clientSessionId)
|
|
44
|
+
headers['X-Ziggs-Session'] = this.session.clientSessionId;
|
|
45
|
+
if (this.session?.workspaceIds)
|
|
46
|
+
headers['X-Ziggs-Workspaces'] = this.session.workspaceIds;
|
|
47
|
+
if (this.session?.app)
|
|
48
|
+
headers['X-Ziggs-App'] = this.session.app;
|
|
49
|
+
if (this.session?.sessionName)
|
|
50
|
+
headers['X-Ziggs-Session-Name'] = this.session.sessionName;
|
|
41
51
|
return headers;
|
|
42
52
|
}
|
|
43
53
|
inboxUrl(path, opts) {
|
|
@@ -47,6 +47,16 @@ export interface PullOffersOptions {
|
|
|
47
47
|
since?: string;
|
|
48
48
|
}
|
|
49
49
|
export declare function pullOffers(options: PullOffersOptions | undefined, creds: Creds): Promise<Agreement[]>;
|
|
50
|
+
/**
|
|
51
|
+
* The board read with its total. The board is capped (at most 100 rows), so
|
|
52
|
+
* the number of rows returned is not the number of listings. `total` and
|
|
53
|
+
* `hasMore` are absent from an older server; read them as unknown, not none.
|
|
54
|
+
*/
|
|
55
|
+
export declare function pullOffersPage(options: PullOffersOptions | undefined, creds: Creds): Promise<{
|
|
56
|
+
offers: Agreement[];
|
|
57
|
+
total: number | null;
|
|
58
|
+
hasMore: boolean;
|
|
59
|
+
}>;
|
|
50
60
|
export interface PullRequestsOptions {
|
|
51
61
|
limit?: number;
|
|
52
62
|
since?: string;
|
|
@@ -64,6 +64,14 @@ async function setOfferPaused(agreementId, verb, creds) {
|
|
|
64
64
|
return shapeAgreement(data['agreement']);
|
|
65
65
|
}
|
|
66
66
|
export async function pullOffers(options, creds) {
|
|
67
|
+
return (await pullOffersPage(options, creds)).offers;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The board read with its total. The board is capped (at most 100 rows), so
|
|
71
|
+
* the number of rows returned is not the number of listings. `total` and
|
|
72
|
+
* `hasMore` are absent from an older server; read them as unknown, not none.
|
|
73
|
+
*/
|
|
74
|
+
export async function pullOffersPage(options, creds) {
|
|
67
75
|
assertCreds(creds, 'marketplace offers pull');
|
|
68
76
|
const params = new URLSearchParams();
|
|
69
77
|
if (options?.limit != null)
|
|
@@ -80,7 +88,9 @@ export async function pullOffers(options, creds) {
|
|
|
80
88
|
throwApiError(res, body, `Marketplace offers pull failed: ${res.status}`);
|
|
81
89
|
}
|
|
82
90
|
const data = await res.json().catch(() => null);
|
|
83
|
-
|
|
91
|
+
const offers = data?.['offers'] ?? [];
|
|
92
|
+
const total = typeof data?.['total'] === 'number' ? data['total'] : null;
|
|
93
|
+
return { offers, total, hasMore: data?.['hasMore'] === true };
|
|
84
94
|
}
|
|
85
95
|
export async function pullRequests(options, creds) {
|
|
86
96
|
assertCreds(creds, 'request pull');
|
|
@@ -6,9 +6,13 @@ export interface PaymentsError extends Error {
|
|
|
6
6
|
}
|
|
7
7
|
export interface WalletBalance {
|
|
8
8
|
walletId: string | null;
|
|
9
|
+
/** Always `points` on a read. The wallet row stores a different code. */
|
|
9
10
|
currency: string;
|
|
11
|
+
/** Hundredths of a point. */
|
|
10
12
|
balance: number;
|
|
13
|
+
/** Hundredths of a point, total minus holds. */
|
|
11
14
|
availableBalance: number;
|
|
15
|
+
unit: 'hundredths of a point';
|
|
12
16
|
}
|
|
13
17
|
/**
|
|
14
18
|
* A resolved wallet reference (GET /payments/wallets/resolve).
|
|
@@ -5,6 +5,10 @@ import { throwApiError } from '../shared/apiError.js';
|
|
|
5
5
|
function randomIdempotencyKey(prefix = 'op') {
|
|
6
6
|
return `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
|
|
7
7
|
}
|
|
8
|
+
/** The wallet stores `pez`. A person or an assistant reads points. */
|
|
9
|
+
function shownPointCurrency(currency) {
|
|
10
|
+
return typeof currency === 'string' && currency && currency !== 'pez' ? currency : 'points';
|
|
11
|
+
}
|
|
8
12
|
/**
|
|
9
13
|
* the one payments client for every surface (agent-sdk, ziggs-mcp,
|
|
10
14
|
* scripts). Consolidates the former agent-sdk private ZiggsPayClient. Wallet
|
|
@@ -45,9 +49,10 @@ export class PaymentsClient {
|
|
|
45
49
|
const wallet = w['wallet'];
|
|
46
50
|
return {
|
|
47
51
|
walletId: wallet?.['walletId'] || null,
|
|
48
|
-
currency: wallet?.['currency']
|
|
52
|
+
currency: shownPointCurrency(wallet?.['currency']),
|
|
49
53
|
balance: w['balance'] ?? 0,
|
|
50
54
|
availableBalance: w['availableBalance'] ?? 0,
|
|
55
|
+
unit: 'hundredths of a point',
|
|
51
56
|
};
|
|
52
57
|
}
|
|
53
58
|
async resolve({ userId, agentId } = {}) {
|
package/dist/types.d.ts
CHANGED
|
@@ -47,6 +47,18 @@ export interface Creds {
|
|
|
47
47
|
* `src/instanceIdentity.ts` for what each rail sends.
|
|
48
48
|
*/
|
|
49
49
|
instanceId?: string;
|
|
50
|
+
/**
|
|
51
|
+
* This window, sent as `X-Ziggs-Session`. Reconnects that present the same
|
|
52
|
+
* id land on the same row. Unset on a long-lived process: the inbox host
|
|
53
|
+
* header is the window.
|
|
54
|
+
*/
|
|
55
|
+
clientSessionId?: string;
|
|
56
|
+
/** Comma-separated workspace ids. Sent as `X-Ziggs-Workspaces`. Absent does not narrow. */
|
|
57
|
+
workspaceIds?: string;
|
|
58
|
+
/** Connection label, sent as `X-Ziggs-App`. */
|
|
59
|
+
app?: string;
|
|
60
|
+
/** Person-readable window name, sent as `X-Ziggs-Session-Name`. */
|
|
61
|
+
sessionName?: string;
|
|
50
62
|
}
|
|
51
63
|
export type TaskState = 'active' | 'proposal' | 'completed' | 'failed' | 'cancelled' | 'ledger_open';
|
|
52
64
|
export type PlanStepStatus = 'pending' | 'in_progress' | 'completed' | 'skipped';
|