@caupulican/pi-adaptative 0.81.26 → 0.81.27

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 (229) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/cli/args.d.ts.map +1 -1
  3. package/dist/cli/args.js +3 -2
  4. package/dist/cli/args.js.map +1 -1
  5. package/dist/core/agent-session-services.d.ts +4 -0
  6. package/dist/core/agent-session-services.d.ts.map +1 -1
  7. package/dist/core/agent-session-services.js +19 -2
  8. package/dist/core/agent-session-services.js.map +1 -1
  9. package/dist/core/agent-session.d.ts +21 -10
  10. package/dist/core/agent-session.d.ts.map +1 -1
  11. package/dist/core/agent-session.js +71 -33
  12. package/dist/core/agent-session.js.map +1 -1
  13. package/dist/core/autonomy/bounded-completion.d.ts.map +1 -1
  14. package/dist/core/autonomy/bounded-completion.js +59 -19
  15. package/dist/core/autonomy/bounded-completion.js.map +1 -1
  16. package/dist/core/autonomy/lane-tool-surface.d.ts +31 -0
  17. package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -0
  18. package/dist/core/autonomy/lane-tool-surface.js +96 -0
  19. package/dist/core/autonomy/lane-tool-surface.js.map +1 -0
  20. package/dist/core/background-lane-controller.d.ts +6 -3
  21. package/dist/core/background-lane-controller.d.ts.map +1 -1
  22. package/dist/core/background-lane-controller.js +134 -25
  23. package/dist/core/background-lane-controller.js.map +1 -1
  24. package/dist/core/billing-failover-controller.d.ts.map +1 -1
  25. package/dist/core/billing-failover-controller.js +1 -1
  26. package/dist/core/billing-failover-controller.js.map +1 -1
  27. package/dist/core/context/current-work-memory.d.ts +9 -0
  28. package/dist/core/context/current-work-memory.d.ts.map +1 -0
  29. package/dist/core/context/current-work-memory.js +61 -0
  30. package/dist/core/context/current-work-memory.js.map +1 -0
  31. package/dist/core/context/file-store-memory-provider.d.ts +9 -0
  32. package/dist/core/context/file-store-memory-provider.d.ts.map +1 -0
  33. package/dist/core/context/file-store-memory-provider.js +106 -0
  34. package/dist/core/context/file-store-memory-provider.js.map +1 -0
  35. package/dist/core/context/long-term-memory-trigger.d.ts +15 -0
  36. package/dist/core/context/long-term-memory-trigger.d.ts.map +1 -0
  37. package/dist/core/context/long-term-memory-trigger.js +39 -0
  38. package/dist/core/context/long-term-memory-trigger.js.map +1 -0
  39. package/dist/core/context/memory-prompt-block.d.ts +3 -1
  40. package/dist/core/context/memory-prompt-block.d.ts.map +1 -1
  41. package/dist/core/context/memory-prompt-block.js +20 -3
  42. package/dist/core/context/memory-prompt-block.js.map +1 -1
  43. package/dist/core/context/memory-prompt-budget.d.ts +17 -0
  44. package/dist/core/context/memory-prompt-budget.d.ts.map +1 -0
  45. package/dist/core/context/memory-prompt-budget.js +64 -0
  46. package/dist/core/context/memory-prompt-budget.js.map +1 -0
  47. package/dist/core/context/memory-provider-contract.d.ts.map +1 -1
  48. package/dist/core/context/memory-provider-contract.js +2 -5
  49. package/dist/core/context/memory-provider-contract.js.map +1 -1
  50. package/dist/core/context/memory-tier-composer.d.ts +27 -0
  51. package/dist/core/context/memory-tier-composer.d.ts.map +1 -0
  52. package/dist/core/context/memory-tier-composer.js +79 -0
  53. package/dist/core/context/memory-tier-composer.js.map +1 -0
  54. package/dist/core/context-gc.d.ts.map +1 -1
  55. package/dist/core/context-gc.js +1 -0
  56. package/dist/core/context-gc.js.map +1 -1
  57. package/dist/core/cost/cost-summary.d.ts +3 -1
  58. package/dist/core/cost/cost-summary.d.ts.map +1 -1
  59. package/dist/core/cost/cost-summary.js +3 -3
  60. package/dist/core/cost/cost-summary.js.map +1 -1
  61. package/dist/core/cost-guard.d.ts +17 -7
  62. package/dist/core/cost-guard.d.ts.map +1 -1
  63. package/dist/core/cost-guard.js +33 -10
  64. package/dist/core/cost-guard.js.map +1 -1
  65. package/dist/core/default-tool-surface.d.ts +9 -0
  66. package/dist/core/default-tool-surface.d.ts.map +1 -0
  67. package/dist/core/default-tool-surface.js +18 -0
  68. package/dist/core/default-tool-surface.js.map +1 -0
  69. package/dist/core/delegation/worker-runner.d.ts +11 -5
  70. package/dist/core/delegation/worker-runner.d.ts.map +1 -1
  71. package/dist/core/delegation/worker-runner.js +24 -12
  72. package/dist/core/delegation/worker-runner.js.map +1 -1
  73. package/dist/core/extensions/loader.d.ts.map +1 -1
  74. package/dist/core/extensions/loader.js +15 -0
  75. package/dist/core/extensions/loader.js.map +1 -1
  76. package/dist/core/extensions/runner.d.ts +2 -0
  77. package/dist/core/extensions/runner.d.ts.map +1 -1
  78. package/dist/core/extensions/runner.js +7 -0
  79. package/dist/core/extensions/runner.js.map +1 -1
  80. package/dist/core/extensions/types.d.ts +9 -0
  81. package/dist/core/extensions/types.d.ts.map +1 -1
  82. package/dist/core/extensions/types.js.map +1 -1
  83. package/dist/core/failure-corpus.d.ts.map +1 -1
  84. package/dist/core/failure-corpus.js +2 -4
  85. package/dist/core/failure-corpus.js.map +1 -1
  86. package/dist/core/footer-data-provider.d.ts.map +1 -1
  87. package/dist/core/footer-data-provider.js +9 -1
  88. package/dist/core/footer-data-provider.js.map +1 -1
  89. package/dist/core/goals/goal-continuation-prompt.d.ts.map +1 -1
  90. package/dist/core/goals/goal-continuation-prompt.js +4 -3
  91. package/dist/core/goals/goal-continuation-prompt.js.map +1 -1
  92. package/dist/core/http-dispatcher.d.ts +12 -0
  93. package/dist/core/http-dispatcher.d.ts.map +1 -1
  94. package/dist/core/http-dispatcher.js +42 -4
  95. package/dist/core/http-dispatcher.js.map +1 -1
  96. package/dist/core/memory/memory-manager.d.ts +8 -3
  97. package/dist/core/memory/memory-manager.d.ts.map +1 -1
  98. package/dist/core/memory/memory-manager.js +27 -11
  99. package/dist/core/memory/memory-manager.js.map +1 -1
  100. package/dist/core/memory/memory-provider.d.ts +5 -1
  101. package/dist/core/memory/memory-provider.d.ts.map +1 -1
  102. package/dist/core/memory/memory-provider.js.map +1 -1
  103. package/dist/core/memory/providers/file-store.d.ts +3 -1
  104. package/dist/core/memory/providers/file-store.d.ts.map +1 -1
  105. package/dist/core/memory/providers/file-store.js +7 -2
  106. package/dist/core/memory/providers/file-store.js.map +1 -1
  107. package/dist/core/memory/providers/transcript-recall.d.ts +1 -0
  108. package/dist/core/memory/providers/transcript-recall.d.ts.map +1 -1
  109. package/dist/core/memory/providers/transcript-recall.js +4 -7
  110. package/dist/core/memory/providers/transcript-recall.js.map +1 -1
  111. package/dist/core/memory-controller.d.ts +36 -10
  112. package/dist/core/memory-controller.d.ts.map +1 -1
  113. package/dist/core/memory-controller.js +137 -21
  114. package/dist/core/memory-controller.js.map +1 -1
  115. package/dist/core/model-registry.d.ts +23 -0
  116. package/dist/core/model-registry.d.ts.map +1 -1
  117. package/dist/core/model-registry.js +87 -8
  118. package/dist/core/model-registry.js.map +1 -1
  119. package/dist/core/model-resolver.d.ts.map +1 -1
  120. package/dist/core/model-resolver.js +30 -11
  121. package/dist/core/model-resolver.js.map +1 -1
  122. package/dist/core/model-router-controller.d.ts.map +1 -1
  123. package/dist/core/model-router-controller.js +33 -29
  124. package/dist/core/model-router-controller.js.map +1 -1
  125. package/dist/core/model-selection-controller.d.ts +3 -0
  126. package/dist/core/model-selection-controller.d.ts.map +1 -1
  127. package/dist/core/model-selection-controller.js +8 -1
  128. package/dist/core/model-selection-controller.js.map +1 -1
  129. package/dist/core/models/perf-profile.d.ts.map +1 -1
  130. package/dist/core/models/perf-profile.js +95 -33
  131. package/dist/core/models/perf-profile.js.map +1 -1
  132. package/dist/core/profile-filter-controller.d.ts +11 -0
  133. package/dist/core/profile-filter-controller.d.ts.map +1 -1
  134. package/dist/core/profile-filter-controller.js +56 -11
  135. package/dist/core/profile-filter-controller.js.map +1 -1
  136. package/dist/core/profile-registry.d.ts +2 -2
  137. package/dist/core/profile-registry.d.ts.map +1 -1
  138. package/dist/core/profile-registry.js +58 -7
  139. package/dist/core/profile-registry.js.map +1 -1
  140. package/dist/core/reflection-controller.d.ts +7 -7
  141. package/dist/core/reflection-controller.d.ts.map +1 -1
  142. package/dist/core/reflection-controller.js +78 -12
  143. package/dist/core/reflection-controller.js.map +1 -1
  144. package/dist/core/research/research-runner.d.ts +2 -2
  145. package/dist/core/research/research-runner.d.ts.map +1 -1
  146. package/dist/core/research/research-runner.js +8 -6
  147. package/dist/core/research/research-runner.js.map +1 -1
  148. package/dist/core/resource-loader.d.ts +4 -2
  149. package/dist/core/resource-loader.d.ts.map +1 -1
  150. package/dist/core/resource-loader.js +11 -1
  151. package/dist/core/resource-loader.js.map +1 -1
  152. package/dist/core/runtime-builder.d.ts +13 -1
  153. package/dist/core/runtime-builder.d.ts.map +1 -1
  154. package/dist/core/runtime-builder.js +127 -35
  155. package/dist/core/runtime-builder.js.map +1 -1
  156. package/dist/core/sdk.d.ts +8 -7
  157. package/dist/core/sdk.d.ts.map +1 -1
  158. package/dist/core/sdk.js +35 -5
  159. package/dist/core/sdk.js.map +1 -1
  160. package/dist/core/security/secret-text.d.ts +3 -0
  161. package/dist/core/security/secret-text.d.ts.map +1 -0
  162. package/dist/core/security/secret-text.js +26 -0
  163. package/dist/core/security/secret-text.js.map +1 -0
  164. package/dist/core/settings-manager.d.ts +59 -17
  165. package/dist/core/settings-manager.d.ts.map +1 -1
  166. package/dist/core/settings-manager.js +300 -51
  167. package/dist/core/settings-manager.js.map +1 -1
  168. package/dist/core/skills.d.ts.map +1 -1
  169. package/dist/core/skills.js +1 -1
  170. package/dist/core/skills.js.map +1 -1
  171. package/dist/core/system-prompt-builder.d.ts +7 -0
  172. package/dist/core/system-prompt-builder.d.ts.map +1 -1
  173. package/dist/core/system-prompt-builder.js +23 -1
  174. package/dist/core/system-prompt-builder.js.map +1 -1
  175. package/dist/core/tools/delegate.d.ts.map +1 -1
  176. package/dist/core/tools/delegate.js +15 -11
  177. package/dist/core/tools/delegate.js.map +1 -1
  178. package/dist/main.d.ts.map +1 -1
  179. package/dist/main.js +2 -0
  180. package/dist/main.js.map +1 -1
  181. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  182. package/dist/modes/interactive/components/footer.js +8 -1
  183. package/dist/modes/interactive/components/footer.js.map +1 -1
  184. package/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  185. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  186. package/dist/modes/interactive/components/settings-selector.js +69 -29
  187. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  188. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  189. package/dist/modes/interactive/components/thinking-selector.js +2 -0
  190. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  191. package/dist/modes/interactive/config-backup.d.ts +7 -1
  192. package/dist/modes/interactive/config-backup.d.ts.map +1 -1
  193. package/dist/modes/interactive/config-backup.js +196 -32
  194. package/dist/modes/interactive/config-backup.js.map +1 -1
  195. package/dist/modes/interactive/interactive-mode.d.ts +1 -1
  196. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  197. package/dist/modes/interactive/interactive-mode.js +10 -28
  198. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  199. package/dist/modes/interactive/local-model-commands.d.ts.map +1 -1
  200. package/dist/modes/interactive/local-model-commands.js +2 -0
  201. package/dist/modes/interactive/local-model-commands.js.map +1 -1
  202. package/dist/modes/interactive/profile-menu-controller.d.ts +6 -4
  203. package/dist/modes/interactive/profile-menu-controller.d.ts.map +1 -1
  204. package/dist/modes/interactive/profile-menu-controller.js +248 -65
  205. package/dist/modes/interactive/profile-menu-controller.js.map +1 -1
  206. package/dist/modes/interactive/report-commands.d.ts.map +1 -1
  207. package/dist/modes/interactive/report-commands.js +8 -2
  208. package/dist/modes/interactive/report-commands.js.map +1 -1
  209. package/dist/modes/interactive/settings-selector-flow.d.ts.map +1 -1
  210. package/dist/modes/interactive/settings-selector-flow.js +8 -0
  211. package/dist/modes/interactive/settings-selector-flow.js.map +1 -1
  212. package/dist/modes/interactive/theme/theme-schema.json +1 -1
  213. package/dist/modes/interactive/theme/theme.d.ts +1 -1
  214. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  215. package/dist/modes/interactive/theme/theme.js +3 -1
  216. package/dist/modes/interactive/theme/theme.js.map +1 -1
  217. package/docs/extensions.md +32 -0
  218. package/docs/resources.md +15 -7
  219. package/docs/settings.md +54 -5
  220. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  221. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  222. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  223. package/examples/extensions/preset.ts +2 -2
  224. package/examples/extensions/sandbox/package-lock.json +2 -2
  225. package/examples/extensions/sandbox/package.json +1 -1
  226. package/examples/extensions/with-deps/package-lock.json +2 -2
  227. package/examples/extensions/with-deps/package.json +1 -1
  228. package/npm-shrinkwrap.json +44 -35
  229. package/package.json +4 -4
