@caupulican/pi-adaptative 0.81.26 → 0.81.29

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 (286) hide show
  1. package/CHANGELOG.md +45 -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 +30 -12
  10. package/dist/core/agent-session.d.ts.map +1 -1
  11. package/dist/core/agent-session.js +128 -36
  12. package/dist/core/agent-session.js.map +1 -1
  13. package/dist/core/auth-storage.d.ts +6 -0
  14. package/dist/core/auth-storage.d.ts.map +1 -1
  15. package/dist/core/auth-storage.js +35 -0
  16. package/dist/core/auth-storage.js.map +1 -1
  17. package/dist/core/autonomy/bounded-completion.d.ts.map +1 -1
  18. package/dist/core/autonomy/bounded-completion.js +59 -19
  19. package/dist/core/autonomy/bounded-completion.js.map +1 -1
  20. package/dist/core/autonomy/contracts.d.ts +2 -0
  21. package/dist/core/autonomy/contracts.d.ts.map +1 -1
  22. package/dist/core/autonomy/contracts.js.map +1 -1
  23. package/dist/core/autonomy/lane-tool-surface.d.ts +31 -0
  24. package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -0
  25. package/dist/core/autonomy/lane-tool-surface.js +96 -0
  26. package/dist/core/autonomy/lane-tool-surface.js.map +1 -0
  27. package/dist/core/autonomy/lane-tracker.d.ts +5 -0
  28. package/dist/core/autonomy/lane-tracker.d.ts.map +1 -1
  29. package/dist/core/autonomy/lane-tracker.js +14 -3
  30. package/dist/core/autonomy/lane-tracker.js.map +1 -1
  31. package/dist/core/background-lane-controller.d.ts +28 -4
  32. package/dist/core/background-lane-controller.d.ts.map +1 -1
  33. package/dist/core/background-lane-controller.js +237 -28
  34. package/dist/core/background-lane-controller.js.map +1 -1
  35. package/dist/core/billing-failover-controller.d.ts.map +1 -1
  36. package/dist/core/billing-failover-controller.js +1 -1
  37. package/dist/core/billing-failover-controller.js.map +1 -1
  38. package/dist/core/context/current-work-memory.d.ts +9 -0
  39. package/dist/core/context/current-work-memory.d.ts.map +1 -0
  40. package/dist/core/context/current-work-memory.js +61 -0
  41. package/dist/core/context/current-work-memory.js.map +1 -0
  42. package/dist/core/context/file-store-memory-provider.d.ts +9 -0
  43. package/dist/core/context/file-store-memory-provider.d.ts.map +1 -0
  44. package/dist/core/context/file-store-memory-provider.js +106 -0
  45. package/dist/core/context/file-store-memory-provider.js.map +1 -0
  46. package/dist/core/context/long-term-memory-trigger.d.ts +15 -0
  47. package/dist/core/context/long-term-memory-trigger.d.ts.map +1 -0
  48. package/dist/core/context/long-term-memory-trigger.js +39 -0
  49. package/dist/core/context/long-term-memory-trigger.js.map +1 -0
  50. package/dist/core/context/memory-prompt-block.d.ts +3 -1
  51. package/dist/core/context/memory-prompt-block.d.ts.map +1 -1
  52. package/dist/core/context/memory-prompt-block.js +20 -3
  53. package/dist/core/context/memory-prompt-block.js.map +1 -1
  54. package/dist/core/context/memory-prompt-budget.d.ts +17 -0
  55. package/dist/core/context/memory-prompt-budget.d.ts.map +1 -0
  56. package/dist/core/context/memory-prompt-budget.js +64 -0
  57. package/dist/core/context/memory-prompt-budget.js.map +1 -0
  58. package/dist/core/context/memory-provider-contract.d.ts.map +1 -1
  59. package/dist/core/context/memory-provider-contract.js +2 -5
  60. package/dist/core/context/memory-provider-contract.js.map +1 -1
  61. package/dist/core/context/memory-tier-composer.d.ts +27 -0
  62. package/dist/core/context/memory-tier-composer.d.ts.map +1 -0
  63. package/dist/core/context/memory-tier-composer.js +79 -0
  64. package/dist/core/context/memory-tier-composer.js.map +1 -0
  65. package/dist/core/context-gc.d.ts.map +1 -1
  66. package/dist/core/context-gc.js +2 -0
  67. package/dist/core/context-gc.js.map +1 -1
  68. package/dist/core/context-pipeline.d.ts +5 -3
  69. package/dist/core/context-pipeline.d.ts.map +1 -1
  70. package/dist/core/context-pipeline.js +15 -5
  71. package/dist/core/context-pipeline.js.map +1 -1
  72. package/dist/core/cost/cost-summary.d.ts +3 -1
  73. package/dist/core/cost/cost-summary.d.ts.map +1 -1
  74. package/dist/core/cost/cost-summary.js +3 -3
  75. package/dist/core/cost/cost-summary.js.map +1 -1
  76. package/dist/core/cost-guard.d.ts +17 -7
  77. package/dist/core/cost-guard.d.ts.map +1 -1
  78. package/dist/core/cost-guard.js +33 -10
  79. package/dist/core/cost-guard.js.map +1 -1
  80. package/dist/core/default-tool-surface.d.ts +9 -0
  81. package/dist/core/default-tool-surface.d.ts.map +1 -0
  82. package/dist/core/default-tool-surface.js +18 -0
  83. package/dist/core/default-tool-surface.js.map +1 -0
  84. package/dist/core/delegation/worker-result.d.ts.map +1 -1
  85. package/dist/core/delegation/worker-result.js +3 -0
  86. package/dist/core/delegation/worker-result.js.map +1 -1
  87. package/dist/core/delegation/worker-runner.d.ts +11 -5
  88. package/dist/core/delegation/worker-runner.d.ts.map +1 -1
  89. package/dist/core/delegation/worker-runner.js +77 -16
  90. package/dist/core/delegation/worker-runner.js.map +1 -1
  91. package/dist/core/extensions/loader.d.ts.map +1 -1
  92. package/dist/core/extensions/loader.js +15 -0
  93. package/dist/core/extensions/loader.js.map +1 -1
  94. package/dist/core/extensions/runner.d.ts +2 -0
  95. package/dist/core/extensions/runner.d.ts.map +1 -1
  96. package/dist/core/extensions/runner.js +7 -0
  97. package/dist/core/extensions/runner.js.map +1 -1
  98. package/dist/core/extensions/types.d.ts +9 -0
  99. package/dist/core/extensions/types.d.ts.map +1 -1
  100. package/dist/core/extensions/types.js.map +1 -1
  101. package/dist/core/failure-corpus.d.ts.map +1 -1
  102. package/dist/core/failure-corpus.js +2 -4
  103. package/dist/core/failure-corpus.js.map +1 -1
  104. package/dist/core/footer-data-provider.d.ts.map +1 -1
  105. package/dist/core/footer-data-provider.js +9 -1
  106. package/dist/core/footer-data-provider.js.map +1 -1
  107. package/dist/core/goals/goal-continuation-prompt.d.ts.map +1 -1
  108. package/dist/core/goals/goal-continuation-prompt.js +4 -3
  109. package/dist/core/goals/goal-continuation-prompt.js.map +1 -1
  110. package/dist/core/http-dispatcher.d.ts +12 -0
  111. package/dist/core/http-dispatcher.d.ts.map +1 -1
  112. package/dist/core/http-dispatcher.js +42 -4
  113. package/dist/core/http-dispatcher.js.map +1 -1
  114. package/dist/core/local-runtime-controller.d.ts +16 -0
  115. package/dist/core/local-runtime-controller.d.ts.map +1 -1
  116. package/dist/core/local-runtime-controller.js +107 -28
  117. package/dist/core/local-runtime-controller.js.map +1 -1
  118. package/dist/core/memory/memory-manager.d.ts +8 -3
  119. package/dist/core/memory/memory-manager.d.ts.map +1 -1
  120. package/dist/core/memory/memory-manager.js +27 -11
  121. package/dist/core/memory/memory-manager.js.map +1 -1
  122. package/dist/core/memory/memory-provider.d.ts +5 -1
  123. package/dist/core/memory/memory-provider.d.ts.map +1 -1
  124. package/dist/core/memory/memory-provider.js.map +1 -1
  125. package/dist/core/memory/providers/file-store.d.ts +3 -1
  126. package/dist/core/memory/providers/file-store.d.ts.map +1 -1
  127. package/dist/core/memory/providers/file-store.js +7 -2
  128. package/dist/core/memory/providers/file-store.js.map +1 -1
  129. package/dist/core/memory/providers/transcript-recall.d.ts +1 -0
  130. package/dist/core/memory/providers/transcript-recall.d.ts.map +1 -1
  131. package/dist/core/memory/providers/transcript-recall.js +4 -7
  132. package/dist/core/memory/providers/transcript-recall.js.map +1 -1
  133. package/dist/core/memory-controller.d.ts +36 -10
  134. package/dist/core/memory-controller.d.ts.map +1 -1
  135. package/dist/core/memory-controller.js +137 -21
  136. package/dist/core/memory-controller.js.map +1 -1
  137. package/dist/core/model-registry.d.ts +25 -0
  138. package/dist/core/model-registry.d.ts.map +1 -1
  139. package/dist/core/model-registry.js +91 -8
  140. package/dist/core/model-registry.js.map +1 -1
  141. package/dist/core/model-resolver.d.ts.map +1 -1
  142. package/dist/core/model-resolver.js +30 -11
  143. package/dist/core/model-resolver.js.map +1 -1
  144. package/dist/core/model-router-controller.d.ts.map +1 -1
  145. package/dist/core/model-router-controller.js +33 -29
  146. package/dist/core/model-router-controller.js.map +1 -1
  147. package/dist/core/model-selection-controller.d.ts +3 -0
  148. package/dist/core/model-selection-controller.d.ts.map +1 -1
  149. package/dist/core/model-selection-controller.js +8 -1
  150. package/dist/core/model-selection-controller.js.map +1 -1
  151. package/dist/core/models/local-runtime.d.ts +2 -0
  152. package/dist/core/models/local-runtime.d.ts.map +1 -1
  153. package/dist/core/models/local-runtime.js +10 -4
  154. package/dist/core/models/local-runtime.js.map +1 -1
  155. package/dist/core/models/perf-profile.d.ts.map +1 -1
  156. package/dist/core/models/perf-profile.js +95 -33
  157. package/dist/core/models/perf-profile.js.map +1 -1
  158. package/dist/core/models/runtime-arbiter.d.ts +11 -0
  159. package/dist/core/models/runtime-arbiter.d.ts.map +1 -1
  160. package/dist/core/models/runtime-arbiter.js +35 -13
  161. package/dist/core/models/runtime-arbiter.js.map +1 -1
  162. package/dist/core/profile-filter-controller.d.ts +11 -0
  163. package/dist/core/profile-filter-controller.d.ts.map +1 -1
  164. package/dist/core/profile-filter-controller.js +56 -11
  165. package/dist/core/profile-filter-controller.js.map +1 -1
  166. package/dist/core/profile-registry.d.ts +2 -2
  167. package/dist/core/profile-registry.d.ts.map +1 -1
  168. package/dist/core/profile-registry.js +58 -7
  169. package/dist/core/profile-registry.js.map +1 -1
  170. package/dist/core/reflection-controller.d.ts +9 -7
  171. package/dist/core/reflection-controller.d.ts.map +1 -1
  172. package/dist/core/reflection-controller.js +81 -12
  173. package/dist/core/reflection-controller.js.map +1 -1
  174. package/dist/core/research/research-runner.d.ts +2 -2
  175. package/dist/core/research/research-runner.d.ts.map +1 -1
  176. package/dist/core/research/research-runner.js +8 -6
  177. package/dist/core/research/research-runner.js.map +1 -1
  178. package/dist/core/resource-loader.d.ts +4 -2
  179. package/dist/core/resource-loader.d.ts.map +1 -1
  180. package/dist/core/resource-loader.js +11 -1
  181. package/dist/core/resource-loader.js.map +1 -1
  182. package/dist/core/runtime-builder.d.ts +30 -3
  183. package/dist/core/runtime-builder.d.ts.map +1 -1
  184. package/dist/core/runtime-builder.js +140 -40
  185. package/dist/core/runtime-builder.js.map +1 -1
  186. package/dist/core/sdk.d.ts +8 -7
  187. package/dist/core/sdk.d.ts.map +1 -1
  188. package/dist/core/sdk.js +38 -5
  189. package/dist/core/sdk.js.map +1 -1
  190. package/dist/core/security/secret-text.d.ts +3 -0
  191. package/dist/core/security/secret-text.d.ts.map +1 -0
  192. package/dist/core/security/secret-text.js +26 -0
  193. package/dist/core/security/secret-text.js.map +1 -0
  194. package/dist/core/settings-manager.d.ts +59 -17
  195. package/dist/core/settings-manager.d.ts.map +1 -1
  196. package/dist/core/settings-manager.js +300 -51
  197. package/dist/core/settings-manager.js.map +1 -1
  198. package/dist/core/skills.d.ts.map +1 -1
  199. package/dist/core/skills.js +1 -1
  200. package/dist/core/skills.js.map +1 -1
  201. package/dist/core/system-prompt-builder.d.ts +7 -0
  202. package/dist/core/system-prompt-builder.d.ts.map +1 -1
  203. package/dist/core/system-prompt-builder.js +23 -1
  204. package/dist/core/system-prompt-builder.js.map +1 -1
  205. package/dist/core/tool-gate-controller.d.ts +3 -0
  206. package/dist/core/tool-gate-controller.d.ts.map +1 -1
  207. package/dist/core/tool-gate-controller.js +20 -15
  208. package/dist/core/tool-gate-controller.js.map +1 -1
  209. package/dist/core/tool-selection/expected-utility.d.ts +51 -0
  210. package/dist/core/tool-selection/expected-utility.d.ts.map +1 -0
  211. package/dist/core/tool-selection/expected-utility.js +85 -0
  212. package/dist/core/tool-selection/expected-utility.js.map +1 -0
  213. package/dist/core/tool-selection/tool-performance-store.d.ts +82 -0
  214. package/dist/core/tool-selection/tool-performance-store.d.ts.map +1 -0
  215. package/dist/core/tool-selection/tool-performance-store.js +249 -0
  216. package/dist/core/tool-selection/tool-performance-store.js.map +1 -0
  217. package/dist/core/tool-selection/tool-selection-controller.d.ts +41 -0
  218. package/dist/core/tool-selection/tool-selection-controller.d.ts.map +1 -0
  219. package/dist/core/tool-selection/tool-selection-controller.js +199 -0
  220. package/dist/core/tool-selection/tool-selection-controller.js.map +1 -0
  221. package/dist/core/tools/delegate-status.d.ts +9 -0
  222. package/dist/core/tools/delegate-status.d.ts.map +1 -0
  223. package/dist/core/tools/delegate-status.js +52 -0
  224. package/dist/core/tools/delegate-status.js.map +1 -0
  225. package/dist/core/tools/delegate.d.ts +10 -0
  226. package/dist/core/tools/delegate.d.ts.map +1 -1
  227. package/dist/core/tools/delegate.js +36 -13
  228. package/dist/core/tools/delegate.js.map +1 -1
  229. package/dist/core/tools/run-toolkit-script.d.ts +3 -0
  230. package/dist/core/tools/run-toolkit-script.d.ts.map +1 -1
  231. package/dist/core/tools/run-toolkit-script.js +17 -7
  232. package/dist/core/tools/run-toolkit-script.js.map +1 -1
  233. package/dist/main.d.ts.map +1 -1
  234. package/dist/main.js +2 -0
  235. package/dist/main.js.map +1 -1
  236. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  237. package/dist/modes/interactive/components/footer.js +8 -1
  238. package/dist/modes/interactive/components/footer.js.map +1 -1
  239. package/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  240. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  241. package/dist/modes/interactive/components/settings-selector.js +69 -29
  242. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  243. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  244. package/dist/modes/interactive/components/thinking-selector.js +2 -0
  245. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  246. package/dist/modes/interactive/config-backup.d.ts +7 -1
  247. package/dist/modes/interactive/config-backup.d.ts.map +1 -1
  248. package/dist/modes/interactive/config-backup.js +196 -32
  249. package/dist/modes/interactive/config-backup.js.map +1 -1
  250. package/dist/modes/interactive/interactive-mode.d.ts +1 -1
  251. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  252. package/dist/modes/interactive/interactive-mode.js +22 -28
  253. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  254. package/dist/modes/interactive/local-model-commands.d.ts.map +1 -1
  255. package/dist/modes/interactive/local-model-commands.js +2 -0
  256. package/dist/modes/interactive/local-model-commands.js.map +1 -1
  257. package/dist/modes/interactive/profile-menu-controller.d.ts +6 -4
  258. package/dist/modes/interactive/profile-menu-controller.d.ts.map +1 -1
  259. package/dist/modes/interactive/profile-menu-controller.js +248 -65
  260. package/dist/modes/interactive/profile-menu-controller.js.map +1 -1
  261. package/dist/modes/interactive/report-commands.d.ts.map +1 -1
  262. package/dist/modes/interactive/report-commands.js +8 -2
  263. package/dist/modes/interactive/report-commands.js.map +1 -1
  264. package/dist/modes/interactive/settings-selector-flow.d.ts.map +1 -1
  265. package/dist/modes/interactive/settings-selector-flow.js +8 -0
  266. package/dist/modes/interactive/settings-selector-flow.js.map +1 -1
  267. package/dist/modes/interactive/theme/theme-schema.json +1 -1
  268. package/dist/modes/interactive/theme/theme.d.ts +1 -1
  269. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  270. package/dist/modes/interactive/theme/theme.js +3 -1
  271. package/dist/modes/interactive/theme/theme.js.map +1 -1
  272. package/docs/extensions.md +32 -0
  273. package/docs/integration-sweep-builder-blueprint-2026-07-09.md +365 -0
  274. package/docs/integration-sweep-resume-2026-07-09.md +407 -0
  275. package/docs/resources.md +15 -7
  276. package/docs/settings.md +56 -5
  277. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  278. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  279. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  280. package/examples/extensions/preset.ts +2 -2
  281. package/examples/extensions/sandbox/package-lock.json +2 -2
  282. package/examples/extensions/sandbox/package.json +1 -1
  283. package/examples/extensions/with-deps/package-lock.json +2 -2
  284. package/examples/extensions/with-deps/package.json +1 -1
  285. package/npm-shrinkwrap.json +44 -35
  286. package/package.json +4 -4
