@demicodes/agent 0.16.0 → 0.17.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.
@@ -1,4 +1,4 @@
1
- import { b as AgentMetadata, d as TranscriptPatch, l as ServerFrame, n as AgentServerTransport, o as ClientFrame, r as AgentTransport, s as ClientSessionEvent, t as AgentClientTransport, u as ShellCommandStatusLike } from "./transport-CfvLnrq0.mjs";
2
- import { a as AgentClient, i as AgentActionOptions, n as createWebSocketClientTransport, o as AgentClientListener, r as createWebSocketServerTransport, t as JsonWebSocket } from "./websocket-transport-DkL4cjeV.mjs";
1
+ import { b as AgentMetadata, d as TranscriptPatch, l as ServerFrame, n as AgentServerTransport, o as ClientFrame, r as AgentTransport, s as ClientSessionEvent, t as AgentClientTransport, u as ShellCommandStatusLike } from "./transport-DtBCCS_A.mjs";
2
+ import { a as AgentClient, i as AgentActionOptions, n as createWebSocketClientTransport, o as AgentClientListener, r as createWebSocketServerTransport, t as JsonWebSocket } from "./websocket-transport-DdfGgBjO.mjs";
3
3
  import { ProviderSelection } from "@demicodes/provider";
4
4
  export { type AgentActionOptions, AgentClient, type AgentClientListener, type AgentClientTransport, type AgentMetadata, type AgentServerTransport, type AgentTransport, type ClientFrame, type ClientSessionEvent, type JsonWebSocket, type ProviderSelection, type ServerFrame, type ShellCommandStatusLike, type TranscriptPatch, createWebSocketClientTransport, createWebSocketServerTransport };
@@ -1,2 +1,2 @@
1
- import { n as createWebSocketServerTransport, r as AgentClient, t as createWebSocketClientTransport } from "./websocket-transport-BjSj3U0I.mjs";
1
+ import { n as createWebSocketServerTransport, r as AgentClient, t as createWebSocketClientTransport } from "./websocket-transport-c6P3NBuf.mjs";
2
2
  export { AgentClient, createWebSocketClientTransport, createWebSocketServerTransport };
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { A as AgentTool, B as TranscriptOptions, C as AgentSessionCheckpoint, D as AgentSessionRestoreParams, E as AgentSessionParams, F as SessionEvent, G as resolveRetryPolicy, H as DEFAULT_TURN_RETRY_POLICY, I as SessionEventListener, K as retryDelayMs, L as CompactionWindow, M as AgentToolInvokeContext, N as AgentToolInvokeResult, O as AgentSessionStore, P as ExternalMutationReservation, R as DrainedTranscriptPatches, S as AgentReferenceResolveContext, T as AgentSessionOptions, U as TurnRetryPolicy, V as estimateTranscriptBlockTokens, W as isRetryableCode, _ as AgentHarnessRuntime, a as createInProcessTransportPair, b as AgentMetadata, c as ConversationSummary, d as TranscriptPatch, f as AbortResult, g as AgentHarnessContext, h as AgentHarness, i as InProcessTransportPair, j as AgentToolContext, k as AgentSystemPromptContext, l as ServerFrame, m as AgentDisposeContext, n as AgentServerTransport, o as ClientFrame, p as AbortTarget, r as AgentTransport, s as ClientSessionEvent, t as AgentClientTransport, u as ShellCommandStatusLike, v as AgentHostContext, w as AgentSessionCloneParams, x as AgentPromptContext, y as AgentLifecycleEvent, z as TranscriptLog } from "./transport-CfvLnrq0.mjs";
2
- import { a as AgentClient, i as AgentActionOptions, n as createWebSocketClientTransport, o as AgentClientListener, r as createWebSocketServerTransport, t as JsonWebSocket } from "./websocket-transport-DkL4cjeV.mjs";
1
+ import { A as AgentTool, B as TranscriptLog, C as AgentSessionCheckpoint, D as AgentSessionRestoreParams, E as AgentSessionParams, F as ModelSwitchApply, G as isRetryableCode, H as estimateTranscriptBlockTokens, I as SessionEvent, K as resolveRetryPolicy, L as SessionEventListener, M as AgentToolInvokeContext, N as AgentToolInvokeResult, O as AgentSessionStore, P as ExternalMutationReservation, R as CompactionWindow, S as AgentReferenceResolveContext, T as AgentSessionOptions, U as DEFAULT_TURN_RETRY_POLICY, V as TranscriptOptions, W as TurnRetryPolicy, _ as AgentHarnessRuntime, a as createInProcessTransportPair, b as AgentMetadata, c as ConversationSummary, d as TranscriptPatch, f as AbortResult, g as AgentHarnessContext, h as AgentHarness, i as InProcessTransportPair, j as AgentToolContext, k as AgentSystemPromptContext, l as ServerFrame, m as AgentDisposeContext, n as AgentServerTransport, o as ClientFrame, p as AbortTarget, q as retryDelayMs, r as AgentTransport, s as ClientSessionEvent, t as AgentClientTransport, u as ShellCommandStatusLike, v as AgentHostContext, w as AgentSessionCloneParams, x as AgentPromptContext, y as AgentLifecycleEvent, z as DrainedTranscriptPatches } from "./transport-DtBCCS_A.mjs";
2
+ import { a as AgentClient, i as AgentActionOptions, n as createWebSocketClientTransport, o as AgentClientListener, r as createWebSocketServerTransport, t as JsonWebSocket } from "./websocket-transport-DdfGgBjO.mjs";
3
3
  import { BashAuditEvent, BashEnvironment, BashEnvironmentOptions, CommandMetadataRecord, Host, ShellCommandStatus, ShellOutputChunk } from "@demicodes/shell";
