@caupulican/pi-adaptative 0.80.103 → 0.81.0
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.
- package/CHANGELOG.md +120 -0
- package/dist/cli/session-picker.d.ts +1 -1
- package/dist/cli/session-picker.d.ts.map +1 -1
- package/dist/cli/session-picker.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +7 -1
- package/dist/cli.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +6 -6
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +152 -512
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +635 -4590
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/autonomy/session-lane-record.d.ts +1 -1
- package/dist/core/autonomy/session-lane-record.d.ts.map +1 -1
- package/dist/core/autonomy/session-lane-record.js.map +1 -1
- package/dist/core/autonomy/status.d.ts +1 -0
- package/dist/core/autonomy/status.d.ts.map +1 -1
- package/dist/core/autonomy/status.js +1 -0
- package/dist/core/autonomy/status.js.map +1 -1
- package/dist/core/autonomy-telemetry.d.ts +80 -0
- package/dist/core/autonomy-telemetry.d.ts.map +1 -0
- package/dist/core/autonomy-telemetry.js +266 -0
- package/dist/core/autonomy-telemetry.js.map +1 -0
- package/dist/core/background-lane-controller.d.ts +186 -0
- package/dist/core/background-lane-controller.d.ts.map +1 -0
- package/dist/core/background-lane-controller.js +691 -0
- package/dist/core/background-lane-controller.js.map +1 -0
- package/dist/core/bash-execution-controller.d.ts +51 -0
- package/dist/core/bash-execution-controller.d.ts.map +1 -0
- package/dist/core/bash-execution-controller.js +96 -0
- package/dist/core/bash-execution-controller.js.map +1 -0
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +9 -2
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/compaction-support.d.ts +56 -0
- package/dist/core/compaction-support.d.ts.map +1 -0
- package/dist/core/compaction-support.js +99 -0
- package/dist/core/compaction-support.js.map +1 -0
- package/dist/core/context/artifact-retrieval.d.ts +1 -1
- package/dist/core/context/artifact-retrieval.d.ts.map +1 -1
- package/dist/core/context/artifact-retrieval.js +1 -1
- package/dist/core/context/artifact-retrieval.js.map +1 -1
- package/dist/core/context/context-composition.d.ts.map +1 -1
- package/dist/core/context/context-composition.js +1 -1
- package/dist/core/context/context-composition.js.map +1 -1
- package/dist/core/context/tool-output-packer.d.ts +1 -1
- package/dist/core/context/tool-output-packer.d.ts.map +1 -1
- package/dist/core/context/tool-output-packer.js +1 -1
- package/dist/core/context/tool-output-packer.js.map +1 -1
- package/dist/core/context-gc.d.ts.map +1 -1
- package/dist/core/context-gc.js +1 -1
- package/dist/core/context-gc.js.map +1 -1
- package/dist/core/context-pipeline.d.ts +223 -0
- package/dist/core/context-pipeline.d.ts.map +1 -0
- package/dist/core/context-pipeline.js +594 -0
- package/dist/core/context-pipeline.js.map +1 -0
- package/dist/core/cost/daily-usage.d.ts +1 -1
- package/dist/core/cost/daily-usage.d.ts.map +1 -1
- package/dist/core/cost/daily-usage.js +1 -1
- package/dist/core/cost/daily-usage.js.map +1 -1
- package/dist/core/cost/session-usage.d.ts +1 -1
- package/dist/core/cost/session-usage.d.ts.map +1 -1
- package/dist/core/cost/session-usage.js +1 -1
- package/dist/core/cost/session-usage.js.map +1 -1
- package/dist/core/delegation/session-worker-result.d.ts +1 -1
- package/dist/core/delegation/session-worker-result.d.ts.map +1 -1
- package/dist/core/delegation/session-worker-result.js.map +1 -1
- package/dist/core/exec.d.ts +2 -0
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js +15 -9
- package/dist/core/exec.js.map +1 -1
- package/dist/core/export-html/index.d.ts +1 -1
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js +2 -2
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/extensions/builtin.d.ts.map +1 -1
- package/dist/core/extensions/builtin.js +2 -2
- package/dist/core/extensions/builtin.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +1 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +2 -4
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/goal-loop-controller.d.ts +24 -0
- package/dist/core/goal-loop-controller.d.ts.map +1 -0
- package/dist/core/goal-loop-controller.js +83 -0
- package/dist/core/goal-loop-controller.js.map +1 -0
- package/dist/core/goals/goal-runtime-snapshot.d.ts +1 -1
- package/dist/core/goals/goal-runtime-snapshot.d.ts.map +1 -1
- package/dist/core/goals/goal-runtime-snapshot.js.map +1 -1
- package/dist/core/goals/session-goal-state.d.ts +1 -1
- package/dist/core/goals/session-goal-state.d.ts.map +1 -1
- package/dist/core/goals/session-goal-state.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/learning/learning-audit.d.ts +1 -1
- package/dist/core/learning/learning-audit.d.ts.map +1 -1
- package/dist/core/learning/learning-audit.js.map +1 -1
- package/dist/core/learning/session-learning-decision.d.ts +1 -1
- package/dist/core/learning/session-learning-decision.d.ts.map +1 -1
- package/dist/core/learning/session-learning-decision.js.map +1 -1
- package/dist/core/local-runtime-controller.d.ts +99 -0
- package/dist/core/local-runtime-controller.d.ts.map +1 -0
- package/dist/core/local-runtime-controller.js +214 -0
- package/dist/core/local-runtime-controller.js.map +1 -0
- package/dist/core/memory/providers/transcript-recall.d.ts.map +1 -1
- package/dist/core/memory/providers/transcript-recall.js +1 -1
- package/dist/core/memory/providers/transcript-recall.js.map +1 -1
- package/dist/core/memory-controller.d.ts +139 -0
- package/dist/core/memory-controller.d.ts.map +1 -0
- package/dist/core/memory-controller.js +323 -0
- package/dist/core/memory-controller.js.map +1 -0
- package/dist/core/model-router/status.d.ts +1 -1
- package/dist/core/model-router/status.d.ts.map +1 -1
- package/dist/core/model-router/status.js.map +1 -1
- package/dist/core/model-router-controller.d.ts +140 -0
- package/dist/core/model-router-controller.d.ts.map +1 -0
- package/dist/core/model-router-controller.js +623 -0
- package/dist/core/model-router-controller.js.map +1 -0
- package/dist/core/model-selection-controller.d.ts +95 -0
- package/dist/core/model-selection-controller.d.ts.map +1 -0
- package/dist/core/model-selection-controller.js +252 -0
- package/dist/core/model-selection-controller.js.map +1 -0
- package/dist/core/models/model-ref.d.ts +13 -0
- package/dist/core/models/model-ref.d.ts.map +1 -1
- package/dist/core/models/model-ref.js +22 -0
- package/dist/core/models/model-ref.js.map +1 -1
- package/dist/core/profile-filter-controller.d.ts +77 -0
- package/dist/core/profile-filter-controller.d.ts.map +1 -0
- package/dist/core/profile-filter-controller.js +159 -0
- package/dist/core/profile-filter-controller.js.map +1 -0
- package/dist/core/reflection-controller.d.ts +111 -0
- package/dist/core/reflection-controller.d.ts.map +1 -0
- package/dist/core/reflection-controller.js +412 -0
- package/dist/core/reflection-controller.js.map +1 -0
- package/dist/core/research/model-fitness.d.ts +12 -0
- package/dist/core/research/model-fitness.d.ts.map +1 -1
- package/dist/core/research/model-fitness.js +21 -0
- package/dist/core/research/model-fitness.js.map +1 -1
- package/dist/core/research/session-evidence-bundle.d.ts +1 -1
- package/dist/core/research/session-evidence-bundle.d.ts.map +1 -1
- package/dist/core/research/session-evidence-bundle.js.map +1 -1
- package/dist/core/runtime-builder.d.ts +222 -0
- package/dist/core/runtime-builder.d.ts.map +1 -0
- package/dist/core/runtime-builder.js +640 -0
- package/dist/core/runtime-builder.js.map +1 -0
- package/dist/core/sdk.d.ts +2 -2
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +3 -4
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-analytics.d.ts +96 -0
- package/dist/core/session-analytics.d.ts.map +1 -0
- package/dist/core/session-analytics.js +331 -0
- package/dist/core/session-analytics.js.map +1 -0
- package/dist/core/session-manager-factory.d.ts +18 -0
- package/dist/core/session-manager-factory.d.ts.map +1 -0
- package/dist/core/session-manager-factory.js +32 -0
- package/dist/core/session-manager-factory.js.map +1 -0
- package/dist/core/session-tree-navigator.d.ts +68 -0
- package/dist/core/session-tree-navigator.d.ts.map +1 -0
- package/dist/core/session-tree-navigator.js +217 -0
- package/dist/core/session-tree-navigator.js.map +1 -0
- package/dist/core/system-prompt-builder.d.ts +63 -0
- package/dist/core/system-prompt-builder.d.ts.map +1 -0
- package/dist/core/system-prompt-builder.js +181 -0
- package/dist/core/system-prompt-builder.js.map +1 -0
- package/dist/core/tool-gate-controller.d.ts +36 -0
- package/dist/core/tool-gate-controller.d.ts.map +1 -0
- package/dist/core/tool-gate-controller.js +94 -0
- package/dist/core/tool-gate-controller.js.map +1 -0
- package/dist/core/tools/artifact-retrieve.d.ts.map +1 -1
- package/dist/core/tools/artifact-retrieve.js +1 -1
- package/dist/core/tools/artifact-retrieve.js.map +1 -1
- package/dist/core/tools/bash.d.ts +4 -2
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +49 -7
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts +6 -0
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js +61 -1
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/find.d.ts +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +1 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +1 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +1 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +1 -1
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +1 -1
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts +1 -1
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +1 -1
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/read.d.ts +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +1 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js +1 -1
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +13 -12
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/auth-dialogs-controller.d.ts +59 -0
- package/dist/modes/interactive/auth-dialogs-controller.d.ts.map +1 -0
- package/dist/modes/interactive/auth-dialogs-controller.js +398 -0
- package/dist/modes/interactive/auth-dialogs-controller.js.map +1 -0
- package/dist/modes/interactive/auto-learn-controller.d.ts +168 -0
- package/dist/modes/interactive/auto-learn-controller.d.ts.map +1 -0
- package/dist/modes/interactive/auto-learn-controller.js +1239 -0
- package/dist/modes/interactive/auto-learn-controller.js.map +1 -0
- package/dist/modes/interactive/autocomplete-provider.d.ts +26 -0
- package/dist/modes/interactive/autocomplete-provider.d.ts.map +1 -0
- package/dist/modes/interactive/autocomplete-provider.js +103 -0
- package/dist/modes/interactive/autocomplete-provider.js.map +1 -0
- package/dist/modes/interactive/autonomy-commands.d.ts +38 -0
- package/dist/modes/interactive/autonomy-commands.d.ts.map +1 -0
- package/dist/modes/interactive/autonomy-commands.js +142 -0
- package/dist/modes/interactive/autonomy-commands.js.map +1 -0
- package/dist/modes/interactive/clipboard-input.d.ts +37 -0
- package/dist/modes/interactive/clipboard-input.d.ts.map +1 -0
- package/dist/modes/interactive/clipboard-input.js +59 -0
- package/dist/modes/interactive/clipboard-input.js.map +1 -0
- package/dist/modes/interactive/compaction-queue.d.ts +30 -0
- package/dist/modes/interactive/compaction-queue.d.ts.map +1 -0
- package/dist/modes/interactive/compaction-queue.js +91 -0
- package/dist/modes/interactive/compaction-queue.js.map +1 -0
- package/dist/modes/interactive/components/bash-execution.d.ts +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +1 -1
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +2 -2
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/config-backup.d.ts +27 -0
- package/dist/modes/interactive/config-backup.d.ts.map +1 -0
- package/dist/modes/interactive/config-backup.js +146 -0
- package/dist/modes/interactive/config-backup.js.map +1 -0
- package/dist/modes/interactive/editor-overlay-host.d.ts +48 -0
- package/dist/modes/interactive/editor-overlay-host.d.ts.map +1 -0
- package/dist/modes/interactive/editor-overlay-host.js +43 -0
- package/dist/modes/interactive/editor-overlay-host.js.map +1 -0
- package/dist/modes/interactive/extension-ui-host.d.ts +165 -0
- package/dist/modes/interactive/extension-ui-host.d.ts.map +1 -0
- package/dist/modes/interactive/extension-ui-host.js +610 -0
- package/dist/modes/interactive/extension-ui-host.js.map +1 -0
- package/dist/modes/interactive/external-editor.d.ts +18 -0
- package/dist/modes/interactive/external-editor.d.ts.map +1 -0
- package/dist/modes/interactive/external-editor.js +107 -0
- package/dist/modes/interactive/external-editor.js.map +1 -0
- package/dist/modes/interactive/history-reload-math.d.ts +24 -0
- package/dist/modes/interactive/history-reload-math.d.ts.map +1 -0
- package/dist/modes/interactive/history-reload-math.js +129 -0
- package/dist/modes/interactive/history-reload-math.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +22 -238
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +714 -5910
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/key-handlers.d.ts +46 -0
- package/dist/modes/interactive/key-handlers.d.ts.map +1 -0
- package/dist/modes/interactive/key-handlers.js +80 -0
- package/dist/modes/interactive/key-handlers.js.map +1 -0
- package/dist/modes/interactive/local-model-commands.d.ts +68 -0
- package/dist/modes/interactive/local-model-commands.d.ts.map +1 -0
- package/dist/modes/interactive/local-model-commands.js +288 -0
- package/dist/modes/interactive/local-model-commands.js.map +1 -0
- package/dist/modes/interactive/profile-menu-controller.d.ts +77 -0
- package/dist/modes/interactive/profile-menu-controller.d.ts.map +1 -0
- package/dist/modes/interactive/profile-menu-controller.js +917 -0
- package/dist/modes/interactive/profile-menu-controller.js.map +1 -0
- package/dist/modes/interactive/report-commands.d.ts +46 -0
- package/dist/modes/interactive/report-commands.d.ts.map +1 -0
- package/dist/modes/interactive/report-commands.js +255 -0
- package/dist/modes/interactive/report-commands.js.map +1 -0
- package/dist/modes/interactive/resource-display.d.ts +73 -0
- package/dist/modes/interactive/resource-display.d.ts.map +1 -0
- package/dist/modes/interactive/resource-display.js +278 -0
- package/dist/modes/interactive/resource-display.js.map +1 -0
- package/dist/modes/interactive/resource-shell-commands.d.ts +64 -0
- package/dist/modes/interactive/resource-shell-commands.d.ts.map +1 -0
- package/dist/modes/interactive/resource-shell-commands.js +202 -0
- package/dist/modes/interactive/resource-shell-commands.js.map +1 -0
- package/dist/modes/interactive/session-flow-commands.d.ts +139 -0
- package/dist/modes/interactive/session-flow-commands.d.ts.map +1 -0
- package/dist/modes/interactive/session-flow-commands.js +458 -0
- package/dist/modes/interactive/session-flow-commands.js.map +1 -0
- package/dist/modes/interactive/session-io-commands.d.ts +73 -0
- package/dist/modes/interactive/session-io-commands.d.ts.map +1 -0
- package/dist/modes/interactive/session-io-commands.js +202 -0
- package/dist/modes/interactive/session-io-commands.js.map +1 -0
- package/dist/modes/interactive/settings-selector-flow.d.ts +42 -0
- package/dist/modes/interactive/settings-selector-flow.d.ts.map +1 -0
- package/dist/modes/interactive/settings-selector-flow.js +287 -0
- package/dist/modes/interactive/settings-selector-flow.js.map +1 -0
- package/dist/modes/interactive/signal-lifecycle.d.ts +55 -0
- package/dist/modes/interactive/signal-lifecycle.d.ts.map +1 -0
- package/dist/modes/interactive/signal-lifecycle.js +177 -0
- package/dist/modes/interactive/signal-lifecycle.js.map +1 -0
- package/dist/modes/interactive/startup-checks.d.ts +38 -0
- package/dist/modes/interactive/startup-checks.d.ts.map +1 -0
- package/dist/modes/interactive/startup-checks.js +189 -0
- package/dist/modes/interactive/startup-checks.js.map +1 -0
- package/dist/modes/rpc/rpc-client.d.ts +1 -1
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +1 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/utils/paths.d.ts +2 -14
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +5 -30
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/process-memory.d.ts +8 -0
- package/dist/utils/process-memory.d.ts.map +1 -0
- package/dist/utils/process-memory.js +11 -0
- package/dist/utils/process-memory.js.map +1 -0
- package/dist/utils/shell.d.ts +0 -9
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +0 -37
- package/dist/utils/shell.js.map +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/sdk/11-sessions.ts +8 -8
- package/examples/sdk/13-session-runtime.ts +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +4 -4
- package/dist/core/compaction/branch-summarization.d.ts +0 -88
- package/dist/core/compaction/branch-summarization.d.ts.map +0 -1
- package/dist/core/compaction/branch-summarization.js +0 -243
- package/dist/core/compaction/branch-summarization.js.map +0 -1
- package/dist/core/compaction/compaction.d.ts +0 -143
- package/dist/core/compaction/compaction.d.ts.map +0 -1
- package/dist/core/compaction/compaction.js +0 -659
- package/dist/core/compaction/compaction.js.map +0 -1
- package/dist/core/compaction/index.d.ts +0 -7
- package/dist/core/compaction/index.d.ts.map +0 -1
- package/dist/core/compaction/index.js +0 -7
- package/dist/core/compaction/index.js.map +0 -1
- package/dist/core/compaction/utils.d.ts +0 -38
- package/dist/core/compaction/utils.d.ts.map +0 -1
- package/dist/core/compaction/utils.js +0 -153
- package/dist/core/compaction/utils.js.map +0 -1
- package/dist/core/message-retention.d.ts +0 -26
- package/dist/core/message-retention.d.ts.map +0 -1
- package/dist/core/message-retention.js +0 -95
- package/dist/core/message-retention.js.map +0 -1
- package/dist/core/messages.d.ts +0 -77
- package/dist/core/messages.d.ts.map +0 -1
- package/dist/core/messages.js +0 -123
- package/dist/core/messages.js.map +0 -1
- package/dist/core/session-manager.d.ts +0 -337
- package/dist/core/session-manager.d.ts.map +0 -1
- package/dist/core/session-manager.js +0 -1328
- package/dist/core/session-manager.js.map +0 -1
- package/dist/core/tools/truncate.d.ts +0 -70
- package/dist/core/tools/truncate.d.ts.map +0 -1
- package/dist/core/tools/truncate.js +0 -215
- package/dist/core/tools/truncate.js.map +0 -1
|
@@ -287,6 +287,27 @@ export async function runModelFitnessProbe(options) {
|
|
|
287
287
|
const tokensPerSecond = overallSpeed.evalMs > 0 ? Math.round((overallSpeed.tokens / overallSpeed.evalMs) * 1000) : undefined;
|
|
288
288
|
return { trials, tokensPerSecond, research, worker, judge, search, toolCall, digest, totalCostUsd };
|
|
289
289
|
}
|
|
290
|
+
/**
|
|
291
|
+
* Pure verdict: true when the probe found ZERO successes on every LANE surface it actually graded
|
|
292
|
+
* AND the judge (if it ran) also failed. A lane/judge with total 0 (i.e. never run) carries no
|
|
293
|
+
* evidence and is excluded from the lane check — but at least one lane must actually have been
|
|
294
|
+
* graded for an all-failed verdict at all: `gradedLanes.every(...)` is vacuously true over an
|
|
295
|
+
* empty array, so a report where only the judge ran (every research/worker/search/toolCall/digest
|
|
296
|
+
* lane is ungraded) is excluded explicitly rather than misread as "all lanes failed" on zero lane
|
|
297
|
+
* evidence. An empty/degenerate report (nothing graded at all, lanes AND judge) is likewise never
|
|
298
|
+
* mistaken for a failed one. This is the gate adoption flows must consult before assigning a role —
|
|
299
|
+
* see `isProbeAllFailed` callers in interactive-mode.ts and agent-session.ts.
|
|
300
|
+
*/
|
|
301
|
+
export function isProbeAllFailed(report) {
|
|
302
|
+
const lanes = [report.research, report.worker, report.search, report.toolCall, report.digest];
|
|
303
|
+
const gradedLanes = lanes.filter((lane) => lane.total > 0);
|
|
304
|
+
const judgeGraded = report.judge.total > 0;
|
|
305
|
+
if (gradedLanes.length === 0 && !judgeGraded)
|
|
306
|
+
return false;
|
|
307
|
+
const lanesAllFailed = gradedLanes.length > 0 && gradedLanes.every((lane) => lane.succeeded === 0);
|
|
308
|
+
const judgeFailed = !judgeGraded || report.judge.parsed === 0;
|
|
309
|
+
return lanesAllFailed && judgeFailed;
|
|
310
|
+
}
|
|
290
311
|
/** Compact human-readable report for tool output / interactive display. Bounded, no raw dumps. */
|
|
291
312
|
export function formatModelFitnessReport(model, report) {
|
|
292
313
|
const speed = (tokensPerSecond) => tokensPerSecond !== undefined ? `, ~${tokensPerSecond} tok/s` : "";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-fitness.js","sourceRoot":"","sources":["../../../src/core/research/model-fitness.ts"],"names":[],"mappings":"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","sourcesContent":["import { runBoundedCompletion } from \"../autonomy/bounded-completion.ts\";\nimport type { CapabilityEnvelope } from \"../autonomy/contracts.ts\";\nimport { CURATION_DIGEST_SYSTEM_PROMPT } from \"../context/brain-curator.ts\";\nimport { runWorker } from \"../delegation/worker-runner.ts\";\nimport { runRouteJudge } from \"../model-router/route-judge.ts\";\nimport { runResearch } from \"./research-runner.ts\";\n\n/**\n * Model fitness probe: measures whether a candidate model can actually drive the harness's\n * subagent contracts — the research lane, the scout-worker lane, and the routing judge — by\n * running each real runner against the model and scoring parse/success rates plus judge\n * discrimination. Provider-free: the completion executor is injected, so this works against any\n * registered model (local Ollama models included) and against faux providers in tests.\n */\n\nexport interface FitnessCompletion {\n\ttext: string;\n\tcostUsd: number;\n\tstopReason: string;\n\t/** Output tokens generated (for tok/s). Optional: providers that don't report it are skipped. */\n\toutputTokens?: number;\n\t/** Pure generation time in ms (e.g. Ollama eval_duration). Falls back to wall-clock if absent. */\n\tevalMs?: number;\n}\n\nexport type FitnessComplete = (args: {\n\tsystemPrompt: string;\n\tuserPrompt: string;\n\tsignal?: AbortSignal;\n}) => Promise<FitnessCompletion>;\n\nexport interface JudgeFitnessPrompt {\n\tprompt: string;\n\t/** True when the prompt is planning-shaped and must never route cheap. */\n\tplanning: boolean;\n}\n\n/** Default judge probe set: three planning-shaped prompts, three trivial lookups. */\nexport const DEFAULT_JUDGE_FITNESS_PROMPTS: readonly JudgeFitnessPrompt[] = [\n\t{ prompt: \"how should we plan the migration of the session storage layer?\", planning: true },\n\t{ prompt: \"design an approach for splitting the settings manager\", planning: true },\n\t{ prompt: \"draft a roadmap for the autonomy rework\", planning: true },\n\t{ prompt: \"what does the resolvePath function return?\", planning: false },\n\t{ prompt: \"list the files in the delegation module\", planning: false },\n\t{ prompt: \"why is this test flaky?\", planning: false },\n];\n\nexport interface ModelFitnessOptions {\n\tcomplete: FitnessComplete;\n\t/** Trials per lane surface. Default 3. */\n\ttrials?: number;\n\t/** Wall-clock budget per call in ms. Default 120000. */\n\tmaxWallClockMs?: number;\n\tjudgePrompts?: readonly JudgeFitnessPrompt[];\n\tsignal?: AbortSignal;\n\t/** Injected clock for latency measurement (test seam). Defaults to Date.now. */\n\tnow?: () => number;\n}\n\nexport interface LaneFitnessScore {\n\tsucceeded: number;\n\ttotal: number;\n\toutcomes: string[];\n\tmeanMs: number;\n\t/** Mean output tokens/second across the surface's calls; undefined when not reported. */\n\ttokensPerSecond?: number;\n}\n\nexport interface JudgeFitnessScore {\n\tparsed: number;\n\tplanningElevated: number;\n\tplanningTotal: number;\n\ttrivialCheap: number;\n\ttrivialTotal: number;\n\ttotal: number;\n\toutcomes: string[];\n\tmeanMs: number;\n\t/** Mean output tokens/second across the judge calls; undefined when not reported. */\n\ttokensPerSecond?: number;\n}\n\nexport interface ModelFitnessReport {\n\ttrials: number;\n\t/** Aggregate output tokens/second across ALL probe calls (the headline speed number). */\n\ttokensPerSecond?: number;\n\tresearch: LaneFitnessScore;\n\tworker: LaneFitnessScore;\n\tjudge: JudgeFitnessScore;\n\t/** Heavy-lifter surface: can the model formulate a structured search plan? */\n\tsearch: LaneFitnessScore;\n\t/** Heavy-lifter surface: can the model emit a well-formed tool call against a schema? */\n\ttoolCall: LaneFitnessScore;\n\t/** Curator surface: can the model digest a context chunk to strict JSON WITHOUT losing key facts? */\n\tdigest: LaneFitnessScore;\n\ttotalCostUsd: number;\n}\n\n/** Static prompts for the heavy-lifter surfaces (stable for provider prompt caching). */\nexport const SEARCH_PROBE_SYSTEM_PROMPT = [\n\t\"You plan code searches for a coding agent. You never answer the question yourself.\",\n\t\"Given a question about a codebase, respond with STRICT JSON only - no prose:\",\n\t'{\"queries\":[{\"pattern\":\"<regex or literal to grep>\",\"glob\":\"<file glob like **/*.ts>\"}]}',\n\t\"Return 1 to 4 queries, most specific first.\",\n].join(\"\\n\");\n\nexport const TOOL_CALL_PROBE_SYSTEM_PROMPT = [\n\t\"You operate tools for a coding agent. You have exactly one tool:\",\n\t\"grep(pattern: string, path: string) - search files under a path for a pattern.\",\n\t\"Respond to every task with STRICT JSON only - no prose:\",\n\t'{\"tool\":\"grep\",\"arguments\":{\"pattern\":\"<pattern>\",\"path\":\"<path>\"}}',\n].join(\"\\n\");\n\nconst SEARCH_PROBE_TASKS: readonly string[] = [\n\t\"Where is the retry/backoff logic for HTTP requests implemented?\",\n\t\"Which files define the settings for background research?\",\n\t\"Find where session entries of type custom are appended.\",\n];\n\n// The probe measures the REAL curation contract — same prompt the BrainCurator ships.\nexport { CURATION_DIGEST_SYSTEM_PROMPT as DIGEST_PROBE_SYSTEM_PROMPT } from \"../context/brain-curator.ts\";\n\n/**\n * Digest probe chunks each carry a NONCE identifier that cannot be guessed from the\n * instructions: acceptance requires the digest to RETAIN the nonce verbatim, so the score\n * measures extraction fidelity, not narration (a model cannot pass by paraphrasing).\n */\nconst DIGEST_PROBE_TASKS: readonly { chunk: string; nonce: string }[] = [\n\t{\n\t\tnonce: \"retryWithJitter_zx41\",\n\t\tchunk: [\n\t\t\t\"grep results for 'retry' under src/http:\",\n\t\t\t\"src/http/client.ts:88: export function retryWithJitter_zx41(fn, attempts = 3) {\",\n\t\t\t\"src/http/client.ts:112: // exponential backoff capped at 30s\",\n\t\t\t\"src/http/pool.ts:41: client.retry = false\",\n\t\t].join(\"\\n\"),\n\t},\n\t{\n\t\tnonce: \"ERR_QM_7734\",\n\t\tchunk: [\n\t\t\t\"$ npm run migrate\",\n\t\t\t\"migrating 14 files...\",\n\t\t\t\"error ERR_QM_7734: column 'owner_id' missing on table sessions (migration 0009)\",\n\t\t\t\"exit code 1\",\n\t\t].join(\"\\n\"),\n\t},\n\t{\n\t\tnonce: \"v3.9.2-hotfix.1\",\n\t\tchunk: [\n\t\t\t\"read package.json (34 lines):\",\n\t\t\t' \"name\": \"acme-billing\",',\n\t\t\t' \"version\": \"v3.9.2-hotfix.1\",',\n\t\t\t' \"engines\": { \"node\": \">=22\" },',\n\t\t].join(\"\\n\"),\n\t},\n];\n\nfunction parseDigest(text: string, nonce: string): boolean {\n\tconst parsed = extractJsonObject(text);\n\tif (!parsed) return false;\n\tconst digest = (parsed as { digest?: unknown }).digest;\n\tif (typeof digest !== \"string\") return false;\n\tconst trimmed = digest.trim();\n\t// Bounded and faithful: short enough to be a stub annotation, still carrying the nonce fact.\n\treturn trimmed.length > 0 && trimmed.length <= 240 && trimmed.includes(nonce);\n}\n\nconst TOOL_CALL_PROBE_TASKS: readonly string[] = [\n\t\"Find usages of the function resolveCliModel under src/.\",\n\t\"Search for the string 'budget_exhausted' in the core directory.\",\n\t\"Locate where LaneTracker is instantiated under src/core.\",\n];\n\nfunction parseSearchPlan(text: string): boolean {\n\tconst parsed = extractJsonObject(text);\n\tif (!parsed) return false;\n\tconst queries = (parsed as { queries?: unknown }).queries;\n\tif (!Array.isArray(queries) || queries.length === 0 || queries.length > 8) return false;\n\treturn queries.every(\n\t\t(query) =>\n\t\t\tquery &&\n\t\t\ttypeof query === \"object\" &&\n\t\t\ttypeof (query as { pattern?: unknown }).pattern === \"string\" &&\n\t\t\t(query as { pattern: string }).pattern.trim().length > 0,\n\t);\n}\n\nfunction parseToolCall(text: string): boolean {\n\tconst parsed = extractJsonObject(text);\n\tif (!parsed) return false;\n\tconst record = parsed as { tool?: unknown; arguments?: unknown };\n\tif (record.tool !== \"grep\") return false;\n\tconst args = record.arguments;\n\tif (!args || typeof args !== \"object\" || Array.isArray(args)) return false;\n\tconst pattern = (args as { pattern?: unknown }).pattern;\n\tconst path = (args as { path?: unknown }).path;\n\treturn (\n\t\ttypeof pattern === \"string\" && pattern.trim().length > 0 && typeof path === \"string\" && path.trim().length > 0\n\t);\n}\n\nfunction extractJsonObject(text: string): unknown | undefined {\n\tconst trimmed = text.trim();\n\tconst candidates: string[] = [trimmed];\n\tconst fenced = /```(?:json)?\\s*([\\s\\S]*?)```/.exec(trimmed);\n\tif (fenced?.[1]) candidates.push(fenced[1].trim());\n\tconst start = trimmed.indexOf(\"{\");\n\tconst end = trimmed.lastIndexOf(\"}\");\n\tif (start >= 0 && end > start) candidates.push(trimmed.slice(start, end + 1));\n\tfor (const candidate of candidates) {\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(candidate);\n\t\t\tif (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) return parsed;\n\t\t} catch {\n\t\t\t// try next candidate\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction fitnessEnvelope(): CapabilityEnvelope {\n\treturn {\n\t\tid: \"model-fitness-probe\",\n\t\tcapabilities: [\"research\", \"read_files\", \"memory_read\"],\n\t\tmaxEstimatedUsd: 1,\n\t\tcreatedAt: new Date().toISOString(),\n\t};\n}\n\nexport async function runModelFitnessProbe(options: ModelFitnessOptions): Promise<ModelFitnessReport> {\n\tconst trials = Math.max(1, Math.min(options.trials ?? 3, 20));\n\tconst maxWallClockMs = options.maxWallClockMs ?? 120_000;\n\tconst judgePrompts = options.judgePrompts ?? DEFAULT_JUDGE_FITNESS_PROMPTS;\n\tconst now = options.now ?? Date.now;\n\tlet totalCostUsd = 0;\n\n\t// Token-speed instrumentation: the lane runners' own contracts carry text/cost only, so the\n\t// completer is wrapped once here and generation stats are accumulated per surface.\n\tconst overallSpeed = { tokens: 0, evalMs: 0 };\n\tlet surfaceSpeed = { tokens: 0, evalMs: 0 };\n\tconst complete: FitnessComplete = async (args) => {\n\t\tconst completion = await options.complete(args);\n\t\tconst tokens = completion.outputTokens ?? 0;\n\t\tconst evalMs = completion.evalMs ?? 0;\n\t\tif (tokens > 0 && evalMs > 0) {\n\t\t\tsurfaceSpeed.tokens += tokens;\n\t\t\tsurfaceSpeed.evalMs += evalMs;\n\t\t\toverallSpeed.tokens += tokens;\n\t\t\toverallSpeed.evalMs += evalMs;\n\t\t}\n\t\treturn completion;\n\t};\n\tconst takeSurfaceSpeed = (): number | undefined => {\n\t\tconst speed =\n\t\t\tsurfaceSpeed.evalMs > 0 ? Math.round((surfaceSpeed.tokens / surfaceSpeed.evalMs) * 1000) : undefined;\n\t\tsurfaceSpeed = { tokens: 0, evalMs: 0 };\n\t\treturn speed;\n\t};\n\n\tconst research: LaneFitnessScore = { succeeded: 0, total: trials, outcomes: [], meanMs: 0 };\n\tfor (let i = 0; i < trials; i++) {\n\t\tconst started = now();\n\t\tconst result = await runResearch({\n\t\t\tquery: `fitness:probe requirements:req-${i}`,\n\t\t\tcontext: [\n\t\t\t\t\"Goal: add a retry helper to the HTTP client module\",\n\t\t\t\t\"Open requirements:\",\n\t\t\t\t\"- Find what retry/backoff conventions the codebase already uses\",\n\t\t\t\t\"- Identify which call sites would adopt the helper\",\n\t\t\t].join(\"\\n\"),\n\t\t\tenvelope: fitnessEnvelope(),\n\t\t\tmaxUsd: 1,\n\t\t\tmaxSources: 8,\n\t\t\tmaxFindings: 5,\n\t\t\tmaxWallClockMs,\n\t\t\tsignal: options.signal,\n\t\t\tcomplete,\n\t\t});\n\t\tresearch.meanMs += now() - started;\n\t\ttotalCostUsd += result.costUsd;\n\t\tif (result.status === \"succeeded\") research.succeeded++;\n\t\tresearch.outcomes.push(`${result.status}/${result.reasonCode}`);\n\t}\n\tresearch.meanMs = Math.round(research.meanMs / trials);\n\tresearch.tokensPerSecond = takeSurfaceSpeed();\n\n\tconst worker: LaneFitnessScore = { succeeded: 0, total: trials, outcomes: [], meanMs: 0 };\n\tfor (let i = 0; i < trials; i++) {\n\t\tconst started = now();\n\t\tconst outcome = await runWorker({\n\t\t\trequest: {\n\t\t\t\tid: `fitness-worker-${i}`,\n\t\t\t\tinstructions:\n\t\t\t\t\t\"Summarize in two sentences what a capability envelope is: a declared set of allowed tools, paths, and capability names that bounds what a delegated worker may do.\",\n\t\t\t\troute: { tier: \"cheap\", risk: \"read-only\", confidence: 1, reasonCode: \"fitness_probe\", reasons: [] },\n\t\t\t\tenvelope: { id: `fitness-env-${i}`, capabilities: [\"read_files\"], maxEstimatedUsd: 1 },\n\t\t\t\tmaxEstimatedUsd: 1,\n\t\t\t},\n\t\t\tmaxUsd: 1,\n\t\t\tmaxWallClockMs,\n\t\t\tusageReportId: `fitness:${i}`,\n\t\t\tsignal: options.signal,\n\t\t\tcomplete,\n\t\t});\n\t\tworker.meanMs += now() - started;\n\t\ttotalCostUsd += outcome.costUsd;\n\t\tif (outcome.result.status === \"completed\" && outcome.accepted) worker.succeeded++;\n\t\tworker.outcomes.push(`${outcome.result.status}/${outcome.reasonCode}`);\n\t}\n\tworker.meanMs = Math.round(worker.meanMs / trials);\n\tworker.tokensPerSecond = takeSurfaceSpeed();\n\n\tconst judge: JudgeFitnessScore = {\n\t\tparsed: 0,\n\t\tplanningElevated: 0,\n\t\tplanningTotal: judgePrompts.filter((entry) => entry.planning).length,\n\t\ttrivialCheap: 0,\n\t\ttrivialTotal: judgePrompts.filter((entry) => !entry.planning).length,\n\t\ttotal: judgePrompts.length,\n\t\toutcomes: [],\n\t\tmeanMs: 0,\n\t};\n\tfor (const entry of judgePrompts) {\n\t\tconst started = now();\n\t\tconst result = await runRouteJudge({\n\t\t\tprompt: entry.prompt,\n\t\t\tbaseline: { tier: \"cheap\", risk: \"read-only\", confidence: 0.5, reasonCode: \"fitness_probe\", reasons: [] },\n\t\t\tmaxWallClockMs,\n\t\t\tsignal: options.signal,\n\t\t\tcomplete,\n\t\t});\n\t\tjudge.meanMs += now() - started;\n\t\ttotalCostUsd += result.costUsd;\n\t\tconst tier = result.decision.tier;\n\t\tif (result.verdict) {\n\t\t\tjudge.parsed++;\n\t\t\t// A useful judge must both keep planning off the cheap tier AND actually send trivial\n\t\t\t// prompts there — all-medium verdicts are safe but save nothing.\n\t\t\tif (entry.planning && tier !== \"cheap\") judge.planningElevated++;\n\t\t\tif (!entry.planning && tier === \"cheap\") judge.trivialCheap++;\n\t\t}\n\t\tjudge.outcomes.push(\n\t\t\t`\"${entry.prompt.slice(0, 40)}\" -> ${tier}${result.fallbackReason ? ` (${result.fallbackReason})` : \"\"}`,\n\t\t);\n\t}\n\tjudge.meanMs = judgePrompts.length > 0 ? Math.round(judge.meanMs / judgePrompts.length) : 0;\n\tjudge.tokensPerSecond = takeSurfaceSpeed();\n\n\tconst probeSurface = async (\n\t\tsystemPrompt: string,\n\t\ttasks: readonly string[],\n\t\taccepts: (text: string, taskIndex: number) => boolean,\n\t): Promise<LaneFitnessScore> => {\n\t\tconst score: LaneFitnessScore = { succeeded: 0, total: tasks.length, outcomes: [], meanMs: 0 };\n\t\tfor (const [taskIndex, task] of tasks.entries()) {\n\t\t\tconst started = now();\n\t\t\t// Same wall-clock envelope as the lane surfaces — a hung model must not hang the probe.\n\t\t\tconst bounded = await runBoundedCompletion({\n\t\t\t\tmaxWallClockMs,\n\t\t\t\tsignal: options.signal,\n\t\t\t\texecute: (signal) => complete({ systemPrompt, userPrompt: task, signal }),\n\t\t\t});\n\t\t\tif (bounded.completion) totalCostUsd += bounded.completion.costUsd;\n\t\t\tif (bounded.failure || !bounded.completion) {\n\t\t\t\tscore.outcomes.push(bounded.failure ? bounded.failure.status : \"completion_error\");\n\t\t\t} else {\n\t\t\t\tconst ok = accepts(bounded.completion.text, taskIndex);\n\t\t\t\tif (ok) score.succeeded++;\n\t\t\t\tscore.outcomes.push(ok ? \"ok\" : \"unparseable_output\");\n\t\t\t}\n\t\t\tscore.meanMs += now() - started;\n\t\t}\n\t\tscore.meanMs = tasks.length > 0 ? Math.round(score.meanMs / tasks.length) : 0;\n\t\treturn score;\n\t};\n\n\tconst search = await probeSurface(SEARCH_PROBE_SYSTEM_PROMPT, SEARCH_PROBE_TASKS, parseSearchPlan);\n\tsearch.tokensPerSecond = takeSurfaceSpeed();\n\tconst toolCall = await probeSurface(TOOL_CALL_PROBE_SYSTEM_PROMPT, TOOL_CALL_PROBE_TASKS, parseToolCall);\n\ttoolCall.tokensPerSecond = takeSurfaceSpeed();\n\tconst digest = await probeSurface(\n\t\tCURATION_DIGEST_SYSTEM_PROMPT,\n\t\tDIGEST_PROBE_TASKS.map((task) => task.chunk),\n\t\t(text, taskIndex) => parseDigest(text, DIGEST_PROBE_TASKS[taskIndex]!.nonce),\n\t);\n\tdigest.tokensPerSecond = takeSurfaceSpeed();\n\n\tconst tokensPerSecond =\n\t\toverallSpeed.evalMs > 0 ? Math.round((overallSpeed.tokens / overallSpeed.evalMs) * 1000) : undefined;\n\n\treturn { trials, tokensPerSecond, research, worker, judge, search, toolCall, digest, totalCostUsd };\n}\n\n/** Compact human-readable report for tool output / interactive display. Bounded, no raw dumps. */\nexport function formatModelFitnessReport(model: string, report: ModelFitnessReport): string {\n\tconst speed = (tokensPerSecond: number | undefined) =>\n\t\ttokensPerSecond !== undefined ? `, ~${tokensPerSecond} tok/s` : \"\";\n\tconst lines = [\n\t\t`Model fitness: ${model} (${report.trials} trials/lane${speed(report.tokensPerSecond)})`,\n\t\t`- research lane: ${report.research.succeeded}/${report.research.total} succeeded, mean ${report.research.meanMs}ms${speed(report.research.tokensPerSecond)} [${report.research.outcomes.join(\", \")}]`,\n\t\t`- worker lane: ${report.worker.succeeded}/${report.worker.total} completed+accepted, mean ${report.worker.meanMs}ms${speed(report.worker.tokensPerSecond)} [${report.worker.outcomes.join(\", \")}]`,\n\t\t`- search plans: ${report.search.succeeded}/${report.search.total} well-formed, mean ${report.search.meanMs}ms${speed(report.search.tokensPerSecond)}`,\n\t\t`- tool calls: ${report.toolCall.succeeded}/${report.toolCall.total} well-formed, mean ${report.toolCall.meanMs}ms${speed(report.toolCall.tokensPerSecond)}`,\n\t\t`- digests: ${report.digest.succeeded}/${report.digest.total} faithful, mean ${report.digest.meanMs}ms${speed(report.digest.tokensPerSecond)}`,\n\t\t`- route judge: parsed ${report.judge.parsed}/${report.judge.total}, planning-elevated ${report.judge.planningElevated}/${report.judge.planningTotal}, trivial-cheap ${report.judge.trivialCheap}/${report.judge.trivialTotal}, mean ${report.judge.meanMs}ms${speed(report.judge.tokensPerSecond)}`,\n\t\t...report.judge.outcomes.map((outcome) => ` ${outcome}`),\n\t];\n\tif (report.totalCostUsd > 0) {\n\t\tlines.push(`- probe cost: $${report.totalCostUsd.toFixed(4)}`);\n\t}\n\treturn lines.join(\"\\n\");\n}\n"]}
|
|
1
|
+
{"version":3,"file":"model-fitness.js","sourceRoot":"","sources":["../../../src/core/research/model-fitness.ts"],"names":[],"mappings":"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","sourcesContent":["import { runBoundedCompletion } from \"../autonomy/bounded-completion.ts\";\nimport type { CapabilityEnvelope } from \"../autonomy/contracts.ts\";\nimport { CURATION_DIGEST_SYSTEM_PROMPT } from \"../context/brain-curator.ts\";\nimport { runWorker } from \"../delegation/worker-runner.ts\";\nimport { runRouteJudge } from \"../model-router/route-judge.ts\";\nimport { runResearch } from \"./research-runner.ts\";\n\n/**\n * Model fitness probe: measures whether a candidate model can actually drive the harness's\n * subagent contracts — the research lane, the scout-worker lane, and the routing judge — by\n * running each real runner against the model and scoring parse/success rates plus judge\n * discrimination. Provider-free: the completion executor is injected, so this works against any\n * registered model (local Ollama models included) and against faux providers in tests.\n */\n\nexport interface FitnessCompletion {\n\ttext: string;\n\tcostUsd: number;\n\tstopReason: string;\n\t/** Output tokens generated (for tok/s). Optional: providers that don't report it are skipped. */\n\toutputTokens?: number;\n\t/** Pure generation time in ms (e.g. Ollama eval_duration). Falls back to wall-clock if absent. */\n\tevalMs?: number;\n}\n\nexport type FitnessComplete = (args: {\n\tsystemPrompt: string;\n\tuserPrompt: string;\n\tsignal?: AbortSignal;\n}) => Promise<FitnessCompletion>;\n\nexport interface JudgeFitnessPrompt {\n\tprompt: string;\n\t/** True when the prompt is planning-shaped and must never route cheap. */\n\tplanning: boolean;\n}\n\n/** Default judge probe set: three planning-shaped prompts, three trivial lookups. */\nexport const DEFAULT_JUDGE_FITNESS_PROMPTS: readonly JudgeFitnessPrompt[] = [\n\t{ prompt: \"how should we plan the migration of the session storage layer?\", planning: true },\n\t{ prompt: \"design an approach for splitting the settings manager\", planning: true },\n\t{ prompt: \"draft a roadmap for the autonomy rework\", planning: true },\n\t{ prompt: \"what does the resolvePath function return?\", planning: false },\n\t{ prompt: \"list the files in the delegation module\", planning: false },\n\t{ prompt: \"why is this test flaky?\", planning: false },\n];\n\nexport interface ModelFitnessOptions {\n\tcomplete: FitnessComplete;\n\t/** Trials per lane surface. Default 3. */\n\ttrials?: number;\n\t/** Wall-clock budget per call in ms. Default 120000. */\n\tmaxWallClockMs?: number;\n\tjudgePrompts?: readonly JudgeFitnessPrompt[];\n\tsignal?: AbortSignal;\n\t/** Injected clock for latency measurement (test seam). Defaults to Date.now. */\n\tnow?: () => number;\n}\n\nexport interface LaneFitnessScore {\n\tsucceeded: number;\n\ttotal: number;\n\toutcomes: string[];\n\tmeanMs: number;\n\t/** Mean output tokens/second across the surface's calls; undefined when not reported. */\n\ttokensPerSecond?: number;\n}\n\nexport interface JudgeFitnessScore {\n\tparsed: number;\n\tplanningElevated: number;\n\tplanningTotal: number;\n\ttrivialCheap: number;\n\ttrivialTotal: number;\n\ttotal: number;\n\toutcomes: string[];\n\tmeanMs: number;\n\t/** Mean output tokens/second across the judge calls; undefined when not reported. */\n\ttokensPerSecond?: number;\n}\n\nexport interface ModelFitnessReport {\n\ttrials: number;\n\t/** Aggregate output tokens/second across ALL probe calls (the headline speed number). */\n\ttokensPerSecond?: number;\n\tresearch: LaneFitnessScore;\n\tworker: LaneFitnessScore;\n\tjudge: JudgeFitnessScore;\n\t/** Heavy-lifter surface: can the model formulate a structured search plan? */\n\tsearch: LaneFitnessScore;\n\t/** Heavy-lifter surface: can the model emit a well-formed tool call against a schema? */\n\ttoolCall: LaneFitnessScore;\n\t/** Curator surface: can the model digest a context chunk to strict JSON WITHOUT losing key facts? */\n\tdigest: LaneFitnessScore;\n\ttotalCostUsd: number;\n}\n\n/** Static prompts for the heavy-lifter surfaces (stable for provider prompt caching). */\nexport const SEARCH_PROBE_SYSTEM_PROMPT = [\n\t\"You plan code searches for a coding agent. You never answer the question yourself.\",\n\t\"Given a question about a codebase, respond with STRICT JSON only - no prose:\",\n\t'{\"queries\":[{\"pattern\":\"<regex or literal to grep>\",\"glob\":\"<file glob like **/*.ts>\"}]}',\n\t\"Return 1 to 4 queries, most specific first.\",\n].join(\"\\n\");\n\nexport const TOOL_CALL_PROBE_SYSTEM_PROMPT = [\n\t\"You operate tools for a coding agent. You have exactly one tool:\",\n\t\"grep(pattern: string, path: string) - search files under a path for a pattern.\",\n\t\"Respond to every task with STRICT JSON only - no prose:\",\n\t'{\"tool\":\"grep\",\"arguments\":{\"pattern\":\"<pattern>\",\"path\":\"<path>\"}}',\n].join(\"\\n\");\n\nconst SEARCH_PROBE_TASKS: readonly string[] = [\n\t\"Where is the retry/backoff logic for HTTP requests implemented?\",\n\t\"Which files define the settings for background research?\",\n\t\"Find where session entries of type custom are appended.\",\n];\n\n// The probe measures the REAL curation contract — same prompt the BrainCurator ships.\nexport { CURATION_DIGEST_SYSTEM_PROMPT as DIGEST_PROBE_SYSTEM_PROMPT } from \"../context/brain-curator.ts\";\n\n/**\n * Digest probe chunks each carry a NONCE identifier that cannot be guessed from the\n * instructions: acceptance requires the digest to RETAIN the nonce verbatim, so the score\n * measures extraction fidelity, not narration (a model cannot pass by paraphrasing).\n */\nconst DIGEST_PROBE_TASKS: readonly { chunk: string; nonce: string }[] = [\n\t{\n\t\tnonce: \"retryWithJitter_zx41\",\n\t\tchunk: [\n\t\t\t\"grep results for 'retry' under src/http:\",\n\t\t\t\"src/http/client.ts:88: export function retryWithJitter_zx41(fn, attempts = 3) {\",\n\t\t\t\"src/http/client.ts:112: // exponential backoff capped at 30s\",\n\t\t\t\"src/http/pool.ts:41: client.retry = false\",\n\t\t].join(\"\\n\"),\n\t},\n\t{\n\t\tnonce: \"ERR_QM_7734\",\n\t\tchunk: [\n\t\t\t\"$ npm run migrate\",\n\t\t\t\"migrating 14 files...\",\n\t\t\t\"error ERR_QM_7734: column 'owner_id' missing on table sessions (migration 0009)\",\n\t\t\t\"exit code 1\",\n\t\t].join(\"\\n\"),\n\t},\n\t{\n\t\tnonce: \"v3.9.2-hotfix.1\",\n\t\tchunk: [\n\t\t\t\"read package.json (34 lines):\",\n\t\t\t' \"name\": \"acme-billing\",',\n\t\t\t' \"version\": \"v3.9.2-hotfix.1\",',\n\t\t\t' \"engines\": { \"node\": \">=22\" },',\n\t\t].join(\"\\n\"),\n\t},\n];\n\nfunction parseDigest(text: string, nonce: string): boolean {\n\tconst parsed = extractJsonObject(text);\n\tif (!parsed) return false;\n\tconst digest = (parsed as { digest?: unknown }).digest;\n\tif (typeof digest !== \"string\") return false;\n\tconst trimmed = digest.trim();\n\t// Bounded and faithful: short enough to be a stub annotation, still carrying the nonce fact.\n\treturn trimmed.length > 0 && trimmed.length <= 240 && trimmed.includes(nonce);\n}\n\nconst TOOL_CALL_PROBE_TASKS: readonly string[] = [\n\t\"Find usages of the function resolveCliModel under src/.\",\n\t\"Search for the string 'budget_exhausted' in the core directory.\",\n\t\"Locate where LaneTracker is instantiated under src/core.\",\n];\n\nfunction parseSearchPlan(text: string): boolean {\n\tconst parsed = extractJsonObject(text);\n\tif (!parsed) return false;\n\tconst queries = (parsed as { queries?: unknown }).queries;\n\tif (!Array.isArray(queries) || queries.length === 0 || queries.length > 8) return false;\n\treturn queries.every(\n\t\t(query) =>\n\t\t\tquery &&\n\t\t\ttypeof query === \"object\" &&\n\t\t\ttypeof (query as { pattern?: unknown }).pattern === \"string\" &&\n\t\t\t(query as { pattern: string }).pattern.trim().length > 0,\n\t);\n}\n\nfunction parseToolCall(text: string): boolean {\n\tconst parsed = extractJsonObject(text);\n\tif (!parsed) return false;\n\tconst record = parsed as { tool?: unknown; arguments?: unknown };\n\tif (record.tool !== \"grep\") return false;\n\tconst args = record.arguments;\n\tif (!args || typeof args !== \"object\" || Array.isArray(args)) return false;\n\tconst pattern = (args as { pattern?: unknown }).pattern;\n\tconst path = (args as { path?: unknown }).path;\n\treturn (\n\t\ttypeof pattern === \"string\" && pattern.trim().length > 0 && typeof path === \"string\" && path.trim().length > 0\n\t);\n}\n\nfunction extractJsonObject(text: string): unknown | undefined {\n\tconst trimmed = text.trim();\n\tconst candidates: string[] = [trimmed];\n\tconst fenced = /```(?:json)?\\s*([\\s\\S]*?)```/.exec(trimmed);\n\tif (fenced?.[1]) candidates.push(fenced[1].trim());\n\tconst start = trimmed.indexOf(\"{\");\n\tconst end = trimmed.lastIndexOf(\"}\");\n\tif (start >= 0 && end > start) candidates.push(trimmed.slice(start, end + 1));\n\tfor (const candidate of candidates) {\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(candidate);\n\t\t\tif (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) return parsed;\n\t\t} catch {\n\t\t\t// try next candidate\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction fitnessEnvelope(): CapabilityEnvelope {\n\treturn {\n\t\tid: \"model-fitness-probe\",\n\t\tcapabilities: [\"research\", \"read_files\", \"memory_read\"],\n\t\tmaxEstimatedUsd: 1,\n\t\tcreatedAt: new Date().toISOString(),\n\t};\n}\n\nexport async function runModelFitnessProbe(options: ModelFitnessOptions): Promise<ModelFitnessReport> {\n\tconst trials = Math.max(1, Math.min(options.trials ?? 3, 20));\n\tconst maxWallClockMs = options.maxWallClockMs ?? 120_000;\n\tconst judgePrompts = options.judgePrompts ?? DEFAULT_JUDGE_FITNESS_PROMPTS;\n\tconst now = options.now ?? Date.now;\n\tlet totalCostUsd = 0;\n\n\t// Token-speed instrumentation: the lane runners' own contracts carry text/cost only, so the\n\t// completer is wrapped once here and generation stats are accumulated per surface.\n\tconst overallSpeed = { tokens: 0, evalMs: 0 };\n\tlet surfaceSpeed = { tokens: 0, evalMs: 0 };\n\tconst complete: FitnessComplete = async (args) => {\n\t\tconst completion = await options.complete(args);\n\t\tconst tokens = completion.outputTokens ?? 0;\n\t\tconst evalMs = completion.evalMs ?? 0;\n\t\tif (tokens > 0 && evalMs > 0) {\n\t\t\tsurfaceSpeed.tokens += tokens;\n\t\t\tsurfaceSpeed.evalMs += evalMs;\n\t\t\toverallSpeed.tokens += tokens;\n\t\t\toverallSpeed.evalMs += evalMs;\n\t\t}\n\t\treturn completion;\n\t};\n\tconst takeSurfaceSpeed = (): number | undefined => {\n\t\tconst speed =\n\t\t\tsurfaceSpeed.evalMs > 0 ? Math.round((surfaceSpeed.tokens / surfaceSpeed.evalMs) * 1000) : undefined;\n\t\tsurfaceSpeed = { tokens: 0, evalMs: 0 };\n\t\treturn speed;\n\t};\n\n\tconst research: LaneFitnessScore = { succeeded: 0, total: trials, outcomes: [], meanMs: 0 };\n\tfor (let i = 0; i < trials; i++) {\n\t\tconst started = now();\n\t\tconst result = await runResearch({\n\t\t\tquery: `fitness:probe requirements:req-${i}`,\n\t\t\tcontext: [\n\t\t\t\t\"Goal: add a retry helper to the HTTP client module\",\n\t\t\t\t\"Open requirements:\",\n\t\t\t\t\"- Find what retry/backoff conventions the codebase already uses\",\n\t\t\t\t\"- Identify which call sites would adopt the helper\",\n\t\t\t].join(\"\\n\"),\n\t\t\tenvelope: fitnessEnvelope(),\n\t\t\tmaxUsd: 1,\n\t\t\tmaxSources: 8,\n\t\t\tmaxFindings: 5,\n\t\t\tmaxWallClockMs,\n\t\t\tsignal: options.signal,\n\t\t\tcomplete,\n\t\t});\n\t\tresearch.meanMs += now() - started;\n\t\ttotalCostUsd += result.costUsd;\n\t\tif (result.status === \"succeeded\") research.succeeded++;\n\t\tresearch.outcomes.push(`${result.status}/${result.reasonCode}`);\n\t}\n\tresearch.meanMs = Math.round(research.meanMs / trials);\n\tresearch.tokensPerSecond = takeSurfaceSpeed();\n\n\tconst worker: LaneFitnessScore = { succeeded: 0, total: trials, outcomes: [], meanMs: 0 };\n\tfor (let i = 0; i < trials; i++) {\n\t\tconst started = now();\n\t\tconst outcome = await runWorker({\n\t\t\trequest: {\n\t\t\t\tid: `fitness-worker-${i}`,\n\t\t\t\tinstructions:\n\t\t\t\t\t\"Summarize in two sentences what a capability envelope is: a declared set of allowed tools, paths, and capability names that bounds what a delegated worker may do.\",\n\t\t\t\troute: { tier: \"cheap\", risk: \"read-only\", confidence: 1, reasonCode: \"fitness_probe\", reasons: [] },\n\t\t\t\tenvelope: { id: `fitness-env-${i}`, capabilities: [\"read_files\"], maxEstimatedUsd: 1 },\n\t\t\t\tmaxEstimatedUsd: 1,\n\t\t\t},\n\t\t\tmaxUsd: 1,\n\t\t\tmaxWallClockMs,\n\t\t\tusageReportId: `fitness:${i}`,\n\t\t\tsignal: options.signal,\n\t\t\tcomplete,\n\t\t});\n\t\tworker.meanMs += now() - started;\n\t\ttotalCostUsd += outcome.costUsd;\n\t\tif (outcome.result.status === \"completed\" && outcome.accepted) worker.succeeded++;\n\t\tworker.outcomes.push(`${outcome.result.status}/${outcome.reasonCode}`);\n\t}\n\tworker.meanMs = Math.round(worker.meanMs / trials);\n\tworker.tokensPerSecond = takeSurfaceSpeed();\n\n\tconst judge: JudgeFitnessScore = {\n\t\tparsed: 0,\n\t\tplanningElevated: 0,\n\t\tplanningTotal: judgePrompts.filter((entry) => entry.planning).length,\n\t\ttrivialCheap: 0,\n\t\ttrivialTotal: judgePrompts.filter((entry) => !entry.planning).length,\n\t\ttotal: judgePrompts.length,\n\t\toutcomes: [],\n\t\tmeanMs: 0,\n\t};\n\tfor (const entry of judgePrompts) {\n\t\tconst started = now();\n\t\tconst result = await runRouteJudge({\n\t\t\tprompt: entry.prompt,\n\t\t\tbaseline: { tier: \"cheap\", risk: \"read-only\", confidence: 0.5, reasonCode: \"fitness_probe\", reasons: [] },\n\t\t\tmaxWallClockMs,\n\t\t\tsignal: options.signal,\n\t\t\tcomplete,\n\t\t});\n\t\tjudge.meanMs += now() - started;\n\t\ttotalCostUsd += result.costUsd;\n\t\tconst tier = result.decision.tier;\n\t\tif (result.verdict) {\n\t\t\tjudge.parsed++;\n\t\t\t// A useful judge must both keep planning off the cheap tier AND actually send trivial\n\t\t\t// prompts there — all-medium verdicts are safe but save nothing.\n\t\t\tif (entry.planning && tier !== \"cheap\") judge.planningElevated++;\n\t\t\tif (!entry.planning && tier === \"cheap\") judge.trivialCheap++;\n\t\t}\n\t\tjudge.outcomes.push(\n\t\t\t`\"${entry.prompt.slice(0, 40)}\" -> ${tier}${result.fallbackReason ? ` (${result.fallbackReason})` : \"\"}`,\n\t\t);\n\t}\n\tjudge.meanMs = judgePrompts.length > 0 ? Math.round(judge.meanMs / judgePrompts.length) : 0;\n\tjudge.tokensPerSecond = takeSurfaceSpeed();\n\n\tconst probeSurface = async (\n\t\tsystemPrompt: string,\n\t\ttasks: readonly string[],\n\t\taccepts: (text: string, taskIndex: number) => boolean,\n\t): Promise<LaneFitnessScore> => {\n\t\tconst score: LaneFitnessScore = { succeeded: 0, total: tasks.length, outcomes: [], meanMs: 0 };\n\t\tfor (const [taskIndex, task] of tasks.entries()) {\n\t\t\tconst started = now();\n\t\t\t// Same wall-clock envelope as the lane surfaces — a hung model must not hang the probe.\n\t\t\tconst bounded = await runBoundedCompletion({\n\t\t\t\tmaxWallClockMs,\n\t\t\t\tsignal: options.signal,\n\t\t\t\texecute: (signal) => complete({ systemPrompt, userPrompt: task, signal }),\n\t\t\t});\n\t\t\tif (bounded.completion) totalCostUsd += bounded.completion.costUsd;\n\t\t\tif (bounded.failure || !bounded.completion) {\n\t\t\t\tscore.outcomes.push(bounded.failure ? bounded.failure.status : \"completion_error\");\n\t\t\t} else {\n\t\t\t\tconst ok = accepts(bounded.completion.text, taskIndex);\n\t\t\t\tif (ok) score.succeeded++;\n\t\t\t\tscore.outcomes.push(ok ? \"ok\" : \"unparseable_output\");\n\t\t\t}\n\t\t\tscore.meanMs += now() - started;\n\t\t}\n\t\tscore.meanMs = tasks.length > 0 ? Math.round(score.meanMs / tasks.length) : 0;\n\t\treturn score;\n\t};\n\n\tconst search = await probeSurface(SEARCH_PROBE_SYSTEM_PROMPT, SEARCH_PROBE_TASKS, parseSearchPlan);\n\tsearch.tokensPerSecond = takeSurfaceSpeed();\n\tconst toolCall = await probeSurface(TOOL_CALL_PROBE_SYSTEM_PROMPT, TOOL_CALL_PROBE_TASKS, parseToolCall);\n\ttoolCall.tokensPerSecond = takeSurfaceSpeed();\n\tconst digest = await probeSurface(\n\t\tCURATION_DIGEST_SYSTEM_PROMPT,\n\t\tDIGEST_PROBE_TASKS.map((task) => task.chunk),\n\t\t(text, taskIndex) => parseDigest(text, DIGEST_PROBE_TASKS[taskIndex]!.nonce),\n\t);\n\tdigest.tokensPerSecond = takeSurfaceSpeed();\n\n\tconst tokensPerSecond =\n\t\toverallSpeed.evalMs > 0 ? Math.round((overallSpeed.tokens / overallSpeed.evalMs) * 1000) : undefined;\n\n\treturn { trials, tokensPerSecond, research, worker, judge, search, toolCall, digest, totalCostUsd };\n}\n\n/**\n * Pure verdict: true when the probe found ZERO successes on every LANE surface it actually graded\n * AND the judge (if it ran) also failed. A lane/judge with total 0 (i.e. never run) carries no\n * evidence and is excluded from the lane check — but at least one lane must actually have been\n * graded for an all-failed verdict at all: `gradedLanes.every(...)` is vacuously true over an\n * empty array, so a report where only the judge ran (every research/worker/search/toolCall/digest\n * lane is ungraded) is excluded explicitly rather than misread as \"all lanes failed\" on zero lane\n * evidence. An empty/degenerate report (nothing graded at all, lanes AND judge) is likewise never\n * mistaken for a failed one. This is the gate adoption flows must consult before assigning a role —\n * see `isProbeAllFailed` callers in interactive-mode.ts and agent-session.ts.\n */\nexport function isProbeAllFailed(report: ModelFitnessReport): boolean {\n\tconst lanes = [report.research, report.worker, report.search, report.toolCall, report.digest];\n\tconst gradedLanes = lanes.filter((lane) => lane.total > 0);\n\tconst judgeGraded = report.judge.total > 0;\n\tif (gradedLanes.length === 0 && !judgeGraded) return false;\n\tconst lanesAllFailed = gradedLanes.length > 0 && gradedLanes.every((lane) => lane.succeeded === 0);\n\tconst judgeFailed = !judgeGraded || report.judge.parsed === 0;\n\treturn lanesAllFailed && judgeFailed;\n}\n\n/** Compact human-readable report for tool output / interactive display. Bounded, no raw dumps. */\nexport function formatModelFitnessReport(model: string, report: ModelFitnessReport): string {\n\tconst speed = (tokensPerSecond: number | undefined) =>\n\t\ttokensPerSecond !== undefined ? `, ~${tokensPerSecond} tok/s` : \"\";\n\tconst lines = [\n\t\t`Model fitness: ${model} (${report.trials} trials/lane${speed(report.tokensPerSecond)})`,\n\t\t`- research lane: ${report.research.succeeded}/${report.research.total} succeeded, mean ${report.research.meanMs}ms${speed(report.research.tokensPerSecond)} [${report.research.outcomes.join(\", \")}]`,\n\t\t`- worker lane: ${report.worker.succeeded}/${report.worker.total} completed+accepted, mean ${report.worker.meanMs}ms${speed(report.worker.tokensPerSecond)} [${report.worker.outcomes.join(\", \")}]`,\n\t\t`- search plans: ${report.search.succeeded}/${report.search.total} well-formed, mean ${report.search.meanMs}ms${speed(report.search.tokensPerSecond)}`,\n\t\t`- tool calls: ${report.toolCall.succeeded}/${report.toolCall.total} well-formed, mean ${report.toolCall.meanMs}ms${speed(report.toolCall.tokensPerSecond)}`,\n\t\t`- digests: ${report.digest.succeeded}/${report.digest.total} faithful, mean ${report.digest.meanMs}ms${speed(report.digest.tokensPerSecond)}`,\n\t\t`- route judge: parsed ${report.judge.parsed}/${report.judge.total}, planning-elevated ${report.judge.planningElevated}/${report.judge.planningTotal}, trivial-cheap ${report.judge.trivialCheap}/${report.judge.trivialTotal}, mean ${report.judge.meanMs}ms${speed(report.judge.tokensPerSecond)}`,\n\t\t...report.judge.outcomes.map((outcome) => ` ${outcome}`),\n\t];\n\tif (report.totalCostUsd > 0) {\n\t\tlines.push(`- probe cost: $${report.totalCostUsd.toFixed(4)}`);\n\t}\n\treturn lines.join(\"\\n\");\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { SessionEntry, SessionManager } from "@caupulican/pi-agent-core/node";
|
|
1
2
|
import type { EvidenceBundle } from "../autonomy/contracts.ts";
|
|
2
|
-
import type { SessionEntry, SessionManager } from "../session-manager.ts";
|
|
3
3
|
export declare const EVIDENCE_BUNDLE_CUSTOM_TYPE = "evidence_bundle";
|
|
4
4
|
export interface EvidenceBundleSnapshotPayload {
|
|
5
5
|
version: 1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-evidence-bundle.d.ts","sourceRoot":"","sources":["../../../src/core/research/session-evidence-bundle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"session-evidence-bundle.d.ts","sourceRoot":"","sources":["../../../src/core/research/session-evidence-bundle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACnF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG/D,eAAO,MAAM,2BAA2B,oBAAoB,CAAC;AAE7D,MAAM,WAAW,6BAA6B;IAC7C,OAAO,EAAE,CAAC,CAAC;IACX,MAAM,EAAE,cAAc,CAAC;CACvB;AAED,wBAAgB,4BAA4B,CAC3C,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,mBAAmB,CAAC,EACzD,MAAM,EAAE,cAAc,GACpB,MAAM,CAMR;AAQD,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,cAAc,EAAE,CAmB7F;AAED,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,cAAc,GAAG,SAAS,CAe5G","sourcesContent":["import type { SessionEntry, SessionManager } from \"@caupulican/pi-agent-core/node\";\nimport type { EvidenceBundle } from \"../autonomy/contracts.ts\";\nimport { cloneEvidenceBundleForStorage, isEvidenceBundle } from \"./evidence-bundle.ts\";\n\nexport const EVIDENCE_BUNDLE_CUSTOM_TYPE = \"evidence_bundle\";\n\nexport interface EvidenceBundleSnapshotPayload {\n\tversion: 1;\n\tbundle: EvidenceBundle;\n}\n\nexport function appendEvidenceBundleSnapshot(\n\tsessionManager: Pick<SessionManager, \"appendCustomEntry\">,\n\tbundle: EvidenceBundle,\n): string {\n\tconst payload: EvidenceBundleSnapshotPayload = {\n\t\tversion: 1,\n\t\tbundle: cloneEvidenceBundleForStorage(bundle),\n\t};\n\treturn sessionManager.appendCustomEntry(EVIDENCE_BUNDLE_CUSTOM_TYPE, payload);\n}\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst prototype = Object.getPrototypeOf(value);\n\treturn prototype === Object.prototype || prototype === null;\n}\n\nexport function getEvidenceBundleSnapshots(entries: readonly SessionEntry[]): EvidenceBundle[] {\n\tconst bundles: EvidenceBundle[] = [];\n\n\tfor (const entry of entries) {\n\t\tif (entry.type !== \"custom\" || entry.customType !== EVIDENCE_BUNDLE_CUSTOM_TYPE) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst payload = entry.data;\n\t\tif (!isPlainRecord(payload)) continue;\n\t\tif (payload.version !== 1) continue;\n\t\tif (!(\"bundle\" in payload)) continue;\n\t\tconst bundle = payload.bundle;\n\t\tif (isEvidenceBundle(bundle)) {\n\t\t\tbundles.push(cloneEvidenceBundleForStorage(bundle));\n\t\t}\n\t}\n\n\treturn bundles;\n}\n\nexport function getLatestEvidenceBundleSnapshot(entries: readonly SessionEntry[]): EvidenceBundle | undefined {\n\tfor (let i = entries.length - 1; i >= 0; i--) {\n\t\tconst entry = entries[i];\n\t\tif (entry.type === \"custom\" && entry.customType === EVIDENCE_BUNDLE_CUSTOM_TYPE) {\n\t\t\tconst payload = entry.data;\n\t\t\tif (!isPlainRecord(payload)) continue;\n\t\t\tif (payload.version !== 1) continue;\n\t\t\tif (!(\"bundle\" in payload)) continue;\n\t\t\tconst bundle = payload.bundle;\n\t\t\tif (isEvidenceBundle(bundle)) {\n\t\t\t\treturn cloneEvidenceBundleForStorage(bundle);\n\t\t\t}\n\t\t}\n\t}\n\treturn undefined;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-evidence-bundle.js","sourceRoot":"","sources":["../../../src/core/research/session-evidence-bundle.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,6BAA6B,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAEvF,MAAM,CAAC,MAAM,2BAA2B,GAAG,iBAAiB,CAAC;AAO7D,MAAM,UAAU,4BAA4B,CAC3C,cAAyD,EACzD,MAAsB,EACb;IACT,MAAM,OAAO,GAAkC;QAC9C,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,6BAA6B,CAAC,MAAM,CAAC;KAC7C,CAAC;IACF,OAAO,cAAc,CAAC,iBAAiB,CAAC,2BAA2B,EAAE,OAAO,CAAC,CAAC;AAAA,CAC9E;AAED,SAAS,aAAa,CAAC,KAAc,EAAoC;IACxE,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9E,MAAM,SAAS,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC/C,OAAO,SAAS,KAAK,MAAM,CAAC,SAAS,IAAI,SAAS,KAAK,IAAI,CAAC;AAAA,CAC5D;AAED,MAAM,UAAU,0BAA0B,CAAC,OAAgC,EAAoB;IAC9F,MAAM,OAAO,GAAqB,EAAE,CAAC;IAErC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,KAAK,2BAA2B,EAAE,CAAC;YACjF,SAAS;QACV,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC;QAC3B,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC;YAAE,SAAS;QACtC,IAAI,OAAO,CAAC,OAAO,KAAK,CAAC;YAAE,SAAS;QACpC,IAAI,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC;YAAE,SAAS;QACrC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC9B,IAAI,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,6BAA6B,CAAC,MAAM,CAAC,CAAC,CAAC;QACrD,CAAC;IACF,CAAC;IAED,OAAO,OAAO,CAAC;AAAA,CACf;AAED,MAAM,UAAU,+BAA+B,CAAC,OAAgC,EAA8B;IAC7G,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACzB,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,KAAK,2BAA2B,EAAE,CAAC;YACjF,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC;YAC3B,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC;gBAAE,SAAS;YACtC,IAAI,OAAO,CAAC,OAAO,KAAK,CAAC;gBAAE,SAAS;YACpC,IAAI,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC;gBAAE,SAAS;YACrC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAC9B,IAAI,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC9B,OAAO,6BAA6B,CAAC,MAAM,CAAC,CAAC;YAC9C,CAAC;QACF,CAAC;IACF,CAAC;IACD,OAAO,SAAS,CAAC;AAAA,CACjB","sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"session-evidence-bundle.js","sourceRoot":"","sources":["../../../src/core/research/session-evidence-bundle.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,6BAA6B,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAEvF,MAAM,CAAC,MAAM,2BAA2B,GAAG,iBAAiB,CAAC;AAO7D,MAAM,UAAU,4BAA4B,CAC3C,cAAyD,EACzD,MAAsB,EACb;IACT,MAAM,OAAO,GAAkC;QAC9C,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,6BAA6B,CAAC,MAAM,CAAC;KAC7C,CAAC;IACF,OAAO,cAAc,CAAC,iBAAiB,CAAC,2BAA2B,EAAE,OAAO,CAAC,CAAC;AAAA,CAC9E;AAED,SAAS,aAAa,CAAC,KAAc,EAAoC;IACxE,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9E,MAAM,SAAS,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC/C,OAAO,SAAS,KAAK,MAAM,CAAC,SAAS,IAAI,SAAS,KAAK,IAAI,CAAC;AAAA,CAC5D;AAED,MAAM,UAAU,0BAA0B,CAAC,OAAgC,EAAoB;IAC9F,MAAM,OAAO,GAAqB,EAAE,CAAC;IAErC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,KAAK,2BAA2B,EAAE,CAAC;YACjF,SAAS;QACV,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC;QAC3B,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC;YAAE,SAAS;QACtC,IAAI,OAAO,CAAC,OAAO,KAAK,CAAC;YAAE,SAAS;QACpC,IAAI,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC;YAAE,SAAS;QACrC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC9B,IAAI,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,6BAA6B,CAAC,MAAM,CAAC,CAAC,CAAC;QACrD,CAAC;IACF,CAAC;IAED,OAAO,OAAO,CAAC;AAAA,CACf;AAED,MAAM,UAAU,+BAA+B,CAAC,OAAgC,EAA8B;IAC7G,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACzB,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,KAAK,2BAA2B,EAAE,CAAC;YACjF,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC;YAC3B,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC;gBAAE,SAAS;YACtC,IAAI,OAAO,CAAC,OAAO,KAAK,CAAC;gBAAE,SAAS;YACpC,IAAI,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC;gBAAE,SAAS;YACrC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAC9B,IAAI,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC9B,OAAO,6BAA6B,CAAC,MAAM,CAAC,CAAC;YAC9C,CAAC;QACF,CAAC;IACF,CAAC;IACD,OAAO,SAAS,CAAC;AAAA,CACjB","sourcesContent":["import type { SessionEntry, SessionManager } from \"@caupulican/pi-agent-core/node\";\nimport type { EvidenceBundle } from \"../autonomy/contracts.ts\";\nimport { cloneEvidenceBundleForStorage, isEvidenceBundle } from \"./evidence-bundle.ts\";\n\nexport const EVIDENCE_BUNDLE_CUSTOM_TYPE = \"evidence_bundle\";\n\nexport interface EvidenceBundleSnapshotPayload {\n\tversion: 1;\n\tbundle: EvidenceBundle;\n}\n\nexport function appendEvidenceBundleSnapshot(\n\tsessionManager: Pick<SessionManager, \"appendCustomEntry\">,\n\tbundle: EvidenceBundle,\n): string {\n\tconst payload: EvidenceBundleSnapshotPayload = {\n\t\tversion: 1,\n\t\tbundle: cloneEvidenceBundleForStorage(bundle),\n\t};\n\treturn sessionManager.appendCustomEntry(EVIDENCE_BUNDLE_CUSTOM_TYPE, payload);\n}\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst prototype = Object.getPrototypeOf(value);\n\treturn prototype === Object.prototype || prototype === null;\n}\n\nexport function getEvidenceBundleSnapshots(entries: readonly SessionEntry[]): EvidenceBundle[] {\n\tconst bundles: EvidenceBundle[] = [];\n\n\tfor (const entry of entries) {\n\t\tif (entry.type !== \"custom\" || entry.customType !== EVIDENCE_BUNDLE_CUSTOM_TYPE) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst payload = entry.data;\n\t\tif (!isPlainRecord(payload)) continue;\n\t\tif (payload.version !== 1) continue;\n\t\tif (!(\"bundle\" in payload)) continue;\n\t\tconst bundle = payload.bundle;\n\t\tif (isEvidenceBundle(bundle)) {\n\t\t\tbundles.push(cloneEvidenceBundleForStorage(bundle));\n\t\t}\n\t}\n\n\treturn bundles;\n}\n\nexport function getLatestEvidenceBundleSnapshot(entries: readonly SessionEntry[]): EvidenceBundle | undefined {\n\tfor (let i = entries.length - 1; i >= 0; i--) {\n\t\tconst entry = entries[i];\n\t\tif (entry.type === \"custom\" && entry.customType === EVIDENCE_BUNDLE_CUSTOM_TYPE) {\n\t\t\tconst payload = entry.data;\n\t\t\tif (!isPlainRecord(payload)) continue;\n\t\t\tif (payload.version !== 1) continue;\n\t\t\tif (!(\"bundle\" in payload)) continue;\n\t\t\tconst bundle = payload.bundle;\n\t\t\tif (isEvidenceBundle(bundle)) {\n\t\t\t\treturn cloneEvidenceBundleForStorage(bundle);\n\t\t\t}\n\t\t}\n\t}\n\treturn undefined;\n}\n"]}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime build & reload: the session's tool-registry assembly and the self-modification-safe
|
|
3
|
+
* extension reload path. Owns building the base tool definitions, wrapping them into the live tool
|
|
4
|
+
* registry (`_refreshToolRegistry`), constructing the {@link ExtensionRunner} for a rebuilt runtime
|
|
5
|
+
* (`_buildRuntime`), and the repo's self-modification safety crown jewel: the preflight-guarded
|
|
6
|
+
* `reload()` with its snapshot / doctor / commit-or-rollback sequence, plus the single-extension
|
|
7
|
+
* live load/unload/reconcile operations that rebuild the runtime in place.
|
|
8
|
+
*
|
|
9
|
+
* Extracted verbatim from agent-session.ts (god-file decomposition). Owns ONLY the tool-registry
|
|
10
|
+
* state — the base tool definitions, the wrapped tool registry, the definition registry, and the
|
|
11
|
+
* per-tool prompt snippet/guideline maps. Everything else the build & reload touch — the live
|
|
12
|
+
* {@link ExtensionRunner}, the agent's tool/system-prompt state, the base system prompt, the
|
|
13
|
+
* resource loader, the session/settings managers, the model registry, the profile tool filter and
|
|
14
|
+
* its warning sinks, the requested-active-tool-names request, the memory subsystem, and the many
|
|
15
|
+
* host callbacks the rebuilt tools/runtime are wired to — is reached through narrow deps accessors
|
|
16
|
+
* that read and write the SAME storage the host owns today.
|
|
17
|
+
*
|
|
18
|
+
* Snapshot-ownership boundary (deliberate, load-bearing for reload safety): the reload snapshot
|
|
19
|
+
* spans state owned by OTHER collaborators — the extension runner and its ref, `agent.state.tools`
|
|
20
|
+
* / `agent.state.systemPrompt`, and `_baseSystemPrompt`. Those are captured and restored through
|
|
21
|
+
* {@link RuntimeBuilderDeps} get/set accessors so save/restore mutate exactly the host/agent fields
|
|
22
|
+
* they mutated before extraction; only the five tool-registry maps are captured by direct field
|
|
23
|
+
* reference here (this builder owns them). The `_extensionRunnerRef.current` update folds into
|
|
24
|
+
* {@link RuntimeBuilderDeps.setExtensionRunner} (the same field-then-ref pattern the host used at
|
|
25
|
+
* every assignment site), so no observer runs between the two writes.
|
|
26
|
+
*
|
|
27
|
+
* Host-binding boundary (deliberate): `_bindExtensionCore` — which exposes the SESSION's own public
|
|
28
|
+
* surface (sendMessage, setModel, compact, abort, reload, …) to the extension runner — stays
|
|
29
|
+
* host-side and is invoked from {@link buildRuntime} via {@link RuntimeBuilderDeps.bindExtensionCore};
|
|
30
|
+
* it is host identity, not build logic, and moving it would only re-export ~30 host methods through
|
|
31
|
+
* deps to hand them straight back. The host keeps one-line delegations for the public reload /
|
|
32
|
+
* load / unload / reconcile API and for `getAllTools` / `getToolDefinition`, and a private
|
|
33
|
+
* `_refreshToolRegistry` delegation for its internal callers.
|
|
34
|
+
*/
|
|
35
|
+
import type { Agent, AgentContext, AgentMessage, AgentTool } from "@caupulican/pi-agent-core";
|
|
36
|
+
import type { SessionManager } from "@caupulican/pi-agent-core/node";
|
|
37
|
+
import type { Api, Model, Usage } from "@caupulican/pi-ai";
|
|
38
|
+
import type { IsolatedCompletionOptions, IsolatedCompletionResult, WorkerDelegationRunOutcome } from "./agent-session.ts";
|
|
39
|
+
import type { ArtifactStore } from "./context/context-artifacts.ts";
|
|
40
|
+
import type { MemoryPromptInclusionReport, MemoryRetrievalDiagnostics } from "./context/memory-diagnostics.ts";
|
|
41
|
+
import type { ContextGcReport } from "./context-gc.ts";
|
|
42
|
+
import { type ContextUsage, type Extension, type ExtensionCommandContextActions, type ExtensionErrorListener, ExtensionRunner, type ExtensionUIContext, type ShutdownHandler, type ToolDefinition, type ToolInfo } from "./extensions/index.ts";
|
|
43
|
+
import type { GoalState } from "./goals/goal-state.ts";
|
|
44
|
+
import type { MemoryManager } from "./memory/memory-manager.ts";
|
|
45
|
+
import type { ModelRegistry } from "./model-registry.ts";
|
|
46
|
+
import type { ModelFitnessReport } from "./research/model-fitness.ts";
|
|
47
|
+
import type { ResourceLoader } from "./resource-loader.ts";
|
|
48
|
+
import { type ResourceProfileFilterSettings, type SettingsManager } from "./settings-manager.ts";
|
|
49
|
+
export interface RuntimeBuilderDeps {
|
|
50
|
+
/** Live agent — the snapshot/doctor read and restore its `state.tools` / `state.systemPrompt`. */
|
|
51
|
+
getAgent(): Agent;
|
|
52
|
+
/** Workspace root, passed to the tool-definition factory and the extension runner. */
|
|
53
|
+
getCwd(): string;
|
|
54
|
+
/** Session log, passed to the extension runner. */
|
|
55
|
+
getSessionManager(): SessionManager;
|
|
56
|
+
/** Tool/shell/toolkit/resource settings + reload target (settingsManager.reload()). */
|
|
57
|
+
getSettingsManager(): SettingsManager;
|
|
58
|
+
/** Model registry, passed to the extension runner and profile model re-resolution. */
|
|
59
|
+
getModelRegistry(): ModelRegistry;
|
|
60
|
+
/** Extension/skill/prompt/theme discovery + the reload/commit/rollback generation swap. */
|
|
61
|
+
getResourceLoader(): ResourceLoader;
|
|
62
|
+
/** Live extension runner (host-owned; pervasive). */
|
|
63
|
+
getExtensionRunner(): ExtensionRunner;
|
|
64
|
+
/** Store the extension runner AND update the Agent's mutable `_extensionRunnerRef.current` (both together). */
|
|
65
|
+
setExtensionRunner(runner: ExtensionRunner): void;
|
|
66
|
+
/** Base (extension-free) system prompt; captured/restored by the reload snapshot. */
|
|
67
|
+
getBaseSystemPrompt(): string;
|
|
68
|
+
setBaseSystemPrompt(prompt: string): void;
|
|
69
|
+
/** SDK-provided plain tools, synthesized into the registry alongside built-ins. */
|
|
70
|
+
getCustomTools(): ToolDefinition[];
|
|
71
|
+
/** Optional plain-tool override; when set, the built-in factory + core diagnostics are skipped. */
|
|
72
|
+
getBaseToolsOverride(): Record<string, AgentTool> | undefined;
|
|
73
|
+
/** Pre-filter tool REQUEST (never the capability/profile-filtered active set) preserved across a rebuild. */
|
|
74
|
+
getRequestedActiveToolNames(): string[] | undefined;
|
|
75
|
+
setRequestedActiveToolNames(names: string[] | undefined): void;
|
|
76
|
+
/** Resource-profile tool allow/block filter + the raw allow/exclude sets applied during registry build. */
|
|
77
|
+
getToolProfileFilter(): Required<ResourceProfileFilterSettings> | undefined;
|
|
78
|
+
setToolProfileFilter(filter: Required<ResourceProfileFilterSettings> | undefined): void;
|
|
79
|
+
getAllowedToolNames(): Set<string> | undefined;
|
|
80
|
+
getExcludedToolNames(): Set<string> | undefined;
|
|
81
|
+
/** Re-derive the profile tool filter from freshly reloaded settings (reload only). */
|
|
82
|
+
deriveToolProfileFilter(): Required<ResourceProfileFilterSettings>;
|
|
83
|
+
/** True when a tool/command name survives the active profile's allow/block + user allow/exclude. */
|
|
84
|
+
isToolOrCommandAllowedByProfile(name: string): boolean;
|
|
85
|
+
/** Filter the loaded extensions through the active resource profile (records inert/denied warnings host-side). */
|
|
86
|
+
filterExtensionsForRuntime(extensions: Extension[]): Extension[];
|
|
87
|
+
/** Sink for the G13 unbound-profile-tool-grant warnings surfaced in /context. */
|
|
88
|
+
setUnboundToolGrantWarnings(warnings: string[]): void;
|
|
89
|
+
/** Currently-active tool names (reads agent.state.tools; the pre-filter fallback for a rebuild). */
|
|
90
|
+
getActiveToolNames(): string[];
|
|
91
|
+
/** Apply the recomputed active set (capability filter + companion auto-activation live here). */
|
|
92
|
+
setActiveToolsByName(toolNames: string[]): void;
|
|
93
|
+
/** Normalize a tool's prompt snippet / guidelines through the system-prompt builder. */
|
|
94
|
+
normalizePromptSnippet(text: string | undefined): string | undefined;
|
|
95
|
+
normalizePromptGuidelines(guidelines: string[] | undefined): string[];
|
|
96
|
+
/** Wire the session's own public surface into a freshly-built runner (host identity; stays host-side). */
|
|
97
|
+
bindExtensionCore(runner: ExtensionRunner): void;
|
|
98
|
+
/** Re-apply UI context / mode / command-context / error subscription to a runner. */
|
|
99
|
+
applyExtensionBindings(runner: ExtensionRunner): void;
|
|
100
|
+
/** Re-run resource discovery for the active extensions (reload only). */
|
|
101
|
+
extendResourcesFromExtensions(reason: "startup" | "reload"): Promise<void>;
|
|
102
|
+
/** Re-apply the active profile's model/thinking from reloaded settings (reload only). */
|
|
103
|
+
reapplyActiveProfileModelSettings(): Promise<void>;
|
|
104
|
+
/** Notify extensions-changed listeners after a single-extension live op. */
|
|
105
|
+
notifyExtensionsChanged(): void;
|
|
106
|
+
/** Session-scoped tool-output artifact store for grep/find/artifact_retrieve (gated on the profile). */
|
|
107
|
+
getToolArtifactStore(): ArtifactStore;
|
|
108
|
+
/** Live memory manager — its provider tools join the registry. */
|
|
109
|
+
getMemoryManager(): MemoryManager;
|
|
110
|
+
/** Memory retrieval + prompt-inclusion diagnostics for the core diagnostics tool. */
|
|
111
|
+
getMemoryAuditDiagnostics(): {
|
|
112
|
+
retrieval: MemoryRetrievalDiagnostics;
|
|
113
|
+
promptInclusion: MemoryPromptInclusionReport;
|
|
114
|
+
};
|
|
115
|
+
/** Drop extension-contributed pending memory providers before a reload re-registers them. */
|
|
116
|
+
clearPendingMemoryProviders(): void;
|
|
117
|
+
/** (Re)derive the memory subsystem from reloaded settings/providers. */
|
|
118
|
+
initializeMemory(): Promise<void>;
|
|
119
|
+
/** Goal-tool state accessors. */
|
|
120
|
+
getGoalStateSnapshot(): GoalState | undefined;
|
|
121
|
+
saveGoalStateSnapshot(state: GoalState): string;
|
|
122
|
+
/** Context-gc report for the core diagnostics tool. */
|
|
123
|
+
getContextGcReport(messages: AgentMessage[]): ContextGcReport;
|
|
124
|
+
/** Worker-delegation runner for the delegate tool. */
|
|
125
|
+
runWorkerDelegationOnce(request: {
|
|
126
|
+
instructions: string;
|
|
127
|
+
systemPrompt?: string;
|
|
128
|
+
}): Promise<WorkerDelegationRunOutcome>;
|
|
129
|
+
/** Model-fitness probe for the model_fitness tool. */
|
|
130
|
+
runModelFitness(args: {
|
|
131
|
+
model: string;
|
|
132
|
+
trials?: number;
|
|
133
|
+
}): Promise<{
|
|
134
|
+
started: true;
|
|
135
|
+
model: string;
|
|
136
|
+
report: ModelFitnessReport;
|
|
137
|
+
} | {
|
|
138
|
+
started: false;
|
|
139
|
+
skipReason: string;
|
|
140
|
+
}>;
|
|
141
|
+
/** Fitness-gated reflex-brain model resolver (run_toolkit_script interpretation). */
|
|
142
|
+
resolveCurationModelIfFit(): Model<Api> | undefined;
|
|
143
|
+
/** One-shot, tool-less LLM call — the reflex-brain interpreter rides this. */
|
|
144
|
+
runIsolatedCompletion(opts: IsolatedCompletionOptions): Promise<IsolatedCompletionResult>;
|
|
145
|
+
/** Roll reflex-brain spend into spawned-usage accounting. */
|
|
146
|
+
addSpawnedUsage(usage: Usage, opts?: {
|
|
147
|
+
label?: string;
|
|
148
|
+
sourceSessionId?: string;
|
|
149
|
+
reportId?: string;
|
|
150
|
+
}): string | undefined;
|
|
151
|
+
/** Post-rebuild doctor helpers (validate the rebuilt runtime can render a context). */
|
|
152
|
+
createAgentContextSnapshot(): AgentContext;
|
|
153
|
+
getContextUsage(): ContextUsage | undefined;
|
|
154
|
+
/** Reload/live-op preflight refusal guards (identical refusal behavior; host-checked). */
|
|
155
|
+
isStreaming(): boolean;
|
|
156
|
+
isCompacting(): boolean;
|
|
157
|
+
/** Extension bindings present — gate for re-emitting session_start on reload. */
|
|
158
|
+
getExtensionUIContext(): ExtensionUIContext | undefined;
|
|
159
|
+
getExtensionCommandContextActions(): ExtensionCommandContextActions | undefined;
|
|
160
|
+
getExtensionShutdownHandler(): ShutdownHandler | undefined;
|
|
161
|
+
getExtensionErrorListener(): ExtensionErrorListener | undefined;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Owns the tool-registry build and the self-modification-safe extension reload extracted from
|
|
165
|
+
* {@link AgentSession}. See the module header for the snapshot-ownership and host-binding boundaries.
|
|
166
|
+
*/
|
|
167
|
+
export declare class RuntimeBuilder {
|
|
168
|
+
private _toolRegistry;
|
|
169
|
+
private _toolDefinitions;
|
|
170
|
+
private _toolPromptSnippets;
|
|
171
|
+
private _toolPromptGuidelines;
|
|
172
|
+
private _baseToolDefinitions;
|
|
173
|
+
private readonly deps;
|
|
174
|
+
constructor(deps: RuntimeBuilderDeps);
|
|
175
|
+
/** Whether a tool name is present in the live wrapped registry. */
|
|
176
|
+
hasTool(name: string): boolean;
|
|
177
|
+
/** The live wrapped tool for a name, if registered (activation lookup). */
|
|
178
|
+
getRegisteredTool(name: string): AgentTool | undefined;
|
|
179
|
+
/** A registered tool's normalized prompt snippet, if any. */
|
|
180
|
+
getToolPromptSnippet(name: string): string | undefined;
|
|
181
|
+
/** A registered tool's normalized prompt guidelines, if any. */
|
|
182
|
+
getToolPromptGuidelines(name: string): string[] | undefined;
|
|
183
|
+
/**
|
|
184
|
+
* Get all configured tools with name, description, parameter schema, prompt guidelines, and source metadata.
|
|
185
|
+
*/
|
|
186
|
+
getAllTools(): ToolInfo[];
|
|
187
|
+
getToolDefinition(name: string): ToolDefinition | undefined;
|
|
188
|
+
refreshToolRegistry(options?: {
|
|
189
|
+
activeToolNames?: string[];
|
|
190
|
+
includeAllExtensionTools?: boolean;
|
|
191
|
+
}): void;
|
|
192
|
+
private _createReloadRuntimeSnapshot;
|
|
193
|
+
private _restoreReloadRuntimeSnapshot;
|
|
194
|
+
private _doctorReloadRuntime;
|
|
195
|
+
buildRuntime(options: {
|
|
196
|
+
activeToolNames?: string[];
|
|
197
|
+
flagValues?: Map<string, boolean | string>;
|
|
198
|
+
includeAllExtensionTools?: boolean;
|
|
199
|
+
}): void;
|
|
200
|
+
reload(): Promise<void>;
|
|
201
|
+
/**
|
|
202
|
+
* Unload a single extension without full reload.
|
|
203
|
+
* Runs the extension's session_shutdown lifecycle, unregisters its providers,
|
|
204
|
+
* disposes its event subscriptions, and rebuilds the runtime.
|
|
205
|
+
* Falls back to full reload on error.
|
|
206
|
+
*/
|
|
207
|
+
unloadExtensionLive(extensionPath: string): Promise<void>;
|
|
208
|
+
/**
|
|
209
|
+
* Load a single extension without full reload.
|
|
210
|
+
* Loads the extension with fresh import, rebuilds the runtime,
|
|
211
|
+
* and runs the extension's session_start lifecycle.
|
|
212
|
+
* Falls back to full reload on error.
|
|
213
|
+
*/
|
|
214
|
+
loadExtensionLive(extensionPath: string): Promise<void>;
|
|
215
|
+
/**
|
|
216
|
+
* Reconcile loaded extensions with the active profile.
|
|
217
|
+
* Loads extensions that should be enabled but aren't, and unloads extensions that shouldn't be.
|
|
218
|
+
* Falls back to full reload if any individual load/unload fails.
|
|
219
|
+
*/
|
|
220
|
+
reconcileLoadedExtensions(): Promise<void>;
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=runtime-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-builder.d.ts","sourceRoot":"","sources":["../../src/core/runtime-builder.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Runtime build & reload: the session's tool-registry assembly and the self-modification-safe\n * extension reload path. Owns building the base tool definitions, wrapping them into the live tool\n * registry (`_refreshToolRegistry`), constructing the {@link ExtensionRunner} for a rebuilt runtime\n * (`_buildRuntime`), and the repo's self-modification safety crown jewel: the preflight-guarded\n * `reload()` with its snapshot / doctor / commit-or-rollback sequence, plus the single-extension\n * live load/unload/reconcile operations that rebuild the runtime in place.\n *\n * Extracted verbatim from agent-session.ts (god-file decomposition). Owns ONLY the tool-registry\n * state — the base tool definitions, the wrapped tool registry, the definition registry, and the\n * per-tool prompt snippet/guideline maps. Everything else the build & reload touch — the live\n * {@link ExtensionRunner}, the agent's tool/system-prompt state, the base system prompt, the\n * resource loader, the session/settings managers, the model registry, the profile tool filter and\n * its warning sinks, the requested-active-tool-names request, the memory subsystem, and the many\n * host callbacks the rebuilt tools/runtime are wired to — is reached through narrow deps accessors\n * that read and write the SAME storage the host owns today.\n *\n * Snapshot-ownership boundary (deliberate, load-bearing for reload safety): the reload snapshot\n * spans state owned by OTHER collaborators — the extension runner and its ref, `agent.state.tools`\n * / `agent.state.systemPrompt`, and `_baseSystemPrompt`. Those are captured and restored through\n * {@link RuntimeBuilderDeps} get/set accessors so save/restore mutate exactly the host/agent fields\n * they mutated before extraction; only the five tool-registry maps are captured by direct field\n * reference here (this builder owns them). The `_extensionRunnerRef.current` update folds into\n * {@link RuntimeBuilderDeps.setExtensionRunner} (the same field-then-ref pattern the host used at\n * every assignment site), so no observer runs between the two writes.\n *\n * Host-binding boundary (deliberate): `_bindExtensionCore` — which exposes the SESSION's own public\n * surface (sendMessage, setModel, compact, abort, reload, …) to the extension runner — stays\n * host-side and is invoked from {@link buildRuntime} via {@link RuntimeBuilderDeps.bindExtensionCore};\n * it is host identity, not build logic, and moving it would only re-export ~30 host methods through\n * deps to hand them straight back. The host keeps one-line delegations for the public reload /\n * load / unload / reconcile API and for `getAllTools` / `getToolDefinition`, and a private\n * `_refreshToolRegistry` delegation for its internal callers.\n */\n\nimport type { Agent, AgentContext, AgentMessage, AgentTool } from \"@caupulican/pi-agent-core\";\nimport type { SessionManager } from \"@caupulican/pi-agent-core/node\";\nimport type { Api, Model, Usage } from \"@caupulican/pi-ai\";\nimport { resetApiProviders } from \"@caupulican/pi-ai\";\nimport type {\n\tIsolatedCompletionOptions,\n\tIsolatedCompletionResult,\n\tWorkerDelegationRunOutcome,\n} from \"./agent-session.ts\";\nimport type { ArtifactStore } from \"./context/context-artifacts.ts\";\nimport type { MemoryPromptInclusionReport, MemoryRetrievalDiagnostics } from \"./context/memory-diagnostics.ts\";\nimport type { ContextGcReport } from \"./context-gc.ts\";\nimport { createCoreDiagnosticsToolDefinitions } from \"./extensions/builtin.ts\";\nimport {\n\ttype ContextUsage,\n\ttype Extension,\n\ttype ExtensionCommandContextActions,\n\ttype ExtensionErrorListener,\n\tExtensionRunner,\n\ttype ExtensionUIContext,\n\ttype ShutdownHandler,\n\ttype ToolDefinition,\n\ttype ToolInfo,\n\twrapRegisteredTools,\n} from \"./extensions/index.ts\";\nimport { disposeExtensionEventSubscriptions } from \"./extensions/loader.ts\";\nimport { emitSessionShutdownEvent } from \"./extensions/runner.ts\";\nimport type { GoalState } from \"./goals/goal-state.ts\";\nimport type { MemoryManager } from \"./memory/memory-manager.ts\";\nimport type { ModelRegistry } from \"./model-registry.ts\";\nimport type { ModelFitnessReport } from \"./research/model-fitness.ts\";\nimport type { ResourceLoader } from \"./resource-loader.ts\";\nimport {\n\tmatchesResourceProfilePattern,\n\ttype ResourceProfileFilterSettings,\n\ttype SettingsManager,\n} from \"./settings-manager.ts\";\nimport { createSyntheticSourceInfo, type SourceInfo } from \"./source-info.ts\";\nimport {\n\tbuildReflexUserPrompt,\n\tparseReflexPlan,\n\tREFLEX_INTERPRETER_SYSTEM_PROMPT,\n} from \"./toolkit/reflex-interpreter.ts\";\nimport { executeToolkitScript } from \"./toolkit/script-runner.ts\";\nimport { createDelegateToolDefinition } from \"./tools/delegate.ts\";\nimport { createGoalToolDefinition } from \"./tools/goal.ts\";\nimport { createAllToolDefinitions } from \"./tools/index.ts\";\nimport { createModelFitnessToolDefinition } from \"./tools/model-fitness.ts\";\nimport { createRunToolkitScriptToolDefinition } from \"./tools/run-toolkit-script.ts\";\nimport { createToolDefinitionFromAgentTool } from \"./tools/tool-definition-wrapper.ts\";\n\ninterface ToolDefinitionEntry {\n\tdefinition: ToolDefinition;\n\tsourceInfo: SourceInfo;\n}\n\ninterface ReloadRuntimeSnapshot {\n\textensionRunner: ExtensionRunner;\n\tbaseToolDefinitions: Map<string, ToolDefinition>;\n\ttoolRegistry: Map<string, AgentTool>;\n\ttoolDefinitions: Map<string, ToolDefinitionEntry>;\n\ttoolPromptSnippets: Map<string, string>;\n\ttoolPromptGuidelines: Map<string, string[]>;\n\tagentTools: AgentTool[];\n\tagentSystemPrompt: string;\n\tbaseSystemPrompt: string;\n}\n\nexport interface RuntimeBuilderDeps {\n\t/** Live agent — the snapshot/doctor read and restore its `state.tools` / `state.systemPrompt`. */\n\tgetAgent(): Agent;\n\t/** Workspace root, passed to the tool-definition factory and the extension runner. */\n\tgetCwd(): string;\n\t/** Session log, passed to the extension runner. */\n\tgetSessionManager(): SessionManager;\n\t/** Tool/shell/toolkit/resource settings + reload target (settingsManager.reload()). */\n\tgetSettingsManager(): SettingsManager;\n\t/** Model registry, passed to the extension runner and profile model re-resolution. */\n\tgetModelRegistry(): ModelRegistry;\n\t/** Extension/skill/prompt/theme discovery + the reload/commit/rollback generation swap. */\n\tgetResourceLoader(): ResourceLoader;\n\n\t/** Live extension runner (host-owned; pervasive). */\n\tgetExtensionRunner(): ExtensionRunner;\n\t/** Store the extension runner AND update the Agent's mutable `_extensionRunnerRef.current` (both together). */\n\tsetExtensionRunner(runner: ExtensionRunner): void;\n\t/** Base (extension-free) system prompt; captured/restored by the reload snapshot. */\n\tgetBaseSystemPrompt(): string;\n\tsetBaseSystemPrompt(prompt: string): void;\n\n\t/** SDK-provided plain tools, synthesized into the registry alongside built-ins. */\n\tgetCustomTools(): ToolDefinition[];\n\t/** Optional plain-tool override; when set, the built-in factory + core diagnostics are skipped. */\n\tgetBaseToolsOverride(): Record<string, AgentTool> | undefined;\n\t/** Pre-filter tool REQUEST (never the capability/profile-filtered active set) preserved across a rebuild. */\n\tgetRequestedActiveToolNames(): string[] | undefined;\n\tsetRequestedActiveToolNames(names: string[] | undefined): void;\n\n\t/** Resource-profile tool allow/block filter + the raw allow/exclude sets applied during registry build. */\n\tgetToolProfileFilter(): Required<ResourceProfileFilterSettings> | undefined;\n\tsetToolProfileFilter(filter: Required<ResourceProfileFilterSettings> | undefined): void;\n\tgetAllowedToolNames(): Set<string> | undefined;\n\tgetExcludedToolNames(): Set<string> | undefined;\n\t/** Re-derive the profile tool filter from freshly reloaded settings (reload only). */\n\tderiveToolProfileFilter(): Required<ResourceProfileFilterSettings>;\n\t/** True when a tool/command name survives the active profile's allow/block + user allow/exclude. */\n\tisToolOrCommandAllowedByProfile(name: string): boolean;\n\t/** Filter the loaded extensions through the active resource profile (records inert/denied warnings host-side). */\n\tfilterExtensionsForRuntime(extensions: Extension[]): Extension[];\n\t/** Sink for the G13 unbound-profile-tool-grant warnings surfaced in /context. */\n\tsetUnboundToolGrantWarnings(warnings: string[]): void;\n\n\t/** Currently-active tool names (reads agent.state.tools; the pre-filter fallback for a rebuild). */\n\tgetActiveToolNames(): string[];\n\t/** Apply the recomputed active set (capability filter + companion auto-activation live here). */\n\tsetActiveToolsByName(toolNames: string[]): void;\n\t/** Normalize a tool's prompt snippet / guidelines through the system-prompt builder. */\n\tnormalizePromptSnippet(text: string | undefined): string | undefined;\n\tnormalizePromptGuidelines(guidelines: string[] | undefined): string[];\n\n\t/** Wire the session's own public surface into a freshly-built runner (host identity; stays host-side). */\n\tbindExtensionCore(runner: ExtensionRunner): void;\n\t/** Re-apply UI context / mode / command-context / error subscription to a runner. */\n\tapplyExtensionBindings(runner: ExtensionRunner): void;\n\t/** Re-run resource discovery for the active extensions (reload only). */\n\textendResourcesFromExtensions(reason: \"startup\" | \"reload\"): Promise<void>;\n\t/** Re-apply the active profile's model/thinking from reloaded settings (reload only). */\n\treapplyActiveProfileModelSettings(): Promise<void>;\n\t/** Notify extensions-changed listeners after a single-extension live op. */\n\tnotifyExtensionsChanged(): void;\n\n\t/** Session-scoped tool-output artifact store for grep/find/artifact_retrieve (gated on the profile). */\n\tgetToolArtifactStore(): ArtifactStore;\n\n\t/** Live memory manager — its provider tools join the registry. */\n\tgetMemoryManager(): MemoryManager;\n\t/** Memory retrieval + prompt-inclusion diagnostics for the core diagnostics tool. */\n\tgetMemoryAuditDiagnostics(): { retrieval: MemoryRetrievalDiagnostics; promptInclusion: MemoryPromptInclusionReport };\n\t/** Drop extension-contributed pending memory providers before a reload re-registers them. */\n\tclearPendingMemoryProviders(): void;\n\t/** (Re)derive the memory subsystem from reloaded settings/providers. */\n\tinitializeMemory(): Promise<void>;\n\n\t/** Goal-tool state accessors. */\n\tgetGoalStateSnapshot(): GoalState | undefined;\n\tsaveGoalStateSnapshot(state: GoalState): string;\n\t/** Context-gc report for the core diagnostics tool. */\n\tgetContextGcReport(messages: AgentMessage[]): ContextGcReport;\n\t/** Worker-delegation runner for the delegate tool. */\n\trunWorkerDelegationOnce(request: {\n\t\tinstructions: string;\n\t\tsystemPrompt?: string;\n\t}): Promise<WorkerDelegationRunOutcome>;\n\t/** Model-fitness probe for the model_fitness tool. */\n\trunModelFitness(args: {\n\t\tmodel: string;\n\t\ttrials?: number;\n\t}): Promise<{ started: true; model: string; report: ModelFitnessReport } | { started: false; skipReason: string }>;\n\t/** Fitness-gated reflex-brain model resolver (run_toolkit_script interpretation). */\n\tresolveCurationModelIfFit(): Model<Api> | undefined;\n\t/** One-shot, tool-less LLM call — the reflex-brain interpreter rides this. */\n\trunIsolatedCompletion(opts: IsolatedCompletionOptions): Promise<IsolatedCompletionResult>;\n\t/** Roll reflex-brain spend into spawned-usage accounting. */\n\taddSpawnedUsage(\n\t\tusage: Usage,\n\t\topts?: { label?: string; sourceSessionId?: string; reportId?: string },\n\t): string | undefined;\n\n\t/** Post-rebuild doctor helpers (validate the rebuilt runtime can render a context). */\n\tcreateAgentContextSnapshot(): AgentContext;\n\tgetContextUsage(): ContextUsage | undefined;\n\n\t/** Reload/live-op preflight refusal guards (identical refusal behavior; host-checked). */\n\tisStreaming(): boolean;\n\tisCompacting(): boolean;\n\n\t/** Extension bindings present — gate for re-emitting session_start on reload. */\n\tgetExtensionUIContext(): ExtensionUIContext | undefined;\n\tgetExtensionCommandContextActions(): ExtensionCommandContextActions | undefined;\n\tgetExtensionShutdownHandler(): ShutdownHandler | undefined;\n\tgetExtensionErrorListener(): ExtensionErrorListener | undefined;\n}\n\n/**\n * Owns the tool-registry build and the self-modification-safe extension reload extracted from\n * {@link AgentSession}. See the module header for the snapshot-ownership and host-binding boundaries.\n */\nexport class RuntimeBuilder {\n\t// Tool registry for extension getTools/setTools\n\tprivate _toolRegistry: Map<string, AgentTool> = new Map();\n\tprivate _toolDefinitions: Map<string, ToolDefinitionEntry> = new Map();\n\tprivate _toolPromptSnippets: Map<string, string> = new Map();\n\tprivate _toolPromptGuidelines: Map<string, string[]> = new Map();\n\tprivate _baseToolDefinitions: Map<string, ToolDefinition> = new Map();\n\n\tprivate readonly deps: RuntimeBuilderDeps;\n\n\tconstructor(deps: RuntimeBuilderDeps) {\n\t\tthis.deps = deps;\n\t}\n\n\t/** Whether a tool name is present in the live wrapped registry. */\n\thasTool(name: string): boolean {\n\t\treturn this._toolRegistry.has(name);\n\t}\n\n\t/** The live wrapped tool for a name, if registered (activation lookup). */\n\tgetRegisteredTool(name: string): AgentTool | undefined {\n\t\treturn this._toolRegistry.get(name);\n\t}\n\n\t/** A registered tool's normalized prompt snippet, if any. */\n\tgetToolPromptSnippet(name: string): string | undefined {\n\t\treturn this._toolPromptSnippets.get(name);\n\t}\n\n\t/** A registered tool's normalized prompt guidelines, if any. */\n\tgetToolPromptGuidelines(name: string): string[] | undefined {\n\t\treturn this._toolPromptGuidelines.get(name);\n\t}\n\n\t/**\n\t * Get all configured tools with name, description, parameter schema, prompt guidelines, and source metadata.\n\t */\n\tgetAllTools(): ToolInfo[] {\n\t\treturn Array.from(this._toolDefinitions.values()).map(({ definition, sourceInfo }) => ({\n\t\t\tname: definition.name,\n\t\t\tdescription: definition.description,\n\t\t\tparameters: definition.parameters,\n\t\t\tpromptGuidelines: definition.promptGuidelines,\n\t\t\tsourceInfo,\n\t\t}));\n\t}\n\n\tgetToolDefinition(name: string): ToolDefinition | undefined {\n\t\treturn this._toolDefinitions.get(name)?.definition;\n\t}\n\n\trefreshToolRegistry(options?: { activeToolNames?: string[]; includeAllExtensionTools?: boolean }): void {\n\t\tconst previousRegistryNames = new Set(this._toolRegistry.keys());\n\t\t// Re-derive from the pre-filter REQUEST, never from agent.state.tools: the active set is\n\t\t// capability/profile-filtered, so feeding it back through setActiveToolsByName would\n\t\t// permanently shrink what a later switch to a larger model (or permissive profile) restores.\n\t\tconst previousActiveToolNames = this.deps.getRequestedActiveToolNames() ?? this.deps.getActiveToolNames();\n\t\tconst allowedToolNames = this.deps.getAllowedToolNames();\n\t\tconst excludedToolNames = this.deps.getExcludedToolNames();\n\t\tconst toolProfileFilter = this.deps.getToolProfileFilter();\n\t\tconst isAllowedTool = (name: string): boolean => {\n\t\t\tif (allowedToolNames && !allowedToolNames.has(name)) return false;\n\t\t\tif (excludedToolNames?.has(name)) return false;\n\t\t\tif (!toolProfileFilter) return true;\n\t\t\tif (toolProfileFilter.allow.length > 0 && !matchesResourceProfilePattern(name, toolProfileFilter.allow)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (matchesResourceProfilePattern(name, toolProfileFilter.block)) return false;\n\t\t\treturn true;\n\t\t};\n\n\t\tconst registeredTools = this.deps.getExtensionRunner().getAllRegisteredTools();\n\t\tconst allCustomTools = [\n\t\t\t...registeredTools,\n\t\t\t...this.deps.getCustomTools().map((definition) => ({\n\t\t\t\tdefinition,\n\t\t\t\tsourceInfo: createSyntheticSourceInfo(`<sdk:${definition.name}>`, { source: \"sdk\" }),\n\t\t\t})),\n\t\t\t// Memory subsystem provider tools (e.g. file-store's `memory` tool).\n\t\t\t...this.deps\n\t\t\t\t.getMemoryManager()\n\t\t\t\t.getToolDefinitions()\n\t\t\t\t.map((definition) => ({\n\t\t\t\t\tdefinition,\n\t\t\t\t\tsourceInfo: createSyntheticSourceInfo(`<memory:${definition.name}>`, { source: \"sdk\" }),\n\t\t\t\t})),\n\t\t].filter((tool) => isAllowedTool(tool.definition.name));\n\t\tconst definitionRegistry = new Map<string, ToolDefinitionEntry>(\n\t\t\tArray.from(this._baseToolDefinitions.entries())\n\t\t\t\t.filter(([name]) => isAllowedTool(name))\n\t\t\t\t.map(([name, definition]) => [\n\t\t\t\t\tname,\n\t\t\t\t\t{\n\t\t\t\t\t\tdefinition,\n\t\t\t\t\t\tsourceInfo: createSyntheticSourceInfo(`<builtin:${name}>`, { source: \"builtin\" }),\n\t\t\t\t\t},\n\t\t\t\t]),\n\t\t);\n\t\tfor (const tool of allCustomTools) {\n\t\t\tdefinitionRegistry.set(tool.definition.name, {\n\t\t\t\tdefinition: tool.definition,\n\t\t\t\tsourceInfo: tool.sourceInfo,\n\t\t\t});\n\t\t}\n\t\tthis._toolDefinitions = definitionRegistry;\n\t\tthis._toolPromptSnippets = new Map(\n\t\t\tArray.from(definitionRegistry.values())\n\t\t\t\t.map(({ definition }) => {\n\t\t\t\t\tconst snippet = this.deps.normalizePromptSnippet(definition.promptSnippet);\n\t\t\t\t\treturn snippet ? ([definition.name, snippet] as const) : undefined;\n\t\t\t\t})\n\t\t\t\t.filter((entry): entry is readonly [string, string] => entry !== undefined),\n\t\t);\n\t\tthis._toolPromptGuidelines = new Map(\n\t\t\tArray.from(definitionRegistry.values())\n\t\t\t\t.map(({ definition }) => {\n\t\t\t\t\tconst guidelines = this.deps.normalizePromptGuidelines(definition.promptGuidelines);\n\t\t\t\t\treturn guidelines.length > 0 ? ([definition.name, guidelines] as const) : undefined;\n\t\t\t\t})\n\t\t\t\t.filter((entry): entry is readonly [string, string[]] => entry !== undefined),\n\t\t);\n\t\tconst runner = this.deps.getExtensionRunner();\n\t\tconst wrappedExtensionTools = wrapRegisteredTools(allCustomTools, runner);\n\t\tconst wrappedBuiltInTools = wrapRegisteredTools(\n\t\t\tArray.from(this._baseToolDefinitions.values())\n\t\t\t\t.filter((definition) => isAllowedTool(definition.name))\n\t\t\t\t.map((definition) => ({\n\t\t\t\t\tdefinition,\n\t\t\t\t\tsourceInfo: createSyntheticSourceInfo(`<builtin:${definition.name}>`, { source: \"builtin\" }),\n\t\t\t\t})),\n\t\t\trunner,\n\t\t);\n\n\t\tconst toolRegistry = new Map(wrappedBuiltInTools.map((tool) => [tool.name, tool]));\n\t\tfor (const tool of wrappedExtensionTools as AgentTool[]) {\n\t\t\ttoolRegistry.set(tool.name, tool);\n\t\t}\n\t\tthis._toolRegistry = toolRegistry;\n\n\t\tconst requestedBase = options?.activeToolNames ? [...options.activeToolNames] : [...previousActiveToolNames];\n\t\tconst nextActiveToolNames = requestedBase.filter((name) => isAllowedTool(name));\n\n\t\tconst autoActivated: string[] = [];\n\t\tif (allowedToolNames) {\n\t\t\tfor (const toolName of this._toolRegistry.keys()) {\n\t\t\t\tif (allowedToolNames.has(toolName)) {\n\t\t\t\t\tnextActiveToolNames.push(toolName);\n\t\t\t\t\tautoActivated.push(toolName);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (options?.includeAllExtensionTools) {\n\t\t\tfor (const tool of wrappedExtensionTools) {\n\t\t\t\tnextActiveToolNames.push(tool.name);\n\t\t\t\tautoActivated.push(tool.name);\n\t\t\t}\n\t\t} else if (!options?.activeToolNames) {\n\t\t\tfor (const toolName of this._toolRegistry.keys()) {\n\t\t\t\tif (!previousRegistryNames.has(toolName)) {\n\t\t\t\t\tnextActiveToolNames.push(toolName);\n\t\t\t\t\tautoActivated.push(toolName);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Strict UAC: the active profile is the COMPLETE grant, so a tool the profile names\n\t\t// explicitly is itself a request for that tool — it must ACTIVATE from the registry even\n\t\t// if the session never requested it. Without this, activation is only ever the requested\n\t\t// defaults ∩ allow-list, and a profile granting non-default tools (a search-only profile's\n\t\t// grep/find) yields an empty or truncated tool set on load and /reload. A blanket \"*\"\n\t\t// stays grant-only: activation then still derives from the request/defaults above.\n\t\tconst explicitAllowPatterns = toolProfileFilter?.allow.filter((pattern) => pattern !== \"*\") ?? [];\n\t\tif (explicitAllowPatterns.length > 0) {\n\t\t\tconst boundPatterns = new Set<string>();\n\t\t\tfor (const toolName of this._toolRegistry.keys()) {\n\t\t\t\tif (!isAllowedTool(toolName)) continue;\n\t\t\t\tfor (const pattern of explicitAllowPatterns) {\n\t\t\t\t\tif (matchesResourceProfilePattern(toolName, [pattern])) boundPatterns.add(pattern);\n\t\t\t\t}\n\t\t\t\tif (matchesResourceProfilePattern(toolName, explicitAllowPatterns)) {\n\t\t\t\t\tnextActiveToolNames.push(toolName);\n\t\t\t\t\tautoActivated.push(toolName);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// G13: an explicit grant that binds to NO registered tool is a silent no-op — typo'd\n\t\t\t// name, or the owning extension is not granted/loaded. Surface it.\n\t\t\tthis.deps.setUnboundToolGrantWarnings(\n\t\t\t\texplicitAllowPatterns\n\t\t\t\t\t.filter((pattern) => !boundPatterns.has(pattern))\n\t\t\t\t\t.map(\n\t\t\t\t\t\t(pattern) =>\n\t\t\t\t\t\t\t`profile tool grant \"${pattern}\" binds to no registered tool (typo, or the owning extension is not granted/loaded)`,\n\t\t\t\t\t),\n\t\t\t);\n\t\t} else {\n\t\t\tthis.deps.setUnboundToolGrantWarnings([]);\n\t\t}\n\n\t\t// artifact_retrieve companion auto-activation is enforced inside\n\t\t// setActiveToolsByName() itself (not duplicated here), so every activation path --\n\t\t// including the public, extension-exposed setActiveTools() -- gets the same\n\t\t// guarantee, not just this settings/profile refresh flow.\n\t\tthis.deps.setActiveToolsByName([...new Set(nextActiveToolNames)]);\n\t\t// setActiveToolsByName just stored the profile-filtered ACTIVE set as the request; restore\n\t\t// the true pre-filter request (plus this refresh's auto-activations) so an internal refresh\n\t\t// can never permanently narrow it.\n\t\tthis.deps.setRequestedActiveToolNames([...new Set([...requestedBase, ...autoActivated])]);\n\t}\n\n\tprivate _createReloadRuntimeSnapshot(): ReloadRuntimeSnapshot {\n\t\tconst agent = this.deps.getAgent();\n\t\treturn {\n\t\t\textensionRunner: this.deps.getExtensionRunner(),\n\t\t\tbaseToolDefinitions: this._baseToolDefinitions,\n\t\t\ttoolRegistry: this._toolRegistry,\n\t\t\ttoolDefinitions: this._toolDefinitions,\n\t\t\ttoolPromptSnippets: this._toolPromptSnippets,\n\t\t\ttoolPromptGuidelines: this._toolPromptGuidelines,\n\t\t\tagentTools: agent.state.tools,\n\t\t\tagentSystemPrompt: agent.state.systemPrompt,\n\t\t\tbaseSystemPrompt: this.deps.getBaseSystemPrompt(),\n\t\t};\n\t}\n\n\tprivate _restoreReloadRuntimeSnapshot(snapshot: ReloadRuntimeSnapshot): void {\n\t\t// setExtensionRunner restores both _extensionRunner and _extensionRunnerRef.current together\n\t\t// (the same field-then-ref pair the host wrote at every assignment site); nothing reads the\n\t\t// ref between the two writes, so folding them is unobservable.\n\t\tthis.deps.setExtensionRunner(snapshot.extensionRunner);\n\t\tthis._baseToolDefinitions = snapshot.baseToolDefinitions;\n\t\tthis._toolRegistry = snapshot.toolRegistry;\n\t\tthis._toolDefinitions = snapshot.toolDefinitions;\n\t\tthis._toolPromptSnippets = snapshot.toolPromptSnippets;\n\t\tthis._toolPromptGuidelines = snapshot.toolPromptGuidelines;\n\t\tconst agent = this.deps.getAgent();\n\t\tagent.state.tools = snapshot.agentTools;\n\t\tagent.state.systemPrompt = snapshot.agentSystemPrompt;\n\t\tthis.deps.setBaseSystemPrompt(snapshot.baseSystemPrompt);\n\t\tthis.deps.applyExtensionBindings(snapshot.extensionRunner);\n\t}\n\n\tprivate _doctorReloadRuntime(): void {\n\t\tconst extensionErrors = this.deps.getResourceLoader().getExtensions().errors;\n\t\tif (extensionErrors.length > 0) {\n\t\t\tconst summary = extensionErrors\n\t\t\t\t.slice(0, 6)\n\t\t\t\t.map((error) => `${error.path}: ${error.error}`)\n\t\t\t\t.join(\"; \");\n\t\t\tthrow new Error(`Extension reload failed doctor: ${summary}`);\n\t\t}\n\n\t\tconst missingActiveTools = this.deps.getActiveToolNames().filter((name) => !this._toolRegistry.has(name));\n\t\tif (missingActiveTools.length > 0) {\n\t\t\tthrow new Error(\n\t\t\t\t`Extension reload failed doctor: active tool(s) missing after reload: ${missingActiveTools.join(\", \")}`,\n\t\t\t);\n\t\t}\n\n\t\tfor (const tool of this.deps.getAgent().state.tools) {\n\t\t\tif (!this._toolDefinitions.has(tool.name)) {\n\t\t\t\tthrow new Error(`Extension reload failed doctor: tool ${tool.name} missing from definition registry`);\n\t\t\t}\n\t\t}\n\n\t\tthis.deps.createAgentContextSnapshot();\n\t\tthis.deps.getContextUsage();\n\t}\n\n\tbuildRuntime(options: {\n\t\tactiveToolNames?: string[];\n\t\tflagValues?: Map<string, boolean | string>;\n\t\tincludeAllExtensionTools?: boolean;\n\t}): void {\n\t\tconst settingsManager = this.deps.getSettingsManager();\n\t\tconst autoResizeImages = settingsManager.getImageAutoResize();\n\t\tconst shellCommandPrefix = settingsManager.getShellCommandPrefix();\n\t\tconst shellPath = settingsManager.getShellPath();\n\t\tconst baseToolsOverride = this.deps.getBaseToolsOverride();\n\t\t// grep/find must not emit a \"Full output: artifact tool-output:<id>\" handle that\n\t\t// nothing can resolve. If artifact_retrieve is explicitly excluded/blocked/outside\n\t\t// an active allowlist, don't hand grep/find an artifact store at all: they fall\n\t\t// back to their pre-existing bounded preview/truncation behavior, with no\n\t\t// payload/meta files ever written and no retrieval promise made.\n\t\tconst toolArtifactStore = this.deps.isToolOrCommandAllowedByProfile(\"artifact_retrieve\")\n\t\t\t? this.deps.getToolArtifactStore()\n\t\t\t: undefined;\n\t\tconst baseToolDefinitions = baseToolsOverride\n\t\t\t? Object.fromEntries(\n\t\t\t\t\tObject.entries(baseToolsOverride).map(([name, tool]) => [name, createToolDefinitionFromAgentTool(tool)]),\n\t\t\t\t)\n\t\t\t: createAllToolDefinitions(this.deps.getCwd(), {\n\t\t\t\t\tread: { autoResizeImages },\n\t\t\t\t\tbash: { commandPrefix: shellCommandPrefix, shellPath },\n\t\t\t\t\tgrep: { artifactStore: toolArtifactStore },\n\t\t\t\t\tfind: { artifactStore: toolArtifactStore },\n\t\t\t\t\tartifact_retrieve: { artifactStore: toolArtifactStore },\n\t\t\t\t});\n\n\t\tthis._baseToolDefinitions = new Map(\n\t\t\tObject.entries(baseToolDefinitions).map(([name, tool]) => [name, tool as ToolDefinition]),\n\t\t);\n\t\tif (!baseToolsOverride) {\n\t\t\tfor (const definition of createCoreDiagnosticsToolDefinitions(\n\t\t\t\t() => this.deps.getActiveToolNames(),\n\t\t\t\t() => this.getAllTools(),\n\t\t\t\t(messages) => this.deps.getContextGcReport(messages),\n\t\t\t\t() => this.deps.getMemoryAuditDiagnostics(),\n\t\t\t)) {\n\t\t\t\tthis._baseToolDefinitions.set(definition.name, definition);\n\t\t\t}\n\t\t\tconst goalToolDefinition = createGoalToolDefinition({\n\t\t\t\tgetGoalState: () => this.deps.getGoalStateSnapshot(),\n\t\t\t\tsaveGoalState: (state) => {\n\t\t\t\t\tthis.deps.saveGoalStateSnapshot(state);\n\t\t\t\t},\n\t\t\t});\n\t\t\tthis._baseToolDefinitions.set(goalToolDefinition.name, goalToolDefinition);\n\t\t\tconst delegateToolDefinition = createDelegateToolDefinition({\n\t\t\t\trunWorkerDelegation: (args) => this.deps.runWorkerDelegationOnce(args),\n\t\t\t});\n\t\t\tthis._baseToolDefinitions.set(delegateToolDefinition.name, delegateToolDefinition);\n\t\t\t// Registered but not default-active: probes spend tokens on the probed model, so\n\t\t\t// activation is an explicit choice (settings/profile/setActiveTools or /autonomy fitness).\n\t\t\tconst modelFitnessToolDefinition = createModelFitnessToolDefinition({\n\t\t\t\trunProbe: (args) => this.deps.runModelFitness(args),\n\t\t\t});\n\t\t\tthis._baseToolDefinitions.set(modelFitnessToolDefinition.name, modelFitnessToolDefinition);\n\t\t\tconst runToolkitScriptToolDefinition = createRunToolkitScriptToolDefinition({\n\t\t\t\tgetScripts: () => this.deps.getSettingsManager().getToolkitScripts(),\n\t\t\t\texecute: (script, scriptArgs) => executeToolkitScript({ script, scriptArgs, cwd: this.deps.getCwd() }),\n\t\t\t\t// Reflex brain (fitness-gated local model): resolves ambiguous requests into a\n\t\t\t\t// registry pick. Best-effort — absent/unfit brain keeps the shortlist behavior.\n\t\t\t\tinterpret: async (request, scripts) => {\n\t\t\t\t\tconst model = this.deps.resolveCurationModelIfFit();\n\t\t\t\t\tif (!model) return undefined;\n\t\t\t\t\tconst completion = await this.deps.runIsolatedCompletion({\n\t\t\t\t\t\tsystemPrompt: REFLEX_INTERPRETER_SYSTEM_PROMPT,\n\t\t\t\t\t\tmessages: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: buildReflexUserPrompt(request, scripts) }],\n\t\t\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tthinkingLevel: \"off\",\n\t\t\t\t\t\tmaxTokens: 256,\n\t\t\t\t\t\tcacheRetention: \"short\",\n\t\t\t\t\t});\n\t\t\t\t\tif (completion.usage.cost.total > 0 || completion.usage.totalTokens > 0) {\n\t\t\t\t\t\tthis.deps.addSpawnedUsage(completion.usage, { label: \"toolkit-brain\" });\n\t\t\t\t\t}\n\t\t\t\t\treturn parseReflexPlan(completion.text);\n\t\t\t\t},\n\t\t\t});\n\t\t\tthis._baseToolDefinitions.set(runToolkitScriptToolDefinition.name, runToolkitScriptToolDefinition);\n\t\t}\n\n\t\tconst extensionsResult = this.deps.getResourceLoader().getExtensions();\n\t\tif (options.flagValues) {\n\t\t\tfor (const [name, value] of options.flagValues) {\n\t\t\t\textensionsResult.runtime.flagValues.set(name, value);\n\t\t\t}\n\t\t}\n\t\tconst extensions = this.deps.filterExtensionsForRuntime(extensionsResult.extensions);\n\t\tconst runtimeExtensionPaths = new Set(extensions.map((extension) => extension.path));\n\t\textensionsResult.runtime.pendingProviderRegistrations =\n\t\t\textensionsResult.runtime.pendingProviderRegistrations.filter((registration) =>\n\t\t\t\truntimeExtensionPaths.has(registration.extensionPath),\n\t\t\t);\n\n\t\tconst runner = new ExtensionRunner(\n\t\t\textensions,\n\t\t\textensionsResult.runtime,\n\t\t\tthis.deps.getCwd(),\n\t\t\tthis.deps.getSessionManager(),\n\t\t\tthis.deps.getModelRegistry(),\n\t\t);\n\t\tthis.deps.setExtensionRunner(runner);\n\t\tthis.deps.bindExtensionCore(runner);\n\t\tthis.deps.applyExtensionBindings(runner);\n\n\t\tconst defaultActiveToolNames = baseToolsOverride\n\t\t\t? Object.keys(baseToolsOverride)\n\t\t\t: [\"read\", \"bash\", \"edit\", \"write\", \"context_audit\", \"goal\", \"delegate\", \"run_toolkit_script\"];\n\t\tconst baseActiveToolNames = options.activeToolNames ?? defaultActiveToolNames;\n\t\tthis.refreshToolRegistry({\n\t\t\tactiveToolNames: baseActiveToolNames,\n\t\t\tincludeAllExtensionTools: options.includeAllExtensionTools,\n\t\t});\n\t}\n\n\tasync reload(): Promise<void> {\n\t\tif (this.deps.isStreaming()) {\n\t\t\tthrow new Error(\"Cannot reload while the agent is streaming or a tool call is active\");\n\t\t}\n\t\tif (this.deps.isCompacting()) {\n\t\t\tthrow new Error(\"Cannot reload while context compaction or branch summarization is active\");\n\t\t}\n\t\tconst previousRunner = this.deps.getExtensionRunner();\n\t\tconst snapshot = this._createReloadRuntimeSnapshot();\n\t\t// Preserve the pre-filter tool REQUEST across the rebuild, not the capability/profile-filtered\n\t\t// active set — otherwise a reload under a small model permanently shrinks the restorable set.\n\t\tconst activeToolNames = this.deps.getRequestedActiveToolNames() ?? this.deps.getActiveToolNames();\n\t\tconst previousFlagValues = previousRunner.getFlagValues();\n\t\tconst reloadErrors: string[] = [];\n\t\tlet newRunner: ExtensionRunner | undefined;\n\t\ttry {\n\t\t\tawait this.deps.getSettingsManager().reload();\n\t\t\t// Re-derive the resource-profile tool filter from the freshly reloaded settings.\n\t\t\t// Unlike skills/prompts/themes (which re-filter through the resource loader on every\n\t\t\t// reload), the tool filter is held on the session, so without this a live edit to the\n\t\t\t// active profile's tools allow/block — or switching the active profile — would not\n\t\t\t// apply on /reload and allowed tools would stay missing.\n\t\t\tthis.deps.setToolProfileFilter(this.deps.deriveToolProfileFilter());\n\t\t\t// Re-apply the active profile's model/thinking from the freshly reloaded settings, so a live\n\t\t\t// profile edit (or switch) takes effect on /reload. Skipped when the launch used an explicit\n\t\t\t// --model/--thinking flag, which must win over the profile across reloads.\n\t\t\tawait this.deps.reapplyActiveProfileModelSettings();\n\t\t\tawait this.deps.getResourceLoader().reload({ failOnExtensionErrors: true, deferExtensionDispose: true });\n\t\t\tresetApiProviders();\n\t\t\tthis.buildRuntime({\n\t\t\t\tactiveToolNames,\n\t\t\t\tflagValues: previousFlagValues,\n\t\t\t\tincludeAllExtensionTools: true,\n\t\t\t});\n\t\t\tnewRunner = this.deps.getExtensionRunner();\n\t\t\tconst offDoctorErrors = newRunner.onError((error) => {\n\t\t\t\treloadErrors.push(`${error.extensionPath} ${error.event}: ${error.error}`);\n\t\t\t});\n\t\t\ttry {\n\t\t\t\tthis._doctorReloadRuntime();\n\t\t\t\t// Reload starts memory providers fresh; loaded extensions re-register below.\n\t\t\t\tthis.deps.clearPendingMemoryProviders();\n\t\t\t\tconst hasBindings =\n\t\t\t\t\tthis.deps.getExtensionUIContext() ||\n\t\t\t\t\tthis.deps.getExtensionCommandContextActions() ||\n\t\t\t\t\tthis.deps.getExtensionShutdownHandler() ||\n\t\t\t\t\tthis.deps.getExtensionErrorListener();\n\t\t\t\tif (hasBindings) {\n\t\t\t\t\tawait newRunner.emit({ type: \"session_start\", reason: \"reload\" });\n\t\t\t\t\tawait this.deps.extendResourcesFromExtensions(\"reload\");\n\t\t\t\t\tthis._doctorReloadRuntime();\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\toffDoctorErrors();\n\t\t\t}\n\t\t\tif (reloadErrors.length > 0) {\n\t\t\t\tthrow new Error(`Extension reload failed doctor: ${reloadErrors.slice(0, 6).join(\"; \")}`);\n\t\t\t}\n\t\t\tawait emitSessionShutdownEvent(previousRunner, { type: \"session_shutdown\", reason: \"reload\" });\n\t\t\tpreviousRunner.invalidate();\n\t\t\tthis.deps.getResourceLoader().commitReload?.();\n\t\t\t// Re-derive the memory subsystem from the reloaded settings/providers.\n\t\t\tawait this.deps.initializeMemory();\n\t\t} catch (error) {\n\t\t\tif (newRunner && newRunner !== previousRunner) {\n\t\t\t\tnewRunner.invalidate(\n\t\t\t\t\t\"This extension ctx was discarded because reload failed and Pi restored the previous valid runtime.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.deps.getResourceLoader().rollbackReload?.();\n\t\t\tthis._restoreReloadRuntimeSnapshot(snapshot);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Unload a single extension without full reload.\n\t * Runs the extension's session_shutdown lifecycle, unregisters its providers,\n\t * disposes its event subscriptions, and rebuilds the runtime.\n\t * Falls back to full reload on error.\n\t */\n\tasync unloadExtensionLive(extensionPath: string): Promise<void> {\n\t\tif (this.deps.isStreaming()) {\n\t\t\tthrow new Error(\"Cannot unload extension while the agent is streaming or a tool call is active\");\n\t\t}\n\t\tif (this.deps.isCompacting()) {\n\t\t\tthrow new Error(\"Cannot unload extension while context compaction or branch summarization is active\");\n\t\t}\n\n\t\tconst ext = this.deps.getResourceLoader().getLoadedExtension(extensionPath);\n\t\tif (!ext) {\n\t\t\treturn; // Nothing to unload\n\t\t}\n\n\t\tconst previousRunner = this.deps.getExtensionRunner();\n\t\ttry {\n\t\t\t// Run session_shutdown lifecycle for this extension only\n\t\t\tawait this.deps.getExtensionRunner().emitToExtension(ext, { type: \"session_shutdown\", reason: \"unload\" });\n\n\t\t\t// Unregister its providers (keyed by the extension's own path, as registered)\n\t\t\tconst runtime = this.deps.getResourceLoader().getExtensions().runtime;\n\t\t\tfor (const name of runtime.getProvidersForExtension(ext.path)) {\n\t\t\t\truntime.unregisterProvider(name, ext.path);\n\t\t\t}\n\n\t\t\t// Dispose its event subscriptions and run disposers\n\t\t\tawait disposeExtensionEventSubscriptions([ext]);\n\n\t\t\t// Remove from loaded extensions\n\t\t\tthis.deps.getResourceLoader().removeLoadedExtension(extensionPath);\n\n\t\t\t// Rebuild runtime with new extension set\n\t\t\tconst activeToolNames = this.deps.getRequestedActiveToolNames() ?? this.deps.getActiveToolNames();\n\t\t\tconst previousFlagValues = previousRunner.getFlagValues();\n\t\t\tthis.buildRuntime({\n\t\t\t\tactiveToolNames,\n\t\t\t\tflagValues: previousFlagValues,\n\t\t\t\tincludeAllExtensionTools: true,\n\t\t\t});\n\t\t\tpreviousRunner.invalidate();\n\n\t\t\t// Notify extensions-changed listeners\n\t\t\tthis.deps.notifyExtensionsChanged();\n\t\t} catch (error) {\n\t\t\t// Fall back to full reload on error\n\t\t\ttry {\n\t\t\t\tawait this.reload();\n\t\t\t} catch {\n\t\t\t\t// Suppress nested error; original error will be thrown below\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Load a single extension without full reload.\n\t * Loads the extension with fresh import, rebuilds the runtime,\n\t * and runs the extension's session_start lifecycle.\n\t * Falls back to full reload on error.\n\t */\n\tasync loadExtensionLive(extensionPath: string): Promise<void> {\n\t\tif (this.deps.isStreaming()) {\n\t\t\tthrow new Error(\"Cannot load extension while the agent is streaming or a tool call is active\");\n\t\t}\n\t\tif (this.deps.isCompacting()) {\n\t\t\tthrow new Error(\"Cannot load extension while context compaction or branch summarization is active\");\n\t\t}\n\n\t\tconst previousRunner = this.deps.getExtensionRunner();\n\t\ttry {\n\t\t\t// Load the extension with fresh import\n\t\t\tconst { extension, error } = await this.deps.getResourceLoader().loadSingleExtension(extensionPath);\n\t\t\tif (error || !extension) {\n\t\t\t\tthrow new Error(error || `Failed to load extension: ${extensionPath}`);\n\t\t\t}\n\n\t\t\t// Rebuild runtime to aggregate tools/commands/handlers/providers\n\t\t\tconst activeToolNames = this.deps.getRequestedActiveToolNames() ?? this.deps.getActiveToolNames();\n\t\t\tconst previousFlagValues = previousRunner.getFlagValues();\n\t\t\tthis.buildRuntime({\n\t\t\t\tactiveToolNames,\n\t\t\t\tflagValues: previousFlagValues,\n\t\t\t\tincludeAllExtensionTools: true,\n\t\t\t});\n\n\t\t\t// Run session_start lifecycle for the new extension only\n\t\t\tawait this.deps.getExtensionRunner().emitToExtension(extension, { type: \"session_start\", reason: \"load\" });\n\n\t\t\t// Notify extensions-changed listeners\n\t\t\tthis.deps.notifyExtensionsChanged();\n\t\t} catch (error) {\n\t\t\t// Fall back to full reload on error\n\t\t\ttry {\n\t\t\t\tawait this.reload();\n\t\t\t} catch {\n\t\t\t\t// Suppress nested error; original error will be thrown below\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Reconcile loaded extensions with the active profile.\n\t * Loads extensions that should be enabled but aren't, and unloads extensions that shouldn't be.\n\t * Falls back to full reload if any individual load/unload fails.\n\t */\n\tasync reconcileLoadedExtensions(): Promise<void> {\n\t\tif (this.deps.isStreaming()) {\n\t\t\tthrow new Error(\"Cannot reconcile extensions while the agent is streaming or a tool call is active\");\n\t\t}\n\t\tif (this.deps.isCompacting()) {\n\t\t\tthrow new Error(\"Cannot reconcile extensions while context compaction or branch summarization is active\");\n\t\t}\n\n\t\ttry {\n\t\t\t// Get all discoverable extension paths\n\t\t\tconst allDiscoverablePaths = await this.deps.getResourceLoader().getDiscoverableExtensionPaths();\n\n\t\t\t// Get the target enabled set based on profile filters\n\t\t\tconst targetEnabledSet = new Set<string>();\n\t\t\tfor (const path of allDiscoverablePaths) {\n\t\t\t\tif (this.deps.getSettingsManager().isResourceAllowedByProfile(\"extensions\", path)) {\n\t\t\t\t\ttargetEnabledSet.add(path);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Get currently loaded set\n\t\t\tconst loadedExtensions = this.deps.getResourceLoader().getExtensions().extensions;\n\t\t\tconst loadedSet = new Set<string>();\n\t\t\tfor (const ext of loadedExtensions) {\n\t\t\t\tloadedSet.add(ext.path);\n\t\t\t}\n\n\t\t\t// Collect unloads and loads\n\t\t\tconst toUnload: string[] = [];\n\t\t\tconst toLoad: string[] = [];\n\n\t\t\tfor (const path of loadedSet) {\n\t\t\t\tif (!targetEnabledSet.has(path)) {\n\t\t\t\t\ttoUnload.push(path);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const path of targetEnabledSet) {\n\t\t\t\tif (!loadedSet.has(path)) {\n\t\t\t\t\ttoLoad.push(path);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Apply unloads first, then loads, to minimize churn\n\t\t\t// Collect errors but continue through all operations\n\t\t\tconst errors: Error[] = [];\n\n\t\t\tfor (const path of toUnload) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.unloadExtensionLive(path);\n\t\t\t\t} catch (error) {\n\t\t\t\t\terrors.push(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const path of toLoad) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.loadExtensionLive(path);\n\t\t\t\t} catch (error) {\n\t\t\t\t\terrors.push(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If any errors occurred, throw the first one (already fell back to full reload in load/unload)\n\t\t\tif (errors.length > 0) {\n\t\t\t\tthrow errors[0];\n\t\t\t}\n\n\t\t\t// Single notification at the end\n\t\t\tthis.deps.notifyExtensionsChanged();\n\t\t} catch (error) {\n\t\t\t// Fall back to full reload on error\n\t\t\ttry {\n\t\t\t\tawait this.reload();\n\t\t\t} catch {\n\t\t\t\t// Suppress nested error; original error will be thrown below\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n"]}
|