@@ -3,12 +3,13 @@ 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";
10
10
  import { formatNoApiKeyFoundMessage, formatNoModelSelectedMessage } from "./auth-guidance.js";
11
11
  import { buildForegroundEnvelope, formatForegroundEnvelopeObservation } from "./autonomy/foreground-envelope.js";
12
+ import { evaluateToolGate } from "./autonomy/gates.js";
12
13
  import { AutonomyTelemetry } from "./autonomy-telemetry.js";
13
14
  import { BackgroundLaneController } from "./background-lane-controller.js";
14
15
  import { BashExecutionController } from "./bash-execution-controller.js";
@@ -23,6 +24,7 @@ import { GatewayRegistry } from "./gateways/channel-provider.js";
23
24
  import { GoalLoopController } from "./goal-loop-controller.js";
24
25
  import { buildGoalRuntimeSnapshot, } from "./goals/goal-runtime-snapshot.js";
25
26
  import { appendGoalStateSnapshot, getLatestGoalStateSnapshot } from "./goals/session-goal-state.js";
27
+ import { constrainStreamIdleToHttpTimeout } from "./http-dispatcher.js";
26
28
  import { appendLearningDecisionSnapshot, getLearningDecisionSnapshots } from "./learning/session-learning-decision.js";
27
29
  import { isPromotedFrontmatter, SkillCurator } from "./learning/skill-curator.js";
