@m8tes/sdk 0.1.0-alpha.2 → 0.1.0-alpha.4

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 CHANGED
@@ -5,7 +5,9 @@ All notable changes to `@m8tes/sdk`.
5
5
  > **Release process** (mirrors `sdk/py`): every change to behaviour or public API
6
6
  > lands an entry under `## [Unreleased]` in the same commit. A RELEASE then bumps
7
7
  > `package.json` `version` (semver) and retitles that section. Entries are never
8
- > skipped — without one, a consumer cannot tell what changed. Publish via the `Publish @m8tes/sdk` workflow — never `npm publish` by
8
+ > skipped — without one, a consumer cannot tell what changed. A version bump
9
+ > merged to main publishes automatically (`Publish npm packages`); dry-run stays
10
+ > on the package-specific workflow. Never `npm publish` by
9
11
  > hand (it does not rewrite the pnpm `workspace:` protocol).
10
12
  >
11
13
  > While the version is a `-alpha.N` prerelease, publish with dist-tag `alpha`.
@@ -13,8 +15,56 @@ All notable changes to `@m8tes/sdk`.
13
15
 
14
16
  ## [Unreleased]
15
17
 
18
+ ## [0.1.0-alpha.4] — 2026-08-21
19
+
20
+ ### Changed
21
+
22
+ - `runs.retry(..., { use_credits: true })` pins the platform default model (m8tes credits) instead of replaying a failed OAuth model.
23
+
16
24
  ### Added
17
25
 
26
+ - **`Agent.active_run_id`** (plus typed `last_active_at` / `active_run_count`) —
27
+ roster liveness for messaging discovery; `active_run_id` is set only when
28
+ exactly one live run exists.
29
+ - **`modelConnections.clearDefault()`** — clear the account model-plan default
30
+ (`DELETE /model-connections/preferred-default`) so platform mates fall back to
31
+ m8tes credits.
32
+ - **`RunOutcome.delivery_channel` and `RunOutcome.needs_reply_count`** — mirror
33
+ `GET /runs/{id}/outcome` after agentic scheduled delivery (`set_run_delivery`).
34
+ - **`tasks.create` / `tasks.update` `permission_mode`.** Same closed union as
35
+ agents (`autonomous` / `approval` / `plan`). Also typed on the `Task` response.
36
+
37
+ - `agents.update(..., { visibility: "organization" })` — share an agent with its
38
+ organization (mirrors the Python SDK and `PATCH /api/v2/agents/{id}`).
39
+
40
+ ## [0.1.0-alpha.3] — 2026-08-19
41
+
42
+ ### Changed
43
+
44
+ - **`runs.get` / `poll` / `wait` / `createAndWait` forward `user_id`.** Strict
45
+ multi-tenant mode requires `?user_id=` on every by-ID GET; `createAndWait`
46
+ reuses the create body's `user_id`, then falls back to the created run's
47
+ stamped `user_id` (agent-inherited scope). A wait-only `options.user_id` is
48
+ folded into the create body when params omit it; conflicting scopes are
49
+ rejected before POST. After create, poll prefers the API-stamped owner when
50
+ it differs from the request scope.
51
+ - **`runs.cancel(id, { user_id })`** — same end-user scope as get (strict mode).
52
+ - **`ApproveParams.remember` docs match persistence.** `remember: true` on allow
53
+ stores a cross-run always-allow policy (not run-only); deny+remember stays
54
+ run-scoped.
55
+
56
+ ### Added
57
+
58
+ - **`Usage.unlimited_runs`.** Mirrors `GET /api/v2/usage` so clients can tell a
59
+ bypassed meter from a soft over-limit.
60
+ - **`Page.nextStartingAfter` / list envelope `next_starting_after`.** Cursor for the
61
+ next `starting_after` page when `hasMore` is true.
62
+ - **`PermissionRequest.can_remember` / `remember_default` and
63
+ `PermissionPolicy.source`.** `remember_default: false` tells a client the
64
+ Always-allow control must start unticked (force-ask floor: spend, access,
65
+ destroy); `source` names the surface that minted a standing grant
66
+ (`"run_approval"` / `"api"`; null on legacy rows).
67
+
18
68
  - **`user_id` end-user scoping on agent and task sub-resource methods.**
19
69
  `agents.enableWebhook` / `disableWebhook` / `enableEmailInbox` /
20
70
  `disableEmailInbox`, `tasks.enableWebhook` / `disableWebhook`, and the full
