@caupulican/pi-adaptative 0.81.39 → 0.81.41
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 +77 -0
- package/README.md +2 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts +2 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts.map +1 -1
- package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js +3 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js.map +1 -1
- package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.ts +4 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts +9 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts.map +1 -1
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.js +290 -107
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.js.map +1 -1
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.ts +357 -122
- package/dist/bundled-resources/skills/tool-call-repair/references/repair-catalogue.md +2 -2
- package/dist/cli/args.d.ts +4 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +31 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-directory-layout.d.ts +15 -0
- package/dist/core/agent-directory-layout.d.ts.map +1 -0
- package/dist/core/agent-directory-layout.js +72 -0
- package/dist/core/agent-directory-layout.js.map +1 -0
- package/dist/core/agent-paths.d.ts +25 -2
- package/dist/core/agent-paths.d.ts.map +1 -1
- package/dist/core/agent-paths.js +79 -4
- package/dist/core/agent-paths.js.map +1 -1
- package/dist/core/agent-session-contracts.d.ts +293 -0
- package/dist/core/agent-session-contracts.d.ts.map +1 -0
- package/dist/core/agent-session-contracts.js +26 -0
- package/dist/core/agent-session-contracts.js.map +1 -0
- package/dist/core/agent-session-runtime.d.ts +52 -8
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +400 -79
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +1 -0
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +1 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +74 -518
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +370 -1432
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +3 -1
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/autonomy/approval-gate.d.ts +3 -2
- package/dist/core/autonomy/approval-gate.d.ts.map +1 -1
- package/dist/core/autonomy/approval-gate.js +6 -28
- package/dist/core/autonomy/approval-gate.js.map +1 -1
- package/dist/core/autonomy/bounded-completion.d.ts +1 -1
- package/dist/core/autonomy/bounded-completion.d.ts.map +1 -1
- package/dist/core/autonomy/bounded-completion.js +1 -1
- package/dist/core/autonomy/bounded-completion.js.map +1 -1
- package/dist/core/autonomy/contracts.d.ts +20 -12
- package/dist/core/autonomy/contracts.d.ts.map +1 -1
- package/dist/core/autonomy/contracts.js.map +1 -1
- package/dist/core/autonomy/foreground-envelope.d.ts +8 -2
- package/dist/core/autonomy/foreground-envelope.d.ts.map +1 -1
- package/dist/core/autonomy/foreground-envelope.js +8 -25
- package/dist/core/autonomy/foreground-envelope.js.map +1 -1
- package/dist/core/autonomy/gates.d.ts.map +1 -1
- package/dist/core/autonomy/gates.js +8 -10
- package/dist/core/autonomy/gates.js.map +1 -1
- package/dist/core/autonomy/lane-private-paths.d.ts +2 -0
- package/dist/core/autonomy/lane-private-paths.d.ts.map +1 -0
- package/dist/core/autonomy/lane-private-paths.js +16 -0
- package/dist/core/autonomy/lane-private-paths.js.map +1 -0
- package/dist/core/autonomy/lane-tool-surface.d.ts +10 -0
- package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
- package/dist/core/autonomy/lane-tool-surface.js +48 -9
- package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
- package/dist/core/autonomy/lane-tracker.d.ts +14 -0
- package/dist/core/autonomy/lane-tracker.d.ts.map +1 -1
- package/dist/core/autonomy/lane-tracker.js +38 -0
- package/dist/core/autonomy/lane-tracker.js.map +1 -1
- package/dist/core/autonomy/risk-assessment.d.ts +1 -2
- package/dist/core/autonomy/risk-assessment.d.ts.map +1 -1
- package/dist/core/autonomy/risk-assessment.js +1 -123
- package/dist/core/autonomy/risk-assessment.js.map +1 -1
- package/dist/core/autonomy/session-lane-record.d.ts +4 -4
- package/dist/core/autonomy/session-lane-record.d.ts.map +1 -1
- package/dist/core/autonomy/session-lane-record.js +16 -29
- package/dist/core/autonomy/session-lane-record.js.map +1 -1
- package/dist/core/autonomy/telemetry-events.d.ts +1 -1
- package/dist/core/autonomy/telemetry-events.d.ts.map +1 -1
- package/dist/core/autonomy/telemetry-events.js +1 -1
- package/dist/core/autonomy/telemetry-events.js.map +1 -1
- package/dist/core/autonomy-telemetry.d.ts +7 -7
- package/dist/core/autonomy-telemetry.d.ts.map +1 -1
- package/dist/core/autonomy-telemetry.js +9 -9
- package/dist/core/autonomy-telemetry.js.map +1 -1
- package/dist/core/background-lane-controller.d.ts +56 -236
- package/dist/core/background-lane-controller.d.ts.map +1 -1
- package/dist/core/background-lane-controller.js +141 -1273
- package/dist/core/background-lane-controller.js.map +1 -1
- package/dist/core/bedrock-sso-login.d.ts +16 -0
- package/dist/core/bedrock-sso-login.d.ts.map +1 -0
- package/dist/core/bedrock-sso-login.js +98 -0
- package/dist/core/bedrock-sso-login.js.map +1 -0
- package/dist/core/capability-contract.d.ts +4 -0
- package/dist/core/capability-contract.d.ts.map +1 -0
- package/dist/core/capability-contract.js +28 -0
- package/dist/core/capability-contract.js.map +1 -0
- package/dist/core/compaction-controller.d.ts +90 -0
- package/dist/core/compaction-controller.d.ts.map +1 -0
- package/dist/core/compaction-controller.js +452 -0
- package/dist/core/compaction-controller.js.map +1 -0
- package/dist/core/compaction-support.d.ts +13 -17
- package/dist/core/compaction-support.d.ts.map +1 -1
- package/dist/core/compaction-support.js +3 -3
- package/dist/core/compaction-support.js.map +1 -1
- package/dist/core/context/context-artifacts.d.ts +6 -2
- package/dist/core/context/context-artifacts.d.ts.map +1 -1
- package/dist/core/context/context-artifacts.js +34 -2
- package/dist/core/context/context-artifacts.js.map +1 -1
- package/dist/core/context/context-store-retention.d.ts +8 -2
- package/dist/core/context/context-store-retention.d.ts.map +1 -1
- package/dist/core/context/context-store-retention.js +158 -35
- package/dist/core/context/context-store-retention.js.map +1 -1
- package/dist/core/context/okf-memory.d.ts.map +1 -1
- package/dist/core/context/okf-memory.js +9 -11
- package/dist/core/context/okf-memory.js.map +1 -1
- package/dist/core/context/sqlite-runtime-index.d.ts.map +1 -1
- package/dist/core/context/sqlite-runtime-index.js +6 -8
- package/dist/core/context/sqlite-runtime-index.js.map +1 -1
- package/dist/core/context-gc.d.ts +3 -0
- package/dist/core/context-gc.d.ts.map +1 -1
- package/dist/core/context-gc.js +10 -5
- package/dist/core/context-gc.js.map +1 -1
- package/dist/core/context-pipeline.d.ts +1 -1
- package/dist/core/context-pipeline.d.ts.map +1 -1
- package/dist/core/context-pipeline.js +16 -37
- package/dist/core/context-pipeline.js.map +1 -1
- package/dist/core/cost/cost-summary.d.ts.map +1 -1
- package/dist/core/cost/cost-summary.js +5 -3
- package/dist/core/cost/cost-summary.js.map +1 -1
- package/dist/core/cost/daily-usage.d.ts.map +1 -1
- package/dist/core/cost/daily-usage.js +4 -5
- package/dist/core/cost/daily-usage.js.map +1 -1
- package/dist/core/default-tool-surface.d.ts.map +1 -1
- package/dist/core/default-tool-surface.js +2 -0
- package/dist/core/default-tool-surface.js.map +1 -1
- package/dist/core/delegation/managed-lane-controller.d.ts +34 -0
- package/dist/core/delegation/managed-lane-controller.d.ts.map +1 -0
- package/dist/core/delegation/managed-lane-controller.js +217 -0
- package/dist/core/delegation/managed-lane-controller.js.map +1 -0
- package/dist/core/delegation/session-worker-claim.d.ts +44 -0
- package/dist/core/delegation/session-worker-claim.d.ts.map +1 -0
- package/dist/core/delegation/session-worker-claim.js +98 -0
- package/dist/core/delegation/session-worker-claim.js.map +1 -0
- package/dist/core/delegation/worker-actions.d.ts +7 -5
- package/dist/core/delegation/worker-actions.d.ts.map +1 -1
- package/dist/core/delegation/worker-actions.js +20 -4
- package/dist/core/delegation/worker-actions.js.map +1 -1
- package/dist/core/delegation/{worker-result.d.ts → worker-claim.d.ts} +13 -13
- package/dist/core/delegation/worker-claim.d.ts.map +1 -0
- package/dist/core/delegation/{worker-result.js → worker-claim.js} +61 -51
- package/dist/core/delegation/worker-claim.js.map +1 -0
- package/dist/core/delegation/worker-delegation-controller.d.ts +110 -0
- package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -0
- package/dist/core/delegation/worker-delegation-controller.js +861 -0
- package/dist/core/delegation/worker-delegation-controller.js.map +1 -0
- package/dist/core/delegation/worker-delegation-request.d.ts +11 -0
- package/dist/core/delegation/worker-delegation-request.d.ts.map +1 -0
- package/dist/core/delegation/worker-delegation-request.js +2 -0
- package/dist/core/delegation/worker-delegation-request.js.map +1 -0
- package/dist/core/delegation/worker-dispatch-scheduler.d.ts +40 -0
- package/dist/core/delegation/worker-dispatch-scheduler.d.ts.map +1 -0
- package/dist/core/delegation/worker-dispatch-scheduler.js +93 -0
- package/dist/core/delegation/worker-dispatch-scheduler.js.map +1 -0
- package/dist/core/delegation/worker-execution-policy.d.ts +62 -0
- package/dist/core/delegation/worker-execution-policy.d.ts.map +1 -0
- package/dist/core/delegation/worker-execution-policy.js +160 -0
- package/dist/core/delegation/worker-execution-policy.js.map +1 -0
- package/dist/core/delegation/worker-lane-projection.d.ts +14 -0
- package/dist/core/delegation/worker-lane-projection.d.ts.map +1 -0
- package/dist/core/delegation/worker-lane-projection.js +100 -0
- package/dist/core/delegation/worker-lane-projection.js.map +1 -0
- package/dist/core/delegation/worker-lifecycle.d.ts +97 -0
- package/dist/core/delegation/worker-lifecycle.d.ts.map +1 -0
- package/dist/core/delegation/worker-lifecycle.js +339 -0
- package/dist/core/delegation/worker-lifecycle.js.map +1 -0
- package/dist/core/delegation/worker-notification-coordinator.d.ts +36 -0
- package/dist/core/delegation/worker-notification-coordinator.d.ts.map +1 -0
- package/dist/core/delegation/worker-notification-coordinator.js +90 -0
- package/dist/core/delegation/worker-notification-coordinator.js.map +1 -0
- package/dist/core/delegation/worker-profile-resolver.d.ts +55 -0
- package/dist/core/delegation/worker-profile-resolver.d.ts.map +1 -0
- package/dist/core/delegation/worker-profile-resolver.js +113 -0
- package/dist/core/delegation/worker-profile-resolver.js.map +1 -0
- package/dist/core/delegation/worker-runner.d.ts +25 -14
- package/dist/core/delegation/worker-runner.d.ts.map +1 -1
- package/dist/core/delegation/worker-runner.js +122 -53
- package/dist/core/delegation/worker-runner.js.map +1 -1
- package/dist/core/delegation/worker-task-label.d.ts +3 -0
- package/dist/core/delegation/worker-task-label.d.ts.map +1 -0
- package/dist/core/delegation/worker-task-label.js +11 -0
- package/dist/core/delegation/worker-task-label.js.map +1 -0
- package/dist/core/doctor.d.ts +8 -0
- package/dist/core/doctor.d.ts.map +1 -1
- package/dist/core/doctor.js +32 -1
- package/dist/core/doctor.js.map +1 -1
- package/dist/core/extension-import-authority.d.ts +6 -0
- package/dist/core/extension-import-authority.d.ts.map +1 -0
- package/dist/core/extension-import-authority.js +10 -0
- package/dist/core/extension-import-authority.js.map +1 -0
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +5 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +52 -18
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +3 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +20 -5
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/stale-context.d.ts +2 -0
- package/dist/core/extensions/stale-context.d.ts.map +1 -0
- package/dist/core/extensions/stale-context.js +2 -0
- package/dist/core/extensions/stale-context.js.map +1 -0
- package/dist/core/extensions/storage.d.ts +8 -0
- package/dist/core/extensions/storage.d.ts.map +1 -0
- package/dist/core/extensions/storage.js +28 -0
- package/dist/core/extensions/storage.js.map +1 -0
- package/dist/core/extensions/types.d.ts +78 -21
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/failure-corpus.d.ts +1 -15
- package/dist/core/failure-corpus.d.ts.map +1 -1
- package/dist/core/failure-corpus.js +9 -37
- package/dist/core/failure-corpus.js.map +1 -1
- package/dist/core/foreground-recovery-controller.d.ts +53 -0
- package/dist/core/foreground-recovery-controller.d.ts.map +1 -0
- package/dist/core/foreground-recovery-controller.js +111 -0
- package/dist/core/foreground-recovery-controller.js.map +1 -0
- package/dist/core/gateways/channel-provider.d.ts +3 -0
- package/dist/core/gateways/channel-provider.d.ts.map +1 -1
- package/dist/core/gateways/channel-provider.js +31 -6
- package/dist/core/gateways/channel-provider.js.map +1 -1
- package/dist/core/goal-loop-controller.d.ts +14 -9
- package/dist/core/goal-loop-controller.d.ts.map +1 -1
- package/dist/core/goal-loop-controller.js +47 -75
- package/dist/core/goal-loop-controller.js.map +1 -1
- package/dist/core/goals/compact-goal-context.d.ts +11 -0
- package/dist/core/goals/compact-goal-context.d.ts.map +1 -0
- package/dist/core/goals/compact-goal-context.js +59 -0
- package/dist/core/goals/compact-goal-context.js.map +1 -0
- package/dist/core/goals/goal-acceptance.d.ts +11 -0
- package/dist/core/goals/goal-acceptance.d.ts.map +1 -0
- package/dist/core/goals/goal-acceptance.js +27 -0
- package/dist/core/goals/goal-acceptance.js.map +1 -0
- package/dist/core/goals/goal-auto-continue-controller.d.ts +28 -0
- package/dist/core/goals/goal-auto-continue-controller.d.ts.map +1 -0
- package/dist/core/goals/goal-auto-continue-controller.js +90 -0
- package/dist/core/goals/goal-auto-continue-controller.js.map +1 -0
- package/dist/core/goals/goal-continuation-controller.d.ts +2 -2
- package/dist/core/goals/goal-continuation-controller.d.ts.map +1 -1
- package/dist/core/goals/goal-continuation-controller.js +52 -11
- package/dist/core/goals/goal-continuation-controller.js.map +1 -1
- package/dist/core/goals/goal-continuation-defaults.d.ts +4 -29
- package/dist/core/goals/goal-continuation-defaults.d.ts.map +1 -1
- package/dist/core/goals/goal-continuation-defaults.js +4 -32
- package/dist/core/goals/goal-continuation-defaults.js.map +1 -1
- package/dist/core/goals/goal-continuation-prompt.d.ts +8 -18
- package/dist/core/goals/goal-continuation-prompt.d.ts.map +1 -1
- package/dist/core/goals/goal-continuation-prompt.js +9 -179
- package/dist/core/goals/goal-continuation-prompt.js.map +1 -1
- package/dist/core/goals/goal-lifecycle.d.ts +43 -0
- package/dist/core/goals/goal-lifecycle.d.ts.map +1 -0
- package/dist/core/goals/goal-lifecycle.js +102 -0
- package/dist/core/goals/goal-lifecycle.js.map +1 -0
- package/dist/core/goals/goal-record.d.ts +17 -0
- package/dist/core/goals/goal-record.d.ts.map +1 -0
- package/dist/core/goals/goal-record.js +31 -0
- package/dist/core/goals/goal-record.js.map +1 -0
- package/dist/core/goals/goal-runtime-snapshot.d.ts +11 -9
- package/dist/core/goals/goal-runtime-snapshot.d.ts.map +1 -1
- package/dist/core/goals/goal-runtime-snapshot.js +10 -8
- package/dist/core/goals/goal-runtime-snapshot.js.map +1 -1
- package/dist/core/goals/goal-session-controller.d.ts +42 -0
- package/dist/core/goals/goal-session-controller.d.ts.map +1 -0
- package/dist/core/goals/goal-session-controller.js +128 -0
- package/dist/core/goals/goal-session-controller.js.map +1 -0
- package/dist/core/goals/goal-state.d.ts +46 -25
- package/dist/core/goals/goal-state.d.ts.map +1 -1
- package/dist/core/goals/goal-state.js +91 -24
- package/dist/core/goals/goal-state.js.map +1 -1
- package/dist/core/goals/goal-tool-core.d.ts +9 -10
- package/dist/core/goals/goal-tool-core.d.ts.map +1 -1
- package/dist/core/goals/goal-tool-core.js +60 -75
- package/dist/core/goals/goal-tool-core.js.map +1 -1
- package/dist/core/goals/session-goal-state.d.ts +20 -12
- package/dist/core/goals/session-goal-state.d.ts.map +1 -1
- package/dist/core/goals/session-goal-state.js +133 -33
- package/dist/core/goals/session-goal-state.js.map +1 -1
- package/dist/core/human-input-controller.d.ts +47 -0
- package/dist/core/human-input-controller.d.ts.map +1 -0
- package/dist/core/human-input-controller.js +181 -0
- package/dist/core/human-input-controller.js.map +1 -0
- package/dist/core/human-input.d.ts +100 -0
- package/dist/core/human-input.d.ts.map +1 -0
- package/dist/core/human-input.js +362 -0
- package/dist/core/human-input.js.map +1 -0
- package/dist/core/index.d.ts +9 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +9 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/{telemetry.d.ts → install-telemetry.d.ts} +1 -1
- package/dist/core/install-telemetry.d.ts.map +1 -0
- package/dist/core/{telemetry.js → install-telemetry.js} +1 -1
- package/dist/core/install-telemetry.js.map +1 -0
- package/dist/core/keybindings.d.ts +17 -1
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +24 -6
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/learning/learning-audit.d.ts +2 -4
- package/dist/core/learning/learning-audit.d.ts.map +1 -1
- package/dist/core/learning/learning-audit.js +9 -29
- package/dist/core/learning/learning-audit.js.map +1 -1
- package/dist/core/learning/learning-gate.d.ts.map +1 -1
- package/dist/core/learning/learning-gate.js +1 -6
- package/dist/core/learning/learning-gate.js.map +1 -1
- package/dist/core/learning/session-learning-decision.d.ts +2 -4
- package/dist/core/learning/session-learning-decision.d.ts.map +1 -1
- package/dist/core/learning/session-learning-decision.js +9 -29
- package/dist/core/learning/session-learning-decision.js.map +1 -1
- package/dist/core/local-runtime-controller.d.ts +1 -1
- package/dist/core/local-runtime-controller.d.ts.map +1 -1
- package/dist/core/local-runtime-controller.js.map +1 -1
- package/dist/core/memory-controller.d.ts.map +1 -1
- package/dist/core/memory-controller.js +4 -4
- package/dist/core/memory-controller.js.map +1 -1
- package/dist/core/model-capability.d.ts +0 -19
- package/dist/core/model-capability.d.ts.map +1 -1
- package/dist/core/model-capability.js +1 -19
- package/dist/core/model-capability.js.map +1 -1
- package/dist/core/model-registry.d.ts +6 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +13 -5
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +17 -2
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +38 -25
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-router/intent-classifier.d.ts +1 -4
- package/dist/core/model-router/intent-classifier.d.ts.map +1 -1
- package/dist/core/model-router/intent-classifier.js +1 -156
- package/dist/core/model-router/intent-classifier.js.map +1 -1
- package/dist/core/model-router-controller.d.ts +1 -1
- package/dist/core/model-router-controller.d.ts.map +1 -1
- package/dist/core/model-router-controller.js +2 -2
- package/dist/core/model-router-controller.js.map +1 -1
- package/dist/core/model-selection-controller.d.ts +5 -5
- package/dist/core/model-selection-controller.d.ts.map +1 -1
- package/dist/core/model-selection-controller.js.map +1 -1
- package/dist/core/model-tool-protocol.d.ts +23 -0
- package/dist/core/model-tool-protocol.d.ts.map +1 -0
- package/dist/core/model-tool-protocol.js +43 -0
- package/dist/core/model-tool-protocol.js.map +1 -0
- package/dist/core/models/adaptation-store.d.ts +4 -6
- package/dist/core/models/adaptation-store.d.ts.map +1 -1
- package/dist/core/models/adaptation-store.js +95 -83
- package/dist/core/models/adaptation-store.js.map +1 -1
- package/dist/core/models/fitness-store.d.ts +2 -12
- package/dist/core/models/fitness-store.d.ts.map +1 -1
- package/dist/core/models/fitness-store.js +84 -57
- package/dist/core/models/fitness-store.js.map +1 -1
- package/dist/core/models/host-state-store.d.ts +34 -0
- package/dist/core/models/host-state-store.d.ts.map +1 -0
- package/dist/core/models/host-state-store.js +86 -0
- package/dist/core/models/host-state-store.js.map +1 -0
- package/dist/core/orchestration/agent-resume.d.ts +24 -0
- package/dist/core/orchestration/agent-resume.d.ts.map +1 -0
- package/dist/core/orchestration/agent-resume.js +90 -0
- package/dist/core/orchestration/agent-resume.js.map +1 -0
- package/dist/core/orchestration/capability-gateway.d.ts +61 -0
- package/dist/core/orchestration/capability-gateway.d.ts.map +1 -0
- package/dist/core/orchestration/capability-gateway.js +152 -0
- package/dist/core/orchestration/capability-gateway.js.map +1 -0
- package/dist/core/orchestration/contracts.d.ts +343 -0
- package/dist/core/orchestration/contracts.d.ts.map +1 -0
- package/dist/core/orchestration/contracts.js +135 -0
- package/dist/core/orchestration/contracts.js.map +1 -0
- package/dist/core/orchestration/delegation-ledger.d.ts +56 -0
- package/dist/core/orchestration/delegation-ledger.d.ts.map +1 -0
- package/dist/core/orchestration/delegation-ledger.js +200 -0
- package/dist/core/orchestration/delegation-ledger.js.map +1 -0
- package/dist/core/orchestration/event-store.d.ts +83 -0
- package/dist/core/orchestration/event-store.d.ts.map +1 -0
- package/dist/core/orchestration/event-store.js +560 -0
- package/dist/core/orchestration/event-store.js.map +1 -0
- package/dist/core/orchestration/lane-tool-manifests.d.ts +9 -0
- package/dist/core/orchestration/lane-tool-manifests.d.ts.map +1 -0
- package/dist/core/orchestration/lane-tool-manifests.js +37 -0
- package/dist/core/orchestration/lane-tool-manifests.js.map +1 -0
- package/dist/core/orchestration/model-binding.d.ts +15 -0
- package/dist/core/orchestration/model-binding.d.ts.map +1 -0
- package/dist/core/orchestration/model-binding.js +29 -0
- package/dist/core/orchestration/model-binding.js.map +1 -0
- package/dist/core/orchestration/policy-compiler.d.ts +49 -0
- package/dist/core/orchestration/policy-compiler.d.ts.map +1 -0
- package/dist/core/orchestration/policy-compiler.js +191 -0
- package/dist/core/orchestration/policy-compiler.js.map +1 -0
- package/dist/core/orchestration/policy-gate.d.ts +18 -0
- package/dist/core/orchestration/policy-gate.d.ts.map +1 -0
- package/dist/core/orchestration/policy-gate.js +24 -0
- package/dist/core/orchestration/policy-gate.js.map +1 -0
- package/dist/core/orchestration/profile-registry.d.ts +51 -0
- package/dist/core/orchestration/profile-registry.d.ts.map +1 -0
- package/dist/core/orchestration/profile-registry.js +393 -0
- package/dist/core/orchestration/profile-registry.js.map +1 -0
- package/dist/core/orchestration/profile-store.d.ts +31 -0
- package/dist/core/orchestration/profile-store.d.ts.map +1 -0
- package/dist/core/orchestration/profile-store.js +136 -0
- package/dist/core/orchestration/profile-store.js.map +1 -0
- package/dist/core/orchestration/risk-budget.d.ts +9 -0
- package/dist/core/orchestration/risk-budget.d.ts.map +1 -0
- package/dist/core/orchestration/risk-budget.js +48 -0
- package/dist/core/orchestration/risk-budget.js.map +1 -0
- package/dist/core/orchestration/task-runtime.d.ts +168 -0
- package/dist/core/orchestration/task-runtime.d.ts.map +1 -0
- package/dist/core/orchestration/task-runtime.js +1600 -0
- package/dist/core/orchestration/task-runtime.js.map +1 -0
- package/dist/core/orchestration/work-state-projection.d.ts +32 -0
- package/dist/core/orchestration/work-state-projection.d.ts.map +1 -0
- package/dist/core/orchestration/work-state-projection.js +116 -0
- package/dist/core/orchestration/work-state-projection.js.map +1 -0
- package/dist/core/orchestration/worker-execution-contract.d.ts +21 -0
- package/dist/core/orchestration/worker-execution-contract.d.ts.map +1 -0
- package/dist/core/orchestration/worker-execution-contract.js +179 -0
- package/dist/core/orchestration/worker-execution-contract.js.map +1 -0
- package/dist/core/orchestration/worker-result-adapter.d.ts +21 -0
- package/dist/core/orchestration/worker-result-adapter.d.ts.map +1 -0
- package/dist/core/orchestration/worker-result-adapter.js +109 -0
- package/dist/core/orchestration/worker-result-adapter.js.map +1 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +20 -3
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/process-identity.d.ts +11 -0
- package/dist/core/process-identity.d.ts.map +1 -0
- package/dist/core/process-identity.js +26 -0
- package/dist/core/process-identity.js.map +1 -0
- package/dist/core/process-matrix/codes.d.ts +14 -3
- package/dist/core/process-matrix/codes.d.ts.map +1 -1
- package/dist/core/process-matrix/codes.js.map +1 -1
- package/dist/core/process-matrix/resume-launcher.d.ts +26 -0
- package/dist/core/process-matrix/resume-launcher.d.ts.map +1 -0
- package/dist/core/process-matrix/resume-launcher.js +62 -0
- package/dist/core/process-matrix/resume-launcher.js.map +1 -0
- package/dist/core/process-matrix/runtime.d.ts +37 -22
- package/dist/core/process-matrix/runtime.d.ts.map +1 -1
- package/dist/core/process-matrix/runtime.js +399 -76
- package/dist/core/process-matrix/runtime.js.map +1 -1
- package/dist/core/process-matrix/store.d.ts +5 -2
- package/dist/core/process-matrix/store.d.ts.map +1 -1
- package/dist/core/process-matrix/store.js +123 -14
- package/dist/core/process-matrix/store.js.map +1 -1
- package/dist/core/process-matrix/supervisor.d.ts +10 -7
- package/dist/core/process-matrix/supervisor.d.ts.map +1 -1
- package/dist/core/process-matrix/supervisor.js +45 -14
- package/dist/core/process-matrix/supervisor.js.map +1 -1
- package/dist/core/profile-filter-controller.d.ts +8 -1
- package/dist/core/profile-filter-controller.d.ts.map +1 -1
- package/dist/core/profile-filter-controller.js +23 -5
- package/dist/core/profile-filter-controller.js.map +1 -1
- package/dist/core/profile-registry.d.ts.map +1 -1
- package/dist/core/profile-registry.js +6 -8
- package/dist/core/profile-registry.js.map +1 -1
- package/dist/core/prompt-templates.d.ts +1 -0
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js +18 -29
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/reflection-controller.d.ts +5 -5
- package/dist/core/reflection-controller.d.ts.map +1 -1
- package/dist/core/reflection-controller.js +5 -2
- package/dist/core/reflection-controller.js.map +1 -1
- package/dist/core/reload-blockers.d.ts.map +1 -1
- package/dist/core/reload-blockers.js +6 -8
- package/dist/core/reload-blockers.js.map +1 -1
- package/dist/core/request-auth.d.ts +7 -0
- package/dist/core/request-auth.d.ts.map +1 -0
- package/dist/core/request-auth.js +8 -0
- package/dist/core/request-auth.js.map +1 -0
- package/dist/core/research/evidence-bundle.d.ts.map +1 -1
- package/dist/core/research/evidence-bundle.js +1 -6
- package/dist/core/research/evidence-bundle.js.map +1 -1
- package/dist/core/research/lane-model-resolver.d.ts +33 -0
- package/dist/core/research/lane-model-resolver.d.ts.map +1 -0
- package/dist/core/research/lane-model-resolver.js +65 -0
- package/dist/core/research/lane-model-resolver.js.map +1 -0
- package/dist/core/research/model-fitness-controller.d.ts +38 -0
- package/dist/core/research/model-fitness-controller.d.ts.map +1 -0
- package/dist/core/research/model-fitness-controller.js +106 -0
- package/dist/core/research/model-fitness-controller.js.map +1 -0
- package/dist/core/research/model-fitness.d.ts +1 -1
- package/dist/core/research/model-fitness.d.ts.map +1 -1
- package/dist/core/research/model-fitness.js +4 -4
- package/dist/core/research/model-fitness.js.map +1 -1
- package/dist/core/research/research-gate.d.ts.map +1 -1
- package/dist/core/research/research-gate.js +7 -7
- package/dist/core/research/research-gate.js.map +1 -1
- package/dist/core/research/research-lane-controller.d.ts +62 -0
- package/dist/core/research/research-lane-controller.d.ts.map +1 -0
- package/dist/core/research/research-lane-controller.js +292 -0
- package/dist/core/research/research-lane-controller.js.map +1 -0
- package/dist/core/research/session-evidence-bundle.d.ts +2 -4
- package/dist/core/research/session-evidence-bundle.d.ts.map +1 -1
- package/dist/core/research/session-evidence-bundle.js +10 -46
- package/dist/core/research/session-evidence-bundle.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +23 -8
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/risk-classifier.d.ts +6 -0
- package/dist/core/risk-classifier.d.ts.map +1 -0
- package/dist/core/risk-classifier.js +233 -0
- package/dist/core/risk-classifier.js.map +1 -0
- package/dist/core/runtime-builder.d.ts +41 -23
- package/dist/core/runtime-builder.d.ts.map +1 -1
- package/dist/core/runtime-builder.js +365 -253
- package/dist/core/runtime-builder.js.map +1 -1
- package/dist/core/sdk.d.ts +6 -3
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +68 -25
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/secrets/credential-exposure-guard.d.ts +9 -0
- package/dist/core/secrets/credential-exposure-guard.d.ts.map +1 -0
- package/dist/core/secrets/credential-exposure-guard.js +241 -0
- package/dist/core/secrets/credential-exposure-guard.js.map +1 -0
- package/dist/core/secrets/secret-dotenv.d.ts +27 -0
- package/dist/core/secrets/secret-dotenv.d.ts.map +1 -0
- package/dist/core/secrets/secret-dotenv.js +183 -0
- package/dist/core/secrets/secret-dotenv.js.map +1 -0
- package/dist/core/secrets/secret-vault-format.d.ts +112 -0
- package/dist/core/secrets/secret-vault-format.d.ts.map +1 -0
- package/dist/core/secrets/secret-vault-format.js +397 -0
- package/dist/core/secrets/secret-vault-format.js.map +1 -0
- package/dist/core/secrets/secret-vault.d.ts +72 -0
- package/dist/core/secrets/secret-vault.d.ts.map +1 -0
- package/dist/core/secrets/secret-vault.js +671 -0
- package/dist/core/secrets/secret-vault.js.map +1 -0
- package/dist/core/session-analytics.d.ts +4 -23
- package/dist/core/session-analytics.d.ts.map +1 -1
- package/dist/core/session-analytics.js +67 -70
- package/dist/core/session-analytics.js.map +1 -1
- package/dist/core/session-image-store.d.ts +33 -0
- package/dist/core/session-image-store.d.ts.map +1 -0
- package/dist/core/session-image-store.js +283 -0
- package/dist/core/session-image-store.js.map +1 -0
- package/dist/core/session-role.d.ts +11 -4
- package/dist/core/session-role.d.ts.map +1 -1
- package/dist/core/session-role.js +24 -5
- package/dist/core/session-role.js.map +1 -1
- package/dist/core/session-snapshot.d.ts +34 -0
- package/dist/core/session-snapshot.d.ts.map +1 -0
- package/dist/core/session-snapshot.js +68 -0
- package/dist/core/session-snapshot.js.map +1 -0
- package/dist/core/session-supervision-runtime.d.ts +31 -0
- package/dist/core/session-supervision-runtime.d.ts.map +1 -0
- package/dist/core/session-supervision-runtime.js +97 -0
- package/dist/core/session-supervision-runtime.js.map +1 -0
- package/dist/core/session-tree-navigator.d.ts +4 -6
- package/dist/core/session-tree-navigator.d.ts.map +1 -1
- package/dist/core/session-tree-navigator.js +4 -1
- package/dist/core/session-tree-navigator.js.map +1 -1
- package/dist/core/settings-manager.d.ts +10 -5
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +81 -29
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +2 -2
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/tasks/session-task-state.d.ts +2 -4
- package/dist/core/tasks/session-task-state.d.ts.map +1 -1
- package/dist/core/tasks/session-task-state.js +10 -28
- package/dist/core/tasks/session-task-state.js.map +1 -1
- package/dist/core/tasks/task-projection.d.ts +20 -0
- package/dist/core/tasks/task-projection.d.ts.map +1 -0
- package/dist/core/tasks/task-projection.js +47 -0
- package/dist/core/tasks/task-projection.js.map +1 -0
- package/dist/core/tasks/task-state.d.ts +4 -0
- package/dist/core/tasks/task-state.d.ts.map +1 -1
- package/dist/core/tasks/task-state.js +28 -11
- package/dist/core/tasks/task-state.js.map +1 -1
- package/dist/core/tool-capability-policy.d.ts +13 -0
- package/dist/core/tool-capability-policy.d.ts.map +1 -0
- package/dist/core/tool-capability-policy.js +86 -0
- package/dist/core/tool-capability-policy.js.map +1 -0
- package/dist/core/tool-gate-controller.d.ts.map +1 -1
- package/dist/core/tool-gate-controller.js +8 -2
- package/dist/core/tool-gate-controller.js.map +1 -1
- package/dist/core/tool-protocol-controller.d.ts +89 -0
- package/dist/core/tool-protocol-controller.d.ts.map +1 -0
- package/dist/core/tool-protocol-controller.js +512 -0
- package/dist/core/tool-protocol-controller.js.map +1 -0
- package/dist/core/tool-recovery-log-records.d.ts +2 -3
- package/dist/core/tool-recovery-log-records.d.ts.map +1 -1
- package/dist/core/tool-recovery-log-records.js +9 -35
- package/dist/core/tool-recovery-log-records.js.map +1 -1
- package/dist/core/tool-recovery-stats.d.ts +21 -1
- package/dist/core/tool-recovery-stats.d.ts.map +1 -1
- package/dist/core/tool-recovery-stats.js.map +1 -1
- package/dist/core/tool-selection/tool-performance-store.d.ts +3 -7
- package/dist/core/tool-selection/tool-performance-store.d.ts.map +1 -1
- package/dist/core/tool-selection/tool-performance-store.js +97 -138
- package/dist/core/tool-selection/tool-performance-store.js.map +1 -1
- package/dist/core/tools/ask-question.d.ts +124 -0
- package/dist/core/tools/ask-question.d.ts.map +1 -0
- package/dist/core/tools/ask-question.js +693 -0
- package/dist/core/tools/ask-question.js.map +1 -0
- package/dist/core/tools/bash.d.ts +5 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +59 -5
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/delegate-status.d.ts +31 -3
- package/dist/core/tools/delegate-status.d.ts.map +1 -1
- package/dist/core/tools/delegate-status.js +148 -29
- package/dist/core/tools/delegate-status.js.map +1 -1
- package/dist/core/tools/delegate.d.ts +15 -13
- package/dist/core/tools/delegate.d.ts.map +1 -1
- package/dist/core/tools/delegate.js +106 -23
- package/dist/core/tools/delegate.js.map +1 -1
- package/dist/core/tools/extensionify.d.ts.map +1 -1
- package/dist/core/tools/extensionify.js +1 -0
- package/dist/core/tools/extensionify.js.map +1 -1
- package/dist/core/tools/git-filter.d.ts +1 -8
- package/dist/core/tools/git-filter.d.ts.map +1 -1
- package/dist/core/tools/git-filter.js +2 -63
- package/dist/core/tools/git-filter.js.map +1 -1
- package/dist/core/tools/goal.d.ts +10 -8
- package/dist/core/tools/goal.d.ts.map +1 -1
- package/dist/core/tools/goal.js +106 -28
- package/dist/core/tools/goal.js.map +1 -1
- package/dist/core/tools/index.d.ts +1 -0
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +1 -0
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/model-fitness.d.ts.map +1 -1
- package/dist/core/tools/model-fitness.js +2 -2
- package/dist/core/tools/model-fitness.js.map +1 -1
- package/dist/core/tools/orchestration-panel.d.ts +40 -0
- package/dist/core/tools/orchestration-panel.d.ts.map +1 -0
- package/dist/core/tools/orchestration-panel.js +124 -0
- package/dist/core/tools/orchestration-panel.js.map +1 -0
- package/dist/core/tools/output-accumulator.d.ts +11 -0
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +36 -3
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/python.d.ts +2 -0
- package/dist/core/tools/python.d.ts.map +1 -1
- package/dist/core/tools/python.js +3 -1
- package/dist/core/tools/python.js.map +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/run-process.d.ts +26 -0
- package/dist/core/tools/run-process.d.ts.map +1 -0
- package/dist/core/tools/run-process.js +138 -0
- package/dist/core/tools/run-process.js.map +1 -0
- package/dist/core/tools/search-command-guard.d.ts +14 -0
- package/dist/core/tools/search-command-guard.d.ts.map +1 -0
- package/dist/core/tools/search-command-guard.js +333 -0
- package/dist/core/tools/search-command-guard.js.map +1 -0
- package/dist/core/tools/secret-store.d.ts +38 -0
- package/dist/core/tools/secret-store.d.ts.map +1 -0
- package/dist/core/tools/secret-store.js +412 -0
- package/dist/core/tools/secret-store.js.map +1 -0
- package/dist/core/tools/shell-command-parser.d.ts +16 -0
- package/dist/core/tools/shell-command-parser.d.ts.map +1 -0
- package/dist/core/tools/shell-command-parser.js +113 -0
- package/dist/core/tools/shell-command-parser.js.map +1 -0
- package/dist/core/tools/task-steps.d.ts +2 -0
- package/dist/core/tools/task-steps.d.ts.map +1 -1
- package/dist/core/tools/task-steps.js +99 -0
- package/dist/core/tools/task-steps.js.map +1 -1
- package/dist/core/tools/tmux-dispatch.d.ts +3 -5
- package/dist/core/tools/tmux-dispatch.d.ts.map +1 -1
- package/dist/core/tools/tmux-dispatch.js +4 -4
- package/dist/core/tools/tmux-dispatch.js.map +1 -1
- package/dist/core/tools/windows-shell-engine.d.ts.map +1 -1
- package/dist/core/tools/windows-shell-engine.js +4 -6
- package/dist/core/tools/windows-shell-engine.js.map +1 -1
- package/dist/core/util/atomic-file.d.ts +6 -2
- package/dist/core/util/atomic-file.d.ts.map +1 -1
- package/dist/core/util/atomic-file.js +4 -4
- package/dist/core/util/atomic-file.js.map +1 -1
- package/dist/core/util/bounded-jsonl.d.ts +10 -0
- package/dist/core/util/bounded-jsonl.d.ts.map +1 -0
- package/dist/core/util/bounded-jsonl.js +75 -0
- package/dist/core/util/bounded-jsonl.js.map +1 -0
- package/dist/core/util/value-guards.d.ts +5 -0
- package/dist/core/util/value-guards.d.ts.map +1 -0
- package/dist/core/util/value-guards.js +12 -0
- package/dist/core/util/value-guards.js.map +1 -0
- package/dist/core/worktree-sync/store.d.ts +3 -3
- package/dist/core/worktree-sync/store.d.ts.map +1 -1
- package/dist/core/worktree-sync/store.js +10 -5
- package/dist/core/worktree-sync/store.js.map +1 -1
- package/dist/index.d.ts +15 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -3
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +149 -51
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts +4 -6
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +186 -28
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/auth-dialogs-controller.d.ts +4 -0
- package/dist/modes/interactive/auth-dialogs-controller.d.ts.map +1 -1
- package/dist/modes/interactive/auth-dialogs-controller.js +60 -1
- package/dist/modes/interactive/auth-dialogs-controller.js.map +1 -1
- package/dist/modes/interactive/clipboard-input.d.ts +7 -1
- package/dist/modes/interactive/clipboard-input.d.ts.map +1 -1
- package/dist/modes/interactive/clipboard-input.js +44 -6
- package/dist/modes/interactive/clipboard-input.js.map +1 -1
- package/dist/modes/interactive/components/activity-lane.d.ts +55 -0
- package/dist/modes/interactive/components/activity-lane.d.ts.map +1 -0
- package/dist/modes/interactive/components/activity-lane.js +304 -0
- package/dist/modes/interactive/components/activity-lane.js.map +1 -0
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +19 -10
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/expandable-text.d.ts +12 -0
- package/dist/modes/interactive/components/expandable-text.d.ts.map +1 -0
- package/dist/modes/interactive/components/expandable-text.js +17 -0
- package/dist/modes/interactive/components/expandable-text.js.map +1 -0
- package/dist/modes/interactive/components/extension-editor.d.ts +15 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +30 -21
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-input.d.ts +1 -0
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-input.js +6 -1
- package/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts +2 -2
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +23 -14
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +6 -6
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +19 -11
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +53 -20
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tool-group.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-group.js +3 -0
- package/dist/modes/interactive/components/tool-group.js.map +1 -1
- package/dist/modes/interactive/components/usage-action-selector.d.ts +16 -0
- package/dist/modes/interactive/components/usage-action-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/usage-action-selector.js +46 -0
- package/dist/modes/interactive/components/usage-action-selector.js.map +1 -0
- package/dist/modes/interactive/config-backup.d.ts.map +1 -1
- package/dist/modes/interactive/config-backup.js +5 -4
- package/dist/modes/interactive/config-backup.js.map +1 -1
- package/dist/modes/interactive/extension-ui-host.d.ts +14 -0
- package/dist/modes/interactive/extension-ui-host.d.ts.map +1 -1
- package/dist/modes/interactive/extension-ui-host.js +77 -15
- package/dist/modes/interactive/extension-ui-host.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts +15 -0
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js +27 -19
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/history-reload-math.d.ts +6 -2
- package/dist/modes/interactive/history-reload-math.d.ts.map +1 -1
- package/dist/modes/interactive/history-reload-math.js +10 -5
- package/dist/modes/interactive/history-reload-math.js.map +1 -1
- package/dist/modes/interactive/interactive-event-controller.d.ts +74 -0
- package/dist/modes/interactive/interactive-event-controller.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-event-controller.js +328 -0
- package/dist/modes/interactive/interactive-event-controller.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +22 -24
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +245 -595
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/key-handlers.d.ts.map +1 -1
- package/dist/modes/interactive/key-handlers.js +1 -1
- package/dist/modes/interactive/key-handlers.js.map +1 -1
- package/dist/modes/interactive/loaded-resources-view.d.ts +20 -0
- package/dist/modes/interactive/loaded-resources-view.d.ts.map +1 -0
- package/dist/modes/interactive/loaded-resources-view.js +147 -0
- package/dist/modes/interactive/loaded-resources-view.js.map +1 -0
- package/dist/modes/interactive/profile-menu-controller.d.ts.map +1 -1
- package/dist/modes/interactive/profile-menu-controller.js +7 -7
- package/dist/modes/interactive/profile-menu-controller.js.map +1 -1
- package/dist/modes/interactive/report-commands.d.ts.map +1 -1
- package/dist/modes/interactive/report-commands.js +21 -0
- package/dist/modes/interactive/report-commands.js.map +1 -1
- package/dist/modes/interactive/resource-display.d.ts.map +1 -1
- package/dist/modes/interactive/resource-display.js +8 -2
- package/dist/modes/interactive/resource-display.js.map +1 -1
- package/dist/modes/interactive/resource-shell-commands.d.ts +1 -5
- package/dist/modes/interactive/resource-shell-commands.d.ts.map +1 -1
- package/dist/modes/interactive/resource-shell-commands.js +0 -5
- package/dist/modes/interactive/resource-shell-commands.js.map +1 -1
- package/dist/modes/interactive/session-flow-commands.d.ts +27 -8
- package/dist/modes/interactive/session-flow-commands.d.ts.map +1 -1
- package/dist/modes/interactive/session-flow-commands.js +150 -64
- package/dist/modes/interactive/session-flow-commands.js.map +1 -1
- package/dist/modes/interactive/session-io-commands.d.ts.map +1 -1
- package/dist/modes/interactive/session-io-commands.js +16 -6
- package/dist/modes/interactive/session-io-commands.js.map +1 -1
- package/dist/modes/interactive/session-replacement-errors.d.ts +7 -0
- package/dist/modes/interactive/session-replacement-errors.d.ts.map +1 -0
- package/dist/modes/interactive/session-replacement-errors.js +15 -0
- package/dist/modes/interactive/session-replacement-errors.js.map +1 -0
- package/dist/modes/interactive/startup-checks.d.ts.map +1 -1
- package/dist/modes/interactive/startup-checks.js +1 -1
- package/dist/modes/interactive/startup-checks.js.map +1 -1
- package/dist/modes/interactive/usage-commands.d.ts +34 -0
- package/dist/modes/interactive/usage-commands.d.ts.map +1 -0
- package/dist/modes/interactive/usage-commands.js +225 -0
- package/dist/modes/interactive/usage-commands.js.map +1 -0
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +82 -23
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +15 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js +138 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js +2 -13
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/clipboard-native.d.ts +1 -0
- package/dist/utils/clipboard-native.d.ts.map +1 -1
- package/dist/utils/clipboard-native.js.map +1 -1
- package/dist/utils/clipboard.d.ts +1 -0
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +52 -1
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/platform.d.ts +3 -0
- package/dist/utils/platform.d.ts.map +1 -0
- package/dist/utils/platform.js +8 -0
- package/dist/utils/platform.js.map +1 -0
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +5 -3
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +3 -1
- package/dist/utils/version-check.js.map +1 -1
- package/dist/utils/work-directory.d.ts +11 -0
- package/dist/utils/work-directory.d.ts.map +1 -1
- package/dist/utils/work-directory.js +30 -9
- package/dist/utils/work-directory.js.map +1 -1
- package/docs/UI_POLISH_ORCHESTRATION.md +38 -0
- package/docs/UI_QUALITY_ORCHESTRATION.md +28 -0
- package/docs/docs.json +4 -0
- package/docs/extensions.md +62 -2
- package/docs/harness-architecture.md +156 -0
- package/docs/keybindings.md +11 -1
- package/docs/process-matrix.md +59 -26
- package/docs/providers.md +9 -1
- package/docs/rpc.md +45 -2
- package/docs/sessions.md +15 -0
- package/docs/settings.md +125 -11
- package/docs/task-steps.md +8 -0
- package/docs/telemetry.md +19 -0
- package/docs/tmux-agent-manager.md +10 -3
- package/docs/ui-reference/README.md +9 -0
- package/docs/ui-reference/orchestration-after.txt +14 -0
- package/docs/ui-reference/orchestration-before.txt +13 -0
- package/docs/ui-reference/orchestration-reference.txt +16 -0
- package/docs/usage.md +22 -2
- package/docs/work-directory.md +19 -8
- 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/question.ts +34 -245
- package/examples/extensions/questionnaire.ts +41 -407
- 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/npm-shrinkwrap.json +13 -13
- package/package.json +4 -4
- package/dist/core/delegation/session-worker-result.d.ts +0 -46
- package/dist/core/delegation/session-worker-result.d.ts.map +0 -1
- package/dist/core/delegation/session-worker-result.js +0 -113
- package/dist/core/delegation/session-worker-result.js.map +0 -1
- package/dist/core/delegation/worker-result.d.ts.map +0 -1
- package/dist/core/delegation/worker-result.js.map +0 -1
- package/dist/core/telemetry.d.ts.map +0 -1
- package/dist/core/telemetry.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-selection-controller.js","sourceRoot":"","sources":["../../src/core/model-selection-controller.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * User-facing model + thinking-level selection.\n *\n * Extracted verbatim from agent-session.ts (god-file decomposition). Owns the manual/explicit model\n * switch and cycle paths and the thinking-level set/cycle/clamp — the deliberate human choices, as\n * opposed to the per-turn auto-routing owned by ModelRouterController. It mutates `agent.state.model`\n * / `agent.state.thinkingLevel` through deps and re-derives the capability-scoped tool surface, but the\n * session keeps the `model`/`thinkingLevel` GETTERS so the drive loop's reads are untouched. Model\n * choice is advisory-only: it warns on a bad-fit fitness probe or an oversized local model, never blocks.\n */\n\nimport { totalmem } from \"node:os\";\nimport type { Agent, ThinkingLevel } from \"@caupulican/pi-agent-core\";\nimport type { SessionManager } from \"@caupulican/pi-agent-core/node\";\nimport type { Api, Model } from \"@caupulican/pi-ai\";\nimport { clampThinkingLevel, getSupportedThinkingLevels, modelsAreEqual } from \"@caupulican/pi-ai\";\nimport type { AgentSessionEvent, ModelCycleResult } from \"./agent-session.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.ts\";\nimport type { ExtensionRunner } from \"./extensions/index.ts\";\nimport type { ModelCapabilityProfile } from \"./model-capability.ts\";\nimport type { ModelRegistry } from \"./model-registry.ts\";\nimport { FitnessStore } from \"./models/fitness-store.ts\";\nimport { OLLAMA_PROVIDER } from \"./models/local-registration.ts\";\nimport type { OllamaRuntime } from \"./models/local-runtime.ts\";\nimport { matchesInstalledLocalModel } from \"./models/model-ref.ts\";\nimport { isProbeAllFailed } from \"./research/model-fitness.ts\";\nimport type { SettingsManager } from \"./settings-manager.ts\";\n\n/** Standard thinking levels (fallback set when the current model is unknown). */\nconst THINKING_LEVELS: ThinkingLevel[] = [\"off\", \"minimal\", \"low\", \"medium\", \"high\"];\n\nexport interface ModelSelectionControllerDeps {\n\tgetAgent(): Agent;\n\tgetModel(): Model<any> | undefined;\n\tgetThinkingLevel(): ThinkingLevel;\n\tgetModelRegistry(): ModelRegistry;\n\tgetSessionManager(): SessionManager;\n\tgetSettingsManager(): SettingsManager;\n\tgetExtensionRunner(): ExtensionRunner;\n\tgetAgentDir(): string;\n\t/** Scoped models (--models flag), used by the cycle path. */\n\tgetScopedModels(): Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\t/** The user-requested active tool set, re-applied when the model's capability class changes. */\n\tgetRequestedActiveToolNames(): string[] | undefined;\n\tgetActiveToolNames(): string[];\n\tsetActiveToolsByName(toolNames: string[]): void;\n\tgetModelCapabilityProfile(): ModelCapabilityProfile;\n\t/** Rebuild the base prompt after a live orchestration-level change without altering requested tools. */\n\trefreshBaseSystemPrompt(): void;\n\t/** Session event emit (warnings + thinking_level_changed; model_select goes via the extension runner). */\n\temit(event: AgentSessionEvent): void;\n\t/** Context-window-usage warning check (session-owned, compaction-adjacent). */\n\tcheckContextWindowUsageWarning(): void;\n\t/** Resolve the Ollama server URL for a model base URL (local-runtime controller). */\n\tderiveOllamaServerUrl(modelBaseUrl: string): string;\n\t/** Local Ollama runtime for the given server URL (used for the oversized-model risk check). */\n\tgetLocalRuntime(serverUrl: string): OllamaRuntime;\n}\n\nexport class ModelSelectionController {\n\tprivate readonly deps: ModelSelectionControllerDeps;\n\n\tconstructor(deps: ModelSelectionControllerDeps) {\n\t\tthis.deps = deps;\n\t}\n\n\tprivate async _emitModelSelect(\n\t\tnextModel: Model<any>,\n\t\tpreviousModel: Model<any> | undefined,\n\t\tsource: \"set\" | \"cycle\" | \"restore\",\n\t): Promise<void> {\n\t\tif (modelsAreEqual(previousModel, nextModel)) return;\n\t\tawait this.deps.getExtensionRunner().emit({\n\t\t\ttype: \"model_select\",\n\t\t\tmodel: nextModel,\n\t\t\tpreviousModel,\n\t\t\tsource,\n\t\t});\n\t}\n\n\t/**\n\t * Set model directly.\n\t * Validates that auth is configured, saves to session and settings.\n\t * @throws Error if no auth is configured for the model\n\t */\n\tasync setModel(model: Model<any>, options: { persistSettings?: boolean } = {}): Promise<void> {\n\t\tif (!this.deps.getModelRegistry().hasConfiguredAuth(model)) {\n\t\t\tthrow new Error(`No API key for ${model.provider}/${model.id}`);\n\t\t}\n\n\t\tconst persistSettings = options.persistSettings ?? true;\n\t\tconst previousModel = this.deps.getModel();\n\t\tconst thinkingLevel = this._getThinkingLevelForModelSwitch();\n\t\tthis.deps.getAgent().state.model = model;\n\t\tthis.deps.getSessionManager().appendModelChange(model.provider, model.id);\n\t\tif (persistSettings) {\n\t\t\tthis.deps.getSettingsManager().setDefaultModelAndProvider(model.provider, model.id);\n\t\t}\n\n\t\t// Re-clamp thinking level for new model's capabilities\n\t\tthis.setThinkingLevel(thinkingLevel, { persistSettings });\n\t\tthis._resyncToolSurfaceForModel();\n\n\t\tawait this._emitModelSelect(model, previousModel, \"set\");\n\t\tthis.deps.checkContextWindowUsageWarning();\n\t\tawait this._warnIfManualModelChoiceIsRisky(model);\n\t}\n\n\tprivate _resyncToolSurfaceForModel(): void {\n\t\t// Re-derive the model-capability tool surface for the new model (restores the full requested\n\t\t// set when moving small -> large, reduces it when moving large -> small). Every switch path,\n\t\t// including model cycling and RPC commands that delegate to it, must pass through this seam.\n\t\tconst requestedActiveToolNames = this.deps.getRequestedActiveToolNames();\n\t\tif (requestedActiveToolNames) {\n\t\t\tconst before = this.deps.getActiveToolNames().join(\",\");\n\t\t\tthis.deps.setActiveToolsByName(requestedActiveToolNames);\n\t\t\tconst capability = this.deps.getModelCapabilityProfile();\n\t\t\tif (capability.class !== \"full\" && this.deps.getActiveToolNames().join(\",\") !== before) {\n\t\t\t\tthis.deps.emit({\n\t\t\t\t\ttype: \"warning\",\n\t\t\t\t\tmessage: `Small-context model detected (${capability.contextWindow ?? \"unknown\"} tokens, class '${capability.class}'): active tools reduced to [${this.deps.getActiveToolNames().join(\", \")}]; background lanes ${capability.backgroundLanesEnabled ? \"enabled\" : \"disabled\"}.`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Manual model choice is a deliberate human decision, not an auto-adoption flow — it is\n\t * ADVISORY ONLY: warn on evidence the model is a bad fit, but never block and never prompt\n\t * (print/RPC modes only ever see plain warning text through the existing `warning` event, the\n\t * same channel `_checkContextWindowUsageWarning` above uses). Two independent checks, both\n\t * best-effort:\n\t * - a recorded all-lanes-failed fitness probe on THIS host (see `isProbeAllFailed`);\n\t * - for an Ollama-served local model, weights that exceed ~90% of total system memory, which\n\t * is the exact failure the OOM report reproduced (llama-server needs the whole model resident).\n\t */\n\tprivate async _warnIfManualModelChoiceIsRisky(model: Model<Api>): Promise<void> {\n\t\tconst canonicalRef = `${model.provider}/${model.id}`;\n\t\ttry {\n\t\t\tconst fitness = FitnessStore.forAgentDir(this.deps.getAgentDir())\n\t\t\t\t.getForHost()\n\t\t\t\t.find((entry) => entry.model === canonicalRef);\n\t\t\tif (fitness && isProbeAllFailed(fitness.report)) {\n\t\t\t\tthis.deps.emit({\n\t\t\t\t\ttype: \"warning\",\n\t\t\t\t\tmessage: `${canonicalRef} failed its fitness probe on all surfaces on this host (probed ${fitness.at}) — it is likely to fail in production too. Proceeding because you set it manually.`,\n\t\t\t\t});\n\t\t\t}\n\t\t} catch {\n\t\t\t// advisory only; a lookup failure must never block a manual model choice\n\t\t}\n\n\t\tif (model.provider !== OLLAMA_PROVIDER) return;\n\t\ttry {\n\t\t\tconst serverUrl = this.deps.deriveOllamaServerUrl(model.baseUrl);\n\t\t\tconst installed = await this.deps.getLocalRuntime(serverUrl).list();\n\t\t\tconst entry = installed.find((candidate) => matchesInstalledLocalModel(model.id, candidate.name));\n\t\t\tif (!entry) return;\n\t\t\tconst memoryBudget = totalmem() * 0.9;\n\t\t\tif (entry.sizeBytes > memoryBudget) {\n\t\t\t\tconst sizeGb = (entry.sizeBytes / 1e9).toFixed(1);\n\t\t\t\tconst totalGb = (totalmem() / 1e9).toFixed(1);\n\t\t\t\tthis.deps.emit({\n\t\t\t\t\ttype: \"warning\",\n\t\t\t\t\tmessage: `${canonicalRef} is ~${sizeGb}GB, over 90% of this machine's ${totalGb}GB RAM — llama-server is likely to OOM when it runs. Proceeding because you set it manually.`,\n\t\t\t\t});\n\t\t\t}\n\t\t} catch {\n\t\t\t// advisory only; an unreachable local server must never block a manual model choice\n\t\t}\n\t}\n\n\t/**\n\t * Cycle to next/previous model.\n\t * Uses scoped models (from --models flag) if available, otherwise all available models.\n\t * @param direction - \"forward\" (default) or \"backward\"\n\t * @returns The new model info, or undefined if only one model available\n\t */\n\tasync cycleModel(direction: \"forward\" | \"backward\" = \"forward\"): Promise<ModelCycleResult | undefined> {\n\t\tif (this.deps.getScopedModels().length > 0) {\n\t\t\treturn this._cycleScopedModel(direction);\n\t\t}\n\t\treturn this._cycleAvailableModel(direction);\n\t}\n\n\tprivate async _cycleScopedModel(direction: \"forward\" | \"backward\"): Promise<ModelCycleResult | undefined> {\n\t\tconst scopedModels = this.deps\n\t\t\t.getScopedModels()\n\t\t\t.filter((scoped) => this.deps.getModelRegistry().hasConfiguredAuth(scoped.model));\n\t\tif (scopedModels.length <= 1) return undefined;\n\n\t\tconst currentModel = this.deps.getModel();\n\t\tlet currentIndex = scopedModels.findIndex((sm) => modelsAreEqual(sm.model, currentModel));\n\n\t\tif (currentIndex === -1) currentIndex = 0;\n\t\tconst len = scopedModels.length;\n\t\tconst nextIndex = direction === \"forward\" ? (currentIndex + 1) % len : (currentIndex - 1 + len) % len;\n\t\tconst next = scopedModels[nextIndex];\n\t\tconst thinkingLevel = this._getThinkingLevelForModelSwitch(next.thinkingLevel);\n\n\t\t// Apply model\n\t\tthis.deps.getAgent().state.model = next.model;\n\t\tthis.deps.getSessionManager().appendModelChange(next.model.provider, next.model.id);\n\t\tthis.deps.getSettingsManager().setDefaultModelAndProvider(next.model.provider, next.model.id);\n\n\t\t// Apply thinking level.\n\t\t// - Explicit scoped model thinking level overrides current session level\n\t\t// - Undefined scoped model thinking level inherits the current session preference\n\t\t// setThinkingLevel clamps to model capabilities.\n\t\tthis.setThinkingLevel(thinkingLevel);\n\t\tthis._resyncToolSurfaceForModel();\n\n\t\tawait this._emitModelSelect(next.model, currentModel, \"cycle\");\n\n\t\tthis.deps.checkContextWindowUsageWarning();\n\t\tawait this._warnIfManualModelChoiceIsRisky(next.model);\n\n\t\treturn { model: next.model, thinkingLevel: this.deps.getThinkingLevel(), isScoped: true };\n\t}\n\n\tprivate async _cycleAvailableModel(direction: \"forward\" | \"backward\"): Promise<ModelCycleResult | undefined> {\n\t\tconst availableModels = await this.deps.getModelRegistry().getAvailable();\n\t\tif (availableModels.length <= 1) return undefined;\n\n\t\tconst currentModel = this.deps.getModel();\n\t\tlet currentIndex = availableModels.findIndex((m) => modelsAreEqual(m, currentModel));\n\n\t\tif (currentIndex === -1) currentIndex = 0;\n\t\tconst len = availableModels.length;\n\t\tconst nextIndex = direction === \"forward\" ? (currentIndex + 1) % len : (currentIndex - 1 + len) % len;\n\t\tconst nextModel = availableModels[nextIndex];\n\n\t\tconst thinkingLevel = this._getThinkingLevelForModelSwitch();\n\t\tthis.deps.getAgent().state.model = nextModel;\n\t\tthis.deps.getSessionManager().appendModelChange(nextModel.provider, nextModel.id);\n\t\tthis.deps.getSettingsManager().setDefaultModelAndProvider(nextModel.provider, nextModel.id);\n\n\t\t// Re-clamp thinking level for new model's capabilities\n\t\tthis.setThinkingLevel(thinkingLevel);\n\t\tthis._resyncToolSurfaceForModel();\n\n\t\tawait this._emitModelSelect(nextModel, currentModel, \"cycle\");\n\n\t\tthis.deps.checkContextWindowUsageWarning();\n\t\tawait this._warnIfManualModelChoiceIsRisky(nextModel);\n\n\t\treturn { model: nextModel, thinkingLevel: this.deps.getThinkingLevel(), isScoped: false };\n\t}\n\n\t/**\n\t * Set thinking level.\n\t * Clamps to model capabilities based on available thinking levels.\n\t * Saves to session and settings only if the level actually changes.\n\t */\n\tsetThinkingLevel(level: ThinkingLevel, options: { persistSettings?: boolean } = {}): void {\n\t\tconst availableLevels = this.getAvailableThinkingLevels();\n\t\tconst effectiveLevel = availableLevels.includes(level) ? level : this._clampThinkingLevel(level, availableLevels);\n\n\t\t// Only persist if actually changing\n\t\tconst previousLevel = this.deps.getAgent().state.thinkingLevel;\n\t\tconst isChanging = effectiveLevel !== previousLevel;\n\t\tconst persistSettings = options.persistSettings ?? true;\n\n\t\tthis.deps.getAgent().state.thinkingLevel = effectiveLevel;\n\n\t\tif (isChanging) {\n\t\t\tthis.deps.refreshBaseSystemPrompt();\n\t\t\tthis.deps.getSessionManager().appendThinkingLevelChange(effectiveLevel);\n\t\t\tif (persistSettings && (this.supportsThinking() || effectiveLevel !== \"off\")) {\n\t\t\t\tthis.deps.getSettingsManager().setDefaultThinkingLevel(effectiveLevel);\n\t\t\t}\n\t\t\tthis.deps.emit({ type: \"thinking_level_changed\", level: effectiveLevel });\n\t\t\tvoid this.deps.getExtensionRunner().emit({\n\t\t\t\ttype: \"thinking_level_select\",\n\t\t\t\tlevel: effectiveLevel,\n\t\t\t\tpreviousLevel,\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Cycle to next thinking level.\n\t * @returns New level, or undefined if model doesn't support thinking\n\t */\n\tcycleThinkingLevel(): ThinkingLevel | undefined {\n\t\tif (!this.supportsThinking()) return undefined;\n\n\t\tconst levels = this.getAvailableThinkingLevels();\n\t\tconst currentIndex = levels.indexOf(this.deps.getThinkingLevel());\n\t\tconst nextIndex = (currentIndex + 1) % levels.length;\n\t\tconst nextLevel = levels[nextIndex];\n\n\t\tthis.setThinkingLevel(nextLevel);\n\t\treturn nextLevel;\n\t}\n\n\t/**\n\t * Get available thinking levels for current model.\n\t * The provider will clamp to what the specific model supports internally.\n\t */\n\tgetAvailableThinkingLevels(): ThinkingLevel[] {\n\t\tconst model = this.deps.getModel();\n\t\tif (!model) return THINKING_LEVELS;\n\t\treturn getSupportedThinkingLevels(model) as ThinkingLevel[];\n\t}\n\n\t/**\n\t * Check if current model supports thinking/reasoning.\n\t */\n\tsupportsThinking(): boolean {\n\t\treturn !!this.deps.getModel()?.reasoning;\n\t}\n\n\tprivate _getThinkingLevelForModelSwitch(explicitLevel?: ThinkingLevel): ThinkingLevel {\n\t\tif (explicitLevel !== undefined) {\n\t\t\treturn explicitLevel;\n\t\t}\n\t\tif (!this.supportsThinking()) {\n\t\t\treturn this.deps.getSettingsManager().getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t\t}\n\t\treturn this.deps.getThinkingLevel();\n\t}\n\n\tprivate _clampThinkingLevel(level: ThinkingLevel, _availableLevels: ThinkingLevel[]): ThinkingLevel {\n\t\tconst model = this.deps.getModel();\n\t\treturn model ? (clampThinkingLevel(model, level) as ThinkingLevel) : \"off\";\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"model-selection-controller.js","sourceRoot":"","sources":["../../src/core/model-selection-controller.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * User-facing model + thinking-level selection.\n *\n * Extracted verbatim from agent-session.ts (god-file decomposition). Owns the manual/explicit model\n * switch and cycle paths and the thinking-level set/cycle/clamp — the deliberate human choices, as\n * opposed to the per-turn auto-routing owned by ModelRouterController. It mutates `agent.state.model`\n * / `agent.state.thinkingLevel` through deps and re-derives the capability-scoped tool surface, but the\n * session keeps the `model`/`thinkingLevel` GETTERS so the drive loop's reads are untouched. Model\n * choice is advisory-only: it warns on a bad-fit fitness probe or an oversized local model, never blocks.\n */\n\nimport { totalmem } from \"node:os\";\nimport type { Agent, ThinkingLevel } from \"@caupulican/pi-agent-core\";\nimport type { SessionManager } from \"@caupulican/pi-agent-core/node\";\nimport type { Api, Model } from \"@caupulican/pi-ai\";\nimport { clampThinkingLevel, getSupportedThinkingLevels, modelsAreEqual } from \"@caupulican/pi-ai\";\nimport type { AgentSessionEvent, ModelCycleResult } from \"./agent-session-contracts.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.ts\";\nimport type { ExtensionRunner } from \"./extensions/index.ts\";\nimport type { ModelCapabilityProfile } from \"./model-capability.ts\";\nimport type { ModelRegistry } from \"./model-registry.ts\";\nimport { FitnessStore } from \"./models/fitness-store.ts\";\nimport { OLLAMA_PROVIDER } from \"./models/local-registration.ts\";\nimport type { OllamaRuntime } from \"./models/local-runtime.ts\";\nimport { matchesInstalledLocalModel } from \"./models/model-ref.ts\";\nimport { isProbeAllFailed } from \"./research/model-fitness.ts\";\nimport type { SettingsManager } from \"./settings-manager.ts\";\n\n/** Standard thinking levels (fallback set when the current model is unknown). */\nconst THINKING_LEVELS: ThinkingLevel[] = [\"off\", \"minimal\", \"low\", \"medium\", \"high\"];\n\nexport interface ModelSelectionControllerDeps {\n\tgetAgent(): Agent;\n\tgetModel(): Model<Api> | undefined;\n\tgetThinkingLevel(): ThinkingLevel;\n\tgetModelRegistry(): ModelRegistry;\n\tgetSessionManager(): SessionManager;\n\tgetSettingsManager(): SettingsManager;\n\tgetExtensionRunner(): ExtensionRunner;\n\tgetAgentDir(): string;\n\t/** Scoped models (--models flag), used by the cycle path. */\n\tgetScopedModels(): Array<{ model: Model<Api>; thinkingLevel?: ThinkingLevel }>;\n\t/** The user-requested active tool set, re-applied when the model's capability class changes. */\n\tgetRequestedActiveToolNames(): string[] | undefined;\n\tgetActiveToolNames(): string[];\n\tsetActiveToolsByName(toolNames: string[]): void;\n\tgetModelCapabilityProfile(): ModelCapabilityProfile;\n\t/** Rebuild the base prompt after a live orchestration-level change without altering requested tools. */\n\trefreshBaseSystemPrompt(): void;\n\t/** Session event emit (warnings + thinking_level_changed; model_select goes via the extension runner). */\n\temit(event: AgentSessionEvent): void;\n\t/** Context-window-usage warning check (session-owned, compaction-adjacent). */\n\tcheckContextWindowUsageWarning(): void;\n\t/** Resolve the Ollama server URL for a model base URL (local-runtime controller). */\n\tderiveOllamaServerUrl(modelBaseUrl: string): string;\n\t/** Local Ollama runtime for the given server URL (used for the oversized-model risk check). */\n\tgetLocalRuntime(serverUrl: string): OllamaRuntime;\n}\n\nexport class ModelSelectionController {\n\tprivate readonly deps: ModelSelectionControllerDeps;\n\n\tconstructor(deps: ModelSelectionControllerDeps) {\n\t\tthis.deps = deps;\n\t}\n\n\tprivate async _emitModelSelect(\n\t\tnextModel: Model<Api>,\n\t\tpreviousModel: Model<Api> | undefined,\n\t\tsource: \"set\" | \"cycle\" | \"restore\",\n\t): Promise<void> {\n\t\tif (modelsAreEqual(previousModel, nextModel)) return;\n\t\tawait this.deps.getExtensionRunner().emit({\n\t\t\ttype: \"model_select\",\n\t\t\tmodel: nextModel,\n\t\t\tpreviousModel,\n\t\t\tsource,\n\t\t});\n\t}\n\n\t/**\n\t * Set model directly.\n\t * Validates that auth is configured, saves to session and settings.\n\t * @throws Error if no auth is configured for the model\n\t */\n\tasync setModel(model: Model<Api>, options: { persistSettings?: boolean } = {}): Promise<void> {\n\t\tif (!this.deps.getModelRegistry().hasConfiguredAuth(model)) {\n\t\t\tthrow new Error(`No API key for ${model.provider}/${model.id}`);\n\t\t}\n\n\t\tconst persistSettings = options.persistSettings ?? true;\n\t\tconst previousModel = this.deps.getModel();\n\t\tconst thinkingLevel = this._getThinkingLevelForModelSwitch();\n\t\tthis.deps.getAgent().state.model = model;\n\t\tthis.deps.getSessionManager().appendModelChange(model.provider, model.id);\n\t\tif (persistSettings) {\n\t\t\tthis.deps.getSettingsManager().setDefaultModelAndProvider(model.provider, model.id);\n\t\t}\n\n\t\t// Re-clamp thinking level for new model's capabilities\n\t\tthis.setThinkingLevel(thinkingLevel, { persistSettings });\n\t\tthis._resyncToolSurfaceForModel();\n\n\t\tawait this._emitModelSelect(model, previousModel, \"set\");\n\t\tthis.deps.checkContextWindowUsageWarning();\n\t\tawait this._warnIfManualModelChoiceIsRisky(model);\n\t}\n\n\tprivate _resyncToolSurfaceForModel(): void {\n\t\t// Re-derive the model-capability tool surface for the new model (restores the full requested\n\t\t// set when moving small -> large, reduces it when moving large -> small). Every switch path,\n\t\t// including model cycling and RPC commands that delegate to it, must pass through this seam.\n\t\tconst requestedActiveToolNames = this.deps.getRequestedActiveToolNames();\n\t\tif (requestedActiveToolNames) {\n\t\t\tconst before = this.deps.getActiveToolNames().join(\",\");\n\t\t\tthis.deps.setActiveToolsByName(requestedActiveToolNames);\n\t\t\tconst capability = this.deps.getModelCapabilityProfile();\n\t\t\tif (capability.class !== \"full\" && this.deps.getActiveToolNames().join(\",\") !== before) {\n\t\t\t\tthis.deps.emit({\n\t\t\t\t\ttype: \"warning\",\n\t\t\t\t\tmessage: `Small-context model detected (${capability.contextWindow ?? \"unknown\"} tokens, class '${capability.class}'): active tools reduced to [${this.deps.getActiveToolNames().join(\", \")}]; background lanes ${capability.backgroundLanesEnabled ? \"enabled\" : \"disabled\"}.`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Manual model choice is a deliberate human decision, not an auto-adoption flow — it is\n\t * ADVISORY ONLY: warn on evidence the model is a bad fit, but never block and never prompt\n\t * (print/RPC modes only ever see plain warning text through the existing `warning` event, the\n\t * same channel `_checkContextWindowUsageWarning` above uses). Two independent checks, both\n\t * best-effort:\n\t * - a recorded all-lanes-failed fitness probe on THIS host (see `isProbeAllFailed`);\n\t * - for an Ollama-served local model, weights that exceed ~90% of total system memory, which\n\t * is the exact failure the OOM report reproduced (llama-server needs the whole model resident).\n\t */\n\tprivate async _warnIfManualModelChoiceIsRisky(model: Model<Api>): Promise<void> {\n\t\tconst canonicalRef = `${model.provider}/${model.id}`;\n\t\ttry {\n\t\t\tconst fitness = FitnessStore.forAgentDir(this.deps.getAgentDir())\n\t\t\t\t.getForHost()\n\t\t\t\t.find((entry) => entry.model === canonicalRef);\n\t\t\tif (fitness && isProbeAllFailed(fitness.report)) {\n\t\t\t\tthis.deps.emit({\n\t\t\t\t\ttype: \"warning\",\n\t\t\t\t\tmessage: `${canonicalRef} failed its fitness probe on all surfaces on this host (probed ${fitness.at}) — it is likely to fail in production too. Proceeding because you set it manually.`,\n\t\t\t\t});\n\t\t\t}\n\t\t} catch {\n\t\t\t// advisory only; a lookup failure must never block a manual model choice\n\t\t}\n\n\t\tif (model.provider !== OLLAMA_PROVIDER) return;\n\t\ttry {\n\t\t\tconst serverUrl = this.deps.deriveOllamaServerUrl(model.baseUrl);\n\t\t\tconst installed = await this.deps.getLocalRuntime(serverUrl).list();\n\t\t\tconst entry = installed.find((candidate) => matchesInstalledLocalModel(model.id, candidate.name));\n\t\t\tif (!entry) return;\n\t\t\tconst memoryBudget = totalmem() * 0.9;\n\t\t\tif (entry.sizeBytes > memoryBudget) {\n\t\t\t\tconst sizeGb = (entry.sizeBytes / 1e9).toFixed(1);\n\t\t\t\tconst totalGb = (totalmem() / 1e9).toFixed(1);\n\t\t\t\tthis.deps.emit({\n\t\t\t\t\ttype: \"warning\",\n\t\t\t\t\tmessage: `${canonicalRef} is ~${sizeGb}GB, over 90% of this machine's ${totalGb}GB RAM — llama-server is likely to OOM when it runs. Proceeding because you set it manually.`,\n\t\t\t\t});\n\t\t\t}\n\t\t} catch {\n\t\t\t// advisory only; an unreachable local server must never block a manual model choice\n\t\t}\n\t}\n\n\t/**\n\t * Cycle to next/previous model.\n\t * Uses scoped models (from --models flag) if available, otherwise all available models.\n\t * @param direction - \"forward\" (default) or \"backward\"\n\t * @returns The new model info, or undefined if only one model available\n\t */\n\tasync cycleModel(direction: \"forward\" | \"backward\" = \"forward\"): Promise<ModelCycleResult | undefined> {\n\t\tif (this.deps.getScopedModels().length > 0) {\n\t\t\treturn this._cycleScopedModel(direction);\n\t\t}\n\t\treturn this._cycleAvailableModel(direction);\n\t}\n\n\tprivate async _cycleScopedModel(direction: \"forward\" | \"backward\"): Promise<ModelCycleResult | undefined> {\n\t\tconst scopedModels = this.deps\n\t\t\t.getScopedModels()\n\t\t\t.filter((scoped) => this.deps.getModelRegistry().hasConfiguredAuth(scoped.model));\n\t\tif (scopedModels.length <= 1) return undefined;\n\n\t\tconst currentModel = this.deps.getModel();\n\t\tlet currentIndex = scopedModels.findIndex((sm) => modelsAreEqual(sm.model, currentModel));\n\n\t\tif (currentIndex === -1) currentIndex = 0;\n\t\tconst len = scopedModels.length;\n\t\tconst nextIndex = direction === \"forward\" ? (currentIndex + 1) % len : (currentIndex - 1 + len) % len;\n\t\tconst next = scopedModels[nextIndex];\n\t\tconst thinkingLevel = this._getThinkingLevelForModelSwitch(next.thinkingLevel);\n\n\t\t// Apply model\n\t\tthis.deps.getAgent().state.model = next.model;\n\t\tthis.deps.getSessionManager().appendModelChange(next.model.provider, next.model.id);\n\t\tthis.deps.getSettingsManager().setDefaultModelAndProvider(next.model.provider, next.model.id);\n\n\t\t// Apply thinking level.\n\t\t// - Explicit scoped model thinking level overrides current session level\n\t\t// - Undefined scoped model thinking level inherits the current session preference\n\t\t// setThinkingLevel clamps to model capabilities.\n\t\tthis.setThinkingLevel(thinkingLevel);\n\t\tthis._resyncToolSurfaceForModel();\n\n\t\tawait this._emitModelSelect(next.model, currentModel, \"cycle\");\n\n\t\tthis.deps.checkContextWindowUsageWarning();\n\t\tawait this._warnIfManualModelChoiceIsRisky(next.model);\n\n\t\treturn { model: next.model, thinkingLevel: this.deps.getThinkingLevel(), isScoped: true };\n\t}\n\n\tprivate async _cycleAvailableModel(direction: \"forward\" | \"backward\"): Promise<ModelCycleResult | undefined> {\n\t\tconst availableModels = await this.deps.getModelRegistry().getAvailable();\n\t\tif (availableModels.length <= 1) return undefined;\n\n\t\tconst currentModel = this.deps.getModel();\n\t\tlet currentIndex = availableModels.findIndex((m) => modelsAreEqual(m, currentModel));\n\n\t\tif (currentIndex === -1) currentIndex = 0;\n\t\tconst len = availableModels.length;\n\t\tconst nextIndex = direction === \"forward\" ? (currentIndex + 1) % len : (currentIndex - 1 + len) % len;\n\t\tconst nextModel = availableModels[nextIndex];\n\n\t\tconst thinkingLevel = this._getThinkingLevelForModelSwitch();\n\t\tthis.deps.getAgent().state.model = nextModel;\n\t\tthis.deps.getSessionManager().appendModelChange(nextModel.provider, nextModel.id);\n\t\tthis.deps.getSettingsManager().setDefaultModelAndProvider(nextModel.provider, nextModel.id);\n\n\t\t// Re-clamp thinking level for new model's capabilities\n\t\tthis.setThinkingLevel(thinkingLevel);\n\t\tthis._resyncToolSurfaceForModel();\n\n\t\tawait this._emitModelSelect(nextModel, currentModel, \"cycle\");\n\n\t\tthis.deps.checkContextWindowUsageWarning();\n\t\tawait this._warnIfManualModelChoiceIsRisky(nextModel);\n\n\t\treturn { model: nextModel, thinkingLevel: this.deps.getThinkingLevel(), isScoped: false };\n\t}\n\n\t/**\n\t * Set thinking level.\n\t * Clamps to model capabilities based on available thinking levels.\n\t * Saves to session and settings only if the level actually changes.\n\t */\n\tsetThinkingLevel(level: ThinkingLevel, options: { persistSettings?: boolean } = {}): void {\n\t\tconst availableLevels = this.getAvailableThinkingLevels();\n\t\tconst effectiveLevel = availableLevels.includes(level) ? level : this._clampThinkingLevel(level, availableLevels);\n\n\t\t// Only persist if actually changing\n\t\tconst previousLevel = this.deps.getAgent().state.thinkingLevel;\n\t\tconst isChanging = effectiveLevel !== previousLevel;\n\t\tconst persistSettings = options.persistSettings ?? true;\n\n\t\tthis.deps.getAgent().state.thinkingLevel = effectiveLevel;\n\n\t\tif (isChanging) {\n\t\t\tthis.deps.refreshBaseSystemPrompt();\n\t\t\tthis.deps.getSessionManager().appendThinkingLevelChange(effectiveLevel);\n\t\t\tif (persistSettings && (this.supportsThinking() || effectiveLevel !== \"off\")) {\n\t\t\t\tthis.deps.getSettingsManager().setDefaultThinkingLevel(effectiveLevel);\n\t\t\t}\n\t\t\tthis.deps.emit({ type: \"thinking_level_changed\", level: effectiveLevel });\n\t\t\tvoid this.deps.getExtensionRunner().emit({\n\t\t\t\ttype: \"thinking_level_select\",\n\t\t\t\tlevel: effectiveLevel,\n\t\t\t\tpreviousLevel,\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Cycle to next thinking level.\n\t * @returns New level, or undefined if model doesn't support thinking\n\t */\n\tcycleThinkingLevel(): ThinkingLevel | undefined {\n\t\tif (!this.supportsThinking()) return undefined;\n\n\t\tconst levels = this.getAvailableThinkingLevels();\n\t\tconst currentIndex = levels.indexOf(this.deps.getThinkingLevel());\n\t\tconst nextIndex = (currentIndex + 1) % levels.length;\n\t\tconst nextLevel = levels[nextIndex];\n\n\t\tthis.setThinkingLevel(nextLevel);\n\t\treturn nextLevel;\n\t}\n\n\t/**\n\t * Get available thinking levels for current model.\n\t * The provider will clamp to what the specific model supports internally.\n\t */\n\tgetAvailableThinkingLevels(): ThinkingLevel[] {\n\t\tconst model = this.deps.getModel();\n\t\tif (!model) return THINKING_LEVELS;\n\t\treturn getSupportedThinkingLevels(model) as ThinkingLevel[];\n\t}\n\n\t/**\n\t * Check if current model supports thinking/reasoning.\n\t */\n\tsupportsThinking(): boolean {\n\t\treturn !!this.deps.getModel()?.reasoning;\n\t}\n\n\tprivate _getThinkingLevelForModelSwitch(explicitLevel?: ThinkingLevel): ThinkingLevel {\n\t\tif (explicitLevel !== undefined) {\n\t\t\treturn explicitLevel;\n\t\t}\n\t\tif (!this.supportsThinking()) {\n\t\t\treturn this.deps.getSettingsManager().getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t\t}\n\t\treturn this.deps.getThinkingLevel();\n\t}\n\n\tprivate _clampThinkingLevel(level: ThinkingLevel, _availableLevels: ThinkingLevel[]): ThinkingLevel {\n\t\tconst model = this.deps.getModel();\n\t\treturn model ? (clampThinkingLevel(model, level) as ThinkingLevel) : \"off\";\n\t}\n}\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type Api, type Model, type SimpleStreamOptions } from "@caupulican/pi-ai";
|
|
2
|
+
import type { ModelAdaptationProfile } from "./models/adaptation-store.ts";
|
|
3
|
+
export declare const MODEL_TOOL_PROTOCOL_VERSION = 1;
|
|
4
|
+
export type ModelToolProtocolReasonCode = "settings_disabled" | "settings_enabled" | "model_enabled" | "probe_calibrated" | "probe_calibration_missing" | "probe_calibration_failed" | "probe_calibration_invalid" | "native_default";
|
|
5
|
+
export interface ModelToolProtocolResolution {
|
|
6
|
+
protocol: SimpleStreamOptions["textToolCallProtocol"];
|
|
7
|
+
reasonCode: ModelToolProtocolReasonCode;
|
|
8
|
+
variantsTried?: readonly string[];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Resolve the effective tool-call transport for any model and execution lane.
|
|
12
|
+
*
|
|
13
|
+
* Explicit settings win, followed by model metadata and then graded probe evidence. A probe-driven
|
|
14
|
+
* text protocol is usable only with a current, recognized calibration; otherwise the model stays on
|
|
15
|
+
* native calls for this turn. Callers use the reason code for diagnostics, but never reimplement the
|
|
16
|
+
* precedence or silently substitute the default dialect.
|
|
17
|
+
*/
|
|
18
|
+
export declare function resolveModelToolProtocol(args: {
|
|
19
|
+
model: Pick<Model<Api>, "textToolCallProtocol">;
|
|
20
|
+
settingsOverride?: boolean;
|
|
21
|
+
adaptation: Pick<ModelAdaptationProfile, "protocol" | "toolProbe">;
|
|
22
|
+
}): ModelToolProtocolResolution;
|
|
23
|
+
//# sourceMappingURL=model-tool-protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-tool-protocol.d.ts","sourceRoot":"","sources":["../../src/core/model-tool-protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAA6B,KAAK,KAAK,EAAE,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC9G,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAE3E,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAE7C,MAAM,MAAM,2BAA2B,GACpC,mBAAmB,GACnB,kBAAkB,GAClB,eAAe,GACf,kBAAkB,GAClB,2BAA2B,GAC3B,0BAA0B,GAC1B,2BAA2B,GAC3B,gBAAgB,CAAC;AAEpB,MAAM,WAAW,2BAA2B;IAC3C,QAAQ,EAAE,mBAAmB,CAAC,sBAAsB,CAAC,CAAC;IACtD,UAAU,EAAE,2BAA2B,CAAC;IACxC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC9C,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,sBAAsB,CAAC,CAAC;IAChD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,UAAU,EAAE,IAAI,CAAC,sBAAsB,EAAE,UAAU,GAAG,WAAW,CAAC,CAAC;CACnE,GAAG,2BAA2B,CAgC9B","sourcesContent":["import { type Api, isTextToolProtocolVariant, type Model, type SimpleStreamOptions } from \"@caupulican/pi-ai\";\nimport type { ModelAdaptationProfile } from \"./models/adaptation-store.ts\";\n\nexport const MODEL_TOOL_PROTOCOL_VERSION = 1;\n\nexport type ModelToolProtocolReasonCode =\n\t| \"settings_disabled\"\n\t| \"settings_enabled\"\n\t| \"model_enabled\"\n\t| \"probe_calibrated\"\n\t| \"probe_calibration_missing\"\n\t| \"probe_calibration_failed\"\n\t| \"probe_calibration_invalid\"\n\t| \"native_default\";\n\nexport interface ModelToolProtocolResolution {\n\tprotocol: SimpleStreamOptions[\"textToolCallProtocol\"];\n\treasonCode: ModelToolProtocolReasonCode;\n\tvariantsTried?: readonly string[];\n}\n\n/**\n * Resolve the effective tool-call transport for any model and execution lane.\n *\n * Explicit settings win, followed by model metadata and then graded probe evidence. A probe-driven\n * text protocol is usable only with a current, recognized calibration; otherwise the model stays on\n * native calls for this turn. Callers use the reason code for diagnostics, but never reimplement the\n * precedence or silently substitute the default dialect.\n */\nexport function resolveModelToolProtocol(args: {\n\tmodel: Pick<Model<Api>, \"textToolCallProtocol\">;\n\tsettingsOverride?: boolean;\n\tadaptation: Pick<ModelAdaptationProfile, \"protocol\" | \"toolProbe\">;\n}): ModelToolProtocolResolution {\n\tif (args.settingsOverride === false) {\n\t\treturn { protocol: undefined, reasonCode: \"settings_disabled\" };\n\t}\n\tif (args.settingsOverride === true) {\n\t\treturn { protocol: true, reasonCode: \"settings_enabled\" };\n\t}\n\tif (args.model.textToolCallProtocol === true) {\n\t\treturn { protocol: true, reasonCode: \"model_enabled\" };\n\t}\n\tif (args.adaptation.toolProbe?.status !== \"text-protocol\") {\n\t\treturn { protocol: undefined, reasonCode: \"native_default\" };\n\t}\n\n\tconst calibration = args.adaptation.protocol;\n\tif (!calibration) {\n\t\treturn { protocol: undefined, reasonCode: \"probe_calibration_missing\" };\n\t}\n\tif (calibration.status === \"failed\") {\n\t\treturn {\n\t\t\tprotocol: undefined,\n\t\t\treasonCode: \"probe_calibration_failed\",\n\t\t\tvariantsTried: calibration.variantsTried,\n\t\t};\n\t}\n\tif (calibration.version !== MODEL_TOOL_PROTOCOL_VERSION || !isTextToolProtocolVariant(calibration.variant)) {\n\t\treturn { protocol: undefined, reasonCode: \"probe_calibration_invalid\" };\n\t}\n\treturn {\n\t\tprotocol: { variant: calibration.variant },\n\t\treasonCode: \"probe_calibrated\",\n\t};\n}\n"]}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { isTextToolProtocolVariant } from "@caupulican/pi-ai";
|
|
2
|
+
export const MODEL_TOOL_PROTOCOL_VERSION = 1;
|
|
3
|
+
/**
|
|
4
|
+
* Resolve the effective tool-call transport for any model and execution lane.
|
|
5
|
+
*
|
|
6
|
+
* Explicit settings win, followed by model metadata and then graded probe evidence. A probe-driven
|
|
7
|
+
* text protocol is usable only with a current, recognized calibration; otherwise the model stays on
|
|
8
|
+
* native calls for this turn. Callers use the reason code for diagnostics, but never reimplement the
|
|
9
|
+
* precedence or silently substitute the default dialect.
|
|
10
|
+
*/
|
|
11
|
+
export function resolveModelToolProtocol(args) {
|
|
12
|
+
if (args.settingsOverride === false) {
|
|
13
|
+
return { protocol: undefined, reasonCode: "settings_disabled" };
|
|
14
|
+
}
|
|
15
|
+
if (args.settingsOverride === true) {
|
|
16
|
+
return { protocol: true, reasonCode: "settings_enabled" };
|
|
17
|
+
}
|
|
18
|
+
if (args.model.textToolCallProtocol === true) {
|
|
19
|
+
return { protocol: true, reasonCode: "model_enabled" };
|
|
20
|
+
}
|
|
21
|
+
if (args.adaptation.toolProbe?.status !== "text-protocol") {
|
|
22
|
+
return { protocol: undefined, reasonCode: "native_default" };
|
|
23
|
+
}
|
|
24
|
+
const calibration = args.adaptation.protocol;
|
|
25
|
+
if (!calibration) {
|
|
26
|
+
return { protocol: undefined, reasonCode: "probe_calibration_missing" };
|
|
27
|
+
}
|
|
28
|
+
if (calibration.status === "failed") {
|
|
29
|
+
return {
|
|
30
|
+
protocol: undefined,
|
|
31
|
+
reasonCode: "probe_calibration_failed",
|
|
32
|
+
variantsTried: calibration.variantsTried,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
if (calibration.version !== MODEL_TOOL_PROTOCOL_VERSION || !isTextToolProtocolVariant(calibration.variant)) {
|
|
36
|
+
return { protocol: undefined, reasonCode: "probe_calibration_invalid" };
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
protocol: { variant: calibration.variant },
|
|
40
|
+
reasonCode: "probe_calibrated",
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=model-tool-protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-tool-protocol.js","sourceRoot":"","sources":["../../src/core/model-tool-protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,yBAAyB,EAAwC,MAAM,mBAAmB,CAAC;AAG9G,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC;AAkB7C;;;;;;;GAOG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAIxC,EAA+B;IAC/B,IAAI,IAAI,CAAC,gBAAgB,KAAK,KAAK,EAAE,CAAC;QACrC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,mBAAmB,EAAE,CAAC;IACjE,CAAC;IACD,IAAI,IAAI,CAAC,gBAAgB,KAAK,IAAI,EAAE,CAAC;QACpC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,kBAAkB,EAAE,CAAC;IAC3D,CAAC;IACD,IAAI,IAAI,CAAC,KAAK,CAAC,oBAAoB,KAAK,IAAI,EAAE,CAAC;QAC9C,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,eAAe,EAAE,CAAC;IACxD,CAAC;IACD,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,KAAK,eAAe,EAAE,CAAC;QAC3D,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAC9D,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;IAC7C,IAAI,CAAC,WAAW,EAAE,CAAC;QAClB,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,2BAA2B,EAAE,CAAC;IACzE,CAAC;IACD,IAAI,WAAW,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACrC,OAAO;YACN,QAAQ,EAAE,SAAS;YACnB,UAAU,EAAE,0BAA0B;YACtC,aAAa,EAAE,WAAW,CAAC,aAAa;SACxC,CAAC;IACH,CAAC;IACD,IAAI,WAAW,CAAC,OAAO,KAAK,2BAA2B,IAAI,CAAC,yBAAyB,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5G,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,2BAA2B,EAAE,CAAC;IACzE,CAAC;IACD,OAAO;QACN,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,CAAC,OAAO,EAAE;QAC1C,UAAU,EAAE,kBAAkB;KAC9B,CAAC;AAAA,CACF","sourcesContent":["import { type Api, isTextToolProtocolVariant, type Model, type SimpleStreamOptions } from \"@caupulican/pi-ai\";\nimport type { ModelAdaptationProfile } from \"./models/adaptation-store.ts\";\n\nexport const MODEL_TOOL_PROTOCOL_VERSION = 1;\n\nexport type ModelToolProtocolReasonCode =\n\t| \"settings_disabled\"\n\t| \"settings_enabled\"\n\t| \"model_enabled\"\n\t| \"probe_calibrated\"\n\t| \"probe_calibration_missing\"\n\t| \"probe_calibration_failed\"\n\t| \"probe_calibration_invalid\"\n\t| \"native_default\";\n\nexport interface ModelToolProtocolResolution {\n\tprotocol: SimpleStreamOptions[\"textToolCallProtocol\"];\n\treasonCode: ModelToolProtocolReasonCode;\n\tvariantsTried?: readonly string[];\n}\n\n/**\n * Resolve the effective tool-call transport for any model and execution lane.\n *\n * Explicit settings win, followed by model metadata and then graded probe evidence. A probe-driven\n * text protocol is usable only with a current, recognized calibration; otherwise the model stays on\n * native calls for this turn. Callers use the reason code for diagnostics, but never reimplement the\n * precedence or silently substitute the default dialect.\n */\nexport function resolveModelToolProtocol(args: {\n\tmodel: Pick<Model<Api>, \"textToolCallProtocol\">;\n\tsettingsOverride?: boolean;\n\tadaptation: Pick<ModelAdaptationProfile, \"protocol\" | \"toolProbe\">;\n}): ModelToolProtocolResolution {\n\tif (args.settingsOverride === false) {\n\t\treturn { protocol: undefined, reasonCode: \"settings_disabled\" };\n\t}\n\tif (args.settingsOverride === true) {\n\t\treturn { protocol: true, reasonCode: \"settings_enabled\" };\n\t}\n\tif (args.model.textToolCallProtocol === true) {\n\t\treturn { protocol: true, reasonCode: \"model_enabled\" };\n\t}\n\tif (args.adaptation.toolProbe?.status !== \"text-protocol\") {\n\t\treturn { protocol: undefined, reasonCode: \"native_default\" };\n\t}\n\n\tconst calibration = args.adaptation.protocol;\n\tif (!calibration) {\n\t\treturn { protocol: undefined, reasonCode: \"probe_calibration_missing\" };\n\t}\n\tif (calibration.status === \"failed\") {\n\t\treturn {\n\t\t\tprotocol: undefined,\n\t\t\treasonCode: \"probe_calibration_failed\",\n\t\t\tvariantsTried: calibration.variantsTried,\n\t\t};\n\t}\n\tif (calibration.version !== MODEL_TOOL_PROTOCOL_VERSION || !isTextToolProtocolVariant(calibration.variant)) {\n\t\treturn { protocol: undefined, reasonCode: \"probe_calibration_invalid\" };\n\t}\n\treturn {\n\t\tprotocol: { variant: calibration.variant },\n\t\treasonCode: \"probe_calibrated\",\n\t};\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type HostFingerprint } from "./
|
|
1
|
+
import { type HostFingerprint } from "./host-state-store.ts";
|
|
2
2
|
import { type ModelPerfProfile, type ModelPerfSample } from "./perf-profile.ts";
|
|
3
3
|
export interface ModelAdaptationRule {
|
|
4
4
|
mode: string;
|
|
@@ -46,9 +46,7 @@ export interface StoredModelAdaptation {
|
|
|
46
46
|
host: HostFingerprint;
|
|
47
47
|
}
|
|
48
48
|
export declare class ModelAdaptationStore {
|
|
49
|
-
private readonly
|
|
50
|
-
private readonly fingerprint;
|
|
51
|
-
private readonly readOnly;
|
|
49
|
+
private readonly storage;
|
|
52
50
|
constructor(filePath: string, options?: {
|
|
53
51
|
fingerprint?: () => HostFingerprint;
|
|
54
52
|
readOnly?: boolean;
|
|
@@ -57,13 +55,13 @@ export declare class ModelAdaptationStore {
|
|
|
57
55
|
fingerprint?: () => HostFingerprint;
|
|
58
56
|
readOnly?: boolean;
|
|
59
57
|
}): ModelAdaptationStore;
|
|
60
|
-
private load;
|
|
61
|
-
private write;
|
|
62
58
|
/**
|
|
63
59
|
* Load-mutate-write under a single exclusive lock so two concurrent stores (e.g. two sessions
|
|
64
60
|
* sharing an agentDir) can't both read the old file and clobber each other's write.
|
|
65
61
|
*/
|
|
66
62
|
private store;
|
|
63
|
+
/** Keep the complete profile read-modify-write transaction under the host-state lock. */
|
|
64
|
+
private mutateProfile;
|
|
67
65
|
/** Persist the profile for a model on the CURRENT host. Best-effort, returns the entry. */
|
|
68
66
|
save(model: string, profile: ModelAdaptationProfile, at?: string): StoredModelAdaptation;
|
|
69
67
|
/** Profile for a model on the current host; prunes retired rules before returning. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adaptation-store.d.ts","sourceRoot":"","sources":["../../../src/core/models/adaptation-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { stateFile } from \"../agent-paths.ts\";\nimport { isWorkerSession } from \"../session-role.ts\";\nimport { withFileLockSync, writeFileAtomicSync } from \"../util/atomic-file.ts\";\nimport { currentHostFingerprint, type HostFingerprint } from \"./fitness-store.ts\";\nimport {\n\thasUsableModelPerfSample,\n\tisModelPerfProfile,\n\ttype ModelPerfProfile,\n\ttype ModelPerfSample,\n\tupdateModelPerfProfile,\n} from \"./perf-profile.ts\";\n\nconst STORE_VERSION = 1;\nconst MAX_RULES_PER_MODEL = 5;\nconst RETIRE_AFTER_MS = 30 * 24 * 60 * 60 * 1000;\n\nexport interface ModelAdaptationRule {\n\tmode: string;\n\ttext: string;\n\taddedAt: string;\n\tlastFiredAt: string;\n}\n\nexport type ModelProtocolCalibration =\n\t| {\n\t\t\tversion: number;\n\t\t\tstatus?: \"calibrated\";\n\t\t\tvariant: string;\n\t\t\tcalibratedAt: string;\n\t }\n\t| {\n\t\t\tversion: number;\n\t\t\tstatus: \"failed\";\n\t\t\tattemptedAt: string;\n\t\t\tvariantsTried: string[];\n\t };\n\nexport type ModelToolProbeVerdict = \"native\" | \"text-protocol\" | \"none\";\nexport type NativeToolProbeGrade = \"task\" | \"echo-only\" | \"absent\";\n\nexport interface ModelToolProbe {\n\tversion: number;\n\tstatus: ModelToolProbeVerdict;\n\tprobedAt: string;\n\tvariant?: string;\n\tnativeGrade?: NativeToolProbeGrade;\n\tdiagnostic?: string;\n}\n\nexport interface ModelTeachStats {\n\ttaught: number;\n\trecurrenceBefore: number;\n\trecurrenceAfter: number;\n}\n\nexport interface ModelAdaptationProfile {\n\trules: ModelAdaptationRule[];\n\tprotocol?: ModelProtocolCalibration;\n\ttoolProbe?: ModelToolProbe;\n\tperf?: ModelPerfProfile;\n\tteachStats: Record<string, ModelTeachStats>;\n}\n\nexport interface StoredModelAdaptation {\n\tmodel: string;\n\tprofile: ModelAdaptationProfile;\n\tat: string;\n\thost: HostFingerprint;\n}\n\ninterface AdaptationStoreFile {\n\tversion: 1;\n\t/** hostId -> modelRef -> latest stored adaptation profile. */\n\thosts: Record<string, Record<string, StoredModelAdaptation>>;\n}\n\nfunction emptyProfile(): ModelAdaptationProfile {\n\treturn { rules: [], teachStats: {} };\n}\n\nfunction normalizeProfile(profile: Partial<ModelAdaptationProfile> | undefined): ModelAdaptationProfile {\n\treturn {\n\t\trules: Array.isArray(profile?.rules) ? profile.rules.filter(isRule) : [],\n\t\t...(isProtocol(profile?.protocol) && { protocol: profile.protocol }),\n\t\t...(isToolProbe(profile?.toolProbe) && { toolProbe: profile.toolProbe }),\n\t\t...(isModelPerfProfile(profile?.perf) && { perf: profile.perf }),\n\t\tteachStats: isRecord(profile?.teachStats) ? filterTeachStats(profile.teachStats) : {},\n\t};\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isRule(value: unknown): value is ModelAdaptationRule {\n\treturn (\n\t\tisRecord(value) &&\n\t\ttypeof value.mode === \"string\" &&\n\t\ttypeof value.text === \"string\" &&\n\t\ttypeof value.addedAt === \"string\" &&\n\t\ttypeof value.lastFiredAt === \"string\"\n\t);\n}\n\nfunction isProtocol(value: unknown): value is ModelProtocolCalibration {\n\tif (!isRecord(value) || typeof value.version !== \"number\") return false;\n\tif (value.status === \"failed\") {\n\t\treturn (\n\t\t\ttypeof value.attemptedAt === \"string\" &&\n\t\t\tArray.isArray(value.variantsTried) &&\n\t\t\tvalue.variantsTried.every((variant) => typeof variant === \"string\")\n\t\t);\n\t}\n\treturn (\n\t\t(value.status === undefined || value.status === \"calibrated\") &&\n\t\ttypeof value.variant === \"string\" &&\n\t\ttypeof value.calibratedAt === \"string\"\n\t);\n}\n\nfunction isToolProbe(value: unknown): value is ModelToolProbe {\n\treturn (\n\t\tisRecord(value) &&\n\t\ttypeof value.version === \"number\" &&\n\t\t(value.status === \"native\" || value.status === \"text-protocol\" || value.status === \"none\") &&\n\t\ttypeof value.probedAt === \"string\" &&\n\t\t(value.variant === undefined || typeof value.variant === \"string\") &&\n\t\t(value.nativeGrade === undefined ||\n\t\t\tvalue.nativeGrade === \"task\" ||\n\t\t\tvalue.nativeGrade === \"echo-only\" ||\n\t\t\tvalue.nativeGrade === \"absent\") &&\n\t\t(value.diagnostic === undefined || typeof value.diagnostic === \"string\")\n\t);\n}\n\nfunction isTeachStats(value: unknown): value is ModelTeachStats {\n\treturn (\n\t\tisRecord(value) &&\n\t\ttypeof value.taught === \"number\" &&\n\t\ttypeof value.recurrenceBefore === \"number\" &&\n\t\ttypeof value.recurrenceAfter === \"number\"\n\t);\n}\n\nfunction filterTeachStats(value: Record<string, unknown>): Record<string, ModelTeachStats> {\n\treturn Object.fromEntries(\n\t\tObject.entries(value).filter((entry): entry is [string, ModelTeachStats] => isTeachStats(entry[1])),\n\t);\n}\n\nfunction ruleRecency(rule: ModelAdaptationRule): number {\n\tconst lastFired = Date.parse(rule.lastFiredAt);\n\tif (Number.isFinite(lastFired)) return lastFired;\n\tconst added = Date.parse(rule.addedAt);\n\treturn Number.isFinite(added) ? added : 0;\n}\n\n/**\n * Minimum post-rule recurrences before efficacy can retire a rule early — a single relapse is\n * noise, not proof the rule stopped working.\n */\nconst MIN_RECURRENCE_AFTER_FOR_EFFICACY = 2;\n\n/**\n * Efficacy-based early retirement. `agent-session.ts`'s `_handleModelAdaptationTelemetry` bumps\n * `recurrenceBefore` each time a failure mode recurs BEFORE a standing rule exists for it (the\n * baseline that earned the rule), then switches to bumping `recurrenceAfter` each time the SAME mode\n * recurs AFTER the rule fired. So a rule that is actually working keeps `recurrenceAfter` low relative\n * to its own pre-rule baseline; a rule that has caught up to (or exceeded) that baseline has\n * demonstrably stopped reducing recurrence and should retire before the time-based outer bound.\n */\nfunction isRuleEffective(stats: ModelTeachStats | undefined): boolean {\n\tif (!stats || stats.recurrenceAfter < MIN_RECURRENCE_AFTER_FOR_EFFICACY) return true; // not enough post-rule evidence yet\n\treturn stats.recurrenceAfter < stats.recurrenceBefore;\n}\n\n/**\n * Prune rules past the time-based outer bound (`RETIRE_AFTER_MS`, always enforced) OR past efficacy\n * (a rule that stopped reducing recurrence retires early; a rule that keeps helping persists until\n * the outer bound).\n */\nfunction pruneRetiredRules(\n\trules: readonly ModelAdaptationRule[],\n\tteachStats: Record<string, ModelTeachStats>,\n\tnow: Date,\n): ModelAdaptationRule[] {\n\tconst cutoff = now.getTime() - RETIRE_AFTER_MS;\n\treturn rules.filter((rule) => ruleRecency(rule) >= cutoff && isRuleEffective(teachStats[rule.mode]));\n}\n\nfunction enforceRuleCap(rules: readonly ModelAdaptationRule[]): ModelAdaptationRule[] {\n\tif (rules.length <= MAX_RULES_PER_MODEL) return [...rules];\n\treturn [...rules].sort((a, b) => ruleRecency(b) - ruleRecency(a)).slice(0, MAX_RULES_PER_MODEL);\n}\n\nfunction mergeRule(rules: readonly ModelAdaptationRule[], rule: ModelAdaptationRule): ModelAdaptationRule[] {\n\tconst withoutSameMode = rules.filter((existing) => existing.mode !== rule.mode);\n\treturn enforceRuleCap([...withoutSameMode, rule]);\n}\n\nexport class ModelAdaptationStore {\n\tprivate readonly filePath: string;\n\tprivate readonly fingerprint: () => HostFingerprint;\n\tprivate readonly readOnly: boolean;\n\n\tconstructor(filePath: string, options?: { fingerprint?: () => HostFingerprint; readOnly?: boolean }) {\n\t\tthis.filePath = filePath;\n\t\tthis.fingerprint = options?.fingerprint ?? currentHostFingerprint;\n\t\tthis.readOnly = options?.readOnly ?? isWorkerSession();\n\t}\n\n\tstatic forAgentDir(\n\t\tagentDir: string,\n\t\toptions?: { fingerprint?: () => HostFingerprint; readOnly?: boolean },\n\t): ModelAdaptationStore {\n\t\treturn new ModelAdaptationStore(stateFile(agentDir, \"model-adaptation.json\"), options);\n\t}\n\n\tprivate load(): AdaptationStoreFile {\n\t\ttry {\n\t\t\tif (!existsSync(this.filePath)) return { version: STORE_VERSION, hosts: {} };\n\t\t\tconst parsed = JSON.parse(readFileSync(this.filePath, \"utf-8\")) as AdaptationStoreFile;\n\t\t\tif (parsed && parsed.version === STORE_VERSION && parsed.hosts && typeof parsed.hosts === \"object\") {\n\t\t\t\treturn parsed;\n\t\t\t}\n\t\t} catch {\n\t\t\t// Unreadable/corrupt store: start fresh in memory; the next save rewrites the file.\n\t\t}\n\t\treturn { version: STORE_VERSION, hosts: {} };\n\t}\n\n\tprivate write(file: AdaptationStoreFile): void {\n\t\twriteFileAtomicSync(this.filePath, `${JSON.stringify(file, null, \"\\t\")}\\n`);\n\t}\n\n\t/**\n\t * Load-mutate-write under a single exclusive lock so two concurrent stores (e.g. two sessions\n\t * sharing an agentDir) can't both read the old file and clobber each other's write.\n\t */\n\tprivate store(model: string, profile: ModelAdaptationProfile, at: string): StoredModelAdaptation {\n\t\tconst host = this.fingerprint();\n\t\tconst entry: StoredModelAdaptation = { model, profile: normalizeProfile(profile), at, host };\n\t\t// Zero-footprint (worker session): no lock, no dir, no write -- `save()`/`get()`'s\n\t\t// prune-write path both funnel through here and get the normally-computed entry back.\n\t\tif (this.readOnly) return entry;\n\t\twithFileLockSync(this.filePath, () => {\n\t\t\tconst file = this.load();\n\t\t\tfile.hosts[host.id] = { ...(file.hosts[host.id] ?? {}), [model]: entry };\n\t\t\tthis.write(file);\n\t\t});\n\t\treturn entry;\n\t}\n\n\t/** Persist the profile for a model on the CURRENT host. Best-effort, returns the entry. */\n\tsave(model: string, profile: ModelAdaptationProfile, at?: string): StoredModelAdaptation {\n\t\treturn this.store(model, profile, at ?? new Date().toISOString());\n\t}\n\n\t/** Profile for a model on the current host; prunes retired rules before returning. */\n\tget(model: string, now: Date = new Date()): ModelAdaptationProfile {\n\t\tconst host = this.fingerprint();\n\t\tconst file = this.load();\n\t\tconst entry = file.hosts[host.id]?.[model];\n\t\tif (!entry) return emptyProfile();\n\t\tconst profile = normalizeProfile(entry.profile);\n\t\tconst prunedRules = pruneRetiredRules(profile.rules, profile.teachStats, now);\n\t\tif (prunedRules.length !== profile.rules.length) {\n\t\t\treturn this.store(model, { ...profile, rules: prunedRules }, now.toISOString()).profile;\n\t\t}\n\t\treturn profile;\n\t}\n\n\t/** Add or replace one standing rule, enforcing the per-model cap. */\n\taddRule(\n\t\tmodel: string,\n\t\trule: { mode: string; text: string; addedAt?: string; lastFiredAt?: string },\n\t\tnow = new Date(),\n\t): StoredModelAdaptation {\n\t\tconst profile = this.get(model, now);\n\t\tconst at = now.toISOString();\n\t\tconst nextRule: ModelAdaptationRule = {\n\t\t\tmode: rule.mode,\n\t\t\ttext: rule.text,\n\t\t\taddedAt: rule.addedAt ?? at,\n\t\t\tlastFiredAt: rule.lastFiredAt ?? at,\n\t\t};\n\t\treturn this.store(model, { ...profile, rules: mergeRule(profile.rules, nextRule) }, at);\n\t}\n\n\tremoveRule(model: string, mode: string, at = new Date()): boolean {\n\t\tconst profile = this.get(model, at);\n\t\tconst rules = profile.rules.filter((rule) => rule.mode !== mode);\n\t\tif (rules.length === profile.rules.length) return false;\n\t\tthis.store(model, { ...profile, rules }, at.toISOString());\n\t\treturn true;\n\t}\n\n\t/** Update last-fired recency for an existing rule. No-op when absent. */\n\tmarkRuleFired(model: string, mode: string, at = new Date()): StoredModelAdaptation | undefined {\n\t\tconst profile = this.get(model, at);\n\t\tconst rules = profile.rules.map((rule) =>\n\t\t\trule.mode === mode ? { ...rule, lastFiredAt: at.toISOString() } : rule,\n\t\t);\n\t\tif (rules.every((rule, index) => rule === profile.rules[index])) return undefined;\n\t\treturn this.store(model, { ...profile, rules }, at.toISOString());\n\t}\n\n\tsetProtocol(model: string, protocol: ModelProtocolCalibration, at?: string): StoredModelAdaptation {\n\t\tconst now = at ?? (protocol.status === \"failed\" ? protocol.attemptedAt : protocol.calibratedAt);\n\t\tconst profile = this.get(model, new Date(now));\n\t\treturn this.store(model, { ...profile, protocol }, now);\n\t}\n\n\tsetToolProbe(model: string, toolProbe: ModelToolProbe, at?: string): StoredModelAdaptation {\n\t\tconst now = at ?? toolProbe.probedAt;\n\t\tconst profile = this.get(model, new Date(now));\n\t\treturn this.store(model, { ...profile, toolProbe }, now);\n\t}\n\n\trecordPerfSample(model: string, sample: ModelPerfSample, at?: string): StoredModelAdaptation | undefined {\n\t\tif (!hasUsableModelPerfSample(sample)) return undefined;\n\t\tconst now = at ?? sample.at ?? new Date().toISOString();\n\t\tconst profile = this.get(model, new Date(now));\n\t\tconst perf = updateModelPerfProfile(profile.perf, sample, now);\n\t\tif (!perf) return undefined;\n\t\treturn this.store(model, { ...profile, perf }, now);\n\t}\n\n\tremoveProtocol(model: string, at = new Date()): boolean {\n\t\tconst profile = this.get(model, at);\n\t\tif (!profile.protocol) return false;\n\t\tconst { protocol: _protocol, ...rest } = profile;\n\t\tthis.store(model, rest, at.toISOString());\n\t\treturn true;\n\t}\n\n\tsetTeachStats(model: string, mode: string, stats: ModelTeachStats, at?: string): StoredModelAdaptation {\n\t\tconst now = at ?? new Date().toISOString();\n\t\tconst profile = this.get(model, new Date(now));\n\t\treturn this.store(model, { ...profile, teachStats: { ...profile.teachStats, [mode]: stats } }, now);\n\t}\n\n\t/** Profiles for the current host (default) or an explicit host id. */\n\tgetForHost(hostId?: string): StoredModelAdaptation[] {\n\t\tconst file = this.load();\n\t\treturn Object.values(file.hosts[hostId ?? this.fingerprint().id] ?? {}).map((entry) => ({\n\t\t\t...entry,\n\t\t\tprofile: normalizeProfile(entry.profile),\n\t\t}));\n\t}\n\n\t/** Every stored profile across all hosts (for cross-machine comparisons). */\n\tgetAll(): StoredModelAdaptation[] {\n\t\tconst file = this.load();\n\t\treturn Object.values(file.hosts).flatMap((models) =>\n\t\t\tObject.values(models).map((entry) => ({ ...entry, profile: normalizeProfile(entry.profile) })),\n\t\t);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"adaptation-store.d.ts","sourceRoot":"","sources":["../../../src/core/models/adaptation-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { stateFile } from \"../agent-paths.ts\";\nimport { isWorkerSession } from \"../session-role.ts\";\nimport { isRecordObject } from \"../util/value-guards.ts\";\nimport { type HostFingerprint, HostStateStore, isHostFingerprint } from \"./host-state-store.ts\";\nimport {\n\thasUsableModelPerfSample,\n\tisModelPerfProfile,\n\ttype ModelPerfProfile,\n\ttype ModelPerfSample,\n\tupdateModelPerfProfile,\n} from \"./perf-profile.ts\";\n\nconst STORE_VERSION = 1;\nconst MAX_RULES_PER_MODEL = 5;\nconst RETIRE_AFTER_MS = 30 * 24 * 60 * 60 * 1000;\n\nexport interface ModelAdaptationRule {\n\tmode: string;\n\ttext: string;\n\taddedAt: string;\n\tlastFiredAt: string;\n}\n\nexport type ModelProtocolCalibration =\n\t| {\n\t\t\tversion: number;\n\t\t\tstatus?: \"calibrated\";\n\t\t\tvariant: string;\n\t\t\tcalibratedAt: string;\n\t }\n\t| {\n\t\t\tversion: number;\n\t\t\tstatus: \"failed\";\n\t\t\tattemptedAt: string;\n\t\t\tvariantsTried: string[];\n\t };\n\nexport type ModelToolProbeVerdict = \"native\" | \"text-protocol\" | \"none\";\nexport type NativeToolProbeGrade = \"task\" | \"echo-only\" | \"absent\";\n\nexport interface ModelToolProbe {\n\tversion: number;\n\tstatus: ModelToolProbeVerdict;\n\tprobedAt: string;\n\tvariant?: string;\n\tnativeGrade?: NativeToolProbeGrade;\n\tdiagnostic?: string;\n}\n\nexport interface ModelTeachStats {\n\ttaught: number;\n\trecurrenceBefore: number;\n\trecurrenceAfter: number;\n}\n\nexport interface ModelAdaptationProfile {\n\trules: ModelAdaptationRule[];\n\tprotocol?: ModelProtocolCalibration;\n\ttoolProbe?: ModelToolProbe;\n\tperf?: ModelPerfProfile;\n\tteachStats: Record<string, ModelTeachStats>;\n}\n\nexport interface StoredModelAdaptation {\n\tmodel: string;\n\tprofile: ModelAdaptationProfile;\n\tat: string;\n\thost: HostFingerprint;\n}\n\ninterface ProfileMutation {\n\tprofile: ModelAdaptationProfile;\n\tentry?: StoredModelAdaptation;\n\tapplied: boolean;\n}\n\nfunction emptyProfile(): ModelAdaptationProfile {\n\treturn { rules: [], teachStats: {} };\n}\n\nfunction normalizeProfile(profile: Partial<ModelAdaptationProfile> | undefined): ModelAdaptationProfile {\n\treturn {\n\t\trules: Array.isArray(profile?.rules) ? profile.rules.filter(isRule) : [],\n\t\t...(isProtocol(profile?.protocol) && { protocol: profile.protocol }),\n\t\t...(isToolProbe(profile?.toolProbe) && { toolProbe: profile.toolProbe }),\n\t\t...(isModelPerfProfile(profile?.perf) && { perf: profile.perf }),\n\t\tteachStats: isRecordObject(profile?.teachStats) ? filterTeachStats(profile.teachStats) : {},\n\t};\n}\n\nfunction isRule(value: unknown): value is ModelAdaptationRule {\n\treturn (\n\t\tisRecordObject(value) &&\n\t\ttypeof value.mode === \"string\" &&\n\t\ttypeof value.text === \"string\" &&\n\t\ttypeof value.addedAt === \"string\" &&\n\t\ttypeof value.lastFiredAt === \"string\"\n\t);\n}\n\nfunction isProtocol(value: unknown): value is ModelProtocolCalibration {\n\tif (!isRecordObject(value) || typeof value.version !== \"number\") return false;\n\tif (value.status === \"failed\") {\n\t\treturn (\n\t\t\ttypeof value.attemptedAt === \"string\" &&\n\t\t\tArray.isArray(value.variantsTried) &&\n\t\t\tvalue.variantsTried.every((variant) => typeof variant === \"string\")\n\t\t);\n\t}\n\treturn (\n\t\t(value.status === undefined || value.status === \"calibrated\") &&\n\t\ttypeof value.variant === \"string\" &&\n\t\ttypeof value.calibratedAt === \"string\"\n\t);\n}\n\nfunction isToolProbe(value: unknown): value is ModelToolProbe {\n\treturn (\n\t\tisRecordObject(value) &&\n\t\ttypeof value.version === \"number\" &&\n\t\t(value.status === \"native\" || value.status === \"text-protocol\" || value.status === \"none\") &&\n\t\ttypeof value.probedAt === \"string\" &&\n\t\t(value.variant === undefined || typeof value.variant === \"string\") &&\n\t\t(value.nativeGrade === undefined ||\n\t\t\tvalue.nativeGrade === \"task\" ||\n\t\t\tvalue.nativeGrade === \"echo-only\" ||\n\t\t\tvalue.nativeGrade === \"absent\") &&\n\t\t(value.diagnostic === undefined || typeof value.diagnostic === \"string\")\n\t);\n}\n\nfunction isTeachStats(value: unknown): value is ModelTeachStats {\n\treturn (\n\t\tisRecordObject(value) &&\n\t\ttypeof value.taught === \"number\" &&\n\t\ttypeof value.recurrenceBefore === \"number\" &&\n\t\ttypeof value.recurrenceAfter === \"number\"\n\t);\n}\n\nfunction filterTeachStats(value: Record<string, unknown>): Record<string, ModelTeachStats> {\n\treturn Object.fromEntries(\n\t\tObject.entries(value).filter((entry): entry is [string, ModelTeachStats] => isTeachStats(entry[1])),\n\t);\n}\n\nfunction ruleRecency(rule: ModelAdaptationRule): number {\n\tconst lastFired = Date.parse(rule.lastFiredAt);\n\tif (Number.isFinite(lastFired)) return lastFired;\n\tconst added = Date.parse(rule.addedAt);\n\treturn Number.isFinite(added) ? added : 0;\n}\n\n/**\n * Minimum post-rule recurrences before efficacy can retire a rule early — a single relapse is\n * noise, not proof the rule stopped working.\n */\nconst MIN_RECURRENCE_AFTER_FOR_EFFICACY = 2;\n\n/**\n * Efficacy-based early retirement. `agent-session.ts`'s `_handleModelAdaptationTelemetry` bumps\n * `recurrenceBefore` each time a failure mode recurs BEFORE a standing rule exists for it (the\n * baseline that earned the rule), then switches to bumping `recurrenceAfter` each time the SAME mode\n * recurs AFTER the rule fired. So a rule that is actually working keeps `recurrenceAfter` low relative\n * to its own pre-rule baseline; a rule that has caught up to (or exceeded) that baseline has\n * demonstrably stopped reducing recurrence and should retire before the time-based outer bound.\n */\nfunction isRuleEffective(stats: ModelTeachStats | undefined): boolean {\n\tif (!stats || stats.recurrenceAfter < MIN_RECURRENCE_AFTER_FOR_EFFICACY) return true; // not enough post-rule evidence yet\n\treturn stats.recurrenceAfter < stats.recurrenceBefore;\n}\n\n/**\n * Prune rules past the time-based outer bound (`RETIRE_AFTER_MS`, always enforced) OR past efficacy\n * (a rule that stopped reducing recurrence retires early; a rule that keeps helping persists until\n * the outer bound).\n */\nfunction pruneRetiredRules(\n\trules: readonly ModelAdaptationRule[],\n\tteachStats: Record<string, ModelTeachStats>,\n\tnow: Date,\n): ModelAdaptationRule[] {\n\tconst cutoff = now.getTime() - RETIRE_AFTER_MS;\n\treturn rules.filter((rule) => ruleRecency(rule) >= cutoff && isRuleEffective(teachStats[rule.mode]));\n}\n\nfunction enforceRuleCap(rules: readonly ModelAdaptationRule[]): ModelAdaptationRule[] {\n\tif (rules.length <= MAX_RULES_PER_MODEL) return [...rules];\n\treturn [...rules].sort((a, b) => ruleRecency(b) - ruleRecency(a)).slice(0, MAX_RULES_PER_MODEL);\n}\n\nfunction mergeRule(rules: readonly ModelAdaptationRule[], rule: ModelAdaptationRule): ModelAdaptationRule[] {\n\tconst withoutSameMode = rules.filter((existing) => existing.mode !== rule.mode);\n\treturn enforceRuleCap([...withoutSameMode, rule]);\n}\n\nfunction parseAdaptationHost(value: unknown, hostId: string): Record<string, StoredModelAdaptation> | undefined {\n\tif (!isRecordObject(value)) return undefined;\n\tconst profiles: Record<string, StoredModelAdaptation> = {};\n\tfor (const [model, candidate] of Object.entries(value)) {\n\t\tif (\n\t\t\t!isRecordObject(candidate) ||\n\t\t\tcandidate.model !== model ||\n\t\t\ttypeof candidate.at !== \"string\" ||\n\t\t\t!isHostFingerprint(candidate.host) ||\n\t\t\tcandidate.host.id !== hostId ||\n\t\t\t!isRecordObject(candidate.profile)\n\t\t)\n\t\t\tcontinue;\n\t\tprofiles[model] = {\n\t\t\tmodel,\n\t\t\tprofile: normalizeProfile(candidate.profile),\n\t\t\tat: candidate.at,\n\t\t\thost: candidate.host,\n\t\t};\n\t}\n\treturn profiles;\n}\n\nexport class ModelAdaptationStore {\n\tprivate readonly storage: HostStateStore<Record<string, StoredModelAdaptation>>;\n\n\tconstructor(filePath: string, options?: { fingerprint?: () => HostFingerprint; readOnly?: boolean }) {\n\t\tthis.storage = new HostStateStore({\n\t\t\tfilePath,\n\t\t\tversion: STORE_VERSION,\n\t\t\tfingerprint: options?.fingerprint,\n\t\t\treadOnly: options?.readOnly ?? isWorkerSession(),\n\t\t\tparseHost: parseAdaptationHost,\n\t\t});\n\t}\n\n\tstatic forAgentDir(\n\t\tagentDir: string,\n\t\toptions?: { fingerprint?: () => HostFingerprint; readOnly?: boolean },\n\t): ModelAdaptationStore {\n\t\treturn new ModelAdaptationStore(stateFile(agentDir, \"model-adaptation.json\"), options);\n\t}\n\n\t/**\n\t * Load-mutate-write under a single exclusive lock so two concurrent stores (e.g. two sessions\n\t * sharing an agentDir) can't both read the old file and clobber each other's write.\n\t */\n\tprivate store(model: string, profile: ModelAdaptationProfile, at: string): StoredModelAdaptation {\n\t\treturn this.storage.mutateCurrentHost(\n\t\t\t() => ({}),\n\t\t\t(profiles, host) => {\n\t\t\t\tconst entry: StoredModelAdaptation = { model, profile: normalizeProfile(profile), at, host };\n\t\t\t\tprofiles[model] = entry;\n\t\t\t\treturn { result: entry, changed: true };\n\t\t\t},\n\t\t);\n\t}\n\n\t/** Keep the complete profile read-modify-write transaction under the host-state lock. */\n\tprivate mutateProfile(\n\t\tmodel: string,\n\t\tnow: Date,\n\t\tmutate: (profile: ModelAdaptationProfile) => ModelAdaptationProfile | undefined,\n\t\tstoredAt = now.toISOString(),\n\t): ProfileMutation {\n\t\treturn this.storage.mutateCurrentHost<ProfileMutation>(\n\t\t\t() => ({}),\n\t\t\t(profiles, host) => {\n\t\t\t\tconst current = normalizeProfile(profiles[model]?.profile);\n\t\t\t\tconst activeRules = pruneRetiredRules(current.rules, current.teachStats, now);\n\t\t\t\tconst pruned = activeRules.length !== current.rules.length;\n\t\t\t\tconst active = pruned ? { ...current, rules: activeRules } : current;\n\t\t\t\tconst requested = mutate(active);\n\t\t\t\tconst applied = requested !== undefined;\n\t\t\t\tif (!applied && !pruned) {\n\t\t\t\t\treturn { result: { profile: active, applied: false }, changed: false };\n\t\t\t\t}\n\t\t\t\tconst profile = normalizeProfile(requested ?? active);\n\t\t\t\tconst entry: StoredModelAdaptation = { model, profile, at: storedAt, host };\n\t\t\t\tprofiles[model] = entry;\n\t\t\t\treturn { result: { profile, entry, applied }, changed: true };\n\t\t\t},\n\t\t);\n\t}\n\n\t/** Persist the profile for a model on the CURRENT host. Best-effort, returns the entry. */\n\tsave(model: string, profile: ModelAdaptationProfile, at?: string): StoredModelAdaptation {\n\t\treturn this.store(model, profile, at ?? new Date().toISOString());\n\t}\n\n\t/** Profile for a model on the current host; prunes retired rules before returning. */\n\tget(model: string, now: Date = new Date()): ModelAdaptationProfile {\n\t\tconst entry = this.storage.getHost()?.[model];\n\t\tif (!entry) return emptyProfile();\n\t\tconst profile = normalizeProfile(entry.profile);\n\t\tconst prunedRules = pruneRetiredRules(profile.rules, profile.teachStats, now);\n\t\tif (prunedRules.length !== profile.rules.length) {\n\t\t\treturn this.mutateProfile(model, now, () => undefined).profile;\n\t\t}\n\t\treturn profile;\n\t}\n\n\t/** Add or replace one standing rule, enforcing the per-model cap. */\n\taddRule(\n\t\tmodel: string,\n\t\trule: { mode: string; text: string; addedAt?: string; lastFiredAt?: string },\n\t\tnow = new Date(),\n\t): StoredModelAdaptation {\n\t\tconst at = now.toISOString();\n\t\tconst nextRule: ModelAdaptationRule = {\n\t\t\tmode: rule.mode,\n\t\t\ttext: rule.text,\n\t\t\taddedAt: rule.addedAt ?? at,\n\t\t\tlastFiredAt: rule.lastFiredAt ?? at,\n\t\t};\n\t\tconst result = this.mutateProfile(model, now, (profile) => ({\n\t\t\t...profile,\n\t\t\trules: mergeRule(profile.rules, nextRule),\n\t\t}));\n\t\treturn result.entry!;\n\t}\n\n\tremoveRule(model: string, mode: string, at = new Date()): boolean {\n\t\treturn this.mutateProfile(model, at, (profile) => {\n\t\t\tconst rules = profile.rules.filter((rule) => rule.mode !== mode);\n\t\t\treturn rules.length === profile.rules.length ? undefined : { ...profile, rules };\n\t\t}).applied;\n\t}\n\n\t/** Update last-fired recency for an existing rule. No-op when absent. */\n\tmarkRuleFired(model: string, mode: string, at = new Date()): StoredModelAdaptation | undefined {\n\t\tconst result = this.mutateProfile(model, at, (profile) => {\n\t\t\tconst rules = profile.rules.map((rule) =>\n\t\t\t\trule.mode === mode ? { ...rule, lastFiredAt: at.toISOString() } : rule,\n\t\t\t);\n\t\t\treturn rules.every((rule, index) => rule === profile.rules[index]) ? undefined : { ...profile, rules };\n\t\t});\n\t\treturn result.applied ? result.entry : undefined;\n\t}\n\n\tsetProtocol(model: string, protocol: ModelProtocolCalibration, at?: string): StoredModelAdaptation {\n\t\tconst now = at ?? (protocol.status === \"failed\" ? protocol.attemptedAt : protocol.calibratedAt);\n\t\treturn this.mutateProfile(model, new Date(now), (profile) => ({ ...profile, protocol }), now).entry!;\n\t}\n\n\tsetToolProbe(model: string, toolProbe: ModelToolProbe, at?: string): StoredModelAdaptation {\n\t\tconst now = at ?? toolProbe.probedAt;\n\t\treturn this.mutateProfile(model, new Date(now), (profile) => ({ ...profile, toolProbe }), now).entry!;\n\t}\n\n\trecordPerfSample(model: string, sample: ModelPerfSample, at?: string): StoredModelAdaptation | undefined {\n\t\tif (!hasUsableModelPerfSample(sample)) return undefined;\n\t\tconst now = at ?? sample.at ?? new Date().toISOString();\n\t\tconst result = this.mutateProfile(\n\t\t\tmodel,\n\t\t\tnew Date(now),\n\t\t\t(profile) => {\n\t\t\t\tconst perf = updateModelPerfProfile(profile.perf, sample, now);\n\t\t\t\treturn perf ? { ...profile, perf } : undefined;\n\t\t\t},\n\t\t\tnow,\n\t\t);\n\t\treturn result.applied ? result.entry : undefined;\n\t}\n\n\tremoveProtocol(model: string, at = new Date()): boolean {\n\t\treturn this.mutateProfile(model, at, (profile) => {\n\t\t\tif (!profile.protocol) return undefined;\n\t\t\tconst { protocol: _protocol, ...rest } = profile;\n\t\t\treturn rest;\n\t\t}).applied;\n\t}\n\n\tsetTeachStats(model: string, mode: string, stats: ModelTeachStats, at?: string): StoredModelAdaptation {\n\t\tconst now = at ?? new Date().toISOString();\n\t\treturn this.mutateProfile(\n\t\t\tmodel,\n\t\t\tnew Date(now),\n\t\t\t(profile) => ({\n\t\t\t\t...profile,\n\t\t\t\tteachStats: { ...profile.teachStats, [mode]: stats },\n\t\t\t}),\n\t\t\tnow,\n\t\t).entry!;\n\t}\n\n\t/** Profiles for the current host (default) or an explicit host id. */\n\tgetForHost(hostId?: string): StoredModelAdaptation[] {\n\t\treturn Object.values(this.storage.getHost(hostId) ?? {}).map((entry) => ({\n\t\t\t...entry,\n\t\t\tprofile: normalizeProfile(entry.profile),\n\t\t}));\n\t}\n\n\t/** Every stored profile across all hosts (for cross-machine comparisons). */\n\tgetAll(): StoredModelAdaptation[] {\n\t\treturn this.storage\n\t\t\t.getAllHosts()\n\t\t\t.flatMap((models) =>\n\t\t\t\tObject.values(models).map((entry) => ({ ...entry, profile: normalizeProfile(entry.profile) })),\n\t\t\t);\n\t}\n}\n"]}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
2
1
|
import { stateFile } from "../agent-paths.js";
|
|
3
2
|
import { isWorkerSession } from "../session-role.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { isRecordObject } from "../util/value-guards.js";
|
|
4
|
+
import { HostStateStore, isHostFingerprint } from "./host-state-store.js";
|
|
6
5
|
import { hasUsableModelPerfSample, isModelPerfProfile, updateModelPerfProfile, } from "./perf-profile.js";
|
|
7
6
|
const STORE_VERSION = 1;
|
|
8
7
|
const MAX_RULES_PER_MODEL = 5;
|
|
@@ -16,21 +15,18 @@ function normalizeProfile(profile) {
|
|
|
16
15
|
...(isProtocol(profile?.protocol) && { protocol: profile.protocol }),
|
|
17
16
|
...(isToolProbe(profile?.toolProbe) && { toolProbe: profile.toolProbe }),
|
|
18
17
|
...(isModelPerfProfile(profile?.perf) && { perf: profile.perf }),
|
|
19
|
-
teachStats:
|
|
18
|
+
teachStats: isRecordObject(profile?.teachStats) ? filterTeachStats(profile.teachStats) : {},
|
|
20
19
|
};
|
|
21
20
|
}
|
|
22
|
-
function isRecord(value) {
|
|
23
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24
|
-
}
|
|
25
21
|
function isRule(value) {
|
|
26
|
-
return (
|
|
22
|
+
return (isRecordObject(value) &&
|
|
27
23
|
typeof value.mode === "string" &&
|
|
28
24
|
typeof value.text === "string" &&
|
|
29
25
|
typeof value.addedAt === "string" &&
|
|
30
26
|
typeof value.lastFiredAt === "string");
|
|
31
27
|
}
|
|
32
28
|
function isProtocol(value) {
|
|
33
|
-
if (!
|
|
29
|
+
if (!isRecordObject(value) || typeof value.version !== "number")
|
|
34
30
|
return false;
|
|
35
31
|
if (value.status === "failed") {
|
|
36
32
|
return (typeof value.attemptedAt === "string" &&
|
|
@@ -42,7 +38,7 @@ function isProtocol(value) {
|
|
|
42
38
|
typeof value.calibratedAt === "string");
|
|
43
39
|
}
|
|
44
40
|
function isToolProbe(value) {
|
|
45
|
-
return (
|
|
41
|
+
return (isRecordObject(value) &&
|
|
46
42
|
typeof value.version === "number" &&
|
|
47
43
|
(value.status === "native" || value.status === "text-protocol" || value.status === "none") &&
|
|
48
44
|
typeof value.probedAt === "string" &&
|
|
@@ -54,7 +50,7 @@ function isToolProbe(value) {
|
|
|
54
50
|
(value.diagnostic === undefined || typeof value.diagnostic === "string"));
|
|
55
51
|
}
|
|
56
52
|
function isTeachStats(value) {
|
|
57
|
-
return (
|
|
53
|
+
return (isRecordObject(value) &&
|
|
58
54
|
typeof value.taught === "number" &&
|
|
59
55
|
typeof value.recurrenceBefore === "number" &&
|
|
60
56
|
typeof value.recurrenceAfter === "number");
|
|
@@ -105,52 +101,69 @@ function mergeRule(rules, rule) {
|
|
|
105
101
|
const withoutSameMode = rules.filter((existing) => existing.mode !== rule.mode);
|
|
106
102
|
return enforceRuleCap([...withoutSameMode, rule]);
|
|
107
103
|
}
|
|
104
|
+
function parseAdaptationHost(value, hostId) {
|
|
105
|
+
if (!isRecordObject(value))
|
|
106
|
+
return undefined;
|
|
107
|
+
const profiles = {};
|
|
108
|
+
for (const [model, candidate] of Object.entries(value)) {
|
|
109
|
+
if (!isRecordObject(candidate) ||
|
|
110
|
+
candidate.model !== model ||
|
|
111
|
+
typeof candidate.at !== "string" ||
|
|
112
|
+
!isHostFingerprint(candidate.host) ||
|
|
113
|
+
candidate.host.id !== hostId ||
|
|
114
|
+
!isRecordObject(candidate.profile))
|
|
115
|
+
continue;
|
|
116
|
+
profiles[model] = {
|
|
117
|
+
model,
|
|
118
|
+
profile: normalizeProfile(candidate.profile),
|
|
119
|
+
at: candidate.at,
|
|
120
|
+
host: candidate.host,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
return profiles;
|
|
124
|
+
}
|
|
108
125
|
export class ModelAdaptationStore {
|
|
109
|
-
|
|
110
|
-
fingerprint;
|
|
111
|
-
readOnly;
|
|
126
|
+
storage;
|
|
112
127
|
constructor(filePath, options) {
|
|
113
|
-
this.
|
|
114
|
-
|
|
115
|
-
|
|
128
|
+
this.storage = new HostStateStore({
|
|
129
|
+
filePath,
|
|
130
|
+
version: STORE_VERSION,
|
|
131
|
+
fingerprint: options?.fingerprint,
|
|
132
|
+
readOnly: options?.readOnly ?? isWorkerSession(),
|
|
133
|
+
parseHost: parseAdaptationHost,
|
|
134
|
+
});
|
|
116
135
|
}
|
|
117
136
|
static forAgentDir(agentDir, options) {
|
|
118
137
|
return new ModelAdaptationStore(stateFile(agentDir, "model-adaptation.json"), options);
|
|
119
138
|
}
|
|
120
|
-
load() {
|
|
121
|
-
try {
|
|
122
|
-
if (!existsSync(this.filePath))
|
|
123
|
-
return { version: STORE_VERSION, hosts: {} };
|
|
124
|
-
const parsed = JSON.parse(readFileSync(this.filePath, "utf-8"));
|
|
125
|
-
if (parsed && parsed.version === STORE_VERSION && parsed.hosts && typeof parsed.hosts === "object") {
|
|
126
|
-
return parsed;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
catch {
|
|
130
|
-
// Unreadable/corrupt store: start fresh in memory; the next save rewrites the file.
|
|
131
|
-
}
|
|
132
|
-
return { version: STORE_VERSION, hosts: {} };
|
|
133
|
-
}
|
|
134
|
-
write(file) {
|
|
135
|
-
writeFileAtomicSync(this.filePath, `${JSON.stringify(file, null, "\t")}\n`);
|
|
136
|
-
}
|
|
137
139
|
/**
|
|
138
140
|
* Load-mutate-write under a single exclusive lock so two concurrent stores (e.g. two sessions
|
|
139
141
|
* sharing an agentDir) can't both read the old file and clobber each other's write.
|
|
140
142
|
*/
|
|
141
143
|
store(model, profile, at) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
144
|
+
return this.storage.mutateCurrentHost(() => ({}), (profiles, host) => {
|
|
145
|
+
const entry = { model, profile: normalizeProfile(profile), at, host };
|
|
146
|
+
profiles[model] = entry;
|
|
147
|
+
return { result: entry, changed: true };
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
/** Keep the complete profile read-modify-write transaction under the host-state lock. */
|
|
151
|
+
mutateProfile(model, now, mutate, storedAt = now.toISOString()) {
|
|
152
|
+
return this.storage.mutateCurrentHost(() => ({}), (profiles, host) => {
|
|
153
|
+
const current = normalizeProfile(profiles[model]?.profile);
|
|
154
|
+
const activeRules = pruneRetiredRules(current.rules, current.teachStats, now);
|
|
155
|
+
const pruned = activeRules.length !== current.rules.length;
|
|
156
|
+
const active = pruned ? { ...current, rules: activeRules } : current;
|
|
157
|
+
const requested = mutate(active);
|
|
158
|
+
const applied = requested !== undefined;
|
|
159
|
+
if (!applied && !pruned) {
|
|
160
|
+
return { result: { profile: active, applied: false }, changed: false };
|
|
161
|
+
}
|
|
162
|
+
const profile = normalizeProfile(requested ?? active);
|
|
163
|
+
const entry = { model, profile, at: storedAt, host };
|
|
164
|
+
profiles[model] = entry;
|
|
165
|
+
return { result: { profile, entry, applied }, changed: true };
|
|
152
166
|
});
|
|
153
|
-
return entry;
|
|
154
167
|
}
|
|
155
168
|
/** Persist the profile for a model on the CURRENT host. Best-effort, returns the entry. */
|
|
156
169
|
save(model, profile, at) {
|
|
@@ -158,21 +171,18 @@ export class ModelAdaptationStore {
|
|
|
158
171
|
}
|
|
159
172
|
/** Profile for a model on the current host; prunes retired rules before returning. */
|
|
160
173
|
get(model, now = new Date()) {
|
|
161
|
-
const
|
|
162
|
-
const file = this.load();
|
|
163
|
-
const entry = file.hosts[host.id]?.[model];
|
|
174
|
+
const entry = this.storage.getHost()?.[model];
|
|
164
175
|
if (!entry)
|
|
165
176
|
return emptyProfile();
|
|
166
177
|
const profile = normalizeProfile(entry.profile);
|
|
167
178
|
const prunedRules = pruneRetiredRules(profile.rules, profile.teachStats, now);
|
|
168
179
|
if (prunedRules.length !== profile.rules.length) {
|
|
169
|
-
return this.
|
|
180
|
+
return this.mutateProfile(model, now, () => undefined).profile;
|
|
170
181
|
}
|
|
171
182
|
return profile;
|
|
172
183
|
}
|
|
173
184
|
/** Add or replace one standing rule, enforcing the per-model cap. */
|
|
174
185
|
addRule(model, rule, now = new Date()) {
|
|
175
|
-
const profile = this.get(model, now);
|
|
176
186
|
const at = now.toISOString();
|
|
177
187
|
const nextRule = {
|
|
178
188
|
mode: rule.mode,
|
|
@@ -180,69 +190,71 @@ export class ModelAdaptationStore {
|
|
|
180
190
|
addedAt: rule.addedAt ?? at,
|
|
181
191
|
lastFiredAt: rule.lastFiredAt ?? at,
|
|
182
192
|
};
|
|
183
|
-
|
|
193
|
+
const result = this.mutateProfile(model, now, (profile) => ({
|
|
194
|
+
...profile,
|
|
195
|
+
rules: mergeRule(profile.rules, nextRule),
|
|
196
|
+
}));
|
|
197
|
+
return result.entry;
|
|
184
198
|
}
|
|
185
199
|
removeRule(model, mode, at = new Date()) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
this.store(model, { ...profile, rules }, at.toISOString());
|
|
191
|
-
return true;
|
|
200
|
+
return this.mutateProfile(model, at, (profile) => {
|
|
201
|
+
const rules = profile.rules.filter((rule) => rule.mode !== mode);
|
|
202
|
+
return rules.length === profile.rules.length ? undefined : { ...profile, rules };
|
|
203
|
+
}).applied;
|
|
192
204
|
}
|
|
193
205
|
/** Update last-fired recency for an existing rule. No-op when absent. */
|
|
194
206
|
markRuleFired(model, mode, at = new Date()) {
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
return
|
|
207
|
+
const result = this.mutateProfile(model, at, (profile) => {
|
|
208
|
+
const rules = profile.rules.map((rule) => rule.mode === mode ? { ...rule, lastFiredAt: at.toISOString() } : rule);
|
|
209
|
+
return rules.every((rule, index) => rule === profile.rules[index]) ? undefined : { ...profile, rules };
|
|
210
|
+
});
|
|
211
|
+
return result.applied ? result.entry : undefined;
|
|
200
212
|
}
|
|
201
213
|
setProtocol(model, protocol, at) {
|
|
202
214
|
const now = at ?? (protocol.status === "failed" ? protocol.attemptedAt : protocol.calibratedAt);
|
|
203
|
-
|
|
204
|
-
return this.store(model, { ...profile, protocol }, now);
|
|
215
|
+
return this.mutateProfile(model, new Date(now), (profile) => ({ ...profile, protocol }), now).entry;
|
|
205
216
|
}
|
|
206
217
|
setToolProbe(model, toolProbe, at) {
|
|
207
218
|
const now = at ?? toolProbe.probedAt;
|
|
208
|
-
|
|
209
|
-
return this.store(model, { ...profile, toolProbe }, now);
|
|
219
|
+
return this.mutateProfile(model, new Date(now), (profile) => ({ ...profile, toolProbe }), now).entry;
|
|
210
220
|
}
|
|
211
221
|
recordPerfSample(model, sample, at) {
|
|
212
222
|
if (!hasUsableModelPerfSample(sample))
|
|
213
223
|
return undefined;
|
|
214
224
|
const now = at ?? sample.at ?? new Date().toISOString();
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
return
|
|
225
|
+
const result = this.mutateProfile(model, new Date(now), (profile) => {
|
|
226
|
+
const perf = updateModelPerfProfile(profile.perf, sample, now);
|
|
227
|
+
return perf ? { ...profile, perf } : undefined;
|
|
228
|
+
}, now);
|
|
229
|
+
return result.applied ? result.entry : undefined;
|
|
220
230
|
}
|
|
221
231
|
removeProtocol(model, at = new Date()) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
232
|
+
return this.mutateProfile(model, at, (profile) => {
|
|
233
|
+
if (!profile.protocol)
|
|
234
|
+
return undefined;
|
|
235
|
+
const { protocol: _protocol, ...rest } = profile;
|
|
236
|
+
return rest;
|
|
237
|
+
}).applied;
|
|
228
238
|
}
|
|
229
239
|
setTeachStats(model, mode, stats, at) {
|
|
230
240
|
const now = at ?? new Date().toISOString();
|
|
231
|
-
|
|
232
|
-
|
|
241
|
+
return this.mutateProfile(model, new Date(now), (profile) => ({
|
|
242
|
+
...profile,
|
|
243
|
+
teachStats: { ...profile.teachStats, [mode]: stats },
|
|
244
|
+
}), now).entry;
|
|
233
245
|
}
|
|
234
246
|
/** Profiles for the current host (default) or an explicit host id. */
|
|
235
247
|
getForHost(hostId) {
|
|
236
|
-
|
|
237
|
-
return Object.values(file.hosts[hostId ?? this.fingerprint().id] ?? {}).map((entry) => ({
|
|
248
|
+
return Object.values(this.storage.getHost(hostId) ?? {}).map((entry) => ({
|
|
238
249
|
...entry,
|
|
239
250
|
profile: normalizeProfile(entry.profile),
|
|
240
251
|
}));
|
|
241
252
|
}
|
|
242
253
|
/** Every stored profile across all hosts (for cross-machine comparisons). */
|
|
243
254
|
getAll() {
|
|
244
|
-
|
|
245
|
-
|
|
255
|
+
return this.storage
|
|
256
|
+
.getAllHosts()
|
|
257
|
+
.flatMap((models) => Object.values(models).map((entry) => ({ ...entry, profile: normalizeProfile(entry.profile) })));
|
|
246
258
|
}
|
|
247
259
|
}
|
|
248
260
|
//# sourceMappingURL=adaptation-store.js.map
|