@ponythewhite/base-context 1.0.10 → 1.0.12

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.
Files changed (125) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/base-context-runtime/pyproject.toml +1 -1
  3. package/dist/base-context-runtime/uv.lock +1 -1
  4. package/dist/build-info.json +1 -1
  5. package/dist/bundle/amazon-bedrock.js +3 -3
  6. package/dist/bundle/{anthropic-5PSCZEER.js → anthropic-BJVPUMPB.js} +2 -2
  7. package/dist/bundle/{azure-openai-responses-AYTLJR33.js → azure-openai-responses-ERRMAXK6.js} +4 -5
  8. package/dist/bundle/{bundled-modules-MX6YNAM2.js → bundled-modules-WCGPZI2H.js} +5 -5
  9. package/dist/bundle/{chunk-D3KOF57W.js → chunk-25VYRAC6.js} +14 -1
  10. package/dist/bundle/{chunk-2IPDSTDR.js → chunk-AEMRBMI2.js} +9 -9
  11. package/dist/bundle/{chunk-Q3MBSBEB.js → chunk-FOGKLC7V.js} +1 -1
  12. package/dist/bundle/{chunk-UHLGPYMI.js → chunk-IAKHCQA2.js} +185 -39
  13. package/dist/bundle/{chunk-KT2BNEPE.js → chunk-MUFZODP5.js} +1 -1
  14. package/dist/bundle/{chunk-QKIFBA7N.js → chunk-Q6UAHLII.js} +2 -2
  15. package/dist/bundle/{chunk-CDXQNS5P.js → chunk-YGV3Y4AD.js} +1009 -185
  16. package/dist/bundle/{cli-main-D7W3WWCV.js → cli-main-CTYDQHFE.js} +4 -4
  17. package/dist/bundle/cli.js +1 -1
  18. package/dist/bundle/{google-HTMCUJ7X.js → google-4GA4YMUX.js} +2 -2
  19. package/dist/bundle/{google-vertex-ZQO65AXF.js → google-vertex-7AMALD7D.js} +2 -2
  20. package/dist/bundle/{main-5J3QBZ5Y.js → main-GVGK354K.js} +5 -5
  21. package/dist/bundle/{mistral-SB7LU56G.js → mistral-74BXMNRM.js} +1 -1
  22. package/dist/bundle/{openai-codex-responses-5CEW4VN3.js → openai-codex-responses-COXNC4IH.js} +2 -2
  23. package/dist/bundle/{openai-completions-BAZJQSS2.js → openai-completions-BCSA5Q6S.js} +2 -2
  24. package/dist/bundle/{openai-responses-VHOE427P.js → openai-responses-ONCIZSJS.js} +3 -3
  25. package/dist/core/agent-session.d.ts +6 -1
  26. package/dist/core/agent-session.d.ts.map +1 -1
  27. package/dist/core/agent-session.js +445 -146
  28. package/dist/core/agent-session.js.map +1 -1
  29. package/dist/core/canonical-context.d.ts +19 -3
  30. package/dist/core/canonical-context.d.ts.map +1 -1
  31. package/dist/core/canonical-context.js +130 -9
  32. package/dist/core/canonical-context.js.map +1 -1
  33. package/dist/core/compaction/compaction.d.ts +9 -1
  34. package/dist/core/compaction/compaction.d.ts.map +1 -1
  35. package/dist/core/compaction/compaction.js +29 -3
  36. package/dist/core/compaction/compaction.js.map +1 -1
  37. package/dist/core/context-epoch-copy.d.ts +1 -1
  38. package/dist/core/context-epoch-copy.d.ts.map +1 -1
  39. package/dist/core/context-epoch-copy.js +18 -7
  40. package/dist/core/context-epoch-copy.js.map +1 -1
  41. package/dist/core/context-epoch.d.ts +4 -0
  42. package/dist/core/context-epoch.d.ts.map +1 -1
  43. package/dist/core/context-epoch.js +8 -1
  44. package/dist/core/context-epoch.js.map +1 -1
  45. package/dist/core/context-tree.d.ts +14 -11
  46. package/dist/core/context-tree.d.ts.map +1 -1
  47. package/dist/core/context-tree.js +145 -9
  48. package/dist/core/context-tree.js.map +1 -1
  49. package/dist/core/history-index-worker.d.ts.map +1 -1
  50. package/dist/core/history-index-worker.js +59 -6
  51. package/dist/core/history-index-worker.js.map +1 -1
  52. package/dist/core/history-index.d.ts +17 -0
  53. package/dist/core/history-index.d.ts.map +1 -1
  54. package/dist/core/history-index.js +22 -0
  55. package/dist/core/history-index.js.map +1 -1
  56. package/dist/core/inference-coordinator.d.ts +1 -1
  57. package/dist/core/inference-coordinator.d.ts.map +1 -1
  58. package/dist/core/inference-coordinator.js +23 -6
  59. package/dist/core/inference-coordinator.js.map +1 -1
  60. package/dist/core/messages.d.ts +2 -0
  61. package/dist/core/messages.d.ts.map +1 -1
  62. package/dist/core/messages.js +2 -0
  63. package/dist/core/messages.js.map +1 -1
  64. package/dist/core/refinement/refinement.d.ts +2 -0
  65. package/dist/core/refinement/refinement.d.ts.map +1 -1
  66. package/dist/core/refinement/refinement.js +10 -1
  67. package/dist/core/refinement/refinement.js.map +1 -1
  68. package/dist/core/request-usage.d.ts +34 -0
  69. package/dist/core/request-usage.d.ts.map +1 -0
  70. package/dist/core/request-usage.js +111 -0
  71. package/dist/core/request-usage.js.map +1 -0
  72. package/dist/core/request-view-selection.d.ts +2 -1
  73. package/dist/core/request-view-selection.d.ts.map +1 -1
  74. package/dist/core/request-view-selection.js +29 -2
  75. package/dist/core/request-view-selection.js.map +1 -1
  76. package/dist/core/session-fork-messages.d.ts +5 -0
  77. package/dist/core/session-fork-messages.d.ts.map +1 -1
  78. package/dist/core/session-fork-messages.js +44 -0
  79. package/dist/core/session-fork-messages.js.map +1 -1
  80. package/dist/core/session-history-index.d.ts +5 -0
  81. package/dist/core/session-history-index.d.ts.map +1 -1
  82. package/dist/core/session-history-index.js +7 -0
  83. package/dist/core/session-history-index.js.map +1 -1
  84. package/dist/core/session-manager.d.ts +2 -0
  85. package/dist/core/session-manager.d.ts.map +1 -1
  86. package/dist/core/session-manager.js +155 -13
  87. package/dist/core/session-manager.js.map +1 -1
  88. package/dist/core/session-tree.d.ts +9 -0
  89. package/dist/core/session-tree.d.ts.map +1 -1
  90. package/dist/core/session-tree.js +71 -11
  91. package/dist/core/session-tree.js.map +1 -1
  92. package/dist/core/settings-manager.d.ts +3 -0
  93. package/dist/core/settings-manager.d.ts.map +1 -1
  94. package/dist/core/settings-manager.js +7 -0
  95. package/dist/core/settings-manager.js.map +1 -1
  96. package/dist/core/system-prompt.d.ts +2 -0
  97. package/dist/core/system-prompt.d.ts.map +1 -1
  98. package/dist/core/system-prompt.js +4 -2
  99. package/dist/core/system-prompt.js.map +1 -1
  100. package/dist/modes/agent-connection/daemon-agent-connection.d.ts.map +1 -1
  101. package/dist/modes/agent-connection/daemon-agent-connection.js +8 -1
  102. package/dist/modes/agent-connection/daemon-agent-connection.js.map +1 -1
  103. package/dist/modes/agent-connection/in-process-agent-connection.d.ts.map +1 -1
  104. package/dist/modes/agent-connection/in-process-agent-connection.js +4 -4
  105. package/dist/modes/agent-connection/in-process-agent-connection.js.map +1 -1
  106. package/dist/modes/daemon/daemon-mode.d.ts.map +1 -1
  107. package/dist/modes/daemon/daemon-mode.js +4 -4
  108. package/dist/modes/daemon/daemon-mode.js.map +1 -1
  109. package/dist/modes/daemon/daemon-protocol.d.ts +13 -3
  110. package/dist/modes/daemon/daemon-protocol.d.ts.map +1 -1
  111. package/dist/modes/daemon/daemon-protocol.js +10 -2
  112. package/dist/modes/daemon/daemon-protocol.js.map +1 -1
  113. package/dist/modes/daemon/daemon-session-summarizer.d.ts +3 -0
  114. package/dist/modes/daemon/daemon-session-summarizer.d.ts.map +1 -1
  115. package/dist/modes/daemon/daemon-session-summarizer.js +71 -32
  116. package/dist/modes/daemon/daemon-session-summarizer.js.map +1 -1
  117. package/dist/modes/interactive/components/context-tree-format.d.ts.map +1 -1
  118. package/dist/modes/interactive/components/context-tree-format.js +49 -0
  119. package/dist/modes/interactive/components/context-tree-format.js.map +1 -1
  120. package/docs/compaction.md +27 -3
  121. package/docs/context-management.md +17 -1
  122. package/docs/rlm.md +1 -1
  123. package/docs/settings.md +12 -0
  124. package/docs/usage.md +24 -1
  125. package/package.json +4 -4
