@m8tes/sdk 0.1.0-alpha.1 → 0.1.0-alpha.3
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/CHANGELOG.md +202 -1
- package/README.md +57 -3
- package/dist/{chunk-UFQQNUFE.js → chunk-CURNMC4F.js} +26 -3
- package/dist/chunk-CURNMC4F.js.map +1 -0
- package/dist/index.cjs +748 -117
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +866 -80
- package/dist/index.d.ts +866 -80
- package/dist/index.js +716 -117
- package/dist/index.js.map +1 -1
- package/dist/protocol/index.cjs +24 -0
- package/dist/protocol/index.cjs.map +1 -1
- package/dist/protocol/index.d.cts +40 -1
- package/dist/protocol/index.d.ts +40 -1
- package/dist/protocol/index.js +1 -1
- package/package.json +4 -4
- package/dist/chunk-UFQQNUFE.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createNormalizer, createSseDecoder, initialConversationState, accumulate, RunFailedError, APIError, parseRetryAfter, parseErrorEnvelope, errorClassForStatus } from './chunk-
|
|
2
|
-
export { APIError, AuthenticationError, BillingError, ConflictError, M8tesApiError, NotFoundError, PROTOCOL_VERSION, PermissionDeniedError, RateLimitError, RunFailedError, RunNotStreamingError, TERMINAL_EVENT_TYPES, ValidationError, accumulate, createAccumulator, createNormalizer, createSseDecoder, errorClassForStatus, errorFromResponse, initialConversationState, isTerminalEvent, parseErrorEnvelope, parseRetryAfter, parseSse, splitConcatenatedJson } from './chunk-
|
|
1
|
+
import { createNormalizer, createSseDecoder, initialConversationState, accumulate, RunFailedError, APIError, parseRetryAfter, ConflictError, NotFoundError, AuthenticationError, PermissionDeniedError, ValidationError, seg, parseErrorEnvelope, errorClassForStatus } from './chunk-CURNMC4F.js';
|
|
2
|
+
export { APIError, AuthenticationError, BillingError, ConflictError, M8tesApiError, NotFoundError, PROTOCOL_VERSION, PermissionDeniedError, RateLimitError, RunFailedError, RunNotStreamingError, TERMINAL_EVENT_TYPES, ValidationError, accumulate, createAccumulator, createNormalizer, createSseDecoder, errorClassForStatus, errorFromResponse, initialConversationState, isTerminalEvent, parseErrorEnvelope, parseRetryAfter, parseSse, seg, splitConcatenatedJson } from './chunk-CURNMC4F.js';
|
|
3
3
|
import { createHmac, timingSafeEqual } from 'crypto';
|
|
4
4
|
|
|
5
5
|
// src/http.ts
|
|
@@ -8,6 +8,23 @@ var MAX_ATTEMPTS = 3;
|
|
|
8
8
|
var INITIAL_BACKOFF_MS = 500;
|
|
9
9
|
var RETRYABLE_STATUS = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
10
10
|
var IDEMPOTENT_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD", "PUT", "DELETE", "OPTIONS"]);
|
|
11
|
+
var IDEMPOTENCY_HEADER = "idempotency-key";
|
|
12
|
+
var REPLAY_HEADER = "idempotent-replay";
|
|
13
|
+
var IDEMPOTENT_POST_PATHS = [
|
|
14
|
+
/^\/runs\/?$/,
|
|
15
|
+
/^\/runs\/with-files\/?$/,
|
|
16
|
+
/^\/runs\/\d+\/reply\/?$/,
|
|
17
|
+
/^\/runs\/\d+\/reply\/with-files\/?$/,
|
|
18
|
+
/^\/tasks\/\d+\/runs\/?$/
|
|
19
|
+
];
|
|
20
|
+
function isIdempotentRoute(path) {
|
|
21
|
+
const clean = path.split("?")[0] ?? "";
|
|
22
|
+
return IDEMPOTENT_POST_PATHS.some((re) => re.test(clean));
|
|
23
|
+
}
|
|
24
|
+
function isRetryable(method, path, headers) {
|
|
25
|
+
if (IDEMPOTENT_METHODS.has(method.toUpperCase())) return true;
|
|
26
|
+
return IDEMPOTENCY_HEADER in headers && isIdempotentRoute(path);
|
|
27
|
+
}
|
|
11
28
|
function backoff(ms, signal) {
|
|
12
29
|
if (signal?.aborted) return Promise.resolve();
|
|
13
30
|
return new Promise((resolve) => {
|
|
@@ -68,14 +85,22 @@ function createHttp(options = {}) {
|
|
|
68
85
|
const message = diagnose(res, text, body, url) ?? (body ? parsed.message : text || parsed.message);
|
|
69
86
|
return new (errorClassForStatus(res.status, errOpts))(message, parsed.fields);
|
|
70
87
|
}
|
|
88
|
+
function mergeHeaders(...sources) {
|
|
89
|
+
const out = {};
|
|
90
|
+
for (const src of sources) {
|
|
91
|
+
for (const [k, v] of Object.entries(src ?? {})) out[k.toLowerCase()] = v;
|
|
92
|
+
}
|
|
93
|
+
return out;
|
|
94
|
+
}
|
|
71
95
|
async function attempt(method, url, opts) {
|
|
72
|
-
const headers = {
|
|
73
|
-
authorization: `Bearer ${apiKey}
|
|
74
|
-
|
|
75
|
-
...opts.headers
|
|
76
|
-
};
|
|
96
|
+
const headers = mergeHeaders(options.headers, opts.headers, {
|
|
97
|
+
authorization: `Bearer ${apiKey}`
|
|
98
|
+
});
|
|
77
99
|
const init = { method, headers };
|
|
78
|
-
if (opts.
|
|
100
|
+
if (opts.form !== void 0) {
|
|
101
|
+
delete headers["content-type"];
|
|
102
|
+
init.body = opts.form;
|
|
103
|
+
} else if (opts.body !== void 0) {
|
|
79
104
|
headers["content-type"] = "application/json";
|
|
80
105
|
init.body = JSON.stringify(opts.body);
|
|
81
106
|
}
|
|
@@ -85,7 +110,7 @@ function createHttp(options = {}) {
|
|
|
85
110
|
}
|
|
86
111
|
async function send(method, path, opts, errOpts = {}) {
|
|
87
112
|
const url = `${baseUrl}${path}${opts.query ?? ""}`;
|
|
88
|
-
const idempotent =
|
|
113
|
+
const idempotent = isRetryable(method, path, mergeHeaders(options.headers, opts.headers));
|
|
89
114
|
let lastNetworkError;
|
|
90
115
|
for (let i = 0; i < MAX_ATTEMPTS; i++) {
|
|
91
116
|
const isLast = i === MAX_ATTEMPTS - 1;
|
|
@@ -133,6 +158,11 @@ function createHttp(options = {}) {
|
|
|
133
158
|
},
|
|
134
159
|
async *stream(method, path, opts = {}) {
|
|
135
160
|
const res = await send(method, path, opts, { conflictIsNotStreaming: true });
|
|
161
|
+
if (opts.onReplay && res.headers.get(REPLAY_HEADER)) {
|
|
162
|
+
const run = await res.json();
|
|
163
|
+
yield* opts.onReplay(run);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
136
166
|
if (!res.body) return;
|
|
137
167
|
const normalizer = opts.normalizer ?? createNormalizer();
|
|
138
168
|
const decoder = createSseDecoder({ onMalformed: options.onMalformed });
|
|
@@ -165,12 +195,14 @@ function createHttp(options = {}) {
|
|
|
165
195
|
var Page = class {
|
|
166
196
|
data;
|
|
167
197
|
hasMore;
|
|
198
|
+
nextStartingAfter;
|
|
168
199
|
/** Fetches the next page given a cursor. Absent on a terminal page. */
|
|
169
200
|
fetchNext;
|
|
170
|
-
constructor(data, hasMore, fetchNext) {
|
|
201
|
+
constructor(data, hasMore, fetchNext, nextStartingAfter) {
|
|
171
202
|
this.data = data;
|
|
172
203
|
this.hasMore = hasMore;
|
|
173
204
|
this.fetchNext = fetchNext;
|
|
205
|
+
this.nextStartingAfter = nextStartingAfter ?? null;
|
|
174
206
|
}
|
|
175
207
|
/**
|
|
176
208
|
* Auto-paging: yields every item across every page.
|
|
@@ -188,7 +220,10 @@ var Page = class {
|
|
|
188
220
|
yield* page.data;
|
|
189
221
|
const last = page.data.at(-1);
|
|
190
222
|
if (!page.hasMore || !last || !page.fetchNext) return;
|
|
191
|
-
|
|
223
|
+
let cursor = page.nextStartingAfter === null || page.nextStartingAfter === void 0 ? void 0 : page.nextStartingAfter;
|
|
224
|
+
if (cursor === void 0) {
|
|
225
|
+
cursor = typeof last.id === "number" || typeof last.id === "string" ? last.id : typeof last.name === "string" ? last.name : void 0;
|
|
226
|
+
}
|
|
192
227
|
if (cursor === void 0 || seen.has(cursor)) return;
|
|
193
228
|
seen.add(cursor);
|
|
194
229
|
page = await page.fetchNext(cursor);
|
|
@@ -240,74 +275,545 @@ function createAgentsResource(http) {
|
|
|
240
275
|
return new Page(
|
|
241
276
|
res?.data ?? [],
|
|
242
277
|
res?.has_more ?? false,
|
|
243
|
-
(starting_after) => fetchPage({ ...p, starting_after })
|
|
278
|
+
(starting_after) => fetchPage({ ...p, starting_after }),
|
|
279
|
+
res?.next_starting_after
|
|
244
280
|
);
|
|
245
281
|
};
|
|
246
282
|
return fetchPage({ ...params });
|
|
247
283
|
},
|
|
248
284
|
get(agentId, params = {}) {
|
|
249
|
-
return http.request("GET", `/agents/${agentId}`, { query: toQuery(params) });
|
|
285
|
+
return http.request("GET", `/agents/${seg(agentId)}`, { query: toQuery(params) });
|
|
250
286
|
},
|
|
251
287
|
update(agentId, params) {
|
|
252
288
|
const { user_id, ...patch } = params;
|
|
253
|
-
return http.request("PATCH", `/agents/${agentId}`, {
|
|
289
|
+
return http.request("PATCH", `/agents/${seg(agentId)}`, {
|
|
254
290
|
body: toBody(patch),
|
|
255
291
|
query: toQuery({ user_id })
|
|
256
292
|
});
|
|
257
293
|
},
|
|
258
294
|
async delete(agentId, params = {}) {
|
|
259
|
-
await http.request("DELETE", `/agents/${agentId}`, { query: toQuery(params) });
|
|
295
|
+
await http.request("DELETE", `/agents/${seg(agentId)}`, { query: toQuery(params) });
|
|
260
296
|
},
|
|
261
|
-
enableWebhook(agentId) {
|
|
262
|
-
return http.request("POST", `/agents/${agentId}/webhook`, {
|
|
297
|
+
enableWebhook(agentId, params = {}) {
|
|
298
|
+
return http.request("POST", `/agents/${seg(agentId)}/webhook`, {
|
|
299
|
+
body: {},
|
|
300
|
+
query: toQuery(params)
|
|
301
|
+
});
|
|
263
302
|
},
|
|
264
|
-
async disableWebhook(agentId) {
|
|
265
|
-
await http.request("DELETE", `/agents/${agentId}/webhook
|
|
303
|
+
async disableWebhook(agentId, params = {}) {
|
|
304
|
+
await http.request("DELETE", `/agents/${seg(agentId)}/webhook`, { query: toQuery(params) });
|
|
266
305
|
},
|
|
267
|
-
enableEmailInbox(agentId) {
|
|
268
|
-
return http.request("POST", `/agents/${agentId}/email-inbox`, {
|
|
306
|
+
enableEmailInbox(agentId, params = {}) {
|
|
307
|
+
return http.request("POST", `/agents/${seg(agentId)}/email-inbox`, {
|
|
308
|
+
body: {},
|
|
309
|
+
query: toQuery(params)
|
|
310
|
+
});
|
|
269
311
|
},
|
|
270
|
-
async disableEmailInbox(agentId) {
|
|
271
|
-
await http.request("DELETE", `/agents/${agentId}/email-inbox
|
|
312
|
+
async disableEmailInbox(agentId, params = {}) {
|
|
313
|
+
await http.request("DELETE", `/agents/${seg(agentId)}/email-inbox`, { query: toQuery(params) });
|
|
272
314
|
}
|
|
273
315
|
};
|
|
274
316
|
}
|
|
275
317
|
|
|
276
318
|
// src/resources/apps.ts
|
|
277
319
|
function createAppsResource(http) {
|
|
278
|
-
const
|
|
320
|
+
const list = async (params = {}) => {
|
|
321
|
+
const res = await http.request("GET", "/apps/", {
|
|
322
|
+
query: toQuery({ user_id: params.user_id })
|
|
323
|
+
});
|
|
324
|
+
return new Page(res?.data ?? [], res?.has_more ?? false, void 0, res?.next_starting_after);
|
|
325
|
+
};
|
|
279
326
|
return {
|
|
280
|
-
|
|
281
|
-
const res = await http.request("GET", "/apps/", {
|
|
282
|
-
query: toQuery({ user_id: params.user_id })
|
|
283
|
-
});
|
|
284
|
-
return new Page(res?.data ?? [], res?.has_more ?? false);
|
|
285
|
-
},
|
|
327
|
+
list,
|
|
286
328
|
async isConnected(appName, params = {}) {
|
|
287
|
-
const { data } = await
|
|
329
|
+
const { data } = await list(params);
|
|
288
330
|
return data.find((a) => a.name === appName)?.connected ?? false;
|
|
289
331
|
},
|
|
290
332
|
connectOauth(appName, params) {
|
|
291
|
-
return http.request("POST", `/apps/${
|
|
333
|
+
return http.request("POST", `/apps/${seg(appName)}/connect`, {
|
|
292
334
|
body: toBody({ ...params })
|
|
293
335
|
});
|
|
294
336
|
},
|
|
295
337
|
connectApiKey(appName, params) {
|
|
296
|
-
return http.request("POST", `/apps/${
|
|
338
|
+
return http.request("POST", `/apps/${seg(appName)}/connect/api-key`, {
|
|
297
339
|
body: toBody({ ...params })
|
|
298
340
|
});
|
|
299
341
|
},
|
|
300
342
|
connectComplete(appName, params) {
|
|
301
|
-
return http.request("POST", `/apps/${
|
|
343
|
+
return http.request("POST", `/apps/${seg(appName)}/connect/complete`, {
|
|
302
344
|
body: toBody({ ...params })
|
|
303
345
|
});
|
|
304
346
|
},
|
|
305
347
|
async disconnect(appName, params = {}) {
|
|
306
|
-
await http.request("DELETE", `/apps/${
|
|
348
|
+
await http.request("DELETE", `/apps/${seg(appName)}/connections`, { query: toQuery(params) });
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// src/resources/account.ts
|
|
354
|
+
function createAccountResource(http) {
|
|
355
|
+
return {
|
|
356
|
+
export() {
|
|
357
|
+
return http.request("GET", "/account/export");
|
|
358
|
+
},
|
|
359
|
+
delete() {
|
|
360
|
+
return http.request("DELETE", "/account");
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// src/resources/users.ts
|
|
366
|
+
function pager(http, path) {
|
|
367
|
+
const fetchPage = async (p) => {
|
|
368
|
+
const res = await http.request("GET", path, {
|
|
369
|
+
query: toQuery(p)
|
|
370
|
+
});
|
|
371
|
+
return new Page(
|
|
372
|
+
res?.data ?? [],
|
|
373
|
+
res?.has_more ?? false,
|
|
374
|
+
(starting_after) => fetchPage({ ...p, starting_after }),
|
|
375
|
+
res?.next_starting_after
|
|
376
|
+
);
|
|
377
|
+
};
|
|
378
|
+
return fetchPage;
|
|
379
|
+
}
|
|
380
|
+
function createUsersResource(http) {
|
|
381
|
+
return {
|
|
382
|
+
create(params) {
|
|
383
|
+
return http.request("POST", "/users/", { body: toBody({ ...params }) });
|
|
384
|
+
},
|
|
385
|
+
list(params = {}) {
|
|
386
|
+
return pager(http, "/users/")({ ...params });
|
|
387
|
+
},
|
|
388
|
+
get(userId) {
|
|
389
|
+
return http.request("GET", `/users/${seg(userId)}`);
|
|
390
|
+
},
|
|
391
|
+
update(userId, params) {
|
|
392
|
+
return http.request("PATCH", `/users/${seg(userId)}`, {
|
|
393
|
+
body: toBody({ ...params })
|
|
394
|
+
});
|
|
395
|
+
},
|
|
396
|
+
async delete(userId) {
|
|
397
|
+
await http.request("DELETE", `/users/${seg(userId)}`);
|
|
398
|
+
},
|
|
399
|
+
usage(params = {}) {
|
|
400
|
+
return pager(http, "/usage/end-users")({ ...params });
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// src/resources/billing.ts
|
|
406
|
+
function createBillingResource(http) {
|
|
407
|
+
return {
|
|
408
|
+
usage() {
|
|
409
|
+
return http.request("GET", "/usage/");
|
|
410
|
+
},
|
|
411
|
+
usageTimeseries(params = {}) {
|
|
412
|
+
const { agent_id, teammate_id, ...rest } = params;
|
|
413
|
+
const query = toQuery(
|
|
414
|
+
toBody({ ...rest, teammate_id: resolveAgentId(teammate_id, agent_id) })
|
|
415
|
+
);
|
|
416
|
+
return http.request("GET", "/usage/timeseries", { query });
|
|
417
|
+
},
|
|
418
|
+
receipts(params = {}) {
|
|
419
|
+
return pager(http, "/billing/receipts")({ ...params });
|
|
420
|
+
},
|
|
421
|
+
plans() {
|
|
422
|
+
return http.request("GET", "/billing/plans");
|
|
423
|
+
},
|
|
424
|
+
setOverage(params) {
|
|
425
|
+
return http.request("PATCH", "/billing/overage", { body: toBody({ ...params }) });
|
|
426
|
+
},
|
|
427
|
+
balance() {
|
|
428
|
+
return http.request("GET", "/billing/balance");
|
|
429
|
+
},
|
|
430
|
+
async topup(params) {
|
|
431
|
+
const res = await http.request("POST", "/billing/topup", {
|
|
432
|
+
body: toBody({ ...params })
|
|
433
|
+
});
|
|
434
|
+
return res.checkout_url;
|
|
435
|
+
},
|
|
436
|
+
setAutoReload(params) {
|
|
437
|
+
return http.request("PATCH", "/billing/auto-reload", {
|
|
438
|
+
body: toBody({ ...params })
|
|
439
|
+
});
|
|
440
|
+
},
|
|
441
|
+
setAlertThreshold(params) {
|
|
442
|
+
return http.request("PATCH", "/billing/alert-settings", {
|
|
443
|
+
body: toBody({ ...params })
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// src/resources/memories.ts
|
|
450
|
+
function createMemoriesResource(http) {
|
|
451
|
+
return {
|
|
452
|
+
create(params) {
|
|
453
|
+
return http.request("POST", "/memories/", { body: toBody({ ...params }) });
|
|
454
|
+
},
|
|
455
|
+
list(params = {}) {
|
|
456
|
+
return pager(http, "/memories/")({ ...params });
|
|
457
|
+
},
|
|
458
|
+
update(memoryId, { user_id, content }) {
|
|
459
|
+
return http.request("PATCH", `/memories/${seg(memoryId)}`, {
|
|
460
|
+
query: toQuery({ user_id }),
|
|
461
|
+
body: toBody({ content })
|
|
462
|
+
});
|
|
463
|
+
},
|
|
464
|
+
async delete(memoryId, params = {}) {
|
|
465
|
+
await http.request("DELETE", `/memories/${seg(memoryId)}`, {
|
|
466
|
+
query: toQuery({ user_id: params.user_id })
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// src/resources/models.ts
|
|
473
|
+
function createModelsResource(http) {
|
|
474
|
+
return {
|
|
475
|
+
async list() {
|
|
476
|
+
const res = await http.request("GET", "/models/");
|
|
477
|
+
return new Page(res?.data ?? [], res?.has_more ?? false, void 0, res?.next_starting_after);
|
|
307
478
|
}
|
|
308
479
|
};
|
|
309
480
|
}
|
|
310
481
|
|
|
482
|
+
// src/resources/model-connections.ts
|
|
483
|
+
function createModelConnectionsResource(http) {
|
|
484
|
+
return {
|
|
485
|
+
async list() {
|
|
486
|
+
const res = await http.request("GET", "/model-connections/");
|
|
487
|
+
return res?.data ?? [];
|
|
488
|
+
},
|
|
489
|
+
authorize(provider) {
|
|
490
|
+
return http.request(
|
|
491
|
+
"POST",
|
|
492
|
+
`/model-connections/${seg(provider)}/authorizations`
|
|
493
|
+
);
|
|
494
|
+
},
|
|
495
|
+
authorizationStatus(provider, state) {
|
|
496
|
+
return http.request(
|
|
497
|
+
"GET",
|
|
498
|
+
`/model-connections/${seg(provider)}/authorizations/${seg(state)}`
|
|
499
|
+
);
|
|
500
|
+
},
|
|
501
|
+
completeAuthorization(provider, state, params) {
|
|
502
|
+
return http.request(
|
|
503
|
+
"POST",
|
|
504
|
+
`/model-connections/${seg(provider)}/authorizations/${seg(state)}`,
|
|
505
|
+
{ body: { code: params.code } }
|
|
506
|
+
);
|
|
507
|
+
},
|
|
508
|
+
async cancelAuthorization(provider, state) {
|
|
509
|
+
await http.request("DELETE", `/model-connections/${seg(provider)}/authorizations/${seg(state)}`);
|
|
510
|
+
},
|
|
511
|
+
disconnect(provider) {
|
|
512
|
+
return http.request("DELETE", `/model-connections/${seg(provider)}`);
|
|
513
|
+
}
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// src/resources/permissions.ts
|
|
518
|
+
function createPermissionsResource(http) {
|
|
519
|
+
return {
|
|
520
|
+
create(params) {
|
|
521
|
+
return http.request("POST", "/permissions/", {
|
|
522
|
+
body: toBody({ ...params })
|
|
523
|
+
});
|
|
524
|
+
},
|
|
525
|
+
list(params) {
|
|
526
|
+
return pager(http, "/permissions/")({ ...params });
|
|
527
|
+
},
|
|
528
|
+
async delete(permissionId, params) {
|
|
529
|
+
await http.request("DELETE", `/permissions/${seg(permissionId)}`, {
|
|
530
|
+
query: toQuery({ user_id: params.user_id })
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
// src/mime.ts
|
|
537
|
+
var EXTENSION_TYPES = Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
538
|
+
// Images (the agent can actually see these via its Read tool)
|
|
539
|
+
jpg: "image/jpeg",
|
|
540
|
+
jpeg: "image/jpeg",
|
|
541
|
+
png: "image/png",
|
|
542
|
+
gif: "image/gif",
|
|
543
|
+
webp: "image/webp",
|
|
544
|
+
// Documents
|
|
545
|
+
pdf: "application/pdf",
|
|
546
|
+
txt: "text/plain",
|
|
547
|
+
md: "text/markdown",
|
|
548
|
+
markdown: "text/markdown",
|
|
549
|
+
html: "text/html",
|
|
550
|
+
htm: "text/html",
|
|
551
|
+
// Code
|
|
552
|
+
py: "text/x-python",
|
|
553
|
+
js: "application/javascript",
|
|
554
|
+
mjs: "application/javascript",
|
|
555
|
+
cjs: "application/javascript",
|
|
556
|
+
json: "application/json",
|
|
557
|
+
ts: "text/typescript",
|
|
558
|
+
tsx: "text/typescript",
|
|
559
|
+
css: "text/css",
|
|
560
|
+
c: "text/x-c",
|
|
561
|
+
h: "text/x-c",
|
|
562
|
+
java: "text/x-java-source",
|
|
563
|
+
go: "text/x-go",
|
|
564
|
+
sql: "application/sql",
|
|
565
|
+
// Data / config
|
|
566
|
+
csv: "text/csv",
|
|
567
|
+
tsv: "text/csv",
|
|
568
|
+
xml: "application/xml",
|
|
569
|
+
yaml: "text/yaml",
|
|
570
|
+
yml: "text/yaml",
|
|
571
|
+
// Archives
|
|
572
|
+
zip: "application/zip",
|
|
573
|
+
gz: "application/gzip",
|
|
574
|
+
tgz: "application/gzip",
|
|
575
|
+
tar: "application/x-tar",
|
|
576
|
+
// Office
|
|
577
|
+
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
578
|
+
xls: "application/vnd.ms-excel",
|
|
579
|
+
docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
580
|
+
pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
581
|
+
ppt: "application/vnd.ms-powerpoint"
|
|
582
|
+
});
|
|
583
|
+
var UPLOADABLE_EXTENSIONS = Object.keys(EXTENSION_TYPES);
|
|
584
|
+
function mimeTypeForFilename(name) {
|
|
585
|
+
const ext = name.includes(".") ? name.slice(name.lastIndexOf(".") + 1).toLowerCase() : "";
|
|
586
|
+
return EXTENSION_TYPES[ext];
|
|
587
|
+
}
|
|
588
|
+
function unknownTypeMessage(name) {
|
|
589
|
+
return `@m8tes/sdk: cannot infer a content type for "${name}", and the upload endpoint rejects files whose type it does not recognise. Pass it explicitly \u2014 { name: "${name}", data, type: "text/plain" } \u2014 or rename the file with a known extension (${UPLOADABLE_EXTENSIONS.slice(0, 12).join(", ")}, ...).`;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
// src/polling.ts
|
|
593
|
+
function isPermanent(err) {
|
|
594
|
+
return err instanceof AuthenticationError || err instanceof PermissionDeniedError || err instanceof NotFoundError || err instanceof ValidationError;
|
|
595
|
+
}
|
|
596
|
+
var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled", "closed"]);
|
|
597
|
+
var BENIGN_GATE_REFUSAL_CODES = /* @__PURE__ */ new Set(["gate_cancelled", "run_not_active"]);
|
|
598
|
+
var AUTO_CONTINUED_MESSAGE = "auto_continued";
|
|
599
|
+
function isBenignGateRefusal(err) {
|
|
600
|
+
if (err.errorCode !== void 0) return BENIGN_GATE_REFUSAL_CODES.has(err.errorCode);
|
|
601
|
+
return err instanceof ConflictError && err.message === AUTO_CONTINUED_MESSAGE;
|
|
602
|
+
}
|
|
603
|
+
var RunTimeoutError = class extends Error {
|
|
604
|
+
runId;
|
|
605
|
+
timeoutSeconds;
|
|
606
|
+
/** The last error seen while polling, if any. Without it a timeout hides the
|
|
607
|
+
* transient failure that actually caused it. */
|
|
608
|
+
cause;
|
|
609
|
+
/** The run's status when the deadline hit, when one was ever observed. */
|
|
610
|
+
lastStatus;
|
|
611
|
+
constructor(runId, timeoutSeconds, cause, lastStatus) {
|
|
612
|
+
const advice = lastStatus === "awaiting_approval" ? `The run is waiting for a human and will never finish on its own: use runs.wait() with onApproval/onQuestion, or resolve it yourself via runs.permissions(${runId}).` : `Raise the timeout, or stream the run instead of polling it.`;
|
|
613
|
+
super(
|
|
614
|
+
`Run ${runId} did not reach a terminal status within ${timeoutSeconds}s` + (lastStatus ? ` (last status: ${lastStatus})` : "") + `. ${advice}` + (cause instanceof Error ? ` Last error while polling: ${cause.message}` : "")
|
|
615
|
+
);
|
|
616
|
+
this.name = "RunTimeoutError";
|
|
617
|
+
this.runId = runId;
|
|
618
|
+
this.timeoutSeconds = timeoutSeconds;
|
|
619
|
+
this.cause = cause;
|
|
620
|
+
if (lastStatus !== void 0) this.lastStatus = lastStatus;
|
|
621
|
+
}
|
|
622
|
+
};
|
|
623
|
+
var RunPausedError = class extends Error {
|
|
624
|
+
runId;
|
|
625
|
+
request;
|
|
626
|
+
constructor(runId, request, hint) {
|
|
627
|
+
super(`Run ${runId} is waiting for a human: ${hint}`);
|
|
628
|
+
this.name = "RunPausedError";
|
|
629
|
+
this.runId = runId;
|
|
630
|
+
this.request = request;
|
|
631
|
+
}
|
|
632
|
+
};
|
|
633
|
+
function plan(options) {
|
|
634
|
+
const interval = options.interval ?? 2;
|
|
635
|
+
const timeout = options.timeout ?? 300;
|
|
636
|
+
for (const [name, value] of [["interval", interval], ["timeout", timeout]]) {
|
|
637
|
+
if (!Number.isFinite(value) || value < 0) {
|
|
638
|
+
throw new TypeError(
|
|
639
|
+
`@m8tes/sdk: ${name} must be a finite, non-negative number of seconds (got ${String(value)}).`
|
|
640
|
+
);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
return { interval, timeout, deadline: now() + timeout * 1e3, signal: options.signal };
|
|
644
|
+
}
|
|
645
|
+
function napUntil(interval, deadline, signal) {
|
|
646
|
+
const remaining = Math.max(0, deadline - now()) / 1e3;
|
|
647
|
+
return sleep(Math.min(interval, remaining), signal);
|
|
648
|
+
}
|
|
649
|
+
async function withDeadline(start, deadline, signal, onExpired) {
|
|
650
|
+
const remaining = deadline - now();
|
|
651
|
+
if (remaining <= 0) throw onExpired();
|
|
652
|
+
const work = start();
|
|
653
|
+
let timer;
|
|
654
|
+
let onAbort;
|
|
655
|
+
try {
|
|
656
|
+
return await Promise.race([
|
|
657
|
+
work,
|
|
658
|
+
new Promise((_, reject) => {
|
|
659
|
+
timer = setTimeout(() => reject(onExpired()), remaining);
|
|
660
|
+
if (signal) {
|
|
661
|
+
onAbort = () => reject(onExpired());
|
|
662
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
663
|
+
}
|
|
664
|
+
})
|
|
665
|
+
]);
|
|
666
|
+
} finally {
|
|
667
|
+
if (timer) clearTimeout(timer);
|
|
668
|
+
if (signal && onAbort) signal.removeEventListener("abort", onAbort);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
function sleep(seconds, signal) {
|
|
672
|
+
if (signal?.aborted) return Promise.resolve();
|
|
673
|
+
return new Promise((resolve) => {
|
|
674
|
+
const timer = setTimeout(done, seconds * 1e3);
|
|
675
|
+
function done() {
|
|
676
|
+
clearTimeout(timer);
|
|
677
|
+
signal?.removeEventListener("abort", done);
|
|
678
|
+
resolve();
|
|
679
|
+
}
|
|
680
|
+
signal?.addEventListener("abort", done, { once: true });
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
function isPlanApproval(request) {
|
|
684
|
+
if (request.tool_name !== "AskUserQuestion") return false;
|
|
685
|
+
const questions = request.tool_input?.questions;
|
|
686
|
+
return Array.isArray(questions) && questions.some((q) => q?.header === "Plan Approval");
|
|
687
|
+
}
|
|
688
|
+
function planText(request) {
|
|
689
|
+
if (!isPlanApproval(request)) return null;
|
|
690
|
+
const questions = request.tool_input?.questions;
|
|
691
|
+
return questions?.find((q) => q?.header === "Plan Approval")?.question ?? null;
|
|
692
|
+
}
|
|
693
|
+
var now = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
|
|
694
|
+
var RunWaitAbortedError = class extends Error {
|
|
695
|
+
/**
|
|
696
|
+
* The run being waited on — `undefined` when the abort landed BEFORE any run
|
|
697
|
+
* was created, which is the one case where there is nothing to go back to.
|
|
698
|
+
* Previously this path passed a literal 0, producing "Waiting on run 0 was
|
|
699
|
+
* aborted" and pointing the reader at a run that never existed.
|
|
700
|
+
*/
|
|
701
|
+
runId;
|
|
702
|
+
constructor(runId) {
|
|
703
|
+
super(
|
|
704
|
+
runId === void 0 ? "Aborted before the run was created; nothing was started and nothing was billed." : `Waiting on run ${runId} was aborted. The run is still executing \u2014 poll it later with runs.get(${runId}), or stop it with runs.cancel(${runId}).`
|
|
705
|
+
);
|
|
706
|
+
this.name = "RunWaitAbortedError";
|
|
707
|
+
if (runId !== void 0) this.runId = runId;
|
|
708
|
+
}
|
|
709
|
+
};
|
|
710
|
+
async function pollRun(deps, runId, options = {}) {
|
|
711
|
+
const { interval, timeout, deadline, signal } = plan(options);
|
|
712
|
+
if (signal?.aborted) throw new RunWaitAbortedError(runId);
|
|
713
|
+
let lastError;
|
|
714
|
+
let lastStatus;
|
|
715
|
+
for (; ; ) {
|
|
716
|
+
let run;
|
|
717
|
+
try {
|
|
718
|
+
run = await withDeadline(
|
|
719
|
+
() => deps.get(runId, signal),
|
|
720
|
+
deadline,
|
|
721
|
+
signal,
|
|
722
|
+
() => signal?.aborted ? new RunWaitAbortedError(runId) : new RunTimeoutError(runId, timeout, lastError, lastStatus)
|
|
723
|
+
);
|
|
724
|
+
} catch (err) {
|
|
725
|
+
if (err instanceof RunTimeoutError || err instanceof RunWaitAbortedError) throw err;
|
|
726
|
+
if (signal?.aborted) throw new RunWaitAbortedError(runId);
|
|
727
|
+
if (isPermanent(err)) throw err;
|
|
728
|
+
lastError = err;
|
|
729
|
+
if (now() >= deadline) throw new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
730
|
+
await napUntil(interval, deadline, signal);
|
|
731
|
+
if (signal?.aborted) throw new RunWaitAbortedError(runId);
|
|
732
|
+
if (now() >= deadline) throw new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
733
|
+
continue;
|
|
734
|
+
}
|
|
735
|
+
lastStatus = run.status;
|
|
736
|
+
if (TERMINAL_STATUSES.has(run.status)) return run;
|
|
737
|
+
if (now() >= deadline) throw new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
738
|
+
await napUntil(interval, deadline, signal);
|
|
739
|
+
if (signal?.aborted) throw new RunWaitAbortedError(runId);
|
|
740
|
+
if (now() >= deadline) throw new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
async function waitForRun(deps, runId, options = {}) {
|
|
744
|
+
const { interval, timeout, deadline, signal } = plan(options);
|
|
745
|
+
if (signal?.aborted) throw new RunWaitAbortedError(runId);
|
|
746
|
+
let lastError;
|
|
747
|
+
let lastStatus;
|
|
748
|
+
const answered = /* @__PURE__ */ new Set();
|
|
749
|
+
for (; ; ) {
|
|
750
|
+
let run;
|
|
751
|
+
try {
|
|
752
|
+
run = await withDeadline(
|
|
753
|
+
() => deps.get(runId, signal),
|
|
754
|
+
deadline,
|
|
755
|
+
signal,
|
|
756
|
+
() => signal?.aborted ? new RunWaitAbortedError(runId) : new RunTimeoutError(runId, timeout, lastError, lastStatus)
|
|
757
|
+
);
|
|
758
|
+
} catch (err) {
|
|
759
|
+
if (err instanceof RunTimeoutError || err instanceof RunWaitAbortedError) throw err;
|
|
760
|
+
if (signal?.aborted) throw new RunWaitAbortedError(runId);
|
|
761
|
+
if (isPermanent(err)) throw err;
|
|
762
|
+
lastError = err;
|
|
763
|
+
if (now() >= deadline) throw new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
764
|
+
await napUntil(interval, deadline, signal);
|
|
765
|
+
if (signal?.aborted) throw new RunWaitAbortedError(runId);
|
|
766
|
+
if (now() >= deadline) throw new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
767
|
+
continue;
|
|
768
|
+
}
|
|
769
|
+
lastStatus = run.status;
|
|
770
|
+
if (TERMINAL_STATUSES.has(run.status)) return run;
|
|
771
|
+
if (run.status === "awaiting_approval") {
|
|
772
|
+
const expired = () => signal?.aborted ? new RunWaitAbortedError(runId) : new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
773
|
+
const bound = (start) => withDeadline(start, deadline, signal, expired);
|
|
774
|
+
const resolveGate = async (start) => {
|
|
775
|
+
try {
|
|
776
|
+
await bound(start);
|
|
777
|
+
} catch (err) {
|
|
778
|
+
if (!(err instanceof ConflictError) && !(err instanceof NotFoundError)) throw err;
|
|
779
|
+
if (!isBenignGateRefusal(err)) throw err;
|
|
780
|
+
}
|
|
781
|
+
};
|
|
782
|
+
const pending = (await bound(() => deps.permissions(runId, signal))).filter(
|
|
783
|
+
(r) => r.status === "pending" && !answered.has(r.request_id)
|
|
784
|
+
);
|
|
785
|
+
for (const request of pending) {
|
|
786
|
+
answered.add(request.request_id);
|
|
787
|
+
if (request.tool_name === "AskUserQuestion") {
|
|
788
|
+
if (!options.onQuestion) {
|
|
789
|
+
throw new RunPausedError(
|
|
790
|
+
runId,
|
|
791
|
+
request,
|
|
792
|
+
"the agent asked a question. Pass onQuestion to answer it, or call runs.answer() yourself."
|
|
793
|
+
);
|
|
794
|
+
}
|
|
795
|
+
const answers = await bound(async () => options.onQuestion(request));
|
|
796
|
+
await resolveGate(() => deps.answer(runId, { answers }, signal));
|
|
797
|
+
} else {
|
|
798
|
+
if (!options.onApproval) {
|
|
799
|
+
throw new RunPausedError(
|
|
800
|
+
runId,
|
|
801
|
+
request,
|
|
802
|
+
`the tool "${request.tool_name}" needs a decision. Pass onApproval, or call runs.approve() yourself.`
|
|
803
|
+
);
|
|
804
|
+
}
|
|
805
|
+
const decision = await bound(async () => options.onApproval(request));
|
|
806
|
+
await resolveGate(() => deps.approve(runId, { request_id: request.request_id, decision }, signal));
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
if (now() >= deadline) throw new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
811
|
+
await napUntil(interval, deadline, signal);
|
|
812
|
+
if (signal?.aborted) throw new RunWaitAbortedError(runId);
|
|
813
|
+
if (now() >= deadline) throw new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
|
|
311
817
|
// src/streaming.ts
|
|
312
818
|
var RunStream = class {
|
|
313
819
|
source;
|
|
@@ -386,29 +892,127 @@ var RunStream = class {
|
|
|
386
892
|
};
|
|
387
893
|
|
|
388
894
|
// src/resources/runs.ts
|
|
895
|
+
function withRunId(err, runId) {
|
|
896
|
+
if (err && typeof err === "object" && !("runId" in err)) {
|
|
897
|
+
Object.defineProperty(err, "runId", { value: runId, enumerable: true, configurable: true });
|
|
898
|
+
const e = err;
|
|
899
|
+
if (typeof e.message === "string" && !e.message.includes(String(runId))) {
|
|
900
|
+
e.message = `${e.message} (while waiting on run ${runId}, which is still executing)`;
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
return err;
|
|
904
|
+
}
|
|
389
905
|
function items(payload) {
|
|
390
906
|
return Array.isArray(payload) ? payload : payload?.data ?? [];
|
|
391
907
|
}
|
|
908
|
+
function idempotencyHeaders(key) {
|
|
909
|
+
return { [IDEMPOTENCY_HEADER]: key ?? crypto.randomUUID() };
|
|
910
|
+
}
|
|
911
|
+
function replayJoin(http) {
|
|
912
|
+
return async function* (run) {
|
|
913
|
+
if (TERMINAL_STATUSES.has(run.status)) {
|
|
914
|
+
throw new ConflictError(
|
|
915
|
+
`Run ${run.id} was already created by an earlier attempt with this idempotency key and has finished (status=${run.status}), so there is no stream to join. You were charged once. Fetch the result with runs.get(${run.id}).`,
|
|
916
|
+
{
|
|
917
|
+
type: "invalid_request_error",
|
|
918
|
+
code: 409,
|
|
919
|
+
status: 409,
|
|
920
|
+
details: { error_code: "idempotent_replay_terminal", run_id: run.id, status: run.status }
|
|
921
|
+
}
|
|
922
|
+
);
|
|
923
|
+
}
|
|
924
|
+
yield* http.stream("GET", `/runs/${seg(run.id)}/stream`);
|
|
925
|
+
};
|
|
926
|
+
}
|
|
392
927
|
function createRunsResource(http) {
|
|
393
928
|
const createBody = (p, stream) => {
|
|
394
|
-
const { agent_id, teammate_id, ...rest } = p;
|
|
929
|
+
const { agent_id, teammate_id, files, idempotencyKey, ...rest } = p;
|
|
395
930
|
return toBody({ ...rest, teammate_id: resolveAgentId(teammate_id, agent_id), stream });
|
|
396
931
|
};
|
|
932
|
+
const createForm = (p, stream) => {
|
|
933
|
+
const form = new FormData();
|
|
934
|
+
form.append("payload", JSON.stringify(createBody(p, stream)));
|
|
935
|
+
for (const f of p.files ?? []) {
|
|
936
|
+
const blobType = f.data instanceof Blob && f.data.type ? f.data.type : void 0;
|
|
937
|
+
const type = f.type ?? blobType ?? mimeTypeForFilename(f.name);
|
|
938
|
+
if (!type) throw new TypeError(unknownTypeMessage(f.name));
|
|
939
|
+
const blob = f.data instanceof Blob && f.data.type === type ? f.data : new Blob([f.data], { type });
|
|
940
|
+
form.append("files", blob, f.name);
|
|
941
|
+
}
|
|
942
|
+
return form;
|
|
943
|
+
};
|
|
944
|
+
const hasFiles = (p) => (p.files?.length ?? 0) > 0;
|
|
945
|
+
const pollDeps = (userId) => ({
|
|
946
|
+
get: (runId, signal) => http.request("GET", `/runs/${seg(runId)}`, {
|
|
947
|
+
query: toQuery({ user_id: userId }),
|
|
948
|
+
signal
|
|
949
|
+
}),
|
|
950
|
+
permissions: async (runId, signal) => items(await http.request("GET", `/runs/${seg(runId)}/permissions`, { signal })),
|
|
951
|
+
approve: (runId, params, signal) => http.request("POST", `/runs/${seg(runId)}/approve`, { body: { remember: false, ...params }, signal }),
|
|
952
|
+
answer: (runId, params, signal) => http.request("POST", `/runs/${seg(runId)}/answer`, { body: params, signal })
|
|
953
|
+
});
|
|
954
|
+
const createAsync = async (params) => {
|
|
955
|
+
const headers = idempotencyHeaders(params.idempotencyKey);
|
|
956
|
+
return hasFiles(params) ? http.request("POST", "/runs/with-files", { form: createForm(params, false), headers }) : http.request("POST", "/runs", { body: createBody(params, false), headers });
|
|
957
|
+
};
|
|
397
958
|
return {
|
|
398
959
|
create(params, options) {
|
|
399
|
-
|
|
960
|
+
const headers = idempotencyHeaders(params.idempotencyKey);
|
|
961
|
+
const init = hasFiles(params) ? { form: createForm(params, true), headers } : { body: createBody(params, true), headers };
|
|
962
|
+
const path = hasFiles(params) ? "/runs/with-files" : "/runs";
|
|
963
|
+
return new RunStream(
|
|
964
|
+
http.stream("POST", path, { ...init, onReplay: replayJoin(http) }),
|
|
965
|
+
options
|
|
966
|
+
);
|
|
967
|
+
},
|
|
968
|
+
createAsync,
|
|
969
|
+
async createAndWait(params, options = {}) {
|
|
970
|
+
if (options.signal?.aborted) throw new RunWaitAbortedError();
|
|
971
|
+
if (options.user_id != null && params.user_id != null && options.user_id !== params.user_id) {
|
|
972
|
+
throw new ValidationError(
|
|
973
|
+
`createAndWait: options.user_id (${JSON.stringify(options.user_id)}) conflicts with params.user_id (${JSON.stringify(params.user_id)}). Use one scope for create and poll.`,
|
|
974
|
+
{ type: "invalid_request_error", code: 0, status: 0 }
|
|
975
|
+
);
|
|
976
|
+
}
|
|
977
|
+
const createParams = params.user_id == null && options.user_id != null ? { ...params, user_id: options.user_id } : params;
|
|
978
|
+
const started = await createAsync(createParams);
|
|
979
|
+
const userId = started.user_id ?? createParams.user_id ?? void 0;
|
|
980
|
+
try {
|
|
981
|
+
return await waitForRun(pollDeps(userId), started.id, { ...options, user_id: userId });
|
|
982
|
+
} catch (err) {
|
|
983
|
+
throw withRunId(err, started.id);
|
|
984
|
+
}
|
|
400
985
|
},
|
|
401
|
-
|
|
402
|
-
return
|
|
986
|
+
poll(runId, options = {}) {
|
|
987
|
+
return pollRun(pollDeps(options.user_id), runId, options);
|
|
988
|
+
},
|
|
989
|
+
wait(runId, options = {}) {
|
|
990
|
+
return waitForRun(pollDeps(options.user_id), runId, options);
|
|
991
|
+
},
|
|
992
|
+
// `confirm` is a QUERY param and the route takes no body (verified against
|
|
993
|
+
// fastapi/app/routers/v2/runs.py::retry_run), so send neither.
|
|
994
|
+
retry(runId, params = {}) {
|
|
995
|
+
return http.request("POST", `/runs/${seg(runId)}/retry`, {
|
|
996
|
+
query: params.confirm ? toQuery({ confirm: true }) : ""
|
|
997
|
+
});
|
|
403
998
|
},
|
|
404
999
|
stream(runId, options) {
|
|
405
|
-
return new RunStream(http.stream("GET", `/runs/${runId}/stream`), options);
|
|
1000
|
+
return new RunStream(http.stream("GET", `/runs/${seg(runId)}/stream`), options);
|
|
406
1001
|
},
|
|
407
1002
|
reply(runId, message, options) {
|
|
408
|
-
return new RunStream(
|
|
1003
|
+
return new RunStream(
|
|
1004
|
+
http.stream("POST", `/runs/${seg(runId)}/reply`, {
|
|
1005
|
+
body: { message },
|
|
1006
|
+
headers: idempotencyHeaders(options?.idempotencyKey),
|
|
1007
|
+
onReplay: replayJoin(http)
|
|
1008
|
+
}),
|
|
1009
|
+
options
|
|
1010
|
+
);
|
|
409
1011
|
},
|
|
410
|
-
get(runId) {
|
|
411
|
-
return http.request("GET", `/runs/${runId}
|
|
1012
|
+
get(runId, params = {}) {
|
|
1013
|
+
return http.request("GET", `/runs/${seg(runId)}`, {
|
|
1014
|
+
query: toQuery({ user_id: params.user_id })
|
|
1015
|
+
});
|
|
412
1016
|
},
|
|
413
1017
|
async list(params = {}) {
|
|
414
1018
|
const { agent_id, teammate_id, ...rest } = params;
|
|
@@ -420,35 +1024,38 @@ function createRunsResource(http) {
|
|
|
420
1024
|
return new Page(
|
|
421
1025
|
res?.data ?? [],
|
|
422
1026
|
res?.has_more ?? false,
|
|
423
|
-
(starting_after) => fetchPage({ ...p, starting_after })
|
|
1027
|
+
(starting_after) => fetchPage({ ...p, starting_after }),
|
|
1028
|
+
res?.next_starting_after
|
|
424
1029
|
);
|
|
425
1030
|
};
|
|
426
1031
|
return fetchPage(q);
|
|
427
1032
|
},
|
|
428
|
-
cancel(runId) {
|
|
429
|
-
return http.request("POST", `/runs/${runId}/cancel`, {
|
|
1033
|
+
cancel(runId, params = {}) {
|
|
1034
|
+
return http.request("POST", `/runs/${seg(runId)}/cancel`, {
|
|
1035
|
+
query: toQuery({ user_id: params.user_id })
|
|
1036
|
+
});
|
|
430
1037
|
},
|
|
431
1038
|
approve(runId, params) {
|
|
432
|
-
return http.request("POST", `/runs/${runId}/approve`, {
|
|
1039
|
+
return http.request("POST", `/runs/${seg(runId)}/approve`, {
|
|
433
1040
|
body: { remember: false, ...params }
|
|
434
1041
|
});
|
|
435
1042
|
},
|
|
436
1043
|
answer(runId, params) {
|
|
437
|
-
return http.request("POST", `/runs/${runId}/answer`, {
|
|
1044
|
+
return http.request("POST", `/runs/${seg(runId)}/answer`, {
|
|
438
1045
|
body: { answers: params.answers }
|
|
439
1046
|
});
|
|
440
1047
|
},
|
|
441
1048
|
async permissions(runId) {
|
|
442
|
-
return items(await http.request("GET", `/runs/${runId}/permissions`));
|
|
1049
|
+
return items(await http.request("GET", `/runs/${seg(runId)}/permissions`));
|
|
443
1050
|
},
|
|
444
1051
|
outcome(runId) {
|
|
445
|
-
return http.request("GET", `/runs/${runId}/outcome`);
|
|
1052
|
+
return http.request("GET", `/runs/${seg(runId)}/outcome`);
|
|
446
1053
|
},
|
|
447
1054
|
async files(runId) {
|
|
448
|
-
return items(await http.request("GET", `/runs/${runId}/files`));
|
|
1055
|
+
return items(await http.request("GET", `/runs/${seg(runId)}/files`));
|
|
449
1056
|
},
|
|
450
1057
|
async downloadFile(runId, filename) {
|
|
451
|
-
const res = await http.raw("GET", `/runs/${runId}/files/${
|
|
1058
|
+
const res = await http.raw("GET", `/runs/${seg(runId)}/files/${seg(filename)}/download`, {
|
|
452
1059
|
headers: { accept: "application/octet-stream" }
|
|
453
1060
|
});
|
|
454
1061
|
return res.arrayBuffer();
|
|
@@ -473,24 +1080,30 @@ function createSettingsResource(http) {
|
|
|
473
1080
|
function createTasksResource(http) {
|
|
474
1081
|
const triggers = {
|
|
475
1082
|
create(taskId, params) {
|
|
476
|
-
return http.request("POST", `/tasks/${taskId}/triggers/`, {
|
|
477
|
-
body: toBody({ timezone: "UTC", ...params })
|
|
1083
|
+
return http.request("POST", `/tasks/${seg(taskId)}/triggers/`, {
|
|
1084
|
+
body: toBody({ timezone: "UTC", ...params }),
|
|
1085
|
+
query: toQuery({ user_id: params.user_id })
|
|
478
1086
|
});
|
|
479
1087
|
},
|
|
480
|
-
async list(taskId) {
|
|
1088
|
+
async list(taskId, params = {}) {
|
|
481
1089
|
const res = await http.request(
|
|
482
1090
|
"GET",
|
|
483
|
-
`/tasks/${taskId}/triggers
|
|
1091
|
+
`/tasks/${seg(taskId)}/triggers/`,
|
|
1092
|
+
{ query: toQuery(params) }
|
|
484
1093
|
);
|
|
485
1094
|
return Array.isArray(res) ? res : res?.data ?? [];
|
|
486
1095
|
},
|
|
487
1096
|
update(taskId, triggerId, params) {
|
|
488
|
-
|
|
489
|
-
|
|
1097
|
+
const { user_id, ...patch } = params;
|
|
1098
|
+
return http.request("PATCH", `/tasks/${seg(taskId)}/triggers/${seg(triggerId)}`, {
|
|
1099
|
+
body: toBody(patch),
|
|
1100
|
+
query: toQuery({ user_id })
|
|
490
1101
|
});
|
|
491
1102
|
},
|
|
492
|
-
async delete(taskId, triggerId) {
|
|
493
|
-
await http.request("DELETE", `/tasks/${taskId}/triggers/${triggerId}
|
|
1103
|
+
async delete(taskId, triggerId, params = {}) {
|
|
1104
|
+
await http.request("DELETE", `/tasks/${seg(taskId)}/triggers/${seg(triggerId)}`, {
|
|
1105
|
+
query: toQuery(params)
|
|
1106
|
+
});
|
|
494
1107
|
}
|
|
495
1108
|
};
|
|
496
1109
|
return {
|
|
@@ -511,79 +1124,53 @@ function createTasksResource(http) {
|
|
|
511
1124
|
return new Page(
|
|
512
1125
|
res?.data ?? [],
|
|
513
1126
|
res?.has_more ?? false,
|
|
514
|
-
(starting_after) => fetchPage({ ...p, starting_after })
|
|
1127
|
+
(starting_after) => fetchPage({ ...p, starting_after }),
|
|
1128
|
+
res?.next_starting_after
|
|
515
1129
|
);
|
|
516
1130
|
};
|
|
517
1131
|
return fetchPage(q);
|
|
518
1132
|
},
|
|
519
1133
|
get(taskId, params = {}) {
|
|
520
|
-
return http.request("GET", `/tasks/${taskId}`, { query: toQuery(params) });
|
|
1134
|
+
return http.request("GET", `/tasks/${seg(taskId)}`, { query: toQuery(params) });
|
|
521
1135
|
},
|
|
522
1136
|
update(taskId, params) {
|
|
523
1137
|
const { user_id, ...patch } = params;
|
|
524
|
-
return http.request("PATCH", `/tasks/${taskId}`, {
|
|
1138
|
+
return http.request("PATCH", `/tasks/${seg(taskId)}`, {
|
|
525
1139
|
body: toBody(patch),
|
|
526
1140
|
query: toQuery({ user_id })
|
|
527
1141
|
});
|
|
528
1142
|
},
|
|
529
1143
|
async delete(taskId, params = {}) {
|
|
530
|
-
await http.request("DELETE", `/tasks/${taskId}`, { query: toQuery(params) });
|
|
1144
|
+
await http.request("DELETE", `/tasks/${seg(taskId)}`, { query: toQuery(params) });
|
|
531
1145
|
},
|
|
532
1146
|
run(taskId, params = {}, options) {
|
|
1147
|
+
const { idempotencyKey, ...rest } = params;
|
|
533
1148
|
return new RunStream(
|
|
534
|
-
http.stream("POST", `/tasks/${taskId}/runs`, {
|
|
1149
|
+
http.stream("POST", `/tasks/${seg(taskId)}/runs`, {
|
|
1150
|
+
body: toBody({ ...rest, stream: true }),
|
|
1151
|
+
headers: idempotencyHeaders(idempotencyKey),
|
|
1152
|
+
// Shares the create path's replay handling, so a fix on one side can
|
|
1153
|
+
// never silently miss the other.
|
|
1154
|
+
onReplay: replayJoin(http)
|
|
1155
|
+
}),
|
|
535
1156
|
options
|
|
536
1157
|
);
|
|
537
1158
|
},
|
|
538
1159
|
runAsync(taskId, params = {}) {
|
|
539
|
-
|
|
540
|
-
|
|
1160
|
+
const { idempotencyKey, ...rest } = params;
|
|
1161
|
+
return http.request("POST", `/tasks/${seg(taskId)}/runs`, {
|
|
1162
|
+
body: toBody({ ...rest, stream: false }),
|
|
1163
|
+
headers: idempotencyHeaders(idempotencyKey)
|
|
541
1164
|
});
|
|
542
1165
|
},
|
|
543
|
-
enableWebhook(taskId) {
|
|
544
|
-
return http.request("POST", `/tasks/${taskId}/webhook`, {
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
await http.request("DELETE", `/tasks/${taskId}/webhook`);
|
|
548
|
-
}
|
|
549
|
-
};
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
// src/resources/users.ts
|
|
553
|
-
function pager(http, path) {
|
|
554
|
-
const fetchPage = async (p) => {
|
|
555
|
-
const res = await http.request("GET", path, {
|
|
556
|
-
query: toQuery(p)
|
|
557
|
-
});
|
|
558
|
-
return new Page(
|
|
559
|
-
res?.data ?? [],
|
|
560
|
-
res?.has_more ?? false,
|
|
561
|
-
(starting_after) => fetchPage({ ...p, starting_after })
|
|
562
|
-
);
|
|
563
|
-
};
|
|
564
|
-
return fetchPage;
|
|
565
|
-
}
|
|
566
|
-
function createUsersResource(http) {
|
|
567
|
-
return {
|
|
568
|
-
create(params) {
|
|
569
|
-
return http.request("POST", "/users/", { body: toBody({ ...params }) });
|
|
570
|
-
},
|
|
571
|
-
list(params = {}) {
|
|
572
|
-
return pager(http, "/users/")({ ...params });
|
|
573
|
-
},
|
|
574
|
-
get(userId) {
|
|
575
|
-
return http.request("GET", `/users/${encodeURIComponent(userId)}`);
|
|
576
|
-
},
|
|
577
|
-
update(userId, params) {
|
|
578
|
-
return http.request("PATCH", `/users/${encodeURIComponent(userId)}`, {
|
|
579
|
-
body: toBody({ ...params })
|
|
1166
|
+
enableWebhook(taskId, params = {}) {
|
|
1167
|
+
return http.request("POST", `/tasks/${seg(taskId)}/webhook`, {
|
|
1168
|
+
body: {},
|
|
1169
|
+
query: toQuery(params)
|
|
580
1170
|
});
|
|
581
1171
|
},
|
|
582
|
-
async
|
|
583
|
-
await http.request("DELETE", `/
|
|
584
|
-
},
|
|
585
|
-
usage(params = {}) {
|
|
586
|
-
return pager(http, "/usage/end-users")({ ...params });
|
|
1172
|
+
async disableWebhook(taskId, params = {}) {
|
|
1173
|
+
await http.request("DELETE", `/tasks/${seg(taskId)}/webhook`, { query: toQuery(params) });
|
|
587
1174
|
}
|
|
588
1175
|
};
|
|
589
1176
|
}
|
|
@@ -607,8 +1194,8 @@ function verifySignature(body, headers, secret, options = {}) {
|
|
|
607
1194
|
if (options.toleranceSeconds !== void 0) {
|
|
608
1195
|
const ts = Number.parseInt(timestamp, 10);
|
|
609
1196
|
if (!Number.isFinite(ts)) return false;
|
|
610
|
-
const
|
|
611
|
-
if (Math.abs(
|
|
1197
|
+
const now2 = options.now ? options.now() : Math.floor(Date.now() / 1e3);
|
|
1198
|
+
if (Math.abs(now2 - ts) > options.toleranceSeconds) return false;
|
|
612
1199
|
}
|
|
613
1200
|
const raw = typeof body === "string" ? body : new TextDecoder().decode(body);
|
|
614
1201
|
const expected = `v1=${createHmac("sha256", secret).update(`${webhookId}.${timestamp}.${raw}`).digest("hex")}`;
|
|
@@ -626,22 +1213,22 @@ function createWebhooksResource(http) {
|
|
|
626
1213
|
return pager(http, "/webhooks/")({ ...params });
|
|
627
1214
|
},
|
|
628
1215
|
get(webhookId) {
|
|
629
|
-
return http.request("GET", `/webhooks/${webhookId}`);
|
|
1216
|
+
return http.request("GET", `/webhooks/${seg(webhookId)}`);
|
|
630
1217
|
},
|
|
631
1218
|
update(webhookId, params) {
|
|
632
|
-
return http.request("PATCH", `/webhooks/${webhookId}`, { body: toBody({ ...params }) });
|
|
1219
|
+
return http.request("PATCH", `/webhooks/${seg(webhookId)}`, { body: toBody({ ...params }) });
|
|
633
1220
|
},
|
|
634
1221
|
async delete(webhookId) {
|
|
635
|
-
await http.request("DELETE", `/webhooks/${webhookId}`);
|
|
1222
|
+
await http.request("DELETE", `/webhooks/${seg(webhookId)}`);
|
|
636
1223
|
},
|
|
637
1224
|
listDeliveries(webhookId, params = {}) {
|
|
638
|
-
return pager(http, `/webhooks/${webhookId}/deliveries`)({ ...params });
|
|
1225
|
+
return pager(http, `/webhooks/${seg(webhookId)}/deliveries`)({ ...params });
|
|
639
1226
|
}
|
|
640
1227
|
};
|
|
641
1228
|
}
|
|
642
1229
|
|
|
643
1230
|
// src/index.ts
|
|
644
|
-
var M8TES_SDK_VERSION = "0.1.0-alpha.
|
|
1231
|
+
var M8TES_SDK_VERSION = "0.1.0-alpha.3";
|
|
645
1232
|
var M8tes = class {
|
|
646
1233
|
runs;
|
|
647
1234
|
agents;
|
|
@@ -652,6 +1239,12 @@ var M8tes = class {
|
|
|
652
1239
|
apps;
|
|
653
1240
|
webhooks;
|
|
654
1241
|
settings;
|
|
1242
|
+
memories;
|
|
1243
|
+
permissions;
|
|
1244
|
+
models;
|
|
1245
|
+
modelConnections;
|
|
1246
|
+
billing;
|
|
1247
|
+
account;
|
|
655
1248
|
/** The underlying transport. Use it to call an endpoint this version does not wrap yet. */
|
|
656
1249
|
http;
|
|
657
1250
|
constructor(options = {}) {
|
|
@@ -664,9 +1257,15 @@ var M8tes = class {
|
|
|
664
1257
|
this.apps = createAppsResource(this.http);
|
|
665
1258
|
this.webhooks = createWebhooksResource(this.http);
|
|
666
1259
|
this.settings = createSettingsResource(this.http);
|
|
1260
|
+
this.memories = createMemoriesResource(this.http);
|
|
1261
|
+
this.permissions = createPermissionsResource(this.http);
|
|
1262
|
+
this.models = createModelsResource(this.http);
|
|
1263
|
+
this.modelConnections = createModelConnectionsResource(this.http);
|
|
1264
|
+
this.billing = createBillingResource(this.http);
|
|
1265
|
+
this.account = createAccountResource(this.http);
|
|
667
1266
|
}
|
|
668
1267
|
};
|
|
669
1268
|
|
|
670
|
-
export { DEFAULT_BASE_URL, M8TES_SDK_VERSION, M8tes, Page, RunStream, createHttp, verifySignature };
|
|
1269
|
+
export { DEFAULT_BASE_URL, M8TES_SDK_VERSION, M8tes, Page, RunPausedError, RunStream, RunTimeoutError, RunWaitAbortedError, TERMINAL_STATUSES, createHttp, isPlanApproval, planText, pollRun, verifySignature, waitForRun };
|
|
671
1270
|
//# sourceMappingURL=index.js.map
|
|
672
1271
|
//# sourceMappingURL=index.js.map
|