@demicodes/agent 0.14.2 → 0.16.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-gkyOzXn-.mjs";
2
- import { a as AgentClient, i as AgentActionOptions, n as createWebSocketClientTransport, o as AgentClientListener, r as createWebSocketServerTransport, t as JsonWebSocket } from "./websocket-transport-C6bu3Ufc.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-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";
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 };
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-gkyOzXn-.mjs";
2
- import { a as AgentClient, i as AgentActionOptions, n as createWebSocketClientTransport, o as AgentClientListener, r as createWebSocketServerTransport, t as JsonWebSocket } from "./websocket-transport-C6bu3Ufc.mjs";
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";
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";
@@ -48,6 +48,7 @@ declare class AgentSession<State> {
48
48
  private readonly store?;
49
49
  private readonly compactionKeepRecentTokens;
50
50
  private readonly compactionThresholdRatio;
51
+ private readonly compactionThresholdTokens;
51
52
  private readonly listeners;
52
53
  private readonly pendingActions;
53
54
  private readonly queued;
@@ -231,6 +232,7 @@ interface AgentServerSessionOptions {
231
232
  compaction?: {
232
233
  keepRecentTokens?: number;
233
234
  preflightThresholdRatio?: number;
235
+ preflightThresholdTokens?: number;
234
236
  };
235
237
  persistIntervalMs?: number;
236
238
  }
@@ -352,7 +354,8 @@ declare function toShellToolResult(result: ShellCommandStatus, options?: ShellTo
352
354
  declare const SHELL_VIEW_MAX_CHARS = 32768;
353
355
  /**
354
356
  * Bounded UI view of a shell command stored on the tool_call block. Full
355
- * output lives in the command artifact (`/@/commands/<commandId>/…`), keyed by
357
+ * output lives in the command artifact directory (real files on the host
358
+ * filesystem, see `artifactDir`), keyed by
356
359
  * `commandId`; the view carries only the tail render window and never embeds
357
360
  * raw or base64 bytes.
358
361
  */
package/dist/index.mjs CHANGED
@@ -793,6 +793,20 @@ var PendingSteerQueue = class {
793
793
  function estimateTokens(text) {
794
794
  return Math.ceil(text.length / 4);
795
795
  }
796
+ /**
797
+ * Resolves the token count at which auto-compaction fires.
798
+ *
799
+ * - A non-finite `thresholdRatio` disables auto-compaction (used by summary clones).
800
+ * - When `thresholdTokens` is a finite number, it is used as an absolute threshold,
801
+ * clamped to `[0, contextWindow]`.
802
+ * - Otherwise the threshold is `floor(contextWindow * thresholdRatio)`.
803
+ */
804
+ function resolveCompactionThreshold(contextWindow, thresholdRatio, thresholdTokens) {
805
+ if (contextWindow <= 0) return 0;
806
+ if (!Number.isFinite(thresholdRatio)) return Number.POSITIVE_INFINITY;
807
+ if (thresholdTokens != null && Number.isFinite(thresholdTokens)) return Math.min(Math.max(0, Math.floor(thresholdTokens)), contextWindow);
808
+ return Math.floor(contextWindow * thresholdRatio);
809
+ }
796
810
  /** The next (smaller) cut point to retry compaction with, or null when nothing more can be compacted. */
797
811
  function nextSmallerCompactionCutPoint(startIndex, cutPoint) {
798
812
  const compactedBlockCount = cutPoint - startIndex;
@@ -825,7 +839,7 @@ var CompactionController = class {
825
839
  async compactToFit(targetModel) {
826
840
  const contextWindow = targetModel.model.contextWindow;
827
841
  if (contextWindow <= 0) return;
828
- const threshold = Math.floor(contextWindow * this.host.thresholdRatio);
842
+ const threshold = resolveCompactionThreshold(contextWindow, this.host.thresholdRatio, this.host.thresholdTokens);
829
843
  if (this.host.transcript.estimateContextTokens(contextWindow) < threshold) return;
830
844
  await this.host.runWithCompactingPhase(async () => {
831
845
  for (let attempt = 0; attempt < 8 && this.host.transcript.estimateContextTokens(contextWindow) >= threshold; attempt += 1) if (!await this.run()) break;
@@ -835,7 +849,7 @@ var CompactionController = class {
835
849
  async preflight() {
836
850
  const contextWindow = this.host.model.model.contextWindow;
837
851
  if (contextWindow <= 0) return;
838
- const threshold = Math.floor(contextWindow * this.host.thresholdRatio);
852
+ const threshold = resolveCompactionThreshold(contextWindow, this.host.thresholdRatio, this.host.thresholdTokens);
839
853
  if (this.host.transcript.estimateContextTokens(contextWindow) < threshold) return;
840
854
  await this.host.runWithCompactingPhase(() => this.run());
841
855
  }
@@ -1146,7 +1160,7 @@ var ProviderTurnLoop = class {
1146
1160
  isUsageNearLimit(usage) {
1147
1161
  const contextWindow = this.host.model.model.contextWindow;
1148
1162
  if (contextWindow <= 0) return false;
1149
- return usage.inputTokens + usage.outputTokens + usage.cacheReadTokens + usage.cacheWriteTokens >= Math.floor(contextWindow * this.host.thresholdRatio);
1163
+ return usage.inputTokens + usage.outputTokens + usage.cacheReadTokens + usage.cacheWriteTokens >= resolveCompactionThreshold(contextWindow, this.host.thresholdRatio, this.host.thresholdTokens);
1150
1164
  }
1151
1165
  };
1152
1166
  function toToolDefinition(tool) {
@@ -1172,6 +1186,7 @@ var AgentSession = class AgentSession {
1172
1186
  store;
1173
1187
  compactionKeepRecentTokens;
1174
1188
  compactionThresholdRatio;
1189
+ compactionThresholdTokens;
1175
1190
  listeners = /* @__PURE__ */ new Set();
1176
1191
  pendingActions = [];
1177
1192
  queued = [];
@@ -1237,6 +1252,7 @@ var AgentSession = class AgentSession {
1237
1252
  this.retryPolicy = resolveRetryPolicy(options.retry);
1238
1253
  this.compactionKeepRecentTokens = options.compaction?.keepRecentTokens ?? DEFAULT_KEEP_RECENT_TOKENS;
1239
1254
  this.compactionThresholdRatio = options.compaction?.preflightThresholdRatio ?? DEFAULT_PREFLIGHT_THRESHOLD_RATIO;
1255
+ this.compactionThresholdTokens = options.compaction?.preflightThresholdTokens === void 0 ? null : options.compaction.preflightThresholdTokens;
1240
1256
  const transcriptOptions = {
1241
1257
  idFactory: this.idFactory,
1242
1258
  now: options.now
@@ -1256,6 +1272,9 @@ var AgentSession = class AgentSession {
1256
1272
  get thresholdRatio() {
1257
1273
  return self.compactionThresholdRatio;
1258
1274
  },
1275
+ get thresholdTokens() {
1276
+ return self.compactionThresholdTokens;
1277
+ },
1259
1278
  currentSignal: () => self.currentSignal(),
1260
1279
  clone: (transcript) => self.clone({
1261
1280
  transcript,
@@ -1294,6 +1313,9 @@ var AgentSession = class AgentSession {
1294
1313
  get thresholdRatio() {
1295
1314
  return self.compactionThresholdRatio;
1296
1315
  },
1316
+ get thresholdTokens() {
1317
+ return self.compactionThresholdTokens;
1318
+ },
1297
1319
  get steerContinuationCount() {
1298
1320
  return self.steerQueue.continuationCount;
1299
1321
  },
@@ -2350,7 +2372,7 @@ function toShellToolResult(result, options = {}) {
2350
2372
  text: formatShellToolResult(result, options)
2351
2373
  }];
2352
2374
  if (result.status === "exited" && result.binaryStdout) {
2353
- const verdict = binaryStreamVerdict(result.binaryStdout, result.commandId, options.model, {
2375
+ const verdict = binaryStreamVerdict(result.binaryStdout, `${result.artifactDir}/stdout.bin`, options.model, {
2354
2376
  ...DEFAULT_MAX_MEDIA_BYTES,
2355
2377
  ...options.maxMediaBytes
2356
2378
  });
@@ -2425,9 +2447,8 @@ function tailChunkWindow(chunks, maxChars) {
2425
2447
  * magic matches the closed model-media set, the model accepts the type, and
2426
2448
  * the stream was not truncated; otherwise explain why nothing was attached.
2427
2449
  */
2428
- function binaryStreamVerdict(binary, commandId, model, maxMediaBytes) {
2450
+ function binaryStreamVerdict(binary, binPath, model, maxMediaBytes) {
2429
2451
  const media = sniffModelMediaType(binary.data);
2430
- const binPath = `/@/commands/${commandId}/stdout.bin`;
2431
2452
  if (binary.truncated) return { note: `Binary stdout (${binary.totalBytes} bytes${media ? `, ${media.mediaType}` : ""}) exceeded the shell's ${binary.limitBytes}-byte binary limit (maxBinaryBytes) and was not attached; the raw bytes remain readable at ${binPath}. Produce a smaller version and re-run.` };
2432
2453
  if (!media) return { note: `Binary stdout does not match any model-viewable media type; the raw bytes remain readable at ${binPath}.` };
2433
2454
  if (!model || !modelAcceptsMediaType(model, media.mediaType)) return { note: `Binary stdout is ${media.mediaType}, which this model does not accept natively; the raw bytes remain readable at ${binPath}.` };
@@ -2525,7 +2546,7 @@ function formatShellToolResult(result, options) {
2525
2546
  lines.push(`idleMs: ${result.idleMs}`);
2526
2547
  appendArtifact(lines, "stdout", result.stdout);
2527
2548
  appendArtifact(lines, "stderr", result.stderr);
2528
- lines.push(`metaPath: /@/commands/${result.commandId}/meta.json`);
2549
+ lines.push(`metaPath: ${result.artifactDir}/meta.json`);
2529
2550
  }
2530
2551
  if (options.includePreview) appendPreview(lines, result, options.previewBudgetTokens ?? SMALL_CONTEXT_PREVIEW_TOKENS);
2531
2552
  if (result.status === "running") lines.push("next: command is still running; check again with shell_status, or call yield to end this turn and be woken later, or shell_abort to stop it.");
@@ -2546,7 +2567,7 @@ function appendPreview(lines, result, budgetTokens) {
2546
2567
  }
2547
2568
  lines.push("preview:");
2548
2569
  lines.push(preview.text);
2549
- if (preview.truncated || result.output.truncated) lines.push(`previewTruncated: true; read /@/commands/${result.commandId}/stdout.txt or /@/commands/${result.commandId}/stderr.txt for more.`);
2570
+ if (preview.truncated || result.output.truncated) lines.push(`previewTruncated: true; read ${result.artifactDir}/stdout.txt or ${result.artifactDir}/stderr.txt for more.`);
2550
2571
  }
2551
2572
  function boundedPreview(text, budgetTokens) {
2552
2573
  const maxChars = Math.max(0, Math.floor(budgetTokens * APPROX_CHARS_PER_TOKEN));
@@ -1,4 +1,4 @@
1
- import { n as AgentServerTransport, t as AgentClientTransport } from "./transport-gkyOzXn-.mjs";
1
+ import { n as AgentServerTransport, t as AgentClientTransport } from "./transport-CfvLnrq0.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;
@@ -308,6 +308,12 @@ interface AgentSessionOptions<State = unknown> {
308
308
  compaction?: {
309
309
  keepRecentTokens?: number;
310
310
  preflightThresholdRatio?: number;
311
+ /**
312
+ * Absolute token threshold for auto-compaction. When set, replaces the
313
+ * ratio-derived threshold (still clamped to the model context window).
314
+ * A non-finite `preflightThresholdRatio` still disables auto-compaction.
315
+ */
316
+ preflightThresholdTokens?: number;
311
317
  };
312
318
  /**
313
319
  * Maximum interval between checkpoint writes while a turn is streaming. Writes
@@ -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-gkyOzXn-.mjs";
1
+ import { b as AgentMetadata, c as ConversationSummary, f as AbortResult, n as AgentServerTransport, s as ClientSessionEvent, t as AgentClientTransport } from "./transport-CfvLnrq0.mjs";
2
2
  import { ProviderSelection } from "@demicodes/provider";
3
3
  import { Block, UserContentBlock } from "@demicodes/core";
4
4
  //#region src/client.d.ts
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.14.2",
4
+ "version": "0.16.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.14.2",
23
- "@demicodes/provider": "^0.14.2",
24
- "@demicodes/shell": "^0.14.2",
25
- "@demicodes/utils": "^0.14.2"
22
+ "@demicodes/core": "^0.16.0",
23
+ "@demicodes/provider": "^0.16.0",
24
+ "@demicodes/shell": "^0.16.0",
25
+ "@demicodes/utils": "^0.16.0"
26
26
  },
27
27
  "license": "Apache-2.0",
28
28
  "main": "./dist/index.mjs",