@ponythewhite/base-context 1.0.11 → 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 (80) hide show
  1. package/CHANGELOG.md +11 -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-PEFT72QN.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-JZHGOOFM.js → chunk-IAKHCQA2.js} +118 -22
  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-TOOVREMP.js → chunk-YGV3Y4AD.js} +515 -107
  16. package/dist/bundle/{cli-main-BRXGYTGK.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-POUXGEL6.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 -0
  26. package/dist/core/agent-session.d.ts.map +1 -1
  27. package/dist/core/agent-session.js +362 -103
  28. package/dist/core/agent-session.js.map +1 -1
  29. package/dist/core/compaction/compaction.d.ts +9 -1
  30. package/dist/core/compaction/compaction.d.ts.map +1 -1
  31. package/dist/core/compaction/compaction.js +29 -3
  32. package/dist/core/compaction/compaction.js.map +1 -1
  33. package/dist/core/context-tree.d.ts +13 -10
  34. package/dist/core/context-tree.d.ts.map +1 -1
  35. package/dist/core/context-tree.js +49 -3
  36. package/dist/core/context-tree.js.map +1 -1
  37. package/dist/core/inference-coordinator.d.ts +1 -1
  38. package/dist/core/inference-coordinator.d.ts.map +1 -1
  39. package/dist/core/inference-coordinator.js +18 -5
  40. package/dist/core/inference-coordinator.js.map +1 -1
  41. package/dist/core/messages.d.ts +2 -0
  42. package/dist/core/messages.d.ts.map +1 -1
  43. package/dist/core/messages.js +2 -0
  44. package/dist/core/messages.js.map +1 -1
  45. package/dist/core/refinement/refinement.d.ts +2 -0
  46. package/dist/core/refinement/refinement.d.ts.map +1 -1
  47. package/dist/core/refinement/refinement.js +10 -1
  48. package/dist/core/refinement/refinement.js.map +1 -1
  49. package/dist/core/request-usage.d.ts +34 -0
  50. package/dist/core/request-usage.d.ts.map +1 -0
  51. package/dist/core/request-usage.js +111 -0
  52. package/dist/core/request-usage.js.map +1 -0
  53. package/dist/core/settings-manager.d.ts +3 -0
  54. package/dist/core/settings-manager.d.ts.map +1 -1
  55. package/dist/core/settings-manager.js +7 -0
  56. package/dist/core/settings-manager.js.map +1 -1
  57. package/dist/core/system-prompt.d.ts +2 -0
  58. package/dist/core/system-prompt.d.ts.map +1 -1
  59. package/dist/core/system-prompt.js +4 -2
  60. package/dist/core/system-prompt.js.map +1 -1
  61. package/dist/modes/agent-connection/daemon-agent-connection.d.ts.map +1 -1
  62. package/dist/modes/agent-connection/daemon-agent-connection.js +8 -1
  63. package/dist/modes/agent-connection/daemon-agent-connection.js.map +1 -1
  64. package/dist/modes/daemon/daemon-protocol.d.ts +13 -3
  65. package/dist/modes/daemon/daemon-protocol.d.ts.map +1 -1
  66. package/dist/modes/daemon/daemon-protocol.js +10 -2
  67. package/dist/modes/daemon/daemon-protocol.js.map +1 -1
  68. package/dist/modes/daemon/daemon-session-summarizer.d.ts +3 -0
  69. package/dist/modes/daemon/daemon-session-summarizer.d.ts.map +1 -1
  70. package/dist/modes/daemon/daemon-session-summarizer.js +71 -32
  71. package/dist/modes/daemon/daemon-session-summarizer.js.map +1 -1
  72. package/dist/modes/interactive/components/context-tree-format.d.ts.map +1 -1
  73. package/dist/modes/interactive/components/context-tree-format.js +49 -0
  74. package/dist/modes/interactive/components/context-tree-format.js.map +1 -1
  75. package/docs/compaction.md +27 -3
  76. package/docs/context-management.md +17 -1
  77. package/docs/rlm.md +1 -1
  78. package/docs/settings.md +12 -0
  79. package/docs/usage.md +24 -1
  80. package/package.json +4 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.0.12] - 2026-09-21
