settld-api-sdk 0.1.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/package.json +25 -0
- package/src/client.js +627 -0
- package/src/index.d.ts +1372 -0
- package/src/index.js +1 -0
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "settld-api-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/aidenlippert/settld"
|
|
12
|
+
},
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=20"
|
|
15
|
+
},
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./src/index.d.ts",
|
|
19
|
+
"default": "./src/index.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"src"
|
|
24
|
+
]
|
|
25
|
+
}
|
package/src/client.js
ADDED
|
@@ -0,0 +1,627 @@
|
|
|
1
|
+
function assertNonEmptyString(value, name) {
|
|
2
|
+
if (typeof value !== "string" || value.trim() === "") throw new TypeError(`${name} must be a non-empty string`);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
function randomRequestId() {
|
|
6
|
+
try {
|
|
7
|
+
if (globalThis.crypto?.randomUUID) return String(globalThis.crypto.randomUUID());
|
|
8
|
+
} catch {
|
|
9
|
+
// ignore
|
|
10
|
+
}
|
|
11
|
+
return `req_${Math.random().toString(16).slice(2)}${Date.now().toString(16)}`;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function normalizePrefix(value, fallback) {
|
|
15
|
+
if (typeof value === "string" && value.trim() !== "") return value.trim();
|
|
16
|
+
return fallback;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async function readJson(res) {
|
|
20
|
+
const text = await res.text();
|
|
21
|
+
if (!text) return null;
|
|
22
|
+
try {
|
|
23
|
+
return JSON.parse(text);
|
|
24
|
+
} catch {
|
|
25
|
+
return { raw: text };
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function headersToRecord(headers) {
|
|
30
|
+
const out = {};
|
|
31
|
+
for (const [k, v] of headers.entries()) out[String(k).toLowerCase()] = String(v);
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class SettldClient {
|
|
36
|
+
constructor(opts) {
|
|
37
|
+
assertNonEmptyString(opts?.baseUrl, "baseUrl");
|
|
38
|
+
assertNonEmptyString(opts?.tenantId, "tenantId");
|
|
39
|
+
this.baseUrl = String(opts.baseUrl).replace(/\/+$/, "");
|
|
40
|
+
this.tenantId = String(opts.tenantId);
|
|
41
|
+
this.protocol = opts?.protocol ? String(opts.protocol) : "1.0";
|
|
42
|
+
this.apiKey = opts?.apiKey ? String(opts.apiKey) : null;
|
|
43
|
+
this.xApiKey = opts?.xApiKey ? String(opts.xApiKey) : null;
|
|
44
|
+
this.fetchImpl = opts?.fetch ?? fetch;
|
|
45
|
+
this.userAgent = opts?.userAgent ? String(opts.userAgent) : null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async request(method, pathname, { body, requestId, idempotencyKey, expectedPrevChainHash, signal } = {}) {
|
|
49
|
+
const url = new URL(pathname, this.baseUrl);
|
|
50
|
+
const rid = requestId ?? randomRequestId();
|
|
51
|
+
|
|
52
|
+
const headers = {
|
|
53
|
+
"content-type": "application/json",
|
|
54
|
+
"x-proxy-tenant-id": this.tenantId,
|
|
55
|
+
"x-settld-protocol": this.protocol,
|
|
56
|
+
"x-request-id": rid
|
|
57
|
+
};
|
|
58
|
+
if (this.userAgent) headers["user-agent"] = this.userAgent;
|
|
59
|
+
if (idempotencyKey) headers["x-idempotency-key"] = String(idempotencyKey);
|
|
60
|
+
if (expectedPrevChainHash) headers["x-proxy-expected-prev-chain-hash"] = String(expectedPrevChainHash);
|
|
61
|
+
if (this.apiKey) headers["authorization"] = `Bearer ${this.apiKey}`;
|
|
62
|
+
if (this.xApiKey) headers["x-api-key"] = this.xApiKey;
|
|
63
|
+
|
|
64
|
+
const res = await this.fetchImpl(url.toString(), {
|
|
65
|
+
method,
|
|
66
|
+
headers,
|
|
67
|
+
body: body === undefined ? undefined : JSON.stringify(body),
|
|
68
|
+
signal
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const outHeaders = headersToRecord(res.headers);
|
|
72
|
+
const responseRequestId = outHeaders["x-request-id"] ?? null;
|
|
73
|
+
const parsed = await readJson(res);
|
|
74
|
+
if (!res.ok) {
|
|
75
|
+
const errBody = parsed && typeof parsed === "object" ? parsed : {};
|
|
76
|
+
const e = {
|
|
77
|
+
status: res.status,
|
|
78
|
+
code: errBody?.code ?? null,
|
|
79
|
+
message: errBody?.error ?? `request failed (${res.status})`,
|
|
80
|
+
details: errBody?.details,
|
|
81
|
+
requestId: responseRequestId
|
|
82
|
+
};
|
|
83
|
+
const thrown = new Error(e.message);
|
|
84
|
+
thrown.settld = e;
|
|
85
|
+
throw thrown;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return { ok: true, status: res.status, requestId: responseRequestId, body: parsed, headers: outHeaders };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
capabilities(opts) {
|
|
92
|
+
return this.request("GET", "/capabilities", opts);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
openApi(opts) {
|
|
96
|
+
return this.request("GET", "/openapi.json", opts);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
createJob(body, opts) {
|
|
100
|
+
if (!body || typeof body !== "object") throw new TypeError("body is required");
|
|
101
|
+
return this.request("POST", "/jobs", { ...opts, body });
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
getJob(jobId, opts) {
|
|
105
|
+
assertNonEmptyString(jobId, "jobId");
|
|
106
|
+
return this.request("GET", `/jobs/${encodeURIComponent(jobId)}`, opts);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
registerAgent(body, opts) {
|
|
110
|
+
if (!body || typeof body !== "object") throw new TypeError("body is required");
|
|
111
|
+
assertNonEmptyString(body?.publicKeyPem, "body.publicKeyPem");
|
|
112
|
+
return this.request("POST", "/agents/register", { ...opts, body });
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
listAgents(params = {}, opts) {
|
|
116
|
+
const qs = new URLSearchParams();
|
|
117
|
+
if (params.status) qs.set("status", String(params.status));
|
|
118
|
+
if (params.capability) qs.set("capability", String(params.capability));
|
|
119
|
+
if (params.minTrustScore !== undefined && params.minTrustScore !== null) qs.set("minTrustScore", String(params.minTrustScore));
|
|
120
|
+
if (params.includeReputation !== undefined && params.includeReputation !== null) qs.set("includeReputation", String(Boolean(params.includeReputation)));
|
|
121
|
+
if (params.reputationVersion) qs.set("reputationVersion", String(params.reputationVersion));
|
|
122
|
+
if (params.reputationWindow) qs.set("reputationWindow", String(params.reputationWindow));
|
|
123
|
+
if (params.limit !== undefined && params.limit !== null) qs.set("limit", String(params.limit));
|
|
124
|
+
if (params.offset !== undefined && params.offset !== null) qs.set("offset", String(params.offset));
|
|
125
|
+
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
126
|
+
return this.request("GET", `/agents${suffix}`, opts);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
getAgent(agentId, opts) {
|
|
130
|
+
assertNonEmptyString(agentId, "agentId");
|
|
131
|
+
return this.request("GET", `/agents/${encodeURIComponent(agentId)}`, opts);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
getAgentReputation(agentId, opts = {}) {
|
|
135
|
+
assertNonEmptyString(agentId, "agentId");
|
|
136
|
+
const qs = new URLSearchParams();
|
|
137
|
+
if (opts.reputationVersion) qs.set("reputationVersion", String(opts.reputationVersion));
|
|
138
|
+
if (opts.reputationWindow) qs.set("reputationWindow", String(opts.reputationWindow));
|
|
139
|
+
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
140
|
+
const { reputationVersion: _rVersion, reputationWindow: _rWindow, ...requestOpts } = opts ?? {};
|
|
141
|
+
return this.request("GET", `/agents/${encodeURIComponent(agentId)}/reputation${suffix}`, requestOpts);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
searchMarketplaceAgents(params = {}, opts) {
|
|
145
|
+
const qs = new URLSearchParams();
|
|
146
|
+
if (params.status) qs.set("status", String(params.status));
|
|
147
|
+
if (params.capability) qs.set("capability", String(params.capability));
|
|
148
|
+
if (params.minTrustScore !== undefined && params.minTrustScore !== null) qs.set("minTrustScore", String(params.minTrustScore));
|
|
149
|
+
if (params.riskTier) qs.set("riskTier", String(params.riskTier));
|
|
150
|
+
if (params.includeReputation !== undefined && params.includeReputation !== null) qs.set("includeReputation", String(Boolean(params.includeReputation)));
|
|
151
|
+
if (params.reputationVersion) qs.set("reputationVersion", String(params.reputationVersion));
|
|
152
|
+
if (params.reputationWindow) qs.set("reputationWindow", String(params.reputationWindow));
|
|
153
|
+
if (params.scoreStrategy) qs.set("scoreStrategy", String(params.scoreStrategy));
|
|
154
|
+
if (params.limit !== undefined && params.limit !== null) qs.set("limit", String(params.limit));
|
|
155
|
+
if (params.offset !== undefined && params.offset !== null) qs.set("offset", String(params.offset));
|
|
156
|
+
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
157
|
+
return this.request("GET", `/marketplace/agents/search${suffix}`, opts);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
upsertMarketplaceSettlementPolicy(body, opts) {
|
|
161
|
+
if (!body || typeof body !== "object") throw new TypeError("body is required");
|
|
162
|
+
return this.request("POST", "/marketplace/settlement-policies", { ...opts, body });
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
listMarketplaceSettlementPolicies(params = {}, opts) {
|
|
166
|
+
const qs = new URLSearchParams();
|
|
167
|
+
if (params.policyId) qs.set("policyId", String(params.policyId));
|
|
168
|
+
if (params.limit !== undefined && params.limit !== null) qs.set("limit", String(params.limit));
|
|
169
|
+
if (params.offset !== undefined && params.offset !== null) qs.set("offset", String(params.offset));
|
|
170
|
+
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
171
|
+
return this.request("GET", `/marketplace/settlement-policies${suffix}`, opts);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
getMarketplaceSettlementPolicy(policyId, policyVersion, opts) {
|
|
175
|
+
assertNonEmptyString(policyId, "policyId");
|
|
176
|
+
if (!Number.isSafeInteger(Number(policyVersion)) || Number(policyVersion) <= 0) {
|
|
177
|
+
throw new TypeError("policyVersion must be a positive safe integer");
|
|
178
|
+
}
|
|
179
|
+
return this.request(
|
|
180
|
+
"GET",
|
|
181
|
+
`/marketplace/settlement-policies/${encodeURIComponent(policyId)}/${encodeURIComponent(String(policyVersion))}`,
|
|
182
|
+
opts
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
createMarketplaceRfq(body, opts) {
|
|
187
|
+
if (!body || typeof body !== "object") throw new TypeError("body is required");
|
|
188
|
+
return this.request("POST", "/marketplace/rfqs", { ...opts, body });
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
listMarketplaceRfqs(params = {}, opts) {
|
|
192
|
+
const qs = new URLSearchParams();
|
|
193
|
+
if (params.status) qs.set("status", String(params.status));
|
|
194
|
+
if (params.capability) qs.set("capability", String(params.capability));
|
|
195
|
+
if (params.posterAgentId) qs.set("posterAgentId", String(params.posterAgentId));
|
|
196
|
+
if (params.limit !== undefined && params.limit !== null) qs.set("limit", String(params.limit));
|
|
197
|
+
if (params.offset !== undefined && params.offset !== null) qs.set("offset", String(params.offset));
|
|
198
|
+
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
199
|
+
return this.request("GET", `/marketplace/rfqs${suffix}`, opts);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
submitMarketplaceBid(rfqId, body, opts) {
|
|
203
|
+
assertNonEmptyString(rfqId, "rfqId");
|
|
204
|
+
if (!body || typeof body !== "object") throw new TypeError("body is required");
|
|
205
|
+
return this.request("POST", `/marketplace/rfqs/${encodeURIComponent(rfqId)}/bids`, { ...opts, body });
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
listMarketplaceBids(rfqId, params = {}, opts) {
|
|
209
|
+
assertNonEmptyString(rfqId, "rfqId");
|
|
210
|
+
const qs = new URLSearchParams();
|
|
211
|
+
if (params.status) qs.set("status", String(params.status));
|
|
212
|
+
if (params.bidderAgentId) qs.set("bidderAgentId", String(params.bidderAgentId));
|
|
213
|
+
if (params.limit !== undefined && params.limit !== null) qs.set("limit", String(params.limit));
|
|
214
|
+
if (params.offset !== undefined && params.offset !== null) qs.set("offset", String(params.offset));
|
|
215
|
+
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
216
|
+
return this.request("GET", `/marketplace/rfqs/${encodeURIComponent(rfqId)}/bids${suffix}`, opts);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
applyMarketplaceBidCounterOffer(rfqId, bidId, body, opts) {
|
|
220
|
+
assertNonEmptyString(rfqId, "rfqId");
|
|
221
|
+
assertNonEmptyString(bidId, "bidId");
|
|
222
|
+
if (!body || typeof body !== "object") throw new TypeError("body is required");
|
|
223
|
+
return this.request("POST", `/marketplace/rfqs/${encodeURIComponent(rfqId)}/bids/${encodeURIComponent(bidId)}/counter-offer`, {
|
|
224
|
+
...opts,
|
|
225
|
+
body
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
acceptMarketplaceBid(rfqId, body, opts) {
|
|
230
|
+
assertNonEmptyString(rfqId, "rfqId");
|
|
231
|
+
if (!body || typeof body !== "object") throw new TypeError("body is required");
|
|
232
|
+
return this.request("POST", `/marketplace/rfqs/${encodeURIComponent(rfqId)}/accept`, { ...opts, body });
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
getAgentWallet(agentId, opts) {
|
|
236
|
+
assertNonEmptyString(agentId, "agentId");
|
|
237
|
+
return this.request("GET", `/agents/${encodeURIComponent(agentId)}/wallet`, opts);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
creditAgentWallet(agentId, body, opts) {
|
|
241
|
+
assertNonEmptyString(agentId, "agentId");
|
|
242
|
+
if (!body || typeof body !== "object") throw new TypeError("body is required");
|
|
243
|
+
return this.request("POST", `/agents/${encodeURIComponent(agentId)}/wallet/credit`, { ...opts, body });
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
createAgentRun(agentId, body = {}, opts) {
|
|
247
|
+
assertNonEmptyString(agentId, "agentId");
|
|
248
|
+
if (!body || typeof body !== "object") throw new TypeError("body must be an object");
|
|
249
|
+
return this.request("POST", `/agents/${encodeURIComponent(agentId)}/runs`, { ...opts, body });
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
listAgentRuns(agentId, params = {}, opts) {
|
|
253
|
+
assertNonEmptyString(agentId, "agentId");
|
|
254
|
+
const qs = new URLSearchParams();
|
|
255
|
+
if (params.status) qs.set("status", String(params.status));
|
|
256
|
+
if (params.limit !== undefined && params.limit !== null) qs.set("limit", String(params.limit));
|
|
257
|
+
if (params.offset !== undefined && params.offset !== null) qs.set("offset", String(params.offset));
|
|
258
|
+
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
259
|
+
return this.request("GET", `/agents/${encodeURIComponent(agentId)}/runs${suffix}`, opts);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
getAgentRun(agentId, runId, opts) {
|
|
263
|
+
assertNonEmptyString(agentId, "agentId");
|
|
264
|
+
assertNonEmptyString(runId, "runId");
|
|
265
|
+
return this.request("GET", `/agents/${encodeURIComponent(agentId)}/runs/${encodeURIComponent(runId)}`, opts);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
listAgentRunEvents(agentId, runId, opts) {
|
|
269
|
+
assertNonEmptyString(agentId, "agentId");
|
|
270
|
+
assertNonEmptyString(runId, "runId");
|
|
271
|
+
return this.request("GET", `/agents/${encodeURIComponent(agentId)}/runs/${encodeURIComponent(runId)}/events`, opts);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
appendAgentRunEvent(agentId, runId, body, opts) {
|
|
275
|
+
assertNonEmptyString(agentId, "agentId");
|
|
276
|
+
assertNonEmptyString(runId, "runId");
|
|
277
|
+
if (!opts?.expectedPrevChainHash) throw new TypeError("expectedPrevChainHash is required for appendAgentRunEvent");
|
|
278
|
+
if (!body || typeof body !== "object") throw new TypeError("body is required");
|
|
279
|
+
assertNonEmptyString(body?.type, "body.type");
|
|
280
|
+
return this.request("POST", `/agents/${encodeURIComponent(agentId)}/runs/${encodeURIComponent(runId)}/events`, { ...opts, body });
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
getRunVerification(runId, opts) {
|
|
284
|
+
assertNonEmptyString(runId, "runId");
|
|
285
|
+
return this.request("GET", `/runs/${encodeURIComponent(runId)}/verification`, opts);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
getRunSettlement(runId, opts) {
|
|
289
|
+
assertNonEmptyString(runId, "runId");
|
|
290
|
+
return this.request("GET", `/runs/${encodeURIComponent(runId)}/settlement`, opts);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
getRunAgreement(runId, opts) {
|
|
294
|
+
assertNonEmptyString(runId, "runId");
|
|
295
|
+
return this.request("GET", `/runs/${encodeURIComponent(runId)}/agreement`, opts);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
applyRunAgreementChangeOrder(runId, body, opts) {
|
|
299
|
+
assertNonEmptyString(runId, "runId");
|
|
300
|
+
if (!body || typeof body !== "object") throw new TypeError("body is required");
|
|
301
|
+
return this.request("POST", `/runs/${encodeURIComponent(runId)}/agreement/change-order`, { ...opts, body });
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
cancelRunAgreement(runId, body, opts) {
|
|
305
|
+
assertNonEmptyString(runId, "runId");
|
|
306
|
+
if (!body || typeof body !== "object") throw new TypeError("body is required");
|
|
307
|
+
return this.request("POST", `/runs/${encodeURIComponent(runId)}/agreement/cancel`, { ...opts, body });
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
getRunSettlementPolicyReplay(runId, opts) {
|
|
311
|
+
assertNonEmptyString(runId, "runId");
|
|
312
|
+
return this.request("GET", `/runs/${encodeURIComponent(runId)}/settlement/policy-replay`, opts);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
resolveRunSettlement(runId, body, opts) {
|
|
316
|
+
assertNonEmptyString(runId, "runId");
|
|
317
|
+
if (!body || typeof body !== "object") throw new TypeError("body is required");
|
|
318
|
+
return this.request("POST", `/runs/${encodeURIComponent(runId)}/settlement/resolve`, { ...opts, body });
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
opsLockToolCallHold(body, opts) {
|
|
322
|
+
if (!body || typeof body !== "object") throw new TypeError("body is required");
|
|
323
|
+
return this.request("POST", "/ops/tool-calls/holds/lock", { ...opts, body });
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
opsListToolCallHolds(params = {}, opts) {
|
|
327
|
+
const qs = new URLSearchParams();
|
|
328
|
+
if (params.agreementHash) qs.set("agreementHash", String(params.agreementHash));
|
|
329
|
+
if (params.status) qs.set("status", String(params.status));
|
|
330
|
+
if (params.limit !== undefined && params.limit !== null) qs.set("limit", String(params.limit));
|
|
331
|
+
if (params.offset !== undefined && params.offset !== null) qs.set("offset", String(params.offset));
|
|
332
|
+
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
333
|
+
return this.request("GET", `/ops/tool-calls/holds${suffix}`, opts);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
opsGetToolCallHold(holdHash, opts) {
|
|
337
|
+
assertNonEmptyString(holdHash, "holdHash");
|
|
338
|
+
return this.request("GET", `/ops/tool-calls/holds/${encodeURIComponent(holdHash)}`, opts);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
opsRunToolCallHoldbackMaintenance(body = {}, opts) {
|
|
342
|
+
if (!body || typeof body !== "object") throw new TypeError("body must be an object");
|
|
343
|
+
return this.request("POST", "/ops/maintenance/tool-call-holdback/run", { ...opts, body });
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
toolCallListArbitrationCases(params = {}, opts) {
|
|
347
|
+
const qs = new URLSearchParams();
|
|
348
|
+
if (params.agreementHash) qs.set("agreementHash", String(params.agreementHash));
|
|
349
|
+
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
350
|
+
return this.request("GET", `/tool-calls/arbitration/cases${suffix}`, opts);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
toolCallGetArbitrationCase(caseId, opts) {
|
|
354
|
+
assertNonEmptyString(caseId, "caseId");
|
|
355
|
+
return this.request("GET", `/tool-calls/arbitration/cases/${encodeURIComponent(caseId)}`, opts);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
toolCallOpenArbitration(body, opts) {
|
|
359
|
+
if (!body || typeof body !== "object") throw new TypeError("body is required");
|
|
360
|
+
return this.request("POST", "/tool-calls/arbitration/open", { ...opts, body });
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
toolCallSubmitArbitrationVerdict(body, opts) {
|
|
364
|
+
if (!body || typeof body !== "object") throw new TypeError("body is required");
|
|
365
|
+
return this.request("POST", "/tool-calls/arbitration/verdict", { ...opts, body });
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
opsGetSettlementAdjustment(adjustmentId, opts) {
|
|
369
|
+
assertNonEmptyString(adjustmentId, "adjustmentId");
|
|
370
|
+
return this.request("GET", `/ops/settlement-adjustments/${encodeURIComponent(adjustmentId)}`, opts);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
openRunDispute(runId, body = {}, opts) {
|
|
374
|
+
assertNonEmptyString(runId, "runId");
|
|
375
|
+
if (!body || typeof body !== "object" || Array.isArray(body)) throw new TypeError("body must be an object");
|
|
376
|
+
return this.request("POST", `/runs/${encodeURIComponent(runId)}/dispute/open`, { ...opts, body });
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
closeRunDispute(runId, body = {}, opts) {
|
|
380
|
+
assertNonEmptyString(runId, "runId");
|
|
381
|
+
if (!body || typeof body !== "object" || Array.isArray(body)) throw new TypeError("body must be an object");
|
|
382
|
+
return this.request("POST", `/runs/${encodeURIComponent(runId)}/dispute/close`, { ...opts, body });
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
submitRunDisputeEvidence(runId, body, opts) {
|
|
386
|
+
assertNonEmptyString(runId, "runId");
|
|
387
|
+
if (!body || typeof body !== "object" || Array.isArray(body)) throw new TypeError("body is required");
|
|
388
|
+
assertNonEmptyString(body?.evidenceRef, "body.evidenceRef");
|
|
389
|
+
return this.request("POST", `/runs/${encodeURIComponent(runId)}/dispute/evidence`, { ...opts, body });
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
escalateRunDispute(runId, body, opts) {
|
|
393
|
+
assertNonEmptyString(runId, "runId");
|
|
394
|
+
if (!body || typeof body !== "object" || Array.isArray(body)) throw new TypeError("body is required");
|
|
395
|
+
assertNonEmptyString(body?.escalationLevel, "body.escalationLevel");
|
|
396
|
+
return this.request("POST", `/runs/${encodeURIComponent(runId)}/dispute/escalate`, { ...opts, body });
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
async firstVerifiedRun(params = {}, opts = {}) {
|
|
400
|
+
if (!params || typeof params !== "object") throw new TypeError("params must be an object");
|
|
401
|
+
if (!params?.payeeAgent || typeof params.payeeAgent !== "object") throw new TypeError("params.payeeAgent is required");
|
|
402
|
+
assertNonEmptyString(params.payeeAgent?.publicKeyPem, "params.payeeAgent.publicKeyPem");
|
|
403
|
+
|
|
404
|
+
const stepPrefix = normalizePrefix(
|
|
405
|
+
opts.idempotencyPrefix,
|
|
406
|
+
`sdk_first_verified_run_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`
|
|
407
|
+
);
|
|
408
|
+
const requestPrefix = normalizePrefix(opts.requestIdPrefix, randomRequestId());
|
|
409
|
+
const makeStepOpts = (step, extra = {}) => ({
|
|
410
|
+
signal: opts.signal,
|
|
411
|
+
requestId: `${requestPrefix}_${step}`,
|
|
412
|
+
idempotencyKey: `${stepPrefix}_${step}`,
|
|
413
|
+
...extra
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
const payeeRegistration = await this.registerAgent(params.payeeAgent, makeStepOpts("register_payee"));
|
|
417
|
+
const payeeAgentId = payeeRegistration?.body?.agentIdentity?.agentId;
|
|
418
|
+
assertNonEmptyString(payeeAgentId, "payeeAgentId");
|
|
419
|
+
|
|
420
|
+
let payerRegistration = null;
|
|
421
|
+
let payerCredit = null;
|
|
422
|
+
let payerAgentId = null;
|
|
423
|
+
if (params.payerAgent) {
|
|
424
|
+
if (typeof params.payerAgent !== "object") throw new TypeError("params.payerAgent must be an object");
|
|
425
|
+
assertNonEmptyString(params.payerAgent?.publicKeyPem, "params.payerAgent.publicKeyPem");
|
|
426
|
+
payerRegistration = await this.registerAgent(params.payerAgent, makeStepOpts("register_payer"));
|
|
427
|
+
payerAgentId = payerRegistration?.body?.agentIdentity?.agentId ?? null;
|
|
428
|
+
assertNonEmptyString(payerAgentId, "payerAgentId");
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
const settlementAmountCents = params?.settlement?.amountCents;
|
|
432
|
+
const settlementCurrency = params?.settlement?.currency ?? "USD";
|
|
433
|
+
if ((settlementAmountCents !== undefined || params?.settlement?.payerAgentId) && !payerAgentId && !params?.settlement?.payerAgentId) {
|
|
434
|
+
throw new TypeError("params.payerAgent or params.settlement.payerAgentId is required when settlement is requested");
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
if (params.payerCredit && typeof params.payerCredit !== "object") throw new TypeError("params.payerCredit must be an object");
|
|
438
|
+
const payerCreditAmountCents = params?.payerCredit?.amountCents;
|
|
439
|
+
if (payerCreditAmountCents !== undefined && payerCreditAmountCents !== null) {
|
|
440
|
+
if (!Number.isFinite(payerCreditAmountCents) || payerCreditAmountCents <= 0) {
|
|
441
|
+
throw new TypeError("params.payerCredit.amountCents must be a positive number");
|
|
442
|
+
}
|
|
443
|
+
if (!payerAgentId) throw new TypeError("params.payerAgent is required when params.payerCredit is provided");
|
|
444
|
+
payerCredit = await this.creditAgentWallet(
|
|
445
|
+
payerAgentId,
|
|
446
|
+
{
|
|
447
|
+
amountCents: Number(payerCreditAmountCents),
|
|
448
|
+
currency: params?.payerCredit?.currency ?? settlementCurrency
|
|
449
|
+
},
|
|
450
|
+
makeStepOpts("credit_payer_wallet")
|
|
451
|
+
);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
const runBody = { ...(params.run ?? {}) };
|
|
455
|
+
const settlementPayerAgentId = params?.settlement?.payerAgentId ?? payerAgentId;
|
|
456
|
+
if (settlementAmountCents !== undefined && settlementAmountCents !== null) {
|
|
457
|
+
if (!Number.isFinite(settlementAmountCents) || settlementAmountCents <= 0) {
|
|
458
|
+
throw new TypeError("params.settlement.amountCents must be a positive number");
|
|
459
|
+
}
|
|
460
|
+
if (!settlementPayerAgentId) {
|
|
461
|
+
throw new TypeError("params.settlement.payerAgentId or params.payerAgent is required when params.settlement.amountCents is set");
|
|
462
|
+
}
|
|
463
|
+
runBody.settlement = {
|
|
464
|
+
payerAgentId: settlementPayerAgentId,
|
|
465
|
+
amountCents: Number(settlementAmountCents),
|
|
466
|
+
currency: settlementCurrency,
|
|
467
|
+
...(params?.settlement?.disputeWindowDays !== undefined ? { disputeWindowDays: params.settlement.disputeWindowDays } : {})
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
const runCreated = await this.createAgentRun(payeeAgentId, runBody, makeStepOpts("create_run"));
|
|
472
|
+
const runId = runCreated?.body?.run?.runId;
|
|
473
|
+
assertNonEmptyString(runId, "runId");
|
|
474
|
+
let prevChainHash = runCreated?.body?.run?.lastChainHash;
|
|
475
|
+
assertNonEmptyString(prevChainHash, "runCreated.body.run.lastChainHash");
|
|
476
|
+
|
|
477
|
+
const actor = params.actor ?? { type: "agent", id: payeeAgentId };
|
|
478
|
+
const runStarted = await this.appendAgentRunEvent(
|
|
479
|
+
payeeAgentId,
|
|
480
|
+
runId,
|
|
481
|
+
{ type: "RUN_STARTED", actor, payload: params.startedPayload ?? { startedBy: "sdk.firstVerifiedRun" } },
|
|
482
|
+
makeStepOpts("run_started", { expectedPrevChainHash: prevChainHash })
|
|
483
|
+
);
|
|
484
|
+
prevChainHash = runStarted?.body?.run?.lastChainHash;
|
|
485
|
+
assertNonEmptyString(prevChainHash, "runStarted.body.run.lastChainHash");
|
|
486
|
+
|
|
487
|
+
const evidenceRef = typeof params.evidenceRef === "string" && params.evidenceRef.trim() !== ""
|
|
488
|
+
? params.evidenceRef.trim()
|
|
489
|
+
: `evidence://${runId}/output.json`;
|
|
490
|
+
const runEvidenceAdded = await this.appendAgentRunEvent(
|
|
491
|
+
payeeAgentId,
|
|
492
|
+
runId,
|
|
493
|
+
{ type: "EVIDENCE_ADDED", actor, payload: params.evidencePayload ?? { evidenceRef } },
|
|
494
|
+
makeStepOpts("evidence_added", { expectedPrevChainHash: prevChainHash })
|
|
495
|
+
);
|
|
496
|
+
prevChainHash = runEvidenceAdded?.body?.run?.lastChainHash;
|
|
497
|
+
assertNonEmptyString(prevChainHash, "runEvidenceAdded.body.run.lastChainHash");
|
|
498
|
+
|
|
499
|
+
const completedPayload = {
|
|
500
|
+
outputRef: typeof params.outputRef === "string" && params.outputRef.trim() !== "" ? params.outputRef.trim() : evidenceRef,
|
|
501
|
+
...(params.completedPayload ?? {})
|
|
502
|
+
};
|
|
503
|
+
if (params.completedMetrics && typeof params.completedMetrics === "object") completedPayload.metrics = params.completedMetrics;
|
|
504
|
+
const runCompleted = await this.appendAgentRunEvent(
|
|
505
|
+
payeeAgentId,
|
|
506
|
+
runId,
|
|
507
|
+
{ type: "RUN_COMPLETED", actor, payload: completedPayload },
|
|
508
|
+
makeStepOpts("run_completed", { expectedPrevChainHash: prevChainHash })
|
|
509
|
+
);
|
|
510
|
+
|
|
511
|
+
const run = await this.getAgentRun(payeeAgentId, runId, makeStepOpts("get_run"));
|
|
512
|
+
const verification = await this.getRunVerification(runId, makeStepOpts("get_verification"));
|
|
513
|
+
|
|
514
|
+
let settlement = null;
|
|
515
|
+
if (runBody.settlement || runCreated?.body?.settlement || runCompleted?.body?.settlement) {
|
|
516
|
+
settlement = await this.getRunSettlement(runId, makeStepOpts("get_settlement"));
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
return {
|
|
520
|
+
ids: { runId, payeeAgentId, payerAgentId },
|
|
521
|
+
payeeRegistration,
|
|
522
|
+
payerRegistration,
|
|
523
|
+
payerCredit,
|
|
524
|
+
runCreated,
|
|
525
|
+
runStarted,
|
|
526
|
+
runEvidenceAdded,
|
|
527
|
+
runCompleted,
|
|
528
|
+
run,
|
|
529
|
+
verification,
|
|
530
|
+
settlement
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
quoteJob(jobId, body, opts) {
|
|
535
|
+
assertNonEmptyString(jobId, "jobId");
|
|
536
|
+
if (!opts?.expectedPrevChainHash) throw new TypeError("expectedPrevChainHash is required for quoteJob");
|
|
537
|
+
return this.request("POST", `/jobs/${encodeURIComponent(jobId)}/quote`, { ...opts, body });
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
bookJob(jobId, body, opts) {
|
|
541
|
+
assertNonEmptyString(jobId, "jobId");
|
|
542
|
+
if (!opts?.expectedPrevChainHash) throw new TypeError("expectedPrevChainHash is required for bookJob");
|
|
543
|
+
return this.request("POST", `/jobs/${encodeURIComponent(jobId)}/book`, { ...opts, body });
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
appendJobEvent(jobId, body, opts) {
|
|
547
|
+
assertNonEmptyString(jobId, "jobId");
|
|
548
|
+
return this.request("POST", `/jobs/${encodeURIComponent(jobId)}/events`, { ...opts, body });
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
opsStatus(opts) {
|
|
552
|
+
return this.request("GET", "/ops/status", opts);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
listPartyStatements(params, opts) {
|
|
556
|
+
assertNonEmptyString(params?.period, "period");
|
|
557
|
+
const qs = new URLSearchParams({ period: String(params.period) });
|
|
558
|
+
if (params.partyId) qs.set("partyId", String(params.partyId));
|
|
559
|
+
if (params.status) qs.set("status", String(params.status));
|
|
560
|
+
return this.request("GET", `/ops/party-statements?${qs.toString()}`, opts);
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
getPartyStatement(partyId, period, opts) {
|
|
564
|
+
assertNonEmptyString(partyId, "partyId");
|
|
565
|
+
assertNonEmptyString(period, "period");
|
|
566
|
+
return this.request("GET", `/ops/party-statements/${encodeURIComponent(partyId)}/${encodeURIComponent(period)}`, opts);
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
enqueuePayout(partyId, period, opts) {
|
|
570
|
+
assertNonEmptyString(partyId, "partyId");
|
|
571
|
+
assertNonEmptyString(period, "period");
|
|
572
|
+
return this.request("POST", `/ops/payouts/${encodeURIComponent(partyId)}/${encodeURIComponent(period)}/enqueue`, opts);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
requestMonthClose(body, opts) {
|
|
576
|
+
if (!body || typeof body !== "object") throw new TypeError("body is required");
|
|
577
|
+
assertNonEmptyString(body?.month, "month");
|
|
578
|
+
return this.request("POST", "/ops/month-close", { ...opts, body });
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
getTenantAnalytics(tenantId, params = {}, opts) {
|
|
582
|
+
assertNonEmptyString(tenantId, "tenantId");
|
|
583
|
+
const qs = new URLSearchParams();
|
|
584
|
+
if (params.month) qs.set("month", String(params.month));
|
|
585
|
+
if (params.bucket) qs.set("bucket", String(params.bucket));
|
|
586
|
+
if (params.limit !== undefined && params.limit !== null) qs.set("limit", String(params.limit));
|
|
587
|
+
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
588
|
+
return this.request("GET", `/v1/tenants/${encodeURIComponent(tenantId)}/analytics${suffix}`, opts);
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
getTenantTrustGraph(tenantId, params = {}, opts) {
|
|
592
|
+
assertNonEmptyString(tenantId, "tenantId");
|
|
593
|
+
const qs = new URLSearchParams();
|
|
594
|
+
if (params.month) qs.set("month", String(params.month));
|
|
595
|
+
if (params.minRuns !== undefined && params.minRuns !== null) qs.set("minRuns", String(params.minRuns));
|
|
596
|
+
if (params.maxEdges !== undefined && params.maxEdges !== null) qs.set("maxEdges", String(params.maxEdges));
|
|
597
|
+
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
598
|
+
return this.request("GET", `/v1/tenants/${encodeURIComponent(tenantId)}/trust-graph${suffix}`, opts);
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
listTenantTrustGraphSnapshots(tenantId, params = {}, opts) {
|
|
602
|
+
assertNonEmptyString(tenantId, "tenantId");
|
|
603
|
+
const qs = new URLSearchParams();
|
|
604
|
+
if (params.limit !== undefined && params.limit !== null) qs.set("limit", String(params.limit));
|
|
605
|
+
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
606
|
+
return this.request("GET", `/v1/tenants/${encodeURIComponent(tenantId)}/trust-graph/snapshots${suffix}`, opts);
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
createTenantTrustGraphSnapshot(tenantId, body = {}, opts) {
|
|
610
|
+
assertNonEmptyString(tenantId, "tenantId");
|
|
611
|
+
if (body === null || typeof body !== "object" || Array.isArray(body)) throw new TypeError("body must be an object");
|
|
612
|
+
return this.request("POST", `/v1/tenants/${encodeURIComponent(tenantId)}/trust-graph/snapshots`, { ...opts, body });
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
diffTenantTrustGraph(tenantId, params = {}, opts) {
|
|
616
|
+
assertNonEmptyString(tenantId, "tenantId");
|
|
617
|
+
const qs = new URLSearchParams();
|
|
618
|
+
if (params.baseMonth) qs.set("baseMonth", String(params.baseMonth));
|
|
619
|
+
if (params.compareMonth) qs.set("compareMonth", String(params.compareMonth));
|
|
620
|
+
if (params.limit !== undefined && params.limit !== null) qs.set("limit", String(params.limit));
|
|
621
|
+
if (params.minRuns !== undefined && params.minRuns !== null) qs.set("minRuns", String(params.minRuns));
|
|
622
|
+
if (params.maxEdges !== undefined && params.maxEdges !== null) qs.set("maxEdges", String(params.maxEdges));
|
|
623
|
+
if (params.includeUnchanged !== undefined && params.includeUnchanged !== null) qs.set("includeUnchanged", String(Boolean(params.includeUnchanged)));
|
|
624
|
+
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
625
|
+
return this.request("GET", `/v1/tenants/${encodeURIComponent(tenantId)}/trust-graph/diff${suffix}`, opts);
|
|
626
|
+
}
|
|
627
|
+
}
|