4
4
  import { AgentProvider, Provider } from "@demicodes/provider";
5
5
  import { Block, Model, ModelMediaKind, ModelSelection, ProviderErrorDiagnostics, QueuedMessage, SessionPhase, UserContentBlock } from "@demicodes/core";
@@ -123,18 +123,19 @@ declare class AgentSession<State> {
123
123
  }): Promise<void>;
124
124
  cancelPendingSteer(id: string): boolean;
125
125
  /**
126
- * Switches the model (and optionally the provider) for the rest of the session. Queued as an
127
- * action so it lands at a turn boundary, never mid-tool-continuation; the next turn uses it.
128
- * A non-null `provider` replaces the current one (its predecessor is disposed); pass null to
129
- * keep the same provider instance and only change the model.
130
- */
131
- /**
132
- * Records a model/provider switch. It is applied at the next turn's preflight (see
133
- * applyPendingModelSwitch): if the new model can't hold the history, compaction runs there
134
- * with the current (pre-switch) model first, then the swap happens. Recording is cheap and
135
- * non-blocking so it never holds up an in-flight turn or other frames.
126
+ * Records a model/provider switch for the rest of the session. A non-null `provider`
127
+ * replaces the current one (its predecessor is disposed); pass null to keep the same
128
+ * provider instance and only change the model.
129
+ *
130
+ * `apply` picks the boundary the switch lands on: 'next_turn' (default) waits for the
131
+ * start of the next queued action, so a running turn finishes entirely on the old model;
132
+ * 'immediate' also applies mid-turn at the next sampling/tool continuation, so the very
133
+ * next request already runs on the new model (the same "as soon as possible" semantics
134
+ * steering has). Either way, if the new model can't hold the history, compaction runs
135
+ * first with the current (pre-switch) model, then the swap happens. Recording is cheap
136
+ * and non-blocking so it never holds up an in-flight turn or other frames.
136
137
  */
137
- updateModel(provider: AgentProvider | null, model: ModelSelection): void;
138
+ updateModel(provider: AgentProvider | null, model: ModelSelection, apply?: ModelSwitchApply): void;
138
139
  abort(): Promise<AbortResult>;
139
140
  scheduleYieldWakeup(durationMs: number, metadata?: AgentMetadata | null): AgentToolInvokeResult;