@@ -3,7 +3,7 @@ import { tmpdir } from "node:os";
3
3
  import { basename, dirname, join } from "node:path";
4
4
  import { classifyFailure, compactToolResultDetailsForRetention, computeRetryDelayMs, createCustomMessage, DEFAULT_RETRY_POLICY, DEFAULT_STREAM_IDLE, RetryController, sleepAbortable, withStreamIdleWatchdog, } from "@caupulican/pi-agent-core";
5
5
  import { calculateContextTokens, compact, createDeterministicCompaction, estimateContextTokens, getLatestCompactionEntry, prepareCompaction, runCompactionLoop, shouldCompact, } from "@caupulican/pi-agent-core/node";
6
- import { cleanupSessionResources, formatToolRepairStandingRule, generateTextToolProtocolPrimer, isContextOverflow, parseTextToolCalls, streamSimple, } from "@caupulican/pi-ai";
6
+ import { cleanupSessionResources, formatToolRepairStandingRule, generateTextToolProtocolPrimer, getSupportedThinkingLevels, isContextOverflow, modelsAreEqual, parseTextToolCalls, streamSimple, } from "@caupulican/pi-ai";
7
7
  import { Type } from "typebox";
8
8
  import { getAgentDir } from "../config.js";
9
9
  import { stripFrontmatter } from "../utils/frontmatter.js";
