@loomcycle/client 0.29.1 → 0.34.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.
@@ -28,6 +28,87 @@ Object.defineProperty(exports, "__esModule", { value: true });
28
28
  exports.LoomcycleClient = void 0;
29
29
  const fetch_helpers_js_1 = require("./fetch-helpers.js");
30
30
  const stream_js_1 = require("./stream.js");
31
+ /** samplingToWire maps the camelCase SamplingOptions to the snake_case wire
32
+ * object, omitting unset fields so they inherit the agent's value. */
33
+ function samplingToWire(s) {
34
+ const w = {};
35
+ if (s.temperature !== undefined)
36
+ w.temperature = s.temperature;
37
+ if (s.topP !== undefined)
38
+ w.top_p = s.topP;
39
+ if (s.topK !== undefined)
40
+ w.top_k = s.topK;
41
+ if (s.frequencyPenalty !== undefined)
42
+ w.frequency_penalty = s.frequencyPenalty;
43
+ if (s.presencePenalty !== undefined)
44
+ w.presence_penalty = s.presencePenalty;
45
+ if (s.seed !== undefined)
46
+ w.seed = s.seed;
47
+ if (s.stop !== undefined)
48
+ w.stop = s.stop;
49
+ return w;
50
+ }
51
+ /** compactionToWire maps the camelCase CompactionOptions to the snake_case
52
+ * wire object, omitting unset fields so they inherit the agent's value. */
53
+ function compactionToWire(c) {
54
+ const w = {};
55
+ if (c.enabled !== undefined)
56
+ w.enabled = c.enabled;
57
+ if (c.targetPercentage !== undefined)
58
+ w.target_percentage = c.targetPercentage;
59
+ if (c.keepLastN !== undefined)
60
+ w.keep_last_n = c.keepLastN;
61
+ if (c.keepFirst !== undefined)
62
+ w.keep_first = c.keepFirst;
63
+ if (c.autocompactAtPct !== undefined)
64
+ w.autocompact_at_pct = c.autocompactAtPct;
65
+ if (c.model !== undefined)
66
+ w.model = c.model;
67
+ return w;
68
+ }
69
+ /** runBody builds the snake_case /v1/runs request body from RunOptions,
70
+ * omitting unset fields (preserves the server's nil semantics — notably
71
+ * `allowedHosts: null` is treated as "omit", not deny-all). Shared by
72
+ * runStreaming and each spawn of spawnRunBatch. `signal`/`debug` are client
73
+ * concerns and never sent. */
74
+ function runBody(opts) {
75
+ const body = {
76
+ agent: opts.agent,
77
+ segments: opts.segments,
78
+ };
79
+ if (opts.allowedTools !== undefined)
80
+ body.allowed_tools = opts.allowedTools;
81
+ if (opts.allowedHosts !== undefined && opts.allowedHosts !== null) {
82
+ body.allowed_hosts = opts.allowedHosts;
83
+ }
84
+ if (opts.webSearchFilter !== undefined)
85
+ body.web_search_filter = opts.webSearchFilter;
86
+ if (opts.sessionId !== undefined)
87
+ body.session_id = opts.sessionId;
88
+ if (opts.tenantId !== undefined)
89
+ body.tenant_id = opts.tenantId;
90
+ if (opts.userId !== undefined)
91
+ body.user_id = opts.userId;
92
+ if (opts.agentId !== undefined)
93
+ body.agent_id = opts.agentId;
94
+ if (opts.userTier !== undefined)
95
+ body.user_tier = opts.userTier;
96
+ if (opts.userBearer !== undefined)
97
+ body.user_bearer = opts.userBearer;
98
+ if (opts.userCredentials !== undefined)
99
+ body.user_credentials = opts.userCredentials;
100
+ if (opts.parentContext !== undefined)
101
+ body.parent_context = opts.parentContext;
102
+ if (opts.metadata !== undefined)
103
+ body.metadata = opts.metadata;
104
+ if (opts.runTimeoutSeconds !== undefined)
105
+ body.run_timeout_seconds = opts.runTimeoutSeconds;
106
+ if (opts.sampling !== undefined)
107
+ body.sampling = samplingToWire(opts.sampling);
108
+ if (opts.compaction !== undefined)
109
+ body.compaction = compactionToWire(opts.compaction);
110
+ return body;
111
+ }
31
112
  class LoomcycleClient {
32
113
  ctx;
33
114
  constructor(opts = {}) {
@@ -60,44 +141,7 @@ class LoomcycleClient {
60
141
  * events around the real frames. Silent (default) when omitted.
61
142
  */
62
143
  async *runStreaming(opts) {
63
- // Build the body conditionally so omitted fields stay off the wire.
64
- // The pointer-vs-empty distinction on allowed_hosts is preserved by
65
- // treating `null` as "omit" — same as the server's nil semantics —
66
- // so callers threading a possibly-unset slice don't accidentally
67
- // send `allowed_hosts: null` (which JSON-decodes to a deny-all on
68
- // some implementations).
69
- const body = {
70
- agent: opts.agent,
71
- segments: opts.segments,
72
- };
73
- if (opts.allowedTools !== undefined)
74
- body.allowed_tools = opts.allowedTools;
75
- if (opts.allowedHosts !== undefined && opts.allowedHosts !== null) {
76
- body.allowed_hosts = opts.allowedHosts;
77
- }
78
- if (opts.webSearchFilter !== undefined)
79
- body.web_search_filter = opts.webSearchFilter;
80
- if (opts.sessionId !== undefined)
81
- body.session_id = opts.sessionId;
82
- if (opts.tenantId !== undefined)
83
- body.tenant_id = opts.tenantId;
84
- if (opts.userId !== undefined)
85
- body.user_id = opts.userId;
86
- if (opts.agentId !== undefined)
87
- body.agent_id = opts.agentId;
88
- if (opts.userTier !== undefined)
89
- body.user_tier = opts.userTier;
90
- if (opts.userBearer !== undefined)
91
- body.user_bearer = opts.userBearer;
92
- if (opts.userCredentials !== undefined)
93
- body.user_credentials = opts.userCredentials;
94
- if (opts.parentContext !== undefined)
95
- body.parent_context = opts.parentContext;
96
- if (opts.metadata !== undefined)
97
- body.metadata = opts.metadata;
98
- if (opts.runTimeoutSeconds !== undefined)
99
- body.run_timeout_seconds = opts.runTimeoutSeconds;
100
- yield* this.streamSSE("/v1/runs", body, opts.signal, opts.debug);
144
+ yield* this.streamSSE("/v1/runs", runBody(opts), opts.signal, opts.debug);
101
145
  }
102
146
  /**
103
147
  * Continue an existing session with a new run. The session's prior
@@ -141,8 +185,52 @@ class LoomcycleClient {
141
185
  body.metadata = opts.metadata;
142
186
  if (opts.runTimeoutSeconds !== undefined)
143
187
  body.run_timeout_seconds = opts.runTimeoutSeconds;
188
+ if (opts.sampling !== undefined)
189
+ body.sampling = samplingToWire(opts.sampling);
190
+ if (opts.compaction !== undefined)
191
+ body.compaction = compactionToWire(opts.compaction);
144
192
  yield* this.streamSSE(`/v1/sessions/${encodeURIComponent(opts.sessionId)}/messages`, body, opts.signal, opts.debug);
145
193
  }
194
+ /**
195
+ * Spawn N fresh runs concurrently in ONE call (RFC Y external fan-out) and
196
+ * resolve once they ALL settle, returning the combined index-aligned
197
+ * envelope. A per-child failure is captured in that child's result
198
+ * (`status` + `error`) and never rejects the batch. Prefer this over firing
199
+ * N parallel {@link LoomcycleClient.runStreaming} calls.
200
+ *
201
+ * Each spawn is a fresh run (its `sessionId` is ignored). Capped at 32 —
202
+ * an over-cap batch rejects with InvalidArgumentError. `mode: "detach"`
203
+ * (async handles) is reserved for a future release and rejected today.
204
+ *
205
+ * Blocking: resolves only when the slowest child finishes (or `timeoutMs`
206
+ * elapses). Mirrors POST /v1/runs:batch.
207
+ */
208
+ async spawnRunBatch(opts) {
209
+ const body = {
210
+ spawns: opts.spawns.map(runBody),
211
+ };
212
+ if (opts.mode !== undefined)
213
+ body.mode = opts.mode;
214
+ if (opts.timeoutMs !== undefined)
215
+ body.timeout_ms = opts.timeoutMs;
216
+ return (0, fetch_helpers_js_1.postJSON)(this.ctx, "/v1/runs:batch", body, {
217
+ signal: opts.signal,
218
+ });
219
+ }
220
+ /**
221
+ * Compact a run's conversation: summarize the history to free context and
222
+ * continue from the summary. Targets the run by `runId`. A live run must be
223
+ * PARKED (awaiting input) — a mid-turn run rejects (RunBusyError / 409).
224
+ * Returns `{ compacted, before_tokens, after_tokens, applied }`, where
225
+ * `applied` is "live", "marker", or "noop". Mirrors
226
+ * POST /v1/runs/{run_id}/compact.
227
+ */
228
+ async compactRun(runId, opts) {
229
+ const body = {};
230
+ if (opts?.reason !== undefined)
231
+ body.reason = opts.reason;
232
+ return (0, fetch_helpers_js_1.postJSON)(this.ctx, `/v1/runs/${encodeURIComponent(runId)}/compact`, body, opts);
233
+ }
146
234
  // ---- Agent metadata ----
147
235
  /** Read one agent's status + usage stats. Raises AgentNotFoundError
148
236
  * when the agent_id is unknown. */
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, 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";
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, CompactRunResult, RunBatchOptions, RunBatchResult, 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);
@@ -67,6 +67,33 @@ export declare class LoomcycleClient {
67
67
  * `_meta` open/close events.
68
68
  */
69
69
  continueSession(opts: ContinueOptions): AsyncIterable<AgentEvent>;
70
+ /**
71
+ * Spawn N fresh runs concurrently in ONE call (RFC Y external fan-out) and
72
+ * resolve once they ALL settle, returning the combined index-aligned
73
+ * envelope. A per-child failure is captured in that child's result
74
+ * (`status` + `error`) and never rejects the batch. Prefer this over firing
75
+ * N parallel {@link LoomcycleClient.runStreaming} calls.
76
+ *
77
+ * Each spawn is a fresh run (its `sessionId` is ignored). Capped at 32 —
78
+ * an over-cap batch rejects with InvalidArgumentError. `mode: "detach"`
79
+ * (async handles) is reserved for a future release and rejected today.
80
+ *
81
+ * Blocking: resolves only when the slowest child finishes (or `timeoutMs`
82
+ * elapses). Mirrors POST /v1/runs:batch.
83
+ */
84
+ spawnRunBatch(opts: RunBatchOptions): Promise<RunBatchResult>;
85
+ /**
86
+ * Compact a run's conversation: summarize the history to free context and
87
+ * continue from the summary. Targets the run by `runId`. A live run must be
88
+ * PARKED (awaiting input) — a mid-turn run rejects (RunBusyError / 409).
89
+ * Returns `{ compacted, before_tokens, after_tokens, applied }`, where
90
+ * `applied` is "live", "marker", or "noop". Mirrors
91
+ * POST /v1/runs/{run_id}/compact.
92
+ */
93
+ compactRun(runId: string, opts?: {
94
+ reason?: string;
95
+ signal?: AbortSignal;
96
+ }): Promise<CompactRunResult>;
70
97
  /** Read one agent's status + usage stats. Raises AgentNotFoundError
71
98
  * when the agent_id is unknown. */
72
99
  getAgent(agentId: string, opts?: {
package/dist/client.js CHANGED
@@ -25,6 +25,87 @@
25
25
  */
26
26
  import { authHeaders, deleteRequest, jsonFetch, patchJSON, postJSON, putJSON, raiseFromResponse, } from "./fetch-helpers.js";
27
27
  import { parseSSE } from "./stream.js";
28
+ /** samplingToWire maps the camelCase SamplingOptions to the snake_case wire
29
+ * object, omitting unset fields so they inherit the agent's value. */
30
+ function samplingToWire(s) {
31
+ const w = {};
32
+ if (s.temperature !== undefined)
33
+ w.temperature = s.temperature;
34
+ if (s.topP !== undefined)
35
+ w.top_p = s.topP;
36
+ if (s.topK !== undefined)
37
+ w.top_k = s.topK;
38
+ if (s.frequencyPenalty !== undefined)
39
+ w.frequency_penalty = s.frequencyPenalty;
40
+ if (s.presencePenalty !== undefined)
41
+ w.presence_penalty = s.presencePenalty;
42
+ if (s.seed !== undefined)
43
+ w.seed = s.seed;
44
+ if (s.stop !== undefined)
45
+ w.stop = s.stop;
46
+ return w;
47
+ }
48
+ /** compactionToWire maps the camelCase CompactionOptions to the snake_case
49
+ * wire object, omitting unset fields so they inherit the agent's value. */
50
+ function compactionToWire(c) {
51
+ const w = {};
52
+ if (c.enabled !== undefined)
53
+ w.enabled = c.enabled;
54
+ if (c.targetPercentage !== undefined)
55
+ w.target_percentage = c.targetPercentage;
56
+ if (c.keepLastN !== undefined)
57
+ w.keep_last_n = c.keepLastN;
58
+ if (c.keepFirst !== undefined)
59
+ w.keep_first = c.keepFirst;
60
+ if (c.autocompactAtPct !== undefined)
61
+ w.autocompact_at_pct = c.autocompactAtPct;
62
+ if (c.model !== undefined)
63
+ w.model = c.model;
64
+ return w;
65
+ }
66
+ /** runBody builds the snake_case /v1/runs request body from RunOptions,
67
+ * omitting unset fields (preserves the server's nil semantics — notably
68
+ * `allowedHosts: null` is treated as "omit", not deny-all). Shared by
69
+ * runStreaming and each spawn of spawnRunBatch. `signal`/`debug` are client
70
+ * concerns and never sent. */
71
+ function runBody(opts) {
72
+ const body = {
73
+ agent: opts.agent,
74
+ segments: opts.segments,
75
+ };
76
+ if (opts.allowedTools !== undefined)
77
+ body.allowed_tools = opts.allowedTools;
78
+ if (opts.allowedHosts !== undefined && opts.allowedHosts !== null) {
79
+ body.allowed_hosts = opts.allowedHosts;
80
+ }
81
+ if (opts.webSearchFilter !== undefined)
82
+ body.web_search_filter = opts.webSearchFilter;
83
+ if (opts.sessionId !== undefined)
84
+ body.session_id = opts.sessionId;
85
+ if (opts.tenantId !== undefined)
86
+ body.tenant_id = opts.tenantId;
87
+ if (opts.userId !== undefined)
88
+ body.user_id = opts.userId;
89
+ if (opts.agentId !== undefined)
90
+ body.agent_id = opts.agentId;
91
+ if (opts.userTier !== undefined)
92
+ body.user_tier = opts.userTier;
93
+ if (opts.userBearer !== undefined)
94
+ body.user_bearer = opts.userBearer;
95
+ if (opts.userCredentials !== undefined)
96
+ body.user_credentials = opts.userCredentials;
97
+ if (opts.parentContext !== undefined)
98
+ body.parent_context = opts.parentContext;
99
+ if (opts.metadata !== undefined)
100
+ body.metadata = opts.metadata;
101
+ if (opts.runTimeoutSeconds !== undefined)
102
+ body.run_timeout_seconds = opts.runTimeoutSeconds;
103
+ if (opts.sampling !== undefined)
104
+ body.sampling = samplingToWire(opts.sampling);
105
+ if (opts.compaction !== undefined)
106
+ body.compaction = compactionToWire(opts.compaction);
107
+ return body;
108
+ }
28
109
  export class LoomcycleClient {
29
110
  ctx;
30
111
  constructor(opts = {}) {
@@ -57,44 +138,7 @@ export class LoomcycleClient {
57
138
  * events around the real frames. Silent (default) when omitted.
58
139
  */
59
140
  async *runStreaming(opts) {
60
- // Build the body conditionally so omitted fields stay off the wire.
61
- // The pointer-vs-empty distinction on allowed_hosts is preserved by
62
- // treating `null` as "omit" — same as the server's nil semantics —
63
- // so callers threading a possibly-unset slice don't accidentally
64
- // send `allowed_hosts: null` (which JSON-decodes to a deny-all on
65
- // some implementations).
66
- const body = {
67
- agent: opts.agent,
68
- segments: opts.segments,
69
- };
70
- if (opts.allowedTools !== undefined)
71
- body.allowed_tools = opts.allowedTools;
72
- if (opts.allowedHosts !== undefined && opts.allowedHosts !== null) {
73
- body.allowed_hosts = opts.allowedHosts;
74
- }
75
- if (opts.webSearchFilter !== undefined)
76
- body.web_search_filter = opts.webSearchFilter;
77
- if (opts.sessionId !== undefined)
78
- body.session_id = opts.sessionId;
79
- if (opts.tenantId !== undefined)
80
- body.tenant_id = opts.tenantId;
81
- if (opts.userId !== undefined)
82
- body.user_id = opts.userId;
83
- if (opts.agentId !== undefined)
84
- body.agent_id = opts.agentId;
85
- if (opts.userTier !== undefined)
86
- body.user_tier = opts.userTier;
87
- if (opts.userBearer !== undefined)
88
- body.user_bearer = opts.userBearer;
89
- if (opts.userCredentials !== undefined)
90
- body.user_credentials = opts.userCredentials;
91
- if (opts.parentContext !== undefined)
92
- body.parent_context = opts.parentContext;
93
- if (opts.metadata !== undefined)
94
- body.metadata = opts.metadata;
95
- if (opts.runTimeoutSeconds !== undefined)
96
- body.run_timeout_seconds = opts.runTimeoutSeconds;
97
- yield* this.streamSSE("/v1/runs", body, opts.signal, opts.debug);
141
+ yield* this.streamSSE("/v1/runs", runBody(opts), opts.signal, opts.debug);
98
142
  }
99
143
  /**
100
144
  * Continue an existing session with a new run. The session's prior
@@ -138,8 +182,52 @@ export class LoomcycleClient {
138
182
  body.metadata = opts.metadata;
139
183
  if (opts.runTimeoutSeconds !== undefined)
140
184
  body.run_timeout_seconds = opts.runTimeoutSeconds;
185
+ if (opts.sampling !== undefined)
186
+ body.sampling = samplingToWire(opts.sampling);
187
+ if (opts.compaction !== undefined)
188
+ body.compaction = compactionToWire(opts.compaction);
141
189
  yield* this.streamSSE(`/v1/sessions/${encodeURIComponent(opts.sessionId)}/messages`, body, opts.signal, opts.debug);
142
190
  }
191
+ /**
192
+ * Spawn N fresh runs concurrently in ONE call (RFC Y external fan-out) and
193
+ * resolve once they ALL settle, returning the combined index-aligned
194
+ * envelope. A per-child failure is captured in that child's result
195
+ * (`status` + `error`) and never rejects the batch. Prefer this over firing
196
+ * N parallel {@link LoomcycleClient.runStreaming} calls.
197
+ *
198
+ * Each spawn is a fresh run (its `sessionId` is ignored). Capped at 32 —
199
+ * an over-cap batch rejects with InvalidArgumentError. `mode: "detach"`
200
+ * (async handles) is reserved for a future release and rejected today.
201
+ *
202
+ * Blocking: resolves only when the slowest child finishes (or `timeoutMs`
203
+ * elapses). Mirrors POST /v1/runs:batch.
204
+ */
205
+ async spawnRunBatch(opts) {
206
+ const body = {
207
+ spawns: opts.spawns.map(runBody),
208
+ };
209
+ if (opts.mode !== undefined)
210
+ body.mode = opts.mode;
211
+ if (opts.timeoutMs !== undefined)
212
+ body.timeout_ms = opts.timeoutMs;
213
+ return postJSON(this.ctx, "/v1/runs:batch", body, {
214
+ signal: opts.signal,
215
+ });
216
+ }
217
+ /**
218
+ * Compact a run's conversation: summarize the history to free context and
219
+ * continue from the summary. Targets the run by `runId`. A live run must be
220
+ * PARKED (awaiting input) — a mid-turn run rejects (RunBusyError / 409).
221
+ * Returns `{ compacted, before_tokens, after_tokens, applied }`, where
222
+ * `applied` is "live", "marker", or "noop". Mirrors
223
+ * POST /v1/runs/{run_id}/compact.
224
+ */
225
+ async compactRun(runId, opts) {
226
+ const body = {};
227
+ if (opts?.reason !== undefined)
228
+ body.reason = opts.reason;
229
+ return postJSON(this.ctx, `/v1/runs/${encodeURIComponent(runId)}/compact`, body, opts);
230
+ }
143
231
  // ---- Agent metadata ----
144
232
  /** Read one agent's status + usage stats. Raises AgentNotFoundError
145
233
  * when the agent_id is unknown. */
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, 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";
85
+ export type { AgentEvent, ClientOptions, ContinueOptions, EventType, HostWidening, ParentContext, PromptContent, PromptSegment, RetryInfo, RunOptions, SamplingOptions, CompactionOptions, ToolUse, Usage, Agent, AgentStatus, AgentUsage, CancelAgentResult, ListAgentsResponse, RunBatchOptions, RunBatchResult, SpawnRunResult, CompactRunResult, 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
@@ -168,6 +168,15 @@ export interface RunOptions {
168
168
  * its budget spans that wait, so the CPU-oriented default is often too low.
169
169
  * Ignored by LLM agents. 0 / omitted = inherit. */
170
170
  runTimeoutSeconds?: number;
171
+ /** Per-run LLM sampling override (v0.28.0), merged PER FIELD over the
172
+ * agent's own sampling (this wins; unset fields inherit). Omitted =
173
+ * inherit entirely. */
174
+ sampling?: SamplingOptions;
175
+ /** Per-run context-compaction override (v0.32.0), merged PER FIELD over
176
+ * the agent's own compaction block (this wins; unset fields inherit).
177
+ * Omitted = inherit entirely. Trigger compaction mid-run with
178
+ * {@link LoomcycleClient.compactRun}. */
179
+ compaction?: CompactionOptions;
171
180
  /** Opt-in observability: when true, the iterator emits client-
172
181
  * synthesized `{ type: "_meta", meta_subtype: "stream_open" | "stream_close" }`
173
182
  * events around the real event stream. `meta_reason` carries the
@@ -178,6 +187,38 @@ export interface RunOptions {
178
187
  debug?: boolean;
179
188
  signal?: AbortSignal;
180
189
  }
190
+ /** Per-run LLM sampling override (v0.28.0). Mirrors config.Sampling — every
191
+ * field optional; an unset field inherits the agent's value. An explicit
192
+ * `temperature: 0` is deterministic, NOT "unset". Each provider maps what it
193
+ * supports (e.g. topK is Anthropic/Gemini/Ollama; frequencyPenalty/
194
+ * presencePenalty/seed are OpenAI/DeepSeek/Ollama). */
195
+ export interface SamplingOptions {
196
+ temperature?: number;
197
+ topP?: number;
198
+ topK?: number;
199
+ frequencyPenalty?: number;
200
+ presencePenalty?: number;
201
+ seed?: number;
202
+ stop?: string[];
203
+ }
204
+ /** Per-run context-compaction override (v0.32.0). Mirrors config.Compaction —
205
+ * every field optional; an unset field inherits the agent's value. */
206
+ export interface CompactionOptions {
207
+ /** Turn AUTO-compaction on for this run (default off). */
208
+ enabled?: boolean;
209
+ /** Summary aims for ~N% of the compacted span's length (10..50; default 10). */
210
+ targetPercentage?: number;
211
+ /** Keep the last N messages verbatim (default 4; 0 = summarize all). */
212
+ keepLastN?: number;
213
+ /** Pin the first user message (the task) verbatim (default true). */
214
+ keepFirst?: boolean;
215
+ /** Auto-compact when used/window ≥ N% (50..95; default 80; only when
216
+ * enabled + the provider reports a context window). */
217
+ autocompactAtPct?: number;
218
+ /** Run the summary call on a cheaper/faster model served by the SAME
219
+ * provider. Omitted = the run's model. */
220
+ model?: string;
221
+ }
181
222
  /** Opaque caller-tracking lineage (v0.12.x) attached to a run and
182
223
  * propagated to all its sub-agents. The runtime stores and echoes
183
224
  * these fields verbatim and never interprets them. All fields
@@ -234,6 +275,10 @@ export interface ContinueOptions {
234
275
  /** Optional ad-hoc per-run code-js wall-clock budget (seconds) for the
235
276
  * continuation's new run — see {@link RunOptions.runTimeoutSeconds}. */
236
277
  runTimeoutSeconds?: number;
278
+ /** Per-continuation LLM sampling override — see {@link RunOptions.sampling}. */
279
+ sampling?: SamplingOptions;
280
+ /** Per-continuation context-compaction override — see {@link RunOptions.compaction}. */
281
+ compaction?: CompactionOptions;
237
282
  /** Opt-in observability: see {@link RunOptions.debug}. Same shape. */
238
283
  debug?: boolean;
239
284
  signal?: AbortSignal;
@@ -292,6 +337,51 @@ export interface CancelAgentResult {
292
337
  * terminated; the call still succeeds (idempotent contract). */
293
338
  cancelledCount: number;
294
339
  }
340
+ /** Options for {@link LoomcycleClient.spawnRunBatch} — the RFC Y external
341
+ * fan-out. Each spawn is a fresh-run {@link RunOptions} (its `sessionId` is
342
+ * ignored — batch children never continue a session; `signal`/`debug` are
343
+ * per-call client concerns and not sent). Capped at 32; the server rejects an
344
+ * over-cap batch. */
345
+ export interface RunBatchOptions {
346
+ spawns: RunOptions[];
347
+ /** "join" (default) — block until all children settle, returning the
348
+ * combined envelope. "detach" (async run handles) is reserved for a future
349
+ * release and rejected by the server today. */
350
+ mode?: "join";
351
+ /** Optional join deadline (ms): a child still running when it elapses is
352
+ * cancelled and reported with a cancelled status in-envelope. */
353
+ timeoutMs?: number;
354
+ signal?: AbortSignal;
355
+ }
356
+ /** One child run's outcome in a batch. Mirrors the server's SpawnResult wire
357
+ * shape; a per-child failure is reported via `status` + `error`, never as a
358
+ * thrown error (the batch as a whole still resolves). */
359
+ export interface SpawnRunResult {
360
+ agent_id: string;
361
+ run_id: string;
362
+ session_id: string;
363
+ status: AgentStatus;
364
+ stop_reason?: string;
365
+ final_text?: string;
366
+ usage?: AgentUsage;
367
+ error?: string;
368
+ }
369
+ /** Result of {@link LoomcycleClient.spawnRunBatch} — `results` is index-aligned
370
+ * with the request's `spawns`. */
371
+ export interface RunBatchResult {
372
+ results: SpawnRunResult[];
373
+ spawned: number;
374
+ }
375
+ /** Result of {@link LoomcycleClient.compactRun}. `applied` is "live" (pushed to
376
+ * the running loop), "marker" (persisted for a terminal run's next
377
+ * continuation), or "noop" (too short to compact). */
378
+ export interface CompactRunResult {
379
+ run_id: string;
380
+ compacted: boolean;
381
+ before_tokens: number;
382
+ after_tokens: number;
383
+ applied: "live" | "marker" | "noop";
384
+ }
295
385
  /** TranscriptEvent — one persisted store.Event from
296
386
  * GET /v1/sessions/{id}/transcript. The server wraps each
297
387
  * providers.Event in {seq, run_id, ts_ns, type, event:{...}}.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@loomcycle/client",
3
- "version": "0.29.1",
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). 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.)",
3
+ "version": "0.34.0",
4
+ "description": "TypeScript client for the loomcycle sidecar (HTTP+SSE). 54 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).",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
7
7
  "repository": {