package/dist/index.cjs CHANGED
@@ -1298,12 +1298,14 @@ function createHttp(options = {}) {
1298
1298
  var Page = class {
1299
1299
  data;
1300
1300
  hasMore;
1301
+ nextStartingAfter;
1301
1302
  /** Fetches the next page given a cursor. Absent on a terminal page. */
1302
1303
  fetchNext;
1303
- constructor(data, hasMore, fetchNext) {
1304
+ constructor(data, hasMore, fetchNext, nextStartingAfter) {
1304
1305
  this.data = data;
1305
1306
  this.hasMore = hasMore;
1306
1307
  this.fetchNext = fetchNext;
1308
+ this.nextStartingAfter = nextStartingAfter ?? null;
1307
1309
  }
1308
1310
  /**
1309
1311
  * Auto-paging: yields every item across every page.
@@ -1321,7 +1323,10 @@ var Page = class {
1321
1323
  yield* page.data;
1322
1324
  const last = page.data.at(-1);
1323
1325
  if (!page.hasMore || !last || !page.fetchNext) return;
1324
- 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
+ }
1325
1330
  if (cursor === void 0 || seen.has(cursor)) return;
1326
1331
  seen.add(cursor);
1327
1332
  page = await page.fetchNext(cursor);
@@ -1373,7 +1378,8 @@ function createAgentsResource(http) {
1373
1378
  return new Page(
1374
1379
  res?.data ?? [],
1375
1380
  res?.has_more ?? false,
1376
- (starting_after) => fetchPage({ ...p, starting_after })
1381
+ (starting_after) => fetchPage({ ...p, starting_after }),
1382
+ res?.next_starting_after
1377
1383
  );
1378
1384
  };
1379
1385
  return fetchPage({ ...params });
@@ -1418,7 +1424,7 @@ function createAppsResource(http) {
1418
1424
  const res = await http.request("GET", "/apps/", {
1419
1425
  query: toQuery({ user_id: params.user_id })
1420
1426
  });
1421
- return new Page(res?.data ?? [], res?.has_more ?? false);
1427
+ return new Page(res?.data ?? [], res?.has_more ?? false, void 0, res?.next_starting_after);
1422
1428
  };
1423
1429
  return {
1424
1430
  list,
@@ -1468,7 +1474,8 @@ function pager(http, path) {
1468
1474
  return new Page(
1469
1475
  res?.data ?? [],
1470
1476
  res?.has_more ?? false,
1471
- (starting_after) => fetchPage({ ...p, starting_after })
1477
+ (starting_after) => fetchPage({ ...p, starting_after }),
1478
+ res?.next_starting_after
1472
1479
  );
1473
1480
  };
1474
1481
  return fetchPage;
@@ -1570,7 +1577,7 @@ function createModelsResource(http) {
1570
1577
  return {
1571
1578
  async list() {
1572
1579
  const res = await http.request("GET", "/models/");
1573
- return new Page(res?.data ?? [], res?.has_more ?? false);
1580
+ return new Page(res?.data ?? [], res?.has_more ?? false, void 0, res?.next_starting_after);
1574
1581
  }
1575
1582
  };
1576
1583
  }
@@ -1606,6 +1613,13 @@ function createModelConnectionsResource(http) {
1606
1613
  },
1607
1614
  disconnect(provider) {
1608
1615
  return http.request("DELETE", `/model-connections/${seg(provider)}`);
1616
+ },
1617
+ async clearDefault() {
1618
+ const res = await http.request(
1619
+ "DELETE",
1620
+ "/model-connections/preferred-default"
1621
+ );
1622
+ return Boolean(res?.cleared);
1609
1623
  }
1610
1624
  };
1611
1625
  }
@@ -2038,12 +2052,15 @@ function createRunsResource(http) {
2038
2052
  return form;
2039
2053
  };
2040
2054
  const hasFiles = (p) => (p.files?.length ?? 0) > 0;
2041
- const deps = {
2042
- get: (runId, signal) => http.request("GET", `/runs/${seg(runId)}`, { signal }),
2055
+ const pollDeps = (userId) => ({
2056
+ get: (runId, signal) => http.request("GET", `/runs/${seg(runId)}`, {
2057
+ query: toQuery({ user_id: userId }),
2058
+ signal
2059
+ }),
2043
2060
  permissions: async (runId, signal) => items(await http.request("GET", `/runs/${seg(runId)}/permissions`, { signal })),
2044
2061
  approve: (runId, params, signal) => http.request("POST", `/runs/${seg(runId)}/approve`, { body: { remember: false, ...params }, signal }),
2045
2062
  answer: (runId, params, signal) => http.request("POST", `/runs/${seg(runId)}/answer`, { body: params, signal })
2046
- };
2063
+ });
2047
2064
  const createAsync = async (params) => {
2048
2065
  const headers = idempotencyHeaders(params.idempotencyKey);
2049
2066
  return hasFiles(params) ? http.request("POST", "/runs/with-files", { form: createForm(params, false), headers }) : http.request("POST", "/runs", { body: createBody(params, false), headers });
@@ -2061,24 +2078,35 @@ function createRunsResource(http) {
2061
2078
  createAsync,
2062
2079
  async createAndWait(params, options = {}) {
2063
2080
  if (options.signal?.aborted) throw new RunWaitAbortedError();
2064
- const started = await createAsync(params);
2081
+ if (options.user_id != null && params.user_id != null && options.user_id !== params.user_id) {
2082
+ throw new ValidationError(
2083
+ `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.`,
2084
+ { type: "invalid_request_error", code: 0, status: 0 }
2085
+ );
2086
+ }
2087
+ const createParams = params.user_id == null && options.user_id != null ? { ...params, user_id: options.user_id } : params;
2088
+ const started = await createAsync(createParams);
2089
+ const userId = started.user_id ?? createParams.user_id ?? void 0;
2065
2090
  try {
2066
- return await waitForRun(deps, started.id, options);
2091
+ return await waitForRun(pollDeps(userId), started.id, { ...options, user_id: userId });
2067
2092
  } catch (err) {
2068
2093
  throw withRunId(err, started.id);
2069
2094
  }
2070
2095
  },
2071
- poll(runId, options) {
2072
- return pollRun(deps, runId, options);
2096
+ poll(runId, options = {}) {
2097
+ return pollRun(pollDeps(options.user_id), runId, options);
2073
2098
  },
2074
- wait(runId, options) {
2075
- return waitForRun(deps, runId, options);
2099
+ wait(runId, options = {}) {
2100
+ return waitForRun(pollDeps(options.user_id), runId, options);
2076
2101
  },
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.
2102
+ // `confirm` / `use_credits` are QUERY params and the route takes no body
2103
+ // (verified against fastapi/app/routers/v2/runs.py::retry_run).
2079
2104
  retry(runId, params = {}) {
2080
2105
  return http.request("POST", `/runs/${seg(runId)}/retry`, {
2081
- query: params.confirm ? toQuery({ confirm: true }) : ""
2106
+ query: toQuery({
2107
+ confirm: params.confirm ? true : void 0,
2108
+ use_credits: params.use_credits ? true : void 0
2109
+ })
2082
2110
  });
2083
2111
  },
2084
2112
  stream(runId, options) {
@@ -2094,8 +2122,10 @@ function createRunsResource(http) {
2094
2122
  options
2095
2123
  );
2096
2124
  },
2097
- get(runId) {
2098
- return http.request("GET", `/runs/${seg(runId)}`);
2125
+ get(runId, params = {}) {
2126
+ return http.request("GET", `/runs/${seg(runId)}`, {
2127
+ query: toQuery({ user_id: params.user_id })
2128
+ });
2099
2129
  },
2100
2130
  async list(params = {}) {
2101
2131
  const { agent_id, teammate_id, ...rest } = params;
@@ -2107,13 +2137,16 @@ function createRunsResource(http) {
2107
2137
  return new Page(
2108
2138
  res?.data ?? [],
2109
2139
  res?.has_more ?? false,
2110
- (starting_after) => fetchPage({ ...p, starting_after })
2140
+ (starting_after) => fetchPage({ ...p, starting_after }),
2141
+ res?.next_starting_after
2111
2142
  );
2112
2143
  };
2113
2144
  return fetchPage(q);
2114
2145
  },
2115
- cancel(runId) {
2116
- return http.request("POST", `/runs/${seg(runId)}/cancel`, { body: {} });
2146
+ cancel(runId, params = {}) {
2147
+ return http.request("POST", `/runs/${seg(runId)}/cancel`, {
2148
+ query: toQuery({ user_id: params.user_id })
2149
+ });
2117
2150
  },
2118
2151
  approve(runId, params) {
2119
2152
  return http.request("POST", `/runs/${seg(runId)}/approve`, {
@@ -2204,7 +2237,8 @@ function createTasksResource(http) {
2204
2237
  return new Page(
2205
2238
  res?.data ?? [],
2206
2239
  res?.has_more ?? false,
2207
- (starting_after) => fetchPage({ ...p, starting_after })
2240
+ (starting_after) => fetchPage({ ...p, starting_after }),
2241
+ res?.next_starting_after
2208
2242
  );
2209
2243
  };
2210
2244
  return fetchPage(q);
@@ -2307,7 +2341,7 @@ function createWebhooksResource(http) {
2307
2341
  }
2308
2342
 
2309
2343
  // src/index.ts
2310
- var M8TES_SDK_VERSION = "0.1.0-alpha.2";
2344
+ var M8TES_SDK_VERSION = "0.1.0-alpha.4";
2311
2345
  var M8tes = class {
2312
2346
  runs;
2313
2347
  agents;