4
+
5
+ - Fixed compaction and recovery for primary RLM child requests.
6
+ - Fixed usage forwarding when retained children resumed, preserved new child attribution across restarts, and prevented nested usage from being counted twice.
7
+ - Added receipt-based per-purpose and captured-family token totals to `/context`, with explicit unknown usage and catalog-cost labels.
8
+ - Reduced repeated dashboard requests with unchanged-input reuse and one-minute refresh coalescing.
9
+ - Kept refinement advice current without rewriting the system prefix, and added stable cache identities for auxiliary requests.
10
+ - Added earlier model-aware compaction targets with headroom for required context and an explicit `model-limit` opt-out.
11
+ - Fixed child run status after terminal provider errors or cancellation.
12
+ - Added guidance to page long output and batch nonurgent agent updates.
13
+
3
14
  ## [1.0.11] - 2026-09-20
4
15
 
5
16
  - Fixed recovery compaction in long-running sessions that use `prime_context` without a request-budget profile.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "base-context-runtime"
3
- version = "1.0.11"
3
+ version = "1.0.12"
4
4
  description = "Kernel-side runtime shim for Base Context recursion"
5
5
  license = "MIT"
6
6
  license-files = ["LICENSE", "NOTICE"]
@@ -367,7 +367,7 @@ wheels = [
367
367
 
368
368
  [[package]]
369
369
  name = "base-context-runtime"
370
- version = "1.0.11"
370
+ version = "1.0.12"
371
371
  source = { editable = "." }
372
372
  dependencies = [
373
373
  { name = "mcp" },
@@ -1,5 +1,5 @@
1
1
  {
2
- "sourceCommit": "67d926ccc3c680e5197852b7ac34dd2cc69c61f9",
2
+ "sourceCommit": "8a0001383aefd9636a5f5420ee6b555892145936",
3
3
  "sourceDirty": false,
4
4
  "buildHost": {
5
5
  "platform": "linux",
@@ -1,14 +1,14 @@
1
1
  import { createRequire as __piBundleCreateRequire } from 'node:module'; const require = __piBundleCreateRequire(import.meta.url);
2
2
  import {
3
3
  writeFileLogEntry
4
- } from "./chunk-QKIFBA7N.js";
5
- import "./chunk-2IPDSTDR.js";
4
+ } from "./chunk-Q6UAHLII.js";
5
+ import "./chunk-AEMRBMI2.js";
6
6
  import "./chunk-5QCJ5DQU.js";
7
7
  import "./chunk-CRBVRZBV.js";
8
8
  import "./chunk-GRJFXLBM.js";
9
9
  import "./chunk-2T7M7VJ4.js";
10
10
  import "./chunk-DGNX7HQ3.js";
11
- import "./chunk-D3KOF57W.js";
11
+ import "./chunk-25VYRAC6.js";
12
12
  import "./chunk-BAWSWWEU.js";
13
13
 
14
14
  // dist/node/amazon-bedrock.js
@@ -36,7 +36,7 @@ import {
36
36
  streamFailureFromStopReason,
37
37
  streamFailureMessage,
38
38
  truncateRawPayload
39
- } from "./chunk-D3KOF57W.js";
39
+ } from "./chunk-25VYRAC6.js";
40
40
  import "./chunk-BAWSWWEU.js";
41
41
 
42
42
  // ../../node_modules/@anthropic-ai/sdk/internal/tslib.mjs
@@ -6595,7 +6595,7 @@ var streamAnthropic = (model, context, options) => {
6595
6595
  client = created.client;
6596
6596
  isOAuth = created.isOAuthToken;
6597
6597
  }
6598
- if (attempts.enabled) {
6598
+ if (attempts.enabled || options?.signal) {
6599
6599
  client = client.withOptions({});
6600
6600
  client.fetchWithTimeout = attempts.wrapHttp(client.fetchWithTimeout.bind(client));
6601
6601
  }
@@ -3,7 +3,7 @@ import {
3
3
  convertResponsesMessages,
4
4
  convertResponsesTools,
5
5
  processResponsesStream
6
- } from "./chunk-KT2BNEPE.js";
6
+ } from "./chunk-MUFZODP5.js";
7
7
  import "./chunk-NQB5DCFC.js";
8
8
  import {
9
9
  AzureOpenAI
@@ -25,7 +25,7 @@ import {
25
25
  formatStreamFailureMessage,
26
26
  recordStreamFailure,
27
27
  streamFailureFromStopReason
28
- } from "./chunk-D3KOF57W.js";
28
+ } from "./chunk-25VYRAC6.js";
29
29
  import "./chunk-BAWSWWEU.js";
30
30
 
31
31
  // ../ai/src/providers/azure-openai-responses.ts
@@ -74,9 +74,8 @@ var streamAzureOpenAIResponses = (model, context, options) => {
74
74
  };
75
75
  try {
76
76
  const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
77
- let client = createClient(model, apiKey, options);
78
- if (attempts.enabled) {
79
- client = client.withOptions({});
77
+ const client = createClient(model, apiKey, options);
78
+ if (attempts.enabled || options?.signal) {
80
79
  client.fetchWithTimeout = attempts.wrapHttp(client.fetchWithTimeout.bind(client));
81
80
  }
82
81
  let params = buildParams(model, context, options, deploymentName);
@@ -51,7 +51,7 @@ import {
51
51
  oauth_exports,
52
52
  runPrintMode,
53
53
  runRpcMode
54
- } from "./chunk-JZHGOOFM.js";
54
+ } from "./chunk-IAKHCQA2.js";
55
55
  import {
56
56
  AgentSession,
57
57
  CURRENT_SESSION_VERSION,
@@ -143,15 +143,15 @@ import {
143
143
  withFileMutationQueue,
144
144
  wrapRegisteredTool,
145
145
  wrapRegisteredTools
146
- } from "./chunk-TOOVREMP.js";
146
+ } from "./chunk-YGV3Y4AD.js";
147
147
  import "./chunk-CFNASUYO.js";
148
- import "./chunk-QKIFBA7N.js";
148
+ import "./chunk-Q6UAHLII.js";
149
149
  import {
150
150
  VERSION,
151
151
  build_exports,
152
152
  getAgentDir,
153
153
  src_exports
154
- } from "./chunk-2IPDSTDR.js";
154
+ } from "./chunk-AEMRBMI2.js";
155
155
  import "./chunk-5QCJ5DQU.js";
156
156
  import {
157
157
  compile_exports,
@@ -162,7 +162,7 @@ import "./chunk-2T7M7VJ4.js";
162
162
  import "./chunk-UIRUOAIQ.js";
163
163
  import "./chunk-HXOBFFJX.js";
164
164
  import "./chunk-DGNX7HQ3.js";
165
- import "./chunk-D3KOF57W.js";
165
+ import "./chunk-25VYRAC6.js";
166
166
  import {
167
167
  __export
168
168
  } from "./chunk-BAWSWWEU.js";
@@ -21668,8 +21668,18 @@ var ProviderAttemptTracker = class {
21668
21668
  }
21669
21669
  /** Wrap an SDK's single-send method, below its retry loop. */
21670
21670
  wrapHttp(send, operation) {
21671
- if (!this.enabled) return send;
21672
21671
  return async (...args) => {
21672
+ const requestInit = args[1];
21673
+ let signal;
21674
+ if (requestInit?.signal) {
21675
+ this.httpLifetime ??= new AbortController();
21676
+ signal = AbortSignal.any([requestInit.signal, this.httpLifetime.signal]);
21677
+ }
21678
+ if (signal) args[1] = { ...requestInit, signal };
21679
+ if (!this.enabled) {
21680
+ signal?.throwIfAborted();
21681
+ return send(...args);
21682
+ }
21673
21683
  if (operation === "input-count") this.options?.signal?.throwIfAborted();
21674
21684
  if (this.hasRequestBudget && operation !== "input-count") {
21675
21685
  const target = args[0];
@@ -21682,6 +21692,7 @@ var ProviderAttemptTracker = class {
21682
21692
  await this.begin("http", operation === "input-count" ? { kind: "input-count" } : {});
21683
21693
  let response;
21684
21694
  try {
21695
+ signal?.throwIfAborted();
21685
21696
  if (operation === "input-count") this.options?.signal?.throwIfAborted();
21686
21697
  this.sent();
21687
21698
  response = await send(...args);
@@ -21752,6 +21763,8 @@ var ProviderAttemptTracker = class {
21752
21763
  } catch (error) {
21753
21764
  output.stopReason = "error";
21754
21765
  output.errorMessage = `Attempt settlement failed: ${error instanceof Error ? error.message : String(error)}`;
21766
+ } finally {
21767
+ this.httpLifetime?.abort();
21755
21768
  }
21756
21769
  if (output.stopReason === "error" || output.stopReason === "aborted") {
21757
21770
  stream.push({ type: "error", reason: output.stopReason, error: output });
@@ -337,7 +337,7 @@ import {
337
337
  supportsFastMode,
338
338
  truncateRawPayload,
339
339
  withRequestBody
340
- } from "./chunk-D3KOF57W.js";
340
+ } from "./chunk-25VYRAC6.js";
341
341
  import {
342
342
  __export
343
343
  } from "./chunk-BAWSWWEU.js";
@@ -1948,7 +1948,7 @@ function createLazySimpleStream(loadModule) {
1948
1948
  };
1949
1949
  }
1950
1950
  function loadAnthropicProviderModule() {
1951
- anthropicProviderModulePromise ||= import("./anthropic-5PSCZEER.js").then((module) => {
1951
+ anthropicProviderModulePromise ||= import("./anthropic-BJVPUMPB.js").then((module) => {
1952
1952
  const provider = module;
1953
1953
  return {
1954
1954
  stream: provider.streamAnthropic,
@@ -1958,7 +1958,7 @@ function loadAnthropicProviderModule() {
1958
1958
  return anthropicProviderModulePromise;
1959
1959
  }
1960
1960
  function loadAzureOpenAIResponsesProviderModule() {
1961
- azureOpenAIResponsesProviderModulePromise ||= import("./azure-openai-responses-AYTLJR33.js").then((module) => {
1961
+ azureOpenAIResponsesProviderModulePromise ||= import("./azure-openai-responses-ERRMAXK6.js").then((module) => {
1962
1962
  const provider = module;
1963
1963
  return {
1964
1964
  stream: provider.streamAzureOpenAIResponses,
@@ -1968,7 +1968,7 @@ function loadAzureOpenAIResponsesProviderModule() {
1968
1968
  return azureOpenAIResponsesProviderModulePromise;
1969
1969
  }
1970
1970
  function loadGoogleProviderModule() {
1971
- googleProviderModulePromise ||= import("./google-HTMCUJ7X.js").then((module) => {
1971
+ googleProviderModulePromise ||= import("./google-4GA4YMUX.js").then((module) => {
1972
1972
  const provider = module;
1973
1973
  return {
1974
1974
  stream: provider.streamGoogle,
@@ -1978,7 +1978,7 @@ function loadGoogleProviderModule() {
1978
1978
  return googleProviderModulePromise;
1979
1979
  }
1980
1980
  function loadGoogleVertexProviderModule() {
1981
- googleVertexProviderModulePromise ||= import("./google-vertex-ZQO65AXF.js").then((module) => {
1981
+ googleVertexProviderModulePromise ||= import("./google-vertex-7AMALD7D.js").then((module) => {
1982
1982
  const provider = module;
1983
1983
  return {
1984
1984
  stream: provider.streamGoogleVertex,
@@ -1988,7 +1988,7 @@ function loadGoogleVertexProviderModule() {
1988
1988
  return googleVertexProviderModulePromise;
1989
1989
  }
1990
1990
  function loadMistralProviderModule() {
1991
- mistralProviderModulePromise ||= import("./mistral-SB7LU56G.js").then((module) => {
1991
+ mistralProviderModulePromise ||= import("./mistral-74BXMNRM.js").then((module) => {
1992
1992
  const provider = module;
1993
1993
  return {
1994
1994
  stream: provider.streamMistral,
@@ -1998,7 +1998,7 @@ function loadMistralProviderModule() {
1998
1998
  return mistralProviderModulePromise;
1999
1999
  }
2000
2000
  function loadOpenAICodexResponsesProviderModule() {
2001
- openAICodexResponsesProviderModulePromise ||= import("./openai-codex-responses-5CEW4VN3.js").then((module) => {
2001
+ openAICodexResponsesProviderModulePromise ||= import("./openai-codex-responses-COXNC4IH.js").then((module) => {
2002
2002
  const provider = module;
2003
2003
  return {
2004
2004
  stream: provider.streamOpenAICodexResponses,
@@ -2008,7 +2008,7 @@ function loadOpenAICodexResponsesProviderModule() {
2008
2008
  return openAICodexResponsesProviderModulePromise;
2009
2009
  }
2010
2010
  function loadOpenAICompletionsProviderModule() {
2011
- openAICompletionsProviderModulePromise ||= import("./openai-completions-BAZJQSS2.js").then((module) => {
2011
+ openAICompletionsProviderModulePromise ||= import("./openai-completions-BCSA5Q6S.js").then((module) => {
2012
2012
  const provider = module;
2013
2013
  return {
2014
2014
  stream: provider.streamOpenAICompletions,
@@ -2018,7 +2018,7 @@ function loadOpenAICompletionsProviderModule() {
2018
2018
  return openAICompletionsProviderModulePromise;
2019
2019
  }
2020
2020
  function loadOpenAIResponsesProviderModule() {
2021
- openAIResponsesProviderModulePromise ||= import("./openai-responses-VHOE427P.js").then((module) => {
2021
+ openAIResponsesProviderModulePromise ||= import("./openai-responses-ONCIZSJS.js").then((module) => {
2022
2022
  const provider = module;
2023
2023
  return {
2024
2024
  stream: provider.streamOpenAIResponses,
@@ -5,7 +5,7 @@ import {
5
5
  } from "./chunk-4GXPNXOJ.js";
6
6
  import {
7
7
  require_base64_js
8
- } from "./chunk-D3KOF57W.js";
8
+ } from "./chunk-25VYRAC6.js";
9
9
  import {
10
10
  __commonJS,
11
11
  __require,
@@ -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,
@@ -349,7 +351,7 @@ import {
349
351
  watchWithErrorHandler,
350
352
  workerRosterEntryFromSummary,
351
353
  wrapTextWithAnsi
352
- } from "./chunk-TOOVREMP.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. */
@@ -34609,10 +34616,17 @@ var DaemonAgentConnection = class _DaemonAgentConnection {
34609
34616
  });
34610
34617
  }
34611
34618
  async getContextTree() {
34612
- return this.requestData({
34619
+ const tree = await this.requestData({
34613
34620
  type: "get_context_tree",
34614
34621
  activeSessionId: this.activeSessionId
34615
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);
34616
34630
  }
34617
34631
  async getSessionContext() {
34618
34632
  if (this.latestSnapshotIsFresh && this.latestSnapshot?.sessionContext) {
@@ -40813,8 +40827,50 @@ function sumOwnUsage(root) {
40813
40827
  walk(root);
40814
40828
  return total;
40815
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
+ }
40816
40870
  function formatContextTree(root, width) {
40817
40871
  const rows = flattenContextTree(root);
40872
+ if (rows.some(({ node }) => node.ownRequestUsage))
40873
+ return formatReceiptContextTree(root, width);
40818
40874
  const tokenCells = rows.map((row) => formatTokenCount2(spentTokens(row.node.ownUsage)));
40819
40875
  const costCells = rows.map((row) => formatCost(row.node.ownUsage.cost.total));
40820
40876
  const tokenHeader = "tokens";
@@ -40826,6 +40882,9 @@ function formatContextTree(root, width) {
40826
40882
  const lines = [];
40827
40883
  lines.push(theme.bold("Context"));
40828
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("");
40829
40888
  if (root.model) {
40830
40889
  lines.push(`${theme.fg("dim", "Model:")} ${root.model.provider}/${root.model.id}`);
40831
40890
  lines.push("");
@@ -40871,6 +40930,7 @@ function formatContextTree(root, width) {
40871
40930
  lines.push(`${theme.fg("dim", "Current:")} ${rootContext.tokens.toLocaleString()} / ${rootContext.contextWindow.toLocaleString()} (${percent})`);
40872
40931
  }
40873
40932
  }
40933
+ lines.push("", GOAL_SCOPE);
40874
40934
  return lines.join("\n");
40875
40935
  }
40876
40936
 
@@ -59637,6 +59697,7 @@ var DaemonRlmCapacityClient = class {
59637
59697
  // dist/modes/daemon/daemon-session-summarizer.js
59638
59698
  var SWEEP_INTERVAL_MS = 25e3;
59639
59699
  var SETTLE_DEBOUNCE_MS = 2e3;
59700
+ var MIN_REFRESH_INTERVAL_MS = 6e4;
59640
59701
  var SUMMARY_CONTEXT_MESSAGES = 8;
59641
59702
  var SUMMARY_MAX_CHARS_PER_MESSAGE = 600;
59642
59703
  var SUMMARY_MAX_TOKENS = 400;
@@ -59670,7 +59731,7 @@ function messageText(content) {
59670
59731
  const type = block.type;
59671
59732
  if (type === "text" && typeof block.text === "string") {
59672
59733
  parts.push(block.text);
59673
- } else if (type === "tool_use" || type === "toolUse") {
59734
+ } else if (type === "toolCall" || type === "tool_use" || type === "toolUse") {
59674
59735
  const name = block.name;
59675
59736
  if (typeof name === "string") {
59676
59737
  tools.push(name);
@@ -59734,7 +59795,7 @@ function parseAgentStatusResponse(text, isWorking) {
59734
59795
  return { summary, taskState };
59735
59796
  }
59736
59797
  async function generateAgentStatus(params) {
59737
- const { registry, messages, isWorking, signal, requests, model: selectedModel } = params;
59798
+ const { registry, messages, isWorking, sessionId, signal, requests, model: selectedModel } = params;
59738
59799
  if (messages.length === 0) {
59739
59800
  return void 0;
59740
59801
  }
@@ -59758,7 +59819,13 @@ async function generateAgentStatus(params) {
59758
59819
  timestamp
59759
59820
  }
59760
59821
  ]
59761
- }, { 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" });
59762
59829
  if (response.stopReason === "error") {
59763
59830
  return void 0;
59764
59831
  }
@@ -59794,6 +59861,7 @@ var DaemonSessionSummarizer = class {
59794
59861
  debounceTimers = /* @__PURE__ */ new Map();
59795
59862
  // Controller per in-flight summary so a closing session can abort its write.
59796
59863
  inFlight = /* @__PURE__ */ new Map();
59864
+ refreshes = /* @__PURE__ */ new Map();
59797
59865
  tasks = /* @__PURE__ */ new Map();
59798
59866
  forgotten = /* @__PURE__ */ new Set();
59799
59867
  stopped = false;
@@ -59843,6 +59911,7 @@ var DaemonSessionSummarizer = class {
59843
59911
  this.debounceTimers.delete(activeSessionId);
59844
59912
  }
59845
59913
  this.inFlight.get(activeSessionId)?.abort();
59914
+ this.refreshes.delete(activeSessionId);
59846
59915
  this.rerunRequested.delete(activeSessionId);
59847
59916
  await this.tasks.get(activeSessionId);
59848
59917
  }
@@ -59859,6 +59928,9 @@ var DaemonSessionSummarizer = class {
59859
59928
  }
59860
59929
  /** Called when a session finishes a turn; debounce until the agent settles. */
59861
59930
  notifyActivity(state) {
59931
+ this.schedule(state, SETTLE_DEBOUNCE_MS);
59932
+ }
59933
+ schedule(state, delay8) {
59862
59934
  const id = state.activeSessionId;
59863
59935
  if (this.stopped || this.forgotten.has(id))
59864
59936
  return;
@@ -59869,7 +59941,7 @@ var DaemonSessionSummarizer = class {
59869
59941
  const timer = setTimeout(() => {
59870
59942
  this.debounceTimers.delete(id);
59871
59943
  this.summarize(state);
59872
- }, SETTLE_DEBOUNCE_MS);
59944
+ }, delay8);
59873
59945
  timer.unref?.();
59874
59946
  this.debounceTimers.set(id, timer);
59875
59947
  }
@@ -59903,33 +59975,54 @@ var DaemonSessionSummarizer = class {
59903
59975
  const messageCount = messages.length;
59904
59976
  const isWorking = isSessionWorking(state);
59905
59977
  const previous = state.summaryState;
59906
- const contentUnchanged = previous?.basedOnMessageCount === messageCount;
59907
59978
  const owesIdleVerdict = !isWorking && previous?.taskState === void 0;
59908
59979
  const owesSummary = !isWorking && !previous?.summary;
59909
59980
  const turnError = !isWorking ? terminalTurnError(messages) : void 0;
59910
- const owesErrorVerdict = turnError !== void 0 && (previous?.taskState !== "needs_input" || previous?.summary !== turnError);
59911
- if (contentUnchanged && !isWorking && !owesIdleVerdict && !owesSummary && !owesErrorVerdict) {
59912
- 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();
59913
60006
  }
59914
- const streaming = isWorking ? session.state.streamingMessage : void 0;
59915
- const contextMessages = streaming ? [...messages, streaming] : messages;
59916
60007
  const controller = new AbortController();
59917
- 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);
59918
60009
  this.inFlight.set(id, controller);
59919
60010
  let requests;
59920
60011
  let status;
60012
+ let completedInput;
59921
60013
  let changed = false;
59922
60014
  try {
59923
- if (turnError === void 0)
60015
+ if (!reuse && turnError === void 0)
59924
60016
  requests = this.getRequests?.(session);
59925
- 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({
59926
60018
  registry: session.modelRegistry,
59927
- model: session.model,
59928
- messages: contextMessages,
60019
+ model,
60020
+ messages: contextMessages(),
59929
60021
  isWorking,
60022
+ sessionId,
59930
60023
  signal: controller.signal,
59931
60024
  requests
59932
- });
60025
+ }));
59933
60026
  await requests?.dispose();
59934
60027
  const result = generated ?? (!isWorking && (owesIdleVerdict || owesSummary) ? { summary: previous?.summary ?? "", taskState: "needs_input" } : void 0);
59935
60028
  if (!result) {
@@ -59938,6 +60031,8 @@ var DaemonSessionSummarizer = class {
59938
60031
  if (!isCurrent()) {
59939
60032
  return;
59940
60033
  }
60034
+ if (generated && turnError === void 0)
60035
+ completedInput = input;
59941
60036
  const taskState = result.taskState ?? (previous?.basedOnMessageCount === messageCount ? previous?.taskState : void 0);
59942
60037
  status = {
59943
60038
  summary: result.summary,
@@ -59958,6 +60053,7 @@ var DaemonSessionSummarizer = class {
59958
60053
  }
59959
60054
  }
59960
60055
  if (status && isCurrent()) {
60056
+ refresh.input = completedInput;
59961
60057
  state.summaryState = status;
59962
60058
  if (changed)
59963
60059
  this.onStatusChanged?.(state);
@@ -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;