@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
@@ -34,7 +34,7 @@
34
34
  */
35
35
  import { existsSync, readFileSync } from "node:fs";
36
36
  import { isAbsolute, join } from "node:path";
37
- import { resetApiProviders } from "@caupulican/pi-ai";
37
+ import { DEFAULT_ACTIVE_TOOL_NAMES } from "./default-tool-surface.js";
38
38
  import { createCoreDiagnosticsToolDefinitions } from "./extensions/builtin.js";
39
39
  import { ExtensionRunner, wrapRegisteredTools, } from "./extensions/index.js";
40
40
  import { disposeExtensionEventSubscriptions } from "./extensions/loader.js";
@@ -49,6 +49,7 @@ import { buildReflexUserPrompt, parseReflexPlan, REFLEX_INTERPRETER_SYSTEM_PROMP
49
49
  import { executeToolkitScript } from "./toolkit/script-runner.js";
50
50
  import { createContextScoutToolDefinition } from "./tools/context-scout.js";
51
51
  import { createDelegateToolDefinition } from "./tools/delegate.js";
52
+ import { createDelegateStatusToolDefinition } from "./tools/delegate-status.js";
52
53
  import { createFindTool } from "./tools/find.js";
53
54
  import { createGoalToolDefinition } from "./tools/goal.js";
54
55
  import { createGrepTool } from "./tools/grep.js";
@@ -68,6 +69,8 @@ export class RuntimeBuilder {
68
69
  _toolPromptSnippets = new Map();
69
70
  _toolPromptGuidelines = new Map();
70
71
  _baseToolDefinitions = new Map();
72
+ _reloadPromise;
73
+ _reloadRequested = false;
71
74
  deps;
72
75
  constructor(deps) {
73
76
  this.deps = deps;
@@ -201,26 +204,26 @@ export class RuntimeBuilder {
201
204
  this._toolRegistry = toolRegistry;
202
205
  const requestedBase = options?.activeToolNames ? [...options.activeToolNames] : [...previousActiveToolNames];
203
206
  const nextActiveToolNames = requestedBase.filter((name) => isAllowedTool(name));
204
- const autoActivated = [];
207
+ const persistentAutoActivated = [];
205
208
  if (allowedToolNames) {
206
209
  for (const toolName of this._toolRegistry.keys()) {
207
210
  if (allowedToolNames.has(toolName)) {
208
211
  nextActiveToolNames.push(toolName);
209
- autoActivated.push(toolName);
212
+ persistentAutoActivated.push(toolName);
210
213
  }
211
214
  }
212
215
  }
213
216
  else if (options?.includeAllExtensionTools) {
214
217
  for (const tool of wrappedExtensionTools) {
215
218
  nextActiveToolNames.push(tool.name);
216
- autoActivated.push(tool.name);
219
+ persistentAutoActivated.push(tool.name);
217
220
  }
218
221
  }
219
222
  else if (!options?.activeToolNames) {
220
223
  for (const toolName of this._toolRegistry.keys()) {
221
224
  if (!previousRegistryNames.has(toolName)) {
222
225
  nextActiveToolNames.push(toolName);
223
- autoActivated.push(toolName);
226
+ persistentAutoActivated.push(toolName);
224
227
  }
225
228
  }
226
229
  }
@@ -242,7 +245,6 @@ export class RuntimeBuilder {
242
245
  }
243
246
  if (matchesResourceProfilePattern(toolName, explicitAllowPatterns)) {
244
247
  nextActiveToolNames.push(toolName);
245
- autoActivated.push(toolName);
246
248
  }
247
249
  }
248
250
  // G13: an explicit grant that binds to NO registered tool is a silent no-op — typo'd
@@ -260,14 +262,29 @@ export class RuntimeBuilder {
260
262
  // guarantee, not just this settings/profile refresh flow.
261
263
  this.deps.setActiveToolsByName([...new Set(nextActiveToolNames)]);
262
264
  // setActiveToolsByName just stored the profile-filtered ACTIVE set as the request; restore
263
- // the true pre-filter request (plus this refresh's auto-activations) so an internal refresh
264
- // can never permanently narrow it.
265
- this.deps.setRequestedActiveToolNames([...new Set([...requestedBase, ...autoActivated])]);
265
+ // the true pre-filter request (plus non-profile auto-activations) so an internal refresh can
266
+ // never permanently narrow it. Explicit profile grants are generation-local activations: if
267
+ // profile A names grep and profile B later grants "*", A must not pin grep into B's request.
268
+ this.deps.setRequestedActiveToolNames([...new Set([...requestedBase, ...persistentAutoActivated])]);
266
269
  }
267
270
  _createReloadRuntimeSnapshot() {
268
271
  const agent = this.deps.getAgent();
272
+ const toolProfileFilter = this.deps.getToolProfileFilter();
273
+ const requestedActiveToolNames = this.deps.getRequestedActiveToolNames();
269
274
  return {
270
275
  extensionRunner: this.deps.getExtensionRunner(),
276
+ settings: this.deps.getSettingsManager().createReloadSnapshot(),
277
+ modelRegistry: this.deps.getModelRegistry().createReloadSnapshot(),
278
+ model: agent.state.model,
279
+ thinkingLevel: agent.state.thinkingLevel,
280
+ sessionLeafId: this.deps.getSessionManager().getLeafId(),
281
+ toolProfileFilter: toolProfileFilter
282
+ ? { allow: [...toolProfileFilter.allow], block: [...toolProfileFilter.block] }
283
+ : undefined,
284
+ requestedActiveToolNames: requestedActiveToolNames ? [...requestedActiveToolNames] : undefined,
285
+ memory: this.deps.createMemoryReloadSnapshot(),
286
+ profileFilter: this.deps.createProfileFilterReloadSnapshot(),
287
+ unboundToolGrantWarnings: [...this.deps.getUnboundToolGrantWarnings()],
271
288
  baseToolDefinitions: this._baseToolDefinitions,
272
289
  toolRegistry: this._toolRegistry,
273
290
  toolDefinitions: this._toolDefinitions,
@@ -279,6 +296,15 @@ export class RuntimeBuilder {
279
296
  };
280
297
  }
281
298
  _restoreReloadRuntimeSnapshot(snapshot) {
299
+ this.deps.getSettingsManager().restoreReloadSnapshot(snapshot.settings);
300
+ this.deps.getModelRegistry().restoreReloadSnapshot(snapshot.modelRegistry);
301
+ this.deps.setToolProfileFilter(snapshot.toolProfileFilter
302
+ ? { allow: [...snapshot.toolProfileFilter.allow], block: [...snapshot.toolProfileFilter.block] }
303
+ : undefined);
304
+ this.deps.setRequestedActiveToolNames(snapshot.requestedActiveToolNames ? [...snapshot.requestedActiveToolNames] : undefined);
305
+ this.deps.restoreMemoryReloadSnapshot(snapshot.memory);
306
+ this.deps.restoreProfileFilterReloadSnapshot(snapshot.profileFilter);
307
+ this.deps.setUnboundToolGrantWarnings([...snapshot.unboundToolGrantWarnings]);
282
308
  // setExtensionRunner restores both _extensionRunner and _extensionRunnerRef.current together
283
309
  // (the same field-then-ref pair the host wrote at every assignment site); nothing reads the
284
310
  // ref between the two writes, so folding them is unobservable.
@@ -289,9 +315,18 @@ export class RuntimeBuilder {
289
315
  this._toolPromptSnippets = snapshot.toolPromptSnippets;
290
316
  this._toolPromptGuidelines = snapshot.toolPromptGuidelines;
291
317
  const agent = this.deps.getAgent();
318
+ agent.state.model = snapshot.model;
319
+ agent.state.thinkingLevel = snapshot.thinkingLevel;
292
320
  agent.state.tools = snapshot.agentTools;
293
321
  agent.state.systemPrompt = snapshot.agentSystemPrompt;
294
322
  this.deps.setBaseSystemPrompt(snapshot.baseSystemPrompt);
323
+ const sessionManager = this.deps.getSessionManager();
324
+ if (snapshot.sessionLeafId === null) {
325
+ sessionManager.resetLeaf();
326
+ }
327
+ else {
328
+ sessionManager.branch(snapshot.sessionLeafId);
329
+ }
295
330
  this.deps.applyExtensionBindings(snapshot.extensionRunner);
296
331
  }
297
332
  _doctorReloadRuntime() {
@@ -321,11 +356,11 @@ export class RuntimeBuilder {
321
356
  const shellCommandPrefix = settingsManager.getShellCommandPrefix();
322
357
  const shellPath = settingsManager.getShellPath();
323
358
  const baseToolsOverride = this.deps.getBaseToolsOverride();
324
- // grep/find must not emit a "Full output: artifact tool-output:<id>" handle that
325
- // nothing can resolve. If artifact_retrieve is explicitly excluded/blocked/outside
326
- // an active allowlist, don't hand grep/find an artifact store at all: they fall
327
- // back to their pre-existing bounded preview/truncation behavior, with no
328
- // payload/meta files ever written and no retrieval promise made.
359
+ // Artifact-producing tools must not emit a "Full output: artifact tool-output:<id>" handle
360
+ // that nothing can resolve. If artifact_retrieve is explicitly excluded/blocked/outside
361
+ // an active allowlist, don't hand grep/find/run_toolkit_script an artifact store at all:
362
+ // they fall back to their bounded preview/truncation behavior, with no payload/meta files
363
+ // ever written and no retrieval promise made.
329
364
  const toolArtifactStore = this.deps.isToolOrCommandAllowedByProfile("artifact_retrieve")
330
365
  ? this.deps.getToolArtifactStore()
331
366
  : undefined;
@@ -351,9 +386,15 @@ export class RuntimeBuilder {
351
386
  });
352
387
  this._baseToolDefinitions.set(goalToolDefinition.name, goalToolDefinition);
353
388
  const delegateToolDefinition = createDelegateToolDefinition({
389
+ startWorkerDelegation: (args) => this.deps.startWorkerDelegation(args),
354
390
  runWorkerDelegation: (args) => this.deps.runWorkerDelegationOnce(args),
355
391
  });
392
+ const delegateStatusToolDefinition = createDelegateStatusToolDefinition({
393
+ getLaneRecords: () => this.deps.getWorkerLaneRecords(),
394
+ getWorkerResultSnapshots: () => this.deps.getWorkerResultSnapshots(),
395
+ });
356
396
  this._baseToolDefinitions.set(delegateToolDefinition.name, delegateToolDefinition);
397
+ this._baseToolDefinitions.set(delegateStatusToolDefinition.name, delegateStatusToolDefinition);
357
398
  // Registered but not default-active: probes spend tokens on the probed model, so
358
399
  // activation is an explicit choice (settings/profile/setActiveTools or /autonomy fitness).
359
400
  const modelFitnessToolDefinition = createModelFitnessToolDefinition({
@@ -369,6 +410,7 @@ export class RuntimeBuilder {
369
410
  const runToolkitScriptToolDefinition = createRunToolkitScriptToolDefinition({
370
411
  getScripts: () => this.deps.getSettingsManager().getToolkitScripts(),
371
412
  execute: (script, scriptArgs) => executeToolkitScript({ script, scriptArgs, cwd: this.deps.getCwd() }),
413
+ artifactStore: toolArtifactStore,
372
414
  // Reflex brain (fitness-gated local model): resolves ambiguous requests into a
373
415
  // registry pick. Best-effort — absent/unfit brain keeps the shortlist behavior.
374
416
  interpret: async (request, scripts) => {
@@ -408,29 +450,60 @@ export class RuntimeBuilder {
408
450
  extensionsResult.runtime.pendingProviderRegistrations =
409
451
  extensionsResult.runtime.pendingProviderRegistrations.filter((registration) => runtimeExtensionPaths.has(registration.extensionPath));
410
452
  const runner = new ExtensionRunner(extensions, extensionsResult.runtime, this.deps.getCwd(), this.deps.getSessionManager(), this.deps.getModelRegistry());
453
+ const offBuildErrors = options.onError ? runner.onError(options.onError) : undefined;
411
454
  this.deps.setExtensionRunner(runner);
412
- this.deps.bindExtensionCore(runner);
455
+ try {
456
+ this.deps.bindExtensionCore(runner);
457
+ }
458
+ catch (error) {
459
+ offBuildErrors?.();
460
+ throw error;
461
+ }
413
462
  this.deps.applyExtensionBindings(runner);
414
463
  const defaultActiveToolNames = baseToolsOverride
415
464
  ? Object.keys(baseToolsOverride)
416
- : [
417
- "read",
418
- "bash",
419
- "edit",
420
- "write",
421
- "context_audit",
422
- "goal",
423
- "delegate",
424
- "run_toolkit_script",
425
- ...(settingsManager.getScoutSettings().enabled ? ["context_scout"] : []),
426
- ];
465
+ : [...DEFAULT_ACTIVE_TOOL_NAMES, ...(settingsManager.getScoutSettings().enabled ? ["context_scout"] : [])];
427
466
  const baseActiveToolNames = options.activeToolNames ?? defaultActiveToolNames;
428
467
  this.refreshToolRegistry({
429
468
  activeToolNames: baseActiveToolNames,
430
469
  includeAllExtensionTools: options.includeAllExtensionTools,
431
470
  });
471
+ return offBuildErrors;
472
+ }
473
+ reload() {
474
+ if (this._reloadPromise) {
475
+ // State can change while a generation is being validated. Coalesce any number of
476
+ // overlapping requests into one follow-up generation instead of silently treating a
477
+ // later profile/settings mutation as part of the already-snapshotted generation.
478
+ this._reloadRequested = true;
479
+ return this._reloadPromise;
480
+ }
481
+ const reloadPromise = this._drainReloadRequests();
482
+ this._reloadPromise = reloadPromise;
483
+ return reloadPromise;
432
484
  }
433
- async reload() {
485
+ async _drainReloadRequests() {
486
+ let finalError;
487
+ try {
488
+ do {
489
+ this._reloadRequested = false;
490
+ try {
491
+ await this._reloadOnce();
492
+ finalError = undefined;
493
+ }
494
+ catch (error) {
495
+ finalError = error;
496
+ }
497
+ } while (this._reloadRequested);
498
+ if (finalError !== undefined)
499
+ throw finalError;
500
+ }
501
+ finally {
502
+ this._reloadPromise = undefined;
503
+ this._reloadRequested = false;
504
+ }
505
+ }
506
+ async _reloadOnce() {
434
507
  if (this.deps.isStreaming()) {
435
508
  throw new Error("Cannot reload while the agent is streaming or a tool call is active");
436
509
  }
@@ -443,8 +516,10 @@ export class RuntimeBuilder {
443
516
  // active set — otherwise a reload under a small model permanently shrinks the restorable set.
444
517
  const activeToolNames = this.deps.getRequestedActiveToolNames() ?? this.deps.getActiveToolNames();
445
518
  const previousFlagValues = previousRunner.getFlagValues();
519
+ const previousExtensionProviderNames = previousRunner.getRegisteredProviderNames();
446
520
  const reloadErrors = [];
447
521
  let newRunner;
522
+ let offReloadErrors;
448
523
  try {
449
524
  await this.deps.getSettingsManager().reload();
450
525
  // Re-derive the resource-profile tool filter from the freshly reloaded settings.
@@ -453,21 +528,30 @@ export class RuntimeBuilder {
453
528
  // active profile's tools allow/block — or switching the active profile — would not
454
529
  // apply on /reload and allowed tools would stay missing.
455
530
  this.deps.setToolProfileFilter(this.deps.deriveToolProfileFilter());
456
- // Re-apply the active profile's model/thinking from the freshly reloaded settings, so a live
457
- // profile edit (or switch) takes effect on /reload. Skipped when the launch used an explicit
458
- // --model/--thinking flag, which must win over the profile across reloads.
459
- await this.deps.reapplyActiveProfileModelSettings();
460
- await this.deps.getResourceLoader().reload({ failOnExtensionErrors: true, deferExtensionDispose: true });
461
- resetApiProviders();
462
- this.buildRuntime({
531
+ // Resource discovery must consume this exact settings generation. A second settings read here
532
+ // could combine profile state from one generation with resources from the next.
533
+ await this.deps.getResourceLoader().reload({
534
+ failOnExtensionErrors: true,
535
+ deferExtensionDispose: true,
536
+ skipSettingsReload: true,
537
+ });
538
+ // Replace the previous extension-owned provider generation before binding the new one. The
539
+ // bulk refresh also preserves API/OAuth streams for surviving non-extension providers.
540
+ this.deps.getModelRegistry().unregisterProviders(previousExtensionProviderNames);
541
+ offReloadErrors = this.buildRuntime({
463
542
  activeToolNames,
464
543
  flagValues: previousFlagValues,
465
544
  includeAllExtensionTools: true,
545
+ onError: (error) => {
546
+ reloadErrors.push(`${error.extensionPath} ${error.event}: ${error.error}`);
547
+ },
466
548
  });
467
549
  newRunner = this.deps.getExtensionRunner();
468
- const offDoctorErrors = newRunner.onError((error) => {
469
- reloadErrors.push(`${error.extensionPath} ${error.event}: ${error.error}`);
470
- });
550
+ // Extensions are now bound and their queued providers/models are registered, so a profile may
551
+ // safely select a model contributed by an extension granted in that same profile generation.
552
+ await this.deps.reapplyActiveProfileModelSettings();
553
+ // Model capability and system-prompt/tool exposure must reflect the newly selected model.
554
+ this.refreshToolRegistry({ activeToolNames, includeAllExtensionTools: true });
471
555
  try {
472
556
  this._doctorReloadRuntime();
473
557
  // Reload starts memory providers fresh; loaded extensions re-register below.
@@ -483,22 +567,24 @@ export class RuntimeBuilder {
483
567
  }
484
568
  }
485
569
  finally {
486
- offDoctorErrors();
570
+ offReloadErrors?.();
571
+ offReloadErrors = undefined;
487
572
  }
488
573
  if (reloadErrors.length > 0) {
489
574
  throw new Error(`Extension reload failed doctor: ${reloadErrors.slice(0, 6).join("; ")}`);
490
575
  }
491
576
  await emitSessionShutdownEvent(previousRunner, { type: "session_shutdown", reason: "reload" });
492
577
  previousRunner.invalidate();
493
- this.deps.getResourceLoader().commitReload?.();
578
+ await this.deps.getResourceLoader().commitReload?.();
494
579
  // Re-derive the memory subsystem from the reloaded settings/providers.
495
580
  await this.deps.initializeMemory();
496
581
  }
497
582
  catch (error) {
583
+ offReloadErrors?.();
498
584
  if (newRunner && newRunner !== previousRunner) {
499
585
  newRunner.invalidate("This extension ctx was discarded because reload failed and Pi restored the previous valid runtime.");
500
586
  }
501
- this.deps.getResourceLoader().rollbackReload?.();
587
+ await this.deps.getResourceLoader().rollbackReload?.();
502
588
  this._restoreReloadRuntimeSnapshot(snapshot);
503
589
  throw error;
504
590
  }
@@ -526,6 +612,8 @@ export class RuntimeBuilder {
526
612
  await this.deps.getExtensionRunner().emitToExtension(ext, { type: "session_shutdown", reason: "unload" });
527
613
  // Unregister its providers (keyed by the extension's own path, as registered)
528
614
  const runtime = this.deps.getResourceLoader().getExtensions().runtime;
615
+ const ownedMemoryProviders = runtime.memoryProvidersByExtension.get(ext.path) ?? new Set();
616
+ const ownedContextMemoryProviders = runtime.contextMemoryProvidersByExtension.get(ext.path) ?? new Set();
529
617
  for (const name of runtime.getProvidersForExtension(ext.path)) {
530
618
  runtime.unregisterProvider(name, ext.path);
531
619
  }
@@ -542,6 +630,15 @@ export class RuntimeBuilder {
542
630
  includeAllExtensionTools: true,
543
631
  });
544
632
  previousRunner.invalidate();
633
+ const memorySnapshot = this.deps.createMemoryReloadSnapshot();
634
+ this.deps.restoreMemoryReloadSnapshot({
635
+ ...memorySnapshot,
636
+ pendingMemoryProviders: memorySnapshot.pendingMemoryProviders.filter((provider) => !ownedMemoryProviders.has(provider)),
637
+ pendingContextMemoryProviders: memorySnapshot.pendingContextMemoryProviders.filter((provider) => !ownedContextMemoryProviders.has(provider)),
638
+ });
639
+ runtime.memoryProvidersByExtension.delete(ext.path);
640
+ runtime.contextMemoryProvidersByExtension.delete(ext.path);
641
+ await this.deps.initializeMemory();
545
642
  // Notify extensions-changed listeners
546
643
  this.deps.notifyExtensionsChanged();
547
644
  }
@@ -586,6 +683,9 @@ export class RuntimeBuilder {
586
683
  });
587
684
  // Run session_start lifecycle for the new extension only
588
685
  await this.deps.getExtensionRunner().emitToExtension(extension, { type: "session_start", reason: "load" });
686
+ // Activate newly registered legacy/context providers immediately. Reinitialization also
687
+ // refreshes provider tools and preserves all providers owned by existing extensions.
688
+ await this.deps.initializeMemory();
589
689
  // Notify extensions-changed listeners
590
690
  this.deps.notifyExtensionsChanged();
591
691
  }