@m8tes/sdk 0.1.0-alpha.1 → 0.1.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +173 -0
- 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 +717 -110
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +832 -72
- package/dist/index.d.ts +832 -72
- package/dist/index.js +685 -110
- 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 });
|
|
@@ -1326,68 +1379,537 @@ function createAgentsResource(http) {
|
|
|
1326
1379
|
return fetchPage({ ...params });
|
|
1327
1380
|
},
|
|
1328
1381
|
get(agentId, params = {}) {
|
|
1329
|
-
return http.request("GET", `/agents/${agentId}`, { query: toQuery(params) });
|
|
1382
|
+
return http.request("GET", `/agents/${seg(agentId)}`, { query: toQuery(params) });
|
|
1330
1383
|
},
|
|
1331
1384
|
update(agentId, params) {
|
|
1332
1385
|
const { user_id, ...patch } = params;
|
|
1333
|
-
return http.request("PATCH", `/agents/${agentId}`, {
|
|
1386
|
+
return http.request("PATCH", `/agents/${seg(agentId)}`, {
|
|
1334
1387
|
body: toBody(patch),
|
|
1335
1388
|
query: toQuery({ user_id })
|
|
1336
1389
|
});
|
|
1337
1390
|
},
|
|
1338
1391
|
async delete(agentId, params = {}) {
|
|
1339
|
-
await http.request("DELETE", `/agents/${agentId}`, { query: toQuery(params) });
|
|
1392
|
+
await http.request("DELETE", `/agents/${seg(agentId)}`, { query: toQuery(params) });
|
|
1340
1393
|
},
|
|
1341
|
-
enableWebhook(agentId) {
|
|
1342
|
-
return http.request("POST", `/agents/${agentId}/webhook`, {
|
|
1394
|
+
enableWebhook(agentId, params = {}) {
|
|
1395
|
+
return http.request("POST", `/agents/${seg(agentId)}/webhook`, {
|
|
1396
|
+
body: {},
|
|
1397
|
+
query: toQuery(params)
|
|
1398
|
+
});
|
|
1343
1399
|
},
|
|
1344
|
-
async disableWebhook(agentId) {
|
|
1345
|
-
await http.request("DELETE", `/agents/${agentId}/webhook
|
|
1400
|
+
async disableWebhook(agentId, params = {}) {
|
|
1401
|
+
await http.request("DELETE", `/agents/${seg(agentId)}/webhook`, { query: toQuery(params) });
|
|
1346
1402
|
},
|
|
1347
|
-
enableEmailInbox(agentId) {
|
|
1348
|
-
return http.request("POST", `/agents/${agentId}/email-inbox`, {
|
|
1403
|
+
enableEmailInbox(agentId, params = {}) {
|
|
1404
|
+
return http.request("POST", `/agents/${seg(agentId)}/email-inbox`, {
|
|
1405
|
+
body: {},
|
|
1406
|
+
query: toQuery(params)
|
|
1407
|
+
});
|
|
1349
1408
|
},
|
|
1350
|
-
async disableEmailInbox(agentId) {
|
|
1351
|
-
await http.request("DELETE", `/agents/${agentId}/email-inbox
|
|
1409
|
+
async disableEmailInbox(agentId, params = {}) {
|
|
1410
|
+
await http.request("DELETE", `/agents/${seg(agentId)}/email-inbox`, { query: toQuery(params) });
|
|
1352
1411
|
}
|
|
1353
1412
|
};
|
|
1354
1413
|
}
|
|
1355
1414
|
|
|
1356
1415
|
// src/resources/apps.ts
|
|
1357
1416
|
function createAppsResource(http) {
|
|
1358
|
-
const
|
|
1417
|
+
const list = async (params = {}) => {
|
|
1418
|
+
const res = await http.request("GET", "/apps/", {
|
|
1419
|
+
query: toQuery({ user_id: params.user_id })
|
|
1420
|
+
});
|
|
1421
|
+
return new Page(res?.data ?? [], res?.has_more ?? false);
|
|
1422
|
+
};
|
|
1359
1423
|
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
|
-
},
|
|
1424
|
+
list,
|
|
1366
1425
|
async isConnected(appName, params = {}) {
|
|
1367
|
-
const { data } = await
|
|
1426
|
+
const { data } = await list(params);
|
|
1368
1427
|
return data.find((a) => a.name === appName)?.connected ?? false;
|
|
1369
1428
|
},
|
|
1370
1429
|
connectOauth(appName, params) {
|
|
1371
|
-
return http.request("POST", `/apps/${
|
|
1430
|
+
return http.request("POST", `/apps/${seg(appName)}/connect`, {
|
|
1372
1431
|
body: toBody({ ...params })
|
|
1373
1432
|
});
|
|
1374
1433
|
},
|
|
1375
1434
|
connectApiKey(appName, params) {
|
|
1376
|
-
return http.request("POST", `/apps/${
|
|
1435
|
+
return http.request("POST", `/apps/${seg(appName)}/connect/api-key`, {
|
|
1377
1436
|
body: toBody({ ...params })
|
|
1378
1437
|
});
|
|
1379
1438
|
},
|
|
1380
1439
|
connectComplete(appName, params) {
|
|
1381
|
-
return http.request("POST", `/apps/${
|
|
1440
|
+
return http.request("POST", `/apps/${seg(appName)}/connect/complete`, {
|
|
1382
1441
|
body: toBody({ ...params })
|
|
1383
1442
|
});
|
|
1384
1443
|
},
|
|
1385
1444
|
async disconnect(appName, params = {}) {
|
|
1386
|
-
await http.request("DELETE", `/apps/${
|
|
1445
|
+
await http.request("DELETE", `/apps/${seg(appName)}/connections`, { query: toQuery(params) });
|
|
1446
|
+
}
|
|
1447
|
+
};
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1450
|
+
// src/resources/account.ts
|
|
1451
|
+
function createAccountResource(http) {
|
|
1452
|
+
return {
|
|
1453
|
+
export() {
|
|
1454
|
+
return http.request("GET", "/account/export");
|
|
1455
|
+
},
|
|
1456
|
+
delete() {
|
|
1457
|
+
return http.request("DELETE", "/account");
|
|
1458
|
+
}
|
|
1459
|
+
};
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
// src/resources/users.ts
|
|
1463
|
+
function pager(http, path) {
|
|
1464
|
+
const fetchPage = async (p) => {
|
|
1465
|
+
const res = await http.request("GET", path, {
|
|
1466
|
+
query: toQuery(p)
|
|
1467
|
+
});
|
|
1468
|
+
return new Page(
|
|
1469
|
+
res?.data ?? [],
|
|
1470
|
+
res?.has_more ?? false,
|
|
1471
|
+
(starting_after) => fetchPage({ ...p, starting_after })
|
|
1472
|
+
);
|
|
1473
|
+
};
|
|
1474
|
+
return fetchPage;
|
|
1475
|
+
}
|
|
1476
|
+
function createUsersResource(http) {
|
|
1477
|
+
return {
|
|
1478
|
+
create(params) {
|
|
1479
|
+
return http.request("POST", "/users/", { body: toBody({ ...params }) });
|
|
1480
|
+
},
|
|
1481
|
+
list(params = {}) {
|
|
1482
|
+
return pager(http, "/users/")({ ...params });
|
|
1483
|
+
},
|
|
1484
|
+
get(userId) {
|
|
1485
|
+
return http.request("GET", `/users/${seg(userId)}`);
|
|
1486
|
+
},
|
|
1487
|
+
update(userId, params) {
|
|
1488
|
+
return http.request("PATCH", `/users/${seg(userId)}`, {
|
|
1489
|
+
body: toBody({ ...params })
|
|
1490
|
+
});
|
|
1491
|
+
},
|
|
1492
|
+
async delete(userId) {
|
|
1493
|
+
await http.request("DELETE", `/users/${seg(userId)}`);
|
|
1494
|
+
},
|
|
1495
|
+
usage(params = {}) {
|
|
1496
|
+
return pager(http, "/usage/end-users")({ ...params });
|
|
1497
|
+
}
|
|
1498
|
+
};
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
// src/resources/billing.ts
|
|
1502
|
+
function createBillingResource(http) {
|
|
1503
|
+
return {
|
|
1504
|
+
usage() {
|
|
1505
|
+
return http.request("GET", "/usage/");
|
|
1506
|
+
},
|
|
1507
|
+
usageTimeseries(params = {}) {
|
|
1508
|
+
const { agent_id, teammate_id, ...rest } = params;
|
|
1509
|
+
const query = toQuery(
|
|
1510
|
+
toBody({ ...rest, teammate_id: resolveAgentId(teammate_id, agent_id) })
|
|
1511
|
+
);
|
|
1512
|
+
return http.request("GET", "/usage/timeseries", { query });
|
|
1513
|
+
},
|
|
1514
|
+
receipts(params = {}) {
|
|
1515
|
+
return pager(http, "/billing/receipts")({ ...params });
|
|
1516
|
+
},
|
|
1517
|
+
plans() {
|
|
1518
|
+
return http.request("GET", "/billing/plans");
|
|
1519
|
+
},
|
|
1520
|
+
setOverage(params) {
|
|
1521
|
+
return http.request("PATCH", "/billing/overage", { body: toBody({ ...params }) });
|
|
1522
|
+
},
|
|
1523
|
+
balance() {
|
|
1524
|
+
return http.request("GET", "/billing/balance");
|
|
1525
|
+
},
|
|
1526
|
+
async topup(params) {
|
|
1527
|
+
const res = await http.request("POST", "/billing/topup", {
|
|
1528
|
+
body: toBody({ ...params })
|
|
1529
|
+
});
|
|
1530
|
+
return res.checkout_url;
|
|
1531
|
+
},
|
|
1532
|
+
setAutoReload(params) {
|
|
1533
|
+
return http.request("PATCH", "/billing/auto-reload", {
|
|
1534
|
+
body: toBody({ ...params })
|
|
1535
|
+
});
|
|
1536
|
+
},
|
|
1537
|
+
setAlertThreshold(params) {
|
|
1538
|
+
return http.request("PATCH", "/billing/alert-settings", {
|
|
1539
|
+
body: toBody({ ...params })
|
|
1540
|
+
});
|
|
1541
|
+
}
|
|
1542
|
+
};
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
// src/resources/memories.ts
|
|
1546
|
+
function createMemoriesResource(http) {
|
|
1547
|
+
return {
|
|
1548
|
+
create(params) {
|
|
1549
|
+
return http.request("POST", "/memories/", { body: toBody({ ...params }) });
|
|
1550
|
+
},
|
|
1551
|
+
list(params = {}) {
|
|
1552
|
+
return pager(http, "/memories/")({ ...params });
|
|
1553
|
+
},
|
|
1554
|
+
update(memoryId, { user_id, content }) {
|
|
1555
|
+
return http.request("PATCH", `/memories/${seg(memoryId)}`, {
|
|
1556
|
+
query: toQuery({ user_id }),
|
|
1557
|
+
body: toBody({ content })
|
|
1558
|
+
});
|
|
1559
|
+
},
|
|
1560
|
+
async delete(memoryId, params = {}) {
|
|
1561
|
+
await http.request("DELETE", `/memories/${seg(memoryId)}`, {
|
|
1562
|
+
query: toQuery({ user_id: params.user_id })
|
|
1563
|
+
});
|
|
1564
|
+
}
|
|
1565
|
+
};
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1568
|
+
// src/resources/models.ts
|
|
1569
|
+
function createModelsResource(http) {
|
|
1570
|
+
return {
|
|
1571
|
+
async list() {
|
|
1572
|
+
const res = await http.request("GET", "/models/");
|
|
1573
|
+
return new Page(res?.data ?? [], res?.has_more ?? false);
|
|
1574
|
+
}
|
|
1575
|
+
};
|
|
1576
|
+
}
|
|
1577
|
+
|
|
1578
|
+
// src/resources/model-connections.ts
|
|
1579
|
+
function createModelConnectionsResource(http) {
|
|
1580
|
+
return {
|
|
1581
|
+
async list() {
|
|
1582
|
+
const res = await http.request("GET", "/model-connections/");
|
|
1583
|
+
return res?.data ?? [];
|
|
1584
|
+
},
|
|
1585
|
+
authorize(provider) {
|
|
1586
|
+
return http.request(
|
|
1587
|
+
"POST",
|
|
1588
|
+
`/model-connections/${seg(provider)}/authorizations`
|
|
1589
|
+
);
|
|
1590
|
+
},
|
|
1591
|
+
authorizationStatus(provider, state) {
|
|
1592
|
+
return http.request(
|
|
1593
|
+
"GET",
|
|
1594
|
+
`/model-connections/${seg(provider)}/authorizations/${seg(state)}`
|
|
1595
|
+
);
|
|
1596
|
+
},
|
|
1597
|
+
completeAuthorization(provider, state, params) {
|
|
1598
|
+
return http.request(
|
|
1599
|
+
"POST",
|
|
1600
|
+
`/model-connections/${seg(provider)}/authorizations/${seg(state)}`,
|
|
1601
|
+
{ body: { code: params.code } }
|
|
1602
|
+
);
|
|
1603
|
+
},
|
|
1604
|
+
async cancelAuthorization(provider, state) {
|
|
1605
|
+
await http.request("DELETE", `/model-connections/${seg(provider)}/authorizations/${seg(state)}`);
|
|
1606
|
+
},
|
|
1607
|
+
disconnect(provider) {
|
|
1608
|
+
return http.request("DELETE", `/model-connections/${seg(provider)}`);
|
|
1609
|
+
}
|
|
1610
|
+
};
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
// src/resources/permissions.ts
|
|
1614
|
+
function createPermissionsResource(http) {
|
|
1615
|
+
return {
|
|
1616
|
+
create(params) {
|
|
1617
|
+
return http.request("POST", "/permissions/", {
|
|
1618
|
+
body: toBody({ ...params })
|
|
1619
|
+
});
|
|
1620
|
+
},
|
|
1621
|
+
list(params) {
|
|
1622
|
+
return pager(http, "/permissions/")({ ...params });
|
|
1623
|
+
},
|
|
1624
|
+
async delete(permissionId, params) {
|
|
1625
|
+
await http.request("DELETE", `/permissions/${seg(permissionId)}`, {
|
|
1626
|
+
query: toQuery({ user_id: params.user_id })
|
|
1627
|
+
});
|
|
1387
1628
|
}
|
|
1388
1629
|
};
|
|
1389
1630
|
}
|
|
1390
1631
|
|
|
1632
|
+
// src/mime.ts
|
|
1633
|
+
var EXTENSION_TYPES = Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
1634
|
+
// Images (the agent can actually see these via its Read tool)
|
|
1635
|
+
jpg: "image/jpeg",
|
|
1636
|
+
jpeg: "image/jpeg",
|
|
1637
|
+
png: "image/png",
|
|
1638
|
+
gif: "image/gif",
|
|
1639
|
+
webp: "image/webp",
|
|
1640
|
+
// Documents
|
|
1641
|
+
pdf: "application/pdf",
|
|
1642
|
+
txt: "text/plain",
|
|
1643
|
+
md: "text/markdown",
|
|
1644
|
+
markdown: "text/markdown",
|
|
1645
|
+
html: "text/html",
|
|
1646
|
+
htm: "text/html",
|
|
1647
|
+
// Code
|
|
1648
|
+
py: "text/x-python",
|
|
1649
|
+
js: "application/javascript",
|
|
1650
|
+
mjs: "application/javascript",
|
|
1651
|
+
cjs: "application/javascript",
|
|
1652
|
+
json: "application/json",
|
|
1653
|
+
ts: "text/typescript",
|
|
1654
|
+
tsx: "text/typescript",
|
|
1655
|
+
css: "text/css",
|
|
1656
|
+
c: "text/x-c",
|
|
1657
|
+
h: "text/x-c",
|
|
1658
|
+
java: "text/x-java-source",
|
|
1659
|
+
go: "text/x-go",
|
|
1660
|
+
sql: "application/sql",
|
|
1661
|
+
// Data / config
|
|
1662
|
+
csv: "text/csv",
|
|
1663
|
+
tsv: "text/csv",
|
|
1664
|
+
xml: "application/xml",
|
|
1665
|
+
yaml: "text/yaml",
|
|
1666
|
+
yml: "text/yaml",
|
|
1667
|
+
// Archives
|
|
1668
|
+
zip: "application/zip",
|
|
1669
|
+
gz: "application/gzip",
|
|
1670
|
+
tgz: "application/gzip",
|
|
1671
|
+
tar: "application/x-tar",
|
|
1672
|
+
// Office
|
|
1673
|
+
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
1674
|
+
xls: "application/vnd.ms-excel",
|
|
1675
|
+
docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
1676
|
+
pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
1677
|
+
ppt: "application/vnd.ms-powerpoint"
|
|
1678
|
+
});
|
|
1679
|
+
var UPLOADABLE_EXTENSIONS = Object.keys(EXTENSION_TYPES);
|
|
1680
|
+
function mimeTypeForFilename(name) {
|
|
1681
|
+
const ext = name.includes(".") ? name.slice(name.lastIndexOf(".") + 1).toLowerCase() : "";
|
|
1682
|
+
return EXTENSION_TYPES[ext];
|
|
1683
|
+
}
|
|
1684
|
+
function unknownTypeMessage(name) {
|
|
1685
|
+
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(", ")}, ...).`;
|
|
1686
|
+
}
|
|
1687
|
+
|
|
1688
|
+
// src/polling.ts
|
|
1689
|
+
function isPermanent(err) {
|
|
1690
|
+
return err instanceof AuthenticationError || err instanceof PermissionDeniedError || err instanceof NotFoundError || err instanceof ValidationError;
|
|
1691
|
+
}
|
|
1692
|
+
var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled", "closed"]);
|
|
1693
|
+
var BENIGN_GATE_REFUSAL_CODES = /* @__PURE__ */ new Set(["gate_cancelled", "run_not_active"]);
|
|
1694
|
+
var AUTO_CONTINUED_MESSAGE = "auto_continued";
|
|
1695
|
+
function isBenignGateRefusal(err) {
|
|
1696
|
+
if (err.errorCode !== void 0) return BENIGN_GATE_REFUSAL_CODES.has(err.errorCode);
|
|
1697
|
+
return err instanceof ConflictError && err.message === AUTO_CONTINUED_MESSAGE;
|
|
1698
|
+
}
|
|
1699
|
+
var RunTimeoutError = class extends Error {
|
|
1700
|
+
runId;
|
|
1701
|
+
timeoutSeconds;
|
|
1702
|
+
/** The last error seen while polling, if any. Without it a timeout hides the
|
|
1703
|
+
* transient failure that actually caused it. */
|
|
1704
|
+
cause;
|
|
1705
|
+
/** The run's status when the deadline hit, when one was ever observed. */
|
|
1706
|
+
lastStatus;
|
|
1707
|
+
constructor(runId, timeoutSeconds, cause, lastStatus) {
|
|
1708
|
+
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.`;
|
|
1709
|
+
super(
|
|
1710
|
+
`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}` : "")
|
|
1711
|
+
);
|
|
1712
|
+
this.name = "RunTimeoutError";
|
|
1713
|
+
this.runId = runId;
|
|
1714
|
+
this.timeoutSeconds = timeoutSeconds;
|
|
1715
|
+
this.cause = cause;
|
|
1716
|
+
if (lastStatus !== void 0) this.lastStatus = lastStatus;
|
|
1717
|
+
}
|
|
1718
|
+
};
|
|
1719
|
+
var RunPausedError = class extends Error {
|
|
1720
|
+
runId;
|
|
1721
|
+
request;
|
|
1722
|
+
constructor(runId, request, hint) {
|
|
1723
|
+
super(`Run ${runId} is waiting for a human: ${hint}`);
|
|
1724
|
+
this.name = "RunPausedError";
|
|
1725
|
+
this.runId = runId;
|
|
1726
|
+
this.request = request;
|
|
1727
|
+
}
|
|
1728
|
+
};
|
|
1729
|
+
function plan(options) {
|
|
1730
|
+
const interval = options.interval ?? 2;
|
|
1731
|
+
const timeout = options.timeout ?? 300;
|
|
1732
|
+
for (const [name, value] of [["interval", interval], ["timeout", timeout]]) {
|
|
1733
|
+
if (!Number.isFinite(value) || value < 0) {
|
|
1734
|
+
throw new TypeError(
|
|
1735
|
+
`@m8tes/sdk: ${name} must be a finite, non-negative number of seconds (got ${String(value)}).`
|
|
1736
|
+
);
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
return { interval, timeout, deadline: now() + timeout * 1e3, signal: options.signal };
|
|
1740
|
+
}
|
|
1741
|
+
function napUntil(interval, deadline, signal) {
|
|
1742
|
+
const remaining = Math.max(0, deadline - now()) / 1e3;
|
|
1743
|
+
return sleep(Math.min(interval, remaining), signal);
|
|
1744
|
+
}
|
|
1745
|
+
async function withDeadline(start, deadline, signal, onExpired) {
|
|
1746
|
+
const remaining = deadline - now();
|
|
1747
|
+
if (remaining <= 0) throw onExpired();
|
|
1748
|
+
const work = start();
|
|
1749
|
+
let timer;
|
|
1750
|
+
let onAbort;
|
|
1751
|
+
try {
|
|
1752
|
+
return await Promise.race([
|
|
1753
|
+
work,
|
|
1754
|
+
new Promise((_, reject2) => {
|
|
1755
|
+
timer = setTimeout(() => reject2(onExpired()), remaining);
|
|
1756
|
+
if (signal) {
|
|
1757
|
+
onAbort = () => reject2(onExpired());
|
|
1758
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
1759
|
+
}
|
|
1760
|
+
})
|
|
1761
|
+
]);
|
|
1762
|
+
} finally {
|
|
1763
|
+
if (timer) clearTimeout(timer);
|
|
1764
|
+
if (signal && onAbort) signal.removeEventListener("abort", onAbort);
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
function sleep(seconds, signal) {
|
|
1768
|
+
if (signal?.aborted) return Promise.resolve();
|
|
1769
|
+
return new Promise((resolve) => {
|
|
1770
|
+
const timer = setTimeout(done, seconds * 1e3);
|
|
1771
|
+
function done() {
|
|
1772
|
+
clearTimeout(timer);
|
|
1773
|
+
signal?.removeEventListener("abort", done);
|
|
1774
|
+
resolve();
|
|
1775
|
+
}
|
|
1776
|
+
signal?.addEventListener("abort", done, { once: true });
|
|
1777
|
+
});
|
|
1778
|
+
}
|
|
1779
|
+
function isPlanApproval(request) {
|
|
1780
|
+
if (request.tool_name !== "AskUserQuestion") return false;
|
|
1781
|
+
const questions = request.tool_input?.questions;
|
|
1782
|
+
return Array.isArray(questions) && questions.some((q) => q?.header === "Plan Approval");
|
|
1783
|
+
}
|
|
1784
|
+
function planText(request) {
|
|
1785
|
+
if (!isPlanApproval(request)) return null;
|
|
1786
|
+
const questions = request.tool_input?.questions;
|
|
1787
|
+
return questions?.find((q) => q?.header === "Plan Approval")?.question ?? null;
|
|
1788
|
+
}
|
|
1789
|
+
var now = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
|
|
1790
|
+
var RunWaitAbortedError = class extends Error {
|
|
1791
|
+
/**
|
|
1792
|
+
* The run being waited on — `undefined` when the abort landed BEFORE any run
|
|
1793
|
+
* was created, which is the one case where there is nothing to go back to.
|
|
1794
|
+
* Previously this path passed a literal 0, producing "Waiting on run 0 was
|
|
1795
|
+
* aborted" and pointing the reader at a run that never existed.
|
|
1796
|
+
*/
|
|
1797
|
+
runId;
|
|
1798
|
+
constructor(runId) {
|
|
1799
|
+
super(
|
|
1800
|
+
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}).`
|
|
1801
|
+
);
|
|
1802
|
+
this.name = "RunWaitAbortedError";
|
|
1803
|
+
if (runId !== void 0) this.runId = runId;
|
|
1804
|
+
}
|
|
1805
|
+
};
|
|
1806
|
+
async function pollRun(deps, runId, options = {}) {
|
|
1807
|
+
const { interval, timeout, deadline, signal } = plan(options);
|
|
1808
|
+
if (signal?.aborted) throw new RunWaitAbortedError(runId);
|
|
1809
|
+
let lastError;
|
|
1810
|
+
let lastStatus;
|
|
1811
|
+
for (; ; ) {
|
|
1812
|
+
let run;
|
|
1813
|
+
try {
|
|
1814
|
+
run = await withDeadline(
|
|
1815
|
+
() => deps.get(runId, signal),
|
|
1816
|
+
deadline,
|
|
1817
|
+
signal,
|
|
1818
|
+
() => signal?.aborted ? new RunWaitAbortedError(runId) : new RunTimeoutError(runId, timeout, lastError, lastStatus)
|
|
1819
|
+
);
|
|
1820
|
+
} catch (err) {
|
|
1821
|
+
if (err instanceof RunTimeoutError || err instanceof RunWaitAbortedError) throw err;
|
|
1822
|
+
if (signal?.aborted) throw new RunWaitAbortedError(runId);
|
|
1823
|
+
if (isPermanent(err)) throw err;
|
|
1824
|
+
lastError = err;
|
|
1825
|
+
if (now() >= deadline) throw new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
1826
|
+
await napUntil(interval, deadline, signal);
|
|
1827
|
+
if (signal?.aborted) throw new RunWaitAbortedError(runId);
|
|
1828
|
+
if (now() >= deadline) throw new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
1829
|
+
continue;
|
|
1830
|
+
}
|
|
1831
|
+
lastStatus = run.status;
|
|
1832
|
+
if (TERMINAL_STATUSES.has(run.status)) return run;
|
|
1833
|
+
if (now() >= deadline) throw new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
1834
|
+
await napUntil(interval, deadline, signal);
|
|
1835
|
+
if (signal?.aborted) throw new RunWaitAbortedError(runId);
|
|
1836
|
+
if (now() >= deadline) throw new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
1837
|
+
}
|
|
1838
|
+
}
|
|
1839
|
+
async function waitForRun(deps, runId, options = {}) {
|
|
1840
|
+
const { interval, timeout, deadline, signal } = plan(options);
|
|
1841
|
+
if (signal?.aborted) throw new RunWaitAbortedError(runId);
|
|
1842
|
+
let lastError;
|
|
1843
|
+
let lastStatus;
|
|
1844
|
+
const answered = /* @__PURE__ */ new Set();
|
|
1845
|
+
for (; ; ) {
|
|
1846
|
+
let run;
|
|
1847
|
+
try {
|
|
1848
|
+
run = await withDeadline(
|
|
1849
|
+
() => deps.get(runId, signal),
|
|
1850
|
+
deadline,
|
|
1851
|
+
signal,
|
|
1852
|
+
() => signal?.aborted ? new RunWaitAbortedError(runId) : new RunTimeoutError(runId, timeout, lastError, lastStatus)
|
|
1853
|
+
);
|
|
1854
|
+
} catch (err) {
|
|
1855
|
+
if (err instanceof RunTimeoutError || err instanceof RunWaitAbortedError) throw err;
|
|
1856
|
+
if (signal?.aborted) throw new RunWaitAbortedError(runId);
|
|
1857
|
+
if (isPermanent(err)) throw err;
|
|
1858
|
+
lastError = err;
|
|
1859
|
+
if (now() >= deadline) throw new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
1860
|
+
await napUntil(interval, deadline, signal);
|
|
1861
|
+
if (signal?.aborted) throw new RunWaitAbortedError(runId);
|
|
1862
|
+
if (now() >= deadline) throw new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
1863
|
+
continue;
|
|
1864
|
+
}
|
|
1865
|
+
lastStatus = run.status;
|
|
1866
|
+
if (TERMINAL_STATUSES.has(run.status)) return run;
|
|
1867
|
+
if (run.status === "awaiting_approval") {
|
|
1868
|
+
const expired = () => signal?.aborted ? new RunWaitAbortedError(runId) : new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
1869
|
+
const bound = (start) => withDeadline(start, deadline, signal, expired);
|
|
1870
|
+
const resolveGate = async (start) => {
|
|
1871
|
+
try {
|
|
1872
|
+
await bound(start);
|
|
1873
|
+
} catch (err) {
|
|
1874
|
+
if (!(err instanceof ConflictError) && !(err instanceof NotFoundError)) throw err;
|
|
1875
|
+
if (!isBenignGateRefusal(err)) throw err;
|
|
1876
|
+
}
|
|
1877
|
+
};
|
|
1878
|
+
const pending = (await bound(() => deps.permissions(runId, signal))).filter(
|
|
1879
|
+
(r) => r.status === "pending" && !answered.has(r.request_id)
|
|
1880
|
+
);
|
|
1881
|
+
for (const request of pending) {
|
|
1882
|
+
answered.add(request.request_id);
|
|
1883
|
+
if (request.tool_name === "AskUserQuestion") {
|
|
1884
|
+
if (!options.onQuestion) {
|
|
1885
|
+
throw new RunPausedError(
|
|
1886
|
+
runId,
|
|
1887
|
+
request,
|
|
1888
|
+
"the agent asked a question. Pass onQuestion to answer it, or call runs.answer() yourself."
|
|
1889
|
+
);
|
|
1890
|
+
}
|
|
1891
|
+
const answers = await bound(async () => options.onQuestion(request));
|
|
1892
|
+
await resolveGate(() => deps.answer(runId, { answers }, signal));
|
|
1893
|
+
} else {
|
|
1894
|
+
if (!options.onApproval) {
|
|
1895
|
+
throw new RunPausedError(
|
|
1896
|
+
runId,
|
|
1897
|
+
request,
|
|
1898
|
+
`the tool "${request.tool_name}" needs a decision. Pass onApproval, or call runs.approve() yourself.`
|
|
1899
|
+
);
|
|
1900
|
+
}
|
|
1901
|
+
const decision = await bound(async () => options.onApproval(request));
|
|
1902
|
+
await resolveGate(() => deps.approve(runId, { request_id: request.request_id, decision }, signal));
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1906
|
+
if (now() >= deadline) throw new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
1907
|
+
await napUntil(interval, deadline, signal);
|
|
1908
|
+
if (signal?.aborted) throw new RunWaitAbortedError(runId);
|
|
1909
|
+
if (now() >= deadline) throw new RunTimeoutError(runId, timeout, lastError, lastStatus);
|
|
1910
|
+
}
|
|
1911
|
+
}
|
|
1912
|
+
|
|
1391
1913
|
// src/streaming.ts
|
|
1392
1914
|
var RunStream = class {
|
|
1393
1915
|
source;
|
|
@@ -1466,29 +1988,114 @@ var RunStream = class {
|
|
|
1466
1988
|
};
|
|
1467
1989
|
|
|
1468
1990
|
// src/resources/runs.ts
|
|
1991
|
+
function withRunId(err, runId) {
|
|
1992
|
+
if (err && typeof err === "object" && !("runId" in err)) {
|
|
1993
|
+
Object.defineProperty(err, "runId", { value: runId, enumerable: true, configurable: true });
|
|
1994
|
+
const e = err;
|
|
1995
|
+
if (typeof e.message === "string" && !e.message.includes(String(runId))) {
|
|
1996
|
+
e.message = `${e.message} (while waiting on run ${runId}, which is still executing)`;
|
|
1997
|
+
}
|
|
1998
|
+
}
|
|
1999
|
+
return err;
|
|
2000
|
+
}
|
|
1469
2001
|
function items(payload) {
|
|
1470
2002
|
return Array.isArray(payload) ? payload : payload?.data ?? [];
|
|
1471
2003
|
}
|
|
2004
|
+
function idempotencyHeaders(key) {
|
|
2005
|
+
return { [IDEMPOTENCY_HEADER]: key ?? crypto.randomUUID() };
|
|
2006
|
+
}
|
|
2007
|
+
function replayJoin(http) {
|
|
2008
|
+
return async function* (run) {
|
|
2009
|
+
if (TERMINAL_STATUSES.has(run.status)) {
|
|
2010
|
+
throw new ConflictError(
|
|
2011
|
+
`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}).`,
|
|
2012
|
+
{
|
|
2013
|
+
type: "invalid_request_error",
|
|
2014
|
+
code: 409,
|
|
2015
|
+
status: 409,
|
|
2016
|
+
details: { error_code: "idempotent_replay_terminal", run_id: run.id, status: run.status }
|
|
2017
|
+
}
|
|
2018
|
+
);
|
|
2019
|
+
}
|
|
2020
|
+
yield* http.stream("GET", `/runs/${seg(run.id)}/stream`);
|
|
2021
|
+
};
|
|
2022
|
+
}
|
|
1472
2023
|
function createRunsResource(http) {
|
|
1473
2024
|
const createBody = (p, stream) => {
|
|
1474
|
-
const { agent_id, teammate_id, ...rest } = p;
|
|
2025
|
+
const { agent_id, teammate_id, files, idempotencyKey, ...rest } = p;
|
|
1475
2026
|
return toBody({ ...rest, teammate_id: resolveAgentId(teammate_id, agent_id), stream });
|
|
1476
2027
|
};
|
|
2028
|
+
const createForm = (p, stream) => {
|
|
2029
|
+
const form = new FormData();
|
|
2030
|
+
form.append("payload", JSON.stringify(createBody(p, stream)));
|
|
2031
|
+
for (const f of p.files ?? []) {
|
|
2032
|
+
const blobType = f.data instanceof Blob && f.data.type ? f.data.type : void 0;
|
|
2033
|
+
const type = f.type ?? blobType ?? mimeTypeForFilename(f.name);
|
|
2034
|
+
if (!type) throw new TypeError(unknownTypeMessage(f.name));
|
|
2035
|
+
const blob = f.data instanceof Blob && f.data.type === type ? f.data : new Blob([f.data], { type });
|
|
2036
|
+
form.append("files", blob, f.name);
|
|
2037
|
+
}
|
|
2038
|
+
return form;
|
|
2039
|
+
};
|
|
2040
|
+
const hasFiles = (p) => (p.files?.length ?? 0) > 0;
|
|
2041
|
+
const deps = {
|
|
2042
|
+
get: (runId, signal) => http.request("GET", `/runs/${seg(runId)}`, { signal }),
|
|
2043
|
+
permissions: async (runId, signal) => items(await http.request("GET", `/runs/${seg(runId)}/permissions`, { signal })),
|
|
2044
|
+
approve: (runId, params, signal) => http.request("POST", `/runs/${seg(runId)}/approve`, { body: { remember: false, ...params }, signal }),
|
|
2045
|
+
answer: (runId, params, signal) => http.request("POST", `/runs/${seg(runId)}/answer`, { body: params, signal })
|
|
2046
|
+
};
|
|
2047
|
+
const createAsync = async (params) => {
|
|
2048
|
+
const headers = idempotencyHeaders(params.idempotencyKey);
|
|
2049
|
+
return hasFiles(params) ? http.request("POST", "/runs/with-files", { form: createForm(params, false), headers }) : http.request("POST", "/runs", { body: createBody(params, false), headers });
|
|
2050
|
+
};
|
|
1477
2051
|
return {
|
|
1478
2052
|
create(params, options) {
|
|
1479
|
-
|
|
2053
|
+
const headers = idempotencyHeaders(params.idempotencyKey);
|
|
2054
|
+
const init = hasFiles(params) ? { form: createForm(params, true), headers } : { body: createBody(params, true), headers };
|
|
2055
|
+
const path = hasFiles(params) ? "/runs/with-files" : "/runs";
|
|
2056
|
+
return new RunStream(
|
|
2057
|
+
http.stream("POST", path, { ...init, onReplay: replayJoin(http) }),
|
|
2058
|
+
options
|
|
2059
|
+
);
|
|
2060
|
+
},
|
|
2061
|
+
createAsync,
|
|
2062
|
+
async createAndWait(params, options = {}) {
|
|
2063
|
+
if (options.signal?.aborted) throw new RunWaitAbortedError();
|
|
2064
|
+
const started = await createAsync(params);
|
|
2065
|
+
try {
|
|
2066
|
+
return await waitForRun(deps, started.id, options);
|
|
2067
|
+
} catch (err) {
|
|
2068
|
+
throw withRunId(err, started.id);
|
|
2069
|
+
}
|
|
2070
|
+
},
|
|
2071
|
+
poll(runId, options) {
|
|
2072
|
+
return pollRun(deps, runId, options);
|
|
1480
2073
|
},
|
|
1481
|
-
|
|
1482
|
-
return
|
|
2074
|
+
wait(runId, options) {
|
|
2075
|
+
return waitForRun(deps, runId, options);
|
|
2076
|
+
},
|
|
2077
|
+
// `confirm` is a QUERY param and the route takes no body (verified against
|
|
2078
|
+
// fastapi/app/routers/v2/runs.py::retry_run), so send neither.
|
|
2079
|
+
retry(runId, params = {}) {
|
|
2080
|
+
return http.request("POST", `/runs/${seg(runId)}/retry`, {
|
|
2081
|
+
query: params.confirm ? toQuery({ confirm: true }) : ""
|
|
2082
|
+
});
|
|
1483
2083
|
},
|
|
1484
2084
|
stream(runId, options) {
|
|
1485
|
-
return new RunStream(http.stream("GET", `/runs/${runId}/stream`), options);
|
|
2085
|
+
return new RunStream(http.stream("GET", `/runs/${seg(runId)}/stream`), options);
|
|
1486
2086
|
},
|
|
1487
2087
|
reply(runId, message, options) {
|
|
1488
|
-
return new RunStream(
|
|
2088
|
+
return new RunStream(
|
|
2089
|
+
http.stream("POST", `/runs/${seg(runId)}/reply`, {
|
|
2090
|
+
body: { message },
|
|
2091
|
+
headers: idempotencyHeaders(options?.idempotencyKey),
|
|
2092
|
+
onReplay: replayJoin(http)
|
|
2093
|
+
}),
|
|
2094
|
+
options
|
|
2095
|
+
);
|
|
1489
2096
|
},
|
|
1490
2097
|
get(runId) {
|
|
1491
|
-
return http.request("GET", `/runs/${runId}`);
|
|
2098
|
+
return http.request("GET", `/runs/${seg(runId)}`);
|
|
1492
2099
|
},
|
|
1493
2100
|
async list(params = {}) {
|
|
1494
2101
|
const { agent_id, teammate_id, ...rest } = params;
|
|
@@ -1506,29 +2113,29 @@ function createRunsResource(http) {
|
|
|
1506
2113
|
return fetchPage(q);
|
|
1507
2114
|
},
|
|
1508
2115
|
cancel(runId) {
|
|
1509
|
-
return http.request("POST", `/runs/${runId}/cancel`, { body: {} });
|
|
2116
|
+
return http.request("POST", `/runs/${seg(runId)}/cancel`, { body: {} });
|
|
1510
2117
|
},
|
|
1511
2118
|
approve(runId, params) {
|
|
1512
|
-
return http.request("POST", `/runs/${runId}/approve`, {
|
|
2119
|
+
return http.request("POST", `/runs/${seg(runId)}/approve`, {
|
|
1513
2120
|
body: { remember: false, ...params }
|
|
1514
2121
|
});
|
|
1515
2122
|
},
|
|
1516
2123
|
answer(runId, params) {
|
|
1517
|
-
return http.request("POST", `/runs/${runId}/answer`, {
|
|
2124
|
+
return http.request("POST", `/runs/${seg(runId)}/answer`, {
|
|
1518
2125
|
body: { answers: params.answers }
|
|
1519
2126
|
});
|
|
1520
2127
|
},
|
|
1521
2128
|
async permissions(runId) {
|
|
1522
|
-
return items(await http.request("GET", `/runs/${runId}/permissions`));
|
|
2129
|
+
return items(await http.request("GET", `/runs/${seg(runId)}/permissions`));
|
|
1523
2130
|
},
|
|
1524
2131
|
outcome(runId) {
|
|
1525
|
-
return http.request("GET", `/runs/${runId}/outcome`);
|
|
2132
|
+
return http.request("GET", `/runs/${seg(runId)}/outcome`);
|
|
1526
2133
|
},
|
|
1527
2134
|
async files(runId) {
|
|
1528
|
-
return items(await http.request("GET", `/runs/${runId}/files`));
|
|
2135
|
+
return items(await http.request("GET", `/runs/${seg(runId)}/files`));
|
|
1529
2136
|
},
|
|
1530
2137
|
async downloadFile(runId, filename) {
|
|
1531
|
-
const res = await http.raw("GET", `/runs/${runId}/files/${
|
|
2138
|
+
const res = await http.raw("GET", `/runs/${seg(runId)}/files/${seg(filename)}/download`, {
|
|
1532
2139
|
headers: { accept: "application/octet-stream" }
|
|
1533
2140
|
});
|
|
1534
2141
|
return res.arrayBuffer();
|
|
@@ -1553,24 +2160,30 @@ function createSettingsResource(http) {
|
|
|
1553
2160
|
function createTasksResource(http) {
|
|
1554
2161
|
const triggers = {
|
|
1555
2162
|
create(taskId, params) {
|
|
1556
|
-
return http.request("POST", `/tasks/${taskId}/triggers/`, {
|
|
1557
|
-
body: toBody({ timezone: "UTC", ...params })
|
|
2163
|
+
return http.request("POST", `/tasks/${seg(taskId)}/triggers/`, {
|
|
2164
|
+
body: toBody({ timezone: "UTC", ...params }),
|
|
2165
|
+
query: toQuery({ user_id: params.user_id })
|
|
1558
2166
|
});
|
|
1559
2167
|
},
|
|
1560
|
-
async list(taskId) {
|
|
2168
|
+
async list(taskId, params = {}) {
|
|
1561
2169
|
const res = await http.request(
|
|
1562
2170
|
"GET",
|
|
1563
|
-
`/tasks/${taskId}/triggers
|
|
2171
|
+
`/tasks/${seg(taskId)}/triggers/`,
|
|
2172
|
+
{ query: toQuery(params) }
|
|
1564
2173
|
);
|
|
1565
2174
|
return Array.isArray(res) ? res : res?.data ?? [];
|
|
1566
2175
|
},
|
|
1567
2176
|
update(taskId, triggerId, params) {
|
|
1568
|
-
|
|
1569
|
-
|
|
2177
|
+
const { user_id, ...patch } = params;
|
|
2178
|
+
return http.request("PATCH", `/tasks/${seg(taskId)}/triggers/${seg(triggerId)}`, {
|
|
2179
|
+
body: toBody(patch),
|
|
2180
|
+
query: toQuery({ user_id })
|
|
1570
2181
|
});
|
|
1571
2182
|
},
|
|
1572
|
-
async delete(taskId, triggerId) {
|
|
1573
|
-
await http.request("DELETE", `/tasks/${taskId}/triggers/${triggerId}
|
|
2183
|
+
async delete(taskId, triggerId, params = {}) {
|
|
2184
|
+
await http.request("DELETE", `/tasks/${seg(taskId)}/triggers/${seg(triggerId)}`, {
|
|
2185
|
+
query: toQuery(params)
|
|
2186
|
+
});
|
|
1574
2187
|
}
|
|
1575
2188
|
};
|
|
1576
2189
|
return {
|
|
@@ -1597,73 +2210,46 @@ function createTasksResource(http) {
|
|
|
1597
2210
|
return fetchPage(q);
|
|
1598
2211
|
},
|
|
1599
2212
|
get(taskId, params = {}) {
|
|
1600
|
-
return http.request("GET", `/tasks/${taskId}`, { query: toQuery(params) });
|
|
2213
|
+
return http.request("GET", `/tasks/${seg(taskId)}`, { query: toQuery(params) });
|
|
1601
2214
|
},
|
|
1602
2215
|
update(taskId, params) {
|
|
1603
2216
|
const { user_id, ...patch } = params;
|
|
1604
|
-
return http.request("PATCH", `/tasks/${taskId}`, {
|
|
2217
|
+
return http.request("PATCH", `/tasks/${seg(taskId)}`, {
|
|
1605
2218
|
body: toBody(patch),
|
|
1606
2219
|
query: toQuery({ user_id })
|
|
1607
2220
|
});
|
|
1608
2221
|
},
|
|
1609
2222
|
async delete(taskId, params = {}) {
|
|
1610
|
-
await http.request("DELETE", `/tasks/${taskId}`, { query: toQuery(params) });
|
|
2223
|
+
await http.request("DELETE", `/tasks/${seg(taskId)}`, { query: toQuery(params) });
|
|
1611
2224
|
},
|
|
1612
2225
|
run(taskId, params = {}, options) {
|
|
2226
|
+
const { idempotencyKey, ...rest } = params;
|
|
1613
2227
|
return new RunStream(
|
|
1614
|
-
http.stream("POST", `/tasks/${taskId}/runs`, {
|
|
2228
|
+
http.stream("POST", `/tasks/${seg(taskId)}/runs`, {
|
|
2229
|
+
body: toBody({ ...rest, stream: true }),
|
|
2230
|
+
headers: idempotencyHeaders(idempotencyKey),
|
|
2231
|
+
// Shares the create path's replay handling, so a fix on one side can
|
|
2232
|
+
// never silently miss the other.
|
|
2233
|
+
onReplay: replayJoin(http)
|
|
2234
|
+
}),
|
|
1615
2235
|
options
|
|
1616
2236
|
);
|
|
1617
2237
|
},
|
|
1618
2238
|
runAsync(taskId, params = {}) {
|
|
1619
|
-
|
|
1620
|
-
|
|
2239
|
+
const { idempotencyKey, ...rest } = params;
|
|
2240
|
+
return http.request("POST", `/tasks/${seg(taskId)}/runs`, {
|
|
2241
|
+
body: toBody({ ...rest, stream: false }),
|
|
2242
|
+
headers: idempotencyHeaders(idempotencyKey)
|
|
1621
2243
|
});
|
|
1622
2244
|
},
|
|
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 })
|
|
2245
|
+
enableWebhook(taskId, params = {}) {
|
|
2246
|
+
return http.request("POST", `/tasks/${seg(taskId)}/webhook`, {
|
|
2247
|
+
body: {},
|
|
2248
|
+
query: toQuery(params)
|
|
1660
2249
|
});
|
|
1661
2250
|
},
|
|
1662
|
-
async
|
|
1663
|
-
await http.request("DELETE", `/
|
|
1664
|
-
},
|
|
1665
|
-
usage(params = {}) {
|
|
1666
|
-
return pager(http, "/usage/end-users")({ ...params });
|
|
2251
|
+
async disableWebhook(taskId, params = {}) {
|
|
2252
|
+
await http.request("DELETE", `/tasks/${seg(taskId)}/webhook`, { query: toQuery(params) });
|
|
1667
2253
|
}
|
|
1668
2254
|
};
|
|
1669
2255
|
}
|
|
@@ -1687,14 +2273,14 @@ function verifySignature(body, headers, secret, options = {}) {
|
|
|
1687
2273
|
if (options.toleranceSeconds !== void 0) {
|
|
1688
2274
|
const ts = Number.parseInt(timestamp, 10);
|
|
1689
2275
|
if (!Number.isFinite(ts)) return false;
|
|
1690
|
-
const
|
|
1691
|
-
if (Math.abs(
|
|
2276
|
+
const now2 = options.now ? options.now() : Math.floor(Date.now() / 1e3);
|
|
2277
|
+
if (Math.abs(now2 - ts) > options.toleranceSeconds) return false;
|
|
1692
2278
|
}
|
|
1693
2279
|
const raw = typeof body === "string" ? body : new TextDecoder().decode(body);
|
|
1694
|
-
const expected = `v1=${crypto.createHmac("sha256", secret).update(`${webhookId}.${timestamp}.${raw}`).digest("hex")}`;
|
|
2280
|
+
const expected = `v1=${crypto$1.createHmac("sha256", secret).update(`${webhookId}.${timestamp}.${raw}`).digest("hex")}`;
|
|
1695
2281
|
const a = Buffer.from(expected);
|
|
1696
2282
|
const b = Buffer.from(signature);
|
|
1697
|
-
return a.length === b.length && crypto.timingSafeEqual(a, b);
|
|
2283
|
+
return a.length === b.length && crypto$1.timingSafeEqual(a, b);
|
|
1698
2284
|
}
|
|
1699
2285
|
function createWebhooksResource(http) {
|
|
1700
2286
|
return {
|
|
@@ -1706,22 +2292,22 @@ function createWebhooksResource(http) {
|
|
|
1706
2292
|
return pager(http, "/webhooks/")({ ...params });
|
|
1707
2293
|
},
|
|
1708
2294
|
get(webhookId) {
|
|
1709
|
-
return http.request("GET", `/webhooks/${webhookId}`);
|
|
2295
|
+
return http.request("GET", `/webhooks/${seg(webhookId)}`);
|
|
1710
2296
|
},
|
|
1711
2297
|
update(webhookId, params) {
|
|
1712
|
-
return http.request("PATCH", `/webhooks/${webhookId}`, { body: toBody({ ...params }) });
|
|
2298
|
+
return http.request("PATCH", `/webhooks/${seg(webhookId)}`, { body: toBody({ ...params }) });
|
|
1713
2299
|
},
|
|
1714
2300
|
async delete(webhookId) {
|
|
1715
|
-
await http.request("DELETE", `/webhooks/${webhookId}`);
|
|
2301
|
+
await http.request("DELETE", `/webhooks/${seg(webhookId)}`);
|
|
1716
2302
|
},
|
|
1717
2303
|
listDeliveries(webhookId, params = {}) {
|
|
1718
|
-
return pager(http, `/webhooks/${webhookId}/deliveries`)({ ...params });
|
|
2304
|
+
return pager(http, `/webhooks/${seg(webhookId)}/deliveries`)({ ...params });
|
|
1719
2305
|
}
|
|
1720
2306
|
};
|
|
1721
2307
|
}
|
|
1722
2308
|
|
|
1723
2309
|
// src/index.ts
|
|
1724
|
-
var M8TES_SDK_VERSION = "0.1.0-alpha.
|
|
2310
|
+
var M8TES_SDK_VERSION = "0.1.0-alpha.2";
|
|
1725
2311
|
var M8tes = class {
|
|
1726
2312
|
runs;
|
|
1727
2313
|
agents;
|
|
@@ -1732,6 +2318,12 @@ var M8tes = class {
|
|
|
1732
2318
|
apps;
|
|
1733
2319
|
webhooks;
|
|
1734
2320
|
settings;
|
|
2321
|
+
memories;
|
|
2322
|
+
permissions;
|
|
2323
|
+
models;
|
|
2324
|
+
modelConnections;
|
|
2325
|
+
billing;
|
|
2326
|
+
account;
|
|
1735
2327
|
/** The underlying transport. Use it to call an endpoint this version does not wrap yet. */
|
|
1736
2328
|
http;
|
|
1737
2329
|
constructor(options = {}) {
|
|
@@ -1744,6 +2336,12 @@ var M8tes = class {
|
|
|
1744
2336
|
this.apps = createAppsResource(this.http);
|
|
1745
2337
|
this.webhooks = createWebhooksResource(this.http);
|
|
1746
2338
|
this.settings = createSettingsResource(this.http);
|
|
2339
|
+
this.memories = createMemoriesResource(this.http);
|
|
2340
|
+
this.permissions = createPermissionsResource(this.http);
|
|
2341
|
+
this.models = createModelsResource(this.http);
|
|
2342
|
+
this.modelConnections = createModelConnectionsResource(this.http);
|
|
2343
|
+
this.billing = createBillingResource(this.http);
|
|
2344
|
+
this.account = createAccountResource(this.http);
|
|
1747
2345
|
}
|
|
1748
2346
|
};
|
|
1749
2347
|
|
|
@@ -1762,8 +2360,12 @@ exports.PermissionDeniedError = PermissionDeniedError;
|
|
|
1762
2360
|
exports.RateLimitError = RateLimitError;
|
|
1763
2361
|
exports.RunFailedError = RunFailedError;
|
|
1764
2362
|
exports.RunNotStreamingError = RunNotStreamingError;
|
|
2363
|
+
exports.RunPausedError = RunPausedError;
|
|
1765
2364
|
exports.RunStream = RunStream;
|
|
2365
|
+
exports.RunTimeoutError = RunTimeoutError;
|
|
2366
|
+
exports.RunWaitAbortedError = RunWaitAbortedError;
|
|
1766
2367
|
exports.TERMINAL_EVENT_TYPES = TERMINAL_EVENT_TYPES;
|
|
2368
|
+
exports.TERMINAL_STATUSES = TERMINAL_STATUSES;
|
|
1767
2369
|
exports.ValidationError = ValidationError;
|
|
1768
2370
|
exports.accumulate = accumulate;
|
|
1769
2371
|
exports.createAccumulator = createAccumulator;
|
|
@@ -1773,11 +2375,16 @@ exports.createSseDecoder = createSseDecoder;
|
|
|
1773
2375
|
exports.errorClassForStatus = errorClassForStatus;
|
|
1774
2376
|
exports.errorFromResponse = errorFromResponse;
|
|
1775
2377
|
exports.initialConversationState = initialConversationState;
|
|
2378
|
+
exports.isPlanApproval = isPlanApproval;
|
|
1776
2379
|
exports.isTerminalEvent = isTerminalEvent;
|
|
1777
2380
|
exports.parseErrorEnvelope = parseErrorEnvelope;
|
|
1778
2381
|
exports.parseRetryAfter = parseRetryAfter;
|
|
1779
2382
|
exports.parseSse = parseSse;
|
|
2383
|
+
exports.planText = planText;
|
|
2384
|
+
exports.pollRun = pollRun;
|
|
2385
|
+
exports.seg = seg;
|
|
1780
2386
|
exports.splitConcatenatedJson = splitConcatenatedJson;
|
|
1781
2387
|
exports.verifySignature = verifySignature;
|
|
2388
|
+
exports.waitForRun = waitForRun;
|
|
1782
2389
|
//# sourceMappingURL=index.cjs.map
|
|
1783
2390
|
//# sourceMappingURL=index.cjs.map
|