@agents24/client 0.1.0 → 0.2.1
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/README.md +38 -6
- package/compatibility.json +10 -10
- package/dist/adapters/browser.d.ts +83 -1
- package/dist/adapters/browser.js +303 -3
- package/dist/adapters/browser.js.map +1 -1
- package/dist/adapters/cloudflare.js +3 -2
- package/dist/adapters/cloudflare.js.map +1 -1
- package/dist/adapters/node.js +3 -2
- package/dist/adapters/node.js.map +1 -1
- package/dist/adapters/worker.js +3 -2
- package/dist/adapters/worker.js.map +1 -1
- package/dist/bff.d.ts +10 -0
- package/dist/bff.js +282 -0
- package/dist/bff.js.map +1 -0
- package/dist/chunk-FNR3KPB6.js +569 -0
- package/dist/chunk-FNR3KPB6.js.map +1 -0
- package/dist/{chunk-45ITVMX3.js → chunk-GXISGBVW.js} +126 -480
- package/dist/chunk-GXISGBVW.js.map +1 -0
- package/dist/{chunk-VVLMMNXI.js → chunk-IOVCURGW.js} +32 -14
- package/dist/chunk-IOVCURGW.js.map +1 -0
- package/dist/chunk-SPWEZFHZ.js +430 -0
- package/dist/chunk-SPWEZFHZ.js.map +1 -0
- package/dist/context-window.d.ts +16 -1
- package/dist/errors.d.ts +27 -2
- package/dist/generated/protocol.d.ts +50 -9
- package/dist/index.d.ts +4 -3
- package/dist/index.js +4 -555
- package/dist/index.js.map +1 -1
- package/dist/protocol.d.ts +2 -2
- package/dist/protocol.js +31 -1
- package/dist/protocol.js.map +1 -1
- package/dist/runtime-types.d.ts +37 -2
- package/dist/types.d.ts +148 -10
- package/package.json +5 -1
- package/dist/chunk-45ITVMX3.js.map +0 -1
- package/dist/chunk-VVLMMNXI.js.map +0 -1
|
@@ -1,23 +1,40 @@
|
|
|
1
|
-
import { createSseParser, Agents24ProtocolError, parseRuntimeSsePayload, parseThreadSummarySsePayload } from './chunk-
|
|
1
|
+
import { createSseParser, Agents24ProtocolError, parseRuntimeSsePayload, parseThreadSummarySsePayload } from './chunk-IOVCURGW.js';
|
|
2
2
|
|
|
3
3
|
// src/errors.ts
|
|
4
4
|
var Agents24ClientError = class extends Error {
|
|
5
5
|
kind;
|
|
6
6
|
code;
|
|
7
7
|
status;
|
|
8
|
+
failure;
|
|
8
9
|
requestId;
|
|
9
10
|
retryable;
|
|
11
|
+
violations;
|
|
10
12
|
cause;
|
|
11
13
|
constructor(message, options) {
|
|
12
14
|
super(message);
|
|
13
15
|
this.name = "Agents24ClientError";
|
|
14
16
|
this.kind = options.kind;
|
|
15
|
-
this.code = options.code ?? "CLIENT_ERROR";
|
|
17
|
+
this.code = options.failure?.code ?? options.code ?? "CLIENT_ERROR";
|
|
16
18
|
this.status = options.status;
|
|
17
|
-
this.
|
|
18
|
-
this.
|
|
19
|
+
this.failure = options.failure;
|
|
20
|
+
this.requestId = options.failure?.request_id ?? options.requestId;
|
|
21
|
+
this.retryable = options.failure?.retryable ?? options.retryable ?? false;
|
|
22
|
+
const violations = options.failure?.details.violations;
|
|
23
|
+
this.violations = Array.isArray(violations) ? violations : options.violations ?? [];
|
|
19
24
|
this.cause = options.cause;
|
|
20
25
|
}
|
|
26
|
+
get failureId() {
|
|
27
|
+
return this.failure?.failure_id;
|
|
28
|
+
}
|
|
29
|
+
get category() {
|
|
30
|
+
return this.failure?.category;
|
|
31
|
+
}
|
|
32
|
+
get retryAfterMs() {
|
|
33
|
+
return this.failure?.retry_after_ms ?? void 0;
|
|
34
|
+
}
|
|
35
|
+
get details() {
|
|
36
|
+
return this.failure?.details ?? {};
|
|
37
|
+
}
|
|
21
38
|
};
|
|
22
39
|
function missingCapability(name) {
|
|
23
40
|
return new Agents24ClientError(`Required capability is unavailable: ${name}.`, {
|
|
@@ -85,78 +102,6 @@ function secureRandomBytes(length) {
|
|
|
85
102
|
return getRandomValues(target);
|
|
86
103
|
}
|
|
87
104
|
|
|
88
|
-
// src/multipart.ts
|
|
89
|
-
function isBlobLike(value) {
|
|
90
|
-
return typeof value.arrayBuffer === "function";
|
|
91
|
-
}
|
|
92
|
-
async function toBytes(value) {
|
|
93
|
-
if (value instanceof Uint8Array) return value;
|
|
94
|
-
if (value instanceof ArrayBuffer) return new Uint8Array(value);
|
|
95
|
-
if (isBlobLike(value)) return new Uint8Array(await value.arrayBuffer());
|
|
96
|
-
throw new Agents24ClientError("Upload data must be bytes, an ArrayBuffer, or a compatible blob-like value.", {
|
|
97
|
-
kind: "validation",
|
|
98
|
-
code: "INVALID_UPLOAD_DATA"
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
function safeToken(value, field) {
|
|
102
|
-
if (!value || /[\r\n\0]/.test(value)) {
|
|
103
|
-
throw new Agents24ClientError(`${field} contains invalid characters.`, {
|
|
104
|
-
kind: "validation",
|
|
105
|
-
code: "INVALID_MULTIPART_METADATA"
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
return value.replace(/["\\]/g, "_");
|
|
109
|
-
}
|
|
110
|
-
function concat(chunks) {
|
|
111
|
-
const length = chunks.reduce((total, chunk) => total + chunk.byteLength, 0);
|
|
112
|
-
const output = new Uint8Array(length);
|
|
113
|
-
let offset = 0;
|
|
114
|
-
for (const chunk of chunks) {
|
|
115
|
-
output.set(chunk, offset);
|
|
116
|
-
offset += chunk.byteLength;
|
|
117
|
-
}
|
|
118
|
-
return output;
|
|
119
|
-
}
|
|
120
|
-
async function encodePart(part, boundary, encoder) {
|
|
121
|
-
const field = safeToken(part.field, "Multipart field");
|
|
122
|
-
if (typeof part.value === "string") {
|
|
123
|
-
return [encoder.encode(`--${boundary}\r
|
|
124
|
-
Content-Disposition: form-data; name="${field}"\r
|
|
125
|
-
\r
|
|
126
|
-
${part.value}\r
|
|
127
|
-
`)];
|
|
128
|
-
}
|
|
129
|
-
const upload = part.value;
|
|
130
|
-
const filename = safeToken(upload.name, "Upload filename");
|
|
131
|
-
const mediaType = safeToken(upload.mediaType, "Upload media type");
|
|
132
|
-
return [
|
|
133
|
-
encoder.encode(
|
|
134
|
-
`--${boundary}\r
|
|
135
|
-
Content-Disposition: form-data; name="${field}"; filename="${filename}"\r
|
|
136
|
-
Content-Type: ${mediaType}\r
|
|
137
|
-
\r
|
|
138
|
-
`
|
|
139
|
-
),
|
|
140
|
-
await toBytes(upload.data),
|
|
141
|
-
encoder.encode("\r\n")
|
|
142
|
-
];
|
|
143
|
-
}
|
|
144
|
-
function createByteMultipartEncoder(encoder) {
|
|
145
|
-
return {
|
|
146
|
-
async encode(parts) {
|
|
147
|
-
const boundary = `agents24-${Array.from(secureRandomBytes(18), (value) => value.toString(16).padStart(2, "0")).join("")}`;
|
|
148
|
-
const chunks = [];
|
|
149
|
-
for (const part of parts) chunks.push(...await encodePart(part, boundary, encoder));
|
|
150
|
-
chunks.push(encoder.encode(`--${boundary}--\r
|
|
151
|
-
`));
|
|
152
|
-
return {
|
|
153
|
-
body: concat(chunks),
|
|
154
|
-
contentType: `multipart/form-data; boundary=${boundary}`
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
|
|
160
105
|
// src/url.ts
|
|
161
106
|
function urlConstructor() {
|
|
162
107
|
const Constructor = globalThis.URL;
|
|
@@ -187,6 +132,7 @@ function absoluteUrl(baseUrl, path) {
|
|
|
187
132
|
}
|
|
188
133
|
function canonicalHtu(input) {
|
|
189
134
|
const parsed = new (urlConstructor())(input);
|
|
135
|
+
parsed.search = "";
|
|
190
136
|
parsed.hash = "";
|
|
191
137
|
return parsed.toString();
|
|
192
138
|
}
|
|
@@ -212,7 +158,7 @@ var RESERVED_REQUEST_HEADERS = /* @__PURE__ */ new Set([
|
|
|
212
158
|
"pragma",
|
|
213
159
|
"proxy-authorization"
|
|
214
160
|
]);
|
|
215
|
-
function
|
|
161
|
+
function safeToken(value, field) {
|
|
216
162
|
if (!value || /[\r\n\0]/.test(value)) {
|
|
217
163
|
throw new Agents24ClientError(`${field} is invalid.`, {
|
|
218
164
|
kind: "configuration",
|
|
@@ -230,13 +176,13 @@ function appendAdditionalHeaders(target, additional) {
|
|
|
230
176
|
code: "RESERVED_REQUEST_HEADER"
|
|
231
177
|
});
|
|
232
178
|
}
|
|
233
|
-
target[name] =
|
|
179
|
+
target[name] = safeToken(value, `Request header ${name}`);
|
|
234
180
|
}
|
|
235
181
|
}
|
|
236
182
|
function isPublicError(value) {
|
|
237
183
|
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
238
184
|
const candidate = value;
|
|
239
|
-
return typeof candidate.code === "string" && typeof candidate.
|
|
185
|
+
return candidate.schema_version === "agents24.failure.v1" && typeof candidate.failure_id === "string" && typeof candidate.code === "string" && typeof candidate.category === "string" && typeof candidate.message === "string" && typeof candidate.retryable === "boolean" && Boolean(candidate.details && typeof candidate.details === "object" && !Array.isArray(candidate.details));
|
|
240
186
|
}
|
|
241
187
|
async function responseError(response) {
|
|
242
188
|
let body;
|
|
@@ -247,11 +193,10 @@ async function responseError(response) {
|
|
|
247
193
|
}
|
|
248
194
|
if (isPublicError(body)) {
|
|
249
195
|
return new Agents24ClientError(body.message, {
|
|
250
|
-
kind: errorKindForStatus(response.status),
|
|
196
|
+
kind: body.code === "RESOURCE_POLICY_QUOTA_EXCEEDED" ? "quota" : errorKindForStatus(response.status),
|
|
251
197
|
code: body.code,
|
|
252
198
|
status: response.status,
|
|
253
|
-
|
|
254
|
-
retryable: body.retryable
|
|
199
|
+
failure: body
|
|
255
200
|
});
|
|
256
201
|
}
|
|
257
202
|
return new Agents24ClientError("The Agents24 runtime request failed.", {
|
|
@@ -288,6 +233,7 @@ var AuthenticatedHttp = class {
|
|
|
288
233
|
#clock;
|
|
289
234
|
#telemetry;
|
|
290
235
|
#nonces = /* @__PURE__ */ new Map();
|
|
236
|
+
#requestQueue = Promise.resolve();
|
|
291
237
|
constructor(options) {
|
|
292
238
|
this.#baseUrl = options.baseUrl;
|
|
293
239
|
this.#provider = options.sessionProvider;
|
|
@@ -309,6 +255,19 @@ var AuthenticatedHttp = class {
|
|
|
309
255
|
return access;
|
|
310
256
|
}
|
|
311
257
|
async request(method, path, options) {
|
|
258
|
+
let releaseQueue;
|
|
259
|
+
const previousRequest = this.#requestQueue;
|
|
260
|
+
this.#requestQueue = new Promise((resolve) => {
|
|
261
|
+
releaseQueue = resolve;
|
|
262
|
+
});
|
|
263
|
+
await previousRequest;
|
|
264
|
+
try {
|
|
265
|
+
return await this.#requestUnlocked(method, path, options);
|
|
266
|
+
} finally {
|
|
267
|
+
releaseQueue();
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
async #requestUnlocked(method, path, options) {
|
|
312
271
|
const url = absoluteUrl(this.#baseUrl, path);
|
|
313
272
|
const startedAt = this.#clock.now();
|
|
314
273
|
let access = await this.#access(options.signal);
|
|
@@ -317,7 +276,7 @@ var AuthenticatedHttp = class {
|
|
|
317
276
|
let retryCount = 0;
|
|
318
277
|
await this.#emit({ type: "request.started", operation: options.operation, method, retryCount });
|
|
319
278
|
while (true) {
|
|
320
|
-
const token =
|
|
279
|
+
const token = safeToken(access.accessToken, "Access token");
|
|
321
280
|
if (access.tokenType === "DPoP" && !access.dpopKeyProvider) {
|
|
322
281
|
throw new Agents24ClientError("A DPoP-bound session requires a DPoP key provider.", {
|
|
323
282
|
kind: "configuration",
|
|
@@ -333,7 +292,7 @@ var AuthenticatedHttp = class {
|
|
|
333
292
|
appendAdditionalHeaders(headers, options.headers);
|
|
334
293
|
if (options.body !== void 0) headers["Content-Type"] = "application/json";
|
|
335
294
|
if (options.contentType) headers["Content-Type"] = options.contentType;
|
|
336
|
-
if (options.idempotencyKey) headers["Idempotency-Key"] =
|
|
295
|
+
if (options.idempotencyKey) headers["Idempotency-Key"] = safeToken(options.idempotencyKey, "Idempotency key");
|
|
337
296
|
if (access.dpopKeyProvider) {
|
|
338
297
|
headers.DPoP = await access.dpopKeyProvider.signProof({
|
|
339
298
|
method,
|
|
@@ -370,8 +329,10 @@ var AuthenticatedHttp = class {
|
|
|
370
329
|
}
|
|
371
330
|
assertPrivateResponse(response);
|
|
372
331
|
const challengedNonce = response.headers.get("DPoP-Nonce");
|
|
332
|
+
if (challengedNonce && access.dpopKeyProvider) {
|
|
333
|
+
this.#nonces.set(access.sessionId ?? "default", safeToken(challengedNonce, "DPoP nonce"));
|
|
334
|
+
}
|
|
373
335
|
if (response.status === 401 && challengedNonce && access.dpopKeyProvider && !nonceRetried) {
|
|
374
|
-
this.#nonces.set(access.sessionId ?? "default", safeToken2(challengedNonce, "DPoP nonce"));
|
|
375
336
|
nonceRetried = true;
|
|
376
337
|
retryCount += 1;
|
|
377
338
|
continue;
|
|
@@ -413,7 +374,7 @@ async function dpopTokenRequest(input) {
|
|
|
413
374
|
"Cache-Control": "no-store",
|
|
414
375
|
Pragma: "no-cache"
|
|
415
376
|
};
|
|
416
|
-
if (input.idempotencyKey) headers["Idempotency-Key"] =
|
|
377
|
+
if (input.idempotencyKey) headers["Idempotency-Key"] = safeToken(input.idempotencyKey, "Idempotency key");
|
|
417
378
|
if (input.dpopKeyProvider && !(input.prooflessInitialRequest && attempt === 0)) {
|
|
418
379
|
headers.DPoP = await input.dpopKeyProvider.signProof({ method, url: input.url, nonce });
|
|
419
380
|
}
|
|
@@ -446,7 +407,7 @@ async function dpopTokenRequest(input) {
|
|
|
446
407
|
assertPrivateResponse(response);
|
|
447
408
|
const challenge = response.headers.get("DPoP-Nonce");
|
|
448
409
|
if (response.status === 401 && challenge && input.dpopKeyProvider && attempt === 0) {
|
|
449
|
-
nonce =
|
|
410
|
+
nonce = safeToken(challenge, "DPoP nonce");
|
|
450
411
|
continue;
|
|
451
412
|
}
|
|
452
413
|
if (input.prooflessInitialRequest && input.dpopKeyProvider && attempt === 0 && response.ok) {
|
|
@@ -463,6 +424,78 @@ async function dpopTokenRequest(input) {
|
|
|
463
424
|
});
|
|
464
425
|
}
|
|
465
426
|
|
|
427
|
+
// src/multipart.ts
|
|
428
|
+
function isBlobLike(value) {
|
|
429
|
+
return typeof value.arrayBuffer === "function";
|
|
430
|
+
}
|
|
431
|
+
async function toBytes(value) {
|
|
432
|
+
if (value instanceof Uint8Array) return value;
|
|
433
|
+
if (value instanceof ArrayBuffer) return new Uint8Array(value);
|
|
434
|
+
if (isBlobLike(value)) return new Uint8Array(await value.arrayBuffer());
|
|
435
|
+
throw new Agents24ClientError("Upload data must be bytes, an ArrayBuffer, or a compatible blob-like value.", {
|
|
436
|
+
kind: "validation",
|
|
437
|
+
code: "INVALID_UPLOAD_DATA"
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
function safeToken2(value, field) {
|
|
441
|
+
if (!value || /[\r\n\0]/.test(value)) {
|
|
442
|
+
throw new Agents24ClientError(`${field} contains invalid characters.`, {
|
|
443
|
+
kind: "validation",
|
|
444
|
+
code: "INVALID_MULTIPART_METADATA"
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
return value.replace(/["\\]/g, "_");
|
|
448
|
+
}
|
|
449
|
+
function concat(chunks) {
|
|
450
|
+
const length = chunks.reduce((total, chunk) => total + chunk.byteLength, 0);
|
|
451
|
+
const output = new Uint8Array(length);
|
|
452
|
+
let offset = 0;
|
|
453
|
+
for (const chunk of chunks) {
|
|
454
|
+
output.set(chunk, offset);
|
|
455
|
+
offset += chunk.byteLength;
|
|
456
|
+
}
|
|
457
|
+
return output;
|
|
458
|
+
}
|
|
459
|
+
async function encodePart(part, boundary, encoder) {
|
|
460
|
+
const field = safeToken2(part.field, "Multipart field");
|
|
461
|
+
if (typeof part.value === "string") {
|
|
462
|
+
return [encoder.encode(`--${boundary}\r
|
|
463
|
+
Content-Disposition: form-data; name="${field}"\r
|
|
464
|
+
\r
|
|
465
|
+
${part.value}\r
|
|
466
|
+
`)];
|
|
467
|
+
}
|
|
468
|
+
const upload = part.value;
|
|
469
|
+
const filename = safeToken2(upload.name, "Upload filename");
|
|
470
|
+
const mediaType = safeToken2(upload.mediaType, "Upload media type");
|
|
471
|
+
return [
|
|
472
|
+
encoder.encode(
|
|
473
|
+
`--${boundary}\r
|
|
474
|
+
Content-Disposition: form-data; name="${field}"; filename="${filename}"\r
|
|
475
|
+
Content-Type: ${mediaType}\r
|
|
476
|
+
\r
|
|
477
|
+
`
|
|
478
|
+
),
|
|
479
|
+
await toBytes(upload.data),
|
|
480
|
+
encoder.encode("\r\n")
|
|
481
|
+
];
|
|
482
|
+
}
|
|
483
|
+
function createByteMultipartEncoder(encoder) {
|
|
484
|
+
return {
|
|
485
|
+
async encode(parts) {
|
|
486
|
+
const boundary = `agents24-${Array.from(secureRandomBytes(18), (value) => value.toString(16).padStart(2, "0")).join("")}`;
|
|
487
|
+
const chunks = [];
|
|
488
|
+
for (const part of parts) chunks.push(...await encodePart(part, boundary, encoder));
|
|
489
|
+
chunks.push(encoder.encode(`--${boundary}--\r
|
|
490
|
+
`));
|
|
491
|
+
return {
|
|
492
|
+
body: concat(chunks),
|
|
493
|
+
contentType: `multipart/form-data; boundary=${boundary}`
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
|
|
466
499
|
// src/stream.ts
|
|
467
500
|
function detachReason(event) {
|
|
468
501
|
if (event.event !== "run.detached") return void 0;
|
|
@@ -528,7 +561,7 @@ async function consumeRuntimeStream(input) {
|
|
|
528
561
|
let runId = null;
|
|
529
562
|
let resolvedThreadId = null;
|
|
530
563
|
let detached = false;
|
|
531
|
-
let
|
|
564
|
+
let streamComplete = false;
|
|
532
565
|
let reason;
|
|
533
566
|
await consumeBody({
|
|
534
567
|
response: input.response,
|
|
@@ -537,18 +570,12 @@ async function consumeRuntimeStream(input) {
|
|
|
537
570
|
async onPayload(payload) {
|
|
538
571
|
const event = parseRuntimeSsePayload(payload);
|
|
539
572
|
if (cursor !== null && event.seq <= cursor) return;
|
|
540
|
-
if (cursor !== null && event.seq !== cursor + 1) {
|
|
541
|
-
throw new Agents24ProtocolError("invalid_envelope", "Runtime stream sequence is not contiguous.", {
|
|
542
|
-
expected: cursor + 1,
|
|
543
|
-
received: event.seq
|
|
544
|
-
});
|
|
545
|
-
}
|
|
546
573
|
cursor = event.seq;
|
|
547
574
|
runId = event.run_id;
|
|
548
575
|
resolvedThreadId = threadId(event) ?? resolvedThreadId;
|
|
549
576
|
reason = detachReason(event);
|
|
550
577
|
detached = reason !== void 0;
|
|
551
|
-
|
|
578
|
+
streamComplete = event.event === "run.completed" || event.event === "run.failed" || event.event === "run.cancelled" || event.event === "run.paused";
|
|
552
579
|
await input.onEvent(event);
|
|
553
580
|
input.onProgress?.({
|
|
554
581
|
runId,
|
|
@@ -559,7 +586,7 @@ async function consumeRuntimeStream(input) {
|
|
|
559
586
|
});
|
|
560
587
|
}
|
|
561
588
|
});
|
|
562
|
-
if (runId && !
|
|
589
|
+
if (runId && !streamComplete && !detached && !input.signal?.aborted) {
|
|
563
590
|
throw new Agents24ClientError("The runtime stream ended before a terminal or detach event.", {
|
|
564
591
|
kind: "network",
|
|
565
592
|
code: "STREAM_ENDED_BEFORE_TERMINAL",
|
|
@@ -591,387 +618,6 @@ async function consumeThreadSummaryStream(input) {
|
|
|
591
618
|
return cursor;
|
|
592
619
|
}
|
|
593
620
|
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
throw new Agents24ClientError(`${operation} returned an invalid response.`, {
|
|
598
|
-
kind: "protocol",
|
|
599
|
-
code: "INVALID_JSON_RESPONSE"
|
|
600
|
-
});
|
|
601
|
-
}
|
|
602
|
-
return value;
|
|
603
|
-
}
|
|
604
|
-
function deploymentPath(deploymentId, suffix) {
|
|
605
|
-
return `/public/client-runtime/deployments/${encodePath(deploymentId)}${suffix}`;
|
|
606
|
-
}
|
|
607
|
-
function shouldReconnect(error) {
|
|
608
|
-
return error instanceof Agents24ClientError && error.kind === "network" && error.retryable;
|
|
609
|
-
}
|
|
610
|
-
function createAgents24Client(options) {
|
|
611
|
-
if (!options.deploymentId || /[\r\n\0/]/.test(options.deploymentId)) {
|
|
612
|
-
throw new Agents24ClientError("deploymentId is invalid.", {
|
|
613
|
-
kind: "configuration",
|
|
614
|
-
code: "INVALID_DEPLOYMENT_ID"
|
|
615
|
-
});
|
|
616
|
-
}
|
|
617
|
-
if (options.transport !== void 0 && options.transport !== "auto" && options.transport !== "fetch") {
|
|
618
|
-
throw new Agents24ClientError("The requested transport is unavailable.", {
|
|
619
|
-
kind: "missing_capability",
|
|
620
|
-
code: "MISSING_TRANSPORT"
|
|
621
|
-
});
|
|
622
|
-
}
|
|
623
|
-
const baseUrl = normalizeBaseUrl(options.baseUrl);
|
|
624
|
-
const fetch = resolveFetch(options.fetch);
|
|
625
|
-
const decoder = resolveDecoderFactory(options.decoder);
|
|
626
|
-
const clock = options.clock ?? defaultClock();
|
|
627
|
-
const ids = options.ids ?? defaultIds();
|
|
628
|
-
const maxReconnectAttempts = Math.max(0, Math.min(options.maxReconnectAttempts ?? 3, 10));
|
|
629
|
-
const http = new AuthenticatedHttp({
|
|
630
|
-
baseUrl,
|
|
631
|
-
sessionProvider: options.sessionProvider,
|
|
632
|
-
fetch,
|
|
633
|
-
clock,
|
|
634
|
-
...options.telemetry ? { telemetry: options.telemetry } : {}
|
|
635
|
-
});
|
|
636
|
-
const emit = async (event) => {
|
|
637
|
-
try {
|
|
638
|
-
await options.telemetry?.emit(event);
|
|
639
|
-
} catch {
|
|
640
|
-
}
|
|
641
|
-
};
|
|
642
|
-
const attach = async (runId, cursor, headers, signal, onEvent, onProgress) => {
|
|
643
|
-
const response = await http.request(
|
|
644
|
-
"POST",
|
|
645
|
-
deploymentPath(options.deploymentId, `/runs/${encodePath(runId)}/attach`),
|
|
646
|
-
{
|
|
647
|
-
operation: "runs.attach",
|
|
648
|
-
accept: "text/event-stream",
|
|
649
|
-
body: cursor === void 0 ? {} : { cursor },
|
|
650
|
-
...headers ? { headers } : {},
|
|
651
|
-
...signal ? { signal } : {}
|
|
652
|
-
}
|
|
653
|
-
);
|
|
654
|
-
return consumeRuntimeStream({
|
|
655
|
-
response,
|
|
656
|
-
decoder: decoder(),
|
|
657
|
-
onEvent,
|
|
658
|
-
...signal ? { signal } : {},
|
|
659
|
-
...cursor === void 0 ? {} : { afterCursor: cursor },
|
|
660
|
-
...onProgress ? { onProgress } : {}
|
|
661
|
-
});
|
|
662
|
-
};
|
|
663
|
-
const reconnect = async (initial, signal, onEvent, operation, headers) => {
|
|
664
|
-
let state;
|
|
665
|
-
let attempt = 0;
|
|
666
|
-
const onProgress = (next) => {
|
|
667
|
-
if (!state) {
|
|
668
|
-
void emit({
|
|
669
|
-
type: "stream.connected",
|
|
670
|
-
operation,
|
|
671
|
-
...next.runId ? { runId: next.runId } : {},
|
|
672
|
-
...next.cursor === null ? {} : { cursor: next.cursor },
|
|
673
|
-
attempt
|
|
674
|
-
});
|
|
675
|
-
}
|
|
676
|
-
state = next;
|
|
677
|
-
};
|
|
678
|
-
while (true) {
|
|
679
|
-
try {
|
|
680
|
-
state = state?.runId ? await attach(state.runId, state.cursor ?? void 0, headers, signal, onEvent, onProgress) : await initial(onProgress);
|
|
681
|
-
} catch (error) {
|
|
682
|
-
if (signal?.aborted || !shouldReconnect(error) || attempt >= maxReconnectAttempts) throw error;
|
|
683
|
-
attempt += 1;
|
|
684
|
-
await emit({
|
|
685
|
-
type: "stream.reconnecting",
|
|
686
|
-
operation,
|
|
687
|
-
...state?.runId ? { runId: state.runId } : {},
|
|
688
|
-
...state?.cursor == null ? {} : { cursor: state.cursor },
|
|
689
|
-
attempt,
|
|
690
|
-
reason: "network"
|
|
691
|
-
});
|
|
692
|
-
continue;
|
|
693
|
-
}
|
|
694
|
-
if (!state.detached || signal?.aborted) {
|
|
695
|
-
await emit({
|
|
696
|
-
type: "stream.completed",
|
|
697
|
-
operation,
|
|
698
|
-
...state.runId ? { runId: state.runId } : {},
|
|
699
|
-
...state.cursor === null ? {} : { cursor: state.cursor },
|
|
700
|
-
attempt
|
|
701
|
-
});
|
|
702
|
-
return state;
|
|
703
|
-
}
|
|
704
|
-
await emit({
|
|
705
|
-
type: "stream.detached",
|
|
706
|
-
operation,
|
|
707
|
-
...state.runId ? { runId: state.runId } : {},
|
|
708
|
-
...state.cursor === null ? {} : { cursor: state.cursor },
|
|
709
|
-
attempt,
|
|
710
|
-
reason: state.detachReason ?? "server_detach"
|
|
711
|
-
});
|
|
712
|
-
if (attempt >= maxReconnectAttempts || state.detachReason === "revoked" || state.detachReason === "policy_changed") {
|
|
713
|
-
return state;
|
|
714
|
-
}
|
|
715
|
-
if (state.detachReason === "token_expired" && options.sessionProvider.refresh) {
|
|
716
|
-
await options.sessionProvider.refresh({ reason: "stream_detached", ...signal ? { signal } : {} });
|
|
717
|
-
}
|
|
718
|
-
attempt += 1;
|
|
719
|
-
}
|
|
720
|
-
};
|
|
721
|
-
return {
|
|
722
|
-
async bootstrap(input) {
|
|
723
|
-
let response;
|
|
724
|
-
try {
|
|
725
|
-
response = await fetch(
|
|
726
|
-
`${baseUrl}${deploymentPath(options.deploymentId, "/bootstrap")}`,
|
|
727
|
-
{
|
|
728
|
-
method: "GET",
|
|
729
|
-
headers: { Accept: "application/json", "Cache-Control": "no-store", Pragma: "no-cache" },
|
|
730
|
-
redirect: "error",
|
|
731
|
-
cache: "no-store",
|
|
732
|
-
credentials: "omit",
|
|
733
|
-
...input?.signal ? { signal: input.signal } : {}
|
|
734
|
-
}
|
|
735
|
-
);
|
|
736
|
-
} catch (cause) {
|
|
737
|
-
throw new Agents24ClientError("The Agents24 deployment bootstrap could not be reached.", {
|
|
738
|
-
kind: input?.signal?.aborted ? "aborted" : "network",
|
|
739
|
-
code: input?.signal?.aborted ? "ABORTED" : "NETWORK_ERROR",
|
|
740
|
-
retryable: !input?.signal?.aborted,
|
|
741
|
-
cause
|
|
742
|
-
});
|
|
743
|
-
}
|
|
744
|
-
if (response.redirected || response.status >= 300 && response.status < 400) {
|
|
745
|
-
throw new Agents24ClientError("Client-runtime redirects are not allowed.", {
|
|
746
|
-
kind: "network",
|
|
747
|
-
code: "REDIRECT_REJECTED",
|
|
748
|
-
status: response.status
|
|
749
|
-
});
|
|
750
|
-
}
|
|
751
|
-
if (!response.ok) throw await responseError(response);
|
|
752
|
-
return objectResult(await responseJson(response), "Bootstrap");
|
|
753
|
-
},
|
|
754
|
-
chat: {
|
|
755
|
-
async stream(input, onEvent) {
|
|
756
|
-
const initial = async (onProgress) => {
|
|
757
|
-
const response = await http.request(
|
|
758
|
-
"POST",
|
|
759
|
-
deploymentPath(options.deploymentId, "/chat/stream"),
|
|
760
|
-
{
|
|
761
|
-
operation: "chat.stream",
|
|
762
|
-
accept: "text/event-stream",
|
|
763
|
-
idempotencyKey: input.idempotencyKey,
|
|
764
|
-
...input.headers ? { headers: input.headers } : {},
|
|
765
|
-
body: {
|
|
766
|
-
input: input.input,
|
|
767
|
-
attachment_ids: [...input.attachmentIds ?? []],
|
|
768
|
-
...input.threadId ? { thread_id: input.threadId } : {},
|
|
769
|
-
...input.requestedModelId ? { requested_model_id: input.requestedModelId } : {},
|
|
770
|
-
tool_inputs: input.toolInputs ?? {},
|
|
771
|
-
metadata: input.metadata ?? {},
|
|
772
|
-
client: input.client ?? { sdk_name: "@agents24/client", sdk_version: "0.1.0" }
|
|
773
|
-
},
|
|
774
|
-
...input.signal ? { signal: input.signal } : {}
|
|
775
|
-
}
|
|
776
|
-
);
|
|
777
|
-
return consumeRuntimeStream({
|
|
778
|
-
response,
|
|
779
|
-
decoder: decoder(),
|
|
780
|
-
onEvent,
|
|
781
|
-
...input.signal ? { signal: input.signal } : {},
|
|
782
|
-
onProgress
|
|
783
|
-
});
|
|
784
|
-
};
|
|
785
|
-
return reconnect(initial, input.signal, onEvent, "chat.stream", input.headers);
|
|
786
|
-
}
|
|
787
|
-
},
|
|
788
|
-
runs: {
|
|
789
|
-
async attach(input, onEvent) {
|
|
790
|
-
const initial = (onProgress) => attach(input.runId, input.cursor, input.headers, input.signal, onEvent, onProgress);
|
|
791
|
-
return reconnect(initial, input.signal, onEvent, "runs.attach", input.headers);
|
|
792
|
-
},
|
|
793
|
-
async cancel(input) {
|
|
794
|
-
const result = await http.json(
|
|
795
|
-
"POST",
|
|
796
|
-
deploymentPath(options.deploymentId, `/runs/${encodePath(input.runId)}/cancel`),
|
|
797
|
-
{
|
|
798
|
-
operation: "runs.cancel",
|
|
799
|
-
body: {},
|
|
800
|
-
idempotencyKey: input.idempotencyKey,
|
|
801
|
-
...input.signal ? { signal: input.signal } : {}
|
|
802
|
-
}
|
|
803
|
-
);
|
|
804
|
-
return objectResult(result, "Run cancellation");
|
|
805
|
-
}
|
|
806
|
-
},
|
|
807
|
-
threads: {
|
|
808
|
-
async list(input) {
|
|
809
|
-
const path = appendQuery(deploymentPath(options.deploymentId, "/threads"), {
|
|
810
|
-
skip: input?.skip,
|
|
811
|
-
limit: input?.limit
|
|
812
|
-
});
|
|
813
|
-
const result = await http.json("GET", path, {
|
|
814
|
-
operation: "threads.list",
|
|
815
|
-
...input?.signal ? { signal: input.signal } : {}
|
|
816
|
-
});
|
|
817
|
-
return objectResult(result, "Thread listing");
|
|
818
|
-
},
|
|
819
|
-
async get(input) {
|
|
820
|
-
const path = appendQuery(
|
|
821
|
-
deploymentPath(options.deploymentId, `/threads/${encodePath(input.threadId)}`),
|
|
822
|
-
{
|
|
823
|
-
limit: input.limit,
|
|
824
|
-
before_turn_index: input.beforeTurnIndex,
|
|
825
|
-
include_run_events: input.includeRunEvents
|
|
826
|
-
}
|
|
827
|
-
);
|
|
828
|
-
const result = await http.json("GET", path, {
|
|
829
|
-
operation: "threads.get",
|
|
830
|
-
...input.signal ? { signal: input.signal } : {}
|
|
831
|
-
});
|
|
832
|
-
return objectResult(result, "Thread detail");
|
|
833
|
-
},
|
|
834
|
-
async events(input, onEvent) {
|
|
835
|
-
let cursor = input.cursor;
|
|
836
|
-
let attempts = 0;
|
|
837
|
-
while (!input.signal?.aborted) {
|
|
838
|
-
try {
|
|
839
|
-
const path = appendQuery(deploymentPath(options.deploymentId, "/threads/events"), { cursor });
|
|
840
|
-
const response = await http.request("GET", path, {
|
|
841
|
-
operation: "threads.events",
|
|
842
|
-
accept: "text/event-stream",
|
|
843
|
-
...input.signal ? { signal: input.signal } : {}
|
|
844
|
-
});
|
|
845
|
-
cursor = await consumeThreadSummaryStream({
|
|
846
|
-
response,
|
|
847
|
-
decoder: decoder(),
|
|
848
|
-
onEvent,
|
|
849
|
-
...input.signal ? { signal: input.signal } : {},
|
|
850
|
-
...cursor === void 0 ? {} : { afterCursor: cursor },
|
|
851
|
-
onCursor(next) {
|
|
852
|
-
cursor = next;
|
|
853
|
-
}
|
|
854
|
-
}) ?? void 0;
|
|
855
|
-
return;
|
|
856
|
-
} catch (error) {
|
|
857
|
-
if (input.signal?.aborted || !shouldReconnect(error) || attempts >= maxReconnectAttempts) throw error;
|
|
858
|
-
attempts += 1;
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
},
|
|
862
|
-
async delete(input) {
|
|
863
|
-
const result = await http.json(
|
|
864
|
-
"DELETE",
|
|
865
|
-
deploymentPath(options.deploymentId, `/threads/${encodePath(input.threadId)}`),
|
|
866
|
-
{
|
|
867
|
-
operation: "threads.delete",
|
|
868
|
-
idempotencyKey: input.idempotencyKey,
|
|
869
|
-
...input.signal ? { signal: input.signal } : {}
|
|
870
|
-
}
|
|
871
|
-
);
|
|
872
|
-
return objectResult(result, "Thread deletion");
|
|
873
|
-
}
|
|
874
|
-
},
|
|
875
|
-
attachments: {
|
|
876
|
-
async upload(input) {
|
|
877
|
-
const multipart = options.multipart ?? createByteMultipartEncoder(resolveEncoder(options.encoder));
|
|
878
|
-
const encoded = await multipart.encode([
|
|
879
|
-
...input.threadId ? [{ field: "thread_id", value: input.threadId }] : [],
|
|
880
|
-
{ field: "files", value: input.upload }
|
|
881
|
-
]);
|
|
882
|
-
const result = await http.json(
|
|
883
|
-
"POST",
|
|
884
|
-
deploymentPath(options.deploymentId, "/attachments/upload"),
|
|
885
|
-
{
|
|
886
|
-
operation: "attachments.upload",
|
|
887
|
-
rawBody: encoded.body,
|
|
888
|
-
contentType: encoded.contentType,
|
|
889
|
-
idempotencyKey: input.idempotencyKey,
|
|
890
|
-
...input.signal ? { signal: input.signal } : {}
|
|
891
|
-
}
|
|
892
|
-
);
|
|
893
|
-
const body = objectResult(result, "Attachment upload");
|
|
894
|
-
const item = Array.isArray(body.items) ? body.items[0] : body;
|
|
895
|
-
return objectResult(item, "Attachment upload");
|
|
896
|
-
}
|
|
897
|
-
},
|
|
898
|
-
hitl: {
|
|
899
|
-
async resume(input) {
|
|
900
|
-
const result = await http.json(
|
|
901
|
-
"POST",
|
|
902
|
-
deploymentPath(
|
|
903
|
-
options.deploymentId,
|
|
904
|
-
`/runs/${encodePath(input.runId)}/hitl/${encodePath(input.interruptId)}/resume`
|
|
905
|
-
),
|
|
906
|
-
{
|
|
907
|
-
operation: "hitl.resume",
|
|
908
|
-
idempotencyKey: input.idempotencyKey,
|
|
909
|
-
body: {
|
|
910
|
-
schema_version: "agents24.hitl.resume.v2",
|
|
911
|
-
interrupt_id: input.interruptId,
|
|
912
|
-
action: input.action,
|
|
913
|
-
...input.comment ? { comment: input.comment } : {}
|
|
914
|
-
},
|
|
915
|
-
...input.signal ? { signal: input.signal } : {}
|
|
916
|
-
}
|
|
917
|
-
);
|
|
918
|
-
return objectResult(result, "HITL resume");
|
|
919
|
-
}
|
|
920
|
-
},
|
|
921
|
-
mcp: {
|
|
922
|
-
async startAuthorization(input) {
|
|
923
|
-
const result = await http.json(
|
|
924
|
-
"POST",
|
|
925
|
-
deploymentPath(
|
|
926
|
-
options.deploymentId,
|
|
927
|
-
`/runs/${encodePath(input.runId)}/mcp/servers/${encodePath(input.serverId)}/auth/start`
|
|
928
|
-
),
|
|
929
|
-
{
|
|
930
|
-
operation: "mcp.startAuthorization",
|
|
931
|
-
idempotencyKey: input.idempotencyKey,
|
|
932
|
-
body: {
|
|
933
|
-
interrupt_id: input.interruptId,
|
|
934
|
-
redirect_uri: input.redirectUri,
|
|
935
|
-
popup_nonce: input.popupNonce,
|
|
936
|
-
code_challenge: input.codeChallenge,
|
|
937
|
-
code_challenge_method: "S256"
|
|
938
|
-
},
|
|
939
|
-
...input.signal ? { signal: input.signal } : {}
|
|
940
|
-
}
|
|
941
|
-
);
|
|
942
|
-
return objectResult(result, "MCP authorization start");
|
|
943
|
-
},
|
|
944
|
-
async redeemCallback(input) {
|
|
945
|
-
const result = await http.json(
|
|
946
|
-
"POST",
|
|
947
|
-
deploymentPath(options.deploymentId, "/mcp/callback/redeem"),
|
|
948
|
-
{
|
|
949
|
-
operation: "mcp.redeemCallback",
|
|
950
|
-
idempotencyKey: input.idempotencyKey,
|
|
951
|
-
body: { code: input.code, code_verifier: input.codeVerifier },
|
|
952
|
-
...input.signal ? { signal: input.signal } : {}
|
|
953
|
-
}
|
|
954
|
-
);
|
|
955
|
-
return objectResult(result, "MCP callback redemption");
|
|
956
|
-
}
|
|
957
|
-
},
|
|
958
|
-
sessions: {
|
|
959
|
-
async revoke(input) {
|
|
960
|
-
if (!options.sessionProvider.revoke) {
|
|
961
|
-
throw new Agents24ClientError("The configured session provider cannot revoke sessions.", {
|
|
962
|
-
kind: "missing_capability",
|
|
963
|
-
code: "SESSION_REVOKE_UNAVAILABLE"
|
|
964
|
-
});
|
|
965
|
-
}
|
|
966
|
-
await options.sessionProvider.revoke({
|
|
967
|
-
idempotencyKey: input?.idempotencyKey ?? ids.createId(),
|
|
968
|
-
...input?.signal ? { signal: input.signal } : {}
|
|
969
|
-
});
|
|
970
|
-
}
|
|
971
|
-
}
|
|
972
|
-
};
|
|
973
|
-
}
|
|
974
|
-
|
|
975
|
-
export { Agents24ClientError, AuthenticatedHttp, absoluteUrl, canonicalHtu, createAgents24Client, createByteMultipartEncoder, defaultClock, defaultIds, dpopTokenRequest, encodePath, missingCapability, normalizeBaseUrl, resolveEncoder, resolveFetch, responseError, responseJson };
|
|
976
|
-
//# sourceMappingURL=chunk-45ITVMX3.js.map
|
|
977
|
-
//# sourceMappingURL=chunk-45ITVMX3.js.map
|
|
621
|
+
export { Agents24ClientError, AuthenticatedHttp, absoluteUrl, appendQuery, canonicalHtu, consumeRuntimeStream, consumeThreadSummaryStream, createByteMultipartEncoder, defaultClock, defaultIds, dpopTokenRequest, encodePath, missingCapability, normalizeBaseUrl, resolveDecoderFactory, resolveEncoder, resolveFetch, responseError, responseJson };
|
|
622
|
+
//# sourceMappingURL=chunk-GXISGBVW.js.map
|
|
623
|
+
//# sourceMappingURL=chunk-GXISGBVW.js.map
|