@loomcycle/client 0.23.0 → 0.25.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.
@@ -941,6 +941,57 @@ class LoomcycleClient {
941
941
  const path = channelOpPath(channel, opts.scope, opts.userId, "ack");
942
942
  return (0, fetch_helpers_js_1.postJSON)(this.ctx, path, { cursor: opts.cursor }, { signal: opts.signal });
943
943
  }
944
+ // ---- RFC S client twins: fan-in (await) / fan-out (broadcast) ----
945
+ //
946
+ // Multi-channel meta-ops (POST /v1/_channels/_await and /_broadcast).
947
+ // Unlike the per-channel ops above they aren't addressed by name — the
948
+ // whole request is the body — so they don't use channelOpPath. `scope`
949
+ // + `userId` apply to every channel in the set. The complements to the
950
+ // in-band Channel.await / Channel.broadcast tool ops, letting a wire
951
+ // caller join independent producers / ping N workers over the same bus.
952
+ /** Fan IN across `channels`: wait until the `mode` predicate is met
953
+ * (`any` / `all` / `at_least` N), or `waitMs` elapses. NON-committing
954
+ * (detection only) — `subscribe`/`ack` exactly what you process. A
955
+ * timeout is not an error: the result carries `timed_out: true`. */
956
+ async awaitChannels(opts) {
957
+ const body = { channels: opts.channels };
958
+ if (opts.scope)
959
+ body.scope = opts.scope;
960
+ if (opts.userId)
961
+ body.scope_id = opts.userId;
962
+ if (opts.mode)
963
+ body.mode = opts.mode;
964
+ if (opts.n !== undefined)
965
+ body.n = opts.n;
966
+ if (opts.fromCursor !== undefined)
967
+ body.from_cursor = opts.fromCursor;
968
+ if (opts.maxMessages !== undefined)
969
+ body.max_messages = opts.maxMessages;
970
+ if (opts.waitMs !== undefined)
971
+ body.wait_ms = opts.waitMs;
972
+ return (0, fetch_helpers_js_1.postJSON)(this.ctx, "/v1/_channels/_await", body, {
973
+ signal: opts.signal,
974
+ });
975
+ }
976
+ /** Fan OUT: publish the same `payload` to every channel in `channels`,
977
+ * in one call. Atomic at the declare pre-flight — one undeclared
978
+ * channel rejects the whole call ({@link NotFoundError}, code
979
+ * `channel_not_declared`) with nothing published. A per-channel write
980
+ * fault after that is reported in that channel's `results` entry while
981
+ * the successful publishes stand. */
982
+ async broadcastChannels(opts) {
983
+ const body = {
984
+ channels: opts.channels,
985
+ payload: opts.payload,
986
+ };
987
+ if (opts.scope)
988
+ body.scope = opts.scope;
989
+ if (opts.userId)
990
+ body.scope_id = opts.userId;
991
+ if (opts.deliverAt)
992
+ body.deliver_at = opts.deliverAt;
993
+ return (0, fetch_helpers_js_1.postJSON)(this.ctx, "/v1/_channels/_broadcast", body, { signal: opts.signal });
994
+ }
944
995
  // ---- v0.11.5 Channel admin CRUD ----
945
996
  //
946
997
  // Three bearer-authed ops that mutate the runtime-substrate