@@ -23,6 +23,7 @@ import { GatewayRegistry } from "./gateways/channel-provider.js";
23
23
  import { GoalLoopController } from "./goal-loop-controller.js";
24
24
  import { buildGoalRuntimeSnapshot, } from "./goals/goal-runtime-snapshot.js";
25
25
  import { appendGoalStateSnapshot, getLatestGoalStateSnapshot } from "./goals/session-goal-state.js";
26
+ import { constrainStreamIdleToHttpTimeout } from "./http-dispatcher.js";
26
27
  import { appendLearningDecisionSnapshot, getLearningDecisionSnapshots } from "./learning/session-learning-decision.js";
27
28
  import { isPromotedFrontmatter, SkillCurator } from "./learning/skill-curator.js";
28
29
  import { LocalRuntimeController } from "./local-runtime-controller.js";
@@ -201,7 +202,6 @@ export class AgentSession {
201
202
  _analytics;
202
203
  _treeNavigator;
203
204
  _lastCostGuardDecision;
204
- _costGuardDowngraded = false;
205
205
  /** Per-turn model-router subsystem (see model-router-controller.ts); owns the transient route/intent,
206
206
  * the cheap-turn session buffer, the escalation/retry flags, and the sticky last-decision/skip-reason
207
207
  * used by the status report. Its parallel routed drive path delegates every turn back to
@@ -251,6 +251,13 @@ export class AgentSession {
251
251
  const agentDir = config.agentDir ?? getAgentDir();
252
252
  const modelAdaptationStore = ModelAdaptationStore.forAgentDir(agentDir);
253
253
  const baseStreamFn = this.agent.streamFn;
254
+ const previousResolveRequestReasoning = this.agent.resolveRequestReasoning?.bind(this.agent);
255
+ this.agent.resolveRequestReasoning = (reasoning, request) => {
256
+ const resolvedReasoning = previousResolveRequestReasoning
257
+ ? previousResolveRequestReasoning(reasoning, request)
258
+ : reasoning;
259
+ return this._resolveCostGuardRequestReasoning(request.model, request.context, resolvedReasoning, request.maxTokens);
260
+ };
254
261
  const profiledStreamFn = withModelPerfProfile(baseStreamFn, {
255
262
  modelKey: (model) => formatModelRouterModel(model),
256
263
  recordSample: (modelKey, sample) => {
@@ -266,17 +273,16 @@ export class AgentSession {
266
273
  ...streamIdleOptionsOverride,
267
274
  };
268
275
  const httpIdleTimeoutMs = stallSettingsSource.getHttpIdleTimeoutMs();
276
+ const httpBounded = constrainStreamIdleToHttpTimeout({ ...DEFAULT_STREAM_IDLE, ...configured }, httpIdleTimeoutMs);
269
277
  const profile = modelAdaptationStore.get(formatModelRouterModel(model)).perf;
270
278
  const adaptive = resolveAdaptiveStreamIdleOptions({
271
- base: { ...DEFAULT_STREAM_IDLE, ...configured },
279
+ base: httpBounded.options,
272
280
  profile,
273
281
  promptTokens: estimateContextPromptTokens(context),
274
282
  localClass: this._isWarmableLocalModel(model),
275
- ceilingMs: httpIdleTimeoutMs === 0
276
- ? DEFAULT_ADAPTIVE_STREAM_IDLE_CEILING_MS
277
- : Math.max(DEFAULT_STREAM_IDLE.quietIdleMs, httpIdleTimeoutMs - 60_000),
283
+ ceilingMs: httpBounded.adaptiveCeilingMs ?? DEFAULT_ADAPTIVE_STREAM_IDLE_CEILING_MS,
278
284
  });
279
- return { ...configured, ...adaptive };
285
+ return { ...httpBounded.options, ...adaptive };
280
286
  }), baseStreamFn === streamSimple);
281
287
  this.sessionManager = config.sessionManager;
282
288
  this.settingsManager = config.settingsManager;
@@ -325,6 +331,8 @@ export class AgentSession {
325
331
  getToolPromptGuidelines: (name) => this._runtimeBuilder.getToolPromptGuidelines(name),
326
332
  getModelAdaptationRules: () => this._getModelAdaptationRulesForPrompt(),
327
333
  getActiveExtensions: () => this._extensionRunner.activeExtensions,
334
+ getContextWindow: () => this.model?.contextWindow,
335
+ getThinkingLevel: () => this.thinkingLevel,
328
336
  });
329
337
  this._autonomyTelemetry = new AutonomyTelemetry({
330
338
  getSessionManager: () => this.sessionManager,
@@ -350,6 +358,7 @@ export class AgentSession {
350
358
  getModelRegistry: () => this._modelRegistry,
351
359
  isModelExhausted: (model) => this._billingFailover.isExhausted(`${model.provider}/${model.id}`),
352
360
  getModel: () => this.model ?? undefined,
361
+ isDelegateToolActive: () => this.getActiveToolNames().includes("delegate"),
353
362
  getCapabilityEnvelope: () => this.capabilityEnvelope,
354
363
  getModelCapabilityProfile: () => this.getModelCapabilityProfile(),
355
364
  emit: (event) => this._emit(event),
@@ -372,6 +381,8 @@ export class AgentSession {
372
381
  getSessionId: () => this.sessionManager.getSessionId(),
373
382
  isChildSession: () => this._isChildSession,
374
383
  refreshToolRegistry: () => this._refreshToolRegistry(),
384
+ getContextWindow: () => this.model?.contextWindow,
385
+ getGoalState: () => this.getGoalStateSnapshot(),
375
386
  });
376
387
  this._compactionSupport = new CompactionSupport({
377
388
  getModel: () => this.model,
@@ -511,6 +522,9 @@ export class AgentSession {
511
522
  setUnboundToolGrantWarnings: (warnings) => {
512
523
  this._unboundToolGrantWarnings = warnings;
513
524
  },
525
+ getUnboundToolGrantWarnings: () => this._unboundToolGrantWarnings,
526
+ createProfileFilterReloadSnapshot: () => this._profileFilter.createReloadSnapshot(),
527
+ restoreProfileFilterReloadSnapshot: (snapshot) => this._profileFilter.restoreReloadSnapshot(snapshot),
514
528
  getActiveToolNames: () => this.getActiveToolNames(),
515
529
  setActiveToolsByName: (toolNames) => this.setActiveToolsByName(toolNames),
516
530
  normalizePromptSnippet: (text) => this._normalizePromptSnippet(text),
@@ -524,6 +538,8 @@ export class AgentSession {
524
538
  getMemoryManager: () => this._memory.getMemoryManager(),
525
539
  getMemoryAuditDiagnostics: () => this._memory.getMemoryAuditDiagnostics(),
526
540
  clearPendingMemoryProviders: () => this._memory.clearPendingProviders(),
541
+ createMemoryReloadSnapshot: () => this._memory.createReloadSnapshot(),
542
+ restoreMemoryReloadSnapshot: (snapshot) => this._memory.restoreReloadSnapshot(snapshot),
527
543
  initializeMemory: () => this._memory.initialize(),
528
544
  getGoalStateSnapshot: () => this.getGoalStateSnapshot(),
529
545
  saveGoalStateSnapshot: (state) => this.saveGoalStateSnapshot(state),
@@ -587,6 +603,7 @@ export class AgentSession {
587
603
  getActiveToolNames: () => this.getActiveToolNames(),
588
604
  setActiveToolsByName: (names) => this.setActiveToolsByName(names),
589
605
  getModelCapabilityProfile: () => this.getModelCapabilityProfile(),
606
+ refreshBaseSystemPrompt: () => this._refreshBaseSystemPrompt(),
590
607
  emit: (event) => this._emit(event),
591
608
  checkContextWindowUsageWarning: () => this._checkContextWindowUsageWarning(),
592
609
  deriveOllamaServerUrl: (baseUrl) => this._deriveOllamaServerUrl(baseUrl),
@@ -610,7 +627,7 @@ export class AgentSession {
610
627
  getToolProfileFilter: () => this._toolProfileFilter,
611
628
  isExplicitModel: () => this._isExplicitModel,
612
629
  isExplicitThinking: () => this._isExplicitThinking,
613
- setThinkingLevel: (level) => this.setThinkingLevel(level),
630
+ setThinkingLevel: (level) => this.setThinkingLevel(level, { persistSettings: false }),
614
631
  });
615
632
  this._toolGate = new ToolGateController({
616
633
  maybeEscalateToolCall: (toolName, args) => this._modelRouter.maybeEscalateToolCall(toolName, args),
@@ -825,43 +842,43 @@ export class AgentSession {
825
842
  // character caps are the only budget protection for this block -- load-bearing,
826
843
  // not merely defensive.
827
844
  const gcMessages = this._maybeAppendMemoryEvidenceBlock(enforcementResult.messages, memoryReport);
828
- this._applyCostGuard(gcMessages);
829
845
  return gcMessages;
830
846
  };
831
847
  }
832
848
  /**
833
- * Proactive per-turn cost guard (#34): estimate the USD cost of the about-to-be-submitted turn and,
834
- * when it exceeds the user's ceiling, record a warning decision (for the host UI to surface) and —
835
- * if configured to `downgrade` — step reasoning effort down ONCE per over-threshold episode to curb a
836
- * runaway billing spike. Disabled by default (`maxTurnUsd<=0`), so it never alters behavior unless the
837
- * user opts in. Best-effort: never throws into the turn.
849
+ * Resolve the foreground request's cost policy after routing/context conversion, when the actual
850
+ * model, full system prompt, converted messages, and tool schemas are known. The guard is a
851
+ * projection threshold rather than a hard output cap: warning mode never reduces capability, while
852
+ * opt-in downgrade changes only this request's reasoning effort. Best-effort: never throws.
838
853
  */
839
- _applyCostGuard(messages) {
854
+ _resolveCostGuardRequestReasoning(model, context, reasoning, requestMaxTokens) {
840
855
  try {
841
856
  const guard = this.settingsManager.getCostGuardSettings();
842
- if (guard.maxTurnUsd <= 0 || !this.model?.cost) {
857
+ const isChatGptSubscription = model.provider === "openai-codex" && this._modelRegistry.isUsingOAuth(model);
858
+ if (guard.maxTurnUsd <= 0 || !model.cost || isChatGptSubscription) {
843
859
  this._lastCostGuardDecision = undefined;
844
- return;
845
- }
846
- const inputTokens = this._estimateCurrentContextTokens(messages);
847
- const maxOutputTokens = this.model.maxTokens ?? 4096;
848
- const estUsd = estimateTurnCostUsd({ inputTokens, maxOutputTokens, cost: this.model.cost });
860
+ return reasoning;
861
+ }
862
+ const inputTokens = estimateContextPromptTokens(context);
863
+ // Use an explicit request cap when present; otherwise project against the session response
864
+ // reserve instead of a frontier model's theoretical 128K output maximum.
865
+ const maxOutputTokens = Math.min(model.maxTokens ?? 4096, requestMaxTokens ?? this.settingsManager.getCompactionReserveTokens());
866
+ const estUsd = estimateTurnCostUsd({
867
+ inputTokens,
868
+ maxOutputTokens,
869
+ cost: model.cost,
870
+ longContextPricing: model.longContextPricing,
871
+ });
849
872
  const decision = evaluateCostGuard(estUsd, { maxTurnUsd: guard.maxTurnUsd, action: guard.action });
850
873
  this._lastCostGuardDecision = decision;
851
- if (!decision.over) {
852
- this._costGuardDowngraded = false; // back under the ceiling — re-arm the one-shot downgrade
853
- return;
854
- }
855
- if (guard.action === "downgrade" && !this._costGuardDowngraded && this.supportsThinking()) {
856
- const next = downgradeReasoning(this.thinkingLevel);
857
- if (next !== this.thinkingLevel) {
858
- this.setThinkingLevel(next);
859
- this._costGuardDowngraded = true;
860
- }
861
- }
874
+ if (!decision.over || guard.action !== "downgrade" || reasoning === undefined)
875
+ return reasoning;
876
+ const next = downgradeReasoning(reasoning, getSupportedThinkingLevels(model), model.thinkingLevelMap);
877
+ return next;
862
878
  }
863
879
  catch {
864
880
  // cost guard must never disrupt a turn
881
+ return reasoning;
865
882
  }
866
883
  }
867
884
  /** Latest cost-guard decision (for the host footer/UI to surface a warning). Undefined if disabled. */
@@ -2096,6 +2113,13 @@ export class AgentSession {
2096
2113
  _rebuildSystemPrompt(toolNames) {
2097
2114
  return this._systemPromptBuilder.rebuildSystemPrompt(toolNames);
2098
2115
  }
2116
+ _refreshBaseSystemPrompt() {
2117
+ const previousBaseSystemPrompt = this._baseSystemPrompt;
2118
+ this._baseSystemPrompt = this._rebuildSystemPrompt(this.getActiveToolNames());
2119
+ if (this.agent.state.systemPrompt === previousBaseSystemPrompt) {
2120
+ this.agent.state.systemPrompt = this._baseSystemPrompt;
2121
+ }
2122
+ }
2099
2123
  /**
2100
2124
  * Build a system prompt for a specific tool surface WITHOUT touching the session's base prompt
2101
2125
  * state (G4 router-swap; see {@link SystemPromptBuilder.buildSystemPromptForToolNames}).
@@ -2345,7 +2369,7 @@ export class AgentSession {
2345
2369
  // (no page) when nothing is relevant — so it stays net-negative and the GC packs stale pages.
2346
2370
  if (this._memory.shouldAttemptRecall(expandedText)) {
2347
2371
  try {
2348
- const recall = await this._memory.getMemoryManager().prefetch(expandedText);
2372
+ const recall = await this._memory.prefetchRecall(expandedText);
2349
2373
  if (recall) {
2350
2374
  injectedRecall = recall;
2351
2375
  recallQuery = expandedText;
@@ -2725,6 +2749,16 @@ export class AgentSession {
2725
2749
  await this._modelSelection.setModel(model, options);
2726
2750
  this._scheduleLocalPrefixWarm(this.agent.state.model, "selection");
2727
2751
  }
2752
+ /** Re-resolve startup profile model/thinking after allowed extension providers are bound. */
2753
+ async reapplyActiveProfileModelSettings() {
2754
+ const previousModel = this.model;
2755
+ await this._profileFilter.reapplyActiveProfileModelSettings();
2756
+ const activeToolNames = this._requestedActiveToolNames ?? this.getActiveToolNames();
2757
+ this._refreshToolRegistry({ activeToolNames, includeAllExtensionTools: true });
2758
+ if (!modelsAreEqual(previousModel, this.model)) {
2759
+ this._scheduleLocalPrefixWarm(this.model, "selection");
2760
+ }
2761
+ }
2728
2762
  async cycleModel(direction = "forward") {
2729
2763
  const result = await this._modelSelection.cycleModel(direction);
2730
2764
  this._scheduleLocalPrefixWarm(result?.model, "selection");
@@ -3422,6 +3456,7 @@ export class AgentSession {
3422
3456
  setThinkingLevel: (level) => this.setThinkingLevel(level),
3423
3457
  getExternalResourceRoots: () => this.settingsManager.getEffectiveExternalResourceRoots(),
3424
3458
  registerMemoryProvider: (provider) => this.registerMemoryProvider(provider),
3459
+ registerContextMemoryProvider: (provider) => this.registerContextMemoryProvider(provider),
3425
3460
  reportSpawnedUsage: (usage, opts) => {
3426
3461
  this.addSpawnedUsage(usage, opts);
3427
3462
  },
@@ -3482,6 +3517,9 @@ export class AgentSession {
3482
3517
  registerMemoryProvider(provider) {
3483
3518
  this._memory.registerMemoryProvider(provider);
3484
3519
  }
3520
+ registerContextMemoryProvider(provider) {
3521
+ this._memory.registerContextMemoryProvider(provider);
3522
+ }
3485
3523
  /** R8: the gateway/scheduler registry. A deployment runner registers providers and drives start/stop. */
3486
3524
  get gateways() {
3487
3525
  return this._gatewayRegistry;