28
30
  import { LocalRuntimeController } from "./local-runtime-controller.js";
@@ -48,6 +50,8 @@ import { TOOL_RECOVERY_EVENT_LOG_FILE } from "./tool-recovery-log-records.js";
48
50
  import { ToolRecoveryLogger } from "./tool-recovery-logger.js";
49
51
  import { formatToolRepairHealthReport } from "./tool-repair-health.js";
50
52
  import { resolveCurrentToolRepairSettings } from "./tool-repair-settings.js";
53
+ import { ToolPerformanceStore } from "./tool-selection/tool-performance-store.js";
54
+ import { ToolSelectionController } from "./tool-selection/tool-selection-controller.js";
51
55
  // ============================================================================
52
56
  // Stream-idle watchdog wiring
53
57
  // ============================================================================
@@ -153,6 +157,7 @@ export class AgentSession {
153
157
  _bash;
154
158
  _profileFilter;
155
159
  _toolGate;
160
+ _toolSelection;
156
161
  _extensionRunner;
157
162
  _turnIndex = 0;
158
163
  _currentForegroundEnvelope;
@@ -201,7 +206,6 @@ export class AgentSession {
201
206
  _analytics;
202
207
  _treeNavigator;
203
208
  _lastCostGuardDecision;
204
- _costGuardDowngraded = false;
205
209
  /** Per-turn model-router subsystem (see model-router-controller.ts); owns the transient route/intent,
206
210
  * the cheap-turn session buffer, the escalation/retry flags, and the sticky last-decision/skip-reason
207
211
  * used by the status report. Its parallel routed drive path delegates every turn back to
@@ -251,6 +255,13 @@ export class AgentSession {
251
255
  const agentDir = config.agentDir ?? getAgentDir();
252
256
  const modelAdaptationStore = ModelAdaptationStore.forAgentDir(agentDir);
253
257
  const baseStreamFn = this.agent.streamFn;
258
+ const previousResolveRequestReasoning = this.agent.resolveRequestReasoning?.bind(this.agent);
259
+ this.agent.resolveRequestReasoning = (reasoning, request) => {
260
+ const resolvedReasoning = previousResolveRequestReasoning
261
+ ? previousResolveRequestReasoning(reasoning, request)
262
+ : reasoning;
263
+ return this._resolveCostGuardRequestReasoning(request.model, request.context, resolvedReasoning, request.maxTokens);
264
+ };
254
265
  const profiledStreamFn = withModelPerfProfile(baseStreamFn, {
255
266
  modelKey: (model) => formatModelRouterModel(model),
256
267
  recordSample: (modelKey, sample) => {
@@ -266,17 +277,16 @@ export class AgentSession {
266
277
  ...streamIdleOptionsOverride,
267
278
  };
268
279
  const httpIdleTimeoutMs = stallSettingsSource.getHttpIdleTimeoutMs();
280
+ const httpBounded = constrainStreamIdleToHttpTimeout({ ...DEFAULT_STREAM_IDLE, ...configured }, httpIdleTimeoutMs);
269
281
  const profile = modelAdaptationStore.get(formatModelRouterModel(model)).perf;
270
282
  const adaptive = resolveAdaptiveStreamIdleOptions({
271
- base: { ...DEFAULT_STREAM_IDLE, ...configured },
283
+ base: httpBounded.options,
272
284
  profile,
273
285
  promptTokens: estimateContextPromptTokens(context),
274
286
  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),
287
+ ceilingMs: httpBounded.adaptiveCeilingMs ?? DEFAULT_ADAPTIVE_STREAM_IDLE_CEILING_MS,
278
288
  });
279
- return { ...configured, ...adaptive };
289
+ return { ...httpBounded.options, ...adaptive };
280
290
  }), baseStreamFn === streamSimple);
281
291
  this.sessionManager = config.sessionManager;
282
292
  this.settingsManager = config.settingsManager;
@@ -325,6 +335,8 @@ export class AgentSession {
325
335
  getToolPromptGuidelines: (name) => this._runtimeBuilder.getToolPromptGuidelines(name),
326
336
  getModelAdaptationRules: () => this._getModelAdaptationRulesForPrompt(),
327
337
  getActiveExtensions: () => this._extensionRunner.activeExtensions,
338
+ getContextWindow: () => this.model?.contextWindow,
339
+ getThinkingLevel: () => this.thinkingLevel,
328
340
  });
329
341
  this._autonomyTelemetry = new AutonomyTelemetry({
330
342
  getSessionManager: () => this.sessionManager,
@@ -350,6 +362,7 @@ export class AgentSession {
350
362
  getModelRegistry: () => this._modelRegistry,
351
363
  isModelExhausted: (model) => this._billingFailover.isExhausted(`${model.provider}/${model.id}`),
352
364
  getModel: () => this.model ?? undefined,
365
+ isDelegateToolActive: () => this.getActiveToolNames().includes("delegate"),
353
366
  getCapabilityEnvelope: () => this.capabilityEnvelope,
354
367
  getModelCapabilityProfile: () => this.getModelCapabilityProfile(),
355
368
  emit: (event) => this._emit(event),
@@ -372,6 +385,8 @@ export class AgentSession {
372
385
  getSessionId: () => this.sessionManager.getSessionId(),
373
386
  isChildSession: () => this._isChildSession,
374
387
  refreshToolRegistry: () => this._refreshToolRegistry(),
388
+ getContextWindow: () => this.model?.contextWindow,
389
+ getGoalState: () => this.getGoalStateSnapshot(),
375
390
  });
376
391
  this._compactionSupport = new CompactionSupport({
377
392
  getModel: () => this.model,
@@ -391,6 +406,7 @@ export class AgentSession {
391
406
  getSessionManager: () => this.sessionManager,
392
407
  getSettingsManager: () => this.settingsManager,
393
408
  getModelRegistry: () => this._modelRegistry,
409
+ getModel: () => this.model,
394
410
  getAgentDir: () => this._agentDir,
395
411
  getCwd: () => this._cwd,
396
412
  getActiveToolNames: () => this.getActiveToolNames(),
@@ -454,6 +470,7 @@ export class AgentSession {
454
470
  getReflectionSignal: () => this._reflectionAbort.signal,
455
471
  archivePromotedSkill: (name) => this.archivePromotedSkill(name),
456
472
  emitAutonomyTelemetry: (event) => this._emitAutonomyTelemetry(event),
473
+ ensureModelReady: (model) => this._localRuntimeController.ensureIsolatedModelReady(model),
457
474
  addSpawnedUsage: (usage, opts) => this.addSpawnedUsage(usage, opts),
458
475
  saveLearningDecisionSnapshot: (decision) => this.saveLearningDecisionSnapshot(decision),
459
476
  });
@@ -511,6 +528,9 @@ export class AgentSession {
511
528
  setUnboundToolGrantWarnings: (warnings) => {
512
529
  this._unboundToolGrantWarnings = warnings;
513
530
  },
531
+ getUnboundToolGrantWarnings: () => this._unboundToolGrantWarnings,
532
+ createProfileFilterReloadSnapshot: () => this._profileFilter.createReloadSnapshot(),
533
+ restoreProfileFilterReloadSnapshot: (snapshot) => this._profileFilter.restoreReloadSnapshot(snapshot),
514
534
  getActiveToolNames: () => this.getActiveToolNames(),
515
535
  setActiveToolsByName: (toolNames) => this.setActiveToolsByName(toolNames),
516
536
  normalizePromptSnippet: (text) => this._normalizePromptSnippet(text),
@@ -524,10 +544,15 @@ export class AgentSession {
524
544
  getMemoryManager: () => this._memory.getMemoryManager(),
525
545
  getMemoryAuditDiagnostics: () => this._memory.getMemoryAuditDiagnostics(),
526
546
  clearPendingMemoryProviders: () => this._memory.clearPendingProviders(),
547
+ createMemoryReloadSnapshot: () => this._memory.createReloadSnapshot(),
548
+ restoreMemoryReloadSnapshot: (snapshot) => this._memory.restoreReloadSnapshot(snapshot),
527
549
  initializeMemory: () => this._memory.initialize(),
528
550
  getGoalStateSnapshot: () => this.getGoalStateSnapshot(),
529
551
  saveGoalStateSnapshot: (state) => this.saveGoalStateSnapshot(state),
530
552
  getContextGcReport: (messages) => this.getContextGcReport(messages),
553
+ startWorkerDelegation: (request) => this._backgroundLanes.startWorkerDelegation(request),
554
+ getWorkerLaneRecords: () => this._backgroundLanes.getLaneRecords(),
555
+ getWorkerResultSnapshots: () => this.getWorkerResultSnapshots(),
531
556
  runWorkerDelegationOnce: (request) => this.runWorkerDelegationOnce(request),
532
557
  runModelFitness: (args) => this.runModelFitness(args),
533
558
  resolveCurationModelIfFit: () => this._resolveCurationModelIfFit(),
@@ -554,6 +579,9 @@ export class AgentSession {
554
579
  const previousToolArgumentValidation = this.agent.onToolArgumentValidation;
555
580
  this.agent.onToolArgumentValidation = (event) => {
556
581
  const taggedEvent = this._tagModelAdaptationRuleTeaching(event);
582
+ if (taggedEvent.outcome === "repaired" || taggedEvent.outcome === "bounced") {
583
+ this._toolSelection.recordValidation(taggedEvent.tool, taggedEvent.outcome);
584
+ }
557
585
  previousToolArgumentValidation?.(taggedEvent);
558
586
  const logRecord = this._toolRecoveryLogger.recordToolArgumentValidation(taggedEvent);
559
587
  if (!logRecord)
@@ -587,6 +615,7 @@ export class AgentSession {
587
615
  getActiveToolNames: () => this.getActiveToolNames(),
588
616
  setActiveToolsByName: (names) => this.setActiveToolsByName(names),
589
617
  getModelCapabilityProfile: () => this.getModelCapabilityProfile(),
618
+ refreshBaseSystemPrompt: () => this._refreshBaseSystemPrompt(),
590
619
  emit: (event) => this._emit(event),
591
620
  checkContextWindowUsageWarning: () => this._checkContextWindowUsageWarning(),
592
621
  deriveOllamaServerUrl: (baseUrl) => this._deriveOllamaServerUrl(baseUrl),
@@ -610,7 +639,35 @@ export class AgentSession {
610
639
  getToolProfileFilter: () => this._toolProfileFilter,
611
640
  isExplicitModel: () => this._isExplicitModel,
612
641
  isExplicitThinking: () => this._isExplicitThinking,
613
- setThinkingLevel: (level) => this.setThinkingLevel(level),
642
+ setThinkingLevel: (level) => this.setThinkingLevel(level, { persistSettings: false }),
643
+ });
644
+ this._toolSelection = new ToolSelectionController({
645
+ store: ToolPerformanceStore.forAgentDir(this._agentDir),
646
+ getModelRef: () => {
647
+ const model = this.model;
648
+ return model ? formatModelRouterModel(model) : "unknown";
649
+ },
650
+ getActiveTools: () => {
651
+ const activeNames = new Set(this.getActiveToolNames());
652
+ return this.getAllTools()
653
+ .filter((tool) => activeNames.has(tool.name))
654
+ .map((tool) => ({
655
+ name: tool.name,
656
+ description: tool.description,
657
+ parameters: tool.parameters,
658
+ }));
659
+ },
660
+ isCandidateAllowed: (toolName) => {
661
+ const envelope = this.capabilityEnvelope;
662
+ if (!envelope)
663
+ return true;
664
+ return (evaluateToolGate({
665
+ toolName,
666
+ args: {},
667
+ cwd: this._cwd,
668
+ envelope,
669
+ }).outcome === "allow");
670
+ },
614
671
  });
615
672
  this._toolGate = new ToolGateController({
616
673
  maybeEscalateToolCall: (toolName, args) => this._modelRouter.maybeEscalateToolCall(toolName, args),
@@ -618,6 +675,7 @@ export class AgentSession {
618
675
  getCapabilityEnvelope: () => this.capabilityEnvelope,
619
676
  recordGateOutcome: (outcome) => this._recordGateOutcome(outcome),
620
677
  getExtensionRunner: () => this._extensionRunner,
678
+ getToolSelectionController: () => this._toolSelection,
621
679
  });
622
680
  // Always subscribe to agent events for internal handling
623
681
  // (session persistence, extensions, auto-compaction, retry logic)
@@ -825,43 +883,43 @@ export class AgentSession {
825
883
  // character caps are the only budget protection for this block -- load-bearing,
826
884
  // not merely defensive.
827
885
  const gcMessages = this._maybeAppendMemoryEvidenceBlock(enforcementResult.messages, memoryReport);
828
- this._applyCostGuard(gcMessages);
829
886
  return gcMessages;
830
887
  };
831
888
  }
832
889
  /**
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.
890
+ * Resolve the foreground request's cost policy after routing/context conversion, when the actual
891
+ * model, full system prompt, converted messages, and tool schemas are known. The guard is a
892
+ * projection threshold rather than a hard output cap: warning mode never reduces capability, while
893
+ * opt-in downgrade changes only this request's reasoning effort. Best-effort: never throws.
838
894
  */
839
- _applyCostGuard(messages) {
895
+ _resolveCostGuardRequestReasoning(model, context, reasoning, requestMaxTokens) {
840
896
  try {
841
897
  const guard = this.settingsManager.getCostGuardSettings();
842
- if (guard.maxTurnUsd <= 0 || !this.model?.cost) {
898
+ const isChatGptSubscription = model.provider === "openai-codex" && this._modelRegistry.isUsingOAuth(model);
899
+ if (guard.maxTurnUsd <= 0 || !model.cost || isChatGptSubscription) {
843
900
  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 });
901
+ return reasoning;
902
+ }
903
+ const inputTokens = estimateContextPromptTokens(context);
904
+ // Use an explicit request cap when present; otherwise project against the session response
905
+ // reserve instead of a frontier model's theoretical 128K output maximum.
906
+ const maxOutputTokens = Math.min(model.maxTokens ?? 4096, requestMaxTokens ?? this.settingsManager.getCompactionReserveTokens());
907
+ const estUsd = estimateTurnCostUsd({
908
+ inputTokens,
909
+ maxOutputTokens,
910
+ cost: model.cost,
911
+ longContextPricing: model.longContextPricing,
912
+ });
849
913
  const decision = evaluateCostGuard(estUsd, { maxTurnUsd: guard.maxTurnUsd, action: guard.action });
850
914
  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
- }
915
+ if (!decision.over || guard.action !== "downgrade" || reasoning === undefined)
916
+ return reasoning;
917
+ const next = downgradeReasoning(reasoning, getSupportedThinkingLevels(model), model.thinkingLevelMap);
918
+ return next;
862
919
  }
863
920
  catch {
864
921
  // cost guard must never disrupt a turn
922
+ return reasoning;
865
923
  }
866
924
  }
867
925
  /** Latest cost-guard decision (for the host footer/UI to surface a warning). Undefined if disabled. */
@@ -1735,6 +1793,7 @@ export class AgentSession {
1735
1793
  await this._extensionRunner.emit({ type: "agent_end", messages: event.messages });
1736
1794
  }
1737
1795
  else if (event.type === "turn_start") {
1796
+ this._toolSelection.startTurn();
1738
1797
  this._refreshForegroundEnvelope();
1739
1798
  const extensionEvent = {
1740
1799
  type: "turn_start",
@@ -2001,8 +2060,9 @@ export class AgentSession {
2001
2060
  * Also rebuilds the system prompt to reflect the new tool set.
2002
2061
  * Changes take effect on the next agent turn.
2003
2062
  *
2004
- * artifact_retrieve is auto-activated as a companion whenever grep or find ends up
2005
- * in the resulting active set and artifact_retrieve is registered (i.e. not excluded/
2063
+ * artifact_retrieve is auto-activated as a companion whenever an artifact-producing tool
2064
+ * (grep, find, or run_toolkit_script) ends up in the resulting active set and artifact_retrieve
2065
+ * is registered (i.e. not excluded/
2006
2066
  * blocked/outside an allowlist -- the registry itself is built with that same filter,
2007
2067
  * so registry presence already tracks "allowed"). This is enforced here, not just in
2008
2068
  * the settings/profile refresh flow, because this method is a public, extension-
@@ -2033,9 +2093,14 @@ export class AgentSession {
2033
2093
  for (const name of capabilityFiltered) {
2034
2094
  addIfRegistered(name);
2035
2095
  }
2036
- if (validToolNames.includes("grep") || validToolNames.includes("find")) {
2096
+ if (validToolNames.includes("grep") ||
2097
+ validToolNames.includes("find") ||
2098
+ validToolNames.includes("run_toolkit_script")) {
2037
2099
  addIfRegistered("artifact_retrieve");
2038
2100
  }
2101
+ if (validToolNames.includes("delegate")) {
2102
+ addIfRegistered("delegate_status");
2103
+ }
2039
2104
  this.agent.state.tools = tools;
2040
2105
  // Rebuild base system prompt with new tool set
2041
2106
  this._baseSystemPrompt = this._rebuildSystemPrompt(validToolNames);
@@ -2096,6 +2161,13 @@ export class AgentSession {
2096
2161
  _rebuildSystemPrompt(toolNames) {
2097
2162
  return this._systemPromptBuilder.rebuildSystemPrompt(toolNames);
2098
2163
  }
2164
+ _refreshBaseSystemPrompt() {
2165
+ const previousBaseSystemPrompt = this._baseSystemPrompt;
2166
+ this._baseSystemPrompt = this._rebuildSystemPrompt(this.getActiveToolNames());
2167
+ if (this.agent.state.systemPrompt === previousBaseSystemPrompt) {
2168
+ this.agent.state.systemPrompt = this._baseSystemPrompt;
2169
+ }
2170
+ }
2099
2171
  /**
2100
2172
  * Build a system prompt for a specific tool surface WITHOUT touching the session's base prompt
2101
2173
  * state (G4 router-swap; see {@link SystemPromptBuilder.buildSystemPromptForToolNames}).
@@ -2320,6 +2392,11 @@ export class AgentSession {
2320
2392
  if (!requestModel) {
2321
2393
  throw new Error(formatNoModelSelectedMessage());
2322
2394
  }
2395
+ // A manual/default local model has no RouteDecision, so the router readiness gate above is
2396
+ // intentionally a no-op. It still needs the same managed-runtime boot/residency guarantee.
2397
+ if (!resolvedRouteInfo) {
2398
+ await this._localRuntimeController.ensureForegroundModelReady(requestModel);
2399
+ }
2323
2400
  if (!this._modelRegistry.hasConfiguredAuth(requestModel)) {
2324
2401
  const isOAuth = this._modelRegistry.isUsingOAuth(requestModel);
2325
2402
  if (isOAuth) {
@@ -2345,7 +2422,7 @@ export class AgentSession {
2345
2422
  // (no page) when nothing is relevant — so it stays net-negative and the GC packs stale pages.
2346
2423
  if (this._memory.shouldAttemptRecall(expandedText)) {
2347
2424
  try {
2348
- const recall = await this._memory.getMemoryManager().prefetch(expandedText);
2425
+ const recall = await this._memory.prefetchRecall(expandedText);
2349
2426
  if (recall) {
2350
2427
  injectedRecall = recall;
2351
2428
  recallQuery = expandedText;
@@ -2430,6 +2507,7 @@ export class AgentSession {
2430
2507
  this._memory.recordRecallOutcome(injectedRecall, recallQuery, responseText);
2431
2508
  }
2432
2509
  }
2510
+ this._backgroundLanes.drainQueuedWorkerDelegations();
2433
2511
  this._backgroundLanes.scheduleGoalAutoContinueFromIdle(options);
2434
2512
  this._backgroundLanes.scheduleResearchLaneFromIdle();
2435
2513
  }
@@ -2725,6 +2803,16 @@ export class AgentSession {
2725
2803
  await this._modelSelection.setModel(model, options);
2726
2804
  this._scheduleLocalPrefixWarm(this.agent.state.model, "selection");
2727
2805
  }
2806
+ /** Re-resolve startup profile model/thinking after allowed extension providers are bound. */
2807
+ async reapplyActiveProfileModelSettings() {
2808
+ const previousModel = this.model;
2809
+ await this._profileFilter.reapplyActiveProfileModelSettings();
2810
+ const activeToolNames = this._requestedActiveToolNames ?? this.getActiveToolNames();
2811
+ this._refreshToolRegistry({ activeToolNames, includeAllExtensionTools: true });
2812
+ if (!modelsAreEqual(previousModel, this.model)) {
2813
+ this._scheduleLocalPrefixWarm(this.model, "selection");
2814
+ }
2815
+ }
2728
2816
  async cycleModel(direction = "forward") {
2729
2817
  const result = await this._modelSelection.cycleModel(direction);
2730
2818
  this._scheduleLocalPrefixWarm(result?.model, "selection");
@@ -3422,6 +3510,7 @@ export class AgentSession {
3422
3510
  setThinkingLevel: (level) => this.setThinkingLevel(level),
3423
3511
  getExternalResourceRoots: () => this.settingsManager.getEffectiveExternalResourceRoots(),
3424
3512
  registerMemoryProvider: (provider) => this.registerMemoryProvider(provider),
3513
+ registerContextMemoryProvider: (provider) => this.registerContextMemoryProvider(provider),
3425
3514
  reportSpawnedUsage: (usage, opts) => {
3426
3515
  this.addSpawnedUsage(usage, opts);
3427
3516
  },
@@ -3482,6 +3571,9 @@ export class AgentSession {
3482
3571
  registerMemoryProvider(provider) {
3483
3572
  this._memory.registerMemoryProvider(provider);
3484
3573
  }
3574
+ registerContextMemoryProvider(provider) {
3575
+ this._memory.registerContextMemoryProvider(provider);
3576
+ }
3485
3577
  /** R8: the gateway/scheduler registry. A deployment runner registers providers and drives start/stop. */
3486
3578
  get gateways() {
3487
3579
  return this._gatewayRegistry;