@loomcycle/client 1.99.0 → 1.101.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.
package/README.md CHANGED
@@ -139,8 +139,10 @@ The low-level primitives (`runStreaming({interactive:true})` + `sendRunInput` +
139
139
  | Method | Returns | Notes |
140
140
  |---|---|---|
141
141
  | `getAgent(agentId)` | `Promise<Agent>` | One agent's status + usage. Raises `AgentNotFoundError` if unknown. |
142
+ | `getRun(runId)` | `Promise<Agent>` | One run by its run id — `getAgent`'s shape. Use it when an agent id names several runs (every walk of a team is `team:<name>`). Raises `NotFoundError` if unknown. |
142
143
  | `cancelAgent(agentId, opts?)` | `Promise<{ cancelledCount: number }>` | Cascades to children via `parent_agent_id`. Idempotent. |
143
144
  | `listUserAgents(userId, opts?)` | `Promise<Agent[]>` | Optional filter by status (`running` / `completed` / `failed` / `cancelled`). |
145
+ | `listWalkRuns(walkId, { limit?, cursor? })` | `Promise<WalkRunsPage>` | One page of a team walk's runs — its own run and every member, oldest first: `{ agents, next_cursor }`. Pass `next_cursor` back as `cursor`; `""` on the last page. `limit` defaults to 100, at most 1000. Raises `NotFoundError` for a walk you cannot read. |
144
146
  | `getTranscript(sessionId)` | `Promise<TranscriptResponse>` | Persisted event log; one row per event with seq/run_id/ts_ns/type/event. |
145
147
  | `health()` | `Promise<HealthResponse>` | Liveness probe. Hits `/healthz` (no `/v1` prefix). Unauthenticated. |
146
148
  | `getConfig(opts?)` | `Promise<ConfigResponse>` | v1.38.0 — instance configuration: build identity, the feature matrix, and the live provider/model/search cascade with `active`/`selected`. `view` names the disclosure level (`public` / `authenticated` / `admin`). Also readable with **no bearer** against a deployment running `LOOMCYCLE_PUBLIC_CONFIG=1`, which serves the narrower `public` view — the landing-page case. |
@@ -146,11 +146,6 @@ function runBody(opts) {
146
146
  body.tool_hooks = opts.toolHooks;
147
147
  if (opts.sampling !== undefined)
148
148
  body.sampling = samplingToWire(opts.sampling);
149
- // Same keys on the wire as in the option (mode / name / until).
150
- if (opts.toolChoice !== undefined)
151
- body.tool_choice = opts.toolChoice;
152
- if (opts.outputFormat !== undefined)
153
- body.output_format = opts.outputFormat;
154
149
  if (opts.compaction !== undefined)
155
150
  body.compaction = compactionToWire(opts.compaction);
156
151
  if (opts.context !== undefined)
@@ -206,6 +201,11 @@ function applyOverridesToWire(body, opts) {
206
201
  body.interruption = opts.interruption;
207
202
  if (opts.review !== undefined)
208
203
  body.review = opts.review;
204
+ // Same keys on the wire as in the option (mode / name / until).
205
+ if (opts.toolChoice !== undefined)
206
+ body.tool_choice = opts.toolChoice;
207
+ if (opts.outputFormat !== undefined)
208
+ body.output_format = opts.outputFormat;
209
209
  }
210
210
  class LoomcycleClient {
211
211
  ctx;
@@ -291,10 +291,6 @@ class LoomcycleClient {
291
291
  body.tool_hooks = opts.toolHooks;
292
292
  if (opts.sampling !== undefined)
293
293
  body.sampling = samplingToWire(opts.sampling);
294
- if (opts.toolChoice !== undefined)
295
- body.tool_choice = opts.toolChoice;
296
- if (opts.outputFormat !== undefined)
297
- body.output_format = opts.outputFormat;
298
294
  if (opts.compaction !== undefined)
299
295
  body.compaction = compactionToWire(opts.compaction);
300
296
  if (opts.context !== undefined)
@@ -655,6 +651,14 @@ class LoomcycleClient {
655
651
  async getAgent(agentId, opts) {
656
652
  return (0, fetch_helpers_js_1.jsonFetch)(this.ctx, `/v1/agents/${encodeURIComponent(agentId)}`, opts);
657
653
  }
654
+ /** Read one run by its run id — the same {@link Agent} shape as
655
+ * {@link getAgent}. An agent id can name many runs (every walk of a team
656
+ * is filed under `team:<name>`, which getAgent cannot address) and
657
+ * getAgent answers the latest; a run id names one. Raises NotFoundError
658
+ * for an unknown run, or one the caller may not see. */
659
+ async getRun(runId, opts) {
660
+ return (0, fetch_helpers_js_1.jsonFetch)(this.ctx, `/v1/runs/${encodeURIComponent(runId)}`, opts);
661
+ }
658
662
  /** Cancel a live agent (cascades to children via parent_agent_id).
659
663
  * Returns count of agents cancelled. Idempotent — already-terminated
660
664
  * agents return 0. */
@@ -683,6 +687,21 @@ class LoomcycleClient {
683
687
  }
684
688
  return all;
685
689
  }
690
+ /** One page of a team walk's runs — the walk's own run (its run id IS the
691
+ * walk id) and every member it spawned, oldest first. Pass the page's
692
+ * `next_cursor` back as `cursor` for the next one; it is "" on the last.
693
+ * `limit` defaults to 100, at most 1000. Mirrors
694
+ * `GET /v1/runs?walk_id=`. Raises NotFoundError for an unknown walk, or
695
+ * one the caller may not see. */
696
+ async listWalkRuns(walkId, opts) {
697
+ const params = new URLSearchParams({ walk_id: walkId });
698
+ if (opts?.limit !== undefined)
699
+ params.set("limit", String(opts.limit));
700
+ if (opts?.cursor)
701
+ params.set("cursor", opts.cursor);
702
+ const resp = await (0, fetch_helpers_js_1.jsonFetch)(this.ctx, `/v1/runs?${params.toString()}`, opts);
703
+ return { agents: resp.agents ?? [], next_cursor: resp.next_cursor ?? "" };
704
+ }
686
705
  /** Aggregated token-usage + cost report (RFC AV). Group by any of
687
706
  * tenant/user/provider/model/source over an optional time window; group by
688
707
  * `source` for the operator-vs-tenant split. Tenant-scoped server-side: a
@@ -1514,7 +1533,8 @@ class LoomcycleClient {
1514
1533
  return (0, fetch_helpers_js_1.postJSON)(this.ctx, "/v1/_teamdef", body, opts);
1515
1534
  }
1516
1535
  /** Read the debug breakpoints armed on a live team walk
1517
- * (`GET /v1/runs/{run_id}/breakpoints`).
1536
+ * (`GET /v1/runs/{run_id}/breakpoints`), and the review deadline its
1537
+ * member holds get (`review_ttl_seconds`, 0 = none).
1518
1538
  *
1519
1539
  * 404 when no walk is in flight under that run on this replica — loudly,
1520
1540
  * because an arming that appeared to succeed and then never paused anything
@@ -1531,15 +1551,33 @@ class LoomcycleClient {
1531
1551
  * off switch. A malformed entry is refused whole and leaves the previous
1532
1552
  * arming exactly as it was.
1533
1553
  *
1534
- * Each entry is a starter state id — `"wave"` (or `"wave:before_dispatch"`)
1535
- * pauses the state before it dispatches, and `"wave:review"` holds its member
1536
- * runs for a verdict ({@link LoomcycleClient.reviewRun}). An arm takes effect
1537
- * at the next point the walk reaches; disarming RELEASES whatever is still
1538
- * pending rather than stranding it.
1539
- *
1540
- * A pause is read and answered through the run's interrupts. */
1554
+ * `"wave"` (or `"wave:before_dispatch"`) pauses a starter state before it
1555
+ * dispatches, and `"<state>:review"` holds the member runs of a starter,
1556
+ * agent or parallel state for a verdict ({@link LoomcycleClient.reviewRun}).
1557
+ * An arm takes effect at the next point the walk reaches; disarming
1558
+ * RELEASES whatever is still pending rather than stranding it.
1559
+ *
1560
+ * Each state is checked against the walk's own team, as it is when the run
1561
+ * starts: an entry naming a state the team does not have, a pause on a
1562
+ * state that is not a starter, or review on a consolidator or a state that
1563
+ * runs no member, is refused with 400 `invalid_breakpoint` and the previous
1564
+ * arming is kept — rather than armed and silently never hit.
1565
+ *
1566
+ * A pause is read and answered through the run's interrupts.
1567
+ *
1568
+ * `opts.reviewTtlSeconds` also replaces the walk's review deadline — a
1569
+ * member hold nobody rules on within it ends rejected; `0` is no deadline.
1570
+ * Omit it to leave the deadline as it is. It applies from each member's
1571
+ * NEXT hold: a hold already in progress keeps the `expires_at` it
1572
+ * announced. A negative or out-of-range value is refused with 400
1573
+ * `invalid_review_ttl`, and so is the set sent with it. Like the
1574
+ * breakpoints, it lives only as long as the walk; a member restored after
1575
+ * a restart keeps the deadline it started with. */
1541
1576
  async setRunBreakpoints(runId, breakpoints, opts) {
1542
- return (0, fetch_helpers_js_1.putJSON)(this.ctx, `/v1/runs/${encodeURIComponent(runId)}/breakpoints`, { breakpoints }, opts);
1577
+ const body = { breakpoints };
1578
+ if (opts?.reviewTtlSeconds !== undefined)
1579
+ body.review_ttl_seconds = opts.reviewTtlSeconds;
1580
+ return (0, fetch_helpers_js_1.putJSON)(this.ctx, `/v1/runs/${encodeURIComponent(runId)}/breakpoints`, body, { signal: opts?.signal });
1543
1581
  }
1544
1582
  /** Invoke the RFC AL Path VFS tool over HTTP (`POST /v1/_path`). A
1545
1583
  * Unix-like filesystem over your Memory entries, Volume mounts, and
package/dist/cjs/index.js CHANGED
@@ -13,8 +13,10 @@
13
13
  *
14
14
  * // Agent metadata
15
15
  * getAgent(agentId): Promise<Agent>
16
+ * getRun(runId): Promise<Agent>
16
17
  * cancelAgent(agentId, opts?): Promise<CancelAgentResult>
17
18
  * listUserAgents(userId, opts?): Promise<Agent[]>
19
+ * listWalkRuns(walkId, opts?): Promise<WalkRunsPage>
18
20
  * getTranscript(sessionId): Promise<TranscriptResponse>
19
21
  * health(): Promise<HealthResponse>
20
22
  * listUsers(opts?): Promise<ListUsersResponse> // tenant-scoped (RFC L)
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, RunOverrideOptions, EffectiveConfigResponse, RetuneRunResponse, RunConfigResponse, RunPromptResponse, CreateSnapshotOptions, EnsureCodeAgentOptions, EnsureCodeAgentResult, EnsureMcpServerOptions, EnsureMcpServerResult, HealthResponse, 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, ResolveInterruptOptions, ResumeResult, ResolverMatrix, CompactRunResult, ReplaySessionResult, CancelTurnResult, ReviewRunResult, RunBatchOptions, RunBatchResult, RunOptions, ConfiguredRun, ConfiguredRunPatch, 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";
28
+ import type { CredentialListResponse, CredentialMeta, CredentialScope, DirectoryInspection, DirectoryTenant, DirectoryUser, ErasureReport, ErasureResult, Agent, AgentEvent, AgentStatus, CancelAgentResult, ClientOptions, ContinueOptions, RunOverrideOptions, EffectiveConfigResponse, RetuneRunResponse, RunConfigResponse, RunPromptResponse, CreateSnapshotOptions, EnsureCodeAgentOptions, EnsureCodeAgentResult, EnsureMcpServerOptions, EnsureMcpServerResult, HealthResponse, InterruptListResponse, InterruptStatus, WalkRunsPage, 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, ResolveInterruptOptions, ResumeResult, ResolverMatrix, CompactRunResult, ReplaySessionResult, CancelTurnResult, ReviewRunResult, RunBatchOptions, RunBatchResult, RunOptions, ConfiguredRun, ConfiguredRunPatch, 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);
@@ -360,6 +360,14 @@ export declare class LoomcycleClient {
360
360
  getAgent(agentId: string, opts?: {
361
361
  signal?: AbortSignal;
362
362
  }): Promise<Agent>;
363
+ /** Read one run by its run id — the same {@link Agent} shape as
364
+ * {@link getAgent}. An agent id can name many runs (every walk of a team
365
+ * is filed under `team:<name>`, which getAgent cannot address) and
366
+ * getAgent answers the latest; a run id names one. Raises NotFoundError
367
+ * for an unknown run, or one the caller may not see. */
368
+ getRun(runId: string, opts?: {
369
+ signal?: AbortSignal;
370
+ }): Promise<Agent>;
363
371
  /** Cancel a live agent (cascades to children via parent_agent_id).
364
372
  * Returns count of agents cancelled. Idempotent — already-terminated
365
373
  * agents return 0. */
@@ -382,6 +390,17 @@ export declare class LoomcycleClient {
382
390
  tenant?: string;
383
391
  signal?: AbortSignal;
384
392
  }): Promise<Agent[]>;
393
+ /** One page of a team walk's runs — the walk's own run (its run id IS the
394
+ * walk id) and every member it spawned, oldest first. Pass the page's
395
+ * `next_cursor` back as `cursor` for the next one; it is "" on the last.
396
+ * `limit` defaults to 100, at most 1000. Mirrors
397
+ * `GET /v1/runs?walk_id=`. Raises NotFoundError for an unknown walk, or
398
+ * one the caller may not see. */
399
+ listWalkRuns(walkId: string, opts?: {
400
+ limit?: number;
401
+ cursor?: string;
402
+ signal?: AbortSignal;
403
+ }): Promise<WalkRunsPage>;
385
404
  /** Aggregated token-usage + cost report (RFC AV). Group by any of
386
405
  * tenant/user/provider/model/source over an optional time window; group by
387
406
  * `source` for the operator-vs-tenant split. Tenant-scoped server-side: a
@@ -1026,7 +1045,8 @@ export declare class LoomcycleClient {
1026
1045
  signal?: AbortSignal;
1027
1046
  }): Promise<TeamRunResult>;
1028
1047
  /** Read the debug breakpoints armed on a live team walk
1029
- * (`GET /v1/runs/{run_id}/breakpoints`).
1048
+ * (`GET /v1/runs/{run_id}/breakpoints`), and the review deadline its
1049
+ * member holds get (`review_ttl_seconds`, 0 = none).
1030
1050
  *
1031
1051
  * 404 when no walk is in flight under that run on this replica — loudly,
1032
1052
  * because an arming that appeared to succeed and then never paused anything
@@ -1043,15 +1063,31 @@ export declare class LoomcycleClient {
1043
1063
  * off switch. A malformed entry is refused whole and leaves the previous
1044
1064
  * arming exactly as it was.
1045
1065
  *
1046
- * Each entry is a starter state id — `"wave"` (or `"wave:before_dispatch"`)
1047
- * pauses the state before it dispatches, and `"wave:review"` holds its member
1048
- * runs for a verdict ({@link LoomcycleClient.reviewRun}). An arm takes effect
1049
- * at the next point the walk reaches; disarming RELEASES whatever is still
1050
- * pending rather than stranding it.
1051
- *
1052
- * A pause is read and answered through the run's interrupts. */
1066
+ * `"wave"` (or `"wave:before_dispatch"`) pauses a starter state before it
1067
+ * dispatches, and `"<state>:review"` holds the member runs of a starter,
1068
+ * agent or parallel state for a verdict ({@link LoomcycleClient.reviewRun}).
1069
+ * An arm takes effect at the next point the walk reaches; disarming
1070
+ * RELEASES whatever is still pending rather than stranding it.
1071
+ *
1072
+ * Each state is checked against the walk's own team, as it is when the run
1073
+ * starts: an entry naming a state the team does not have, a pause on a
1074
+ * state that is not a starter, or review on a consolidator or a state that
1075
+ * runs no member, is refused with 400 `invalid_breakpoint` and the previous
1076
+ * arming is kept — rather than armed and silently never hit.
1077
+ *
1078
+ * A pause is read and answered through the run's interrupts.
1079
+ *
1080
+ * `opts.reviewTtlSeconds` also replaces the walk's review deadline — a
1081
+ * member hold nobody rules on within it ends rejected; `0` is no deadline.
1082
+ * Omit it to leave the deadline as it is. It applies from each member's
1083
+ * NEXT hold: a hold already in progress keeps the `expires_at` it
1084
+ * announced. A negative or out-of-range value is refused with 400
1085
+ * `invalid_review_ttl`, and so is the set sent with it. Like the
1086
+ * breakpoints, it lives only as long as the walk; a member restored after
1087
+ * a restart keeps the deadline it started with. */
1053
1088
  setRunBreakpoints(runId: string, breakpoints: string[], opts?: {
1054
1089
  signal?: AbortSignal;
1090
+ reviewTtlSeconds?: number;
1055
1091
  }): Promise<TeamBreakpoints>;
1056
1092
  /** Invoke the RFC AL Path VFS tool over HTTP (`POST /v1/_path`). A
1057
1093
  * Unix-like filesystem over your Memory entries, Volume mounts, and
package/dist/client.js CHANGED
@@ -143,11 +143,6 @@ function runBody(opts) {
143
143
  body.tool_hooks = opts.toolHooks;
144
144
  if (opts.sampling !== undefined)
145
145
  body.sampling = samplingToWire(opts.sampling);
146
- // Same keys on the wire as in the option (mode / name / until).
147
- if (opts.toolChoice !== undefined)
148
- body.tool_choice = opts.toolChoice;
149
- if (opts.outputFormat !== undefined)
150
- body.output_format = opts.outputFormat;
151
146
  if (opts.compaction !== undefined)
152
147
  body.compaction = compactionToWire(opts.compaction);
153
148
  if (opts.context !== undefined)
@@ -203,6 +198,11 @@ function applyOverridesToWire(body, opts) {
203
198
  body.interruption = opts.interruption;
204
199
  if (opts.review !== undefined)
205
200
  body.review = opts.review;
201
+ // Same keys on the wire as in the option (mode / name / until).
202
+ if (opts.toolChoice !== undefined)
203
+ body.tool_choice = opts.toolChoice;
204
+ if (opts.outputFormat !== undefined)
205
+ body.output_format = opts.outputFormat;
206
206
  }
207
207
  export class LoomcycleClient {
208
208
  ctx;
@@ -288,10 +288,6 @@ export class LoomcycleClient {
288
288
  body.tool_hooks = opts.toolHooks;
289
289
  if (opts.sampling !== undefined)
290
290
  body.sampling = samplingToWire(opts.sampling);
291
- if (opts.toolChoice !== undefined)
292
- body.tool_choice = opts.toolChoice;
293
- if (opts.outputFormat !== undefined)
294
- body.output_format = opts.outputFormat;
295
291
  if (opts.compaction !== undefined)
296
292
  body.compaction = compactionToWire(opts.compaction);
297
293
  if (opts.context !== undefined)
@@ -652,6 +648,14 @@ export class LoomcycleClient {
652
648
  async getAgent(agentId, opts) {
653
649
  return jsonFetch(this.ctx, `/v1/agents/${encodeURIComponent(agentId)}`, opts);
654
650
  }
651
+ /** Read one run by its run id — the same {@link Agent} shape as
652
+ * {@link getAgent}. An agent id can name many runs (every walk of a team
653
+ * is filed under `team:<name>`, which getAgent cannot address) and
654
+ * getAgent answers the latest; a run id names one. Raises NotFoundError
655
+ * for an unknown run, or one the caller may not see. */
656
+ async getRun(runId, opts) {
657
+ return jsonFetch(this.ctx, `/v1/runs/${encodeURIComponent(runId)}`, opts);
658
+ }
655
659
  /** Cancel a live agent (cascades to children via parent_agent_id).
656
660
  * Returns count of agents cancelled. Idempotent — already-terminated
657
661
  * agents return 0. */
@@ -680,6 +684,21 @@ export class LoomcycleClient {
680
684
  }
681
685
  return all;
682
686
  }
687
+ /** One page of a team walk's runs — the walk's own run (its run id IS the
688
+ * walk id) and every member it spawned, oldest first. Pass the page's
689
+ * `next_cursor` back as `cursor` for the next one; it is "" on the last.
690
+ * `limit` defaults to 100, at most 1000. Mirrors
691
+ * `GET /v1/runs?walk_id=`. Raises NotFoundError for an unknown walk, or
692
+ * one the caller may not see. */
693
+ async listWalkRuns(walkId, opts) {
694
+ const params = new URLSearchParams({ walk_id: walkId });
695
+ if (opts?.limit !== undefined)
696
+ params.set("limit", String(opts.limit));
697
+ if (opts?.cursor)
698
+ params.set("cursor", opts.cursor);
699
+ const resp = await jsonFetch(this.ctx, `/v1/runs?${params.toString()}`, opts);
700
+ return { agents: resp.agents ?? [], next_cursor: resp.next_cursor ?? "" };
701
+ }
683
702
  /** Aggregated token-usage + cost report (RFC AV). Group by any of
684
703
  * tenant/user/provider/model/source over an optional time window; group by
685
704
  * `source` for the operator-vs-tenant split. Tenant-scoped server-side: a
@@ -1511,7 +1530,8 @@ export class LoomcycleClient {
1511
1530
  return postJSON(this.ctx, "/v1/_teamdef", body, opts);
1512
1531
  }
1513
1532
  /** Read the debug breakpoints armed on a live team walk
1514
- * (`GET /v1/runs/{run_id}/breakpoints`).
1533
+ * (`GET /v1/runs/{run_id}/breakpoints`), and the review deadline its
1534
+ * member holds get (`review_ttl_seconds`, 0 = none).
1515
1535
  *
1516
1536
  * 404 when no walk is in flight under that run on this replica — loudly,
1517
1537
  * because an arming that appeared to succeed and then never paused anything
@@ -1528,15 +1548,33 @@ export class LoomcycleClient {
1528
1548
  * off switch. A malformed entry is refused whole and leaves the previous
1529
1549
  * arming exactly as it was.
1530
1550
  *
1531
- * Each entry is a starter state id — `"wave"` (or `"wave:before_dispatch"`)
1532
- * pauses the state before it dispatches, and `"wave:review"` holds its member
1533
- * runs for a verdict ({@link LoomcycleClient.reviewRun}). An arm takes effect
1534
- * at the next point the walk reaches; disarming RELEASES whatever is still
1535
- * pending rather than stranding it.
1536
- *
1537
- * A pause is read and answered through the run's interrupts. */
1551
+ * `"wave"` (or `"wave:before_dispatch"`) pauses a starter state before it
1552
+ * dispatches, and `"<state>:review"` holds the member runs of a starter,
1553
+ * agent or parallel state for a verdict ({@link LoomcycleClient.reviewRun}).
1554
+ * An arm takes effect at the next point the walk reaches; disarming
1555
+ * RELEASES whatever is still pending rather than stranding it.
1556
+ *
1557
+ * Each state is checked against the walk's own team, as it is when the run
1558
+ * starts: an entry naming a state the team does not have, a pause on a
1559
+ * state that is not a starter, or review on a consolidator or a state that
1560
+ * runs no member, is refused with 400 `invalid_breakpoint` and the previous
1561
+ * arming is kept — rather than armed and silently never hit.
1562
+ *
1563
+ * A pause is read and answered through the run's interrupts.
1564
+ *
1565
+ * `opts.reviewTtlSeconds` also replaces the walk's review deadline — a
1566
+ * member hold nobody rules on within it ends rejected; `0` is no deadline.
1567
+ * Omit it to leave the deadline as it is. It applies from each member's
1568
+ * NEXT hold: a hold already in progress keeps the `expires_at` it
1569
+ * announced. A negative or out-of-range value is refused with 400
1570
+ * `invalid_review_ttl`, and so is the set sent with it. Like the
1571
+ * breakpoints, it lives only as long as the walk; a member restored after
1572
+ * a restart keeps the deadline it started with. */
1538
1573
  async setRunBreakpoints(runId, breakpoints, opts) {
1539
- return putJSON(this.ctx, `/v1/runs/${encodeURIComponent(runId)}/breakpoints`, { breakpoints }, opts);
1574
+ const body = { breakpoints };
1575
+ if (opts?.reviewTtlSeconds !== undefined)
1576
+ body.review_ttl_seconds = opts.reviewTtlSeconds;
1577
+ return putJSON(this.ctx, `/v1/runs/${encodeURIComponent(runId)}/breakpoints`, body, { signal: opts?.signal });
1540
1578
  }
1541
1579
  /** Invoke the RFC AL Path VFS tool over HTTP (`POST /v1/_path`). A
1542
1580
  * Unix-like filesystem over your Memory entries, Volume mounts, and
package/dist/index.d.ts CHANGED
@@ -12,8 +12,10 @@
12
12
  *
13
13
  * // Agent metadata
14
14
  * getAgent(agentId): Promise<Agent>
15
+ * getRun(runId): Promise<Agent>
15
16
  * cancelAgent(agentId, opts?): Promise<CancelAgentResult>
16
17
  * listUserAgents(userId, opts?): Promise<Agent[]>
18
+ * listWalkRuns(walkId, opts?): Promise<WalkRunsPage>
17
19
  * getTranscript(sessionId): Promise<TranscriptResponse>
18
20
  * health(): Promise<HealthResponse>
19
21
  * listUsers(opts?): Promise<ListUsersResponse> // tenant-scoped (RFC L)
@@ -128,5 +130,5 @@ export { InteractiveSession } from "./interactive.js";
128
130
  export type { InteractiveSessionOps } from "./interactive.js";
129
131
  export { ClientToolHost, clientToolsURL, CLIENT_TOOL_SUBPROTOCOL } from "./client-tools.js";
130
132
  export type { ClientToolSchema, ClientToolInvocation, ConnectClientToolsOptions, WebSocketLike, WebSocketCtor, } from "./client-tools.js";
131
- export type { AgentEvent, ClientOptions, ContinueOptions, EventType, HostWidening, ImageMediaType, ParentContext, PromptContent, PromptSegment, RetryInfo, RunOptions, SamplingOptions, CompactionOptions, ContextOptions, ToolUse, Usage, Agent, AgentStatus, AgentUsage, RunResult, RunSpec, ConfiguredRun, ConfiguredRunPatch, ToolChoiceOptions, OutputFormatOptions, CancelAgentResult, ListAgentsResponse, RunBatchOptions, RunBatchResult, SpawnRunResult, CompactRunResult, DirectoryBudget, DirectoryInspection, DirectoryTenant, DirectoryUser, ErasureReport, ErasureResidue, ErasureResult, ErasureTier, CancelTurnResult, ReviewRunResult, 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, ChannelHookCall, ChannelHookResult, HookFailMode, HookPhase, HookToolCall, HookToolResult, PostHookCall, PostHookResult, PreHookCall, PreHookResult, 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, HookEvent, InlineWebhook, HookEntry, EventHooks, ToolEntry, ToolHooksByTool, EnsureCodeAgentOptions, EnsureCodeAgentResult, LibraryAgentDefinition, LibraryEntry, LibraryListResponse, LibraryMcpServerDefinition, LibrarySkillDefinition, LLMChatContent, LLMChatMessage, LLMChatOptions, LLMChatResponse, LLMChatStreamDelta, LLMChatStreamItem, LLMChatToolCall, LLMChatUsage, LLMTool, LLMEmbeddingItem, LLMEmbeddingsOptions, LLMEmbeddingsResponse, LLMEmbeddingsUsage, UsageDimension, UsageAggregate, UsageReportResponse, CapabilityInertInfo, LimitInfo, ErrorInfo, CallFormat, CallRef, HookDecisionInfo, EffectiveConfigResponse, EffectiveConfigSource, EffectiveValue, RetuneRunResponse, RunConfigRecord, RunConfigResponse, RunPromptResponse, RunPromptSnapshot, PromptBlock, TokenLimit, TokenLimitsResponse, ConfigResponse, ConfigProvider, ConfigModel, ConfigSearch, ConfigInstance, SetTokenLimitRequest, CredentialScope, CredentialMeta, CredentialListResponse, } from "./types.js";
133
+ export type { AgentEvent, ClientOptions, ContinueOptions, EventType, HostWidening, ImageMediaType, ParentContext, PromptContent, PromptSegment, RetryInfo, RunOptions, SamplingOptions, CompactionOptions, ContextOptions, ToolUse, Usage, Agent, AgentStatus, AwaitedState, AgentUsage, RunResult, RunSpec, ConfiguredRun, ConfiguredRunPatch, ToolChoiceOptions, OutputFormatOptions, CancelAgentResult, ListAgentsResponse, WalkRunsPage, RunBatchOptions, RunBatchResult, SpawnRunResult, CompactRunResult, DirectoryBudget, DirectoryInspection, DirectoryTenant, DirectoryUser, ErasureReport, ErasureResidue, ErasureResult, ErasureTier, CancelTurnResult, ReviewRunResult, 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, ChannelHookCall, ChannelHookResult, HookFailMode, HookPhase, HookToolCall, HookToolResult, PostHookCall, PostHookResult, PreHookCall, PreHookResult, 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, HookEvent, InlineWebhook, HookEntry, EventHooks, ToolEntry, ToolHooksByTool, EnsureCodeAgentOptions, EnsureCodeAgentResult, LibraryAgentDefinition, LibraryEntry, LibraryListResponse, LibraryMcpServerDefinition, LibrarySkillDefinition, LLMChatContent, LLMChatMessage, LLMChatOptions, LLMChatResponse, LLMChatStreamDelta, LLMChatStreamItem, LLMChatToolCall, LLMChatUsage, LLMTool, LLMEmbeddingItem, LLMEmbeddingsOptions, LLMEmbeddingsResponse, LLMEmbeddingsUsage, UsageDimension, UsageAggregate, UsageReportResponse, CapabilityInertInfo, LimitInfo, ErrorInfo, CallFormat, CallRef, HookDecisionInfo, EffectiveConfigResponse, EffectiveConfigSource, EffectiveValue, RetuneRunResponse, RunConfigRecord, SubagentHoldInfo, RunConfigResponse, RunPromptResponse, RunPromptSnapshot, PromptBlock, TokenLimit, TokenLimitsResponse, ConfigResponse, ConfigProvider, ConfigModel, ConfigSearch, ConfigInstance, SetTokenLimitRequest, CredentialScope, CredentialMeta, CredentialListResponse, } from "./types.js";
132
134
  export { AgentIDInUseError, AgentNotFoundError, AlreadyPausingError, AuthError, BackpressureError, NotFoundError, InvalidArgumentError, ChannelCursorRegressionError, LoomcycleError, NotPausedError, PauseNotConfiguredError, PerUserQuotaExhaustedError, SessionBusyError, SessionNotFoundError, SnapshotNotFoundError, SnapshotTooLargeError, SnapshotVersionError, SubstrateToolRefusedError, UnavailableError, } from "./errors.js";
package/dist/index.js CHANGED
@@ -12,8 +12,10 @@
12
12
  *
13
13
  * // Agent metadata
14
14
  * getAgent(agentId): Promise<Agent>
15
+ * getRun(runId): Promise<Agent>
15
16
  * cancelAgent(agentId, opts?): Promise<CancelAgentResult>
16
17
  * listUserAgents(userId, opts?): Promise<Agent[]>
18
+ * listWalkRuns(walkId, opts?): Promise<WalkRunsPage>
17
19
  * getTranscript(sessionId): Promise<TranscriptResponse>
18
20
  * health(): Promise<HealthResponse>
19
21
  * listUsers(opts?): Promise<ListUsersResponse> // tenant-scoped (RFC L)
package/dist/types.d.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  * `client.ts` for the input shapes (RunOptions, CreateSnapshotOptions,
8
8
  * etc.) — those are translated to snake_case in the request body.
9
9
  */
10
- export type EventType = "started" | "text" | "tool_call" | "tool_result" | "usage" | "done" | "error" | "retry" | "host_widened" | "session" | "agent" | "awaiting_input" | "awaiting_review" | "steer" | "context_compaction" | "capability_inert" | "hook_decision" | "limit" | "override" | "context_recap" | "context_state" | "context_distill_declined" | "context_exhausted" | "thinking" | "turn_cancelled" | "provider_fallback" | "fallback_suppressed" | "model_downgraded" | "cache_invalidated" | "reasoning_invalidated" | "channel_publish" | "channel_delivery" | "interruption_pending" | "spawn_child_started" | "spawn_child_result" | "prompt_snapshot" | "_meta";
10
+ export type EventType = "started" | "text" | "tool_call" | "tool_result" | "usage" | "done" | "error" | "retry" | "host_widened" | "session" | "agent" | "awaiting_input" | "awaiting_review" | "subagent_hold" | "steer" | "context_compaction" | "capability_inert" | "hook_decision" | "limit" | "override" | "context_recap" | "context_state" | "context_distill_declined" | "context_exhausted" | "thinking" | "turn_cancelled" | "provider_fallback" | "fallback_suppressed" | "model_downgraded" | "cache_invalidated" | "reasoning_invalidated" | "channel_publish" | "channel_delivery" | "interruption_pending" | "spawn_child_started" | "spawn_child_result" | "prompt_snapshot" | "_meta";
11
11
  export interface ToolUse {
12
12
  id: string;
13
13
  name: string;
@@ -54,6 +54,17 @@ export interface HostWidening {
54
54
  hook_name: string;
55
55
  hosts_added: string[];
56
56
  }
57
+ /** A sub-agent's review hold, as its parent's stream reports it. */
58
+ export interface SubagentHoldInfo {
59
+ subagent: string;
60
+ subagent_run_id: string;
61
+ state: "held" | "released";
62
+ held_by?: string;
63
+ round?: number;
64
+ expires_at?: string;
65
+ /** How the child ended: completed | rejected | failed | cancelled ("released" only). */
66
+ status?: string;
67
+ }
57
68
  /** LimitInfo accompanies an `event: limit` frame (RFC AW per-scope token
58
69
  * budgets). Names which scope tripped, how hard (`soft` warns + the run
59
70
  * continues; `hard` means the NEXT run is refused at admission), and where the
@@ -519,6 +530,11 @@ export interface AgentEvent {
519
530
  expires_at?: string;
520
531
  held_by?: string;
521
532
  };
533
+ /** Payload on `event: subagent_hold` — on a parent's stream, a sub-agent it
534
+ * started through the Agent tool is held for a verdict (`state` "held";
535
+ * rule on it with {@link LoomcycleClient.reviewRun} on `subagent_run_id`)
536
+ * or has ended (`state` "released", with `status`). */
537
+ subagent_hold?: SubagentHoldInfo;
522
538
  /** Payload on `event: steer` (RFC AI) — the operator's drained turn. On a
523
539
  * re-attach replay, `source` is `"replay"`. Nil on all other event types. */
524
540
  user_input?: {
@@ -665,17 +681,27 @@ export interface RunOverrideOptions {
665
681
  * it outright (status `rejected`). Settable while the run is going; `false`
666
682
  * on a run that is held releases it as approved. */
667
683
  review?: boolean;
668
- /** Let this run's agent ASK a human a question, overriding what its
669
- * definition allows.
670
- *
671
- * Overridable because an interruption touches no data and no host — it blocks
672
- * and waits for a person — so the exposure is liveness, bounded by the run's
673
- * timeout and the interruption's own. */
684
+ /** Narrow whether this run's agent may ASK a human a question. `enabled`
685
+ * must be true to keep asking (false switches it off); `kinds` keeps only
686
+ * those the definition also allows; `max_pending` takes the smaller. It
687
+ * never grants the Interruption tool to an agent that does not hold it —
688
+ * there it is reported as `capability_inert`. A retune reaches a parked run
689
+ * at its next operator turn. */
674
690
  interruption?: {
675
691
  enabled?: boolean;
676
692
  kinds?: string[];
677
693
  max_pending?: number;
678
694
  };
695
+ /** Per-run tool choice: whether and which tool the model must call, and
696
+ * for how many calls. REPLACES the agent's own whole. On a retune it
697
+ * replaces the run's own and takes effect from the run's next turn, where
698
+ * its `until` starts counting; mode `auto` removes the forcing. */
699
+ toolChoice?: ToolChoiceOptions;
700
+ /** Per-run answer schema: the final answer is held to it where the model
701
+ * supports it, and returned parsed as `result.structured`. REPLACES the
702
+ * agent's own whole. On a retune it replaces the run's own and takes
703
+ * effect from the run's next turn; a retune cannot remove it. */
704
+ outputFormat?: OutputFormatOptions;
679
705
  }
680
706
  export interface RunOptions extends RunOverrideOptions {
681
707
  agent: string;
@@ -768,13 +794,6 @@ export interface RunOptions extends RunOverrideOptions {
768
794
  * agent's own sampling (this wins; unset fields inherit). Omitted =
769
795
  * inherit entirely. */
770
796
  sampling?: SamplingOptions;
771
- /** Per-run tool choice (RFC DI): whether and which tool the model must
772
- * call, and for how many calls. REPLACES the agent's own whole. */
773
- toolChoice?: ToolChoiceOptions;
774
- /** Per-run answer schema (RFC DI): the final answer is held to it where
775
- * the model supports it, and returned parsed as `result.structured`.
776
- * REPLACES the agent's own whole. */
777
- outputFormat?: OutputFormatOptions;
778
797
  /** Per-run context-compaction override (v0.32.0), merged PER FIELD over
779
798
  * the agent's own compaction block (this wins; unset fields inherit).
780
799
  * Omitted = inherit entirely. Trigger compaction mid-run with
@@ -990,6 +1009,14 @@ export interface ParentContext {
990
1009
  * fields, which are omitted when empty), so an index of 0 is a real first
991
1010
  * position and not an absent one. */
992
1011
  wave_index?: number;
1012
+ /** Which state of the walk ran this run — set on EVERY run a team walk
1013
+ * spawns (agent, parallel, consolidator and starter members alike), where
1014
+ * the wave fields are a starter's alone. */
1015
+ state?: string;
1016
+ /** The walk's own ordinal of state visits (1, 2, …): the runs of one visit
1017
+ * share it, and a revisit of the same state gets a new one. Absent outside
1018
+ * a walk. */
1019
+ state_visit?: number;
993
1020
  }
994
1021
  export interface ContinueOptions extends RunOverrideOptions {
995
1022
  /** Required — the session to continue. */
@@ -1045,13 +1072,6 @@ export interface ContinueOptions extends RunOverrideOptions {
1045
1072
  toolHooks?: ToolHooksByTool;
1046
1073
  /** Per-continuation LLM sampling override — see {@link RunOptions.sampling}. */
1047
1074
  sampling?: SamplingOptions;
1048
- /** Per-run tool choice (RFC DI): whether and which tool the model must
1049
- * call, and for how many calls. REPLACES the agent's own whole. */
1050
- toolChoice?: ToolChoiceOptions;
1051
- /** Per-run answer schema (RFC DI): the final answer is held to it where
1052
- * the model supports it, and returned parsed as `result.structured`.
1053
- * REPLACES the agent's own whole. */
1054
- outputFormat?: OutputFormatOptions;
1055
1075
  /** Per-continuation context-compaction override — see {@link RunOptions.compaction}. */
1056
1076
  compaction?: CompactionOptions;
1057
1077
  /** Per-continuation context-distillation override — see
@@ -1085,6 +1105,10 @@ export interface ClientOptions {
1085
1105
  /** `configured` is a run created but not yet started (RFC DI). */
1086
1106
  /** `rejected` is a run a reviewer turned down without feedback (RFC DJ). */
1087
1107
  export type AgentStatus = "configured" | "running" | "completed" | "failed" | "cancelled" | "rejected";
1108
+ /** What a running run is blocked on: an open Channel subscribe, an open
1109
+ * Interruption ask, a hold for an operator's review verdict, or an
1110
+ * interactive run parked for the operator's next turn (`input`). */
1111
+ export type AwaitedState = "channel" | "interrupted" | "review" | "input";
1088
1112
  export interface AgentUsage {
1089
1113
  input_tokens?: number;
1090
1114
  output_tokens?: number;
@@ -1099,6 +1123,11 @@ export interface Agent {
1099
1123
  session_id: string;
1100
1124
  agent: string;
1101
1125
  parent_agent_id: string | null;
1126
+ /** The run that spawned this one (an Agent-tool spawn, a team-walk member,
1127
+ * a walk started by an agent). Absent for a top-level run. Unlike
1128
+ * parent_agent_id it names one run: an agent id is reused by every run of
1129
+ * that agent. */
1130
+ parent_run_id?: string;
1102
1131
  user_id: string;
1103
1132
  status: AgentStatus;
1104
1133
  started_at: string;
@@ -1108,6 +1137,26 @@ export interface Agent {
1108
1137
  usage: AgentUsage;
1109
1138
  last_heartbeat_at: string | null;
1110
1139
  live: boolean;
1140
+ /** A persistent interactive run — it parks at end_turn waiting for operator
1141
+ * input. Absent for ordinary runs. */
1142
+ interactive?: boolean;
1143
+ /** What a RUNNING run is currently blocked on; absent while it makes
1144
+ * progress and for every run that is not running. See {@link AwaitedState}. */
1145
+ awaited_state?: AwaitedState;
1146
+ /** The channel name (`awaited_state: "channel"`; a fan-in `Channel` await
1147
+ * lists its channels comma-separated, bounded), interruption kind
1148
+ * (`awaited_state: "interrupted"`) or the agent_stop hook holding a review
1149
+ * (`awaited_state: "review"`) the run waits on. */
1150
+ awaited_on?: string;
1151
+ /** The replica owning the run's live cancel handle. Absent in a
1152
+ * single-replica deployment. */
1153
+ replica_id?: string;
1154
+ /** This run is a LIVE resident interactive sub-agent (opened with Agent
1155
+ * op=open) on the replica that answered. HTTP listings only — the gRPC read
1156
+ * cannot reach the per-replica registry this comes from. */
1157
+ resident?: boolean;
1158
+ /** A resident sub-agent's current state; set only with `resident`. */
1159
+ resident_state?: "running" | "awaiting_input" | "completed" | "failed";
1111
1160
  /** Opaque caller-tracking lineage this run carries (inherited from its
1112
1161
  * root for sub-agents), v0.12.x. Echoed here alongside `usage` so you
1113
1162
  * can attribute a child sub-agent's cost to the user-initiated request
@@ -1115,11 +1164,11 @@ export interface Agent {
1115
1164
  parent_context?: ParentContext;
1116
1165
  /** The run's answer (RFC DI) — what the row had no field for; `stop_reason`,
1117
1166
  * `error` and `usage` are above. Present on {@link LoomcycleClient.getAgent}
1118
- * only (listings omit it), and only once the run has finished with
1167
+ * and {@link LoomcycleClient.getRun} only (listings omit it), and only once the run has finished with
1119
1168
  * something to report. */
1120
1169
  result?: RunResult;
1121
1170
  /** The run's own configuration (RFC DI): the overrides it ran with, merged
1122
- * over its definition. {@link LoomcycleClient.getAgent} only, like
1171
+ * over its definition. {@link LoomcycleClient.getAgent} / getRun only, like
1123
1172
  * `result`; absent when the run overrode nothing. */
1124
1173
  spec?: RunSpec;
1125
1174
  /** A CONFIGURED run's request as it will start (RFC DI) — what
@@ -1170,6 +1219,55 @@ export interface RunSpec {
1170
1219
  hooks?: EventHooks;
1171
1220
  tool_hooks?: ToolHooksByTool;
1172
1221
  };
1222
+ /** Hooks a definition added to the run (a team state's), each with the
1223
+ * definition it came from: its owner (`team:<name>`), owning tenant and
1224
+ * whether an operator wrote it. Written by the server only — no run
1225
+ * request can set a source. */
1226
+ sourced_hooks?: Array<{
1227
+ source: {
1228
+ owner: string;
1229
+ tenant?: string;
1230
+ operator_authored?: boolean;
1231
+ };
1232
+ hooks?: EventHooks;
1233
+ tool_hooks?: ToolHooksByTool;
1234
+ }>;
1235
+ /** What the run's hooks resolved to when it started, so a resumed run
1236
+ * fires those and no others: a fingerprint of the agent's own hooks and
1237
+ * the HookDef version each reference found. Present only on a run that
1238
+ * carries hooks. */
1239
+ pinned_hooks?: {
1240
+ agent: string;
1241
+ defs?: Record<string, string>;
1242
+ };
1243
+ /** What bounded a sub-run at its spawn beyond its own agent: its parent's
1244
+ * volumes (names and modes; roots are resolved again on resume, never
1245
+ * stored) and the fan-out width it inherited. Present only on a sub-run.
1246
+ * Written by the server only. */
1247
+ spawn?: {
1248
+ volumes: {
1249
+ active: boolean;
1250
+ bindings?: Array<{
1251
+ name: string;
1252
+ read_only: boolean;
1253
+ default?: boolean;
1254
+ }>;
1255
+ };
1256
+ fanout_cap?: number;
1257
+ };
1258
+ /** The agent version the run started on, which a resumed run continues on:
1259
+ * the AgentDef version its agent name resolved to (`def_id` absent for an
1260
+ * agent with no versions — the operator's yaml or a registered agent). For
1261
+ * a registered agent, `registered_sha256` is a digest of the registration
1262
+ * the run started on; a resume refuses one changed since. `static` marks a
1263
+ * run that started on the operator's static configuration, which a resume
1264
+ * reads again rather than a same-named agent registered or forked since.
1265
+ * Written by the server only. */
1266
+ agent_version?: {
1267
+ def_id?: string;
1268
+ registered_sha256?: string;
1269
+ static?: boolean;
1270
+ };
1173
1271
  }
1174
1272
  /** A finished run's answer (RFC DI). */
1175
1273
  export interface RunResult {
@@ -1184,6 +1282,12 @@ export interface RunResult {
1184
1282
  export interface ListAgentsResponse {
1185
1283
  agents: Agent[];
1186
1284
  }
1285
+ /** One page of a team walk's runs ({@link LoomcycleClient.listWalkRuns}),
1286
+ * ordered by started_at then run id. `next_cursor` is "" on the last page. */
1287
+ export interface WalkRunsPage {
1288
+ agents: Agent[];
1289
+ next_cursor: string;
1290
+ }
1187
1291
  export interface CancelAgentResult {
1188
1292
  /** Number of agents marked cancelled (root + descendants reached
1189
1293
  * via parent_agent_id cascade). 0 when the agent had already
@@ -1560,6 +1664,14 @@ export interface SnapshotCreateResponse {
1560
1664
  label?: string;
1561
1665
  schema_version: number;
1562
1666
  byte_size: number;
1667
+ /** What the capture carried that you should act on, named by location,
1668
+ * never by value: every literal-looking credential in a captured
1669
+ * definition (headers, URLs, stdio env/command/args), and every paused
1670
+ * run parked on a pending interrupt. A literal travels in the snapshot as
1671
+ * written; replace it with a `$cred:` or `${LOOMCYCLE_*}` reference (in a
1672
+ * stdio server's env, command or args only `${LOOMCYCLE_*}` resolves).
1673
+ * Omitted when there are none. */
1674
+ warnings?: string[];
1563
1675
  }
1564
1676
  /** Full envelope returned by GET /v1/_snapshots/{id}. json_content
1565
1677
  * carries the canonical envelope as a parsed JSON object — pipe
@@ -1590,10 +1702,18 @@ export interface SnapshotRestoreResponse {
1590
1702
  channel_cursors_restored?: number;
1591
1703
  evaluations_restored?: number;
1592
1704
  paused_runs_restored?: number;
1705
+ /** How many restored paused runs the server re-dispatched as live loops.
1706
+ * Can be below `paused_runs_restored`: a run whose agent no longer
1707
+ * resolves is flagged failed and named in `warnings` instead. */
1708
+ paused_runs_resumed?: number;
1593
1709
  synthesized_sessions?: number;
1594
1710
  transcript_events_restored?: number;
1595
1711
  interaction_history_restored?: number;
1596
1712
  warnings?: string[];
1713
+ /** Every restore counter keyed by name (`agent_defs`, `hook_defs`,
1714
+ * `mcp_server_defs_activated`, ...) — including the ones the typed fields
1715
+ * above never carried. A new snapshot section adds a key here. */
1716
+ restored?: Record<string, number>;
1597
1717
  }
1598
1718
  export interface MemoryScopeKind {
1599
1719
  name: string;
@@ -1741,6 +1861,13 @@ export interface MemorySearchEntry {
1741
1861
  document?: string;
1742
1862
  /** The chunk's own heading. Same conditions as {@link document}. */
1743
1863
  title?: string;
1864
+ /** Present when the chunk was found through one of its Document derived search
1865
+ * units — a description, claim or question generated for it — rather than its
1866
+ * own text. The chunk appears once however many of its units matched. */
1867
+ matched_unit?: {
1868
+ kind: "description" | "claim" | "question";
1869
+ text: string;
1870
+ };
1744
1871
  }
1745
1872
  export interface MemorySearchResponse {
1746
1873
  scope: string;
@@ -2097,14 +2224,19 @@ export interface TeamRunTarget {
2097
2224
  *
2098
2225
  * `"<state>:review"` arms review instead — see {@link TeamRunTarget.review}. */
2099
2226
  breakpoints?: string[];
2100
- /** Starter state ids whose member runs are held for an operator's verdict
2101
- * when they finish: approve with {@link LoomcycleClient.reviewRun}, reject
2102
- * with feedback the member revises from, or reject. A rejected member
2103
- * reaches the sink as status `"rejected"` and does not count toward the
2104
- * wave's `wait`. Also armable live as the breakpoint `"<state>:review"`. */
2227
+ /** Starter, agent or parallel state ids whose member runs are held for an
2228
+ * operator's verdict when they finish: approve with
2229
+ * {@link LoomcycleClient.reviewRun}, reject with feedback the member revises
2230
+ * from, or reject. A rejected starter member reaches the sink as status
2231
+ * `"rejected"` and does not count toward the wave's `wait`; a rejected agent
2232
+ * or parallel member counts as failed. A consolidator state is refused — its
2233
+ * answer is the walk's verdict on the work, and a parallel state's own
2234
+ * consolidator is never held. Also armable live as the breakpoint
2235
+ * `"<state>:review"`. */
2105
2236
  review?: string[];
2106
2237
  /** With `review`: end a member hold nobody rules on within this many
2107
- * seconds as rejected. Omit for no deadline. */
2238
+ * seconds as rejected. Omit for no deadline. Changeable while the walk
2239
+ * runs — see {@link LoomcycleClient.setRunBreakpoints}. */
2108
2240
  reviewTtlSeconds?: number;
2109
2241
  }
2110
2242
  /** What {@link LoomcycleClient.runTeam} returns for `mode: "detach"` — the
@@ -2132,6 +2264,10 @@ export interface TeamBreakpoints {
2132
2264
  * sorted, so what you read back is what the walk will actually do rather
2133
2265
  * than an echo of the shorthand you sent. */
2134
2266
  armed: string[];
2267
+ /** The review deadline, in seconds, a member hold beginning now gets —
2268
+ * 0 = none. Starts as the run's {@link TeamRunTarget.reviewTtlSeconds};
2269
+ * changeable with {@link LoomcycleClient.setRunBreakpoints}. */
2270
+ review_ttl_seconds: number;
2135
2271
  }
2136
2272
  /** Input for {@link LoomcycleClient.path} — the RFC AL Unix-like VFS tool
2137
2273
  * (POST /v1/_path). Op-discriminated; the server resolves scope + tenant
@@ -2691,6 +2827,9 @@ export interface RunStateEvent {
2691
2827
  agent: string;
2692
2828
  user_id: string;
2693
2829
  parent_agent_id?: string;
2830
+ /** The run that spawned this one; absent for a top-level run. Unlike
2831
+ * `parent_agent_id`, which every run of an agent reuses, it names one run. */
2832
+ parent_run_id?: string;
2694
2833
  status: string;
2695
2834
  stop_reason?: string;
2696
2835
  error?: string;
@@ -2699,6 +2838,16 @@ export interface RunStateEvent {
2699
2838
  * so a subscriber learns which root request a finishing sub-agent
2700
2839
  * belongs to. Omitted when the run carried no context. */
2701
2840
  parent_context?: ParentContext;
2841
+ /** What a `running` run has started waiting on. A wait is announced as its
2842
+ * own `running` event and its end as another `running` event without this
2843
+ * field, so a client folding the stream holds the run's current wait. */
2844
+ awaited_state?: AwaitedState;
2845
+ /** The channel (a fan-in `Channel` await: its channels, comma-separated),
2846
+ * the interruption kind, or the agent_stop hook holding a review. */
2847
+ awaited_on?: string;
2848
+ /** RFC3339: when a review hold ends as rejected if nobody rules on it.
2849
+ * Absent when the wait has no deadline. */
2850
+ hold_expires_at?: string;
2702
2851
  }
2703
2852
  /** Initial stream_open frame emitted before the first run_state. */
2704
2853
  export interface RunStateStreamOpen {
@@ -3017,6 +3166,12 @@ export interface AgentDefOverlay {
3017
3166
  * reports `reranked` (and `rerank_reason` when false); a failed or unavailable
3018
3167
  * rerank keeps the search's own order. */
3019
3168
  memory_rerank?: MemoryRerank;
3169
+ /** `false` makes this agent's searches ignore Document derived search units — the
3170
+ * short descriptions, claims and questions an operator may generate for a
3171
+ * document so a question can match them. Unset uses them wherever they exist
3172
+ * (only where an operator generated them). A chunk found through a unit carries
3173
+ * `matched_unit: {kind, text}`. */
3174
+ memory_units?: boolean;
3020
3175
  memory_quota_bytes?: number;
3021
3176
  memory_backend?: string;
3022
3177
  retry_attempts?: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loomcycle/client",
3
- "version": "1.99.0",
3
+ "version": "1.101.0",
4
4
  "description": "TypeScript client for the loomcycle sidecar (HTTP+SSE). 71 methods covering run streaming, agent metadata, pause/resume/state, resolver re-probe (resolveProbe — issue #88 operator escape hatch), operator-token admin (operatorTokenDef — 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 — 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 — direct provider routing without agent overhead; primary target is n8n's LoomCycleChatModel AI Agent sub-node and any LangChain-compatible consumer). v0.10.1 — dual ESM + CommonJS distribution (additive — ESM consumers unchanged; CJS consumers like n8n's community-node loader now work). v0.19.0 — typed inline code-js agent ingestion (AgentDefOverlay.code_body + ensureCodeAgent — register a deterministic code agent through the substrate with no host filesystem bind; RFC J). v0.20.0 — ensureMcpServer surfaces discoveredToolCount straight from create (loomcycle now auto-discovers MCP tools at ingestion); rediscover is now an explicit force-refresh. v0.21.0 — run/continue accept optional non-secret `metadata` (repo name, review policy, …) passed to the agent, symmetric with the WebHook/Schedule trigger paths. v0.22.0 — 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 — 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 — purgeChannel clears a channel's buffered messages without deleting its definition (allowed on yaml-declared channels too, unlike deleteChannel — 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 — 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 — 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 — the manual-management Web UI console + Context op=time + max_fires self-retiring schedules — is server-side / in-band, no client-surface change). v0.29.1 — 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 — gRPC + TS client parity for the RFC Y external fan-out and the compaction surface: spawnRunBatch() (POST /v1/runs:batch — 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 — 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 — server-side.) v0.34.0 — 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 — RFC AH dynamic filesystem volumes: volumeDef() (POST /v1/_volumedef — 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] — 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 — 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 — steer a live run) + streamRunByID(runId, {fromSeq}) (GET /v1/runs/{id}/stream — 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 — 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 — RFC AL Path VFS + RFC AK Document on the wire: path(input) (POST /v1/_path — a Unix-like filesystem over Memory/Volumes/Documents; resolve/ls/stat/mkdir/mv/rm) + document(input) (POST /v1/_document — 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 — narrow as needed). v1.7.0 — 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 — 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 — 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 — 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 — existing path() / document() callers are unchanged. v1.16.0 — 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> — 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 — RFC BL P5 subject erasure: erasureReport(subject, {tenant}) (GET /v1/_erasure — 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 — 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 — the returned object is the only durable record of what was not reached; persist it. New ErasureReport / ErasureResult / ErasureTier / ErasureResidue types. v1.47.0 — RFC BV memory-view SDK: memorySearch() (POST /v1/_memory/search — 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 — existing callers unchanged. v1.61.0 — 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 — the TeamDef version lifecycle: listTeamVersions(name) (op=list — every version of one team, newest first), promoteTeam(defId) (op=promote — 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 — reversible and version-scoped, unlike deleteTeam) and verifyTeam(name, contentSha256) (op=verify — 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",