@loomcycle/client 1.72.0 → 1.77.0

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.
@@ -1240,17 +1240,46 @@ class LoomcycleClient {
1240
1240
  async forkTeam(name, overlay, opts) {
1241
1241
  return (0, fetch_helpers_js_1.postJSON)(this.ctx, "/v1/_teamdef", { op: "fork", name, overlay }, opts);
1242
1242
  }
1243
+ /** List every version of ONE team, newest first (op=list) — the lineage
1244
+ * behind {@link LoomcycleClient.listTeams}' roll-up. Tenant-scoped
1245
+ * server-side; a name with no versions returns an empty list rather than
1246
+ * raising. */
1247
+ async listTeamVersions(name, opts) {
1248
+ return (0, fetch_helpers_js_1.postJSON)(this.ctx, "/v1/_teamdef", { op: "list", name }, opts);
1249
+ }
1250
+ /** Point the team's active pointer at one version (op=promote) — what a new
1251
+ * run of the team by NAME will execute.
1252
+ *
1253
+ * `forkTeam` defaults to promote:false, so authoring a version and putting
1254
+ * it in force are deliberately two steps: an edited graph can be reviewed,
1255
+ * diagrammed, even run by `defId`, before it becomes what the name means. */
1256
+ async promoteTeam(defId, opts) {
1257
+ return (0, fetch_helpers_js_1.postJSON)(this.ctx, "/v1/_teamdef", { op: "promote", def_id: defId }, opts);
1258
+ }
1259
+ /** Soft-retire one version, or un-retire it (op=retire, `retired` required).
1260
+ *
1261
+ * Retiring is REVERSIBLE and version-scoped: the row stays, its history stays
1262
+ * readable, and passing `false` brings it back. Removing a team is
1263
+ * {@link LoomcycleClient.deleteTeam}, which is neither. */
1264
+ async retireTeam(defId, retired, opts) {
1265
+ return (0, fetch_helpers_js_1.postJSON)(this.ctx, "/v1/_teamdef", { op: "retire", def_id: defId, retired }, opts);
1266
+ }
1267
+ /** Compare a locally computed content hash against the deployed active
1268
+ * version (op=verify) — the drift check for a team kept in source control
1269
+ * and pushed to several deployments.
1270
+ *
1271
+ * Never raises for an absent team: a name with no active version answers
1272
+ * `{deployed: false, matches: false}`, which a caller distinguishes from a
1273
+ * deployed version whose hash differs. */
1274
+ async verifyTeam(name, contentSha256, opts) {
1275
+ return (0, fetch_helpers_js_1.postJSON)(this.ctx, "/v1/_teamdef", { op: "verify", name, content_sha256: contentSha256 }, opts);
1276
+ }
1243
1277
  /** Hard-remove a whole team by name — all versions + the active pointer
1244
1278
  * (op=delete), scoped to the caller's tenant. Teams are runtime-only, so
1245
1279
  * this is how an operator clears an obsolete/test team. */
1246
1280
  async deleteTeam(name, opts) {
1247
1281
  return (0, fetch_helpers_js_1.postJSON)(this.ctx, "/v1/_teamdef", { op: "delete", name }, opts);
1248
1282
  }
1249
- /** Execute a team (op=run) — walk its state graph, spawning each state's agent
1250
- * until a terminal state, returning the per-state trace. Target the active
1251
- * version by `name` OR a specific version by `defId`. `input` is the initial
1252
- * task handed to the entry state's agent. The walk runs under the same
1253
- * admission a normal run gets (token budget / operator-key / depth). */
1254
1283
  async runTeam(target, opts) {
1255
1284
  const body = { op: "run" };
1256
1285
  if (target.name !== undefined)
@@ -1263,8 +1292,39 @@ class LoomcycleClient {
1263
1292
  body.board_chunk_id = target.boardChunkId;
1264
1293
  if (target.boardScope !== undefined)
1265
1294
  body.board_scope = target.boardScope;
1295
+ if (target.mode !== undefined)
1296
+ body.mode = target.mode;
1297
+ if (target.breakpoints !== undefined)
1298
+ body.breakpoints = target.breakpoints;
1266
1299
  return (0, fetch_helpers_js_1.postJSON)(this.ctx, "/v1/_teamdef", body, opts);
1267
1300
  }
1301
+ /** Read the debug breakpoints armed on a live team walk
1302
+ * (`GET /v1/runs/{run_id}/breakpoints`).
1303
+ *
1304
+ * 404 when no walk is in flight under that run on this replica — loudly,
1305
+ * because an arming that appeared to succeed and then never paused anything
1306
+ * is the worst possible outcome for a debugger. Surface it rather than
1307
+ * treating it as "nothing armed". */
1308
+ async getRunBreakpoints(runId, opts) {
1309
+ return (0, fetch_helpers_js_1.jsonFetch)(this.ctx, `/v1/runs/${encodeURIComponent(runId)}/breakpoints`, opts);
1310
+ }
1311
+ /** Replace the debug breakpoints armed on a live team walk
1312
+ * (`PUT /v1/runs/{run_id}/breakpoints`).
1313
+ *
1314
+ * The WHOLE desired set, not a delta: you hold the configuration and push
1315
+ * it, so two operators cannot interleave a read-modify-write. `[]` is the
1316
+ * off switch. A malformed entry is refused whole and leaves the previous
1317
+ * arming exactly as it was.
1318
+ *
1319
+ * Each entry is a starter state id — `"review"` arms both phases,
1320
+ * `"review:before_dispatch"` or `"review:after_collection"` arms one. An arm
1321
+ * takes effect at the next pause the walk reaches; disarming RELEASES
1322
+ * whatever is still pending rather than stranding it.
1323
+ *
1324
+ * A pause is read and answered through the run's interrupts. */
1325
+ async setRunBreakpoints(runId, breakpoints, opts) {
1326
+ return (0, fetch_helpers_js_1.putJSON)(this.ctx, `/v1/runs/${encodeURIComponent(runId)}/breakpoints`, { breakpoints }, opts);
1327
+ }
1268
1328
  /** Invoke the RFC AL Path VFS tool over HTTP (`POST /v1/_path`). A
1269
1329
  * Unix-like filesystem over your Memory entries, Volume mounts, and
1270
1330
  * Documents — address them by human-readable paths (e.g. /docs/launch).
@@ -1772,6 +1832,8 @@ class LoomcycleClient {
1772
1832
  body.publisher = opts.publisher;
1773
1833
  if (opts.period !== undefined)
1774
1834
  body.period = opts.period;
1835
+ if (opts.hold !== undefined)
1836
+ body.hold = opts.hold;
1775
1837
  return (0, fetch_helpers_js_1.postJSON)(this.ctx, "/v1/_channels", body, {
1776
1838
  signal: opts.signal,
1777
1839
  });
@@ -1789,6 +1851,8 @@ class LoomcycleClient {
1789
1851
  body.max_messages = opts.max_messages;
1790
1852
  if (opts.semantic !== undefined)
1791
1853
  body.semantic = opts.semantic;
1854
+ if (opts.hold !== undefined)
1855
+ body.hold = opts.hold;
1792
1856
  return (0, fetch_helpers_js_1.patchJSON)(this.ctx, `/v1/_channels/${encodeURIComponent(name)}`, body, { signal: opts.signal });
1793
1857
  }
1794
1858
  /** Delete a runtime-substrate channel + cascade its persisted
@@ -1807,6 +1871,21 @@ class LoomcycleClient {
1807
1871
  async purgeChannel(name, opts) {
1808
1872
  return (0, fetch_helpers_js_1.postJSON)(this.ctx, `/v1/_channels/${encodeURIComponent(name)}/purge`, {}, { signal: opts?.signal });
1809
1873
  }
1874
+ /** Hand the oldest `count` (default 1) messages held on a `hold:`
1875
+ * channel to its subscribers. Allowed on yaml-declared channels —
1876
+ * releasing moves messages, it does not mutate the definition.
1877
+ * Releasing a channel with nothing held reports zero rather than
1878
+ * failing. */
1879
+ async releaseChannel(name, opts) {
1880
+ const body = {};
1881
+ if (opts?.count !== undefined)
1882
+ body.count = opts.count;
1883
+ if (opts?.scope !== undefined)
1884
+ body.scope = opts.scope;
1885
+ if (opts?.scope_id !== undefined)
1886
+ body.scope_id = opts.scope_id;
1887
+ return (0, fetch_helpers_js_1.postJSON)(this.ctx, `/v1/_channels/${encodeURIComponent(name)}/release`, body, { signal: opts?.signal });
1888
+ }
1810
1889
  // ---- v0.11.5 Memory entry admin CRUD ----
1811
1890
  /** Idempotently upsert one memory entry by full (scope, scope_id,
1812
1891
  * key) identifier. PUT semantics — re-writes overwrite the value.
package/dist/cjs/index.js CHANGED
@@ -84,6 +84,9 @@
84
84
  * forkTeam(name, overlay): Promise<CreatedTeam>
85
85
  * deleteTeam(name): Promise<{name, deleted}>
86
86
  * runTeam({name|defId, input}): Promise<TeamRunResult>
87
+ * runTeam({..., mode:"detach"}): Promise<TeamRunDetached> // the handle, now — the walk runs on
88
+ * getRunBreakpoints(runId): Promise<TeamBreakpoints> // debug a walk that is already running
89
+ * setRunBreakpoints(runId, breakpoints): Promise<TeamBreakpoints>
87
90
  *
88
91
  * // Path VFS + chunked-graph Documents on the wire (v1.4.0 — RFC AL / RFC AK)
89
92
  * path(input): Promise<PathToolResponse> // resolve/ls/stat/mkdir/mv/rm
package/dist/client.d.ts CHANGED
@@ -25,7 +25,7 @@
25
25
  */
26
26
  import { InteractiveSession } from "./interactive.js";
27
27
  import { ClientToolHost, type ConnectClientToolsOptions } from "./client-tools.js";
28
- import type { CredentialListResponse, CredentialMeta, CredentialScope, DirectoryInspection, DirectoryTenant, DirectoryUser, ErasureReport, ErasureResult, Agent, AgentEvent, AgentStatus, CancelAgentResult, ClientOptions, ContinueOptions, CreateSnapshotOptions, EnsureCodeAgentOptions, EnsureCodeAgentResult, EnsureMcpServerOptions, EnsureMcpServerResult, HealthResponse, Hook, InterruptListResponse, InterruptStatus, AckChannelOptions, AwaitChannelsOptions, BroadcastChannelsOptions, ChannelAckResult, ChannelAwaitResult, ChannelBroadcastResult, ChannelDescriptor, ChannelPeekResult, ChannelPublishResult, ChannelPurgeResult, ChannelSubscribeResult, CreateChannelOptions, ListChannelsResponse, PeekChannelOptions, PublishChannelOptions, SetMemoryEntryOptions, SetMemoryEntryResponse, SubscribeChannelOptions, UpdateChannelOptions, LibraryAgentDefinition, LibraryListResponse, LibraryMcpServerDefinition, LibrarySkillDefinition, ListUsersResponse, UserRecord, CreateUserBody, UpdateUserBody, MintedUserToken, ListUserTokensResponse, RunnableAgentsResponse, LLMChatOptions, LLMChatResponse, LLMChatStreamItem, LLMEmbeddingsOptions, LLMEmbeddingsResponse, MCPServerDefVerifyResult, MemoryEmbedStatsResponse, MemoryEntriesResponse, MemoryEntryResponse, MemoryBackfillResponse, MemoryPurgeResponse, MemoryReembedResponse, MemoryScopeIDsResponse, MemoryScopesResponse, MemorySearchInput, MemorySearchResponse, PauseResult, PersistentVolumesResponse, EphemeralVolumesResponse, RegisterHookOptions, RegisterHookResponse, ResolveInterruptOptions, ResumeResult, ResolverMatrix, CompactRunResult, ReplaySessionResult, CancelTurnResult, RunBatchOptions, RunBatchResult, RunOptions, RunStateStreamItem, RuntimeStateResponse, SnapshotCreateResponse, SnapshotDescriptor, SnapshotEnvelope, SnapshotRestoreResponse, StreamUserRunStatesOptions, SubstrateToolInput, SubstrateToolResponse, CreatedTeam, ListTeamsResponse, TeamDefDetail, TeamDiagram, TeamRunResult, PathToolInput, PathToolResponse, DocumentToolInput, DocumentToolResponse, HistoryToolInput, HistoryToolResponse, TranscriptResponse, WhoamiResponse, UsageDimension, UsageReportResponse, TokenLimit, TokenLimitsResponse, ConfigResponse, SetTokenLimitRequest } from "./types.js";
28
+ import type { CredentialListResponse, CredentialMeta, CredentialScope, DirectoryInspection, DirectoryTenant, DirectoryUser, ErasureReport, ErasureResult, Agent, AgentEvent, AgentStatus, CancelAgentResult, ClientOptions, ContinueOptions, CreateSnapshotOptions, EnsureCodeAgentOptions, EnsureCodeAgentResult, EnsureMcpServerOptions, EnsureMcpServerResult, HealthResponse, Hook, InterruptListResponse, InterruptStatus, AckChannelOptions, AwaitChannelsOptions, BroadcastChannelsOptions, ChannelAckResult, ChannelAwaitResult, ChannelBroadcastResult, ChannelDescriptor, ChannelPeekResult, ChannelPublishResult, ChannelPurgeResult, ChannelReleaseResult, ChannelSubscribeResult, CreateChannelOptions, ListChannelsResponse, PeekChannelOptions, PublishChannelOptions, ReleaseChannelOptions, SetMemoryEntryOptions, SetMemoryEntryResponse, SubscribeChannelOptions, UpdateChannelOptions, LibraryAgentDefinition, LibraryListResponse, LibraryMcpServerDefinition, LibrarySkillDefinition, ListUsersResponse, UserRecord, CreateUserBody, UpdateUserBody, MintedUserToken, ListUserTokensResponse, RunnableAgentsResponse, LLMChatOptions, LLMChatResponse, LLMChatStreamItem, LLMEmbeddingsOptions, LLMEmbeddingsResponse, MCPServerDefVerifyResult, MemoryEmbedStatsResponse, MemoryEntriesResponse, MemoryEntryResponse, MemoryBackfillResponse, MemoryPurgeResponse, MemoryReembedResponse, MemoryScopeIDsResponse, MemoryScopesResponse, MemorySearchInput, MemorySearchResponse, PauseResult, PersistentVolumesResponse, EphemeralVolumesResponse, RegisterHookOptions, RegisterHookResponse, ResolveInterruptOptions, ResumeResult, ResolverMatrix, CompactRunResult, ReplaySessionResult, CancelTurnResult, RunBatchOptions, RunBatchResult, RunOptions, RunStateStreamItem, RuntimeStateResponse, SnapshotCreateResponse, SnapshotDescriptor, SnapshotEnvelope, SnapshotRestoreResponse, StreamUserRunStatesOptions, SubstrateToolInput, SubstrateToolResponse, CreatedTeam, ListTeamsResponse, PromotedTeam, RetiredTeam, TeamBreakpoints, TeamDefDetail, TeamRunDetached, TeamRunTarget, TeamVerification, TeamVersionList, TeamDiagram, TeamRunResult, PathToolInput, PathToolResponse, DocumentToolInput, DocumentToolResponse, HistoryToolInput, HistoryToolResponse, TranscriptResponse, WhoamiResponse, UsageDimension, UsageReportResponse, TokenLimit, TokenLimitsResponse, ConfigResponse, SetTokenLimitRequest } from "./types.js";
29
29
  export declare class LoomcycleClient {
30
30
  private ctx;
31
31
  constructor(opts?: ClientOptions);
@@ -870,6 +870,40 @@ export declare class LoomcycleClient {
870
870
  forkTeam(name: string, overlay: Record<string, unknown>, opts?: {
871
871
  signal?: AbortSignal;
872
872
  }): Promise<CreatedTeam>;
873
+ /** List every version of ONE team, newest first (op=list) — the lineage
874
+ * behind {@link LoomcycleClient.listTeams}' roll-up. Tenant-scoped
875
+ * server-side; a name with no versions returns an empty list rather than
876
+ * raising. */
877
+ listTeamVersions(name: string, opts?: {
878
+ signal?: AbortSignal;
879
+ }): Promise<TeamVersionList>;
880
+ /** Point the team's active pointer at one version (op=promote) — what a new
881
+ * run of the team by NAME will execute.
882
+ *
883
+ * `forkTeam` defaults to promote:false, so authoring a version and putting
884
+ * it in force are deliberately two steps: an edited graph can be reviewed,
885
+ * diagrammed, even run by `defId`, before it becomes what the name means. */
886
+ promoteTeam(defId: string, opts?: {
887
+ signal?: AbortSignal;
888
+ }): Promise<PromotedTeam>;
889
+ /** Soft-retire one version, or un-retire it (op=retire, `retired` required).
890
+ *
891
+ * Retiring is REVERSIBLE and version-scoped: the row stays, its history stays
892
+ * readable, and passing `false` brings it back. Removing a team is
893
+ * {@link LoomcycleClient.deleteTeam}, which is neither. */
894
+ retireTeam(defId: string, retired: boolean, opts?: {
895
+ signal?: AbortSignal;
896
+ }): Promise<RetiredTeam>;
897
+ /** Compare a locally computed content hash against the deployed active
898
+ * version (op=verify) — the drift check for a team kept in source control
899
+ * and pushed to several deployments.
900
+ *
901
+ * Never raises for an absent team: a name with no active version answers
902
+ * `{deployed: false, matches: false}`, which a caller distinguishes from a
903
+ * deployed version whose hash differs. */
904
+ verifyTeam(name: string, contentSha256: string, opts?: {
905
+ signal?: AbortSignal;
906
+ }): Promise<TeamVerification>;
873
907
  /** Hard-remove a whole team by name — all versions + the active pointer
874
908
  * (op=delete), scoped to the caller's tenant. Teams are runtime-only, so
875
909
  * this is how an operator clears an obsolete/test team. */
@@ -884,21 +918,43 @@ export declare class LoomcycleClient {
884
918
  * version by `name` OR a specific version by `defId`. `input` is the initial
885
919
  * task handed to the entry state's agent. The walk runs under the same
886
920
  * admission a normal run gets (token budget / operator-key / depth). */
887
- runTeam(target: {
888
- name?: string;
889
- defId?: string;
890
- input?: string;
891
- /** Bind the walk to a Document chunk task board (RFC BT P4): each state
892
- * transition persists `chunk.status` = the current team state, and every
893
- * handler run this walk spawns carries the task key on its
894
- * `parent_context` (so a board client can pin the live agent to the
895
- * card). Omit for an ephemeral run. */
896
- boardChunkId?: string;
897
- /** The Document scope of `boardChunkId` (agent | user, default user). */
898
- boardScope?: "agent" | "user";
921
+ runTeam(target: TeamRunTarget & {
922
+ mode: "detach";
923
+ }, opts?: {
924
+ signal?: AbortSignal;
925
+ }): Promise<TeamRunDetached>;
926
+ runTeam(target: TeamRunTarget & {
927
+ mode?: undefined;
899
928
  }, opts?: {
900
929
  signal?: AbortSignal;
901
930
  }): Promise<TeamRunResult>;
931
+ /** Read the debug breakpoints armed on a live team walk
932
+ * (`GET /v1/runs/{run_id}/breakpoints`).
933
+ *
934
+ * 404 when no walk is in flight under that run on this replica — loudly,
935
+ * because an arming that appeared to succeed and then never paused anything
936
+ * is the worst possible outcome for a debugger. Surface it rather than
937
+ * treating it as "nothing armed". */
938
+ getRunBreakpoints(runId: string, opts?: {
939
+ signal?: AbortSignal;
940
+ }): Promise<TeamBreakpoints>;
941
+ /** Replace the debug breakpoints armed on a live team walk
942
+ * (`PUT /v1/runs/{run_id}/breakpoints`).
943
+ *
944
+ * The WHOLE desired set, not a delta: you hold the configuration and push
945
+ * it, so two operators cannot interleave a read-modify-write. `[]` is the
946
+ * off switch. A malformed entry is refused whole and leaves the previous
947
+ * arming exactly as it was.
948
+ *
949
+ * Each entry is a starter state id — `"review"` arms both phases,
950
+ * `"review:before_dispatch"` or `"review:after_collection"` arms one. An arm
951
+ * takes effect at the next pause the walk reaches; disarming RELEASES
952
+ * whatever is still pending rather than stranding it.
953
+ *
954
+ * A pause is read and answered through the run's interrupts. */
955
+ setRunBreakpoints(runId: string, breakpoints: string[], opts?: {
956
+ signal?: AbortSignal;
957
+ }): Promise<TeamBreakpoints>;
902
958
  /** Invoke the RFC AL Path VFS tool over HTTP (`POST /v1/_path`). A
903
959
  * Unix-like filesystem over your Memory entries, Volume mounts, and
904
960
  * Documents — address them by human-readable paths (e.g. /docs/launch).
@@ -1185,6 +1241,12 @@ export declare class LoomcycleClient {
1185
1241
  purgeChannel(name: string, opts?: {
1186
1242
  signal?: AbortSignal;
1187
1243
  }): Promise<ChannelPurgeResult>;
1244
+ /** Hand the oldest `count` (default 1) messages held on a `hold:`
1245
+ * channel to its subscribers. Allowed on yaml-declared channels —
1246
+ * releasing moves messages, it does not mutate the definition.
1247
+ * Releasing a channel with nothing held reports zero rather than
1248
+ * failing. */
1249
+ releaseChannel(name: string, opts?: ReleaseChannelOptions): Promise<ChannelReleaseResult>;
1188
1250
  /** Idempotently upsert one memory entry by full (scope, scope_id,
1189
1251
  * key) identifier. PUT semantics — re-writes overwrite the value.
1190
1252
  * Optional embed flag triggers a synchronous embed via the
package/dist/client.js CHANGED
@@ -1237,17 +1237,46 @@ export class LoomcycleClient {
1237
1237
  async forkTeam(name, overlay, opts) {
1238
1238
  return postJSON(this.ctx, "/v1/_teamdef", { op: "fork", name, overlay }, opts);
1239
1239
  }
1240
+ /** List every version of ONE team, newest first (op=list) — the lineage
1241
+ * behind {@link LoomcycleClient.listTeams}' roll-up. Tenant-scoped
1242
+ * server-side; a name with no versions returns an empty list rather than
1243
+ * raising. */
1244
+ async listTeamVersions(name, opts) {
1245
+ return postJSON(this.ctx, "/v1/_teamdef", { op: "list", name }, opts);
1246
+ }
1247
+ /** Point the team's active pointer at one version (op=promote) — what a new
1248
+ * run of the team by NAME will execute.
1249
+ *
1250
+ * `forkTeam` defaults to promote:false, so authoring a version and putting
1251
+ * it in force are deliberately two steps: an edited graph can be reviewed,
1252
+ * diagrammed, even run by `defId`, before it becomes what the name means. */
1253
+ async promoteTeam(defId, opts) {
1254
+ return postJSON(this.ctx, "/v1/_teamdef", { op: "promote", def_id: defId }, opts);
1255
+ }
1256
+ /** Soft-retire one version, or un-retire it (op=retire, `retired` required).
1257
+ *
1258
+ * Retiring is REVERSIBLE and version-scoped: the row stays, its history stays
1259
+ * readable, and passing `false` brings it back. Removing a team is
1260
+ * {@link LoomcycleClient.deleteTeam}, which is neither. */
1261
+ async retireTeam(defId, retired, opts) {
1262
+ return postJSON(this.ctx, "/v1/_teamdef", { op: "retire", def_id: defId, retired }, opts);
1263
+ }
1264
+ /** Compare a locally computed content hash against the deployed active
1265
+ * version (op=verify) — the drift check for a team kept in source control
1266
+ * and pushed to several deployments.
1267
+ *
1268
+ * Never raises for an absent team: a name with no active version answers
1269
+ * `{deployed: false, matches: false}`, which a caller distinguishes from a
1270
+ * deployed version whose hash differs. */
1271
+ async verifyTeam(name, contentSha256, opts) {
1272
+ return postJSON(this.ctx, "/v1/_teamdef", { op: "verify", name, content_sha256: contentSha256 }, opts);
1273
+ }
1240
1274
  /** Hard-remove a whole team by name — all versions + the active pointer
1241
1275
  * (op=delete), scoped to the caller's tenant. Teams are runtime-only, so
1242
1276
  * this is how an operator clears an obsolete/test team. */
1243
1277
  async deleteTeam(name, opts) {
1244
1278
  return postJSON(this.ctx, "/v1/_teamdef", { op: "delete", name }, opts);
1245
1279
  }
1246
- /** Execute a team (op=run) — walk its state graph, spawning each state's agent
1247
- * until a terminal state, returning the per-state trace. Target the active
1248
- * version by `name` OR a specific version by `defId`. `input` is the initial
1249
- * task handed to the entry state's agent. The walk runs under the same
1250
- * admission a normal run gets (token budget / operator-key / depth). */
1251
1280
  async runTeam(target, opts) {
1252
1281
  const body = { op: "run" };
1253
1282
  if (target.name !== undefined)
@@ -1260,8 +1289,39 @@ export class LoomcycleClient {
1260
1289
  body.board_chunk_id = target.boardChunkId;
1261
1290
  if (target.boardScope !== undefined)
1262
1291
  body.board_scope = target.boardScope;
1292
+ if (target.mode !== undefined)
1293
+ body.mode = target.mode;
1294
+ if (target.breakpoints !== undefined)
1295
+ body.breakpoints = target.breakpoints;
1263
1296
  return postJSON(this.ctx, "/v1/_teamdef", body, opts);
1264
1297
  }
1298
+ /** Read the debug breakpoints armed on a live team walk
1299
+ * (`GET /v1/runs/{run_id}/breakpoints`).
1300
+ *
1301
+ * 404 when no walk is in flight under that run on this replica — loudly,
1302
+ * because an arming that appeared to succeed and then never paused anything
1303
+ * is the worst possible outcome for a debugger. Surface it rather than
1304
+ * treating it as "nothing armed". */
1305
+ async getRunBreakpoints(runId, opts) {
1306
+ return jsonFetch(this.ctx, `/v1/runs/${encodeURIComponent(runId)}/breakpoints`, opts);
1307
+ }
1308
+ /** Replace the debug breakpoints armed on a live team walk
1309
+ * (`PUT /v1/runs/{run_id}/breakpoints`).
1310
+ *
1311
+ * The WHOLE desired set, not a delta: you hold the configuration and push
1312
+ * it, so two operators cannot interleave a read-modify-write. `[]` is the
1313
+ * off switch. A malformed entry is refused whole and leaves the previous
1314
+ * arming exactly as it was.
1315
+ *
1316
+ * Each entry is a starter state id — `"review"` arms both phases,
1317
+ * `"review:before_dispatch"` or `"review:after_collection"` arms one. An arm
1318
+ * takes effect at the next pause the walk reaches; disarming RELEASES
1319
+ * whatever is still pending rather than stranding it.
1320
+ *
1321
+ * A pause is read and answered through the run's interrupts. */
1322
+ async setRunBreakpoints(runId, breakpoints, opts) {
1323
+ return putJSON(this.ctx, `/v1/runs/${encodeURIComponent(runId)}/breakpoints`, { breakpoints }, opts);
1324
+ }
1265
1325
  /** Invoke the RFC AL Path VFS tool over HTTP (`POST /v1/_path`). A
1266
1326
  * Unix-like filesystem over your Memory entries, Volume mounts, and
1267
1327
  * Documents — address them by human-readable paths (e.g. /docs/launch).
@@ -1769,6 +1829,8 @@ export class LoomcycleClient {
1769
1829
  body.publisher = opts.publisher;
1770
1830
  if (opts.period !== undefined)
1771
1831
  body.period = opts.period;
1832
+ if (opts.hold !== undefined)
1833
+ body.hold = opts.hold;
1772
1834
  return postJSON(this.ctx, "/v1/_channels", body, {
1773
1835
  signal: opts.signal,
1774
1836
  });
@@ -1786,6 +1848,8 @@ export class LoomcycleClient {
1786
1848
  body.max_messages = opts.max_messages;
1787
1849
  if (opts.semantic !== undefined)
1788
1850
  body.semantic = opts.semantic;
1851
+ if (opts.hold !== undefined)
1852
+ body.hold = opts.hold;
1789
1853
  return patchJSON(this.ctx, `/v1/_channels/${encodeURIComponent(name)}`, body, { signal: opts.signal });
1790
1854
  }
1791
1855
  /** Delete a runtime-substrate channel + cascade its persisted
@@ -1804,6 +1868,21 @@ export class LoomcycleClient {
1804
1868
  async purgeChannel(name, opts) {
1805
1869
  return postJSON(this.ctx, `/v1/_channels/${encodeURIComponent(name)}/purge`, {}, { signal: opts?.signal });
1806
1870
  }
1871
+ /** Hand the oldest `count` (default 1) messages held on a `hold:`
1872
+ * channel to its subscribers. Allowed on yaml-declared channels —
1873
+ * releasing moves messages, it does not mutate the definition.
1874
+ * Releasing a channel with nothing held reports zero rather than
1875
+ * failing. */
1876
+ async releaseChannel(name, opts) {
1877
+ const body = {};
1878
+ if (opts?.count !== undefined)
1879
+ body.count = opts.count;
1880
+ if (opts?.scope !== undefined)
1881
+ body.scope = opts.scope;
1882
+ if (opts?.scope_id !== undefined)
1883
+ body.scope_id = opts.scope_id;
1884
+ return postJSON(this.ctx, `/v1/_channels/${encodeURIComponent(name)}/release`, body, { signal: opts?.signal });
1885
+ }
1807
1886
  // ---- v0.11.5 Memory entry admin CRUD ----
1808
1887
  /** Idempotently upsert one memory entry by full (scope, scope_id,
1809
1888
  * key) identifier. PUT semantics — re-writes overwrite the value.
package/dist/index.d.ts CHANGED
@@ -83,6 +83,9 @@
83
83
  * forkTeam(name, overlay): Promise<CreatedTeam>
84
84
  * deleteTeam(name): Promise<{name, deleted}>
85
85
  * runTeam({name|defId, input}): Promise<TeamRunResult>
86
+ * runTeam({..., mode:"detach"}): Promise<TeamRunDetached> // the handle, now — the walk runs on
87
+ * getRunBreakpoints(runId): Promise<TeamBreakpoints> // debug a walk that is already running
88
+ * setRunBreakpoints(runId, breakpoints): Promise<TeamBreakpoints>
86
89
  *
87
90
  * // Path VFS + chunked-graph Documents on the wire (v1.4.0 — RFC AL / RFC AK)
88
91
  * path(input): Promise<PathToolResponse> // resolve/ls/stat/mkdir/mv/rm
@@ -125,5 +128,5 @@ export { InteractiveSession } from "./interactive.js";
125
128
  export type { InteractiveSessionOps } from "./interactive.js";
126
129
  export { ClientToolHost, clientToolsURL, CLIENT_TOOL_SUBPROTOCOL } from "./client-tools.js";
127
130
  export type { ClientToolSchema, ClientToolInvocation, ConnectClientToolsOptions, WebSocketLike, WebSocketCtor, } from "./client-tools.js";
128
- export type { AgentEvent, ClientOptions, ContinueOptions, EventType, HostWidening, ImageMediaType, ParentContext, PromptContent, PromptSegment, RetryInfo, RunOptions, SamplingOptions, CompactionOptions, ToolUse, Usage, Agent, AgentStatus, AgentUsage, CancelAgentResult, ListAgentsResponse, RunBatchOptions, RunBatchResult, SpawnRunResult, CompactRunResult, DirectoryBudget, DirectoryInspection, DirectoryTenant, DirectoryUser, ErasureReport, ErasureResidue, ErasureResult, ErasureTier, CancelTurnResult, TranscriptEvent, TranscriptResponse, HealthResponse, ListUsersResponse, UserSummary, UserRecord, CreateUserBody, UpdateUserBody, MintedUserToken, UserTokenMeta, ListUserTokensResponse, RunnableAgent, RunnableAgentsResponse, WhoamiResponse, PauseResult, ResumeResult, RuntimeStateResponse, RuntimeStateStatus, ResolverMatrix, ResolverModelStatus, ResolverProviderAvailability, CreateSnapshotOptions, SnapshotCreateResponse, SnapshotDescriptor, SnapshotEnvelope, SnapshotListResponse, SnapshotRestoreResponse, MemoryEntriesResponse, MemoryEntry, MemoryEntryResponse, MemoryScopeIDsResponse, MemoryScopeIDSummary, MemoryScopeKind, MemoryScopesResponse, MemorySearchInput, MemorySource, MemoryWhen, MemoryTimeFilter, MemorySearchEntry, MemorySearchResponse, MemoryEmbedModelStats, MemoryEmbedStatsResponse, MemoryReembedConfigured, MemoryReembedResponse, MemoryBackfillResponse, MemoryPurgeResponse, InterruptListResponse, InterruptRow, InterruptStatus, ResolveInterruptOptions, Hook, HookFailMode, HookPhase, HookToolCall, HookToolResult, ListHooksResponse, PostHookCall, PostHookResult, PreHookCall, PreHookResult, RegisterHookOptions, RegisterHookResponse, SubstrateToolInput, SubstrateToolResponse, TeamNameSummary, ListTeamsResponse, TeamDiagram, CreatedTeam, TeamDefDetail, TeamRunResult, PathToolInput, PathToolResponse, DocumentToolInput, DocumentToolResponse, HistoryToolInput, HistoryToolResponse, VolumeMode, PersistentVolumeEntry, PersistentVolumesResponse, EphemeralVolumeEntry, EphemeralVolumesResponse, SystemPromptPayload, UserInputPayload, ChannelDescriptor, ListChannelsResponse, RunStateEvent, RunStateStreamClose, RunStateStreamItem, RunStateStreamOpen, StreamUserRunStatesOptions, AckChannelOptions, ChannelAckResult, ChannelMessageItem, ChannelPeekResult, ChannelPublishResult, ChannelPurgeResult, ChannelScope, ChannelSubscribeResult, PeekChannelOptions, PublishChannelOptions, SubscribeChannelOptions, AwaitChannelsOptions, BroadcastChannelsOptions, ChannelAwaitEntry, ChannelAwaitMode, ChannelAwaitResult, ChannelBroadcastEntry, ChannelBroadcastResult, CreateChannelOptions, UpdateChannelOptions, SetMemoryEntryOptions, SetMemoryEntryResponse, AgentDefRowResponse, AgentDefVerifyResult, SkillDefVerifyResult, EnsureMcpServerOptions, EnsureMcpServerResult, MCPServerDefRowResponse, MCPServerDefVerifyResult, AgentDefOverlay, EnsureCodeAgentOptions, EnsureCodeAgentResult, LibraryAgentDefinition, LibraryEntry, LibraryListResponse, LibraryMcpServerDefinition, LibrarySkillDefinition, LLMChatContent, LLMChatMessage, LLMChatOptions, LLMChatResponse, LLMChatStreamDelta, LLMChatStreamItem, LLMChatToolCall, LLMChatUsage, LLMTool, LLMEmbeddingItem, LLMEmbeddingsOptions, LLMEmbeddingsResponse, LLMEmbeddingsUsage, UsageDimension, UsageAggregate, UsageReportResponse, LimitInfo, TokenLimit, TokenLimitsResponse, ConfigResponse, ConfigProvider, ConfigModel, ConfigSearch, ConfigInstance, SetTokenLimitRequest, CredentialScope, CredentialMeta, CredentialListResponse, } from "./types.js";
131
+ export type { AgentEvent, ClientOptions, ContinueOptions, EventType, HostWidening, ImageMediaType, ParentContext, PromptContent, PromptSegment, RetryInfo, RunOptions, SamplingOptions, CompactionOptions, ToolUse, Usage, Agent, AgentStatus, AgentUsage, CancelAgentResult, ListAgentsResponse, RunBatchOptions, RunBatchResult, SpawnRunResult, CompactRunResult, DirectoryBudget, DirectoryInspection, DirectoryTenant, DirectoryUser, ErasureReport, ErasureResidue, ErasureResult, ErasureTier, CancelTurnResult, TranscriptEvent, TranscriptResponse, HealthResponse, ListUsersResponse, UserSummary, UserRecord, CreateUserBody, UpdateUserBody, MintedUserToken, UserTokenMeta, ListUserTokensResponse, RunnableAgent, RunnableAgentsResponse, WhoamiResponse, PauseResult, ResumeResult, RuntimeStateResponse, RuntimeStateStatus, ResolverMatrix, ResolverModelStatus, ResolverProviderAvailability, CreateSnapshotOptions, SnapshotCreateResponse, SnapshotDescriptor, SnapshotEnvelope, SnapshotListResponse, SnapshotRestoreResponse, MemoryEntriesResponse, MemoryEntry, MemoryEntryResponse, MemoryScopeIDsResponse, MemoryScopeIDSummary, MemoryScopeKind, MemoryScopesResponse, MemorySearchInput, MemorySource, MemoryWhen, MemoryTimeFilter, MemorySearchEntry, MemorySearchResponse, MemoryEmbedModelStats, MemoryEmbedStatsResponse, MemoryReembedConfigured, MemoryReembedResponse, MemoryBackfillResponse, MemoryPurgeResponse, InterruptListResponse, InterruptRow, InterruptStatus, ResolveInterruptOptions, Hook, HookFailMode, HookPhase, HookToolCall, HookToolResult, ListHooksResponse, PostHookCall, PostHookResult, PreHookCall, PreHookResult, RegisterHookOptions, RegisterHookResponse, SubstrateToolInput, SubstrateToolResponse, TeamNameSummary, ListTeamsResponse, TeamDiagram, CreatedTeam, PromotedTeam, RetiredTeam, TeamDefDetail, TeamVerification, TeamVersion, TeamVersionList, TeamBreakpoints, TeamRunDetached, TeamRunResult, TeamRunTarget, PathToolInput, PathToolResponse, DocumentToolInput, DocumentToolResponse, HistoryToolInput, HistoryToolResponse, VolumeMode, PersistentVolumeEntry, PersistentVolumesResponse, EphemeralVolumeEntry, EphemeralVolumesResponse, SystemPromptPayload, UserInputPayload, ChannelDescriptor, ListChannelsResponse, RunStateEvent, RunStateStreamClose, RunStateStreamItem, RunStateStreamOpen, StreamUserRunStatesOptions, AckChannelOptions, ChannelAckResult, ChannelMessageItem, ChannelPeekResult, ChannelPublishResult, ChannelPurgeResult, ChannelReleaseResult, ChannelScope, ChannelSubscribeResult, PeekChannelOptions, PublishChannelOptions, SubscribeChannelOptions, AwaitChannelsOptions, BroadcastChannelsOptions, ChannelAwaitEntry, ChannelAwaitMode, ChannelAwaitResult, ChannelBroadcastEntry, ChannelBroadcastResult, CreateChannelOptions, ReleaseChannelOptions, UpdateChannelOptions, SetMemoryEntryOptions, SetMemoryEntryResponse, AgentDefRowResponse, AgentDefVerifyResult, SkillDefVerifyResult, EnsureMcpServerOptions, EnsureMcpServerResult, MCPServerDefRowResponse, MCPServerDefVerifyResult, AgentDefOverlay, EnsureCodeAgentOptions, EnsureCodeAgentResult, LibraryAgentDefinition, LibraryEntry, LibraryListResponse, LibraryMcpServerDefinition, LibrarySkillDefinition, LLMChatContent, LLMChatMessage, LLMChatOptions, LLMChatResponse, LLMChatStreamDelta, LLMChatStreamItem, LLMChatToolCall, LLMChatUsage, LLMTool, LLMEmbeddingItem, LLMEmbeddingsOptions, LLMEmbeddingsResponse, LLMEmbeddingsUsage, UsageDimension, UsageAggregate, UsageReportResponse, LimitInfo, TokenLimit, TokenLimitsResponse, ConfigResponse, ConfigProvider, ConfigModel, ConfigSearch, ConfigInstance, SetTokenLimitRequest, CredentialScope, CredentialMeta, CredentialListResponse, } from "./types.js";
129
132
  export { AgentIDInUseError, AgentNotFoundError, AlreadyPausingError, AuthError, BackpressureError, HookNotFoundError, NotFoundError, InvalidArgumentError, ChannelCursorRegressionError, LoomcycleError, NotPausedError, PauseNotConfiguredError, PerUserQuotaExhaustedError, SessionBusyError, SessionNotFoundError, SnapshotNotFoundError, SnapshotTooLargeError, SnapshotVersionError, SubstrateToolRefusedError, UnavailableError, } from "./errors.js";
package/dist/index.js CHANGED
@@ -83,6 +83,9 @@
83
83
  * forkTeam(name, overlay): Promise<CreatedTeam>
84
84
  * deleteTeam(name): Promise<{name, deleted}>
85
85
  * runTeam({name|defId, input}): Promise<TeamRunResult>
86
+ * runTeam({..., mode:"detach"}): Promise<TeamRunDetached> // the handle, now — the walk runs on
87
+ * getRunBreakpoints(runId): Promise<TeamBreakpoints> // debug a walk that is already running
88
+ * setRunBreakpoints(runId, breakpoints): Promise<TeamBreakpoints>
86
89
  *
87
90
  * // Path VFS + chunked-graph Documents on the wire (v1.4.0 — RFC AL / RFC AK)
88
91
  * path(input): Promise<PathToolResponse> // resolve/ls/stat/mkdir/mv/rm
package/dist/types.d.ts CHANGED
@@ -1210,6 +1210,57 @@ export interface TeamDefDetail {
1210
1210
  content_sha256?: string;
1211
1211
  definition: unknown;
1212
1212
  }
1213
+ /** One team version's record in {@link TeamVersionList} (op=list). Same shape
1214
+ * as {@link TeamDefDetail} plus the lineage + authorship fields the version
1215
+ * history needs — who wrote it, when, and which version it forked from. */
1216
+ export interface TeamVersion {
1217
+ def_id: string;
1218
+ name: string;
1219
+ version: number;
1220
+ parent_def_id?: string;
1221
+ description?: string;
1222
+ created_at?: string;
1223
+ created_by_agent_id?: string;
1224
+ retired?: boolean;
1225
+ bootstrapped_from_static?: boolean;
1226
+ content_sha256?: string;
1227
+ definition?: unknown;
1228
+ }
1229
+ /** Result of {@link LoomcycleClient.listTeamVersions} (op=list) — every version
1230
+ * of ONE team, newest first. Tenant-scoped server-side. */
1231
+ export interface TeamVersionList {
1232
+ name: string;
1233
+ versions: TeamVersion[];
1234
+ }
1235
+ /** Result of {@link LoomcycleClient.promoteTeam} (op=promote) — the version the
1236
+ * active pointer now names. */
1237
+ export interface PromotedTeam {
1238
+ def_id: string;
1239
+ name: string;
1240
+ promoted: boolean;
1241
+ }
1242
+ /** Result of {@link LoomcycleClient.retireTeam} (op=retire) — the version's new
1243
+ * retired state. Retiring is reversible (pass `false` to un-retire); it is
1244
+ * {@link LoomcycleClient.deleteTeam} that removes anything. */
1245
+ export interface RetiredTeam {
1246
+ def_id: string;
1247
+ retired: boolean;
1248
+ }
1249
+ /** Result of {@link LoomcycleClient.verifyTeam} (op=verify) — whether a locally
1250
+ * computed content hash matches the deployed active version.
1251
+ *
1252
+ * `deployed: false` means the name has no active version in this tenant at all
1253
+ * (`matches` is then false and the current_* fields are empty) — distinct from
1254
+ * a deployed version whose hash differs, which is a DRIFT rather than an
1255
+ * absence. */
1256
+ export interface TeamVerification {
1257
+ name: string;
1258
+ matches: boolean;
1259
+ deployed: boolean;
1260
+ current_sha256: string;
1261
+ current_def_id: string;
1262
+ version: number;
1263
+ }
1213
1264
  /** Result of {@link LoomcycleClient.runTeam} (op=run) — the walk trace. `status`
1214
1265
  * is `"completed"` (a terminal state was reached) or `"iteration_cap"` (a
1215
1266
  * state's cycle cap tripped; `capped_state` + `iteration_count` describe it).
@@ -1219,6 +1270,13 @@ export interface TeamRunResult {
1219
1270
  name: string;
1220
1271
  def_id: string;
1221
1272
  status: string;
1273
+ /** The walk's own run id. A team walk IS a run — it opens a `runs` row filed
1274
+ * under `team:<name>` — which is what makes it addressable while it runs:
1275
+ * {@link LoomcycleClient.setRunBreakpoints} arms it, `GET /v1/runs/{id}/
1276
+ * interrupts` carries a pause, and cancel stops it. Returned on the
1277
+ * synchronous path too, so a caller holding a second connection can debug a
1278
+ * walk it is waiting on. */
1279
+ run_id?: string;
1222
1280
  final_state?: string;
1223
1281
  final_output?: string;
1224
1282
  capped_state?: string;
@@ -1227,6 +1285,58 @@ export interface TeamRunResult {
1227
1285
  steps: Array<Record<string, unknown>>;
1228
1286
  [extra: string]: unknown;
1229
1287
  }
1288
+ /** What team {@link LoomcycleClient.runTeam} walks, and how. */
1289
+ export interface TeamRunTarget {
1290
+ name?: string;
1291
+ defId?: string;
1292
+ /** The initial task handed to the entry state's agent. */
1293
+ input?: string;
1294
+ /** Bind the walk to a Document chunk task board: each state transition
1295
+ * persists `chunk.status` = the current team state, and every handler run
1296
+ * the walk spawns carries the task key on its `parent_context`. */
1297
+ boardChunkId?: string;
1298
+ /** The Document scope of `boardChunkId` (agent | user, default user). */
1299
+ boardScope?: "agent" | "user";
1300
+ /** "detach" returns the run id immediately and leaves the walk running
1301
+ * behind it. Omit to wait for the walk and get its trace — which still
1302
+ * returns `run_id`, so a second connection can debug a walk you await. */
1303
+ mode?: "detach";
1304
+ /** Starter state ids to pause at, armed before the walk starts. Each is
1305
+ * `"<state>"` (both phases) or `"<state>:before_dispatch"` /
1306
+ * `"<state>:after_collection"`.
1307
+ *
1308
+ * A walk can also be armed AFTER it starts — see
1309
+ * {@link LoomcycleClient.setRunBreakpoints} — which is the case this
1310
+ * argument cannot serve: you start a run expecting it to work, watch a wave
1311
+ * go wrong, and want to stop before the next one. */
1312
+ breakpoints?: string[];
1313
+ }
1314
+ /** What {@link LoomcycleClient.runTeam} returns for `mode: "detach"` — the
1315
+ * handle, immediately, with the walk still running behind it.
1316
+ *
1317
+ * Detaching exists because op=run is otherwise SYNCHRONOUS: the caller learns
1318
+ * nothing until the walk is over, so there is no moment at which it can arm a
1319
+ * breakpoint, read a pause, or watch progress. There are no `steps` yet —
1320
+ * poll the run, or read its events, for those. */
1321
+ export interface TeamRunDetached {
1322
+ name: string;
1323
+ def_id: string;
1324
+ /** Address every other run surface with this. */
1325
+ run_id: string;
1326
+ /** Always "running" — the walk has been started, not awaited. */
1327
+ status: string;
1328
+ [extra: string]: unknown;
1329
+ }
1330
+ /** The armed debug breakpoints of a live team walk, as
1331
+ * {@link LoomcycleClient.getRunBreakpoints} / {@link LoomcycleClient.setRunBreakpoints}
1332
+ * report them. */
1333
+ export interface TeamBreakpoints {
1334
+ run_id: string;
1335
+ /** Canonical: always phase-qualified (`"<state>:before_dispatch"`) and
1336
+ * sorted, so what you read back is what the walk will actually do rather
1337
+ * than an echo of the shorthand you sent. */
1338
+ armed: string[];
1339
+ }
1230
1340
  /** Input for {@link LoomcycleClient.path} — the RFC AL Unix-like VFS tool
1231
1341
  * (POST /v1/_path). Op-discriminated; the server resolves scope + tenant
1232
1342
  * from the authenticated principal, never the wire. Address Memory entries,
@@ -1243,6 +1353,12 @@ export type PathToolInput = {
1243
1353
  recursive?: boolean;
1244
1354
  /** ls: only entries of this kind (document/volume_mount/memory_entry/directory). */
1245
1355
  kind_filter?: string;
1356
+ /** ls: maximum entries to return (default 500, max 5000). A truncated listing
1357
+ * reports `truncated: true` and a `next_cursor`; pass that back as `cursor`. */
1358
+ limit?: number;
1359
+ /** ls: continue a truncated listing with the previous response's `next_cursor`.
1360
+ * Opaque — its encoding is not part of the contract, so do not construct one. */
1361
+ cursor?: string;
1246
1362
  /** rm: also delete the backing resource (NOT supported in v1). */
1247
1363
  resource_too?: boolean;
1248
1364
  [extra: string]: unknown;
@@ -1299,6 +1415,10 @@ export type DocumentToolInput = {
1299
1415
  under_path?: string;
1300
1416
  /** query_chunks: raw read-only SELECT (escape hatch; validator-gated). */
1301
1417
  sql?: string;
1418
+ /** Row/response bound. On `documents_summary` it defaults to 500 (max 5000) and
1419
+ * the response reports `truncated: true` when it clips — an `under_path` over a
1420
+ * subject-homed fact store is as wide as the tenant's entity count, so page the
1421
+ * directory with `path op=ls` and pass each page's ids as `document_ids`. */
1302
1422
  limit?: number;
1303
1423
  /** define/list_types: the type name. */
1304
1424
  name?: string;
@@ -1337,6 +1457,13 @@ export type DocumentToolInput = {
1337
1457
  * sync reconciles — so a reading or coverage surface wants this on, and a
1338
1458
  * federation one does not. */
1339
1459
  claims_only?: boolean;
1460
+ /** list_facts: the facts about ONE SUBJECT — the subject's entity chunk id (a
1461
+ * subject document's `root_chunk_id`, from get_document). Returns the facts filed
1462
+ * under it AND the facts filed elsewhere that reference it: filing is
1463
+ * single-parent, so a fact about two things lives in one of their documents and
1464
+ * only points at the other, and a document filter would lose it from the second
1465
+ * subject entirely. */
1466
+ about?: string;
1340
1467
  /** remember: a statement to store as a fact that cites ITSELF — the text becomes both
1341
1468
  * the claim and its source span, so write what you want recorded rather than an
1342
1469
  * instruction about it. Additive only; it is never a way to delete. */
@@ -1366,12 +1493,21 @@ export type DocumentToolResponse = unknown;
1366
1493
  * Loosely typed (the in-process tool owns the full schema); use the `[extra]`
1367
1494
  * index signature for forward-compat fields. */
1368
1495
  export type HistoryToolInput = {
1369
- op: "list" | "get" | "search" | "rename" | "annotate" | "pin" | "archive" | "recap" | "resume";
1496
+ op: "list" | "get" | "search" | "rename" | "annotate" | "pin" | "archive" | "recap" | "resume" | "related" | "window";
1370
1497
  /** Whose chats: self = this caller's agent; user = this end-user's; tenant =
1371
1498
  * this tenant's; global = all tenants (admin only). Default self. */
1372
1499
  scope?: "self" | "user" | "tenant" | "global";
1373
- /** get/rename/annotate/pin/archive/recap/resume: the chat (session) id. */
1500
+ /** get/rename/annotate/pin/archive/recap/resume/window: the chat (session) id.
1501
+ * For `window`, the session a recalled fact reported as its source. */
1374
1502
  session_id?: string;
1503
+ /** window: the fact's source span — the verbatim text it was distilled from,
1504
+ * which recall returns as `source`. It anchors the window to the turn the fact
1505
+ * came from, rather than the start of the chat. */
1506
+ quote?: string;
1507
+ /** window: how many turns either side of the match to return (default 2, max
1508
+ * 10). A distilled fact loses what its turn's neighbours carry — a bare date, a
1509
+ * pronoun — which is what these recover. */
1510
+ context?: number;
1375
1511
  /** list/search: filter by derived chat status (running/completed/failed/cancelled). */
1376
1512
  status?: string;
1377
1513
  /** list/search: RFC3339 lower bound on last activity. */
@@ -1463,6 +1599,8 @@ export interface ChannelDescriptor {
1463
1599
  period?: string;
1464
1600
  default_ttl?: number;
1465
1601
  max_messages?: number;
1602
+ /** Breakpoint: publishes are stored but never delivered until released. */
1603
+ hold?: boolean;
1466
1604
  message_count: number;
1467
1605
  /** RFC3339 — empty when count == 0. */
1468
1606
  oldest_visible_at?: string;
@@ -1652,6 +1790,9 @@ export interface CreateChannelOptions {
1652
1790
  publisher?: string;
1653
1791
  /** Free-form retention hint; not enforced by the substrate. */
1654
1792
  period?: string;
1793
+ /** Breakpoint: publishes are stored but never delivered until
1794
+ * {@link LoomcycleClient.releaseChannel} hands them over. */
1795
+ hold?: boolean;
1655
1796
  signal?: AbortSignal;
1656
1797
  }
1657
1798
  /** Options for {@link LoomcycleClient.updateChannel}. Nil fields
@@ -1662,8 +1803,29 @@ export interface UpdateChannelOptions {
1662
1803
  max_messages?: number;
1663
1804
  /** "queue" | "topic" */
1664
1805
  semantic?: string;
1806
+ /** Turn the breakpoint on or off. Messages already held stay held
1807
+ * until released — turning it off does not flush the queue. */
1808
+ hold?: boolean;
1665
1809
  signal?: AbortSignal;
1666
1810
  }
1811
+ /** Options for {@link LoomcycleClient.releaseChannel}. */
1812
+ export interface ReleaseChannelOptions {
1813
+ /** How many held messages to hand over, oldest first. Default 1. */
1814
+ count?: number;
1815
+ /** "global" (default) | "user" | "tenant". */
1816
+ scope?: string;
1817
+ /** Required when scope is "user". */
1818
+ scope_id?: string;
1819
+ signal?: AbortSignal;
1820
+ }
1821
+ /** Result of {@link LoomcycleClient.releaseChannel}. `released` is the
1822
+ * ids handed over, in delivery order; `still_held` is what is left. */
1823
+ export interface ChannelReleaseResult {
1824
+ channel: string;
1825
+ released: string[];
1826
+ released_count: number;
1827
+ still_held: number;
1828
+ }
1667
1829
  /** Options for {@link LoomcycleClient.setMemoryEntry}. `value` is
1668
1830
  * opaque JSON. Setting `embed: true` triggers a synchronous embed
1669
1831
  * via the operator-configured embedder; the returned `embedded`
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@loomcycle/client",
3
- "version": "1.72.0",
4
- "description": "TypeScript client for the loomcycle sidecar (HTTP+SSE). 67 methods covering run streaming, agent metadata, pause/resume/state, resolver re-probe (resolveProbe \u2014 issue #88 operator escape hatch), operator-token admin (operatorTokenDef \u2014 RFC L OSS multi-tenant auth) + whoami (RFC L authoritative principal, v0.17.0) + tenant-scoped listUsers / listUserAgents, dynamic MCP registration (mcpServerDef + v0.18.0 typed mcpServerDefVerify + ensureMcpServer idempotent register-if-changed), snapshot lifecycle, memory admin (incl. v0.9.0 Vector Memory embed_stats + reembed AND v0.11.5 setMemoryEntry + deleteMemoryEntry), interruption resolve, hook management, v0.8.22 substrate admin (agentDef + skillDef), v0.9.x n8n Phase 0 (listChannels + streamUserRunStates), v0.9.x Channel CRUD (publishChannel + subscribeChannel + peekChannel + ackChannel), v0.11.5 Channel admin CRUD (createChannel + updateChannel + deleteChannel \u2014 runtime substrate; yaml channels refuse mutation with HTTP 409), v0.9.x content_sha256 verify, v0.9.1 transcript first-cycle, v0.9.x dynamic MCP server registration (mcpServerDef + MCPServerDefVerifyResult), v0.10.3 Library v2 enumeration (listLibraryAgents + listLibrarySkills + listLibraryMcpServers), and v0.11.0 LLM Gateway (llmChat + llmStream \u2014 direct provider routing without agent overhead; primary target is n8n's LoomCycleChatModel AI Agent sub-node and any LangChain-compatible consumer). v0.10.1 \u2014 dual ESM + CommonJS distribution (additive \u2014 ESM consumers unchanged; CJS consumers like n8n's community-node loader now work). v0.19.0 \u2014 typed inline code-js agent ingestion (AgentDefOverlay.code_body + ensureCodeAgent \u2014 register a deterministic code agent through the substrate with no host filesystem bind; RFC J). v0.20.0 \u2014 ensureMcpServer surfaces discoveredToolCount straight from create (loomcycle now auto-discovers MCP tools at ingestion); rediscover is now an explicit force-refresh. v0.21.0 \u2014 run/continue accept optional non-secret `metadata` (repo name, review policy, \u2026) passed to the agent, symmetric with the WebHook/Schedule trigger paths. v0.22.0 \u2014 version-aligned lockstep release; no client-surface change (RFC N tenant isolation of the agent/skill/MCP/Schedule/Webhook definition plane + real op-schemas on the builtin MCP meta-tools are both server-side). v0.23.0 \u2014 version-aligned lockstep release; no client-surface change (RFCs O/P/R MCP-server hardening + thin client and the RFC Q DeepSeek tool-content fix are all server-side / MCP-transport-side). v0.24.0 \u2014 purgeChannel clears a channel's buffered messages without deleting its definition (allowed on yaml-declared channels too, unlike deleteChannel \u2014 F20); AgentDefOverlay gains channels / evaluation_scopes / interruption so a COMPLETE interactive/multi-agent agent round-trips over the substrate (F14). (Consolidates the interim 0.24/0.25 package bumps, which were never tag-published, back into lockstep with the loomcycle v0.24.0 tag.) v0.25.0 \u2014 adds the RFC S channel fan-in/fan-out client twins: awaitChannels() (wait for any/all/at_least N messages across channels, or a timeout \u2014 non-committing) + broadcastChannels() (publish one payload to N channels in one atomic-pre-flight call), the client-facing counterparts of the in-band Channel.await / Channel.broadcast tool ops (the rest of v0.25.0 \u2014 the manual-management Web UI console + Context op=time + max_fires self-retiring schedules \u2014 is server-side / in-band, no client-surface change). v0.29.1 \u2014 Usage gains optional `max_context_tokens` (the serving model's context-window ceiling, stamped by the loop from Provider.Capabilities() on each usage event) so a consumer can render a 'context used / max' gauge without a hard-coded per-model table; additive + optional, no behavior change. (Lockstep catch-up: the field landed in loomcycle v0.29.0 but the adapter publish skipped on a version mismatch; v0.29.1 realigns the package version with the release tag so it publishes.) v0.33.0 \u2014 gRPC + TS client parity for the RFC Y external fan-out and the compaction surface: spawnRunBatch() (POST /v1/runs:batch \u2014 spawn up to 32 fresh runs concurrently in one call, combined index-aligned envelope, per-child failures in-envelope) + compactRun(runId) (POST /v1/runs/{run_id}/compact \u2014 summarize a parked run's context); plus per-run sampling + compaction overrides now accepted on runStreaming / continueSession (an explicit temperature 0 is preserved as deterministic, not dropped as falsy). (The gRPC half adds the matching SpawnRunBatch / CompactRun RPCs + the sampling/compaction fields on RunRequest/ContinueRequest \u2014 server-side.) v0.34.0 \u2014 version-aligned lockstep release; no client-surface change (context-transform plugins / RFC Z Phase 1a are server-side config; the exp7 hardening pass is server-side; the R2 cross-provider thinking-model downgrade surfaces a new `model_downgraded` SSE event the generic stream passes through unchanged). v0.35.0 \u2014 RFC AH dynamic filesystem volumes: volumeDef() (POST /v1/_volumedef \u2014 op-discriminated create/get/list/delete/purge; a Volume is flat, so delete unmaps + purge RemoveAll's, no retire/promote/fork) + listVolumes() / listEphemeralVolumes() (GET /v1/_volumes[/ephemeral] \u2014 tenant-scoped; host paths redacted for non-operator callers). Tenant-confined; the runtime derives the path inside an operator-blessed dynamic_root, so callers pass name + mode, never a host path. v1.1.1 \u2014 RFC AI interactive agentic sessions: an `interactive: true` flag on runStreaming/continueSession (a run that parks at end_turn for steering) + sendRunInput(runId, text) (POST /v1/runs/{id}/input \u2014 steer a live run) + streamRunByID(runId, {fromSeq}) (GET /v1/runs/{id}/stream \u2014 re-attach by run_id; the operator's prior turns replay as `steer` events so a cold client reconstructs the whole conversation) + a high-level InteractiveSession driver (client.interactiveSession / attachInteractiveSession \u2014 events()/send()/cancel(), the adapter port of the Web UI run terminal). The AgentEvent union gains awaiting_input/steer/context_compaction frames. Version-aligned with the loomcycle v1.1.x line so the v1.1.1 tag publishes it (also carrying the previously-unpublished v0.35.0 volume surface). v1.4.0 \u2014 RFC AL Path VFS + RFC AK Document on the wire: path(input) (POST /v1/_path \u2014 a Unix-like filesystem over Memory/Volumes/Documents; resolve/ls/stat/mkdir/mv/rm) + document(input) (POST /v1/_document \u2014 chunked-graph documents; 13 ops, needs SQL Memory on the sidecar). Scope (agent/user/tenant) + tenant are resolved server-side from the authenticated principal, never the wire; an off-run scope:'user' op keys on the principal subject so it interoperates with that user's agent runs. New PathToolInput / DocumentToolInput types; responses are op-varying (unknown \u2014 narrow as needed). v1.7.0 \u2014 RFC AT image/vision input: the PromptContent union gains an `image` variant ({ type:'image'; media_type: ImageMediaType; data: base64-no-prefix }) accepted in a user segment by runStreaming / continueSession (segments pass through unchanged \u2014 no method change). The model must be vision-capable or the run errors before the call. New ImageMediaType type (image/png|jpeg|gif|webp). v1.12.1 \u2014 Path/Document browse-by-subject + the full Document op set (RFC AS/AK): path(input, opts) / document(input, opts) accept optional scopeId / tenant browse overrides sent as ?scope_id= / ?tenant= query params (server reads them from the URL, re-checks authorization; omit both to browse your own subject \u2014 byte-identical to the pre-RFC-AS request), and DocumentToolInput.op now covers all 16 backend ops (adds set_path, export_md, import_md) with the matching include_metadata / markdown fields. Additive \u2014 existing path() / document() callers are unchanged. v1.16.0 \u2014 RFC BC client-executed tools (local tool host): connectClientTools({tools,onInvoke}) opens a persistent WebSocket to /v1/client-tools, registers tools this client runs on the user's machine (browser DOM / files / shell), and answers the invoke frames loomcycle routes when an agent of your principal calls a client:<tool> \u2014 returning your reply as an ordinary tool result. Returns a ClientToolHost driver (.close() to stop; auto-reconnect); dependency-free (global WebSocket in browsers / Node 22+, or an injected WebSocketImpl like the ws package on older Node); the bearer rides the Sec-WebSocket-Protocol subprotocol (browsers can't set an Authorization header on a WebSocket). The runtime's first WebSocket surface. v1.45.0 \u2014 RFC BL P5 subject erasure: erasureReport(subject, {tenant}) (GET /v1/_erasure \u2014 what this deployment holds about one subject, in three tiers: deletable with existing primitives, subject-keyed but not deletable, and facts ABOUT the subject in scopes they do not own) + erasureExecute(subject, {dryRun, confirm, tenant}) (POST /v1/_erasure \u2014 removes tiers 1 and 2). DEFAULTS TO A DRY RUN: dryRun defaults true and a live run also requires confirm === subject. The tier-3 residue is traceable only through the subject's chats, which a live run deletes, so a report afterwards shows rows: 0 while those facts remain \u2014 the returned object is the only durable record of what was not reached; persist it. New ErasureReport / ErasureResult / ErasureTier / ErasureResidue types. v1.47.0 \u2014 RFC BV memory-view SDK: memorySearch() (POST /v1/_memory/search \u2014 off-run unified semantic search spanning k/v entries AND document-chunk bodies in one ranked list, each hit tagged kind memory|document with chunk_id on document hits) + memoryEmbedStats(scope) + reembedMemory(scope, scopeId, {dryRun,limit}) (the Vector Memory embed-admin reads the memory-view console needs; dry_run defaults true). Fact reads (list_facts + get_chunk's entity block) ride the existing document() passthrough. Additive \u2014 existing callers unchanged. v1.61.0 \u2014 RFC CJ per-run context-window override: runStreaming / continueSession accept an optional maxContextTokens (integer tokens) that wins over the agent's own max_context_tokens; omitted inherits it (which defers to the provider/driver default). Distinct from a model's output cap; primarily for local inference (Ollama num_ctx). Serialized as the snake_case max_context_tokens field on POST /v1/runs + the continuation body; additive, existing callers unchanged.",
3
+ "version": "1.77.0",
4
+ "description": "TypeScript client for the loomcycle sidecar (HTTP+SSE). 71 methods covering run streaming, agent metadata, pause/resume/state, resolver re-probe (resolveProbe \u2014 issue #88 operator escape hatch), operator-token admin (operatorTokenDef \u2014 RFC L OSS multi-tenant auth) + whoami (RFC L authoritative principal, v0.17.0) + tenant-scoped listUsers / listUserAgents, dynamic MCP registration (mcpServerDef + v0.18.0 typed mcpServerDefVerify + ensureMcpServer idempotent register-if-changed), snapshot lifecycle, memory admin (incl. v0.9.0 Vector Memory embed_stats + reembed AND v0.11.5 setMemoryEntry + deleteMemoryEntry), interruption resolve, hook management, v0.8.22 substrate admin (agentDef + skillDef), v0.9.x n8n Phase 0 (listChannels + streamUserRunStates), v0.9.x Channel CRUD (publishChannel + subscribeChannel + peekChannel + ackChannel), v0.11.5 Channel admin CRUD (createChannel + updateChannel + deleteChannel \u2014 runtime substrate; yaml channels refuse mutation with HTTP 409), v0.9.x content_sha256 verify, v0.9.1 transcript first-cycle, v0.9.x dynamic MCP server registration (mcpServerDef + MCPServerDefVerifyResult), v0.10.3 Library v2 enumeration (listLibraryAgents + listLibrarySkills + listLibraryMcpServers), and v0.11.0 LLM Gateway (llmChat + llmStream \u2014 direct provider routing without agent overhead; primary target is n8n's LoomCycleChatModel AI Agent sub-node and any LangChain-compatible consumer). v0.10.1 \u2014 dual ESM + CommonJS distribution (additive \u2014 ESM consumers unchanged; CJS consumers like n8n's community-node loader now work). v0.19.0 \u2014 typed inline code-js agent ingestion (AgentDefOverlay.code_body + ensureCodeAgent \u2014 register a deterministic code agent through the substrate with no host filesystem bind; RFC J). v0.20.0 \u2014 ensureMcpServer surfaces discoveredToolCount straight from create (loomcycle now auto-discovers MCP tools at ingestion); rediscover is now an explicit force-refresh. v0.21.0 \u2014 run/continue accept optional non-secret `metadata` (repo name, review policy, \u2026) passed to the agent, symmetric with the WebHook/Schedule trigger paths. v0.22.0 \u2014 version-aligned lockstep release; no client-surface change (RFC N tenant isolation of the agent/skill/MCP/Schedule/Webhook definition plane + real op-schemas on the builtin MCP meta-tools are both server-side). v0.23.0 \u2014 version-aligned lockstep release; no client-surface change (RFCs O/P/R MCP-server hardening + thin client and the RFC Q DeepSeek tool-content fix are all server-side / MCP-transport-side). v0.24.0 \u2014 purgeChannel clears a channel's buffered messages without deleting its definition (allowed on yaml-declared channels too, unlike deleteChannel \u2014 F20); AgentDefOverlay gains channels / evaluation_scopes / interruption so a COMPLETE interactive/multi-agent agent round-trips over the substrate (F14). (Consolidates the interim 0.24/0.25 package bumps, which were never tag-published, back into lockstep with the loomcycle v0.24.0 tag.) v0.25.0 \u2014 adds the RFC S channel fan-in/fan-out client twins: awaitChannels() (wait for any/all/at_least N messages across channels, or a timeout \u2014 non-committing) + broadcastChannels() (publish one payload to N channels in one atomic-pre-flight call), the client-facing counterparts of the in-band Channel.await / Channel.broadcast tool ops (the rest of v0.25.0 \u2014 the manual-management Web UI console + Context op=time + max_fires self-retiring schedules \u2014 is server-side / in-band, no client-surface change). v0.29.1 \u2014 Usage gains optional `max_context_tokens` (the serving model's context-window ceiling, stamped by the loop from Provider.Capabilities() on each usage event) so a consumer can render a 'context used / max' gauge without a hard-coded per-model table; additive + optional, no behavior change. (Lockstep catch-up: the field landed in loomcycle v0.29.0 but the adapter publish skipped on a version mismatch; v0.29.1 realigns the package version with the release tag so it publishes.) v0.33.0 \u2014 gRPC + TS client parity for the RFC Y external fan-out and the compaction surface: spawnRunBatch() (POST /v1/runs:batch \u2014 spawn up to 32 fresh runs concurrently in one call, combined index-aligned envelope, per-child failures in-envelope) + compactRun(runId) (POST /v1/runs/{run_id}/compact \u2014 summarize a parked run's context); plus per-run sampling + compaction overrides now accepted on runStreaming / continueSession (an explicit temperature 0 is preserved as deterministic, not dropped as falsy). (The gRPC half adds the matching SpawnRunBatch / CompactRun RPCs + the sampling/compaction fields on RunRequest/ContinueRequest \u2014 server-side.) v0.34.0 \u2014 version-aligned lockstep release; no client-surface change (context-transform plugins / RFC Z Phase 1a are server-side config; the exp7 hardening pass is server-side; the R2 cross-provider thinking-model downgrade surfaces a new `model_downgraded` SSE event the generic stream passes through unchanged). v0.35.0 \u2014 RFC AH dynamic filesystem volumes: volumeDef() (POST /v1/_volumedef \u2014 op-discriminated create/get/list/delete/purge; a Volume is flat, so delete unmaps + purge RemoveAll's, no retire/promote/fork) + listVolumes() / listEphemeralVolumes() (GET /v1/_volumes[/ephemeral] \u2014 tenant-scoped; host paths redacted for non-operator callers). Tenant-confined; the runtime derives the path inside an operator-blessed dynamic_root, so callers pass name + mode, never a host path. v1.1.1 \u2014 RFC AI interactive agentic sessions: an `interactive: true` flag on runStreaming/continueSession (a run that parks at end_turn for steering) + sendRunInput(runId, text) (POST /v1/runs/{id}/input \u2014 steer a live run) + streamRunByID(runId, {fromSeq}) (GET /v1/runs/{id}/stream \u2014 re-attach by run_id; the operator's prior turns replay as `steer` events so a cold client reconstructs the whole conversation) + a high-level InteractiveSession driver (client.interactiveSession / attachInteractiveSession \u2014 events()/send()/cancel(), the adapter port of the Web UI run terminal). The AgentEvent union gains awaiting_input/steer/context_compaction frames. Version-aligned with the loomcycle v1.1.x line so the v1.1.1 tag publishes it (also carrying the previously-unpublished v0.35.0 volume surface). v1.4.0 \u2014 RFC AL Path VFS + RFC AK Document on the wire: path(input) (POST /v1/_path \u2014 a Unix-like filesystem over Memory/Volumes/Documents; resolve/ls/stat/mkdir/mv/rm) + document(input) (POST /v1/_document \u2014 chunked-graph documents; 13 ops, needs SQL Memory on the sidecar). Scope (agent/user/tenant) + tenant are resolved server-side from the authenticated principal, never the wire; an off-run scope:'user' op keys on the principal subject so it interoperates with that user's agent runs. New PathToolInput / DocumentToolInput types; responses are op-varying (unknown \u2014 narrow as needed). v1.7.0 \u2014 RFC AT image/vision input: the PromptContent union gains an `image` variant ({ type:'image'; media_type: ImageMediaType; data: base64-no-prefix }) accepted in a user segment by runStreaming / continueSession (segments pass through unchanged \u2014 no method change). The model must be vision-capable or the run errors before the call. New ImageMediaType type (image/png|jpeg|gif|webp). v1.12.1 \u2014 Path/Document browse-by-subject + the full Document op set (RFC AS/AK): path(input, opts) / document(input, opts) accept optional scopeId / tenant browse overrides sent as ?scope_id= / ?tenant= query params (server reads them from the URL, re-checks authorization; omit both to browse your own subject \u2014 byte-identical to the pre-RFC-AS request), and DocumentToolInput.op now covers all 16 backend ops (adds set_path, export_md, import_md) with the matching include_metadata / markdown fields. Additive \u2014 existing path() / document() callers are unchanged. v1.16.0 \u2014 RFC BC client-executed tools (local tool host): connectClientTools({tools,onInvoke}) opens a persistent WebSocket to /v1/client-tools, registers tools this client runs on the user's machine (browser DOM / files / shell), and answers the invoke frames loomcycle routes when an agent of your principal calls a client:<tool> \u2014 returning your reply as an ordinary tool result. Returns a ClientToolHost driver (.close() to stop; auto-reconnect); dependency-free (global WebSocket in browsers / Node 22+, or an injected WebSocketImpl like the ws package on older Node); the bearer rides the Sec-WebSocket-Protocol subprotocol (browsers can't set an Authorization header on a WebSocket). The runtime's first WebSocket surface. v1.45.0 \u2014 RFC BL P5 subject erasure: erasureReport(subject, {tenant}) (GET /v1/_erasure \u2014 what this deployment holds about one subject, in three tiers: deletable with existing primitives, subject-keyed but not deletable, and facts ABOUT the subject in scopes they do not own) + erasureExecute(subject, {dryRun, confirm, tenant}) (POST /v1/_erasure \u2014 removes tiers 1 and 2). DEFAULTS TO A DRY RUN: dryRun defaults true and a live run also requires confirm === subject. The tier-3 residue is traceable only through the subject's chats, which a live run deletes, so a report afterwards shows rows: 0 while those facts remain \u2014 the returned object is the only durable record of what was not reached; persist it. New ErasureReport / ErasureResult / ErasureTier / ErasureResidue types. v1.47.0 \u2014 RFC BV memory-view SDK: memorySearch() (POST /v1/_memory/search \u2014 off-run unified semantic search spanning k/v entries AND document-chunk bodies in one ranked list, each hit tagged kind memory|document with chunk_id on document hits) + memoryEmbedStats(scope) + reembedMemory(scope, scopeId, {dryRun,limit}) (the Vector Memory embed-admin reads the memory-view console needs; dry_run defaults true). Fact reads (list_facts + get_chunk's entity block) ride the existing document() passthrough. Additive \u2014 existing callers unchanged. v1.61.0 \u2014 RFC CJ per-run context-window override: runStreaming / continueSession accept an optional maxContextTokens (integer tokens) that wins over the agent's own max_context_tokens; omitted inherits it (which defers to the provider/driver default). Distinct from a model's output cap; primarily for local inference (Ollama num_ctx). Serialized as the snake_case max_context_tokens field on POST /v1/runs + the continuation body; additive, existing callers unchanged. v1.72.1 \u2014 the TeamDef version lifecycle: listTeamVersions(name) (op=list \u2014 every version of one team, newest first), promoteTeam(defId) (op=promote \u2014 point the active pointer, which is what a run BY NAME executes; forkTeam defaults to promote:false, so authoring and putting in force stay two steps), retireTeam(defId, retired) (op=retire \u2014 reversible and version-scoped, unlike deleteTeam) and verifyTeam(name, contentSha256) (op=verify \u2014 the drift check for a workflow kept in source control and pushed to several deployments; an absent team answers deployed:false rather than raising). The ops existed on the substrate and over HTTP; a client that could author a team could not put one in force.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
7
7
  "repository": {