140
141
  waitUntilDone(): Promise<void>;
@@ -170,13 +171,20 @@ declare class AgentSession<State> {
170
171
  private runWorker;
171
172
  private executeAction;
172
173
  /**
173
- * Applies a queued model/provider switch at a turn boundary (preflight). If the new model's
174
- * context window can't hold the current history, compaction runs FIRST with the current
175
- * (pre-switch) model + provider — which can still load it to summarize — and only then do we
176
- * swap. Doing it the other way would ask the smaller model to summarize a history it may not
177
- * be able to load.
174
+ * Applies a queued model/provider switch at an action boundary (turn preflight). If the
175
+ * new model's context window can't hold the current history, compaction runs FIRST with
176
+ * the current (pre-switch) model + provider — which can still load it to summarize — and
177
+ * only then do we swap. Doing it the other way would ask the smaller model to summarize
178
+ * a history it may not be able to load. Returns whether that compaction actually ran
179
+ * (false when no switch was pending).
178
180
  */
179
181
  private applyPendingModelSwitch;
182
+ /**
183
+ * Turn-loop variant for mid-turn continuation boundaries: only switches recorded with
184
+ * apply 'immediate' land here; 'next_turn' switches stay pending until the running turn
185
+ * finishes and the next action starts.
186
+ */
187
+ private applyImmediateModelSwitch;
180
188
  private runWithCompactingPhase;
181
189
  private executeSend;
182
190
  private resolveReferences;
@@ -377,4 +385,4 @@ interface ShellToolView {
377
385
  declare function finishShellToolResult<State>(environment: BashEnvironment, result: ShellCommandStatus, ctx: AgentToolInvokeContext<State>): Promise<AgentToolInvokeResult>;
378
386
  declare function shellCommandHandleRequired(result: ShellCommandStatus, budgetTokens: number): boolean;
379
387
  //#endregion
380
- export { AbortResult, AbortTarget, ActiveTurnPhase, AgentActionOptions, AgentClient, AgentClientListener, AgentClientTransport, AgentDisposeContext, AgentHarness, AgentHarnessContext, AgentHarnessRuntime, AgentHostContext, AgentLifecycleEvent, AgentMetadata, AgentPromptContext, AgentReferenceResolveContext, AgentServer, AgentServerOptions, AgentServerSessionOptions, AgentServerTransport, AgentSession, AgentSessionCheckpoint, AgentSessionCloneParams, AgentSessionOptions, AgentSessionParams, AgentSessionRestoreParams, AgentSessionStore, AgentSystemPromptContext, AgentTool, AgentToolContext, AgentToolInvokeContext, AgentToolInvokeResult, AgentTransport, AgentTransportBinding, ClientFrame, ClientSessionEvent, CompactionWindow, ConversationSummary, DEFAULT_MAX_MEDIA_BYTES, DEFAULT_TURN_RETRY_POLICY, DrainedTranscriptPatches, ExternalMutationReservation, InProcessTransportPair, JsonWebSocket, PrepareShell, PrepareShellContext, ProviderStreamError, ResumePoint, RunCommandLineCommandNotRegisteredError, RunCommandLineOptions, RunCommandLineResult, RunCommandLineShellNotFoundError, RunCommandLineTimeoutError, SHELL_VIEW_MAX_CHARS, ServerFrame, SessionEvent, SessionEventListener, ShellCommandStatusLike, ShellToolResultOptions, ShellToolView, StandardAgentToolOptions, TranscriptLog, TranscriptOptions, TranscriptPatch, TurnRetryPolicy, applyTranscriptPatches, cloneBlocks, createInProcessTransportPair, createStandardAgentTools, createWebSocketClientTransport, createWebSocketServerTransport, estimateTranscriptBlockTokens, findResumePoint, finishShellToolResult, isContextLengthExceeded, isRetryableCode, resolveRetryPolicy, retryDelayMs, shellCommandHandleRequired, shellPreviewBudgetTokens, toShellToolResult };
388
+ export { AbortResult, AbortTarget, ActiveTurnPhase, AgentActionOptions, AgentClient, AgentClientListener, AgentClientTransport, AgentDisposeContext, AgentHarness, AgentHarnessContext, AgentHarnessRuntime, AgentHostContext, AgentLifecycleEvent, AgentMetadata, AgentPromptContext, AgentReferenceResolveContext, AgentServer, AgentServerOptions, AgentServerSessionOptions, AgentServerTransport, AgentSession, AgentSessionCheckpoint, AgentSessionCloneParams, AgentSessionOptions, AgentSessionParams, AgentSessionRestoreParams, AgentSessionStore, AgentSystemPromptContext, AgentTool, AgentToolContext, AgentToolInvokeContext, AgentToolInvokeResult, AgentTransport, AgentTransportBinding, ClientFrame, ClientSessionEvent, CompactionWindow, ConversationSummary, DEFAULT_MAX_MEDIA_BYTES, DEFAULT_TURN_RETRY_POLICY, DrainedTranscriptPatches, ExternalMutationReservation, InProcessTransportPair, JsonWebSocket, ModelSwitchApply, PrepareShell, PrepareShellContext, ProviderStreamError, ResumePoint, RunCommandLineCommandNotRegisteredError, RunCommandLineOptions, RunCommandLineResult, RunCommandLineShellNotFoundError, RunCommandLineTimeoutError, SHELL_VIEW_MAX_CHARS, ServerFrame, SessionEvent, SessionEventListener, ShellCommandStatusLike, ShellToolResultOptions, ShellToolView, StandardAgentToolOptions, TranscriptLog, TranscriptOptions, TranscriptPatch, TurnRetryPolicy, applyTranscriptPatches, cloneBlocks, createInProcessTransportPair, createStandardAgentTools, createWebSocketClientTransport, createWebSocketServerTransport, estimateTranscriptBlockTokens, findResumePoint, finishShellToolResult, isContextLengthExceeded, isRetryableCode, resolveRetryPolicy, retryDelayMs, shellCommandHandleRequired, shellPreviewBudgetTokens, toShellToolResult };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as cloneBlocks, i as applyTranscriptPatches, n as createWebSocketServerTransport, o as ProviderStreamError, r as AgentClient, s as isContextLengthExceeded, t as createWebSocketClientTransport } from "./websocket-transport-BjSj3U0I.mjs";
1
+ import { a as cloneBlocks, i as applyTranscriptPatches, n as createWebSocketServerTransport, o as ProviderStreamError, r as AgentClient, s as isContextLengthExceeded, t as createWebSocketClientTransport } from "./websocket-transport-c6P3NBuf.mjs";
2
2
  import { AbortError, abortable, asError, asRecord, asString, bytesToBase64, createId, delay, isAbortError, isRecord, noop, parseJsonOrString, safeJsonStringify, sliceHead, sliceTail, throwIfAborted, toWellFormedText, truncate } from "@demicodes/utils";
3
3
  import { BashEnvironment, CommandRegistry, MAX_TIMEOUT_MS, heredocDelimiter, shellQuote } from "@demicodes/shell";
4
4
  import { providerRuntime } from "@demicodes/provider";
@@ -835,14 +835,22 @@ var CompactionController = class {
835
835
  constructor(host) {
836
836
  this.host = host;
837
837
  }
838
- /** Compacts (up to 8 passes) until the history fits `targetModel`'s context, if over threshold. */
838
+ /**
839
+ * Compacts (up to 8 passes) until the history fits `targetModel`'s context, if over
840
+ * threshold. Returns whether anything was compacted.
841
+ */
839
842
  async compactToFit(targetModel) {
840
843
  const contextWindow = targetModel.model.contextWindow;
841
- if (contextWindow <= 0) return;
844
+ if (contextWindow <= 0) return false;
842
845
  const threshold = resolveCompactionThreshold(contextWindow, this.host.thresholdRatio, this.host.thresholdTokens);
843
- if (this.host.transcript.estimateContextTokens(contextWindow) < threshold) return;
844
- await this.host.runWithCompactingPhase(async () => {
845
- for (let attempt = 0; attempt < 8 && this.host.transcript.estimateContextTokens(contextWindow) >= threshold; attempt += 1) if (!await this.run()) break;
846
+ if (this.host.transcript.estimateContextTokens(contextWindow) < threshold) return false;
847
+ return this.host.runWithCompactingPhase(async () => {
848
+ let compacted = false;
849
+ for (let attempt = 0; attempt < 8 && this.host.transcript.estimateContextTokens(contextWindow) >= threshold; attempt += 1) {
850
+ if (!await this.run()) break;
851
+ compacted = true;
852
+ }
853
+ return compacted;
846
854
  });
847
855
  }
848
856
  /** Runs one compaction pass before a turn when the current model is over threshold. */
@@ -936,6 +944,10 @@ var ProviderTurnLoop = class {
936
944
  let autoCompactions = 0;
937
945
  while (true) {
938
946
  throwIfAborted(this.host.currentSignal());
947
+ if (await this.host.applyImmediateModelSwitch()) {
948
+ this.host.transcript.pushResumeTurn(this.host.currentTurnId(), this.host.model);
949
+ await this.host.commitTranscript();
950
+ }
939
951
  await this.host.materializePendingSteers();
940
952
  const steerContinuationBeforeStream = this.host.steerContinuationCount;
941
953
  const shouldAutoRecover = await this.streamProviderOnce();
@@ -1338,6 +1350,7 @@ var AgentSession = class AgentSession {
1338
1350
  self.activeProviderRun = run;
1339
1351
  },
1340
1352
  streamProvider: (request, run) => self.providerEvents(request, run),
1353
+ applyImmediateModelSwitch: () => self.applyImmediateModelSwitch(),
1341
1354
  runCompaction: () => self.compaction.run(),
1342
1355
  runWithCompactingPhase: (fn) => self.runWithCompactingPhase(fn),
1343
1356
  commitTranscript: () => self.commitTranscript(),
@@ -1471,21 +1484,23 @@ var AgentSession = class AgentSession {
1471
1484
  return false;
1472
1485
  }
1473
1486
  /**
1474
- * Switches the model (and optionally the provider) for the rest of the session. Queued as an
1475
- * action so it lands at a turn boundary, never mid-tool-continuation; the next turn uses it.
1476
- * A non-null `provider` replaces the current one (its predecessor is disposed); pass null to
1477
- * keep the same provider instance and only change the model.
1478
- */
1479
- /**
1480
- * Records a model/provider switch. It is applied at the next turn's preflight (see
1481
- * applyPendingModelSwitch): if the new model can't hold the history, compaction runs there
1482
- * with the current (pre-switch) model first, then the swap happens. Recording is cheap and
1483
- * non-blocking so it never holds up an in-flight turn or other frames.
1487
+ * Records a model/provider switch for the rest of the session. A non-null `provider`
1488
+ * replaces the current one (its predecessor is disposed); pass null to keep the same
1489
+ * provider instance and only change the model.
1490
+ *
1491
+ * `apply` picks the boundary the switch lands on: 'next_turn' (default) waits for the
1492
+ * start of the next queued action, so a running turn finishes entirely on the old model;
1493
+ * 'immediate' also applies mid-turn at the next sampling/tool continuation, so the very
1494
+ * next request already runs on the new model (the same "as soon as possible" semantics
1495
+ * steering has). Either way, if the new model can't hold the history, compaction runs
1496
+ * first with the current (pre-switch) model, then the swap happens. Recording is cheap
1497
+ * and non-blocking so it never holds up an in-flight turn or other frames.
1484
1498
  */
1485
- updateModel(provider, model) {
1499
+ updateModel(provider, model, apply = "next_turn") {
1486
1500
  this.pendingModelSwitch = {
1487
1501
  provider,
1488
- model
1502
+ model,
1503
+ apply
1489
1504
  };
1490
1505
  }
1491
1506
  async abort() {
@@ -1857,23 +1872,34 @@ var AgentSession = class AgentSession {
1857
1872
  }
1858
1873
  }
1859
1874
  /**
1860
- * Applies a queued model/provider switch at a turn boundary (preflight). If the new model's
1861
- * context window can't hold the current history, compaction runs FIRST with the current
1862
- * (pre-switch) model + provider — which can still load it to summarize — and only then do we
1863
- * swap. Doing it the other way would ask the smaller model to summarize a history it may not
1864
- * be able to load.
1875
+ * Applies a queued model/provider switch at an action boundary (turn preflight). If the
1876
+ * new model's context window can't hold the current history, compaction runs FIRST with
1877
+ * the current (pre-switch) model + provider — which can still load it to summarize — and
1878
+ * only then do we swap. Doing it the other way would ask the smaller model to summarize
1879
+ * a history it may not be able to load. Returns whether that compaction actually ran
1880
+ * (false when no switch was pending).
1865
1881
  */
1866
1882
  async applyPendingModelSwitch() {
1867
1883
  const pending = this.pendingModelSwitch;
1868
- if (!pending) return;
1884
+ if (!pending) return false;
1869
1885
  this.pendingModelSwitch = null;
1870
- await this.compaction.compactToFit(pending.model);
1886
+ const compacted = await this.compaction.compactToFit(pending.model);
1871
1887
  if (pending.provider && pending.provider !== this.provider) {
1872
1888
  const previous = this.provider;
1873
1889
  this.provider = pending.provider;
1874
1890
  await previous.dispose?.();
1875
1891
  }
1876
1892
  this.model = pending.model;
1893
+ return compacted;
1894
+ }
1895
+ /**
1896
+ * Turn-loop variant for mid-turn continuation boundaries: only switches recorded with
1897
+ * apply 'immediate' land here; 'next_turn' switches stay pending until the running turn
1898
+ * finishes and the next action starts.
1899
+ */
1900
+ async applyImmediateModelSwitch() {
1901
+ if (this.pendingModelSwitch?.apply !== "immediate") return false;
1902
+ return this.applyPendingModelSwitch();
1877
1903
  }
1878
1904
  async runWithCompactingPhase(fn) {
1879
1905
  const previousPhase = this.currentPhase;
@@ -2856,7 +2882,7 @@ var AgentTransportBindingImpl = class {
2856
2882
  this.session?.cancelPendingSteer(frame.steerId);
2857
2883
  return;
2858
2884
  case "set_provider":
2859
- await this.setProvider(frame.provider);
2885
+ await this.setProvider(frame.provider, frame.apply);
2860
2886
  return;
2861
2887
  case "retry": {
2862
2888
  const session = this.sessionFor("retry");
@@ -3046,7 +3072,7 @@ var AgentTransportBindingImpl = class {
3046
3072
  return;
3047
3073
  }
3048
3074
  }
3049
- async setProvider(provider) {
3075
+ async setProvider(provider, apply) {
3050
3076
  const session = this.session;
3051
3077
  if (!session) {
3052
3078
  this.send({
@@ -3057,11 +3083,11 @@ var AgentTransportBindingImpl = class {
3057
3083
  return;
3058
3084
  }
3059
3085
  if (provider.providerId === this.currentProviderId) {
3060
- await session.updateModel(null, provider.model);
3086
+ session.updateModel(null, provider.model, apply);
3061
3087
  return;
3062
3088
  }
3063
3089
  const next = await this.createRuntime(provider);
3064
- await session.updateModel(next, provider.model);
3090
+ session.updateModel(next, provider.model, apply);
3065
3091
  this.currentProviderId = provider.providerId;
3066
3092
  }
3067
3093
  async createRuntime(selection) {
@@ -1,4 +1,4 @@
1
- import { n as AgentServerTransport, t as AgentClientTransport } from "./transport-CfvLnrq0.mjs";
1
+ import { n as AgentServerTransport, t as AgentClientTransport } from "./transport-DtBCCS_A.mjs";
2
2
  import { Readable, Writable } from "node:stream";
3
3
  //#region src/stdio-transport.d.ts
4
4
  declare function createStdioClientTransport(readable: Readable, writable: Writable): AgentClientTransport;
@@ -209,6 +209,14 @@ interface AgentToolInvokeResult {
209
209
  view?: unknown | null;
210
210
  stopAfterToolResult?: boolean;
211
211
  }
212
+ /**
213
+ * When a recorded model/provider switch is applied:
214
+ * - 'next_turn' (default): the start of the next queued action — a running turn, if any,
215
+ * finishes entirely on the old model.
216
+ * - 'immediate': the next inference boundary — mid-turn that is the next sampling/tool
217
+ * continuation, so the very next request already runs on the new model.
218
+ */
219
+ type ModelSwitchApply = 'immediate' | 'next_turn';
212
220
  type AbortTarget = 'active_provider_stream' | 'active_tool' | 'active_compaction' | 'active_turn' | 'queued_action' | 'queued_message' | 'pending_yield_wakeup';
213
221
  interface AbortResult {
214
222
  aborted: boolean;
@@ -394,6 +402,7 @@ type ClientFrame = {
394
402
  } | {
395
403
  type: 'set_provider';
396
404
  provider: ProviderSelection;
405
+ apply?: ModelSwitchApply;
397
406
  } | {
398
407
  type: 'abort';
399
408
  } | {
@@ -586,4 +595,4 @@ interface InProcessTransportPair {
586
595
  }
587
596
  declare function createInProcessTransportPair(): InProcessTransportPair;
588
597
  //#endregion
589
- export { AgentTool as A, TranscriptOptions as B, AgentSessionCheckpoint as C, AgentSessionRestoreParams as D, AgentSessionParams as E, SessionEvent as F, resolveRetryPolicy as G, DEFAULT_TURN_RETRY_POLICY as H, SessionEventListener as I, retryDelayMs as K, CompactionWindow as L, AgentToolInvokeContext as M, AgentToolInvokeResult as N, AgentSessionStore as O, ExternalMutationReservation as P, DrainedTranscriptPatches as R, AgentReferenceResolveContext as S, AgentSessionOptions as T, TurnRetryPolicy as U, estimateTranscriptBlockTokens as V, isRetryableCode as W, AgentHarnessRuntime as _, createInProcessTransportPair as a, AgentMetadata as b, ConversationSummary as c, TranscriptPatch as d, AbortResult as f, AgentHarnessContext as g, AgentHarness as h, InProcessTransportPair as i, AgentToolContext as j, AgentSystemPromptContext as k, ServerFrame as l, AgentDisposeContext as m, AgentServerTransport as n, ClientFrame as o, AbortTarget as p, AgentTransport as r, ClientSessionEvent as s, AgentClientTransport as t, ShellCommandStatusLike as u, AgentHostContext as v, AgentSessionCloneParams as w, AgentPromptContext as x, AgentLifecycleEvent as y, TranscriptLog as z };
598
+ export { AgentTool as A, TranscriptLog as B, AgentSessionCheckpoint as C, AgentSessionRestoreParams as D, AgentSessionParams as E, ModelSwitchApply as F, isRetryableCode as G, estimateTranscriptBlockTokens as H, SessionEvent as I, resolveRetryPolicy as K, SessionEventListener as L, AgentToolInvokeContext as M, AgentToolInvokeResult as N, AgentSessionStore as O, ExternalMutationReservation as P, CompactionWindow as R, AgentReferenceResolveContext as S, AgentSessionOptions as T, DEFAULT_TURN_RETRY_POLICY as U, TranscriptOptions as V, TurnRetryPolicy as W, AgentHarnessRuntime as _, createInProcessTransportPair as a, AgentMetadata as b, ConversationSummary as c, TranscriptPatch as d, AbortResult as f, AgentHarnessContext as g, AgentHarness as h, InProcessTransportPair as i, AgentToolContext as j, AgentSystemPromptContext as k, ServerFrame as l, AgentDisposeContext as m, AgentServerTransport as n, ClientFrame as o, AbortTarget as p, retryDelayMs as q, AgentTransport as r, ClientSessionEvent as s, AgentClientTransport as t, ShellCommandStatusLike as u, AgentHostContext as v, AgentSessionCloneParams as w, AgentPromptContext as x, AgentLifecycleEvent as y, DrainedTranscriptPatches as z };
@@ -1,4 +1,4 @@
1
- import { b as AgentMetadata, c as ConversationSummary, f as AbortResult, n as AgentServerTransport, s as ClientSessionEvent, t as AgentClientTransport } from "./transport-CfvLnrq0.mjs";
1
+ import { F as ModelSwitchApply, b as AgentMetadata, c as ConversationSummary, f as AbortResult, n as AgentServerTransport, s as ClientSessionEvent, t as AgentClientTransport } from "./transport-DtBCCS_A.mjs";
2
2
  import { ProviderSelection } from "@demicodes/provider";
3
3
  import { Block, UserContentBlock } from "@demicodes/core";
4
4
  //#region src/client.d.ts
@@ -35,10 +35,15 @@ declare class AgentClient {
35
35
  }): Promise<void>;
36
36
  cancelPendingSteer(steerId: string): void;
37
37
  /**
38
- * Switches the provider/model for an open session. The change takes effect on the next
39
- * turn (the server applies it at a turn boundary), so this is fire-and-forget.
38
+ * Switches the provider/model for an open session. Fire-and-forget: the server records
39
+ * the switch and applies it per `options.apply` 'next_turn' (default) waits for the
40
+ * next queued action, so a running turn finishes on the old model; 'immediate' applies
41
+ * at the next inference boundary, so mid-turn the very next sampling/tool continuation
42
+ * already runs on the new model.
40
43
  */
41
- setProvider(provider: ProviderSelection): void;
44
+ setProvider(provider: ProviderSelection, options?: {
45
+ apply?: ModelSwitchApply;
46
+ }): void;
42
47
  /**
43
48
  * Discards the whole latest turn and runs it again from the user's input —
44
49
  * "regenerate". NOT a recovery path: it drops text the turn already emitted and
@@ -156,13 +156,17 @@ var AgentClient = class {
156
156
  });
157
157
  }
158
158
  /**
159
- * Switches the provider/model for an open session. The change takes effect on the next
160
- * turn (the server applies it at a turn boundary), so this is fire-and-forget.
159
+ * Switches the provider/model for an open session. Fire-and-forget: the server records
160
+ * the switch and applies it per `options.apply` 'next_turn' (default) waits for the
161
+ * next queued action, so a running turn finishes on the old model; 'immediate' applies
162
+ * at the next inference boundary, so mid-turn the very next sampling/tool continuation
163
+ * already runs on the new model.
161
164
  */
162
- setProvider(provider) {
165
+ setProvider(provider, options = {}) {
163
166
  this.sendFrame({
164
167
  type: "set_provider",
165
- provider
168
+ provider,
169
+ apply: options.apply
166
170
  });
167
171
  }
168
172
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@demicodes/agent",
3
3
  "description": "Session runtime and transport-neutral client and server protocol for Demi.",
4
- "version": "0.16.0",
4
+ "version": "0.17.0",
5
5
  "private": false,
6
6
  "type": "module",
7
7
  "exports": {
@@ -19,10 +19,10 @@
19
19
  }
20
20
  },
21
21
  "dependencies": {
22
- "@demicodes/core": "^0.16.0",
23
- "@demicodes/provider": "^0.16.0",
24
- "@demicodes/shell": "^0.16.0",
25
- "@demicodes/utils": "^0.16.0"
22
+ "@demicodes/core": "^0.17.0",
23
+ "@demicodes/provider": "^0.17.0",
24
+ "@demicodes/shell": "^0.17.0",
25
+ "@demicodes/utils": "^0.17.0"
26
26
  },
27
27
  "license": "Apache-2.0",
28
28
  "main": "./dist/index.mjs",