@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/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
- ...options.headers,
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.body !== void 0) {
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 = IDEMPOTENT_METHODS.has(method.toUpperCase());
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
- const cursor = typeof last.id === "number" || typeof last.id === "string" ? last.id : typeof last.name === "string" ? last.name : void 0;
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`, { body: {} });
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`, { body: {} });
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 slug = (name) => encodeURIComponent(name);
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
- async list(params = {}) {
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 this.list(params);
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/${slug(appName)}/connect`, {
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/${slug(appName)}/connect/api-key`, {
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/${slug(appName)}/connect/complete`, {
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/${slug(appName)}/connections`, { query: toQuery(params) });
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
- return new RunStream(http.stream("POST", "/runs", { body: createBody(params, true) }), options);
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
- createAsync(params) {
1482
- return http.request("POST", "/runs", { body: createBody(params, false) });
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(http.stream("POST", `/runs/${runId}/reply`, { body: { message } }), options);
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`, { body: {} });
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/${encodeURIComponent(filename)}/download`, {
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
- return http.request("PATCH", `/tasks/${taskId}/triggers/${triggerId}`, {
1569
- body: toBody({ ...params })
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`, { body: toBody({ ...params, stream: true }) }),
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
- return http.request("POST", `/tasks/${taskId}/runs`, {
1620
- body: toBody({ ...params, stream: false })
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`, { body: {} });
1625
- },
1626
- async disableWebhook(taskId) {
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 delete(userId) {
1663
- await http.request("DELETE", `/users/${encodeURIComponent(userId)}`);
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 now = options.now ? options.now() : Math.floor(Date.now() / 1e3);
1691
- if (Math.abs(now - ts) > options.toleranceSeconds) return false;
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.1";
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