@@ -116,6 +116,7 @@ import {
116
116
  acquireDaemonSocketPathLease,
117
117
  acquireSessionLease,
118
118
  addAssistantUsage,
119
+ addRequestUsageTotals,
119
120
  agentFamilyRelationship,
120
121
  assertAgentFamilyReach,
121
122
  assertAgentSessionNameAvailable,
@@ -173,6 +174,7 @@ import {
173
174
  durableDaemonWorkerDescriptor,
174
175
  emitSessionShutdownEvent,
175
176
  emptyGoalState,
177
+ emptyRequestUsageTotals,
176
178
  emptyUsage,
177
179
  encodeJournalFrame,
178
180
  encodeJournalFrameJson,
@@ -296,7 +298,7 @@ import {
296
298
  readSessionBootstrap,
297
299
  readSessionInfo,
298
300
  readSessionJournalHeader,
299
- readUserMessagesForForking,
301
+ readVisibleUserMessagesForForking,
300
302
  renderDiff,
301
303
  renderDiffSeparator,
302
304
  renderRichDiff,
@@ -349,7 +351,7 @@ import {
349
351
  watchWithErrorHandler,
350
352
  workerRosterEntryFromSummary,
351
353
  wrapTextWithAnsi
352
- } from "./chunk-CDXQNS5P.js";
354
+ } from "./chunk-YGV3Y4AD.js";
353
355
  import {
354
356
  array,
355
357
  boolean,
@@ -368,7 +370,7 @@ import {
368
370
  import {
369
371
  installFileLogSink,
370
372
  setLogContext
371
- } from "./chunk-QKIFBA7N.js";
373
+ } from "./chunk-Q6UAHLII.js";
372
374
  import {
373
375
  APP_NAME,
374
376
  APP_TITLE,
@@ -414,7 +416,7 @@ import {
414
416
  shouldUseWindowsShell,
415
417
  signalProcessGroupOrProcess,
416
418
  typebox_exports
417
- } from "./chunk-2IPDSTDR.js";
419
+ } from "./chunk-AEMRBMI2.js";
418
420
  import {
419
421
  PRODUCT,
420
422
  PRODUCT_ENV
@@ -436,7 +438,7 @@ import {
436
438
  getProviders,
437
439
  modelsAreEqual,
438
440
  supportsFastMode
439
- } from "./chunk-D3KOF57W.js";
441
+ } from "./chunk-25VYRAC6.js";
440
442
  import {
441
443
  __commonJS,
442
444
  __export,
@@ -6360,10 +6362,15 @@ var SettingsManager = class _SettingsManager {
6360
6362
  return model === void 0 ? void 0 : structuredClone(model);
6361
6363
  }
6362
6364
  getCompactionSettings() {
6365
+ const targetTokens = this.settings.compaction?.targetTokens;
6366
+ if (targetTokens !== void 0 && targetTokens !== "model-limit" && (!Number.isSafeInteger(targetTokens) || targetTokens <= 0)) {
6367
+ throw new Error('compaction.targetTokens must be a positive safe integer or "model-limit"');
6368
+ }
6363
6369
  return {
6364
6370
  enabled: this.getCompactionEnabled(),
6365
6371
  reserveTokens: this.getCompactionReserveTokens(),
6366
- keepRecentTokens: this.getCompactionKeepRecentTokens()
6372
+ keepRecentTokens: this.getCompactionKeepRecentTokens(),
6373
+ ...targetTokens === void 0 ? {} : { targetTokens }
6367
6374
  };
6368
6375
  }
6369
6376
  /** Detached explicit configuration; the request path resolves and validates its model/effort. */
@@ -31875,6 +31882,67 @@ function buildSessionTreeFromFlatNodes(flatNodes) {
31875
31882
  }
31876
31883
  return roots;
31877
31884
  }
31885
+ function applyTreeUsageOverlays(entries2) {
31886
+ const assistants = new Map(entries2.filter((entry) => entry.type === "message" && entry.message.role === "assistant").map((entry) => [entry.id, entry]));
31887
+ for (const entry of entries2) {
31888
+ if (entry.type !== "child_usage_attributed")
31889
+ continue;
31890
+ const target = assistants.get(entry.targetId);
31891
+ if (target?.type === "message" && target.message.role === "assistant")
31892
+ target.message.usage = cloneUsage(entry.aggregateUsage);
31893
+ }
31894
+ }
31895
+ async function readVisibleSessionTreeFlatNodes(manager, limits = DEFAULT_SESSION_TREE_LIMITS) {
31896
+ const { maxEntries, maxSourceBytes } = limits;
31897
+ if (!Number.isSafeInteger(maxEntries) || maxEntries <= 0 || !Number.isSafeInteger(maxSourceBytes) || maxSourceBytes <= 0)
31898
+ throw new Error("Invalid history materialization limits");
31899
+ if (!manager.supportsCapturedHistoryReads())
31900
+ return readSessionTreeFlatNodes(manager, { maxEntries, maxSourceBytes });
31901
+ return manager.readSourceHistory(async (history) => {
31902
+ const entries2 = [];
31903
+ const visibleIds = /* @__PURE__ */ new Set();
31904
+ let sourceBytes = 0;
31905
+ let after = 0;
31906
+ for (; ; ) {
31907
+ const page = await history.page(after);
31908
+ if (page.indexedThrough < history.source.sourceSequence)
31909
+ throw new Error("Captured history has incomplete index coverage");
31910
+ for (const ref of page.events) {
31911
+ if (ref.kind === "request" || ref.kind === "tool_intent")
31912
+ continue;
31913
+ if (entries2.length >= maxEntries)
31914
+ throw new Error("History entry budget exceeded");
31915
+ if (sourceBytes + ref.locator.length > maxSourceBytes)
31916
+ throw new Error("History source byte budget exceeded");
31917
+ const hydrated = await history.hydrateEntry(ref.id, maxSourceBytes - sourceBytes);
31918
+ if (!hydrated)
31919
+ throw new Error("Session tree entry source is unavailable");
31920
+ sourceBytes += ref.locator.length;
31921
+ let parentId = ref.parentId;
31922
+ while (parentId !== null && !visibleIds.has(parentId)) {
31923
+ const parent = await history.get(parentId);
31924
+ if (!parent || parent.kind !== "request" && parent.kind !== "tool_intent")
31925
+ break;
31926
+ parentId = parent.parentId;
31927
+ }
31928
+ hydrated.entry.parentId = parentId;
31929
+ entries2.push(hydrated.entry);
31930
+ visibleIds.add(ref.id);
31931
+ }
31932
+ if (page.nextAfter === null)
31933
+ break;
31934
+ after = page.nextAfter;
31935
+ }
31936
+ applyTreeUsageOverlays(entries2);
31937
+ const result = { flatNodes: buildSessionTreeFlatNodes(entries2), leafId: history.source.leafId };
31938
+ stringifyBoundedJson(result, maxSourceBytes);
31939
+ return result;
31940
+ });
31941
+ }
31942
+ async function readVisibleSessionTree(manager, limits = DEFAULT_SESSION_TREE_LIMITS) {
31943
+ const { flatNodes, leafId } = await readVisibleSessionTreeFlatNodes(manager, limits);
31944
+ return { tree: buildSessionTreeFromFlatNodes(flatNodes), leafId };
31945
+ }
31878
31946
  async function readSessionTreeFlatNodes(manager, limits = DEFAULT_SESSION_TREE_LIMITS) {
31879
31947
  const capturedLimits = { ...limits };
31880
31948
  let entries2;
@@ -31883,14 +31951,7 @@ async function readSessionTreeFlatNodes(manager, limits = DEFAULT_SESSION_TREE_L
31883
31951
  const history = await manager.materializeSourceHistory(capturedLimits);
31884
31952
  entries2 = history.entries.map(({ entry }) => entry);
31885
31953
  leafId = history.source.leafId;
31886
- const assistants = new Map(entries2.filter((entry) => entry.type === "message" && entry.message.role === "assistant").map((entry) => [entry.id, entry]));
31887
- for (const entry of entries2) {
31888
- if (entry.type !== "child_usage_attributed")
31889
- continue;
31890
- const target = assistants.get(entry.targetId);
31891
- if (target?.type === "message" && target.message.role === "assistant")
31892
- target.message.usage = cloneUsage(entry.aggregateUsage);
31893
- }
31954
+ applyTreeUsageOverlays(entries2);
31894
31955
  } else {
31895
31956
  const history = manager.materializeResidentHistory(capturedLimits);
31896
31957
  entries2 = history.entries;
@@ -31898,10 +31959,6 @@ async function readSessionTreeFlatNodes(manager, limits = DEFAULT_SESSION_TREE_L
31898
31959
  }
31899
31960
  return { flatNodes: buildSessionTreeFlatNodes(entries2), leafId };
31900
31961
  }
31901
- async function readSessionTree(manager, limits = DEFAULT_SESSION_TREE_LIMITS) {
31902
- const { flatNodes, leafId } = await readSessionTreeFlatNodes(manager, limits);
31903
- return { tree: buildSessionTreeFromFlatNodes(flatNodes), leafId };
31904
- }
31905
31962
 
31906
31963
  // dist/core/side-question.js
31907
31964
  var SIDE_QUESTION_INSTRUCTION = "Answer this side question using only the conversation context above. Do not use tools. The user may send follow-up side questions; none of this side conversation is added to the main session.";
@@ -32405,7 +32462,7 @@ var InProcessAgentConnection = class {
32405
32462
  return this.session.buildSessionContext();
32406
32463
  }
32407
32464
  async getSessionTree() {
32408
- return readSessionTree(this.session.sessionManager);
32465
+ return readVisibleSessionTree(this.session.sessionManager);
32409
32466
  }
32410
32467
  async listSavedSessions(scope, callbacks) {
32411
32468
  const sessionDir = this.session.sessionManager.getSessionDir() || void 0;
@@ -32490,7 +32547,7 @@ var InProcessAgentConnection = class {
32490
32547
  throw new Error("Agent messaging requires daemon mode");
32491
32548
  }
32492
32549
  async getUserMessagesForForking() {
32493
- return readUserMessagesForForking(this.session.sessionManager);
32550
+ return readVisibleUserMessagesForForking(this.session.sessionManager);
32494
32551
  }
32495
32552
  async getLastAssistantText() {
32496
32553
  return this.session.getLastAssistantText();
@@ -34559,10 +34616,17 @@ var DaemonAgentConnection = class _DaemonAgentConnection {
34559
34616
  });
34560
34617
  }
34561
34618
  async getContextTree() {
34562
- return this.requestData({
34619
+ const tree = await this.requestData({
34563
34620
  type: "get_context_tree",
34564
34621
  activeSessionId: this.activeSessionId
34565
34622
  });
34623
+ if (this.client.supportsServerCapability("context_request_usage"))
34624
+ return tree;
34625
+ const legacy = (node) => {
34626
+ const { ownRequestUsage: _ignored, ...rest } = node;
34627
+ return { ...rest, children: node.children.map(legacy) };
34628
+ };
34629
+ return legacy(tree);
34566
34630
  }
34567
34631
  async getSessionContext() {
34568
34632
  if (this.latestSnapshotIsFresh && this.latestSnapshot?.sessionContext) {
@@ -40763,8 +40827,50 @@ function sumOwnUsage(root) {
40763
40827
  walk(root);
40764
40828
  return total;
40765
40829
  }
40830
+ var GOAL_SCOPE = "Goal budget: root successful main uncached input + output only; excludes cache, children and auxiliary requests";
40831
+ function formatReceiptContextTree(root, width) {
40832
+ const rows = flattenContextTree(root);
40833
+ const total = emptyRequestUsageTotals();
40834
+ const seen = /* @__PURE__ */ new Set();
40835
+ let missingNodes = 0;
40836
+ const lines = [theme.bold("Context"), "", "Generation receipts: captured sources, known usage only", ""];
40837
+ for (const { node, prefix } of rows) {
40838
+ const usage = node.ownRequestUsage;
40839
+ const label = truncateToWidth(`${prefix}${node.label}`, Math.max(16, width - 45), "...");
40840
+ if (!usage) {
40841
+ missingNodes++;
40842
+ lines.push(`${statusIcon(node.status)} ${label}: request usage unknown`);
40843
+ } else if (seen.has(usage.sessionId)) {
40844
+ lines.push(`${statusIcon(node.status)} ${label}: shared source (counted once)`);
40845
+ } else {
40846
+ seen.add(usage.sessionId);
40847
+ addRequestUsageTotals(total, usage.total);
40848
+ lines.push(`${statusIcon(node.status)} ${label}: ${formatTokenCount2(usage.total.processedTokens)} tokens \xB7 ${formatCost(usage.total.catalogEstimateUsd)} est.`);
40849
+ for (const [purpose, bucket] of Object.entries(usage.byPurpose)) {
40850
+ lines.push(` ${purpose}: ${bucket.processedTokens.toLocaleString()} tokens \xB7 $${bucket.catalogEstimateUsd.toFixed(4)} est. \xB7 ${bucket.settledAttempts} settled`);
40851
+ }
40852
+ }
40853
+ if (node.contextUsage)
40854
+ lines.push(` Context: ${formatContextColumn(node.contextUsage, node.id === "root")}`);
40855
+ }
40856
+ lines.push("", theme.bold("Captured family \u2014 known generation usage"));
40857
+ lines.push(`Sessions with receipts: ${seen.size}; request usage unavailable: ${missingNodes}`);
40858
+ lines.push(`Uncached input: ${total.input.toLocaleString()}`);
40859
+ lines.push(`Input total (including cache): ${total.inputTotal.toLocaleString()}`);
40860
+ lines.push(`Cache read: ${total.cacheRead.toLocaleString()}; cache write: ${total.cacheWrite.toLocaleString()}`);
40861
+ lines.push(`Output: ${total.output.toLocaleString()}`);
40862
+ lines.push(`Processed total: ${total.processedTokens.toLocaleString()}`);
40863
+ lines.push(`Catalog estimate (unvalidated rates, not an invoice): $${total.catalogEstimateUsd.toFixed(4)}`);
40864
+ lines.push(`Unknown usage: ${total.missingUsageAttempts} missing, ${total.partialUsageAttempts} partial, ${total.unsettledAttempts} unsettled attempts; ${total.unpricedAttempts} settled attempts unpriced`);
40865
+ lines.push("Missing fields are not zero. Totals exclude unavailable sessions and non-generation token-count requests.");
40866
+ lines.push("Captured sources are not a guarantee of complete historical family usage.");
40867
+ lines.push("", GOAL_SCOPE);
40868
+ return lines.join("\n");
40869
+ }
40766
40870
  function formatContextTree(root, width) {
40767
40871
  const rows = flattenContextTree(root);
40872
+ if (rows.some(({ node }) => node.ownRequestUsage))
40873
+ return formatReceiptContextTree(root, width);
40768
40874
  const tokenCells = rows.map((row) => formatTokenCount2(spentTokens(row.node.ownUsage)));
40769
40875
  const costCells = rows.map((row) => formatCost(row.node.ownUsage.cost.total));
40770
40876
  const tokenHeader = "tokens";
@@ -40776,6 +40882,9 @@ function formatContextTree(root, width) {
40776
40882
  const lines = [];
40777
40883
  lines.push(theme.bold("Context"));
40778
40884
  lines.push("");
40885
+ lines.push("Legacy conversation projection \u2014 request receipts unavailable; auxiliary usage may be missing");
40886
+ lines.push("Costs below are catalog estimates, not invoices");
40887
+ lines.push("");
40779
40888
  if (root.model) {
40780
40889
  lines.push(`${theme.fg("dim", "Model:")} ${root.model.provider}/${root.model.id}`);
40781
40890
  lines.push("");
@@ -40821,6 +40930,7 @@ function formatContextTree(root, width) {
40821
40930
  lines.push(`${theme.fg("dim", "Current:")} ${rootContext.tokens.toLocaleString()} / ${rootContext.contextWindow.toLocaleString()} (${percent})`);
40822
40931
  }
40823
40932
  }
40933
+ lines.push("", GOAL_SCOPE);
40824
40934
  return lines.join("\n");
40825
40935
  }
40826
40936
 
@@ -59587,6 +59697,7 @@ var DaemonRlmCapacityClient = class {
59587
59697
  // dist/modes/daemon/daemon-session-summarizer.js
59588
59698
  var SWEEP_INTERVAL_MS = 25e3;
59589
59699
  var SETTLE_DEBOUNCE_MS = 2e3;
59700
+ var MIN_REFRESH_INTERVAL_MS = 6e4;
59590
59701
  var SUMMARY_CONTEXT_MESSAGES = 8;
59591
59702
  var SUMMARY_MAX_CHARS_PER_MESSAGE = 600;
59592
59703
  var SUMMARY_MAX_TOKENS = 400;
@@ -59620,7 +59731,7 @@ function messageText(content) {
59620
59731
  const type = block.type;
59621
59732
  if (type === "text" && typeof block.text === "string") {
59622
59733
  parts.push(block.text);
59623
- } else if (type === "tool_use" || type === "toolUse") {
59734
+ } else if (type === "toolCall" || type === "tool_use" || type === "toolUse") {
59624
59735
  const name = block.name;
59625
59736
  if (typeof name === "string") {
59626
59737
  tools.push(name);
@@ -59684,7 +59795,7 @@ function parseAgentStatusResponse(text, isWorking) {
59684
59795
  return { summary, taskState };
59685
59796
  }
59686
59797
  async function generateAgentStatus(params) {
59687
- const { registry, messages, isWorking, signal, requests, model: selectedModel } = params;
59798
+ const { registry, messages, isWorking, sessionId, signal, requests, model: selectedModel } = params;
59688
59799
  if (messages.length === 0) {
59689
59800
  return void 0;
59690
59801
  }
@@ -59708,7 +59819,13 @@ async function generateAgentStatus(params) {
59708
59819
  timestamp
59709
59820
  }
59710
59821
  ]
59711
- }, { maxTokens: SUMMARY_MAX_TOKENS, apiKey: auth.apiKey, headers: auth.headers, signal }, { purpose: "native-control", purposeDetail: "daemon-status" });
59822
+ }, {
59823
+ maxTokens: SUMMARY_MAX_TOKENS,
59824
+ apiKey: auth.apiKey,
59825
+ headers: auth.headers,
59826
+ signal,
59827
+ sessionId: sessionId ? `daemon-status:${sessionId}` : void 0
59828
+ }, { purpose: "native-control", purposeDetail: "daemon-status" });
59712
59829
  if (response.stopReason === "error") {
59713
59830
  return void 0;
59714
59831
  }
@@ -59744,6 +59861,7 @@ var DaemonSessionSummarizer = class {
59744
59861
  debounceTimers = /* @__PURE__ */ new Map();
59745
59862
  // Controller per in-flight summary so a closing session can abort its write.
59746
59863
  inFlight = /* @__PURE__ */ new Map();
59864
+ refreshes = /* @__PURE__ */ new Map();
59747
59865
  tasks = /* @__PURE__ */ new Map();
59748
59866
  forgotten = /* @__PURE__ */ new Set();
59749
59867
  stopped = false;
@@ -59793,6 +59911,7 @@ var DaemonSessionSummarizer = class {
59793
59911
  this.debounceTimers.delete(activeSessionId);
59794
59912
  }
59795
59913
  this.inFlight.get(activeSessionId)?.abort();
59914
+ this.refreshes.delete(activeSessionId);
59796
59915
  this.rerunRequested.delete(activeSessionId);
59797
59916
  await this.tasks.get(activeSessionId);
59798
59917
  }
@@ -59809,6 +59928,9 @@ var DaemonSessionSummarizer = class {
59809
59928
  }
59810
59929
  /** Called when a session finishes a turn; debounce until the agent settles. */
59811
59930
  notifyActivity(state) {
59931
+ this.schedule(state, SETTLE_DEBOUNCE_MS);
59932
+ }
59933
+ schedule(state, delay8) {
59812
59934
  const id = state.activeSessionId;
59813
59935
  if (this.stopped || this.forgotten.has(id))
59814
59936
  return;
@@ -59819,7 +59941,7 @@ var DaemonSessionSummarizer = class {
59819
59941
  const timer = setTimeout(() => {
59820
59942
  this.debounceTimers.delete(id);
59821
59943
  this.summarize(state);
59822
- }, SETTLE_DEBOUNCE_MS);
59944
+ }, delay8);
59823
59945
  timer.unref?.();
59824
59946
  this.debounceTimers.set(id, timer);
59825
59947
  }
@@ -59853,33 +59975,54 @@ var DaemonSessionSummarizer = class {
59853
59975
  const messageCount = messages.length;
59854
59976
  const isWorking = isSessionWorking(state);
59855
59977
  const previous = state.summaryState;
59856
- const contentUnchanged = previous?.basedOnMessageCount === messageCount;
59857
59978
  const owesIdleVerdict = !isWorking && previous?.taskState === void 0;
59858
59979
  const owesSummary = !isWorking && !previous?.summary;
59859
59980
  const turnError = !isWorking ? terminalTurnError(messages) : void 0;
59860
- const owesErrorVerdict = turnError !== void 0 && (previous?.taskState !== "needs_input" || previous?.summary !== turnError);
59861
- if (contentUnchanged && !isWorking && !owesIdleVerdict && !owesSummary && !owesErrorVerdict) {
59862
- return;
59981
+ const contextMessages = () => {
59982
+ const streaming = isWorking ? session.state.streamingMessage : void 0;
59983
+ return streaming ? [...session.messages, streaming] : session.messages;
59984
+ };
59985
+ const input = buildStatusContext(contextMessages(), isWorking);
59986
+ const model = session.model;
59987
+ const isCurrentSource = () => state.runtime.session === session && session.sessionManager === sessionManager && sessionManager.getSessionId() === sessionId && sessionManager.getSessionFile() === sessionFile && session.model === model;
59988
+ let refresh = this.refreshes.get(id);
59989
+ if (!refresh?.isCurrentSource()) {
59990
+ refresh = { isCurrentSource };
59991
+ this.refreshes.set(id, refresh);
59992
+ }
59993
+ const finalTransition = !isWorking && refresh.wasWorking === true;
59994
+ refresh.wasWorking = isWorking;
59995
+ const reuse = turnError === void 0 && refresh.input === input && previous?.summary ? previous : void 0;
59996
+ if ((reuse || turnError !== void 0 && previous?.summary === turnError && previous.taskState === "needs_input") && previous?.basedOnMessageCount === messageCount) {
59997
+ return;
59998
+ }
59999
+ if (!reuse && turnError === void 0) {
60000
+ const remaining = MIN_REFRESH_INTERVAL_MS - (Date.now() - (refresh.attemptedAt ?? -Infinity));
60001
+ if (!finalTransition && remaining > 0) {
60002
+ this.schedule(state, remaining);
60003
+ return;
60004
+ }
60005
+ refresh.attemptedAt = Date.now();
59863
60006
  }
59864
- const streaming = isWorking ? session.state.streamingMessage : void 0;
59865
- const contextMessages = streaming ? [...messages, streaming] : messages;
59866
60007
  const controller = new AbortController();
59867
- const isCurrent = () => !controller.signal.aborted && state.runtime.session === session && session.sessionManager === sessionManager && sessionManager.getSessionId() === sessionId && sessionManager.getSessionFile() === sessionFile && isSessionWorking(state) === isWorking && session.messages.length === messageCount;
60008
+ const isCurrent = () => !controller.signal.aborted && isCurrentSource() && isSessionWorking(state) === isWorking && session.messages.length === messageCount && buildStatusContext(contextMessages(), isWorking) === input && (isWorking || terminalTurnError(session.messages) === turnError);
59868
60009
  this.inFlight.set(id, controller);
59869
60010
  let requests;
59870
60011
  let status;
60012
+ let completedInput;
59871
60013
  let changed = false;
59872
60014
  try {
59873
- if (turnError === void 0)
60015
+ if (!reuse && turnError === void 0)
59874
60016
  requests = this.getRequests?.(session);
59875
- const generated = turnError !== void 0 ? { summary: turnError, taskState: "needs_input" } : await this.generate({
60017
+ const generated = reuse ?? (turnError !== void 0 ? { summary: turnError, taskState: "needs_input" } : await this.generate({
59876
60018
  registry: session.modelRegistry,
59877
- model: session.model,
59878
- messages: contextMessages,
60019
+ model,
60020
+ messages: contextMessages(),
59879
60021
  isWorking,
60022
+ sessionId,
59880
60023
  signal: controller.signal,
59881
60024
  requests
59882
- });
60025
+ }));
59883
60026
  await requests?.dispose();
59884
60027
  const result = generated ?? (!isWorking && (owesIdleVerdict || owesSummary) ? { summary: previous?.summary ?? "", taskState: "needs_input" } : void 0);
59885
60028
  if (!result) {
@@ -59888,6 +60031,8 @@ var DaemonSessionSummarizer = class {
59888
60031
  if (!isCurrent()) {
59889
60032
  return;
59890
60033
  }
60034
+ if (generated && turnError === void 0)
60035
+ completedInput = input;
59891
60036
  const taskState = result.taskState ?? (previous?.basedOnMessageCount === messageCount ? previous?.taskState : void 0);
59892
60037
  status = {
59893
60038
  summary: result.summary,
@@ -59908,6 +60053,7 @@ var DaemonSessionSummarizer = class {
59908
60053
  }
59909
60054
  }
59910
60055
  if (status && isCurrent()) {
60056
+ refresh.input = completedInput;
59911
60057
  state.summaryState = status;
59912
60058
  if (changed)
59913
60059
  this.onStatusChanged?.(state);
@@ -64383,12 +64529,12 @@ var AgentDaemon = class {
64383
64529
  }
64384
64530
  case "get_session_tree": {
64385
64531
  const state = this.getSessionState(command.activeSessionId);
64386
- return success(command.id, "get_session_tree", await readSessionTreeFlatNodes(state.runtime.session.sessionManager));
64532
+ return success(command.id, "get_session_tree", await readVisibleSessionTreeFlatNodes(state.runtime.session.sessionManager));
64387
64533
  }
64388
64534
  case "get_user_messages_for_forking": {
64389
64535
  const state = this.getSessionState(command.activeSessionId);
64390
64536
  return success(command.id, "get_user_messages_for_forking", {
64391
- messages: await readUserMessagesForForking(state.runtime.session.sessionManager)
64537
+ messages: await readVisibleUserMessagesForForking(state.runtime.session.sessionManager)
64392
64538
  });
64393
64539
  }
64394
64540
  case "get_last_assistant_text": {
@@ -14,7 +14,7 @@ import {
14
14
  calculateCost,
15
15
  classifyStreamFailure,
16
16
  withRequestBody
17
- } from "./chunk-D3KOF57W.js";
17
+ } from "./chunk-25VYRAC6.js";
18
18
 
19
19
  // ../ai/src/providers/openai-responses-shared.ts
20
20
  function encodeTextSignatureV1(id, phase) {
@@ -2,11 +2,11 @@ import { createRequire as __piBundleCreateRequire } from 'node:module'; const re
2
2
  import {
3
3
  appendRotatingLog,
4
4
  getAgentLogPath
5
- } from "./chunk-2IPDSTDR.js";
5
+ } from "./chunk-AEMRBMI2.js";
6
6
  import {
7
7
  setLogSink,
8
8
  stringifyLogEntry
9
- } from "./chunk-D3KOF57W.js";
9
+ } from "./chunk-25VYRAC6.js";
10
10
 
11
11
  // dist/core/logging.js
12
12
  var AGENT_LOG_MAX_BYTES = 20 * 1024 * 1024;