@@ -994,6 +1045,15 @@ class LoomcycleClient {
994
1045
  async deleteChannel(name, opts) {
995
1046
  return (0, fetch_helpers_js_1.deleteRequest)(this.ctx, `/v1/_channels/${encodeURIComponent(name)}`, opts);
996
1047
  }
1048
+ /** Clear all buffered messages on a channel WITHOUT removing its
1049
+ * definition or subscriber cursors. Unlike {@link deleteChannel} this
1050
+ * is allowed on yaml-declared channels too — draining a yaml channel
1051
+ * that filled with test traffic was the F20 pain it solves. Returns
1052
+ * the channel name + the number of messages cleared. Unknown channels
1053
+ * reject with a {@link NotFoundError}. */
1054
+ async purgeChannel(name, opts) {
1055
+ return (0, fetch_helpers_js_1.postJSON)(this.ctx, `/v1/_channels/${encodeURIComponent(name)}/purge`, {}, { signal: opts?.signal });
1056
+ }
997
1057
  // ---- v0.11.5 Memory entry admin CRUD ----
998
1058
  /** Idempotently upsert one memory entry by full (scope, scope_id,
999
1059
  * key) identifier. PUT semantics — re-writes overwrite the value.
package/dist/client.d.ts CHANGED
@@ -23,7 +23,7 @@
23
23
  * via fetch-helpers.ts:raiseFromResponse — see README.md for the
24
24
  * full mapping table.
25
25
  */
26
- import type { Agent, AgentEvent, AgentStatus, CancelAgentResult, ClientOptions, ContinueOptions, CreateSnapshotOptions, EnsureCodeAgentOptions, EnsureCodeAgentResult, EnsureMcpServerOptions, EnsureMcpServerResult, HealthResponse, Hook, InterruptListResponse, InterruptStatus, AckChannelOptions, ChannelAckResult, ChannelDescriptor, ChannelPeekResult, ChannelPublishResult, ChannelSubscribeResult, CreateChannelOptions, ListChannelsResponse, PeekChannelOptions, PublishChannelOptions, SetMemoryEntryOptions, SetMemoryEntryResponse, SubscribeChannelOptions, UpdateChannelOptions, LibraryAgentDefinition, LibraryListResponse, LibraryMcpServerDefinition, LibrarySkillDefinition, ListUsersResponse, LLMChatOptions, LLMChatResponse, LLMChatStreamItem, LLMEmbeddingsOptions, LLMEmbeddingsResponse, MCPServerDefVerifyResult, MemoryEntriesResponse, MemoryEntryResponse, MemoryScopeIDsResponse, MemoryScopesResponse, PauseResult, RegisterHookOptions, RegisterHookResponse, ResolveInterruptOptions, ResumeResult, ResolverMatrix, RunOptions, RunStateStreamItem, RuntimeStateResponse, SnapshotCreateResponse, SnapshotDescriptor, SnapshotEnvelope, SnapshotRestoreResponse, StreamUserRunStatesOptions, SubstrateToolInput, SubstrateToolResponse, TranscriptResponse, WhoamiResponse } from "./types.js";
26
+ import type { 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, LLMChatOptions, LLMChatResponse, LLMChatStreamItem, LLMEmbeddingsOptions, LLMEmbeddingsResponse, MCPServerDefVerifyResult, MemoryEntriesResponse, MemoryEntryResponse, MemoryScopeIDsResponse, MemoryScopesResponse, PauseResult, RegisterHookOptions, RegisterHookResponse, ResolveInterruptOptions, ResumeResult, ResolverMatrix, RunOptions, RunStateStreamItem, RuntimeStateResponse, SnapshotCreateResponse, SnapshotDescriptor, SnapshotEnvelope, SnapshotRestoreResponse, StreamUserRunStatesOptions, SubstrateToolInput, SubstrateToolResponse, TranscriptResponse, WhoamiResponse } from "./types.js";
27
27
  export declare class LoomcycleClient {
28
28
  private ctx;
29
29
  constructor(opts?: ClientOptions);
@@ -595,6 +595,18 @@ export declare class LoomcycleClient {
595
595
  * raise a {@link ConflictError} (HTTP 409, code
596
596
  * `channel_cursor_regression`). */
597
597
  ackChannel(channel: string, opts: AckChannelOptions): Promise<ChannelAckResult>;
598
+ /** Fan IN across `channels`: wait until the `mode` predicate is met
599
+ * (`any` / `all` / `at_least` N), or `waitMs` elapses. NON-committing
600
+ * (detection only) — `subscribe`/`ack` exactly what you process. A
601
+ * timeout is not an error: the result carries `timed_out: true`. */
602
+ awaitChannels(opts: AwaitChannelsOptions): Promise<ChannelAwaitResult>;
603
+ /** Fan OUT: publish the same `payload` to every channel in `channels`,
604
+ * in one call. Atomic at the declare pre-flight — one undeclared
605
+ * channel rejects the whole call ({@link NotFoundError}, code
606
+ * `channel_not_declared`) with nothing published. A per-channel write
607
+ * fault after that is reported in that channel's `results` entry while
608
+ * the successful publishes stand. */
609
+ broadcastChannels(opts: BroadcastChannelsOptions): Promise<ChannelBroadcastResult>;
598
610
  /** Create a new runtime-substrate channel. Refuses with HTTP 409
599
611
  * when the name matches a yaml-declared channel (code
600
612
  * `channel_yaml_immutable`) or an existing runtime channel
@@ -611,6 +623,15 @@ export declare class LoomcycleClient {
611
623
  deleteChannel(name: string, opts?: {
612
624
  signal?: AbortSignal;
613
625
  }): Promise<void>;
626
+ /** Clear all buffered messages on a channel WITHOUT removing its
627
+ * definition or subscriber cursors. Unlike {@link deleteChannel} this
628
+ * is allowed on yaml-declared channels too — draining a yaml channel
629
+ * that filled with test traffic was the F20 pain it solves. Returns
630
+ * the channel name + the number of messages cleared. Unknown channels
631
+ * reject with a {@link NotFoundError}. */
632
+ purgeChannel(name: string, opts?: {
633
+ signal?: AbortSignal;
634
+ }): Promise<ChannelPurgeResult>;
614
635
  /** Idempotently upsert one memory entry by full (scope, scope_id,
615
636
  * key) identifier. PUT semantics — re-writes overwrite the value.
616
637
  * Optional embed flag triggers a synchronous embed via the
package/dist/client.js CHANGED
@@ -938,6 +938,57 @@ export class LoomcycleClient {
938
938
  const path = channelOpPath(channel, opts.scope, opts.userId, "ack");
939
939
  return postJSON(this.ctx, path, { cursor: opts.cursor }, { signal: opts.signal });
940
940
  }
941
+ // ---- RFC S client twins: fan-in (await) / fan-out (broadcast) ----
942
+ //
943
+ // Multi-channel meta-ops (POST /v1/_channels/_await and /_broadcast).
944
+ // Unlike the per-channel ops above they aren't addressed by name — the
945
+ // whole request is the body — so they don't use channelOpPath. `scope`
946
+ // + `userId` apply to every channel in the set. The complements to the
947
+ // in-band Channel.await / Channel.broadcast tool ops, letting a wire
948
+ // caller join independent producers / ping N workers over the same bus.
949
+ /** Fan IN across `channels`: wait until the `mode` predicate is met
950
+ * (`any` / `all` / `at_least` N), or `waitMs` elapses. NON-committing
951
+ * (detection only) — `subscribe`/`ack` exactly what you process. A
952
+ * timeout is not an error: the result carries `timed_out: true`. */
953
+ async awaitChannels(opts) {
954
+ const body = { channels: opts.channels };
955
+ if (opts.scope)
956
+ body.scope = opts.scope;
957
+ if (opts.userId)
958
+ body.scope_id = opts.userId;
959
+ if (opts.mode)
960
+ body.mode = opts.mode;
961
+ if (opts.n !== undefined)
962
+ body.n = opts.n;
963
+ if (opts.fromCursor !== undefined)
964
+ body.from_cursor = opts.fromCursor;
965
+ if (opts.maxMessages !== undefined)
966
+ body.max_messages = opts.maxMessages;
967
+ if (opts.waitMs !== undefined)
968
+ body.wait_ms = opts.waitMs;
969
+ return postJSON(this.ctx, "/v1/_channels/_await", body, {
970
+ signal: opts.signal,
971
+ });
972
+ }
973
+ /** Fan OUT: publish the same `payload` to every channel in `channels`,
974
+ * in one call. Atomic at the declare pre-flight — one undeclared
975
+ * channel rejects the whole call ({@link NotFoundError}, code
976
+ * `channel_not_declared`) with nothing published. A per-channel write
977
+ * fault after that is reported in that channel's `results` entry while
978
+ * the successful publishes stand. */
979
+ async broadcastChannels(opts) {
980
+ const body = {
981
+ channels: opts.channels,
982
+ payload: opts.payload,
983
+ };
984
+ if (opts.scope)
985
+ body.scope = opts.scope;
986
+ if (opts.userId)
987
+ body.scope_id = opts.userId;
988
+ if (opts.deliverAt)
989
+ body.deliver_at = opts.deliverAt;
990
+ return postJSON(this.ctx, "/v1/_channels/_broadcast", body, { signal: opts.signal });
991
+ }
941
992
  // ---- v0.11.5 Channel admin CRUD ----
942
993
  //
943
994
  // Three bearer-authed ops that mutate the runtime-substrate
@@ -991,6 +1042,15 @@ export class LoomcycleClient {
991
1042
  async deleteChannel(name, opts) {
992
1043
  return deleteRequest(this.ctx, `/v1/_channels/${encodeURIComponent(name)}`, opts);
993
1044
  }
1045
+ /** Clear all buffered messages on a channel WITHOUT removing its
1046
+ * definition or subscriber cursors. Unlike {@link deleteChannel} this
1047
+ * is allowed on yaml-declared channels too — draining a yaml channel
1048
+ * that filled with test traffic was the F20 pain it solves. Returns
1049
+ * the channel name + the number of messages cleared. Unknown channels
1050
+ * reject with a {@link NotFoundError}. */
1051
+ async purgeChannel(name, opts) {
1052
+ return postJSON(this.ctx, `/v1/_channels/${encodeURIComponent(name)}/purge`, {}, { signal: opts?.signal });
1053
+ }
994
1054
  // ---- v0.11.5 Memory entry admin CRUD ----
995
1055
  /** Idempotently upsert one memory entry by full (scope, scope_id,
996
1056
  * key) identifier. PUT semantics — re-writes overwrite the value.
package/dist/index.d.ts CHANGED
@@ -82,5 +82,5 @@
82
82
  * See `adapters/ts/README.md` for usage examples.
83
83
  */
84
84
  export { LoomcycleClient } from "./client.js";
85
- export type { AgentEvent, ClientOptions, ContinueOptions, EventType, HostWidening, ParentContext, PromptContent, PromptSegment, RetryInfo, RunOptions, ToolUse, Usage, Agent, AgentStatus, AgentUsage, CancelAgentResult, ListAgentsResponse, TranscriptEvent, TranscriptResponse, HealthResponse, ListUsersResponse, UserSummary, WhoamiResponse, PauseResult, ResumeResult, RuntimeStateResponse, RuntimeStateStatus, ResolverMatrix, ResolverModelStatus, ResolverProviderAvailability, CreateSnapshotOptions, SnapshotCreateResponse, SnapshotDescriptor, SnapshotEnvelope, SnapshotListResponse, SnapshotRestoreResponse, MemoryEntriesResponse, MemoryEntry, MemoryEntryResponse, MemoryScopeIDsResponse, MemoryScopeIDSummary, MemoryScopeKind, MemoryScopesResponse, InterruptListResponse, InterruptRow, InterruptStatus, ResolveInterruptOptions, Hook, HookFailMode, HookPhase, HookToolCall, HookToolResult, ListHooksResponse, PostHookCall, PostHookResult, PreHookCall, PreHookResult, RegisterHookOptions, RegisterHookResponse, SubstrateToolInput, SubstrateToolResponse, SystemPromptPayload, UserInputPayload, ChannelDescriptor, ListChannelsResponse, RunStateEvent, RunStateStreamClose, RunStateStreamItem, RunStateStreamOpen, StreamUserRunStatesOptions, AckChannelOptions, ChannelAckResult, ChannelMessageItem, ChannelPeekResult, ChannelPublishResult, ChannelScope, ChannelSubscribeResult, PeekChannelOptions, PublishChannelOptions, SubscribeChannelOptions, 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, } from "./types.js";
85
+ export type { AgentEvent, ClientOptions, ContinueOptions, EventType, HostWidening, ParentContext, PromptContent, PromptSegment, RetryInfo, RunOptions, ToolUse, Usage, Agent, AgentStatus, AgentUsage, CancelAgentResult, ListAgentsResponse, TranscriptEvent, TranscriptResponse, HealthResponse, ListUsersResponse, UserSummary, WhoamiResponse, PauseResult, ResumeResult, RuntimeStateResponse, RuntimeStateStatus, ResolverMatrix, ResolverModelStatus, ResolverProviderAvailability, CreateSnapshotOptions, SnapshotCreateResponse, SnapshotDescriptor, SnapshotEnvelope, SnapshotListResponse, SnapshotRestoreResponse, MemoryEntriesResponse, MemoryEntry, MemoryEntryResponse, MemoryScopeIDsResponse, MemoryScopeIDSummary, MemoryScopeKind, MemoryScopesResponse, InterruptListResponse, InterruptRow, InterruptStatus, ResolveInterruptOptions, Hook, HookFailMode, HookPhase, HookToolCall, HookToolResult, ListHooksResponse, PostHookCall, PostHookResult, PreHookCall, PreHookResult, RegisterHookOptions, RegisterHookResponse, SubstrateToolInput, SubstrateToolResponse, 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, } from "./types.js";
86
86
  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/types.d.ts CHANGED
@@ -675,6 +675,12 @@ export interface ChannelDescriptor {
675
675
  export interface ListChannelsResponse {
676
676
  channels: ChannelDescriptor[];
677
677
  }
678
+ /** Result of {@link LoomcycleClient.purgeChannel} — the channel name and
679
+ * the count of buffered messages cleared. */
680
+ export interface ChannelPurgeResult {
681
+ name: string;
682
+ purged: number;
683
+ }
678
684
  /** Scope selector for the Channel CRUD methods. `"global"` addresses
679
685
  * the admin surface; `"user"` requires `userId` and addresses the
680
686
  * per-end-user URL family. */
@@ -761,6 +767,71 @@ export interface AckChannelOptions {
761
767
  export interface ChannelAckResult {
762
768
  ok: boolean;
763
769
  }
770
+ /** Fan-in mode for {@link LoomcycleClient.awaitChannels}: `any` = ≥1
771
+ * channel has a message; `all` = every channel has ≥1; `at_least` =
772
+ * total messages across channels ≥ `n`. */
773
+ export type ChannelAwaitMode = "any" | "all" | "at_least";
774
+ /** Options for {@link LoomcycleClient.awaitChannels} — wait until the
775
+ * predicate is met across `channels`, or `waitMs` elapses. `scope` +
776
+ * `userId` apply to EVERY channel in the set. Non-committing. Max 32. */
777
+ export interface AwaitChannelsOptions {
778
+ channels: string[];
779
+ scope: ChannelScope;
780
+ /** Required when scope === "user" — the shared scope_id for the set. */
781
+ userId?: string;
782
+ mode?: ChannelAwaitMode;
783
+ /** Required (>0) when mode === "at_least". */
784
+ n?: number;
785
+ fromCursor?: string;
786
+ maxMessages?: number;
787
+ /** Long-poll timeout in ms; capped at the operator's LongPollCapMS. */
788
+ waitMs?: number;
789
+ signal?: AbortSignal;
790
+ }
791
+ /** One fired channel's accumulated messages + the (non-advanced) cursor. */
792
+ export interface ChannelAwaitEntry {
793
+ messages: ChannelMessageItem[];
794
+ next_cursor: string;
795
+ }
796
+ /** Response shape for {@link LoomcycleClient.awaitChannels}. `timed_out`
797
+ * is true only when the predicate was unmet within `waitMs` (never an
798
+ * error). `results` is keyed by channel name. */
799
+ export interface ChannelAwaitResult {
800
+ satisfied: boolean;
801
+ timed_out: boolean;
802
+ mode: ChannelAwaitMode;
803
+ fired: string[];
804
+ total_messages: number;
805
+ results: Record<string, ChannelAwaitEntry>;
806
+ }
807
+ /** Options for {@link LoomcycleClient.broadcastChannels} — publish the
808
+ * same `payload` to every channel in `channels`. Atomic at the declare
809
+ * pre-flight (one undeclared channel rejects the whole call). Max 32. */
810
+ export interface BroadcastChannelsOptions {
811
+ channels: string[];
812
+ scope: ChannelScope;
813
+ userId?: string;
814
+ payload: unknown;
815
+ /** RFC3339Nano deferred-publish time. Omit for "publish now". */
816
+ deliverAt?: string;
817
+ signal?: AbortSignal;
818
+ }
819
+ /** One channel's publish outcome. `error` is set (and `msg_id` absent)
820
+ * when that channel's write failed after the pre-flight passed. */
821
+ export interface ChannelBroadcastEntry {
822
+ channel: string;
823
+ msg_id?: string;
824
+ created_at?: string;
825
+ visible_at?: string;
826
+ error?: string;
827
+ }
828
+ /** Response shape for {@link LoomcycleClient.broadcastChannels}.
829
+ * `published` + `failed` = the deduped channel count. */
830
+ export interface ChannelBroadcastResult {
831
+ published: number;
832
+ failed: number;
833
+ results: ChannelBroadcastEntry[];
834
+ }
764
835
  /** Options for {@link LoomcycleClient.createChannel}. Operator-yaml
765
836
  * channels are immutable from this surface; the server returns
766
837
  * HTTP 409 `channel_yaml_immutable` when `name` matches a yaml-
@@ -1025,6 +1096,19 @@ export interface EnsureMcpServerResult {
1025
1096
  * host filesystem bind — the symmetry that makes code agents work in
1026
1097
  * containers / pure-cloud. Requires `LOOMCYCLE_CODE_AGENTS_ENABLED=1` on the
1027
1098
  * sidecar; create/fork refuses a non-empty `code_body` otherwise. */
1099
+ /** Per-agent Channel tool ACL (mirrors the sidecar `channels:` agent yaml).
1100
+ * The Channel tool default-denies until publish/subscribe patterns are granted. */
1101
+ export interface AgentChannelACL {
1102
+ publish?: string[];
1103
+ subscribe?: string[];
1104
+ }
1105
+ /** Per-agent Interruption tool gate (mirrors the sidecar `interruption:` agent
1106
+ * yaml). `enabled: true` is REQUIRED for the Interruption tool to work at all. */
1107
+ export interface AgentInterruptionACL {
1108
+ enabled?: boolean;
1109
+ kinds?: string[];
1110
+ max_pending?: number;
1111
+ }
1028
1112
  export interface AgentDefOverlay {
1029
1113
  provider?: string;
1030
1114
  model?: string;
@@ -1044,6 +1128,13 @@ export interface AgentDefOverlay {
1044
1128
  memory_quota_bytes?: number;
1045
1129
  memory_backend?: string;
1046
1130
  retry_attempts?: number;
1131
+ /** Evaluation tool scope gate, e.g. `["submit_self", "read_any"]`. The
1132
+ * Evaluation tool default-denies until granted. */
1133
+ evaluation_scopes?: string[];
1134
+ /** Channel tool ACL (default-deny until set). */
1135
+ channels?: AgentChannelACL;
1136
+ /** Interruption tool gate — `enabled: true` REQUIRED for the tool to work. */
1137
+ interruption?: AgentInterruptionACL;
1047
1138
  [extra: string]: unknown;
1048
1139
  }
1049
1140
  /** Options for {@link LoomcycleClient.ensureCodeAgent}. */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@loomcycle/client",
3
- "version": "0.23.0",
4
- "description": "TypeScript client for the loomcycle sidecar (HTTP+SSE). 51 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).",
3
+ "version": "0.25.0",
4
+ "description": "TypeScript client for the loomcycle sidecar (HTTP+SSE). 52 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).",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
7
7
  "repository": {