@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.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var crypto = require('crypto');
|
|
3
|
+
var crypto$1 = require('crypto');
|
|
4
4
|
|
|
5
5
|
// src/protocol/events.ts
|
|
6
6
|
var PROTOCOL_VERSION = "m8tes.stream.v2";
|
|
@@ -1082,12 +1082,52 @@ async function errorFromResponse(res, opts = {}) {
|
|
|
1082
1082
|
return new Cls(message, fields);
|
|
1083
1083
|
}
|
|
1084
1084
|
|
|
1085
|
+
// src/protocol/seg.ts
|
|
1086
|
+
var UNADDRESSABLE = /* @__PURE__ */ new Set(["", ".", ".."]);
|
|
1087
|
+
var SEPARATOR = "/";
|
|
1088
|
+
function reject(value, reason) {
|
|
1089
|
+
throw new ValidationError(
|
|
1090
|
+
`${JSON.stringify(value)} cannot be used as a URL path segment: ${reason}. Percent-encoding does not help \u2014 the server decodes the path before routing it.`,
|
|
1091
|
+
{ type: "invalid_request_error", code: 0, status: 0 }
|
|
1092
|
+
);
|
|
1093
|
+
}
|
|
1094
|
+
function seg(value) {
|
|
1095
|
+
if (value === null || value === void 0) {
|
|
1096
|
+
reject(String(value), "an id of null or undefined is a caller bug, not a resource name");
|
|
1097
|
+
}
|
|
1098
|
+
const text = String(value);
|
|
1099
|
+
if (UNADDRESSABLE.has(text)) {
|
|
1100
|
+
reject(text, "it addresses the parent or the collection, not a resource");
|
|
1101
|
+
}
|
|
1102
|
+
if (text.includes(SEPARATOR)) {
|
|
1103
|
+
reject(text, "a '/' becomes a real path separator once the server decodes it");
|
|
1104
|
+
}
|
|
1105
|
+
return encodeURIComponent(text);
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1085
1108
|
// src/http.ts
|
|
1086
1109
|
var DEFAULT_BASE_URL = "https://api.m8tes.ai/api/v2";
|
|
1087
1110
|
var MAX_ATTEMPTS = 3;
|
|
1088
1111
|
var INITIAL_BACKOFF_MS = 500;
|
|
1089
1112
|
var RETRYABLE_STATUS = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
1090
1113
|
var IDEMPOTENT_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD", "PUT", "DELETE", "OPTIONS"]);
|
|
1114
|
+
var IDEMPOTENCY_HEADER = "idempotency-key";
|
|
1115
|
+
var REPLAY_HEADER = "idempotent-replay";
|
|
1116
|
+
var IDEMPOTENT_POST_PATHS = [
|
|
1117
|
+
/^\/runs\/?$/,
|
|
1118
|
+
/^\/runs\/with-files\/?$/,
|
|
1119
|
+
/^\/runs\/\d+\/reply\/?$/,
|
|
1120
|
+
/^\/runs\/\d+\/reply\/with-files\/?$/,
|
|
1121
|
+
/^\/tasks\/\d+\/runs\/?$/
|
|
1122
|
+
];
|
|
1123
|
+
function isIdempotentRoute(path) {
|
|
1124
|
+
const clean = path.split("?")[0] ?? "";
|
|
1125
|
+
return IDEMPOTENT_POST_PATHS.some((re) => re.test(clean));
|
|
1126
|
+
}
|
|
1127
|
+
function isRetryable(method, path, headers) {
|
|
1128
|
+
if (IDEMPOTENT_METHODS.has(method.toUpperCase())) return true;
|
|
1129
|
+
return IDEMPOTENCY_HEADER in headers && isIdempotentRoute(path);
|
|
1130
|
+
}
|
|
1091
1131
|
function backoff(ms, signal) {
|
|
1092
1132
|
if (signal?.aborted) return Promise.resolve();
|
|
1093
1133
|
return new Promise((resolve) => {
|
|
@@ -1148,14 +1188,22 @@ function createHttp(options = {}) {
|
|
|
1148
1188
|
const message = diagnose(res, text, body, url) ?? (body ? parsed.message : text || parsed.message);
|
|
1149
1189
|
return new (errorClassForStatus(res.status, errOpts))(message, parsed.fields);
|
|
1150
1190
|
}
|
|
1191
|
+
function mergeHeaders(...sources) {
|
|
1192
|
+
const out = {};
|
|
1193
|
+
for (const src of sources) {
|
|
1194
|
+
for (const [k, v] of Object.entries(src ?? {})) out[k.toLowerCase()] = v;
|
|
1195
|
+
}
|
|
1196
|
+
return out;
|
|
1197
|
+
}
|
|
1151
1198
|
async function attempt(method, url, opts) {
|
|
1152
|
-
const headers = {
|
|
1153
|
-
authorization: `Bearer ${apiKey}
|
|
1154
|
-
|
|
1155
|
-
...opts.headers
|
|
1156
|
-
};
|
|
1199
|
+
const headers = mergeHeaders(options.headers, opts.headers, {
|
|
1200
|
+
authorization: `Bearer ${apiKey}`
|
|
1201
|
+
});
|
|
1157
1202
|
const init = { method, headers };
|
|
1158
|
-
if (opts.
|
|
1203
|
+
if (opts.form !== void 0) {
|
|
1204
|
+
delete headers["content-type"];
|
|
1205
|
+
init.body = opts.form;
|
|
1206
|
+
} else if (opts.body !== void 0) {
|
|
1159
1207
|
headers["content-type"] = "application/json";
|
|
1160
1208
|
init.body = JSON.stringify(opts.body);
|
|
1161
1209
|
}
|
|
@@ -1165,7 +1213,7 @@ function createHttp(options = {}) {
|
|
|
1165
1213
|
}
|
|
1166
1214
|
async function send(method, path, opts, errOpts = {}) {
|
|
1167
1215
|
const url = `${baseUrl}${path}${opts.query ?? ""}`;
|
|
1168
|
-
const idempotent =
|
|
1216
|
+
const idempotent = isRetryable(method, path, mergeHeaders(options.headers, opts.headers));
|
|
1169
1217
|
let lastNetworkError;
|
|
1170
1218
|
for (let i = 0; i < MAX_ATTEMPTS; i++) {
|
|
1171
1219
|
const isLast = i === MAX_ATTEMPTS - 1;
|
|
@@ -1213,6 +1261,11 @@ function createHttp(options = {}) {
|
|
|
1213
1261
|
},
|
|
1214
1262
|
async *stream(method, path, opts = {}) {
|
|
1215
1263
|
const res = await send(method, path, opts, { conflictIsNotStreaming: true });
|
|
1264
|
+
if (opts.onReplay && res.headers.get(REPLAY_HEADER)) {
|
|
1265
|
+
const run = await res.json();
|
|
1266
|
+
yield* opts.onReplay(run);
|
|
1267
|
+
return;
|
|
1268
|
+
}
|
|
1216
1269
|
if (!res.body) return;
|
|
1217
1270
|
const normalizer = opts.normalizer ?? createNormalizer();
|
|
1218
1271
|
const decoder = createSseDecoder({ onMalformed: options.onMalformed });
|
|
@@ -1245,12 +1298,14 @@ function createHttp(options = {}) {
|
|
|
1245
1298
|
var Page = class {
|
|
1246
1299
|
data;
|
|
1247
1300
|
hasMore;
|
|
1301
|
+
nextStartingAfter;
|
|
1248
1302
|
/** Fetches the next page given a cursor. Absent on a terminal page. */
|
|
1249
1303
|
fetchNext;
|
|
1250
|
-
constructor(data, hasMore, fetchNext) {
|
|
1304
|
+
constructor(data, hasMore, fetchNext, nextStartingAfter) {
|
|
1251
1305
|
this.data = data;
|
|
1252
1306
|
this.hasMore = hasMore;
|
|
1253
1307
|
this.fetchNext = fetchNext;
|
|
1308
|
+
this.nextStartingAfter = nextStartingAfter ?? null;
|
|
1254
1309
|
}
|
|
1255
1310
|
/**
|
|
1256
1311
|
* Auto-paging: yields every item across every page.
|
|
@@ -1268,7 +1323,10 @@ var Page = class {
|
|
|
1268
1323
|
yield* page.data;
|
|
1269
1324
|
const last = page.data.at(-1);
|
|
1270
1325
|
if (!page.hasMore || !last || !page.fetchNext) return;
|
|
1271
|
-
|
|
1326
|
+
let cursor = page.nextStartingAfter === null || page.nextStartingAfter === void 0 ? void 0 : page.nextStartingAfter;
|
|
1327
|
+
if (cursor === void 0) {
|
|
1328
|
+
cursor = typeof last.id === "number" || typeof last.id === "string" ? last.id : typeof last.name === "string" ? last.name : void 0;
|
|
1329
|
+
}
|
|
1272
1330
|
if (cursor === void 0 || seen.has(cursor)) return;
|
|
1273
1331
|
seen.add(cursor);
|
|
1274
1332
|
page = await page.fetchNext(cursor);
|
|
@@ -1320,74 +1378,545 @@ function createAgentsResource(http) {
|
|
|
1320
1378
|
return new Page(
|
|
1321
1379
|
res?.data ?? [],
|
|
1322
1380
|
res?.has_more ?? false,
|
|
1323
|
-
(starting_after) => fetchPage({ ...p, starting_after })
|
|
1381
|
+
(starting_after) => fetchPage({ ...p, starting_after }),
|
|
1382
|
+
res?.next_starting_after
|
|
1324
1383
|
);
|
|
1325
1384
|
};
|
|
1326
1385
|
return fetchPage({ ...params });
|
|
1327
1386
|
},
|
|
1328
1387
|
get(agentId, params = {}) {
|
|
1329
|
-
return http.request("GET", `/agents/${agentId}`, { query: toQuery(params) });
|
|
1388
|
+
return http.request("GET", `/agents/${seg(agentId)}`, { query: toQuery(params) });
|
|
1330
1389
|
},
|
|
1331
1390
|
update(agentId, params) {
|
|
1332
1391
|
const { user_id, ...patch } = params;
|
|
1333
|
-
return http.request("PATCH", `/agents/${agentId}`, {
|
|
1392
|
+
return http.request("PATCH", `/agents/${seg(agentId)}`, {
|
|
1334
1393
|
body: toBody(patch),
|
|
1335
1394
|
query: toQuery({ user_id })
|
|
1336
1395
|
});
|
|
1337
1396
|
},
|
|
1338
1397
|
async delete(agentId, params = {}) {
|
|
1339
|
-
await http.request("DELETE", `/agents/${agentId}`, { query: toQuery(params) });
|
|
1398
|
+
await http.request("DELETE", `/agents/${seg(agentId)}`, { query: toQuery(params) });
|
|
1340
1399
|
},
|
|
1341
|
-
enableWebhook(agentId) {
|
|
1342
|
-
return http.request("POST", `/agents/${agentId}/webhook`, {
|
|
1400
|
+
enableWebhook(agentId, params = {}) {
|
|
1401
|
+
return http.request("POST", `/agents/${seg(agentId)}/webhook`, {
|
|
1402
|
+
body: {},
|
|
1403
|
+
query: toQuery(params)
|
|
1404
|
+
});
|
|
1343
1405
|
},
|
|
1344
|
-
async disableWebhook(agentId) {
|
|
1345
|
-
await http.request("DELETE", `/agents/${agentId}/webhook
|
|
1406
|
+
async disableWebhook(agentId, params = {}) {
|
|
1407
|
+
await http.request("DELETE", `/agents/${seg(agentId)}/webhook`, { query: toQuery(params) });
|
|
1346
1408
|
},
|
|
1347
|
-
enableEmailInbox(agentId) {
|
|
1348
|
-
return http.request("POST", `/agents/${agentId}/email-inbox`, {
|
|
1409
|
+
enableEmailInbox(agentId, params = {}) {
|
|
1410
|
+
return http.request("POST", `/agents/${seg(agentId)}/email-inbox`, {
|
|
1411
|
+
body: {},
|
|
1412
|
+
query: toQuery(params)
|
|
1413
|
+
});
|
|
1349
1414
|
},
|
|
1350
|
-
async disableEmailInbox(agentId) {
|
|
1351
|
-
await http.request("DELETE", `/agents/${agentId}/email-inbox
|
|
1415
|
+
async disableEmailInbox(agentId, params = {}) {
|
|
1416
|
+
await http.request("DELETE", `/agents/${seg(agentId)}/email-inbox`, { query: toQuery(params) });
|
|
1352
1417
|
}
|
|
1353
1418
|
};
|
|
1354
1419
|
}
|
|
1355
1420
|
|
|
1356
1421
|
// src/resources/apps.ts
|
|
1357
1422
|
function createAppsResource(http) {
|
|
1358
|
-
const
|
|
1423
|
+
const list = async (params = {}) => {
|
|
1424
|
+
const res = await http.request("GET", "/apps/", {
|
|
1425
|
+
query: toQuery({ user_id: params.user_id })
|
|
1426
|
+
});
|
|
1427
|
+
return new Page(res?.data ?? [], res?.has_more ?? false, void 0, res?.next_starting_after);
|
|
1428
|
+
};
|
|
1359
1429
|
return {
|
|
1360
|
-
|
|
1361
|
-
const res = await http.request("GET", "/apps/", {
|
|
1362
|
-
query: toQuery({ user_id: params.user_id })
|
|
1363
|
-
});
|
|
1364
|
-
return new Page(res?.data ?? [], res?.has_more ?? false);
|
|
1365
|
-
},
|
|
1430
|
+
list,
|
|
1366
1431
|
async isConnected(appName, params = {}) {
|
|
1367
|
-
const { data } = await
|
|
1432
|
+
const { data } = await list(params);
|
|
1368
1433
|
return data.find((a) => a.name === appName)?.connected ?? false;
|
|
1369
1434
|
},
|
|
1370
1435
|
connectOauth(appName, params) {
|
|
1371
|
-
return http.request("POST", `/apps/${
|
|
1436
|
+
return http.request("POST", `/apps/${seg(appName)}/connect`, {
|
|
1372
1437
|
body: toBody({ ...params })
|
|
1373
1438
|
});
|
|
1374
1439
|
},
|
|
1375
1440
|
connectApiKey(appName, params) {
|
|
1376
|
-
return http.request("POST", `/apps/${
|
|
1441
|
+
return http.request("POST", `/apps/${seg(appName)}/connect/api-key`, {
|
|
1377
1442
|
body: toBody({ ...params })
|
|
1378
1443
|
});
|
|
1379
1444
|
},
|
|
1380
1445
|
connectComplete(appName, params) {
|
|
1381
|
-
return http.request("POST", `/apps/${
|
|
1446
|
+
return http.request("POST", `/apps/${seg(appName)}/connect/complete`, {
|
|
1382
1447
|
body: toBody({ ...params })
|
|
1383
1448
|
});
|
|
1384
1449
|
},
|
|
1385
1450
|
async disconnect(appName, params = {}) {
|
|
1386
|
-
await http.request("DELETE", `/apps/${
|
|
1451
|
+
await http.request("DELETE", `/apps/${seg(appName)}/connections`, { query: toQuery(params) });
|
|
1452
|
+
}
|
|
1453
|
+
};
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
// src/resources/account.ts
|
|
1457
|
+
function createAccountResource(http) {
|
|
1458
|
+
return {
|
|
1459
|
+
export() {
|
|
1460
|
+
return http.request("GET", "/account/export");
|
|
1461
|
+
},
|
|
1462
|
+
delete() {
|
|
1463
|
+
return http.request("DELETE", "/account");
|
|
1464
|
+
}
|
|
1465
|
+
};
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
// src/resources/users.ts
|
|
1469
|
+
function pager(http, path) {
|
|
1470
|
+
const fetchPage = async (p) => {
|
|
1471
|
+
const res = await http.request("GET", path, {
|
|
1472
|
+
query: toQuery(p)
|
|
1473
|
+
});
|
|
1474
|
+
return new Page(
|
|
1475
|
+
res?.data ?? [],
|
|
1476
|
+
res?.has_more ?? false,
|
|
1477
|
+
(starting_after) => fetchPage({ ...p, starting_after }),
|
|
1478
|
+
res?.next_starting_after
|
|
1479
|
+
);
|
|
1480
|
+
};
|
|
1481
|
+
return fetchPage;
|
|
1482
|
+
}
|
|
1483
|
+
function createUsersResource(http) {
|
|
1484
|
+
return {
|
|
1485
|
+
create(params) {
|
|
1486
|
+
return http.request("POST", "/users/", { body: toBody({ ...params }) });
|
|
1487
|
+
},
|
|
1488
|
+
list(params = {}) {
|
|
1489
|
+
return pager(http, "/users/")({ ...params });
|
|
1490
|
+
},
|
|
1491
|
+
get(userId) {
|
|
1492
|
+
return http.request("GET", `/users/${seg(userId)}`);
|
|
1493
|
+
},
|
|
1494
|
+
update(userId, params) {
|
|
1495
|
+
return http.request("PATCH", `/users/${seg(userId)}`, {
|
|
1496
|
+
body: toBody({ ...params })
|
|
1497
|
+
});
|
|
1498
|
+
},
|
|
1499
|
+
async delete(userId) {
|
|
1500
|
+
await http.request("DELETE", `/users/${seg(userId)}`);
|
|
1501
|
+
},
|
|
1502
|
+
usage(params = {}) {
|
|
1503
|
+
return pager(http, "/usage/end-users")({ ...params });
|
|
1387
1504
|
}
|
|
1388
1505
|
};
|
|
1389
1506
|
}
|
|
1390
1507
|
|
|
1508
|
+
// src/resources/billing.ts
|
|
1509
|
+
function createBillingResource(http) {
|
|
1510
|
+
return {
|
|
1511
|
+
usage() {
|
|
1512
|
+
return http.request("GET", "/usage/");
|
|
1513
|
+
},
|
|
1514
|
+
usageTimeseries(params = {}) {
|
|
1515
|
+
const { agent_id, teammate_id, ...rest } = params;
|
|
1516
|
+
const query = toQuery(
|
|
1517
|
+
toBody({ ...rest, teammate_id: resolveAgentId(teammate_id, agent_id) })
|
|
1518
|
+
);
|
|
1519
|
+
return http.request("GET", "/usage/timeseries", { query });
|
|
1520
|
+
},
|
|
1521
|
+
receipts(params = {}) {
|
|
1522
|
+
return pager(http, "/billing/receipts")({ ...params });
|
|
1523
|
+
},
|
|
1524
|
+
plans() {
|
|
1525
|
+
return http.request("GET", "/billing/plans");
|
|
1526
|
+
},
|
|
1527
|
+
setOverage(params) {
|
|
1528
|
+
return http.request("PATCH", "/billing/overage", { body: toBody({ ...params }) });
|
|
1529
|
+
},
|
|
1530
|
+
balance() {
|
|
1531
|
+
return http.request("GET", "/billing/balance");
|
|
1532
|
+
},
|
|
1533
|
+
async topup(params) {
|
|
1534
|
+
const res = await http.request("POST", "/billing/topup", {
|
|
1535
|
+
body: toBody({ ...params })
|
|
1536
|
+
});
|
|
1537
|
+
return res.checkout_url;
|
|
1538
|
+
},
|
|
1539
|
+
setAutoReload(params) {
|
|
1540
|
+
return http.request("PATCH", "/billing/auto-reload", {
|
|
1541
|
+
body: toBody({ ...params })
|
|
1542
|
+
});
|
|
1543
|
+
},
|
|
1544
|
+
setAlertThreshold(params) {
|
|
1545
|
+
return http.request("PATCH", "/billing/alert-settings", {
|
|
1546
|
+
body: toBody({ ...params })
|
|
1547
|
+
});
|
|
1548
|
+
}
|
|
1549
|
+
};
|
|
1550
|
+
}
|
|
1551
|
+
|
|
1552
|
+
// src/resources/memories.ts
|
|
1553
|
+
function createMemoriesResource(http) {
|
|
1554
|
+
return {
|
|
1555
|
+
create(params) {
|
|
1556
|
+
return http.request("POST", "/memories/", { body: toBody({ ...params }) });
|
|
1557
|
+
},
|
|
1558
|
+
list(params = {}) {
|
|
1559
|
+
return pager(http, "/memories/")({ ...params });
|
|
1560
|
+
},
|
|
1561
|
+
update(memoryId, { user_id, content }) {
|
|
1562
|
+
return http.request("PATCH", `/memories/${seg(memoryId)}`, {
|
|
1563
|
+
query: toQuery({ user_id }),
|
|
1564
|
+
body: toBody({ content })
|
|
1565
|
+
});
|
|
1566
|
+
},
|
|
1567
|
+
async delete(memoryId, params = {}) {
|
|
1568
|
+
await http.request("DELETE", `/memories/${seg(memoryId)}`, {
|
|
1569
|
+
query: toQuery({ user_id: params.user_id })
|
|
1570
|
+
});
|
|
1571
|
+
}
|
|
1572
|
+
};
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1575
|
+
// src/resources/models.ts
|
|
1576
|
+
function createModelsResource(http) {
|
|
1577
|
+
return {
|
|
1578
|
+
async list() {
|
|
1579
|
+
const res = await http.request("GET", "/models/");
|
|
1580
|
+
return new Page(res?.data ?? [], res?.has_more ?? false, void 0, res?.next_starting_after);
|
|
1581
|
+
}
|
|
1582
|
+
};
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
// src/resources/model-connections.ts
|
|
1586
|
+
function createModelConnectionsResource(http) {
|
|
1587
|
+
return {
|
|
1588
|
+
async list() {
|
|
1589
|
+
const res = await http.request("GET", "/model-connections/");
|
|
1590
|
+
return res?.data ?? [];
|
|
1591
|
+
},
|
|
1592
|
+
authorize(provider) {
|
|
1593
|
+
return http.request(
|
|
1594
|
+
"POST",
|
|
1595
|
+
`/model-connections/${seg(provider)}/authorizations`
|
|
1596
|
+
);
|
|
1597
|
+
},
|
|
1598
|
+
authorizationStatus(provider, state) {
|
|
1599
|
+
return http.request(
|
|
1600
|
+
"GET",
|
|
1601
|
+
`/model-connections/${seg(provider)}/authorizations/${seg(state)}`
|
|
1602
|
+
);
|
|
1603
|
+
},
|
|
1604
|
+
completeAuthorization(provider, state, params) {
|
|
1605
|
+
return http.request(
|
|
1606
|
+
"POST",
|
|
1607
|
+
`/model-connections/${seg(provider)}/authorizations/${seg(state)}`,
|
|
1608
|
+
{ body: { code: params.code } }
|
|
1609
|
+
);
|
|
1610
|
+
},
|
|
1611
|
+
async cancelAuthorization(provider, state) {
|
|
1612
|
+
await http.request("DELETE", `/model-connections/${seg(provider)}/authorizations/${seg(state)}`);
|
|
1613
|
+
},
|
|
1614
|
+
disconnect(provider) {
|
|
1615
|
+
return http.request("DELETE", `/model-connections/${seg(provider)}`);
|
|
1616
|
+
}
|
|
1617
|
+
};
|
|
1618
|
+
}
|
|
1619
|
+
|
|
1620
|
+
// src/resources/permissions.ts
|
|
1621
|
+
function createPermissionsResource(http) {
|
|
1622
|
+
return {
|
|
1623
|
+
create(params) {
|
|
1624
|
+
return http.request("POST", "/permissions/", {
|
|
1625
|
+
body: toBody({ ...params })
|
|
1626
|
+
});
|
|
1627
|
+
},
|
|
1628
|
+
list(params) {
|
|
1629
|
+
return pager(http, "/permissions/")({ ...params });
|
|
1630
|
+
},
|
|
1631
|
+
async delete(permissionId, params) {
|
|
1632
|
+
await http.request("DELETE", `/permissions/${seg(permissionId)}`, {
|
|
1633
|
+
query: toQuery({ user_id: params.user_id })
|
|
1634
|
+
});
|
|
1635
|
+
}
|
|
1636
|
+
};
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
// src/mime.ts
|
|
1640
|
+
var EXTENSION_TYPES = Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
1641
|
+
// Images (the agent can actually see these via its Read tool)
|
|
1642
|
+
jpg: "image/jpeg",
|
|
1643
|
+
jpeg: "image/jpeg",
|
|
1644
|
+
png: "image/png",
|
|
1645
|
+
gif: "image/gif",
|
|
1646
|
+
webp: "image/webp",
|
|
1647
|
+
// Documents
|
|
1648
|
+
pdf: "application/pdf",
|
|
1649
|
+
txt: "text/plain",
|
|
1650
|
+
md: "text/markdown",
|
|
1651
|
+
markdown: "text/markdown",
|
|
1652
|
+
html: "text/html",
|
|
1653
|
+
htm: "text/html",
|
|
1654
|
+
// Code
|
|
1655
|
+
py: "text/x-python",
|
|
1656
|
+
js: "application/javascript",
|
|
1657
|
+
mjs: "application/javascript",
|
|
1658
|
+
cjs: "application/javascript",
|
|
1659
|
+
json: "application/json",
|
|
1660
|
+
ts: "text/typescript",
|
|
1661
|
+
tsx: "text/typescript",
|
|
1662
|
+
css: "text/css",
|
|
1663
|
+
c: "text/x-c",
|
|
1664
|
+
h: "text/x-c",
|
|
1665
|
+
java: "text/x-java-source",
|
|
1666
|
+
go: "text/x-go",
|
|
1667
|
+
sql: "application/sql",
|
|
1668
|
+
// Data / config
|
|
1669
|
+
csv: "text/csv",
|
|
1670
|
+
tsv: "text/csv",
|
|
1671
|
+
xml: "application/xml",
|
|
1672
|
+
yaml: "text/yaml",
|
|
1673
|
+
yml: "text/yaml",
|
|
1674
|
+
// Archives
|
|
1675
|
+
zip: "application/zip",
|
|
1676
|
+
gz: "application/gzip",
|
|
1677
|
+
tgz: "application/gzip",
|
|
1678
|
+
tar: "application/x-tar",
|
|
1679
|
+
// Office
|
|
1680
|
+
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
1681
|
+
xls: "application/vnd.ms-excel",
|
|
1682
|
+
docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
1683
|
+
pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
1684
|
+
ppt: "application/vnd.ms-powerpoint"
|
|
1685
|
+
});
|
|
1686
|
+
var UPLOADABLE_EXTENSIONS = Object.keys(EXTENSION_TYPES);
|
|
1687
|
+
function mimeTypeForFilename(name) {
|
|
1688
|
+
const ext = name.includes(".") ? name.slice(name.lastIndexOf(".") + 1).toLowerCase() : "";
|
|
1689
|
+
return EXTENSION_TYPES[ext];
|
|
1690
|
+
}
|
|
1691
|
+
function unknownTypeMessage(name) {
|
|
1692
|
+
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(", ")}, ...).`;
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
// src/polling.ts
|
|
1696
|
+
function isPermanent(err) {
|
|
1697
|
+
return err instanceof AuthenticationError || err instanceof PermissionDeniedError || err instanceof NotFoundError || err instanceof ValidationError;
|
|
1698
|
+
}
|
|
1699
|
+
var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled", "closed"]);
|
|
1700
|
+
var BENIGN_GATE_REFUSAL_CODES = /* @__PURE__ */ new Set(["gate_cancelled", "run_not_active"]);
|
|
1701
|
+
var AUTO_CONTINUED_MESSAGE = "auto_continued";
|
|
1702
|
+
function isBenignGateRefusal(err) {
|
|
1703
|
+
if (err.errorCode !== void 0) return BENIGN_GATE_REFUSAL_CODES.has(err.errorCode);
|
|
1704
|
+
return err instanceof ConflictError && err.message === AUTO_CONTINUED_MESSAGE;
|
|
1705
|
+
}
|
|
1706
|
+
var RunTimeoutError = class extends Error {
|
|
1707
|
+
runId;
|
|
1708
|
+
timeoutSeconds;
|
|
1709
|
+
/** The last error seen while polling, if any. Without it a timeout hides the
|
|
1710
|
+
* transient failure that actually caused it. */
|
|
1711
|
+
cause;
|
|
1712
|
+
/** The run's status when the deadline hit, when one was ever observed. */
|
|
1713
|
+
lastStatus;
|
|
1714
|
+
constructor(runId, timeoutSeconds, cause, lastStatus) {
|
|
1715
|
+
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.`;
|
|
1716
|
+
super(
|
|
1717
|
+
`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}` : "")
|
|
1718
|
+
);
|
|
1719
|
+
this.name = "RunTimeoutError";
|
|
1720
|
+
this.runId = runId;
|
|
1721
|
+
this.timeoutSeconds = timeoutSeconds;
|
|
1722
|
+
this.cause = cause;
|
|
1723
|
+
if (lastStatus !== void 0) this.lastStatus = lastStatus;
|
|
1724
|
+
}
|
|
1725
|
+
};
|
|
1726
|
+
var RunPausedError = class extends Error {
|
|
1727
|
+
runId;
|
|
1728
|
+
request;
|
|
1729
|
+
constructor(runId, request, hint) {
|
|
1730
|
+
super(`Run ${runId} is waiting for a human: ${hint}`);
|
|
1731
|
+
this.name = "RunPausedError";
|
|
1732
|
+
this.runId = runId;
|
|
1733
|
+
this.request = request;
|
|
1734
|
+
}
|
|
1735
|
+
};
|
|
1736
|
+
function plan(options) {
|
|
1737
|
+
const interval = options.interval ?? 2;
|
|
1738
|
+
const timeout = options.timeout ?? 300;
|
|
1739
|
+
for (const [name, value] of [["interval", interval], ["timeout", timeout]]) {
|
|
1740
|
+
if (!Number.isFinite(value) || value < 0) {
|
|
1741
|
+
throw new TypeError(
|
|
1742
|
+
`@m8tes/sdk: ${name} must be a finite, non-negative number of seconds (got ${String(value)}).`
|
|
1743
|
+
);
|
|
1744
|
+
}
|
|
1745
|
+
}
|
|
1746
|
+
return { interval, timeout, deadline: now() + timeout * 1e3, signal: options.signal };
|
|
1747
|
+
}
|
|
1748
|
+
function napUntil(interval, deadline, signal) {
|
|
1749
|
+
const remaining = Math.max(0, deadline - now()) / 1e3;
|
|
1750
|
+
return sleep(Math.min(interval, remaining), signal);
|
|
1751
|
+
}
|
|
1752
|
+
async function withDeadline(start, deadline, signal, onExpired) {
|
|
1753
|
+
const remaining = deadline - now();
|
|
1754
|
+
if (remaining <= 0) throw onExpired();
|
|
1755
|
+
const work = start();
|
|
1756
|
+
let timer;
|
|
1757
|
+
let onAbort;
|
|
1758
|
+
try {
|
|
1759
|
+
return await Promise.race([
|
|
1760
|
+
work,
|
|
1761
|
+
new Promise((_, reject2) => {
|
|
1762
|
+
timer = setTimeout(() => reject2(onExpired()), remaining);
|
|
1763
|
+
if (signal) {
|
|
1764
|
+
onAbort = () => reject2(onExpired());
|
|
1765
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
1766
|
+
}
|
|
1767
|
+
})
|
|
1768
|
+
]);
|
|
1769
|
+
} finally {
|
|
1770
|
+
if (timer) clearTimeout(timer);
|
|
1771
|
+
if (signal && onAbort) signal.removeEventListener("abort", onAbort);
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
function sleep(seconds, signal) {
|
|
1775
|
+
if (signal?.aborted) return Promise.resolve();
|
|
1776
|
+
return new Promise((resolve) => {
|
|
1777
|
+
const timer = setTimeout(done, seconds * 1e3);
|
|
1778
|
+
function done() {
|
|
1779
|
+
clearTimeout(timer);
|
|
1780
|
+
signal?.removeEventListener("abort", done);
|
|
1781
|
+
resolve();
|
|
1782
|
+
}
|
|
1783
|
+
signal?.addEventListener("abort", done, { once: true });
|
|
1784
|
+
});
|
|
1785
|
+
}
|
|
1786
|
+
function isPlanApproval(request) {
|
|
1787
|
+
if (request.tool_name !== "AskUserQuestion") return false;
|
|
1788
|
+
const questions = request.tool_input?.questions;
|
|
1789
|
+
return Array.isArray(questions) && questions.some((q) => q?.header === "Plan Approval");
|
|
1790
|
+
}
|
|
1791
|
+
function planText(request) {
|
|
1792
|
+
if (!isPlanApproval(request)) return null;
|
|
1793
|
+
const questions = request.tool_input?.questions;
|
|
1794
|
+
return questions?.find((q) => q?.header === "Plan Approval")?.question ?? null;
|
|
1795
|
+
}
|
|
1796
|
+
var now = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
|
|
1797
|
+
var RunWaitAbortedError = class extends Error {
|
|
1798
|
+
/**
|
|
1799
|
+
* The run being waited on — `undefined` when the abort landed BEFORE any run
|
|
1800
|
+
* was created, which is the one case where there is nothing to go back to.
|
|
1801
|
+
* Previously this path passed a literal 0, producing "Waiting on run 0 was
|
|
1802
|
+
* aborted" and pointing the reader at a run that never existed.
|
|
1803
|
+
*/
|
|
1804
|
+
runId;
|
|
1805
|
+
constructor(runId) {
|
|
1806
|
+
super(
|
|
1807
|
+
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}).`
|
|
1808
|
+
);
|
|
1809
|
+
this.name = "RunWaitAbortedError";
|
|
1810
|
+
if (runId !== void 0) this.runId = runId;
|
|
1811
|
+
}
|
|
1812
|
+
};
|
|
1813
|
+
async function pollRun(deps, runId, options = {}) {
|
|
1814
|
+
const { interval, timeout, deadline, signal } = plan(options);
|
|
1815
|
+
if (signal?.aborted) throw new RunWaitAbortedError(runId);
|
|
1816
|
+
let lastError;
|
|
1817
|
+
let lastStatus;
|
|
1818
|
+
for (; ; ) {
|
|
1819
|
+
let run;
|
|
1820
|
+
try {
|
|
1821
|
+
run = await withDeadline(
|
|
1822
|
+
() => deps.get(runId, signal),
|
|
1823
|
+
deadline,
|
|
1824
|
+
signal,
|
|
1825
|
+
() => signal?.aborted ? new RunWaitAbortedError(runId) : new RunTimeoutError(runId, timeout, lastError, lastStatus)
|
|
1826
|
+
);
|
|
1827
|
+
} catch (err) {
|
|
1828
|
+
if (err instanceof RunTimeoutError || err instanceof RunWaitAbortedError) throw err;
|
|
1829
|
+
if (signal?.aborted) throw new RunWaitAbortedError(runId);
|
|
1830
|
+
if (isPermanent(err)) throw err;
|
|
1831
|
+
lastError = err;
|
|
1832
|
+
if (now() >= deadline) throw new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
1833
|
+
await napUntil(interval, deadline, signal);
|
|
1834
|
+
if (signal?.aborted) throw new RunWaitAbortedError(runId);
|
|
1835
|
+
if (now() >= deadline) throw new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
1836
|
+
continue;
|
|
1837
|
+
}
|
|
1838
|
+
lastStatus = run.status;
|
|
1839
|
+
if (TERMINAL_STATUSES.has(run.status)) return run;
|
|
1840
|
+
if (now() >= deadline) throw new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
1841
|
+
await napUntil(interval, deadline, signal);
|
|
1842
|
+
if (signal?.aborted) throw new RunWaitAbortedError(runId);
|
|
1843
|
+
if (now() >= deadline) throw new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1846
|
+
async function waitForRun(deps, runId, options = {}) {
|
|
1847
|
+
const { interval, timeout, deadline, signal } = plan(options);
|
|
1848
|
+
if (signal?.aborted) throw new RunWaitAbortedError(runId);
|
|
1849
|
+
let lastError;
|
|
1850
|
+
let lastStatus;
|
|
1851
|
+
const answered = /* @__PURE__ */ new Set();
|
|
1852
|
+
for (; ; ) {
|
|
1853
|
+
let run;
|
|
1854
|
+
try {
|
|
1855
|
+
run = await withDeadline(
|
|
1856
|
+
() => deps.get(runId, signal),
|
|
1857
|
+
deadline,
|
|
1858
|
+
signal,
|
|
1859
|
+
() => signal?.aborted ? new RunWaitAbortedError(runId) : new RunTimeoutError(runId, timeout, lastError, lastStatus)
|
|
1860
|
+
);
|
|
1861
|
+
} catch (err) {
|
|
1862
|
+
if (err instanceof RunTimeoutError || err instanceof RunWaitAbortedError) throw err;
|
|
1863
|
+
if (signal?.aborted) throw new RunWaitAbortedError(runId);
|
|
1864
|
+
if (isPermanent(err)) throw err;
|
|
1865
|
+
lastError = err;
|
|
1866
|
+
if (now() >= deadline) throw new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
1867
|
+
await napUntil(interval, deadline, signal);
|
|
1868
|
+
if (signal?.aborted) throw new RunWaitAbortedError(runId);
|
|
1869
|
+
if (now() >= deadline) throw new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
1870
|
+
continue;
|
|
1871
|
+
}
|
|
1872
|
+
lastStatus = run.status;
|
|
1873
|
+
if (TERMINAL_STATUSES.has(run.status)) return run;
|
|
1874
|
+
if (run.status === "awaiting_approval") {
|
|
1875
|
+
const expired = () => signal?.aborted ? new RunWaitAbortedError(runId) : new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
1876
|
+
const bound = (start) => withDeadline(start, deadline, signal, expired);
|
|
1877
|
+
const resolveGate = async (start) => {
|
|
1878
|
+
try {
|
|
1879
|
+
await bound(start);
|
|
1880
|
+
} catch (err) {
|
|
1881
|
+
if (!(err instanceof ConflictError) && !(err instanceof NotFoundError)) throw err;
|
|
1882
|
+
if (!isBenignGateRefusal(err)) throw err;
|
|
1883
|
+
}
|
|
1884
|
+
};
|
|
1885
|
+
const pending = (await bound(() => deps.permissions(runId, signal))).filter(
|
|
1886
|
+
(r) => r.status === "pending" && !answered.has(r.request_id)
|
|
1887
|
+
);
|
|
1888
|
+
for (const request of pending) {
|
|
1889
|
+
answered.add(request.request_id);
|
|
1890
|
+
if (request.tool_name === "AskUserQuestion") {
|
|
1891
|
+
if (!options.onQuestion) {
|
|
1892
|
+
throw new RunPausedError(
|
|
1893
|
+
runId,
|
|
1894
|
+
request,
|
|
1895
|
+
"the agent asked a question. Pass onQuestion to answer it, or call runs.answer() yourself."
|
|
1896
|
+
);
|
|
1897
|
+
}
|
|
1898
|
+
const answers = await bound(async () => options.onQuestion(request));
|
|
1899
|
+
await resolveGate(() => deps.answer(runId, { answers }, signal));
|
|
1900
|
+
} else {
|
|
1901
|
+
if (!options.onApproval) {
|
|
1902
|
+
throw new RunPausedError(
|
|
1903
|
+
runId,
|
|
1904
|
+
request,
|
|
1905
|
+
`the tool "${request.tool_name}" needs a decision. Pass onApproval, or call runs.approve() yourself.`
|
|
1906
|
+
);
|
|
1907
|
+
}
|
|
1908
|
+
const decision = await bound(async () => options.onApproval(request));
|
|
1909
|
+
await resolveGate(() => deps.approve(runId, { request_id: request.request_id, decision }, signal));
|
|
1910
|
+
}
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1913
|
+
if (now() >= deadline) throw new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
1914
|
+
await napUntil(interval, deadline, signal);
|
|
1915
|
+
if (signal?.aborted) throw new RunWaitAbortedError(runId);
|
|
1916
|
+
if (now() >= deadline) throw new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
|
|
1391
1920
|
// src/streaming.ts
|
|
1392
1921
|
var RunStream = class {
|
|
1393
1922
|
source;
|
|
@@ -1466,29 +1995,127 @@ var RunStream = class {
|
|
|
1466
1995
|
};
|
|
1467
1996
|
|
|
1468
1997
|
// src/resources/runs.ts
|
|
1998
|
+
function withRunId(err, runId) {
|
|
1999
|
+
if (err && typeof err === "object" && !("runId" in err)) {
|
|
2000
|
+
Object.defineProperty(err, "runId", { value: runId, enumerable: true, configurable: true });
|
|
2001
|
+
const e = err;
|
|
2002
|
+
if (typeof e.message === "string" && !e.message.includes(String(runId))) {
|
|
2003
|
+
e.message = `${e.message} (while waiting on run ${runId}, which is still executing)`;
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
return err;
|
|
2007
|
+
}
|
|
1469
2008
|
function items(payload) {
|
|
1470
2009
|
return Array.isArray(payload) ? payload : payload?.data ?? [];
|
|
1471
2010
|
}
|
|
2011
|
+
function idempotencyHeaders(key) {
|
|
2012
|
+
return { [IDEMPOTENCY_HEADER]: key ?? crypto.randomUUID() };
|
|
2013
|
+
}
|
|
2014
|
+
function replayJoin(http) {
|
|
2015
|
+
return async function* (run) {
|
|
2016
|
+
if (TERMINAL_STATUSES.has(run.status)) {
|
|
2017
|
+
throw new ConflictError(
|
|
2018
|
+
`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}).`,
|
|
2019
|
+
{
|
|
2020
|
+
type: "invalid_request_error",
|
|
2021
|
+
code: 409,
|
|
2022
|
+
status: 409,
|
|
2023
|
+
details: { error_code: "idempotent_replay_terminal", run_id: run.id, status: run.status }
|
|
2024
|
+
}
|
|
2025
|
+
);
|
|
2026
|
+
}
|
|
2027
|
+
yield* http.stream("GET", `/runs/${seg(run.id)}/stream`);
|
|
2028
|
+
};
|
|
2029
|
+
}
|
|
1472
2030
|
function createRunsResource(http) {
|
|
1473
2031
|
const createBody = (p, stream) => {
|
|
1474
|
-
const { agent_id, teammate_id, ...rest } = p;
|
|
2032
|
+
const { agent_id, teammate_id, files, idempotencyKey, ...rest } = p;
|
|
1475
2033
|
return toBody({ ...rest, teammate_id: resolveAgentId(teammate_id, agent_id), stream });
|
|
1476
2034
|
};
|
|
2035
|
+
const createForm = (p, stream) => {
|
|
2036
|
+
const form = new FormData();
|
|
2037
|
+
form.append("payload", JSON.stringify(createBody(p, stream)));
|
|
2038
|
+
for (const f of p.files ?? []) {
|
|
2039
|
+
const blobType = f.data instanceof Blob && f.data.type ? f.data.type : void 0;
|
|
2040
|
+
const type = f.type ?? blobType ?? mimeTypeForFilename(f.name);
|
|
2041
|
+
if (!type) throw new TypeError(unknownTypeMessage(f.name));
|
|
2042
|
+
const blob = f.data instanceof Blob && f.data.type === type ? f.data : new Blob([f.data], { type });
|
|
2043
|
+
form.append("files", blob, f.name);
|
|
2044
|
+
}
|
|
2045
|
+
return form;
|
|
2046
|
+
};
|
|
2047
|
+
const hasFiles = (p) => (p.files?.length ?? 0) > 0;
|
|
2048
|
+
const pollDeps = (userId) => ({
|
|
2049
|
+
get: (runId, signal) => http.request("GET", `/runs/${seg(runId)}`, {
|
|
2050
|
+
query: toQuery({ user_id: userId }),
|
|
2051
|
+
signal
|
|
2052
|
+
}),
|
|
2053
|
+
permissions: async (runId, signal) => items(await http.request("GET", `/runs/${seg(runId)}/permissions`, { signal })),
|
|
2054
|
+
approve: (runId, params, signal) => http.request("POST", `/runs/${seg(runId)}/approve`, { body: { remember: false, ...params }, signal }),
|
|
2055
|
+
answer: (runId, params, signal) => http.request("POST", `/runs/${seg(runId)}/answer`, { body: params, signal })
|
|
2056
|
+
});
|
|
2057
|
+
const createAsync = async (params) => {
|
|
2058
|
+
const headers = idempotencyHeaders(params.idempotencyKey);
|
|
2059
|
+
return hasFiles(params) ? http.request("POST", "/runs/with-files", { form: createForm(params, false), headers }) : http.request("POST", "/runs", { body: createBody(params, false), headers });
|
|
2060
|
+
};
|
|
1477
2061
|
return {
|
|
1478
2062
|
create(params, options) {
|
|
1479
|
-
|
|
2063
|
+
const headers = idempotencyHeaders(params.idempotencyKey);
|
|
2064
|
+
const init = hasFiles(params) ? { form: createForm(params, true), headers } : { body: createBody(params, true), headers };
|
|
2065
|
+
const path = hasFiles(params) ? "/runs/with-files" : "/runs";
|
|
2066
|
+
return new RunStream(
|
|
2067
|
+
http.stream("POST", path, { ...init, onReplay: replayJoin(http) }),
|
|
2068
|
+
options
|
|
2069
|
+
);
|
|
2070
|
+
},
|
|
2071
|
+
createAsync,
|
|
2072
|
+
async createAndWait(params, options = {}) {
|
|
2073
|
+
if (options.signal?.aborted) throw new RunWaitAbortedError();
|
|
2074
|
+
if (options.user_id != null && params.user_id != null && options.user_id !== params.user_id) {
|
|
2075
|
+
throw new ValidationError(
|
|
2076
|
+
`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.`,
|
|
2077
|
+
{ type: "invalid_request_error", code: 0, status: 0 }
|
|
2078
|
+
);
|
|
2079
|
+
}
|
|
2080
|
+
const createParams = params.user_id == null && options.user_id != null ? { ...params, user_id: options.user_id } : params;
|
|
2081
|
+
const started = await createAsync(createParams);
|
|
2082
|
+
const userId = started.user_id ?? createParams.user_id ?? void 0;
|
|
2083
|
+
try {
|
|
2084
|
+
return await waitForRun(pollDeps(userId), started.id, { ...options, user_id: userId });
|
|
2085
|
+
} catch (err) {
|
|
2086
|
+
throw withRunId(err, started.id);
|
|
2087
|
+
}
|
|
1480
2088
|
},
|
|
1481
|
-
|
|
1482
|
-
return
|
|
2089
|
+
poll(runId, options = {}) {
|
|
2090
|
+
return pollRun(pollDeps(options.user_id), runId, options);
|
|
2091
|
+
},
|
|
2092
|
+
wait(runId, options = {}) {
|
|
2093
|
+
return waitForRun(pollDeps(options.user_id), runId, options);
|
|
2094
|
+
},
|
|
2095
|
+
// `confirm` is a QUERY param and the route takes no body (verified against
|
|
2096
|
+
// fastapi/app/routers/v2/runs.py::retry_run), so send neither.
|
|
2097
|
+
retry(runId, params = {}) {
|
|
2098
|
+
return http.request("POST", `/runs/${seg(runId)}/retry`, {
|
|
2099
|
+
query: params.confirm ? toQuery({ confirm: true }) : ""
|
|
2100
|
+
});
|
|
1483
2101
|
},
|
|
1484
2102
|
stream(runId, options) {
|
|
1485
|
-
return new RunStream(http.stream("GET", `/runs/${runId}/stream`), options);
|
|
2103
|
+
return new RunStream(http.stream("GET", `/runs/${seg(runId)}/stream`), options);
|
|
1486
2104
|
},
|
|
1487
2105
|
reply(runId, message, options) {
|
|
1488
|
-
return new RunStream(
|
|
2106
|
+
return new RunStream(
|
|
2107
|
+
http.stream("POST", `/runs/${seg(runId)}/reply`, {
|
|
2108
|
+
body: { message },
|
|
2109
|
+
headers: idempotencyHeaders(options?.idempotencyKey),
|
|
2110
|
+
onReplay: replayJoin(http)
|
|
2111
|
+
}),
|
|
2112
|
+
options
|
|
2113
|
+
);
|
|
1489
2114
|
},
|
|
1490
|
-
get(runId) {
|
|
1491
|
-
return http.request("GET", `/runs/${runId}
|
|
2115
|
+
get(runId, params = {}) {
|
|
2116
|
+
return http.request("GET", `/runs/${seg(runId)}`, {
|
|
2117
|
+
query: toQuery({ user_id: params.user_id })
|
|
2118
|
+
});
|
|
1492
2119
|
},
|
|
1493
2120
|
async list(params = {}) {
|
|
1494
2121
|
const { agent_id, teammate_id, ...rest } = params;
|
|
@@ -1500,35 +2127,38 @@ function createRunsResource(http) {
|
|
|
1500
2127
|
return new Page(
|
|
1501
2128
|
res?.data ?? [],
|
|
1502
2129
|
res?.has_more ?? false,
|
|
1503
|
-
(starting_after) => fetchPage({ ...p, starting_after })
|
|
2130
|
+
(starting_after) => fetchPage({ ...p, starting_after }),
|
|
2131
|
+
res?.next_starting_after
|
|
1504
2132
|
);
|
|
1505
2133
|
};
|
|
1506
2134
|
return fetchPage(q);
|
|
1507
2135
|
},
|
|
1508
|
-
cancel(runId) {
|
|
1509
|
-
return http.request("POST", `/runs/${runId}/cancel`, {
|
|
2136
|
+
cancel(runId, params = {}) {
|
|
2137
|
+
return http.request("POST", `/runs/${seg(runId)}/cancel`, {
|
|
2138
|
+
query: toQuery({ user_id: params.user_id })
|
|
2139
|
+
});
|
|
1510
2140
|
},
|
|
1511
2141
|
approve(runId, params) {
|
|
1512
|
-
return http.request("POST", `/runs/${runId}/approve`, {
|
|
2142
|
+
return http.request("POST", `/runs/${seg(runId)}/approve`, {
|
|
1513
2143
|
body: { remember: false, ...params }
|
|
1514
2144
|
});
|
|
1515
2145
|
},
|
|
1516
2146
|
answer(runId, params) {
|
|
1517
|
-
return http.request("POST", `/runs/${runId}/answer`, {
|
|
2147
|
+
return http.request("POST", `/runs/${seg(runId)}/answer`, {
|
|
1518
2148
|
body: { answers: params.answers }
|
|
1519
2149
|
});
|
|
1520
2150
|
},
|
|
1521
2151
|
async permissions(runId) {
|
|
1522
|
-
return items(await http.request("GET", `/runs/${runId}/permissions`));
|
|
2152
|
+
return items(await http.request("GET", `/runs/${seg(runId)}/permissions`));
|
|
1523
2153
|
},
|
|
1524
2154
|
outcome(runId) {
|
|
1525
|
-
return http.request("GET", `/runs/${runId}/outcome`);
|
|
2155
|
+
return http.request("GET", `/runs/${seg(runId)}/outcome`);
|
|
1526
2156
|
},
|
|
1527
2157
|
async files(runId) {
|
|
1528
|
-
return items(await http.request("GET", `/runs/${runId}/files`));
|
|
2158
|
+
return items(await http.request("GET", `/runs/${seg(runId)}/files`));
|
|
1529
2159
|
},
|
|
1530
2160
|
async downloadFile(runId, filename) {
|
|
1531
|
-
const res = await http.raw("GET", `/runs/${runId}/files/${
|
|
2161
|
+
const res = await http.raw("GET", `/runs/${seg(runId)}/files/${seg(filename)}/download`, {
|
|
1532
2162
|
headers: { accept: "application/octet-stream" }
|
|
1533
2163
|
});
|
|
1534
2164
|
return res.arrayBuffer();
|
|
@@ -1553,24 +2183,30 @@ function createSettingsResource(http) {
|
|
|
1553
2183
|
function createTasksResource(http) {
|
|
1554
2184
|
const triggers = {
|
|
1555
2185
|
create(taskId, params) {
|
|
1556
|
-
return http.request("POST", `/tasks/${taskId}/triggers/`, {
|
|
1557
|
-
body: toBody({ timezone: "UTC", ...params })
|
|
2186
|
+
return http.request("POST", `/tasks/${seg(taskId)}/triggers/`, {
|
|
2187
|
+
body: toBody({ timezone: "UTC", ...params }),
|
|
2188
|
+
query: toQuery({ user_id: params.user_id })
|
|
1558
2189
|
});
|
|
1559
2190
|
},
|
|
1560
|
-
async list(taskId) {
|
|
2191
|
+
async list(taskId, params = {}) {
|
|
1561
2192
|
const res = await http.request(
|
|
1562
2193
|
"GET",
|
|
1563
|
-
`/tasks/${taskId}/triggers
|
|
2194
|
+
`/tasks/${seg(taskId)}/triggers/`,
|
|
2195
|
+
{ query: toQuery(params) }
|
|
1564
2196
|
);
|
|
1565
2197
|
return Array.isArray(res) ? res : res?.data ?? [];
|
|
1566
2198
|
},
|
|
1567
2199
|
update(taskId, triggerId, params) {
|
|
1568
|
-
|
|
1569
|
-
|
|
2200
|
+
const { user_id, ...patch } = params;
|
|
2201
|
+
return http.request("PATCH", `/tasks/${seg(taskId)}/triggers/${seg(triggerId)}`, {
|
|
2202
|
+
body: toBody(patch),
|
|
2203
|
+
query: toQuery({ user_id })
|
|
1570
2204
|
});
|
|
1571
2205
|
},
|
|
1572
|
-
async delete(taskId, triggerId) {
|
|
1573
|
-
await http.request("DELETE", `/tasks/${taskId}/triggers/${triggerId}
|
|
2206
|
+
async delete(taskId, triggerId, params = {}) {
|
|
2207
|
+
await http.request("DELETE", `/tasks/${seg(taskId)}/triggers/${seg(triggerId)}`, {
|
|
2208
|
+
query: toQuery(params)
|
|
2209
|
+
});
|
|
1574
2210
|
}
|
|
1575
2211
|
};
|
|
1576
2212
|
return {
|
|
@@ -1591,79 +2227,53 @@ function createTasksResource(http) {
|
|
|
1591
2227
|
return new Page(
|
|
1592
2228
|
res?.data ?? [],
|
|
1593
2229
|
res?.has_more ?? false,
|
|
1594
|
-
(starting_after) => fetchPage({ ...p, starting_after })
|
|
2230
|
+
(starting_after) => fetchPage({ ...p, starting_after }),
|
|
2231
|
+
res?.next_starting_after
|
|
1595
2232
|
);
|
|
1596
2233
|
};
|
|
1597
2234
|
return fetchPage(q);
|
|
1598
2235
|
},
|
|
1599
2236
|
get(taskId, params = {}) {
|
|
1600
|
-
return http.request("GET", `/tasks/${taskId}`, { query: toQuery(params) });
|
|
2237
|
+
return http.request("GET", `/tasks/${seg(taskId)}`, { query: toQuery(params) });
|
|
1601
2238
|
},
|
|
1602
2239
|
update(taskId, params) {
|
|
1603
2240
|
const { user_id, ...patch } = params;
|
|
1604
|
-
return http.request("PATCH", `/tasks/${taskId}`, {
|
|
2241
|
+
return http.request("PATCH", `/tasks/${seg(taskId)}`, {
|
|
1605
2242
|
body: toBody(patch),
|
|
1606
2243
|
query: toQuery({ user_id })
|
|
1607
2244
|
});
|
|
1608
2245
|
},
|
|
1609
2246
|
async delete(taskId, params = {}) {
|
|
1610
|
-
await http.request("DELETE", `/tasks/${taskId}`, { query: toQuery(params) });
|
|
2247
|
+
await http.request("DELETE", `/tasks/${seg(taskId)}`, { query: toQuery(params) });
|
|
1611
2248
|
},
|
|
1612
2249
|
run(taskId, params = {}, options) {
|
|
2250
|
+
const { idempotencyKey, ...rest } = params;
|
|
1613
2251
|
return new RunStream(
|
|
1614
|
-
http.stream("POST", `/tasks/${taskId}/runs`, {
|
|
2252
|
+
http.stream("POST", `/tasks/${seg(taskId)}/runs`, {
|
|
2253
|
+
body: toBody({ ...rest, stream: true }),
|
|
2254
|
+
headers: idempotencyHeaders(idempotencyKey),
|
|
2255
|
+
// Shares the create path's replay handling, so a fix on one side can
|
|
2256
|
+
// never silently miss the other.
|
|
2257
|
+
onReplay: replayJoin(http)
|
|
2258
|
+
}),
|
|
1615
2259
|
options
|
|
1616
2260
|
);
|
|
1617
2261
|
},
|
|
1618
2262
|
runAsync(taskId, params = {}) {
|
|
1619
|
-
|
|
1620
|
-
|
|
2263
|
+
const { idempotencyKey, ...rest } = params;
|
|
2264
|
+
return http.request("POST", `/tasks/${seg(taskId)}/runs`, {
|
|
2265
|
+
body: toBody({ ...rest, stream: false }),
|
|
2266
|
+
headers: idempotencyHeaders(idempotencyKey)
|
|
1621
2267
|
});
|
|
1622
2268
|
},
|
|
1623
|
-
enableWebhook(taskId) {
|
|
1624
|
-
return http.request("POST", `/tasks/${taskId}/webhook`, {
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
await http.request("DELETE", `/tasks/${taskId}/webhook`);
|
|
1628
|
-
}
|
|
1629
|
-
};
|
|
1630
|
-
}
|
|
1631
|
-
|
|
1632
|
-
// src/resources/users.ts
|
|
1633
|
-
function pager(http, path) {
|
|
1634
|
-
const fetchPage = async (p) => {
|
|
1635
|
-
const res = await http.request("GET", path, {
|
|
1636
|
-
query: toQuery(p)
|
|
1637
|
-
});
|
|
1638
|
-
return new Page(
|
|
1639
|
-
res?.data ?? [],
|
|
1640
|
-
res?.has_more ?? false,
|
|
1641
|
-
(starting_after) => fetchPage({ ...p, starting_after })
|
|
1642
|
-
);
|
|
1643
|
-
};
|
|
1644
|
-
return fetchPage;
|
|
1645
|
-
}
|
|
1646
|
-
function createUsersResource(http) {
|
|
1647
|
-
return {
|
|
1648
|
-
create(params) {
|
|
1649
|
-
return http.request("POST", "/users/", { body: toBody({ ...params }) });
|
|
1650
|
-
},
|
|
1651
|
-
list(params = {}) {
|
|
1652
|
-
return pager(http, "/users/")({ ...params });
|
|
1653
|
-
},
|
|
1654
|
-
get(userId) {
|
|
1655
|
-
return http.request("GET", `/users/${encodeURIComponent(userId)}`);
|
|
1656
|
-
},
|
|
1657
|
-
update(userId, params) {
|
|
1658
|
-
return http.request("PATCH", `/users/${encodeURIComponent(userId)}`, {
|
|
1659
|
-
body: toBody({ ...params })
|
|
2269
|
+
enableWebhook(taskId, params = {}) {
|
|
2270
|
+
return http.request("POST", `/tasks/${seg(taskId)}/webhook`, {
|
|
2271
|
+
body: {},
|
|
2272
|
+
query: toQuery(params)
|
|
1660
2273
|
});
|
|
1661
2274
|
},
|
|
1662
|
-
async
|
|
1663
|
-
await http.request("DELETE", `/
|
|
1664
|
-
},
|
|
1665
|
-
usage(params = {}) {
|
|
1666
|
-
return pager(http, "/usage/end-users")({ ...params });
|
|
2275
|
+
async disableWebhook(taskId, params = {}) {
|
|
2276
|
+
await http.request("DELETE", `/tasks/${seg(taskId)}/webhook`, { query: toQuery(params) });
|
|
1667
2277
|
}
|
|
1668
2278
|
};
|
|
1669
2279
|
}
|
|
@@ -1687,14 +2297,14 @@ function verifySignature(body, headers, secret, options = {}) {
|
|
|
1687
2297
|
if (options.toleranceSeconds !== void 0) {
|
|
1688
2298
|
const ts = Number.parseInt(timestamp, 10);
|
|
1689
2299
|
if (!Number.isFinite(ts)) return false;
|
|
1690
|
-
const
|
|
1691
|
-
if (Math.abs(
|
|
2300
|
+
const now2 = options.now ? options.now() : Math.floor(Date.now() / 1e3);
|
|
2301
|
+
if (Math.abs(now2 - ts) > options.toleranceSeconds) return false;
|
|
1692
2302
|
}
|
|
1693
2303
|
const raw = typeof body === "string" ? body : new TextDecoder().decode(body);
|
|
1694
|
-
const expected = `v1=${crypto.createHmac("sha256", secret).update(`${webhookId}.${timestamp}.${raw}`).digest("hex")}`;
|
|
2304
|
+
const expected = `v1=${crypto$1.createHmac("sha256", secret).update(`${webhookId}.${timestamp}.${raw}`).digest("hex")}`;
|
|
1695
2305
|
const a = Buffer.from(expected);
|
|
1696
2306
|
const b = Buffer.from(signature);
|
|
1697
|
-
return a.length === b.length && crypto.timingSafeEqual(a, b);
|
|
2307
|
+
return a.length === b.length && crypto$1.timingSafeEqual(a, b);
|
|
1698
2308
|
}
|
|
1699
2309
|
function createWebhooksResource(http) {
|
|
1700
2310
|
return {
|
|
@@ -1706,22 +2316,22 @@ function createWebhooksResource(http) {
|
|
|
1706
2316
|
return pager(http, "/webhooks/")({ ...params });
|
|
1707
2317
|
},
|
|
1708
2318
|
get(webhookId) {
|
|
1709
|
-
return http.request("GET", `/webhooks/${webhookId}`);
|
|
2319
|
+
return http.request("GET", `/webhooks/${seg(webhookId)}`);
|
|
1710
2320
|
},
|
|
1711
2321
|
update(webhookId, params) {
|
|
1712
|
-
return http.request("PATCH", `/webhooks/${webhookId}`, { body: toBody({ ...params }) });
|
|
2322
|
+
return http.request("PATCH", `/webhooks/${seg(webhookId)}`, { body: toBody({ ...params }) });
|
|
1713
2323
|
},
|
|
1714
2324
|
async delete(webhookId) {
|
|
1715
|
-
await http.request("DELETE", `/webhooks/${webhookId}`);
|
|
2325
|
+
await http.request("DELETE", `/webhooks/${seg(webhookId)}`);
|
|
1716
2326
|
},
|
|
1717
2327
|
listDeliveries(webhookId, params = {}) {
|
|
1718
|
-
return pager(http, `/webhooks/${webhookId}/deliveries`)({ ...params });
|
|
2328
|
+
return pager(http, `/webhooks/${seg(webhookId)}/deliveries`)({ ...params });
|
|
1719
2329
|
}
|
|
1720
2330
|
};
|
|
1721
2331
|
}
|
|
1722
2332
|
|
|
1723
2333
|
// src/index.ts
|
|
1724
|
-
var M8TES_SDK_VERSION = "0.1.0-alpha.
|
|
2334
|
+
var M8TES_SDK_VERSION = "0.1.0-alpha.3";
|
|
1725
2335
|
var M8tes = class {
|
|
1726
2336
|
runs;
|
|
1727
2337
|
agents;
|
|
@@ -1732,6 +2342,12 @@ var M8tes = class {
|
|
|
1732
2342
|
apps;
|
|
1733
2343
|
webhooks;
|
|
1734
2344
|
settings;
|
|
2345
|
+
memories;
|
|
2346
|
+
permissions;
|
|
2347
|
+
models;
|
|
2348
|
+
modelConnections;
|
|
2349
|
+
billing;
|
|
2350
|
+
account;
|
|
1735
2351
|
/** The underlying transport. Use it to call an endpoint this version does not wrap yet. */
|
|
1736
2352
|
http;
|
|
1737
2353
|
constructor(options = {}) {
|
|
@@ -1744,6 +2360,12 @@ var M8tes = class {
|
|
|
1744
2360
|
this.apps = createAppsResource(this.http);
|
|
1745
2361
|
this.webhooks = createWebhooksResource(this.http);
|
|
1746
2362
|
this.settings = createSettingsResource(this.http);
|
|
2363
|
+
this.memories = createMemoriesResource(this.http);
|
|
2364
|
+
this.permissions = createPermissionsResource(this.http);
|
|
2365
|
+
this.models = createModelsResource(this.http);
|
|
2366
|
+
this.modelConnections = createModelConnectionsResource(this.http);
|
|
2367
|
+
this.billing = createBillingResource(this.http);
|
|
2368
|
+
this.account = createAccountResource(this.http);
|
|
1747
2369
|
}
|
|
1748
2370
|
};
|
|
1749
2371
|
|
|
@@ -1762,8 +2384,12 @@ exports.PermissionDeniedError = PermissionDeniedError;
|
|
|
1762
2384
|
exports.RateLimitError = RateLimitError;
|
|
1763
2385
|
exports.RunFailedError = RunFailedError;
|
|
1764
2386
|
exports.RunNotStreamingError = RunNotStreamingError;
|
|
2387
|
+
exports.RunPausedError = RunPausedError;
|
|
1765
2388
|
exports.RunStream = RunStream;
|
|
2389
|
+
exports.RunTimeoutError = RunTimeoutError;
|
|
2390
|
+
exports.RunWaitAbortedError = RunWaitAbortedError;
|
|
1766
2391
|
exports.TERMINAL_EVENT_TYPES = TERMINAL_EVENT_TYPES;
|
|
2392
|
+
exports.TERMINAL_STATUSES = TERMINAL_STATUSES;
|
|
1767
2393
|
exports.ValidationError = ValidationError;
|
|
1768
2394
|
exports.accumulate = accumulate;
|
|
1769
2395
|
exports.createAccumulator = createAccumulator;
|
|
@@ -1773,11 +2399,16 @@ exports.createSseDecoder = createSseDecoder;
|
|
|
1773
2399
|
exports.errorClassForStatus = errorClassForStatus;
|
|
1774
2400
|
exports.errorFromResponse = errorFromResponse;
|
|
1775
2401
|
exports.initialConversationState = initialConversationState;
|
|
2402
|
+
exports.isPlanApproval = isPlanApproval;
|
|
1776
2403
|
exports.isTerminalEvent = isTerminalEvent;
|
|
1777
2404
|
exports.parseErrorEnvelope = parseErrorEnvelope;
|
|
1778
2405
|
exports.parseRetryAfter = parseRetryAfter;
|
|
1779
2406
|
exports.parseSse = parseSse;
|
|
2407
|
+
exports.planText = planText;
|
|
2408
|
+
exports.pollRun = pollRun;
|
|
2409
|
+
exports.seg = seg;
|
|
1780
2410
|
exports.splitConcatenatedJson = splitConcatenatedJson;
|
|
1781
2411
|
exports.verifySignature = verifySignature;
|
|
2412
|
+
exports.waitForRun = waitForRun;
|
|
1782
2413
|
//# sourceMappingURL=index.cjs.map
|
|
1783
2414
|
//# sourceMappingURL=index.cjs.map
|