@caupulican/pi-adaptative 0.80.103 → 0.81.1
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 +128 -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 +154 -512
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +675 -4589
- 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/http-dispatcher.d.ts +4 -1
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js +6 -1
- package/dist/core/http-dispatcher.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/settings-manager.d.ts +16 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +22 -0
- package/dist/core/settings-manager.js.map +1 -1
- 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
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory controller: the session's plug-and-play memory subsystem — the read-only OKF retrieval
|
|
3
|
+
* provider, the bounded prompt-evidence surfacing pilot, cross-session recall effectiveness, and the
|
|
4
|
+
* live {@link MemoryManager} (bundled file-store + transcript-recall providers plus any extension
|
|
5
|
+
* contributions).
|
|
6
|
+
*
|
|
7
|
+
* Extracted verbatim from agent-session.ts (god-file decomposition). Owns the lazily-built OKF
|
|
8
|
+
* provider, the latest retrieval/prompt-inclusion reports, the recreated-on-reload MemoryManager, the
|
|
9
|
+
* recall {@link EffectivenessTracker}, and the extension-contributed pending providers. Everything
|
|
10
|
+
* else it needs — settings, the current turn index, agent/workspace dirs, the session id, the
|
|
11
|
+
* child-session flag, and the tool-registry refresh — is reached through narrow deps accessors rather
|
|
12
|
+
* than the whole AgentSession.
|
|
13
|
+
*
|
|
14
|
+
* Context-transform boundary (deliberate): {@link runMemoryRetrieval} and
|
|
15
|
+
* {@link maybeAppendMemoryEvidenceBlock} are invoked from the session's context transform as one-line
|
|
16
|
+
* delegations. This controller deliberately imports no compaction/context-pipeline internals — it only
|
|
17
|
+
* ever reads settings and builds the retrieval report + the bounded evidence block, so the transform
|
|
18
|
+
* stays the single owner of the pass ordering.
|
|
19
|
+
*/
|
|
20
|
+
import { join } from "node:path";
|
|
21
|
+
import { defaultMemoryPromptInclusionReport, sanitizeMemoryRetrievalReportForDiagnostics, } from "./context/memory-diagnostics.js";
|
|
22
|
+
import { buildMemoryPromptBlock } from "./context/memory-prompt-block.js";
|
|
23
|
+
import { DEFAULT_LOCAL_MEMORY_EGRESS_POLICY, } from "./context/memory-provider-contract.js";
|
|
24
|
+
import { retrieveMemoryForContext } from "./context/memory-retrieval.js";
|
|
25
|
+
import { createOkfMemoryProvider } from "./context/okf-memory-provider.js";
|
|
26
|
+
import { EffectivenessTracker } from "./memory/effectiveness-tracker.js";
|
|
27
|
+
import { MemoryManager } from "./memory/memory-manager.js";
|
|
28
|
+
import { FileStoreProvider } from "./memory/providers/file-store.js";
|
|
29
|
+
import { TranscriptRecallProvider } from "./memory/providers/transcript-recall.js";
|
|
30
|
+
import { wrapUntrustedText } from "./security/untrusted-boundary.js";
|
|
31
|
+
/**
|
|
32
|
+
* Text of the most recent user message, or "" if there is none (e.g. goal-continuation
|
|
33
|
+
* turns with no new user input). An empty query degrades to zero memory-retrieval results
|
|
34
|
+
* by construction (see memory-provider-contract.ts's score-on-empty-query-tokens rule) --
|
|
35
|
+
* no special-casing needed here beyond returning "".
|
|
36
|
+
*/
|
|
37
|
+
function latestUserMessageText(messages) {
|
|
38
|
+
for (let index = messages.length - 1; index >= 0; index--) {
|
|
39
|
+
const message = messages[index];
|
|
40
|
+
if (message.role !== "user")
|
|
41
|
+
continue;
|
|
42
|
+
if (typeof message.content === "string")
|
|
43
|
+
return message.content;
|
|
44
|
+
const parts = [];
|
|
45
|
+
for (const part of message.content) {
|
|
46
|
+
if (part.type === "text")
|
|
47
|
+
parts.push(part.text);
|
|
48
|
+
}
|
|
49
|
+
return parts.join("\n");
|
|
50
|
+
}
|
|
51
|
+
return "";
|
|
52
|
+
}
|
|
53
|
+
function emptyMemoryRetrievalReport(maxResults) {
|
|
54
|
+
return { request: { query: "", maxResults }, providerReports: [], results: [], contextItems: [] };
|
|
55
|
+
}
|
|
56
|
+
export class MemoryController {
|
|
57
|
+
_memoryOkfProvider = undefined;
|
|
58
|
+
_latestMemoryRetrievalReport = undefined;
|
|
59
|
+
_latestMemoryPromptInclusionReport = undefined;
|
|
60
|
+
/** Plug-and-play memory subsystem. Recreated on each (re)initialize so reload is safe. */
|
|
61
|
+
_memoryManager = new MemoryManager();
|
|
62
|
+
/** R4: tracks whether injected recall is actually used, to adapt the recall gate. */
|
|
63
|
+
_effectivenessTracker = new EffectivenessTracker();
|
|
64
|
+
/** Memory providers registered by extensions via pi.registerMemoryProvider, applied on (re)init. */
|
|
65
|
+
_pendingMemoryProviders = [];
|
|
66
|
+
deps;
|
|
67
|
+
constructor(deps) {
|
|
68
|
+
this.deps = deps;
|
|
69
|
+
}
|
|
70
|
+
/** The live memory manager. Callers reach prefetch / tool-definitions / markers / shutdown through it. */
|
|
71
|
+
getMemoryManager() {
|
|
72
|
+
return this._memoryManager;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Fixed path for this slice's local Pi OKF memory documents, shared across sessions
|
|
76
|
+
* under this agentDir (not session-scoped, unlike tool-artifacts/context-gc, since OKF
|
|
77
|
+
* memory represents durable cross-session knowledge, not a per-session capture). Not
|
|
78
|
+
* yet user-configurable -- see the memory-retrieval settings doc comment.
|
|
79
|
+
*/
|
|
80
|
+
_memoryOkfDir() {
|
|
81
|
+
return join(this.deps.getAgentDir(), "okf-memory");
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Session-scoped, read-only local OKF memory provider. Lazily created ONLY when memory
|
|
85
|
+
* retrieval is enabled (see `runMemoryRetrieval`) -- never force-created, so a session
|
|
86
|
+
* with the setting off never touches `_memoryOkfDir()` at all (no directory access, no
|
|
87
|
+
* creation; `createOkfMemoryProvider` itself never writes/mkdirs either way).
|
|
88
|
+
*/
|
|
89
|
+
_getMemoryOkfProvider() {
|
|
90
|
+
this._memoryOkfProvider ??= createOkfMemoryProvider({ rootDir: this._memoryOkfDir() });
|
|
91
|
+
return this._memoryOkfProvider;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Observe-only local memory retrieval (see context/memory-retrieval.ts and
|
|
95
|
+
* context/okf-memory-provider.ts): default disabled, opt-in setting. When disabled,
|
|
96
|
+
* never constructs the OKF provider (no directory access under `_memoryOkfDir()` at
|
|
97
|
+
* all) and returns an empty report -- fully fail-closed. When enabled, queries the
|
|
98
|
+
* local, read-only OKF provider with the latest user message text (empty if there is
|
|
99
|
+
* none, e.g. a goal-continuation turn -- degrades to zero results by construction, see
|
|
100
|
+
* `latestUserMessageText`'s doc comment) under `DEFAULT_LOCAL_MEMORY_EGRESS_POLICY`.
|
|
101
|
+
* Retrieved items are only ever stored in the report; nothing here touches `messages`,
|
|
102
|
+
* the transcript, or the provider-visible prompt. Never throws into a live turn: any
|
|
103
|
+
* failure (including a provider search error) degrades to an empty report.
|
|
104
|
+
*/
|
|
105
|
+
async runMemoryRetrieval(messages) {
|
|
106
|
+
try {
|
|
107
|
+
const settings = this.deps.getSettingsManager().getMemoryRetrievalSettings();
|
|
108
|
+
if (!settings.enabled) {
|
|
109
|
+
const report = emptyMemoryRetrievalReport(settings.maxResults);
|
|
110
|
+
this._latestMemoryRetrievalReport = report;
|
|
111
|
+
return report;
|
|
112
|
+
}
|
|
113
|
+
const report = await retrieveMemoryForContext([this._getMemoryOkfProvider()], { query: latestUserMessageText(messages), maxResults: settings.maxResults }, {
|
|
114
|
+
createdAtTurn: this.deps.getTurnIndex(),
|
|
115
|
+
maxResults: settings.maxResults,
|
|
116
|
+
defaultLocalPolicy: DEFAULT_LOCAL_MEMORY_EGRESS_POLICY,
|
|
117
|
+
});
|
|
118
|
+
this._latestMemoryRetrievalReport = report;
|
|
119
|
+
return report;
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
const report = emptyMemoryRetrievalReport(0);
|
|
123
|
+
this._latestMemoryRetrievalReport = report;
|
|
124
|
+
return report;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/** Read-only inspection of the latest memory-retrieval report, for tests/debugging. */
|
|
128
|
+
getMemoryRetrievalReport() {
|
|
129
|
+
return this._latestMemoryRetrievalReport ?? emptyMemoryRetrievalReport(0);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Bounded prompt-surfacing pilot for local memory evidence (see
|
|
133
|
+
* context/memory-prompt-block.ts): opt-in, default disabled, and gated on TWO settings
|
|
134
|
+
* (`enabled` AND `includeInPrompt`) plus a non-empty `report.contextItems` -- the first
|
|
135
|
+
* two are belt-and-suspenders on top of the fact that `runMemoryRetrieval` already
|
|
136
|
+
* leaves `contextItems` empty whenever `enabled` is false, regardless of
|
|
137
|
+
* `includeInPrompt`. Reuses the `report` this pass's `runMemoryRetrieval` call already
|
|
138
|
+
* computed -- never re-queries the provider here.
|
|
139
|
+
*
|
|
140
|
+
* Appends exactly one ephemeral `custom`/"memory_evidence" message wrapped by
|
|
141
|
+
* `wrapUntrustedText` (the same nonce-fenced boundary + always-on system-prompt rule
|
|
142
|
+
* used for other untrusted content) to the END of `messages`. This is purely additive
|
|
143
|
+
* (never mutates an existing message) and purely transient: `messages` here is the
|
|
144
|
+
* array about to be sent to the provider, not `this.agent.state.messages` or anything
|
|
145
|
+
* persisted via `sessionManager` -- so the injected message can never reach the
|
|
146
|
+
* transcript, regardless of how many times this pass runs.
|
|
147
|
+
*
|
|
148
|
+
* Also records a `MemoryPromptInclusionReport` (context/memory-diagnostics.ts) at each
|
|
149
|
+
* branch below, for context_audit's diagnostic surface only -- this is pure bookkeeping
|
|
150
|
+
* alongside the existing branches, not a new branch/condition: the messages returned
|
|
151
|
+
* are unchanged by this recording.
|
|
152
|
+
*/
|
|
153
|
+
maybeAppendMemoryEvidenceBlock(messages, report) {
|
|
154
|
+
try {
|
|
155
|
+
const settings = this.deps.getSettingsManager().getMemoryRetrievalSettings();
|
|
156
|
+
const base = {
|
|
157
|
+
enabled: settings.enabled,
|
|
158
|
+
includeInPrompt: settings.includeInPrompt,
|
|
159
|
+
selectedItemCount: report.contextItems.length,
|
|
160
|
+
};
|
|
161
|
+
if (!settings.enabled) {
|
|
162
|
+
this._latestMemoryPromptInclusionReport = {
|
|
163
|
+
...base,
|
|
164
|
+
status: "disabled",
|
|
165
|
+
includedCount: 0,
|
|
166
|
+
omittedCount: 0,
|
|
167
|
+
blockChars: 0,
|
|
168
|
+
};
|
|
169
|
+
return messages;
|
|
170
|
+
}
|
|
171
|
+
if (!settings.includeInPrompt) {
|
|
172
|
+
this._latestMemoryPromptInclusionReport = {
|
|
173
|
+
...base,
|
|
174
|
+
status: "include_disabled",
|
|
175
|
+
includedCount: 0,
|
|
176
|
+
omittedCount: 0,
|
|
177
|
+
blockChars: 0,
|
|
178
|
+
};
|
|
179
|
+
return messages;
|
|
180
|
+
}
|
|
181
|
+
if (report.contextItems.length === 0) {
|
|
182
|
+
this._latestMemoryPromptInclusionReport = {
|
|
183
|
+
...base,
|
|
184
|
+
status: "no_results",
|
|
185
|
+
includedCount: 0,
|
|
186
|
+
omittedCount: 0,
|
|
187
|
+
blockChars: 0,
|
|
188
|
+
};
|
|
189
|
+
return messages;
|
|
190
|
+
}
|
|
191
|
+
const block = buildMemoryPromptBlock(report.contextItems);
|
|
192
|
+
if (!block.text) {
|
|
193
|
+
this._latestMemoryPromptInclusionReport = {
|
|
194
|
+
...base,
|
|
195
|
+
status: "empty_block",
|
|
196
|
+
includedCount: block.includedCount,
|
|
197
|
+
omittedCount: block.omittedCount,
|
|
198
|
+
blockChars: 0,
|
|
199
|
+
};
|
|
200
|
+
return messages;
|
|
201
|
+
}
|
|
202
|
+
const wrapped = wrapUntrustedText(block.text, "memory:pi-okf");
|
|
203
|
+
const evidenceMessage = {
|
|
204
|
+
role: "custom",
|
|
205
|
+
customType: "memory_evidence",
|
|
206
|
+
content: [{ type: "text", text: wrapped }],
|
|
207
|
+
display: false,
|
|
208
|
+
timestamp: Date.now(),
|
|
209
|
+
};
|
|
210
|
+
this._latestMemoryPromptInclusionReport = {
|
|
211
|
+
...base,
|
|
212
|
+
status: "included",
|
|
213
|
+
includedCount: block.includedCount,
|
|
214
|
+
omittedCount: block.omittedCount,
|
|
215
|
+
blockChars: wrapped.length,
|
|
216
|
+
sourceLabel: "memory:pi-okf",
|
|
217
|
+
};
|
|
218
|
+
return [...messages, evidenceMessage];
|
|
219
|
+
}
|
|
220
|
+
catch {
|
|
221
|
+
// `base` may not exist yet if the throw happened before it was computed (e.g.
|
|
222
|
+
// settings access or `report.contextItems` itself threw), so this branch cannot
|
|
223
|
+
// rely on it -- fall back to safe, fixed defaults rather than risk referencing
|
|
224
|
+
// a partially-evaluated value.
|
|
225
|
+
this._latestMemoryPromptInclusionReport = {
|
|
226
|
+
enabled: false,
|
|
227
|
+
includeInPrompt: false,
|
|
228
|
+
selectedItemCount: 0,
|
|
229
|
+
status: "failed",
|
|
230
|
+
includedCount: 0,
|
|
231
|
+
omittedCount: 0,
|
|
232
|
+
blockChars: 0,
|
|
233
|
+
};
|
|
234
|
+
return messages;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/** Read-only inspection of the latest memory-prompt-inclusion decision, for tests/debugging and context_audit. */
|
|
238
|
+
getMemoryPromptInclusionReport() {
|
|
239
|
+
return this._latestMemoryPromptInclusionReport ?? defaultMemoryPromptInclusionReport();
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Combines the already-stored, no-arg latest reports (never re-queries the provider or
|
|
243
|
+
* touches the OKF directory) into the safe, allow-list-projected shape context_audit
|
|
244
|
+
* exposes. See context/memory-diagnostics.ts for why this projection is allow-list
|
|
245
|
+
* based rather than a spread-then-delete of the raw report.
|
|
246
|
+
*/
|
|
247
|
+
getMemoryAuditDiagnostics() {
|
|
248
|
+
const settings = this.deps.getSettingsManager().getMemoryRetrievalSettings();
|
|
249
|
+
return {
|
|
250
|
+
retrieval: sanitizeMemoryRetrievalReportForDiagnostics(this.getMemoryRetrievalReport(), settings),
|
|
251
|
+
promptInclusion: this.getMemoryPromptInclusionReport(),
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Zero-I/O gate for cross-session recall (R3): skip trivial turns (short acks, slash commands) so
|
|
256
|
+
* recall only runs when it could plausibly help. The provider's similarity cutoff is the real
|
|
257
|
+
* filter — this just avoids the index query on turns that obviously don't warrant it.
|
|
258
|
+
*/
|
|
259
|
+
shouldAttemptRecall(text) {
|
|
260
|
+
const t = text.trim();
|
|
261
|
+
if (t.length < 12 || t.startsWith("/"))
|
|
262
|
+
return false;
|
|
263
|
+
const words = t.split(/\s+/).filter((w) => w.length >= 3);
|
|
264
|
+
// R4 adaptive gate: if recall has rarely been used lately (enough samples to trust the signal),
|
|
265
|
+
// raise the bar so we only recall on clearly substantial turns — and relax it again once recall
|
|
266
|
+
// starts paying off. Never fully disabled, so the loop can recover.
|
|
267
|
+
const recallRarelyUseful = this._effectivenessTracker.sampleCount >= 5 && this._effectivenessTracker.usefulLately() < 0.15;
|
|
268
|
+
return words.length >= (recallRarelyUseful ? 6 : 3);
|
|
269
|
+
}
|
|
270
|
+
/** R4: score whether the agent actually used an injected recall page, so the recall gate can adapt. */
|
|
271
|
+
recordRecallOutcome(recallText, queryText, responseText) {
|
|
272
|
+
this._effectivenessTracker.recordRecallOutcome(recallText, queryText, responseText);
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* (Re)build the memory subsystem: a fresh MemoryManager (reload-safe), register the bundled
|
|
276
|
+
* file-store + any extension-contributed providers, initialize, then surface the memory tools and
|
|
277
|
+
* the frozen system-prompt block. Best-effort: never throws into the session lifecycle.
|
|
278
|
+
*/
|
|
279
|
+
async initialize() {
|
|
280
|
+
try {
|
|
281
|
+
// Release the previous generation's providers (locks/handles) before recreating, so a
|
|
282
|
+
// reload does not orphan the old MemoryManager. No-op on first init / for file-store.
|
|
283
|
+
await this._memoryManager.shutdownAll().catch(() => { });
|
|
284
|
+
const manager = new MemoryManager();
|
|
285
|
+
manager.registerProvider(new FileStoreProvider());
|
|
286
|
+
// Bundled read-only cross-session recall (R3): indexes past-session transcripts and answers
|
|
287
|
+
// prefetch() with a <memory_context> page. Never writes.
|
|
288
|
+
manager.registerProvider(new TranscriptRecallProvider());
|
|
289
|
+
for (const provider of this._pendingMemoryProviders) {
|
|
290
|
+
try {
|
|
291
|
+
manager.registerProvider(provider);
|
|
292
|
+
}
|
|
293
|
+
catch {
|
|
294
|
+
// Duplicate name or reserved-tool collision — skip this provider, keep the rest.
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
this._memoryManager = manager;
|
|
298
|
+
await manager.initializeAll(this.deps.getSessionId(), {
|
|
299
|
+
agentDir: this.deps.getAgentDir(),
|
|
300
|
+
cwd: this.deps.getCwd(),
|
|
301
|
+
isChildSession: this.deps.isChildSession(),
|
|
302
|
+
});
|
|
303
|
+
// Surface memory tools + the frozen memory block now that providers are initialized.
|
|
304
|
+
// refreshToolRegistry() ends in setActiveToolsByName(), which rebuilds AND assigns the
|
|
305
|
+
// system prompt (including the memory block), so no explicit _rebuildSystemPrompt is needed.
|
|
306
|
+
this.deps.refreshToolRegistry();
|
|
307
|
+
}
|
|
308
|
+
catch (error) {
|
|
309
|
+
console.error("Memory subsystem init failed:", error instanceof Error ? error.message : String(error));
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
/** Register a memory provider contributed by an extension; applied on the next memory (re)init. */
|
|
313
|
+
registerMemoryProvider(provider) {
|
|
314
|
+
if (!this._pendingMemoryProviders.some((p) => p.name === provider.name)) {
|
|
315
|
+
this._pendingMemoryProviders.push(provider);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
/** Reload starts memory providers fresh; loaded extensions re-register before the next `initialize()`. */
|
|
319
|
+
clearPendingProviders() {
|
|
320
|
+
this._pendingMemoryProviders = [];
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
//# sourceMappingURL=memory-controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-controller.js","sourceRoot":"","sources":["../../src/core/memory-controller.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Memory controller: the session's plug-and-play memory subsystem — the read-only OKF retrieval\n * provider, the bounded prompt-evidence surfacing pilot, cross-session recall effectiveness, and the\n * live {@link MemoryManager} (bundled file-store + transcript-recall providers plus any extension\n * contributions).\n *\n * Extracted verbatim from agent-session.ts (god-file decomposition). Owns the lazily-built OKF\n * provider, the latest retrieval/prompt-inclusion reports, the recreated-on-reload MemoryManager, the\n * recall {@link EffectivenessTracker}, and the extension-contributed pending providers. Everything\n * else it needs — settings, the current turn index, agent/workspace dirs, the session id, the\n * child-session flag, and the tool-registry refresh — is reached through narrow deps accessors rather\n * than the whole AgentSession.\n *\n * Context-transform boundary (deliberate): {@link runMemoryRetrieval} and\n * {@link maybeAppendMemoryEvidenceBlock} are invoked from the session's context transform as one-line\n * delegations. This controller deliberately imports no compaction/context-pipeline internals — it only\n * ever reads settings and builds the retrieval report + the bounded evidence block, so the transform\n * stays the single owner of the pass ordering.\n */\n\nimport { join } from \"node:path\";\nimport type { AgentMessage, CustomMessage } from \"@caupulican/pi-agent-core\";\nimport {\n\tdefaultMemoryPromptInclusionReport,\n\ttype MemoryPromptInclusionReport,\n\ttype MemoryRetrievalDiagnostics,\n\tsanitizeMemoryRetrievalReportForDiagnostics,\n} from \"./context/memory-diagnostics.ts\";\nimport { buildMemoryPromptBlock } from \"./context/memory-prompt-block.ts\";\nimport {\n\ttype MemoryProvider as ContextMemoryProvider,\n\tDEFAULT_LOCAL_MEMORY_EGRESS_POLICY,\n} from \"./context/memory-provider-contract.ts\";\nimport { type MemoryRetrievalReport, retrieveMemoryForContext } from \"./context/memory-retrieval.ts\";\nimport { createOkfMemoryProvider } from \"./context/okf-memory-provider.ts\";\nimport { EffectivenessTracker } from \"./memory/effectiveness-tracker.ts\";\nimport { MemoryManager } from \"./memory/memory-manager.ts\";\nimport type { MemoryProvider } from \"./memory/memory-provider.ts\";\nimport { FileStoreProvider } from \"./memory/providers/file-store.ts\";\nimport { TranscriptRecallProvider } from \"./memory/providers/transcript-recall.ts\";\nimport { wrapUntrustedText } from \"./security/untrusted-boundary.ts\";\nimport type { SettingsManager } from \"./settings-manager.ts\";\n\n/**\n * Text of the most recent user message, or \"\" if there is none (e.g. goal-continuation\n * turns with no new user input). An empty query degrades to zero memory-retrieval results\n * by construction (see memory-provider-contract.ts's score-on-empty-query-tokens rule) --\n * no special-casing needed here beyond returning \"\".\n */\nfunction latestUserMessageText(messages: AgentMessage[]): string {\n\tfor (let index = messages.length - 1; index >= 0; index--) {\n\t\tconst message = messages[index];\n\t\tif (message.role !== \"user\") continue;\n\t\tif (typeof message.content === \"string\") return message.content;\n\t\tconst parts: string[] = [];\n\t\tfor (const part of message.content) {\n\t\t\tif (part.type === \"text\") parts.push(part.text);\n\t\t}\n\t\treturn parts.join(\"\\n\");\n\t}\n\treturn \"\";\n}\n\nfunction emptyMemoryRetrievalReport(maxResults: number): MemoryRetrievalReport {\n\treturn { request: { query: \"\", maxResults }, providerReports: [], results: [], contextItems: [] };\n}\n\nexport interface MemoryControllerDeps {\n\t/** Memory-retrieval + prompt-inclusion settings (the opt-in gates for retrieval and surfacing). */\n\tgetSettingsManager(): SettingsManager;\n\t/** Current turn index, stamped into a retrieval request's `createdAtTurn`. */\n\tgetTurnIndex(): number;\n\t/** Agent root — the durable OKF memory docs live under `<agentDir>/okf-memory`. */\n\tgetAgentDir(): string;\n\t/** Workspace root, passed to provider initialization. */\n\tgetCwd(): string;\n\t/** This session's id, passed to provider initialization. */\n\tgetSessionId(): string;\n\t/** Child sessions gate durable memory writes; passed to provider initialization. */\n\tisChildSession(): boolean;\n\t/** Re-derive the tool registry after (re)init so the newly-surfaced memory tools take effect. */\n\trefreshToolRegistry(): void;\n}\n\nexport class MemoryController {\n\tprivate _memoryOkfProvider: ContextMemoryProvider | undefined = undefined;\n\tprivate _latestMemoryRetrievalReport: MemoryRetrievalReport | undefined = undefined;\n\tprivate _latestMemoryPromptInclusionReport: MemoryPromptInclusionReport | undefined = undefined;\n\t/** Plug-and-play memory subsystem. Recreated on each (re)initialize so reload is safe. */\n\tprivate _memoryManager: MemoryManager = new MemoryManager();\n\t/** R4: tracks whether injected recall is actually used, to adapt the recall gate. */\n\tprivate readonly _effectivenessTracker = new EffectivenessTracker();\n\t/** Memory providers registered by extensions via pi.registerMemoryProvider, applied on (re)init. */\n\tprivate _pendingMemoryProviders: MemoryProvider[] = [];\n\n\tprivate readonly deps: MemoryControllerDeps;\n\n\tconstructor(deps: MemoryControllerDeps) {\n\t\tthis.deps = deps;\n\t}\n\n\t/** The live memory manager. Callers reach prefetch / tool-definitions / markers / shutdown through it. */\n\tgetMemoryManager(): MemoryManager {\n\t\treturn this._memoryManager;\n\t}\n\n\t/**\n\t * Fixed path for this slice's local Pi OKF memory documents, shared across sessions\n\t * under this agentDir (not session-scoped, unlike tool-artifacts/context-gc, since OKF\n\t * memory represents durable cross-session knowledge, not a per-session capture). Not\n\t * yet user-configurable -- see the memory-retrieval settings doc comment.\n\t */\n\tprivate _memoryOkfDir(): string {\n\t\treturn join(this.deps.getAgentDir(), \"okf-memory\");\n\t}\n\n\t/**\n\t * Session-scoped, read-only local OKF memory provider. Lazily created ONLY when memory\n\t * retrieval is enabled (see `runMemoryRetrieval`) -- never force-created, so a session\n\t * with the setting off never touches `_memoryOkfDir()` at all (no directory access, no\n\t * creation; `createOkfMemoryProvider` itself never writes/mkdirs either way).\n\t */\n\tprivate _getMemoryOkfProvider(): ContextMemoryProvider {\n\t\tthis._memoryOkfProvider ??= createOkfMemoryProvider({ rootDir: this._memoryOkfDir() });\n\t\treturn this._memoryOkfProvider;\n\t}\n\n\t/**\n\t * Observe-only local memory retrieval (see context/memory-retrieval.ts and\n\t * context/okf-memory-provider.ts): default disabled, opt-in setting. When disabled,\n\t * never constructs the OKF provider (no directory access under `_memoryOkfDir()` at\n\t * all) and returns an empty report -- fully fail-closed. When enabled, queries the\n\t * local, read-only OKF provider with the latest user message text (empty if there is\n\t * none, e.g. a goal-continuation turn -- degrades to zero results by construction, see\n\t * `latestUserMessageText`'s doc comment) under `DEFAULT_LOCAL_MEMORY_EGRESS_POLICY`.\n\t * Retrieved items are only ever stored in the report; nothing here touches `messages`,\n\t * the transcript, or the provider-visible prompt. Never throws into a live turn: any\n\t * failure (including a provider search error) degrades to an empty report.\n\t */\n\tasync runMemoryRetrieval(messages: AgentMessage[]): Promise<MemoryRetrievalReport> {\n\t\ttry {\n\t\t\tconst settings = this.deps.getSettingsManager().getMemoryRetrievalSettings();\n\t\t\tif (!settings.enabled) {\n\t\t\t\tconst report = emptyMemoryRetrievalReport(settings.maxResults);\n\t\t\t\tthis._latestMemoryRetrievalReport = report;\n\t\t\t\treturn report;\n\t\t\t}\n\t\t\tconst report = await retrieveMemoryForContext(\n\t\t\t\t[this._getMemoryOkfProvider()],\n\t\t\t\t{ query: latestUserMessageText(messages), maxResults: settings.maxResults },\n\t\t\t\t{\n\t\t\t\t\tcreatedAtTurn: this.deps.getTurnIndex(),\n\t\t\t\t\tmaxResults: settings.maxResults,\n\t\t\t\t\tdefaultLocalPolicy: DEFAULT_LOCAL_MEMORY_EGRESS_POLICY,\n\t\t\t\t},\n\t\t\t);\n\t\t\tthis._latestMemoryRetrievalReport = report;\n\t\t\treturn report;\n\t\t} catch {\n\t\t\tconst report = emptyMemoryRetrievalReport(0);\n\t\t\tthis._latestMemoryRetrievalReport = report;\n\t\t\treturn report;\n\t\t}\n\t}\n\n\t/** Read-only inspection of the latest memory-retrieval report, for tests/debugging. */\n\tgetMemoryRetrievalReport(): MemoryRetrievalReport {\n\t\treturn this._latestMemoryRetrievalReport ?? emptyMemoryRetrievalReport(0);\n\t}\n\n\t/**\n\t * Bounded prompt-surfacing pilot for local memory evidence (see\n\t * context/memory-prompt-block.ts): opt-in, default disabled, and gated on TWO settings\n\t * (`enabled` AND `includeInPrompt`) plus a non-empty `report.contextItems` -- the first\n\t * two are belt-and-suspenders on top of the fact that `runMemoryRetrieval` already\n\t * leaves `contextItems` empty whenever `enabled` is false, regardless of\n\t * `includeInPrompt`. Reuses the `report` this pass's `runMemoryRetrieval` call already\n\t * computed -- never re-queries the provider here.\n\t *\n\t * Appends exactly one ephemeral `custom`/\"memory_evidence\" message wrapped by\n\t * `wrapUntrustedText` (the same nonce-fenced boundary + always-on system-prompt rule\n\t * used for other untrusted content) to the END of `messages`. This is purely additive\n\t * (never mutates an existing message) and purely transient: `messages` here is the\n\t * array about to be sent to the provider, not `this.agent.state.messages` or anything\n\t * persisted via `sessionManager` -- so the injected message can never reach the\n\t * transcript, regardless of how many times this pass runs.\n\t *\n\t * Also records a `MemoryPromptInclusionReport` (context/memory-diagnostics.ts) at each\n\t * branch below, for context_audit's diagnostic surface only -- this is pure bookkeeping\n\t * alongside the existing branches, not a new branch/condition: the messages returned\n\t * are unchanged by this recording.\n\t */\n\tmaybeAppendMemoryEvidenceBlock(messages: AgentMessage[], report: MemoryRetrievalReport): AgentMessage[] {\n\t\ttry {\n\t\t\tconst settings = this.deps.getSettingsManager().getMemoryRetrievalSettings();\n\t\t\tconst base = {\n\t\t\t\tenabled: settings.enabled,\n\t\t\t\tincludeInPrompt: settings.includeInPrompt,\n\t\t\t\tselectedItemCount: report.contextItems.length,\n\t\t\t};\n\t\t\tif (!settings.enabled) {\n\t\t\t\tthis._latestMemoryPromptInclusionReport = {\n\t\t\t\t\t...base,\n\t\t\t\t\tstatus: \"disabled\",\n\t\t\t\t\tincludedCount: 0,\n\t\t\t\t\tomittedCount: 0,\n\t\t\t\t\tblockChars: 0,\n\t\t\t\t};\n\t\t\t\treturn messages;\n\t\t\t}\n\t\t\tif (!settings.includeInPrompt) {\n\t\t\t\tthis._latestMemoryPromptInclusionReport = {\n\t\t\t\t\t...base,\n\t\t\t\t\tstatus: \"include_disabled\",\n\t\t\t\t\tincludedCount: 0,\n\t\t\t\t\tomittedCount: 0,\n\t\t\t\t\tblockChars: 0,\n\t\t\t\t};\n\t\t\t\treturn messages;\n\t\t\t}\n\t\t\tif (report.contextItems.length === 0) {\n\t\t\t\tthis._latestMemoryPromptInclusionReport = {\n\t\t\t\t\t...base,\n\t\t\t\t\tstatus: \"no_results\",\n\t\t\t\t\tincludedCount: 0,\n\t\t\t\t\tomittedCount: 0,\n\t\t\t\t\tblockChars: 0,\n\t\t\t\t};\n\t\t\t\treturn messages;\n\t\t\t}\n\n\t\t\tconst block = buildMemoryPromptBlock(report.contextItems);\n\t\t\tif (!block.text) {\n\t\t\t\tthis._latestMemoryPromptInclusionReport = {\n\t\t\t\t\t...base,\n\t\t\t\t\tstatus: \"empty_block\",\n\t\t\t\t\tincludedCount: block.includedCount,\n\t\t\t\t\tomittedCount: block.omittedCount,\n\t\t\t\t\tblockChars: 0,\n\t\t\t\t};\n\t\t\t\treturn messages;\n\t\t\t}\n\n\t\t\tconst wrapped = wrapUntrustedText(block.text, \"memory:pi-okf\");\n\t\t\tconst evidenceMessage: CustomMessage = {\n\t\t\t\trole: \"custom\",\n\t\t\t\tcustomType: \"memory_evidence\",\n\t\t\t\tcontent: [{ type: \"text\", text: wrapped }],\n\t\t\t\tdisplay: false,\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t};\n\t\t\tthis._latestMemoryPromptInclusionReport = {\n\t\t\t\t...base,\n\t\t\t\tstatus: \"included\",\n\t\t\t\tincludedCount: block.includedCount,\n\t\t\t\tomittedCount: block.omittedCount,\n\t\t\t\tblockChars: wrapped.length,\n\t\t\t\tsourceLabel: \"memory:pi-okf\",\n\t\t\t};\n\t\t\treturn [...messages, evidenceMessage];\n\t\t} catch {\n\t\t\t// `base` may not exist yet if the throw happened before it was computed (e.g.\n\t\t\t// settings access or `report.contextItems` itself threw), so this branch cannot\n\t\t\t// rely on it -- fall back to safe, fixed defaults rather than risk referencing\n\t\t\t// a partially-evaluated value.\n\t\t\tthis._latestMemoryPromptInclusionReport = {\n\t\t\t\tenabled: false,\n\t\t\t\tincludeInPrompt: false,\n\t\t\t\tselectedItemCount: 0,\n\t\t\t\tstatus: \"failed\",\n\t\t\t\tincludedCount: 0,\n\t\t\t\tomittedCount: 0,\n\t\t\t\tblockChars: 0,\n\t\t\t};\n\t\t\treturn messages;\n\t\t}\n\t}\n\n\t/** Read-only inspection of the latest memory-prompt-inclusion decision, for tests/debugging and context_audit. */\n\tgetMemoryPromptInclusionReport(): MemoryPromptInclusionReport {\n\t\treturn this._latestMemoryPromptInclusionReport ?? defaultMemoryPromptInclusionReport();\n\t}\n\n\t/**\n\t * Combines the already-stored, no-arg latest reports (never re-queries the provider or\n\t * touches the OKF directory) into the safe, allow-list-projected shape context_audit\n\t * exposes. See context/memory-diagnostics.ts for why this projection is allow-list\n\t * based rather than a spread-then-delete of the raw report.\n\t */\n\tgetMemoryAuditDiagnostics(): {\n\t\tretrieval: MemoryRetrievalDiagnostics;\n\t\tpromptInclusion: MemoryPromptInclusionReport;\n\t} {\n\t\tconst settings = this.deps.getSettingsManager().getMemoryRetrievalSettings();\n\t\treturn {\n\t\t\tretrieval: sanitizeMemoryRetrievalReportForDiagnostics(this.getMemoryRetrievalReport(), settings),\n\t\t\tpromptInclusion: this.getMemoryPromptInclusionReport(),\n\t\t};\n\t}\n\n\t/**\n\t * Zero-I/O gate for cross-session recall (R3): skip trivial turns (short acks, slash commands) so\n\t * recall only runs when it could plausibly help. The provider's similarity cutoff is the real\n\t * filter — this just avoids the index query on turns that obviously don't warrant it.\n\t */\n\tshouldAttemptRecall(text: string): boolean {\n\t\tconst t = text.trim();\n\t\tif (t.length < 12 || t.startsWith(\"/\")) return false;\n\t\tconst words = t.split(/\\s+/).filter((w) => w.length >= 3);\n\t\t// R4 adaptive gate: if recall has rarely been used lately (enough samples to trust the signal),\n\t\t// raise the bar so we only recall on clearly substantial turns — and relax it again once recall\n\t\t// starts paying off. Never fully disabled, so the loop can recover.\n\t\tconst recallRarelyUseful =\n\t\t\tthis._effectivenessTracker.sampleCount >= 5 && this._effectivenessTracker.usefulLately() < 0.15;\n\t\treturn words.length >= (recallRarelyUseful ? 6 : 3);\n\t}\n\n\t/** R4: score whether the agent actually used an injected recall page, so the recall gate can adapt. */\n\trecordRecallOutcome(recallText: string, queryText: string, responseText: string): void {\n\t\tthis._effectivenessTracker.recordRecallOutcome(recallText, queryText, responseText);\n\t}\n\n\t/**\n\t * (Re)build the memory subsystem: a fresh MemoryManager (reload-safe), register the bundled\n\t * file-store + any extension-contributed providers, initialize, then surface the memory tools and\n\t * the frozen system-prompt block. Best-effort: never throws into the session lifecycle.\n\t */\n\tasync initialize(): Promise<void> {\n\t\ttry {\n\t\t\t// Release the previous generation's providers (locks/handles) before recreating, so a\n\t\t\t// reload does not orphan the old MemoryManager. No-op on first init / for file-store.\n\t\t\tawait this._memoryManager.shutdownAll().catch(() => {});\n\t\t\tconst manager = new MemoryManager();\n\t\t\tmanager.registerProvider(new FileStoreProvider());\n\t\t\t// Bundled read-only cross-session recall (R3): indexes past-session transcripts and answers\n\t\t\t// prefetch() with a <memory_context> page. Never writes.\n\t\t\tmanager.registerProvider(new TranscriptRecallProvider());\n\t\t\tfor (const provider of this._pendingMemoryProviders) {\n\t\t\t\ttry {\n\t\t\t\t\tmanager.registerProvider(provider);\n\t\t\t\t} catch {\n\t\t\t\t\t// Duplicate name or reserved-tool collision — skip this provider, keep the rest.\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._memoryManager = manager;\n\t\t\tawait manager.initializeAll(this.deps.getSessionId(), {\n\t\t\t\tagentDir: this.deps.getAgentDir(),\n\t\t\t\tcwd: this.deps.getCwd(),\n\t\t\t\tisChildSession: this.deps.isChildSession(),\n\t\t\t});\n\t\t\t// Surface memory tools + the frozen memory block now that providers are initialized.\n\t\t\t// refreshToolRegistry() ends in setActiveToolsByName(), which rebuilds AND assigns the\n\t\t\t// system prompt (including the memory block), so no explicit _rebuildSystemPrompt is needed.\n\t\t\tthis.deps.refreshToolRegistry();\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Memory subsystem init failed:\", error instanceof Error ? error.message : String(error));\n\t\t}\n\t}\n\n\t/** Register a memory provider contributed by an extension; applied on the next memory (re)init. */\n\tregisterMemoryProvider(provider: MemoryProvider): void {\n\t\tif (!this._pendingMemoryProviders.some((p) => p.name === provider.name)) {\n\t\t\tthis._pendingMemoryProviders.push(provider);\n\t\t}\n\t}\n\n\t/** Reload starts memory providers fresh; loaded extensions re-register before the next `initialize()`. */\n\tclearPendingProviders(): void {\n\t\tthis._pendingMemoryProviders = [];\n\t}\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { SessionEntry } from "@caupulican/pi-agent-core/node";
|
|
1
2
|
import type { RouteDecision } from "../autonomy/contracts.ts";
|
|
2
|
-
import type { SessionEntry } from "../session-manager.ts";
|
|
3
3
|
import type { ModelRouterIntent } from "./intent-classifier.ts";
|
|
4
4
|
export declare const MODEL_ROUTER_DECISION_CUSTOM_TYPE = "model_router_decision";
|
|
5
5
|
export type ModelRouterStatusSettings = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/core/model-router/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/core/model-router/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAa,aAAa,EAAa,MAAM,0BAA0B,CAAC;AACpF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,eAAO,MAAM,iCAAiC,0BAA0B,CAAC;AAEzE,MAAM,MAAM,yBAAyB,GAAG;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACvC,KAAK,EAAE,aAAa,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,QAAQ,GAAG,WAAW,GAAG,QAAQ,CAAC;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC3B,CAAC;AAiDF,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,KAAK,SAAI,GAAG,yBAAyB,EAAE,CAQ7G;AAED,wBAAgB,uBAAuB,CACtC,QAAQ,EAAE,yBAAyB,EACnC,YAAY,CAAC,EAAE,yBAAyB,EACxC,WAAW,GAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAyB,EACzD,eAAe,GAAE,yBAAyB,EAAO,EACjD,cAAc,CAAC,EAAE,MAAM,EACvB,YAAY,CAAC,EAAE,iBAAiB,GAC9B,MAAM,CA+BR","sourcesContent":["import type { SessionEntry } from \"@caupulican/pi-agent-core/node\";\nimport type { ModelTier, RouteDecision, RouteRisk } from \"../autonomy/contracts.ts\";\nimport type { ModelRouterIntent } from \"./intent-classifier.ts\";\n\nexport const MODEL_ROUTER_DECISION_CUSTOM_TYPE = \"model_router_decision\";\n\nexport type ModelRouterStatusSettings = {\n\tenabled: boolean;\n\tcheapModel?: string;\n\tmediumModel?: string;\n\texpensiveModel?: string;\n\tlearningModel?: string;\n};\n\nexport type ModelRouterDecisionStatus = {\n\troute: RouteDecision;\n\troutedModel: string;\n\toutcome: \"routed\" | \"escalated\" | \"failed\";\n\tretryModel?: string;\n\tintent?: ModelRouterIntent;\n};\n\nfunction isRouteDecision(value: unknown): value is RouteDecision {\n\tif (!value || typeof value !== \"object\") return false;\n\tconst route = value as Partial<RouteDecision>;\n\tconst validTiers = new Set<ModelTier>([\"cheap\", \"medium\", \"expensive\", \"learning\"]);\n\tconst validRisks = new Set<RouteRisk>([\"read-only\", \"scoped-write\", \"high-impact\", \"approval-required\"]);\n\n\treturn (\n\t\ttypeof route.confidence === \"number\" &&\n\t\ttypeof route.reasonCode === \"string\" &&\n\t\tArray.isArray(route.reasons) &&\n\t\troute.reasons.every((r) => typeof r === \"string\") &&\n\t\tvalidTiers.has(route.tier as ModelTier) &&\n\t\tvalidRisks.has(route.risk as RouteRisk) &&\n\t\t(route.model === undefined || typeof route.model === \"string\") &&\n\t\t(route.fallbackFrom === undefined ||\n\t\t\troute.fallbackFrom === \"cheap\" ||\n\t\t\troute.fallbackFrom === \"medium\" ||\n\t\t\troute.fallbackFrom === \"expensive\" ||\n\t\t\troute.fallbackFrom === \"learning\") &&\n\t\t(route.createdAt === undefined || typeof route.createdAt === \"string\")\n\t);\n}\n\nfunction isModelRouterDecisionStatus(data: unknown): data is ModelRouterDecisionStatus {\n\tif (!data || typeof data !== \"object\") return false;\n\tconst record = data as Partial<ModelRouterDecisionStatus>;\n\treturn (\n\t\tisRouteDecision(record.route) &&\n\t\trecord.route.tier !== \"learning\" && // Validate user prompt decisions never need learning tier in runtime\n\t\ttypeof record.routedModel === \"string\" &&\n\t\t(record.outcome === \"routed\" || record.outcome === \"escalated\" || record.outcome === \"failed\") &&\n\t\t(record.retryModel === undefined || typeof record.retryModel === \"string\") &&\n\t\t(record.intent === undefined || record.intent === \"research\" || record.intent === \"modify\")\n\t);\n}\n\nfunction formatDecision(decision: ModelRouterDecisionStatus): string {\n\tconst { tier, risk, reasonCode } = decision.route;\n\tlet outcomeText: string = decision.outcome;\n\tif (decision.outcome === \"escalated\" && decision.retryModel) {\n\t\toutcomeText = `escalated -> ${decision.retryModel}`;\n\t} else if (decision.outcome === \"failed\") {\n\t\toutcomeText = \"failed\";\n\t}\n\treturn `${tier}/${risk} -> ${decision.routedModel} (${reasonCode}, ${outcomeText})`;\n}\n\nexport function getRecentModelRouterDecisions(entries: SessionEntry[], limit = 3): ModelRouterDecisionStatus[] {\n\tconst decisions: ModelRouterDecisionStatus[] = [];\n\tfor (const entry of entries) {\n\t\tif (entry.type !== \"custom\" || entry.customType !== MODEL_ROUTER_DECISION_CUSTOM_TYPE) continue;\n\t\tif (!isModelRouterDecisionStatus(entry.data)) continue;\n\t\tdecisions.push(entry.data);\n\t}\n\treturn decisions.slice(-limit);\n}\n\nexport function formatModelRouterStatus(\n\tsettings: ModelRouterStatusSettings,\n\tlastDecision?: ModelRouterDecisionStatus,\n\tformatLabel: (label: string) => string = (label) => label,\n\trecentDecisions: ModelRouterDecisionStatus[] = [],\n\tlastSkipReason?: string,\n\tlatestIntent?: ModelRouterIntent,\n): string {\n\tconst effectiveLastDecision = lastSkipReason ? undefined : lastDecision;\n\tconst lines = [\n\t\t`${formatLabel(\"Status:\")} ${settings.enabled ? \"enabled\" : \"disabled\"}`,\n\t\t`${formatLabel(\"Cheap model:\")} ${settings.cheapModel ?? \"unset\"}`,\n\t\t`${formatLabel(\"Medium model:\")} ${settings.mediumModel ?? \"unset\"}`,\n\t\t`${formatLabel(\"Expensive model:\")} ${settings.expensiveModel ?? \"unset\"}`,\n\t\t`${formatLabel(\"Learning model:\")} ${settings.learningModel ?? \"active\"}`,\n\t];\n\tif (!settings.enabled) {\n\t\tlines.push(`${formatLabel(\"Routing:\")} inactive (disabled)`);\n\t} else if (lastSkipReason) {\n\t\tlines.push(`${formatLabel(\"Routing:\")} skipped (${lastSkipReason})`);\n\t} else if (effectiveLastDecision) {\n\t\tlines.push(`${formatLabel(\"Routing:\")} active`);\n\t} else {\n\t\tlines.push(`${formatLabel(\"Routing:\")} waiting for prompt`);\n\t}\n\tlines.push(`${formatLabel(\"Latest intent:\")} ${latestIntent ?? \"none\"}`);\n\tif (!effectiveLastDecision) {\n\t\tlines.push(`${formatLabel(\"Last decision:\")} none`);\n\t} else {\n\t\tlines.push(`${formatLabel(\"Last decision:\")} ${formatDecision(effectiveLastDecision)}`);\n\t}\n\tif (recentDecisions.length > 0) {\n\t\tlines.push(formatLabel(\"Recent decisions:\"));\n\t\tfor (const decision of recentDecisions) {\n\t\t\tlines.push(`- ${formatDecision(decision)}`);\n\t\t}\n\t}\n\treturn lines.join(\"\\n\");\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/core/model-router/status.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,iCAAiC,GAAG,uBAAuB,CAAC;AAkBzE,SAAS,eAAe,CAAC,KAAc,EAA0B;IAChE,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACtD,MAAM,KAAK,GAAG,KAA+B,CAAC;IAC9C,MAAM,UAAU,GAAG,IAAI,GAAG,CAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;IACpF,MAAM,UAAU,GAAG,IAAI,GAAG,CAAY,CAAC,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAEzG,OAAO,CACN,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ;QACpC,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ;QACpC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;QAC5B,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;QACjD,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,IAAiB,CAAC;QACvC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,IAAiB,CAAC;QACvC,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC;QAC9D,CAAC,KAAK,CAAC,YAAY,KAAK,SAAS;YAChC,KAAK,CAAC,YAAY,KAAK,OAAO;YAC9B,KAAK,CAAC,YAAY,KAAK,QAAQ;YAC/B,KAAK,CAAC,YAAY,KAAK,WAAW;YAClC,KAAK,CAAC,YAAY,KAAK,UAAU,CAAC;QACnC,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,CAAC,CACtE,CAAC;AAAA,CACF;AAED,SAAS,2BAA2B,CAAC,IAAa,EAAqC;IACtF,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACpD,MAAM,MAAM,GAAG,IAA0C,CAAC;IAC1D,OAAO,CACN,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC;QAC7B,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,qEAAqE;QACzG,OAAO,MAAM,CAAC,WAAW,KAAK,QAAQ;QACtC,CAAC,MAAM,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,OAAO,KAAK,WAAW,IAAI,MAAM,CAAC,OAAO,KAAK,QAAQ,CAAC;QAC9F,CAAC,MAAM,CAAC,UAAU,KAAK,SAAS,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,CAAC;QAC1E,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAC3F,CAAC;AAAA,CACF;AAED,SAAS,cAAc,CAAC,QAAmC,EAAU;IACpE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC;IAClD,IAAI,WAAW,GAAW,QAAQ,CAAC,OAAO,CAAC;IAC3C,IAAI,QAAQ,CAAC,OAAO,KAAK,WAAW,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;QAC7D,WAAW,GAAG,gBAAgB,QAAQ,CAAC,UAAU,EAAE,CAAC;IACrD,CAAC;SAAM,IAAI,QAAQ,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC1C,WAAW,GAAG,QAAQ,CAAC;IACxB,CAAC;IACD,OAAO,GAAG,IAAI,IAAI,IAAI,OAAO,QAAQ,CAAC,WAAW,KAAK,UAAU,KAAK,WAAW,GAAG,CAAC;AAAA,CACpF;AAED,MAAM,UAAU,6BAA6B,CAAC,OAAuB,EAAE,KAAK,GAAG,CAAC,EAA+B;IAC9G,MAAM,SAAS,GAAgC,EAAE,CAAC;IAClD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,KAAK,iCAAiC;YAAE,SAAS;QAChG,IAAI,CAAC,2BAA2B,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,SAAS;QACvD,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;AAAA,CAC/B;AAED,MAAM,UAAU,uBAAuB,CACtC,QAAmC,EACnC,YAAwC,EACxC,WAAW,GAA8B,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EACzD,eAAe,GAAgC,EAAE,EACjD,cAAuB,EACvB,YAAgC,EACvB;IACT,MAAM,qBAAqB,GAAG,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC;IACxE,MAAM,KAAK,GAAG;QACb,GAAG,WAAW,CAAC,SAAS,CAAC,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,EAAE;QACxE,GAAG,WAAW,CAAC,cAAc,CAAC,IAAI,QAAQ,CAAC,UAAU,IAAI,OAAO,EAAE;QAClE,GAAG,WAAW,CAAC,eAAe,CAAC,IAAI,QAAQ,CAAC,WAAW,IAAI,OAAO,EAAE;QACpE,GAAG,WAAW,CAAC,kBAAkB,CAAC,IAAI,QAAQ,CAAC,cAAc,IAAI,OAAO,EAAE;QAC1E,GAAG,WAAW,CAAC,iBAAiB,CAAC,IAAI,QAAQ,CAAC,aAAa,IAAI,QAAQ,EAAE;KACzE,CAAC;IACF,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,UAAU,CAAC,sBAAsB,CAAC,CAAC;IAC9D,CAAC;SAAM,IAAI,cAAc,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,UAAU,CAAC,aAAa,cAAc,GAAG,CAAC,CAAC;IACtE,CAAC;SAAM,IAAI,qBAAqB,EAAE,CAAC;QAClC,KAAK,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACjD,CAAC;SAAM,CAAC;QACP,KAAK,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,UAAU,CAAC,qBAAqB,CAAC,CAAC;IAC7D,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,gBAAgB,CAAC,IAAI,YAAY,IAAI,MAAM,EAAE,CAAC,CAAC;IACzE,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACrD,CAAC;SAAM,CAAC;QACP,KAAK,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,gBAAgB,CAAC,IAAI,cAAc,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC;IACzF,CAAC;IACD,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAC7C,KAAK,MAAM,QAAQ,IAAI,eAAe,EAAE,CAAC;YACxC,KAAK,CAAC,IAAI,CAAC,KAAK,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC7C,CAAC;IACF,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAAA,CACxB","sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/core/model-router/status.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SessionEntry } from \"@caupulican/pi-agent-core/node\";\nimport type { ModelTier, RouteDecision, RouteRisk } from \"../autonomy/contracts.ts\";\nimport type { ModelRouterIntent } from \"./intent-classifier.ts\";\n\nexport const MODEL_ROUTER_DECISION_CUSTOM_TYPE = \"model_router_decision\";\n\nexport type ModelRouterStatusSettings = {\n\tenabled: boolean;\n\tcheapModel?: string;\n\tmediumModel?: string;\n\texpensiveModel?: string;\n\tlearningModel?: string;\n};\n\nexport type ModelRouterDecisionStatus = {\n\troute: RouteDecision;\n\troutedModel: string;\n\toutcome: \"routed\" | \"escalated\" | \"failed\";\n\tretryModel?: string;\n\tintent?: ModelRouterIntent;\n};\n\nfunction isRouteDecision(value: unknown): value is RouteDecision {\n\tif (!value || typeof value !== \"object\") return false;\n\tconst route = value as Partial<RouteDecision>;\n\tconst validTiers = new Set<ModelTier>([\"cheap\", \"medium\", \"expensive\", \"learning\"]);\n\tconst validRisks = new Set<RouteRisk>([\"read-only\", \"scoped-write\", \"high-impact\", \"approval-required\"]);\n\n\treturn (\n\t\ttypeof route.confidence === \"number\" &&\n\t\ttypeof route.reasonCode === \"string\" &&\n\t\tArray.isArray(route.reasons) &&\n\t\troute.reasons.every((r) => typeof r === \"string\") &&\n\t\tvalidTiers.has(route.tier as ModelTier) &&\n\t\tvalidRisks.has(route.risk as RouteRisk) &&\n\t\t(route.model === undefined || typeof route.model === \"string\") &&\n\t\t(route.fallbackFrom === undefined ||\n\t\t\troute.fallbackFrom === \"cheap\" ||\n\t\t\troute.fallbackFrom === \"medium\" ||\n\t\t\troute.fallbackFrom === \"expensive\" ||\n\t\t\troute.fallbackFrom === \"learning\") &&\n\t\t(route.createdAt === undefined || typeof route.createdAt === \"string\")\n\t);\n}\n\nfunction isModelRouterDecisionStatus(data: unknown): data is ModelRouterDecisionStatus {\n\tif (!data || typeof data !== \"object\") return false;\n\tconst record = data as Partial<ModelRouterDecisionStatus>;\n\treturn (\n\t\tisRouteDecision(record.route) &&\n\t\trecord.route.tier !== \"learning\" && // Validate user prompt decisions never need learning tier in runtime\n\t\ttypeof record.routedModel === \"string\" &&\n\t\t(record.outcome === \"routed\" || record.outcome === \"escalated\" || record.outcome === \"failed\") &&\n\t\t(record.retryModel === undefined || typeof record.retryModel === \"string\") &&\n\t\t(record.intent === undefined || record.intent === \"research\" || record.intent === \"modify\")\n\t);\n}\n\nfunction formatDecision(decision: ModelRouterDecisionStatus): string {\n\tconst { tier, risk, reasonCode } = decision.route;\n\tlet outcomeText: string = decision.outcome;\n\tif (decision.outcome === \"escalated\" && decision.retryModel) {\n\t\toutcomeText = `escalated -> ${decision.retryModel}`;\n\t} else if (decision.outcome === \"failed\") {\n\t\toutcomeText = \"failed\";\n\t}\n\treturn `${tier}/${risk} -> ${decision.routedModel} (${reasonCode}, ${outcomeText})`;\n}\n\nexport function getRecentModelRouterDecisions(entries: SessionEntry[], limit = 3): ModelRouterDecisionStatus[] {\n\tconst decisions: ModelRouterDecisionStatus[] = [];\n\tfor (const entry of entries) {\n\t\tif (entry.type !== \"custom\" || entry.customType !== MODEL_ROUTER_DECISION_CUSTOM_TYPE) continue;\n\t\tif (!isModelRouterDecisionStatus(entry.data)) continue;\n\t\tdecisions.push(entry.data);\n\t}\n\treturn decisions.slice(-limit);\n}\n\nexport function formatModelRouterStatus(\n\tsettings: ModelRouterStatusSettings,\n\tlastDecision?: ModelRouterDecisionStatus,\n\tformatLabel: (label: string) => string = (label) => label,\n\trecentDecisions: ModelRouterDecisionStatus[] = [],\n\tlastSkipReason?: string,\n\tlatestIntent?: ModelRouterIntent,\n): string {\n\tconst effectiveLastDecision = lastSkipReason ? undefined : lastDecision;\n\tconst lines = [\n\t\t`${formatLabel(\"Status:\")} ${settings.enabled ? \"enabled\" : \"disabled\"}`,\n\t\t`${formatLabel(\"Cheap model:\")} ${settings.cheapModel ?? \"unset\"}`,\n\t\t`${formatLabel(\"Medium model:\")} ${settings.mediumModel ?? \"unset\"}`,\n\t\t`${formatLabel(\"Expensive model:\")} ${settings.expensiveModel ?? \"unset\"}`,\n\t\t`${formatLabel(\"Learning model:\")} ${settings.learningModel ?? \"active\"}`,\n\t];\n\tif (!settings.enabled) {\n\t\tlines.push(`${formatLabel(\"Routing:\")} inactive (disabled)`);\n\t} else if (lastSkipReason) {\n\t\tlines.push(`${formatLabel(\"Routing:\")} skipped (${lastSkipReason})`);\n\t} else if (effectiveLastDecision) {\n\t\tlines.push(`${formatLabel(\"Routing:\")} active`);\n\t} else {\n\t\tlines.push(`${formatLabel(\"Routing:\")} waiting for prompt`);\n\t}\n\tlines.push(`${formatLabel(\"Latest intent:\")} ${latestIntent ?? \"none\"}`);\n\tif (!effectiveLastDecision) {\n\t\tlines.push(`${formatLabel(\"Last decision:\")} none`);\n\t} else {\n\t\tlines.push(`${formatLabel(\"Last decision:\")} ${formatDecision(effectiveLastDecision)}`);\n\t}\n\tif (recentDecisions.length > 0) {\n\t\tlines.push(formatLabel(\"Recent decisions:\"));\n\t\tfor (const decision of recentDecisions) {\n\t\t\tlines.push(`- ${formatDecision(decision)}`);\n\t\t}\n\t}\n\treturn lines.join(\"\\n\");\n}\n"]}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model-router turn routing: the session's per-turn model-selection subsystem — the regex/executor
|
|
3
|
+
* route resolver, the optional bounded routing judge, the executor lane (Level-0 toolkit direct hit
|
|
4
|
+
* + speculative brain-refined retry), the per-tier thinking/tool-surface swap around a routed turn,
|
|
5
|
+
* the cheap-research-turn session buffer with mutating-tool escalation to an expensive retry, and
|
|
6
|
+
* the router status/diagnostics report.
|
|
7
|
+
*
|
|
8
|
+
* Extracted verbatim from agent-session.ts (god-file decomposition). Owns the transient per-turn
|
|
9
|
+
* route state — the active intent/route, the cheap-turn session buffer, the escalation-requested and
|
|
10
|
+
* retry-in-flight flags — and the sticky last-decision/last-skip-reason/last-intent used by the
|
|
11
|
+
* status report. Everything else it needs — the live agent + its state, the current model, the
|
|
12
|
+
* session/settings managers, the model registry, the agent dir, the reflection abort signal, the
|
|
13
|
+
* base system prompt, the isolated-completion primitive, spawned-usage accounting, the event/telemetry
|
|
14
|
+
* emitters, and the recently-extracted BackgroundLaneController (resolveLaneModel) / ContextPipeline
|
|
15
|
+
* (resolveCurationModelIfFit) collaborators — is reached through narrow deps accessors rather than the
|
|
16
|
+
* whole AgentSession.
|
|
17
|
+
*
|
|
18
|
+
* Drive-path boundary (deliberate): the actual agent.prompt()/continue() loop stays host-side in
|
|
19
|
+
* AgentSession._runAgentPrompt; this controller's parallel routed drive path ({@link runRoutedTurn})
|
|
20
|
+
* owns only the route decision/escalation/tier bookkeeping and delegates every agent turn back through
|
|
21
|
+
* {@link ModelRouterControllerDeps.runAgentPrompt}, so the drive-loop logic is never duplicated. The
|
|
22
|
+
* host keeps a one-line delegation at each call-in: the routing prep + routed-turn entry in
|
|
23
|
+
* _promptUnserialized, the beforeToolCall escalation branch ({@link maybeEscalateToolCall}), the
|
|
24
|
+
* message_end cheap-turn buffering ({@link captureSessionMessage}), the retry-event suppression
|
|
25
|
+
* ({@link isRetryInFlight}), and the public getModelRouterStatus / autonomy-telemetry reads.
|
|
26
|
+
*/
|
|
27
|
+
import type { Agent, AgentMessage } from "@caupulican/pi-agent-core";
|
|
28
|
+
import type { SessionManager } from "@caupulican/pi-agent-core/node";
|
|
29
|
+
import type { Api, Model, Usage } from "@caupulican/pi-ai";
|
|
30
|
+
import type { AgentSessionEvent, IsolatedCompletionOptions, IsolatedCompletionResult } from "./agent-session.ts";
|
|
31
|
+
import type { RouteDecision } from "./autonomy/contracts.ts";
|
|
32
|
+
import { type AutonomyTelemetryEvent } from "./autonomy/telemetry-events.ts";
|
|
33
|
+
import type { ModelRegistry } from "./model-registry.ts";
|
|
34
|
+
import { type ModelRouterDecisionStatus } from "./model-router/status.ts";
|
|
35
|
+
import type { SettingsManager } from "./settings-manager.ts";
|
|
36
|
+
/** Canonical `provider/id` label for a routed/resolved model, as it appears in decisions and status. */
|
|
37
|
+
export declare function formatModelRouterModel(model: Model<Api>): string;
|
|
38
|
+
export interface ModelRouterControllerDeps {
|
|
39
|
+
/** Live agent — the controller reads/writes agent.state.{model,thinkingLevel,tools,systemPrompt,messages}
|
|
40
|
+
* for the per-turn tier swap and aborts it on a mutating-tool escalation. */
|
|
41
|
+
getAgent(): Agent;
|
|
42
|
+
/** Current session model, used to decide whether a routed turn actually swaps the model. */
|
|
43
|
+
getModel(): Model<Api> | undefined;
|
|
44
|
+
/** Router/executor/judge/thinking settings + capability mode (all opt-in gates). */
|
|
45
|
+
getSettingsManager(): SettingsManager;
|
|
46
|
+
/** Session log: routed-turn message buffering/persistence, decision persistence, recent-decision status. */
|
|
47
|
+
getSessionManager(): SessionManager;
|
|
48
|
+
/** Resolves configured route/judge/executor model patterns against configured auth. */
|
|
49
|
+
getModelRegistry(): ModelRegistry;
|
|
50
|
+
/** Root dir the host-keyed {@link FitnessStore} lives under (executor tool-call fitness gate). */
|
|
51
|
+
getAgentDir(): string;
|
|
52
|
+
/** Aborts the judge's bounded completion when the session is disposed. */
|
|
53
|
+
getReflectionSignal(): AbortSignal;
|
|
54
|
+
/** Base (extension-free) system prompt — the tier swap only sheds tools when the turn is on it. */
|
|
55
|
+
getBaseSystemPrompt(): string;
|
|
56
|
+
/** The host-side drive loop (agent.prompt()/continue()); the routed drive path delegates every turn here. */
|
|
57
|
+
runAgentPrompt(messages: AgentMessage | AgentMessage[]): Promise<void>;
|
|
58
|
+
/** Rebuilds the system prompt for a filtered tool surface (routed-model capability shedding). */
|
|
59
|
+
buildSystemPromptForToolNames(toolNames: string[]): string;
|
|
60
|
+
/** Re-resolves the restored model against the registry after a routed turn (provider override safety). */
|
|
61
|
+
refreshCurrentModelFromRegistry(): void;
|
|
62
|
+
/** One-shot, tool-less LLM call — the routing judge and the executor reflex-brain warmup ride this. */
|
|
63
|
+
runIsolatedCompletion(opts: IsolatedCompletionOptions): Promise<IsolatedCompletionResult>;
|
|
64
|
+
/** Rolls judge/brain spend into spawned-usage accounting. */
|
|
65
|
+
addSpawnedUsage(usage: Usage, opts?: {
|
|
66
|
+
label?: string;
|
|
67
|
+
sourceSessionId?: string;
|
|
68
|
+
reportId?: string;
|
|
69
|
+
}): string | undefined;
|
|
70
|
+
/** Session event stream (executor-miss warning). */
|
|
71
|
+
emit(event: AgentSessionEvent): void;
|
|
72
|
+
/** Autonomy telemetry stream (one route-decision event per user-facing routed turn). */
|
|
73
|
+
emitAutonomyTelemetry(event: AutonomyTelemetryEvent): void;
|
|
74
|
+
/** Resolves the judge model pattern via {@link BackgroundLaneController}. */
|
|
75
|
+
resolveLaneModel(pattern: string): Model<Api> | undefined;
|
|
76
|
+
/** Fitness-gated reflex-brain model via {@link ContextPipeline} (executor speculative refinement). */
|
|
77
|
+
resolveCurationModelIfFit(): Model<Api> | undefined;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Owns the model-router turn routing extracted from {@link AgentSession}. See the module header for the
|
|
81
|
+
* drive-path boundary that keeps the agent.prompt()/continue() loop host-side.
|
|
82
|
+
*/
|
|
83
|
+
export declare class ModelRouterController {
|
|
84
|
+
/** Active model-router intent for the current transient routed turn, if any. */
|
|
85
|
+
private _activeModelRouterIntent?;
|
|
86
|
+
private _activeModelRouterRoute?;
|
|
87
|
+
private _modelRouterSessionBuffer?;
|
|
88
|
+
private _modelRouterEscalationRequested;
|
|
89
|
+
private _isModelRouterRetry;
|
|
90
|
+
private _lastModelRouterDecision?;
|
|
91
|
+
private _lastModelRouterSkipReason?;
|
|
92
|
+
private _lastModelRouterIntent?;
|
|
93
|
+
private readonly deps;
|
|
94
|
+
constructor(deps: ModelRouterControllerDeps);
|
|
95
|
+
/** True while the escalation retry turn is running, so the host can suppress its duplicate prompt events. */
|
|
96
|
+
isRetryInFlight(): boolean;
|
|
97
|
+
/** Latest completed route decision (sticky), for the autonomy telemetry snapshot. */
|
|
98
|
+
getLastDecision(): ModelRouterDecisionStatus | undefined;
|
|
99
|
+
/**
|
|
100
|
+
* beforeToolCall escalation gate: a cheap research turn that reaches for a mutating tool aborts the
|
|
101
|
+
* turn and requests a retry on the expensive model. Returns the block result the host hook forwards,
|
|
102
|
+
* or undefined when no escalation is required.
|
|
103
|
+
*/
|
|
104
|
+
maybeEscalateToolCall(toolName: string, args: unknown): {
|
|
105
|
+
block: true;
|
|
106
|
+
reason: string;
|
|
107
|
+
} | undefined;
|
|
108
|
+
/**
|
|
109
|
+
* message_end hook: while a cheap routed turn is buffering, capture its messages into the session
|
|
110
|
+
* buffer instead of persisting them (they are flushed on success or discarded on escalation).
|
|
111
|
+
* Returns true when the message was buffered, so the host skips its own persistence.
|
|
112
|
+
*/
|
|
113
|
+
captureSessionMessage(message: AgentMessage): boolean;
|
|
114
|
+
private _isModelAvailableAndAuthed;
|
|
115
|
+
private _resolveExecutorRoute;
|
|
116
|
+
/** True if a run_toolkit_script tool result since `fromIndex` actually EXECUTED (not error/ambiguous). */
|
|
117
|
+
private _executorTurnExecutedScript;
|
|
118
|
+
private _buildExecutorRefinedPrompt;
|
|
119
|
+
private _resolveModelRouterTurnRoute;
|
|
120
|
+
private _resolveModelRouterModelForIntent;
|
|
121
|
+
resolveConfiguredTierModel(tier: "cheap" | "medium" | "expensive"): Model<Api> | undefined;
|
|
122
|
+
/**
|
|
123
|
+
* Router resolution with the routing judge (auto-on with the router): the regex classifier's
|
|
124
|
+
* decision is the baseline; when a judge model resolves (judgeModel, else mediumModel), one
|
|
125
|
+
* bounded, tool-less completion may move the tier between cheap/medium/expensive — never to
|
|
126
|
+
* learning. Core rule encoded in the judge prompt: planning is never cheap unless genuinely
|
|
127
|
+
* trivial. Every fallback stays visible in the decision reasons, and judge spend reports
|
|
128
|
+
* through spawned-usage accounting.
|
|
129
|
+
*/
|
|
130
|
+
resolveTurnRouteJudged(prompt: string, options?: {
|
|
131
|
+
skipJudge?: boolean;
|
|
132
|
+
}): Promise<{
|
|
133
|
+
decision: RouteDecision;
|
|
134
|
+
model: Model<Api>;
|
|
135
|
+
} | undefined>;
|
|
136
|
+
private _resolveModelRouterTurnModel;
|
|
137
|
+
getStatus(formatLabel?: (label: string) => string): string;
|
|
138
|
+
runRoutedTurn(messages: AgentMessage | AgentMessage[], routedModel: Model<Api> | undefined, routeDecision: RouteDecision | undefined, persistDecision?: boolean): Promise<void>;
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=model-router-controller.d.ts.map
|