@coool/opencode-adaptive 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -7
- package/dist/adapters/codex-capacity/index.d.ts +0 -1
- package/dist/adapters/codex-capacity/index.js.map +1 -1
- package/dist/adapters/codex-capacity/parse.d.ts +2 -2
- package/dist/adapters/codex-capacity/parse.js +19 -3
- package/dist/adapters/codex-capacity/parse.js.map +1 -1
- package/dist/adapters/codex-capacity/reading.d.ts +0 -1
- package/dist/adapters/codex-capacity/reading.js.map +1 -1
- package/dist/adapters/codex-capacity/sensor.d.ts +0 -1
- package/dist/adapters/codex-capacity/sensor.js.map +1 -1
- package/dist/adapters/codex-capacity/types.d.ts +0 -4
- package/dist/adapters/codex-capacity/types.js +14 -0
- package/dist/adapters/codex-capacity/types.js.map +1 -1
- package/dist/adapters/opencode/escalation-tool.d.ts +0 -1
- package/dist/adapters/opencode/escalation-tool.js +5 -3
- package/dist/adapters/opencode/escalation-tool.js.map +1 -1
- package/dist/adapters/opencode/events.d.ts +0 -1
- package/dist/adapters/opencode/events.js.map +1 -1
- package/dist/adapters/opencode/hooks.d.ts +0 -1
- package/dist/adapters/opencode/hooks.js +24 -7
- package/dist/adapters/opencode/hooks.js.map +1 -1
- package/dist/adapters/opencode/index.d.ts +0 -1
- package/dist/adapters/opencode/index.js.map +1 -1
- package/dist/adapters/opencode/inventory.d.ts +0 -1
- package/dist/adapters/opencode/inventory.js.map +1 -1
- package/dist/adapters/opencode/report.d.ts +0 -1
- package/dist/adapters/opencode/report.js.map +1 -1
- package/dist/adapters/opencode/session-ops.d.ts +0 -1
- package/dist/adapters/opencode/session-ops.js.map +1 -1
- package/dist/adapters/opencode/storage.d.ts +0 -1
- package/dist/adapters/opencode/storage.js.map +1 -1
- package/dist/adapters/opencode/tier-tool.d.ts +0 -1
- package/dist/adapters/opencode/tier-tool.js.map +1 -1
- package/dist/adapters/opencode/types.d.ts +0 -1
- package/dist/adapters/opencode/types.js.map +1 -1
- package/dist/core/compatibility/gate.d.ts +0 -3
- package/dist/core/compatibility/gate.js +0 -4
- package/dist/core/compatibility/gate.js.map +1 -1
- package/dist/core/compatibility/index.d.ts +0 -1
- package/dist/core/compatibility/index.js.map +1 -1
- package/dist/core/compatibility/types.d.ts +0 -1
- package/dist/core/compatibility/types.js.map +1 -1
- package/dist/core/scheduler/admit.d.ts +0 -1
- package/dist/core/scheduler/admit.js +22 -21
- package/dist/core/scheduler/admit.js.map +1 -1
- package/dist/core/scheduler/escalate.d.ts +0 -1
- package/dist/core/scheduler/escalate.js +6 -17
- package/dist/core/scheduler/escalate.js.map +1 -1
- package/dist/core/scheduler/index.d.ts +0 -1
- package/dist/core/scheduler/index.js.map +1 -1
- package/dist/core/scheduler/mode.d.ts +0 -1
- package/dist/core/scheduler/mode.js.map +1 -1
- package/dist/core/scheduler/types.d.ts +2 -9
- package/dist/core/scheduler/types.js +2 -1
- package/dist/core/scheduler/types.js.map +1 -1
- package/dist/core/tier-policy/index.d.ts +0 -1
- package/dist/core/tier-policy/index.js.map +1 -1
- package/dist/core/tier-policy/resolve.d.ts +0 -1
- package/dist/core/tier-policy/resolve.js.map +1 -1
- package/dist/core/tier-policy/tier-list.d.ts +0 -1
- package/dist/core/tier-policy/tier-list.js.map +1 -1
- package/dist/core/tier-policy/types.d.ts +2 -1
- package/dist/core/tier-policy/types.js +4 -0
- package/dist/core/tier-policy/types.js.map +1 -1
- package/dist/core/work-unit/index.d.ts +0 -1
- package/dist/core/work-unit/index.js.map +1 -1
- package/dist/core/work-unit/interruption.d.ts +0 -1
- package/dist/core/work-unit/interruption.js.map +1 -1
- package/dist/core/work-unit/tracker.d.ts +11 -4
- package/dist/core/work-unit/tracker.js +26 -6
- package/dist/core/work-unit/tracker.js.map +1 -1
- package/dist/core/work-unit/types.d.ts +6 -1
- package/dist/core/work-unit/types.js.map +1 -1
- package/dist/execution/continuation/execute.d.ts +0 -1
- package/dist/execution/continuation/execute.js.map +1 -1
- package/dist/execution/continuation/index.d.ts +0 -2
- package/dist/execution/continuation/index.js +0 -1
- package/dist/execution/continuation/index.js.map +1 -1
- package/dist/execution/continuation/plan.d.ts +0 -1
- package/dist/execution/continuation/plan.js +1 -3
- package/dist/execution/continuation/plan.js.map +1 -1
- package/dist/execution/continuation/prompts.d.ts +0 -1
- package/dist/execution/continuation/prompts.js.map +1 -1
- package/dist/execution/continuation/types.d.ts +0 -2
- package/dist/execution/continuation/types.js.map +1 -1
- package/dist/execution/escalation/index.d.ts +0 -1
- package/dist/execution/escalation/index.js.map +1 -1
- package/dist/execution/escalation/types.d.ts +0 -1
- package/dist/execution/escalation/types.js.map +1 -1
- package/dist/execution/index.d.ts +0 -1
- package/dist/execution/index.js.map +1 -1
- package/dist/execution/parking/index.d.ts +0 -1
- package/dist/execution/parking/index.js.map +1 -1
- package/dist/execution/parking/plan.d.ts +0 -1
- package/dist/execution/parking/plan.js.map +1 -1
- package/dist/execution/retry/decide.d.ts +0 -1
- package/dist/execution/retry/decide.js +1 -2
- package/dist/execution/retry/decide.js.map +1 -1
- package/dist/execution/retry/index.d.ts +0 -1
- package/dist/execution/retry/index.js.map +1 -1
- package/dist/execution/retry/types.d.ts +0 -2
- package/dist/execution/retry/types.js.map +1 -1
- package/dist/gui-experimental.cjs +1 -1
- package/dist/gui.d.ts +0 -1
- package/dist/gui.js +6 -3
- package/dist/gui.js.map +1 -1
- package/dist/health/capacity/index.d.ts +0 -1
- package/dist/health/capacity/index.js.map +1 -1
- package/dist/health/capacity/merge.d.ts +0 -1
- package/dist/health/capacity/merge.js.map +1 -1
- package/dist/health/capacity/registry.d.ts +0 -1
- package/dist/health/capacity/registry.js.map +1 -1
- package/dist/health/capacity/types.d.ts +0 -1
- package/dist/health/capacity/types.js.map +1 -1
- package/dist/health/circuit-breaker/breaker.d.ts +8 -1
- package/dist/health/circuit-breaker/breaker.js +18 -0
- package/dist/health/circuit-breaker/breaker.js.map +1 -1
- package/dist/health/circuit-breaker/index.d.ts +0 -1
- package/dist/health/circuit-breaker/index.js.map +1 -1
- package/dist/health/circuit-breaker/types.d.ts +0 -1
- package/dist/health/circuit-breaker/types.js.map +1 -1
- package/dist/health/classifier/classify.d.ts +0 -1
- package/dist/health/classifier/classify.js.map +1 -1
- package/dist/health/classifier/index.d.ts +0 -1
- package/dist/health/classifier/index.js.map +1 -1
- package/dist/health/classifier/types.d.ts +0 -1
- package/dist/health/classifier/types.js.map +1 -1
- package/dist/health/index.d.ts +0 -1
- package/dist/health/index.js.map +1 -1
- package/dist/health/resource-health/index.d.ts +0 -1
- package/dist/health/resource-health/index.js.map +1 -1
- package/dist/health/resource-health/key.d.ts +0 -1
- package/dist/health/resource-health/key.js.map +1 -1
- package/dist/health/resource-health/registry.d.ts +6 -1
- package/dist/health/resource-health/registry.js +19 -1
- package/dist/health/resource-health/registry.js.map +1 -1
- package/dist/health/resource-health/transitions.d.ts +2 -4
- package/dist/health/resource-health/transitions.js +10 -18
- package/dist/health/resource-health/transitions.js.map +1 -1
- package/dist/health/resource-health/types.d.ts +7 -1
- package/dist/health/resource-health/types.js +1 -0
- package/dist/health/resource-health/types.js.map +1 -1
- package/dist/index.d.ts +0 -6
- package/dist/index.js +44 -19
- package/dist/index.js.map +1 -1
- package/dist/plugin-id.d.ts +0 -1
- package/dist/plugin-id.js.map +1 -1
- package/dist/rpc/definition.d.ts +24 -1
- package/dist/rpc/definition.js +28 -2
- package/dist/rpc/definition.js.map +1 -1
- package/dist/rpc/handlers.d.ts +12 -24
- package/dist/rpc/handlers.js +22 -8
- package/dist/rpc/handlers.js.map +1 -1
- package/dist/rpc/status.d.ts +0 -1
- package/dist/rpc/status.js.map +1 -1
- package/dist/rpc.d.ts +0 -1
- package/dist/rpc.js.map +1 -1
- package/dist/state/capacity/index.d.ts +0 -1
- package/dist/state/capacity/index.js.map +1 -1
- package/dist/state/capacity/parse.d.ts +0 -1
- package/dist/state/capacity/parse.js +14 -2
- package/dist/state/capacity/parse.js.map +1 -1
- package/dist/state/capacity/store.d.ts +0 -1
- package/dist/state/capacity/store.js +16 -2
- package/dist/state/capacity/store.js.map +1 -1
- package/dist/state/capacity/types.d.ts +0 -1
- package/dist/state/capacity/types.js.map +1 -1
- package/dist/state/health/index.d.ts +0 -1
- package/dist/state/health/index.js.map +1 -1
- package/dist/state/health/parse.d.ts +0 -1
- package/dist/state/health/parse.js +20 -4
- package/dist/state/health/parse.js.map +1 -1
- package/dist/state/health/store.d.ts +0 -1
- package/dist/state/health/store.js +16 -2
- package/dist/state/health/store.js.map +1 -1
- package/dist/state/health/types.d.ts +0 -1
- package/dist/state/health/types.js.map +1 -1
- package/dist/state/parked-work/index.d.ts +0 -1
- package/dist/state/parked-work/index.js.map +1 -1
- package/dist/state/parked-work/parse.d.ts +0 -1
- package/dist/state/parked-work/parse.js.map +1 -1
- package/dist/state/parked-work/store.d.ts +0 -1
- package/dist/state/parked-work/store.js +20 -3
- package/dist/state/parked-work/store.js.map +1 -1
- package/dist/state/parked-work/types.d.ts +0 -1
- package/dist/state/parked-work/types.js.map +1 -1
- package/dist/state/receipts/bound.d.ts +0 -1
- package/dist/state/receipts/bound.js.map +1 -1
- package/dist/state/receipts/index.d.ts +0 -1
- package/dist/state/receipts/index.js.map +1 -1
- package/dist/state/receipts/parse.d.ts +0 -1
- package/dist/state/receipts/parse.js.map +1 -1
- package/dist/state/receipts/store.d.ts +0 -1
- package/dist/state/receipts/store.js +24 -4
- package/dist/state/receipts/store.js.map +1 -1
- package/dist/state/receipts/types.d.ts +0 -1
- package/dist/state/receipts/types.js.map +1 -1
- package/dist/state/session-modes/index.d.ts +0 -1
- package/dist/state/session-modes/index.js.map +1 -1
- package/dist/state/session-modes/parse.d.ts +0 -1
- package/dist/state/session-modes/parse.js.map +1 -1
- package/dist/state/session-modes/store.d.ts +0 -1
- package/dist/state/session-modes/store.js +15 -1
- package/dist/state/session-modes/store.js.map +1 -1
- package/dist/state/session-modes/types.d.ts +0 -1
- package/dist/state/session-modes/types.js.map +1 -1
- package/dist/state/settings/index.d.ts +0 -1
- package/dist/state/settings/index.js.map +1 -1
- package/dist/state/settings/parse.d.ts +0 -1
- package/dist/state/settings/parse.js.map +1 -1
- package/dist/state/settings/store.d.ts +0 -1
- package/dist/state/settings/store.js +9 -1
- package/dist/state/settings/store.js.map +1 -1
- package/dist/state/settings/types.d.ts +0 -1
- package/dist/state/settings/types.js.map +1 -1
- package/dist/state/tier-requests/index.d.ts +4 -0
- package/dist/state/tier-requests/index.js +4 -0
- package/dist/state/tier-requests/index.js.map +1 -0
- package/dist/state/tier-requests/parse.d.ts +3 -0
- package/dist/state/tier-requests/parse.js +53 -0
- package/dist/state/tier-requests/parse.js.map +1 -0
- package/dist/state/tier-requests/store.d.ts +27 -0
- package/dist/state/tier-requests/store.js +96 -0
- package/dist/state/tier-requests/store.js.map +1 -0
- package/dist/state/tier-requests/types.d.ts +30 -0
- package/dist/state/tier-requests/types.js +7 -0
- package/dist/state/tier-requests/types.js.map +1 -0
- package/dist/supervisor/index.d.ts +0 -1
- package/dist/supervisor/index.js.map +1 -1
- package/dist/supervisor/log.d.ts +0 -1
- package/dist/supervisor/log.js.map +1 -1
- package/dist/supervisor/supervisor.d.ts +23 -6
- package/dist/supervisor/supervisor.js +397 -111
- package/dist/supervisor/supervisor.js.map +1 -1
- package/dist/supervisor/types.d.ts +0 -1
- package/dist/supervisor/types.js.map +1 -1
- package/dist/supervisor/view.d.ts +0 -1
- package/dist/supervisor/view.js.map +1 -1
- package/dist/tui.d.ts +0 -1
- package/dist/tui.js +14 -10
- package/dist/tui.js.map +1 -1
- package/dist/ui/gui/api.d.ts +0 -1
- package/dist/ui/gui/api.js.map +1 -1
- package/dist/ui/gui/view.d.ts +0 -1
- package/dist/ui/gui/view.js.map +1 -1
- package/dist/ui/tui/controller.d.ts +0 -1
- package/dist/ui/tui/controller.js +28 -12
- package/dist/ui/tui/controller.js.map +1 -1
- package/dist/ui/tui/menu.d.ts +1 -2
- package/dist/ui/tui/menu.js +2 -2
- package/dist/ui/tui/menu.js.map +1 -1
- package/dist/ui/tui/options.d.ts +0 -1
- package/dist/ui/tui/options.js.map +1 -1
- package/dist/ui/tui/receipts.d.ts +0 -1
- package/dist/ui/tui/receipts.js +4 -1
- package/dist/ui/tui/receipts.js.map +1 -1
- package/dist/ui/tui/status.d.ts +1 -2
- package/dist/ui/tui/status.js +4 -2
- package/dist/ui/tui/status.js.map +1 -1
- package/dist/ui/tui/tiers.d.ts +0 -1
- package/dist/ui/tui/tiers.js.map +1 -1
- package/package.json +2 -2
- package/dist/adapters/codex-capacity/index.d.ts.map +0 -1
- package/dist/adapters/codex-capacity/parse.d.ts.map +0 -1
- package/dist/adapters/codex-capacity/reading.d.ts.map +0 -1
- package/dist/adapters/codex-capacity/sensor.d.ts.map +0 -1
- package/dist/adapters/codex-capacity/types.d.ts.map +0 -1
- package/dist/adapters/opencode/escalation-tool.d.ts.map +0 -1
- package/dist/adapters/opencode/events.d.ts.map +0 -1
- package/dist/adapters/opencode/hooks.d.ts.map +0 -1
- package/dist/adapters/opencode/index.d.ts.map +0 -1
- package/dist/adapters/opencode/inventory.d.ts.map +0 -1
- package/dist/adapters/opencode/report.d.ts.map +0 -1
- package/dist/adapters/opencode/session-ops.d.ts.map +0 -1
- package/dist/adapters/opencode/storage.d.ts.map +0 -1
- package/dist/adapters/opencode/tier-tool.d.ts.map +0 -1
- package/dist/adapters/opencode/types.d.ts.map +0 -1
- package/dist/core/compatibility/gate.d.ts.map +0 -1
- package/dist/core/compatibility/index.d.ts.map +0 -1
- package/dist/core/compatibility/types.d.ts.map +0 -1
- package/dist/core/scheduler/admit.d.ts.map +0 -1
- package/dist/core/scheduler/escalate.d.ts.map +0 -1
- package/dist/core/scheduler/index.d.ts.map +0 -1
- package/dist/core/scheduler/mode.d.ts.map +0 -1
- package/dist/core/scheduler/types.d.ts.map +0 -1
- package/dist/core/tier-policy/index.d.ts.map +0 -1
- package/dist/core/tier-policy/resolve.d.ts.map +0 -1
- package/dist/core/tier-policy/tier-list.d.ts.map +0 -1
- package/dist/core/tier-policy/types.d.ts.map +0 -1
- package/dist/core/work-unit/index.d.ts.map +0 -1
- package/dist/core/work-unit/interruption.d.ts.map +0 -1
- package/dist/core/work-unit/tracker.d.ts.map +0 -1
- package/dist/core/work-unit/types.d.ts.map +0 -1
- package/dist/execution/continuation/execute.d.ts.map +0 -1
- package/dist/execution/continuation/index.d.ts.map +0 -1
- package/dist/execution/continuation/ledger.d.ts +0 -20
- package/dist/execution/continuation/ledger.d.ts.map +0 -1
- package/dist/execution/continuation/ledger.js +0 -31
- package/dist/execution/continuation/ledger.js.map +0 -1
- package/dist/execution/continuation/plan.d.ts.map +0 -1
- package/dist/execution/continuation/prompts.d.ts.map +0 -1
- package/dist/execution/continuation/types.d.ts.map +0 -1
- package/dist/execution/escalation/index.d.ts.map +0 -1
- package/dist/execution/escalation/types.d.ts.map +0 -1
- package/dist/execution/index.d.ts.map +0 -1
- package/dist/execution/parking/index.d.ts.map +0 -1
- package/dist/execution/parking/plan.d.ts.map +0 -1
- package/dist/execution/recovery/gate.d.ts +0 -20
- package/dist/execution/recovery/gate.d.ts.map +0 -1
- package/dist/execution/recovery/gate.js +0 -23
- package/dist/execution/recovery/gate.js.map +0 -1
- package/dist/execution/recovery/index.d.ts +0 -3
- package/dist/execution/recovery/index.d.ts.map +0 -1
- package/dist/execution/recovery/index.js +0 -2
- package/dist/execution/recovery/index.js.map +0 -1
- package/dist/execution/retry/decide.d.ts.map +0 -1
- package/dist/execution/retry/index.d.ts.map +0 -1
- package/dist/execution/retry/types.d.ts.map +0 -1
- package/dist/gui.d.ts.map +0 -1
- package/dist/health/capacity/index.d.ts.map +0 -1
- package/dist/health/capacity/merge.d.ts.map +0 -1
- package/dist/health/capacity/registry.d.ts.map +0 -1
- package/dist/health/capacity/types.d.ts.map +0 -1
- package/dist/health/circuit-breaker/breaker.d.ts.map +0 -1
- package/dist/health/circuit-breaker/index.d.ts.map +0 -1
- package/dist/health/circuit-breaker/types.d.ts.map +0 -1
- package/dist/health/classifier/classify.d.ts.map +0 -1
- package/dist/health/classifier/index.d.ts.map +0 -1
- package/dist/health/classifier/types.d.ts.map +0 -1
- package/dist/health/index.d.ts.map +0 -1
- package/dist/health/resource-health/index.d.ts.map +0 -1
- package/dist/health/resource-health/key.d.ts.map +0 -1
- package/dist/health/resource-health/registry.d.ts.map +0 -1
- package/dist/health/resource-health/transitions.d.ts.map +0 -1
- package/dist/health/resource-health/types.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/plugin-id.d.ts.map +0 -1
- package/dist/rpc/definition.d.ts.map +0 -1
- package/dist/rpc/handlers.d.ts.map +0 -1
- package/dist/rpc/status.d.ts.map +0 -1
- package/dist/rpc.d.ts.map +0 -1
- package/dist/state/capacity/index.d.ts.map +0 -1
- package/dist/state/capacity/parse.d.ts.map +0 -1
- package/dist/state/capacity/store.d.ts.map +0 -1
- package/dist/state/capacity/types.d.ts.map +0 -1
- package/dist/state/health/index.d.ts.map +0 -1
- package/dist/state/health/parse.d.ts.map +0 -1
- package/dist/state/health/store.d.ts.map +0 -1
- package/dist/state/health/types.d.ts.map +0 -1
- package/dist/state/parked-work/index.d.ts.map +0 -1
- package/dist/state/parked-work/parse.d.ts.map +0 -1
- package/dist/state/parked-work/store.d.ts.map +0 -1
- package/dist/state/parked-work/types.d.ts.map +0 -1
- package/dist/state/receipts/bound.d.ts.map +0 -1
- package/dist/state/receipts/index.d.ts.map +0 -1
- package/dist/state/receipts/parse.d.ts.map +0 -1
- package/dist/state/receipts/store.d.ts.map +0 -1
- package/dist/state/receipts/types.d.ts.map +0 -1
- package/dist/state/session-modes/index.d.ts.map +0 -1
- package/dist/state/session-modes/parse.d.ts.map +0 -1
- package/dist/state/session-modes/store.d.ts.map +0 -1
- package/dist/state/session-modes/types.d.ts.map +0 -1
- package/dist/state/settings/index.d.ts.map +0 -1
- package/dist/state/settings/parse.d.ts.map +0 -1
- package/dist/state/settings/store.d.ts.map +0 -1
- package/dist/state/settings/types.d.ts.map +0 -1
- package/dist/supervisor/index.d.ts.map +0 -1
- package/dist/supervisor/log.d.ts.map +0 -1
- package/dist/supervisor/supervisor.d.ts.map +0 -1
- package/dist/supervisor/types.d.ts.map +0 -1
- package/dist/supervisor/view.d.ts.map +0 -1
- package/dist/tui.d.ts.map +0 -1
- package/dist/ui/gui/api.d.ts.map +0 -1
- package/dist/ui/gui/view.d.ts.map +0 -1
- package/dist/ui/tui/controller.d.ts.map +0 -1
- package/dist/ui/tui/menu.d.ts.map +0 -1
- package/dist/ui/tui/options.d.ts.map +0 -1
- package/dist/ui/tui/receipts.d.ts.map +0 -1
- package/dist/ui/tui/status.d.ts.map +0 -1
- package/dist/ui/tui/tiers.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracker.js","sourceRoot":"","sources":["../../../src/core/work-unit/tracker.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tracker.js","sourceRoot":"","sources":["../../../src/core/work-unit/tracker.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Episode tracker (ADP-001): a deterministic, clock-free state machine over\n * normalized work-unit events, keyed by session. All timestamps come from the\n * events themselves, so behavior is fully reproducible.\n *\n * Self-switch attribution: `session.model.selected` fires for both manual and\n * plugin-made switches. Before performing `session.switchModel` our adapter\n * calls `noteOwnSwitch`; the next `model-selected` event for that session\n * matching the noted reference is attributed `selected-adaptive` and consumes\n * the note. A non-matching selection clears the note, so a stale note can\n * never claim a later user pick — the failure direction is always\n * \"our switch looks external\" (treated as a manual pick, left alone), never\n * the reverse. At most one note per session is kept: a newer note replaces an\n * unconsumed older one, and the older switch's event (if it ever arrives) is\n * then attributed external — again the safe direction, since the adapter\n * serializes per-session switches.\n */\nimport {\n sameModelRef,\n type ActiveUnit,\n type ApplyResult,\n type ClosedUnit,\n type ModelRef,\n type ModelSource,\n type ModelTransition,\n type OpenedResult,\n type SelectionResult,\n type WorkUnitEvent,\n} from \"./types.js\"\n\n/** Insert into a bounded map, evicting the oldest (first) entry past the cap. */\nfunction setBounded<K, V>(map: Map<K, V>, key: K, value: V, cap: number): void {\n if (!map.has(key) && map.size >= cap) {\n for (const oldest of map.keys()) {\n map.delete(oldest)\n break\n }\n }\n map.set(key, value)\n}\n\nexport class WorkUnitTracker {\n readonly #active = new Map<string, ActiveUnit>()\n // Intentionally unbounded: evicting an episode counter could re-mint a unit\n // id (`${sessionID}#${episode}`) that a persisted receipt or parked record\n // already carries — a collision replaces parked work. The map holds one\n // number per session ever seen; that growth is bounded by session churn,\n // not by episodes.\n readonly #episodes = new Map<string, number>()\n /**\n * Bounded per-session maps (last model, pending own-switch note): a\n * long-lived host meets unbounded short-lived sessions, and the model\n * knowledge of a long-gone session is worthless. Insertion order gives the\n * eviction (oldest session first).\n */\n static readonly MAX_TRACKED_SESSIONS = 1024\n readonly #lastModel = new Map<string, ModelTransition>()\n readonly #pendingOwn = new Map<string, ModelRef>()\n\n /**\n * Arms the pending own-switch note consumed by the next matching\n * `model-selected` event for this session.\n */\n noteOwnSwitch(sessionID: string, model: ModelRef): void {\n setBounded(this.#pendingOwn, sessionID, model, WorkUnitTracker.MAX_TRACKED_SESSIONS)\n }\n\n /**\n * Raises each session's episode floor. Used at startup: unit ids are\n * durable keys (`${sessionID}#${episode}`) persisted in receipts and\n * parked work, so after a restart the counters must never re-mint an id\n * a persisted record already carries — a collision would replace parked\n * work and misattribute receipt outcomes.\n */\n seedEpisodes(seeds: ReadonlyMap<string, number>): void {\n for (const [sessionID, episode] of seeds) {\n if (episode > (this.#episodes.get(sessionID) ?? 0)) this.#episodes.set(sessionID, episode)\n }\n }\n\n /** Apply an execution-started event; the tracker always opens a unit. */\n apply(event: Extract<WorkUnitEvent, { kind: \"execution-started\" }>): OpenedResult\n apply(\n event: Extract<WorkUnitEvent, { kind: \"model-selected\" | \"model-request\" }>,\n ): SelectionResult\n apply(event: WorkUnitEvent): ApplyResult\n apply(event: WorkUnitEvent): ApplyResult {\n switch (event.kind) {\n case \"execution-started\": {\n const previous = this.#active.get(event.sessionID)\n if (previous !== undefined) this.#active.delete(event.sessionID)\n // A new execution on a session that still has an active unit means\n // the previous execution was superseded (matches OpenCode's\n // `interrupted{reason:\"superseded\"}` semantics).\n const superseded: ClosedUnit | undefined = previous && {\n ...previous,\n kind: \"interrupted\",\n closedAt: event.at,\n reason: \"superseded\",\n }\n const episode = (this.#episodes.get(event.sessionID) ?? 0) + 1\n this.#episodes.set(event.sessionID, episode)\n const unit: ActiveUnit = {\n kind: \"active\",\n id: `${event.sessionID}#${String(episode)}`,\n sessionID: event.sessionID,\n episode,\n startedAt: event.at,\n model: this.#lastModel.get(event.sessionID)?.model,\n transitions: [],\n }\n this.#active.set(event.sessionID, unit)\n return superseded ? { kind: \"opened\", unit, superseded } : { kind: \"opened\", unit }\n }\n case \"execution-succeeded\":\n case \"execution-failed\":\n case \"execution-interrupted\": {\n const current = this.#active.get(event.sessionID)\n if (current === undefined)\n return { kind: \"ignored\", reason: \"terminal-without-active-unit\" }\n this.#active.delete(event.sessionID)\n const base = { ...current, closedAt: event.at }\n if (event.kind === \"execution-succeeded\") {\n return { kind: \"closed\", unit: { ...base, kind: \"succeeded\" } }\n }\n if (event.kind === \"execution-failed\") {\n return { kind: \"closed\", unit: { ...base, kind: \"failed\", error: event.error } }\n }\n return { kind: \"closed\", unit: { ...base, kind: \"interrupted\", reason: event.reason } }\n }\n case \"model-selected\": {\n const adaptive = this.#consumePendingOwn(event.sessionID, event.model)\n return this.#trackModel(\n event.sessionID,\n event.at,\n event.model,\n adaptive ? \"selected-adaptive\" : \"selected-external\",\n )\n }\n case \"model-request\":\n // Context-hook observations never consume the pending note: only\n // actual selection events resolve it.\n return this.#trackModel(event.sessionID, event.at, event.model, \"request\")\n }\n }\n\n /** The open unit for a session, if any. */\n active(sessionID: string): ActiveUnit | undefined {\n return this.#active.get(sessionID)\n }\n\n /** Last model known to be in effect for a session, across episodes. */\n lastModel(sessionID: string): ModelTransition | undefined {\n return this.#lastModel.get(sessionID)\n }\n\n /**\n * Returns whether the pending note matched. The note is consumed on any\n * selection event: matched → `selected-adaptive`; unmatched (or absent) →\n * `selected-external` with the note dropped.\n */\n #consumePendingOwn(sessionID: string, model: ModelRef): boolean {\n const pending = this.#pendingOwn.get(sessionID)\n this.#pendingOwn.delete(sessionID)\n return pending !== undefined && sameModelRef(pending, model)\n }\n\n #trackModel(sessionID: string, at: number, model: ModelRef, source: ModelSource): ApplyResult {\n const transition: ModelTransition = { at, model, source }\n setBounded(this.#lastModel, sessionID, transition, WorkUnitTracker.MAX_TRACKED_SESSIONS)\n const current = this.#active.get(sessionID)\n if (current === undefined) return { kind: \"model-noted\", transition }\n const unit: ActiveUnit = {\n ...current,\n model,\n transitions: [...current.transitions, transition],\n }\n this.#active.set(sessionID, unit)\n return { kind: \"model-tracked\", unit, transition }\n }\n}\n"]}
|
|
@@ -122,6 +122,12 @@ export type IgnoredReason = (typeof IGNORED_REASONS)[number];
|
|
|
122
122
|
export type OpenedResult = Extract<ApplyResult, {
|
|
123
123
|
kind: "opened";
|
|
124
124
|
}>;
|
|
125
|
+
/** Result of a selection event: the tracker always records model knowledge. */
|
|
126
|
+
export type SelectionResult = Extract<ApplyResult, {
|
|
127
|
+
kind: "model-noted";
|
|
128
|
+
} | {
|
|
129
|
+
kind: "model-tracked";
|
|
130
|
+
}>;
|
|
125
131
|
export type ApplyResult = {
|
|
126
132
|
readonly kind: "opened";
|
|
127
133
|
readonly unit: ActiveUnit;
|
|
@@ -143,4 +149,3 @@ export type ApplyResult = {
|
|
|
143
149
|
readonly reason: IgnoredReason;
|
|
144
150
|
};
|
|
145
151
|
export {};
|
|
146
|
-
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/work-unit/types.ts"],"names":[],"mappings":"AAiBA,sEAAsE;AACtE,MAAM,UAAU,YAAY,CAAC,CAAW,EAAE,CAAW;IACnD,OAAO,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,CAAA;AAClF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,mBAAmB;IACnB,mBAAmB;IACnB,SAAS;CAC2B,CAAA;AAmGtC;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,8BAA8B,CAAsC,CAAA"}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/work-unit/types.ts"],"names":[],"mappings":"AAiBA,sEAAsE;AACtE,MAAM,UAAU,YAAY,CAAC,CAAW,EAAE,CAAW;IACnD,OAAO,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,CAAA;AAClF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,mBAAmB;IACnB,mBAAmB;IACnB,SAAS;CAC2B,CAAA;AAmGtC;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,8BAA8B,CAAsC,CAAA","sourcesContent":["/**\n * Work-unit model (ADP-001): one unit is exactly one OpenCode execution\n * episode — `session.execution.started` → `succeeded`/`failed`/`interrupted`.\n * Tool/step/text continuations never open, close, or split a unit (only the\n * execution events do); a subagent runs in its own session and therefore gets\n * its own units; a later continuation on the same session (e.g. a new /goal\n * round) is a new episode of that session.\n */\nimport type { InterruptReason } from \"./interruption.js\"\n\n/** OpenCode model reference (`Model.Ref`): provider, model, optional variant. */\nexport interface ModelRef {\n readonly providerID: string\n readonly id: string\n readonly variant?: string | undefined\n}\n\n/** Full-field equality; a variant change is a different reference. */\nexport function sameModelRef(a: ModelRef, b: ModelRef): boolean {\n return a.providerID === b.providerID && a.id === b.id && a.variant === b.variant\n}\n\n/**\n * How the model in effect became known. `selected-*` comes from the\n * `session.model.selected` event (which fires for both manual and\n * plugin-made switches — the tracker resolves which via pending own-switch\n * notes, see `WorkUnitTracker.noteOwnSwitch`); `request` comes from the\n * `context` hook and reports the model actually executing.\n */\nexport const MODEL_SOURCES = [\n \"selected-adaptive\",\n \"selected-external\",\n \"request\",\n] as const satisfies readonly string[]\n\nexport type ModelSource = (typeof MODEL_SOURCES)[number]\n\nexport interface ModelTransition {\n readonly at: number\n readonly model: ModelRef\n readonly source: ModelSource\n}\n\n/**\n * Minimal shape of the wire `Session.StructuredError` carried by\n * `session.execution.failed` (`response.body` is deliberately dropped here —\n * the adapter folds it into bounded `ErrorEvidence` for the classifier).\n */\nexport interface ExecutionError {\n readonly type: string\n readonly message: string\n readonly status?: number | undefined\n readonly retryAfterMs?: number | undefined\n}\n\n/**\n * The episode lifecycle. `kind` doubles as status: `\"active\"` while the\n * execution runs, then the terminal kind it closed with.\n */\ninterface UnitBase {\n /** Stable per-episode identifier: `${sessionID}#${episode}`. */\n readonly id: string\n readonly sessionID: string\n /** 1-based count of episodes started for this session (tracker lifetime). */\n readonly episode: number\n readonly startedAt: number\n /**\n * Model in effect for the unit: seeded from the last known selection when\n * the unit opens, then updated by transitions.\n */\n readonly model?: ModelRef | undefined\n readonly transitions: readonly ModelTransition[]\n}\n\nexport interface ActiveUnit extends UnitBase {\n readonly kind: \"active\"\n}\n\nexport interface SucceededUnit extends UnitBase {\n readonly kind: \"succeeded\"\n readonly closedAt: number\n}\n\nexport interface FailedUnit extends UnitBase {\n readonly kind: \"failed\"\n readonly closedAt: number\n readonly error: ExecutionError\n}\n\nexport interface InterruptedUnit extends UnitBase {\n readonly kind: \"interrupted\"\n readonly closedAt: number\n readonly reason: InterruptReason\n}\n\nexport type ClosedUnit = SucceededUnit | FailedUnit | InterruptedUnit\n\nexport type WorkUnit = ActiveUnit | ClosedUnit\n\n/**\n * Normalized episode events. The OpenCode adapter unwraps host event payloads\n * (`event.data.*`) and forwards them here; `model-request` is fed from the\n * `context` session hook.\n */\nexport type WorkUnitEvent =\n | { readonly kind: \"execution-started\"; readonly sessionID: string; readonly at: number }\n | { readonly kind: \"execution-succeeded\"; readonly sessionID: string; readonly at: number }\n | {\n readonly kind: \"execution-failed\"\n readonly sessionID: string\n readonly at: number\n readonly error: ExecutionError\n }\n | {\n readonly kind: \"execution-interrupted\"\n readonly sessionID: string\n readonly at: number\n readonly reason: InterruptReason\n }\n | {\n readonly kind: \"model-selected\"\n readonly sessionID: string\n readonly at: number\n readonly model: ModelRef\n }\n | {\n readonly kind: \"model-request\"\n readonly sessionID: string\n readonly at: number\n readonly model: ModelRef\n }\n\n/**\n * Why an event produced no state change. Only terminal events can be ignored\n * — they arrive without an active unit when the terminal was already handled\n * (duplicate delivery) or never preceded by `execution-started`.\n */\nexport const IGNORED_REASONS = [\"terminal-without-active-unit\"] as const satisfies readonly string[]\n\nexport type IgnoredReason = (typeof IGNORED_REASONS)[number]\n\n/** Result of an execution-started event: the tracker always opens (possibly superseding). */\nexport type OpenedResult = Extract<ApplyResult, { kind: \"opened\" }>\n\n/** Result of a selection event: the tracker always records model knowledge. */\nexport type SelectionResult = Extract<\n ApplyResult,\n { kind: \"model-noted\" } | { kind: \"model-tracked\" }\n>\n\nexport type ApplyResult =\n | {\n readonly kind: \"opened\"\n readonly unit: ActiveUnit\n readonly superseded?: ClosedUnit | undefined\n }\n | { readonly kind: \"closed\"; readonly unit: ClosedUnit }\n | {\n readonly kind: \"model-tracked\"\n readonly unit: ActiveUnit\n readonly transition: ModelTransition\n }\n /** Model knowledge recorded with no active unit; remembered for the next admission. */\n | { readonly kind: \"model-noted\"; readonly transition: ModelTransition }\n | { readonly kind: \"ignored\"; readonly reason: IgnoredReason }\n"]}
|
|
@@ -16,4 +16,3 @@ import type { ContinuationExecuteInput } from "./types.js";
|
|
|
16
16
|
* failure because each step awaits the previous one.
|
|
17
17
|
*/
|
|
18
18
|
export declare function executeContinuation(input: ContinuationExecuteInput): Promise<ContinuationOutcome>;
|
|
19
|
-
//# sourceMappingURL=execute.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute.js","sourceRoot":"","sources":["../../../src/execution/continuation/execute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAIlD;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,KAA+B;IAE/B,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,KAAK,CAAA;IACxC,IAAI,MAAM,CAAC,IAAI,KAAK,cAAc;QAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAA;IAClE,IAAI,MAAM,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QACjC,MAAM,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAC3B,MAAM,GAAG,CAAC,WAAW,CAAC,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;QAC9C,MAAM,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAA;QAChD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;IAC5B,CAAC;IACD,MAAM,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;IAC3B,MAAM,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAA;IAChD,OAAO,EAAE,IAAI,EAAE,sBAAsB,EAAE,CAAA;AACzC,CAAC"}
|
|
1
|
+
{"version":3,"file":"execute.js","sourceRoot":"","sources":["../../../src/execution/continuation/execute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAIlD;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,KAA+B;IAE/B,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,KAAK,CAAA;IACxC,IAAI,MAAM,CAAC,IAAI,KAAK,cAAc;QAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAA;IAClE,IAAI,MAAM,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QACjC,MAAM,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAC3B,MAAM,GAAG,CAAC,WAAW,CAAC,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;QAC9C,MAAM,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAA;QAChD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;IAC5B,CAAC;IACD,MAAM,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;IAC3B,MAAM,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAA;IAChD,OAAO,EAAE,IAAI,EAAE,sBAAsB,EAAE,CAAA;AACzC,CAAC","sourcesContent":["import { CONTINUATION_PROMPT } from \"./prompts.js\"\nimport type { ContinuationOutcome } from \"./types.js\"\nimport type { ContinuationExecuteInput } from \"./types.js\"\n\n/**\n * Executes a planned continuation through the narrow ops seam, enforcing\n * the partial-work invariants in one place (ADP-014/ADP-023):\n *\n * 1. Every owned path settles the session FIRST — Adaptive never switches\n * or prompts while a failed execution is still settling.\n * 2. The delivered prompt is always the fixed continuation prompt over the\n * existing session/workspace state — the original instruction is never\n * re-sent, so the never-replay invariant holds by construction.\n * 3. `allow-native` performs no host operations at all.\n *\n * Ops failures propagate to the caller (the wiring's fail-open wrapper\n * decides degradation); the ordering guarantee holds up to the first\n * failure because each step awaits the previous one.\n */\nexport async function executeContinuation(\n input: ContinuationExecuteInput,\n): Promise<ContinuationOutcome> {\n const { action, ops, sessionID } = input\n if (action.kind === \"allow-native\") return { kind: \"left-native\" }\n if (action.kind === \"in-session\") {\n await ops.settle(sessionID)\n await ops.switchModel(sessionID, action.model)\n await ops.prompt(sessionID, CONTINUATION_PROMPT)\n return { kind: \"resumed\" }\n }\n await ops.settle(sessionID)\n await ops.prompt(sessionID, CONTINUATION_PROMPT)\n return { kind: \"continuation-started\" }\n}\n"]}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
export { CONTINUATION_ACTIONS } from "./types.js";
|
|
2
1
|
export type { ContinuationAction, ContinuationActionKind, ContinuationExecuteInput, ContinuationOps, ContinuationOutcome, ContinuationPlanInput, } from "./types.js";
|
|
3
2
|
export { CONTINUATION_PROMPT } from "./prompts.js";
|
|
4
3
|
export { planContinuation } from "./plan.js";
|
|
5
4
|
export { executeContinuation } from "./execute.js";
|
|
6
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/execution/continuation/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/execution/continuation/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA","sourcesContent":["export type {\n ContinuationAction,\n ContinuationActionKind,\n ContinuationExecuteInput,\n ContinuationOps,\n ContinuationOutcome,\n ContinuationPlanInput,\n} from \"./types.js\"\nexport { CONTINUATION_PROMPT } from \"./prompts.js\"\nexport { planContinuation } from \"./plan.js\"\nexport { executeContinuation } from \"./execute.js\"\n"]}
|
|
@@ -10,4 +10,3 @@ import type { ContinuationAction, ContinuationPlanInput } from "./types.js";
|
|
|
10
10
|
* continuation work unit from existing durable session state.
|
|
11
11
|
*/
|
|
12
12
|
export declare function planContinuation(input: ContinuationPlanInput): ContinuationAction;
|
|
13
|
-
//# sourceMappingURL=plan.d.ts.map
|
|
@@ -12,9 +12,7 @@ export function planContinuation(input) {
|
|
|
12
12
|
if (input.recovery.kind === "none")
|
|
13
13
|
return { kind: "allow-native" };
|
|
14
14
|
if (input.continuationPossible)
|
|
15
|
-
return input.recovery.
|
|
16
|
-
? { kind: "in-session", model: input.recovery.model }
|
|
17
|
-
: { kind: "in-session", model: input.recovery.model, probeId: input.recovery.probeId };
|
|
15
|
+
return { kind: "in-session", model: input.recovery.model };
|
|
18
16
|
return { kind: "clean-continuation" };
|
|
19
17
|
}
|
|
20
18
|
//# sourceMappingURL=plan.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/execution/continuation/plan.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAA4B;IAC3D,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,CAAA;IACnE,IAAI,KAAK,CAAC,oBAAoB;
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/execution/continuation/plan.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAA4B;IAC3D,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,CAAA;IACnE,IAAI,KAAK,CAAC,oBAAoB;QAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAA;IAC1F,OAAO,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAA;AACvC,CAAC","sourcesContent":["import type { ContinuationAction, ContinuationPlanInput } from \"./types.js\"\n\n/**\n * Partial-work safety planner (ADP-023). Total, deterministic, pure.\n *\n * - No owned recovery: OpenCode's native retry is the preferred recovery;\n * Adaptive leaves it alone.\n * - Owned recovery and the in-session path is possible: continue the same\n * session on the recovered candidate (settle → switch → resume).\n * - Owned recovery and the in-session path is impossible: start a clean\n * continuation work unit from existing durable session state.\n */\nexport function planContinuation(input: ContinuationPlanInput): ContinuationAction {\n if (input.recovery.kind === \"none\") return { kind: \"allow-native\" }\n if (input.continuationPossible) return { kind: \"in-session\", model: input.recovery.model }\n return { kind: \"clean-continuation\" }\n}\n"]}
|
|
@@ -5,4 +5,3 @@
|
|
|
5
5
|
* never-replay invariant is structural, not a caller responsibility.
|
|
6
6
|
*/
|
|
7
7
|
export declare const CONTINUATION_PROMPT = "Continue the interrupted work from the current session state. Do not repeat completed work; resume from what the session already produced.";
|
|
8
|
-
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/execution/continuation/prompts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAC9B,4IAA4I,CAAA"}
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/execution/continuation/prompts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAC9B,4IAA4I,CAAA","sourcesContent":["/**\n * Continuation prompt for owned recovery and parked-work resume (ADP-023).\n * Continues from session state; never replays the original instruction once\n * tool side effects may exist. The executor sends exactly this prompt — the\n * never-replay invariant is structural, not a caller responsibility.\n */\nexport const CONTINUATION_PROMPT =\n \"Continue the interrupted work from the current session state. Do not repeat completed work; resume from what the session already produced.\"\n"]}
|
|
@@ -20,7 +20,6 @@ export type ContinuationAction = {
|
|
|
20
20
|
} | {
|
|
21
21
|
kind: "in-session";
|
|
22
22
|
model: ModelRef;
|
|
23
|
-
probeId?: string | undefined;
|
|
24
23
|
} | {
|
|
25
24
|
kind: "clean-continuation";
|
|
26
25
|
};
|
|
@@ -67,4 +66,3 @@ export type ContinuationOutcome = {
|
|
|
67
66
|
} | {
|
|
68
67
|
kind: "continuation-started";
|
|
69
68
|
};
|
|
70
|
-
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/execution/continuation/types.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,cAAc,EAAE,YAAY,EAAE,oBAAoB,CAAU,CAAA"}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/execution/continuation/types.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,cAAc,EAAE,YAAY,EAAE,oBAAoB,CAAU,CAAA","sourcesContent":["import type { ModelRef } from \"../../core/work-unit/types.js\"\nimport type { RecoveryOption } from \"../retry/types.js\"\n\n/**\n * What Adaptive does for a failed work unit's recovery (ADP-013/ADP-014).\n * - `allow-native`: Adaptive did not take ownership (no veto) — OpenCode's\n * native retry lifecycle is the preferred recovery and stays untouched.\n * - `in-session`: Adaptive vetoed native retry and continues the same\n * session on a recovered candidate (settle → switch → resume).\n * - `clean-continuation`: the in-session path is not possible; start a\n * clean continuation work unit from existing durable session state.\n *\n * The union has no \"replay\" variant by construction: every owned path\n * continues from session state, so \"Adaptive replays the original\n * instruction after side effects\" is unrepresentable, not merely avoided.\n */\nexport const CONTINUATION_ACTIONS = [\"allow-native\", \"in-session\", \"clean-continuation\"] as const\nexport type ContinuationActionKind = (typeof CONTINUATION_ACTIONS)[number]\n\nexport type ContinuationAction =\n | { kind: \"allow-native\" }\n | { kind: \"in-session\"; model: ModelRef }\n | { kind: \"clean-continuation\" }\n\nexport interface ContinuationPlanInput {\n /**\n * Recovery option computed by the wiring for the failing unit: `none`\n * means Adaptive did not veto (OpenCode's native retry is the preferred\n * recovery); `switch` means Adaptive vetoed and owns the recovery.\n */\n readonly recovery: RecoveryOption\n /**\n * True when the in-session owned path is possible (session alive, settle\n * + switch + resume available). Only consulted for `switch` recovery.\n */\n readonly continuationPossible: boolean\n}\n\n/**\n * Narrow seam over the host session operations the owned continuation\n * needs. Implemented by the OpenCode adapter (which tags its own model\n * switches for attribution before calling the host); tests use fakes that\n * record call order. Never imports `@opencode/plugin`.\n */\nexport interface ContinuationOps {\n /**\n * Wait until the session's failed execution has settled. Every owned\n * path settles first — Adaptive never switches or prompts while a failed\n * execution is still settling.\n */\n settle(sessionID: string): Promise<void>\n /** Switch the session's model (own-switch attribution handled by the adapter). */\n switchModel(sessionID: string, model: ModelRef): Promise<void>\n /** Deliver a prompt to the session; starts/continues execution. */\n prompt(sessionID: string, text: string): Promise<void>\n}\n\nexport interface ContinuationExecuteInput {\n readonly sessionID: string\n readonly action: ContinuationAction\n readonly ops: ContinuationOps\n}\n\nexport type ContinuationOutcome =\n { kind: \"left-native\" } | { kind: \"resumed\" } | { kind: \"continuation-started\" }\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/execution/escalation/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/execution/escalation/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA","sourcesContent":["export * from \"./types.js\"\n"]}
|
|
@@ -28,4 +28,3 @@ export declare function truncateBounded(text: string, max: number): string;
|
|
|
28
28
|
export declare function parseEscalationRequest(input: unknown): EscalationRequest | undefined;
|
|
29
29
|
/** One-line summary recorded as escalation evidence (bounded). */
|
|
30
30
|
export declare function escalationDetail(request: EscalationRequest): string;
|
|
31
|
-
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/execution/escalation/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,iDAAiD;AACjD,MAAM,CAAC,MAAM,oBAAoB,GAAG,mBAAmB,CAAA;AAEvD,yEAAyE;AACzE,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,CAAA;AAO9C;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,GAAW;IACvD,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,IAAI,CAAA;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IAC9B,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAC3C,OAAO,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;AAClE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAc;IACnD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,SAAS,CAAA;IACjE,MAAM,MAAM,GAAG,KAAgC,CAAA;IAC/C,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAA;IAC/B,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,CAAA;IACnC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAA;IACvE,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAA;IAC3E,OAAO;QACL,MAAM,EAAE,eAAe,CAAC,MAAM,EAAE,2BAA2B,CAAC;QAC5D,QAAQ,EAAE,eAAe,CAAC,QAAQ,EAAE,2BAA2B,CAAC;KACjE,CAAA;AACH,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,gBAAgB,CAAC,OAA0B;IACzD,OAAO,eAAe,CAAC,GAAG,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,QAAQ,EAAE,EAAE,2BAA2B,CAAC,CAAA;AAC/F,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/execution/escalation/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,iDAAiD;AACjD,MAAM,CAAC,MAAM,oBAAoB,GAAG,mBAAmB,CAAA;AAEvD,yEAAyE;AACzE,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,CAAA;AAO9C;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,GAAW;IACvD,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,IAAI,CAAA;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IAC9B,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAC3C,OAAO,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;AAClE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAc;IACnD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,SAAS,CAAA;IACjE,MAAM,MAAM,GAAG,KAAgC,CAAA;IAC/C,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAA;IAC/B,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,CAAA;IACnC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAA;IACvE,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAA;IAC3E,OAAO;QACL,MAAM,EAAE,eAAe,CAAC,MAAM,EAAE,2BAA2B,CAAC;QAC5D,QAAQ,EAAE,eAAe,CAAC,QAAQ,EAAE,2BAA2B,CAAC;KACjE,CAAA;AACH,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,gBAAgB,CAAC,OAA0B;IACzD,OAAO,eAAe,CAAC,GAAG,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,QAAQ,EAAE,EAAE,2BAA2B,CAAC,CAAA;AAC/F,CAAC","sourcesContent":["/**\n * The Adaptive-owned escalation request surface (T-18, ADP-015..017). The\n * schema requires a reason and evidence — it is deliberately the smallest\n * typed mechanism for an agent to request stronger capability, and it is not\n * a planning or task-management API. The request is recorded against the\n * current work unit and applies at the next safe boundary within the finite\n * per-unit budget; a completing unit discards it (routing re-runs fresh).\n */\n\n/** The tool name as registered with the host. */\nexport const ESCALATION_TOOL_NAME = \"adaptive_escalate\"\n\n/** Each field is bounded — the request never carries unbounded prose. */\nexport const MAX_ESCALATION_FIELD_LENGTH = 256\n\nexport interface EscalationRequest {\n readonly reason: string\n readonly evidence: string\n}\n\n/**\n * Truncates to `max` UTF-16 code units without splitting a surrogate pair:\n * a trailing high surrogate whose low half was cut is dropped, so the\n * persisted evidence never carries a lone surrogate.\n */\nexport function truncateBounded(text: string, max: number): string {\n if (text.length <= max) return text\n const cut = text.slice(0, max)\n const last = cut.charCodeAt(cut.length - 1)\n return last >= 0xd800 && last <= 0xdbff ? cut.slice(0, -1) : cut\n}\n\n/**\n * Total parser for the tool input (the host forwards model-produced JSON, so\n * the runtime shape is untrusted even though the standard schema describes\n * it). Both fields are required, non-empty, and bounded.\n */\nexport function parseEscalationRequest(input: unknown): EscalationRequest | undefined {\n if (typeof input !== \"object\" || input === null) return undefined\n const record = input as Record<string, unknown>\n const reason = record[\"reason\"]\n const evidence = record[\"evidence\"]\n if (typeof reason !== \"string\" || reason.length === 0) return undefined\n if (typeof evidence !== \"string\" || evidence.length === 0) return undefined\n return {\n reason: truncateBounded(reason, MAX_ESCALATION_FIELD_LENGTH),\n evidence: truncateBounded(evidence, MAX_ESCALATION_FIELD_LENGTH),\n }\n}\n\n/** One-line summary recorded as escalation evidence (bounded). */\nexport function escalationDetail(request: EscalationRequest): string {\n return truncateBounded(`${request.reason}: ${request.evidence}`, MAX_ESCALATION_FIELD_LENGTH)\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/execution/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,yBAAyB,CAAA;AACvC,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/execution/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,yBAAyB,CAAA;AACvC,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA","sourcesContent":["export * from \"./retry/index.js\"\nexport * from \"./continuation/index.js\"\nexport * from \"./parking/index.js\"\nexport * from \"./escalation/index.js\"\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/execution/parking/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/execution/parking/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA","sourcesContent":["export { selectResumable } from \"./plan.js\"\nexport type { ResumeContext, ResumePlan } from \"./plan.js\"\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/execution/parking/plan.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAA;AA8BpC;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,OAAgC,EAChC,OAAsB;IAEtB,MAAM,OAAO,GAAmB,EAAE,CAAA;IAClC,MAAM,IAAI,GAAmB,EAAE,CAAA;IAC/B,MAAM,IAAI,GAAmB,EAAE,CAAA;IAC/B,MAAM,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAA;IAClE,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE,CAAC;QAC3B,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5C,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YACjB,SAAQ;QACV,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC,IAAI,mBAAmB,EAAE,CAAC;YAClD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YACjB,SAAQ;QACV,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YACzC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YACjB,SAAQ;QACV,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACtB,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;AAChC,CAAC"}
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/execution/parking/plan.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAA;AA8BpC;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,OAAgC,EAChC,OAAsB;IAEtB,MAAM,OAAO,GAAmB,EAAE,CAAA;IAClC,MAAM,IAAI,GAAmB,EAAE,CAAA;IAC/B,MAAM,IAAI,GAAmB,EAAE,CAAA;IAC/B,MAAM,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAA;IAClE,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE,CAAC;QAC3B,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5C,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YACjB,SAAQ;QACV,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC,IAAI,mBAAmB,EAAE,CAAC;YAClD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YACjB,SAAQ;QACV,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YACzC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YACjB,SAAQ;QACV,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACtB,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;AAChC,CAAC","sourcesContent":["import type { ParkedRecord } from \"../../state/parked-work/types.js\"\n\n/**\n * Resume-attempt budget (ADP-011): a record whose continuation prompt kept\n * failing is dropped once its attempts reach this count — the idle loop\n * must be provably bounded, not \"as long as idle events keep firing\".\n */\nexport const MAX_PARKED_ATTEMPTS = 5\n\n/**\n * Predicates supplied by the wiring at each safe boundary. Kept as\n * injected predicates so this module stays host-agnostic and fully\n * unit-testable with fakes.\n */\nexport interface ResumeContext {\n /** Whether the parked record's tier still has configured resources. */\n tierConfigured(tier: ParkedRecord[\"tier\"]): boolean\n /** Whether the session the record belongs to still exists. */\n sessionAlive(sessionID: string): boolean\n}\n\nexport interface ResumePlan {\n /**\n * Records worth a fresh routing attempt now, oldest parked first (ties\n * keep park order). The wiring re-runs routing for each; a successful\n * route pops the record via the store and starts a clean continuation.\n */\n readonly attempt: readonly ParkedRecord[]\n /** Tier no longer configured — keep parked until the user configures it. */\n readonly hold: readonly ParkedRecord[]\n /**\n * Session gone, or the record exhausted its resume-attempt budget — the\n * record can never (or may no longer) resume; the wiring drops it.\n */\n readonly drop: readonly ParkedRecord[]\n}\n\n/**\n * Parked-work resume selection at a safe boundary (ADP-024). Total,\n * deterministic, pure: partitions the parked list by resumability without\n * consulting health (routing re-decides with fresh health per attempt).\n */\nexport function selectResumable(\n records: readonly ParkedRecord[],\n context: ResumeContext,\n): ResumePlan {\n const attempt: ParkedRecord[] = []\n const hold: ParkedRecord[] = []\n const drop: ParkedRecord[] = []\n const byAge = [...records].sort((a, b) => a.parkedAt - b.parkedAt)\n for (const record of byAge) {\n if (!context.sessionAlive(record.sessionID)) {\n drop.push(record)\n continue\n }\n if ((record.attempts ?? 0) >= MAX_PARKED_ATTEMPTS) {\n drop.push(record)\n continue\n }\n if (!context.tierConfigured(record.tier)) {\n hold.push(record)\n continue\n }\n attempt.push(record)\n }\n return { attempt, hold, drop }\n}\n"]}
|
|
@@ -27,4 +27,3 @@ export declare function decideRetry(input: RetryInput): RetryCoreDecision;
|
|
|
27
27
|
* execution (the hook is not even registered, this keeps the union closed).
|
|
28
28
|
*/
|
|
29
29
|
export declare function forMode(decision: RetryCoreDecision, mode: OperatingMode): RetryDecision;
|
|
30
|
-
//# sourceMappingURL=decide.d.ts.map
|
|
@@ -55,8 +55,7 @@ export function decideRetry(input) {
|
|
|
55
55
|
if (input.vetoesUsed >= MAX_VETOES_PER_UNIT) {
|
|
56
56
|
return { kind: "leave" };
|
|
57
57
|
}
|
|
58
|
-
|
|
59
|
-
return probeId === undefined ? { kind: "veto", model } : { kind: "veto", model, probeId };
|
|
58
|
+
return { kind: "veto", model: recovery.model };
|
|
60
59
|
}
|
|
61
60
|
/**
|
|
62
61
|
* Mode wrapper — the same core decision for Observe and Control; Observe
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decide.js","sourceRoot":"","sources":["../../../src/execution/retry/decide.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAU5D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,WAAW,CAAC,KAAiB;IAC3C,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,gBAAgB,EAAE,CAAC;QAC3C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IAC1B,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,EAAE,CAAC;QACrC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IAC1B,CAAC;IACD,MAAM,QAAQ,GAAmB,KAAK,CAAC,QAAQ,CAAA;IAC/C,IAAI,QAAQ,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC7B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IAC1B,CAAC;IACD,mEAAmE;IACnE,4EAA4E;IAC5E,4DAA4D;IAC5D,wEAAwE;IACxE,yEAAyE;IACzE,8DAA8D;IAC9D,MAAM,YAAY,GAChB,QAAQ,CAAC,OAAO,KAAK,SAAS;QAC9B,YAAY,CACV;YACE,GAAG,QAAQ,CAAC,KAAK;YACjB,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO;SACnF,EACD;YACE,GAAG,KAAK,CAAC,YAAY;YACrB,OAAO,EAAE,KAAK,CAAC,YAAY,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO;SAC3F,CACF,CAAA;IACH,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IAC1B,CAAC;IACD,MAAM,MAAM,GAAwB,KAAK,CAAC,MAAM,CAAA;IAChD,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAClB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IAC1B,CAAC;IACD,IAAI,KAAK,CAAC,UAAU,IAAI,mBAAmB,EAAE,CAAC;QAC5C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IAC1B,CAAC;IACD,
|
|
1
|
+
{"version":3,"file":"decide.js","sourceRoot":"","sources":["../../../src/execution/retry/decide.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAU5D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,WAAW,CAAC,KAAiB;IAC3C,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,gBAAgB,EAAE,CAAC;QAC3C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IAC1B,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,EAAE,CAAC;QACrC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IAC1B,CAAC;IACD,MAAM,QAAQ,GAAmB,KAAK,CAAC,QAAQ,CAAA;IAC/C,IAAI,QAAQ,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC7B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IAC1B,CAAC;IACD,mEAAmE;IACnE,4EAA4E;IAC5E,4DAA4D;IAC5D,wEAAwE;IACxE,yEAAyE;IACzE,8DAA8D;IAC9D,MAAM,YAAY,GAChB,QAAQ,CAAC,OAAO,KAAK,SAAS;QAC9B,YAAY,CACV;YACE,GAAG,QAAQ,CAAC,KAAK;YACjB,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO;SACnF,EACD;YACE,GAAG,KAAK,CAAC,YAAY;YACrB,OAAO,EAAE,KAAK,CAAC,YAAY,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO;SAC3F,CACF,CAAA;IACH,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IAC1B,CAAC;IACD,MAAM,MAAM,GAAwB,KAAK,CAAC,MAAM,CAAA;IAChD,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAClB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IAC1B,CAAC;IACD,IAAI,KAAK,CAAC,UAAU,IAAI,mBAAmB,EAAE,CAAC;QAC5C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IAC1B,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAA;AAChD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,QAA2B,EAAE,IAAmB;IACtE,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ;YACX,OAAO,QAAQ,CAAA;QACjB,KAAK,SAAS;YACZ,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAA;QAClD,KAAK,KAAK;YACR,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IAC5B,CAAC;AACH,CAAC","sourcesContent":["import { MAX_VETOES_PER_UNIT } from \"./types.js\"\nimport { sameModelRef } from \"../../core/work-unit/types.js\"\nimport type { OperatingMode } from \"../../core/scheduler/types.js\"\nimport type {\n NativeRetryDecision,\n RecoveryOption,\n RetryCoreDecision,\n RetryInput,\n RetryDecision,\n} from \"./types.js\"\n\n/**\n * Retry-hook policy (ADP-013/014). Total, deterministic, side-effect free.\n *\n * Veto (take ownership of horizontal recovery) only when ALL hold:\n * - the classification is failover-eligible (infrastructure failure —\n * capability problems and host decisions never veto);\n * - the evidence is definitive — ambiguous evidence (Retry-After headers\n * alone, bounded-textual matches) conservatively leaves OpenCode's native\n * retry, which the host schedules with its parsed `retryAfterMs` (ADP-012);\n * - a same-tier recovery candidate exists AND differs from the resource that\n * just failed — without one, the native retry of the same resource IS the\n * preferred horizontal recovery (vetoing onto the failed resource would\n * discard the host's backoff and re-prompt it immediately). A breaker-probe\n * recovery is exempt: its target IS the failed resource by design, and the\n * veto is what starts the probe episode;\n * - the host still wants to retry (`retry: true`) — an already-vetoed or\n * exhausted lifecycle is never resurrected; recovery defers to the next\n * safe boundary (ADP-014, ADP-023);\n * - the per-unit veto budget has room left.\n */\nexport function decideRetry(input: RetryInput): RetryCoreDecision {\n if (!input.classification.failoverEligible) {\n return { kind: \"leave\" }\n }\n if (!input.classification.definitive) {\n return { kind: \"leave\" }\n }\n const recovery: RecoveryOption = input.recovery\n if (recovery.kind === \"none\") {\n return { kind: \"leave\" }\n }\n // A probe recovery targets the very resource that just failed (the\n // half-open probe re-admits it); the veto is what starts the probe episode,\n // so the same-resource exemption below must not swallow it.\n // The host reports base-model calls with variant \"default\" (verified on\n // 2.2.5, same fact refKey normalizes in the supervisor), so the sameness\n // check must not treat that spelling as a different resource.\n const sameResource =\n recovery.probeId === undefined &&\n sameModelRef(\n {\n ...recovery.model,\n variant: recovery.model.variant === \"default\" ? undefined : recovery.model.variant,\n },\n {\n ...input.failingModel,\n variant: input.failingModel.variant === \"default\" ? undefined : input.failingModel.variant,\n },\n )\n if (sameResource) {\n return { kind: \"leave\" }\n }\n const native: NativeRetryDecision = input.native\n if (!native.retry) {\n return { kind: \"leave\" }\n }\n if (input.vetoesUsed >= MAX_VETOES_PER_UNIT) {\n return { kind: \"leave\" }\n }\n return { kind: \"veto\", model: recovery.model }\n}\n\n/**\n * Mode wrapper — the same core decision for Observe and Control; Observe\n * wraps it for receipt recording without intervening; OFF never touches\n * execution (the hook is not even registered, this keeps the union closed).\n */\nexport function forMode(decision: RetryCoreDecision, mode: OperatingMode): RetryDecision {\n switch (mode) {\n case \"active\":\n return decision\n case \"observe\":\n return { kind: \"observe-only\", would: decision }\n case \"off\":\n return { kind: \"leave\" }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/execution/retry/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/execution/retry/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA","sourcesContent":["export * from \"./types.js\"\nexport * from \"./decide.js\"\n"]}
|
|
@@ -54,7 +54,6 @@ export declare const MAX_VETOES_PER_UNIT = 4;
|
|
|
54
54
|
export type RetryCoreDecision = {
|
|
55
55
|
kind: "veto";
|
|
56
56
|
model: ModelRef;
|
|
57
|
-
probeId?: string | undefined;
|
|
58
57
|
} | {
|
|
59
58
|
kind: "leave";
|
|
60
59
|
};
|
|
@@ -63,4 +62,3 @@ export type RetryDecision = RetryCoreDecision | {
|
|
|
63
62
|
kind: "observe-only";
|
|
64
63
|
would: RetryCoreDecision;
|
|
65
64
|
};
|
|
66
|
-
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/execution/retry/types.ts"],"names":[],"mappings":"AAkCA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/execution/retry/types.ts"],"names":[],"mappings":"AAkCA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAA","sourcesContent":["import type { ModelRef } from \"../../core/work-unit/types.js\"\nimport type { FailureClassification } from \"../../health/classifier/types.js\"\n\n/**\n * Mirror of the host retry-hook decision shape (`SessionRetryDecision` from\n * `@opencode/plugin`). The execution core never imports the plugin package —\n * the adapter passes `hook.decision` straight through; the shapes are\n * structurally identical.\n */\nexport type NativeRetryDecision = { retry: false } | { retry: true; delay: number }\n\n/**\n * Horizontal-recovery option computed by the wiring for the failing work\n * unit, from the same tier (ADP-013). `none` means no healthy alternative\n * exists right now — OpenCode's native retry of the same resource is then\n * the preferred recovery. `switch` carries the candidate chosen by the\n * scheduler over the remaining tier candidates; `probeId` is present when\n * that candidate was admitted as a circuit-breaker probe.\n */\nexport type RecoveryOption =\n { kind: \"none\" } | { kind: \"switch\"; model: ModelRef; probeId?: string | undefined }\n\nexport interface RetryInput {\n /** Classification of the failure that triggered the retry hook. */\n readonly classification: FailureClassification\n /** The resource whose execution just failed. */\n readonly failingModel: ModelRef\n /** The host's own retry decision; left untouched unless we veto. */\n readonly native: NativeRetryDecision\n readonly recovery: RecoveryOption\n /** Vetoes already issued for this work unit (per-unit budget). */\n readonly vetoesUsed: number\n}\n\n/**\n * Per-work-unit budget on owned-recovery vetoes. Each veto switches to one\n * alternative; health state already blocks repeats, but the explicit budget\n * makes loop boundedness trivially provable (ADP-038). After exhaustion the\n * policy leaves OpenCode's native retry — its built-in max attempts are the\n * hard limit — and future units re-route fresh at safe boundaries.\n */\nexport const MAX_VETOES_PER_UNIT = 4\n\n/**\n * Core decision, mode-independent. `veto` takes ownership of recovery\n * (`{retry: false}` in the hook + a native continuation by switching to the\n * recovered candidate); `leave` keeps the host's own `decision` untouched.\n */\nexport type RetryCoreDecision = { kind: \"veto\"; model: ModelRef } | { kind: \"leave\" }\n\n/** Mode-wrapped decision. Observe records `would` without intervening. */\nexport type RetryDecision = RetryCoreDecision | { kind: \"observe-only\"; would: RetryCoreDecision }\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const n=require("solid-js/web"),
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const n=require("solid-js/web"),w=require("@opencode/plugin/gui"),u=require("solid-js"),M=require("@opencode/schema/rpc"),q=128,L="coool.adaptive",C="coool.adaptive",l={internal:f()};function r(e,t){return{"~standard":{version:1,vendor:C,validate:a=>e(a)?{value:a}:{issues:[{message:t}]}}}}function f(){return{"~standard":{version:1,vendor:C,validate:e=>e===void 0?{value:void 0}:{issues:[{message:"unexpected input: no input expected"}]}}}}const i=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),g=e=>typeof e=="string",m=e=>{if(!(i(e)&&g(e.sessionID)))return!1;const t=e.sessionID;return t.length>0&&t.length<=q},N=e=>i(e)&&g(e.sessionID)&&(e.mode===null||g(e.mode)),V=e=>i(e)&&g(e.sessionID)&&(e.tier===null||g(e.tier)),F=M.Rpc.define({id:L,methods:{"settings.get":{errors:l,input:f(),output:r(i,"output must be an object")},"settings.set":{errors:l,input:r(i,"input must be an object"),output:r(i,"output must be an object")},"status.get":{errors:l,input:f(),output:r(i,"output must be an object")},"receipts.list":{errors:l,input:f(),output:r(Array.isArray,"output must be an array")},"session-mode.get":{errors:l,input:r(m,"input must be an object with a sessionID string"),output:r(i,"output must be an object")},"session-mode.set":{errors:l,input:r(N,"input must be an object with a sessionID string and a mode string or null"),output:r(i,"output must be an object")},"tier-request.get":{errors:l,input:r(m,"input must be an object with a sessionID string"),output:r(i,"output must be an object")},"tier-request.set":{errors:l,input:r(V,"input must be an object with a sessionID string and a tier string or null"),output:r(i,"output must be an object")}},events:{"settings-changed":{schema:r(i,"event data must be an object")},"session-mode-changed":{schema:r(m,"event data must be an object with a sessionID string")},"tier-request-changed":{schema:r(m,"event data must be an object with a sessionID string")}}}),D=["off","observe","active"],G=["quick","standard","advanced"];function W(e){const t=e.rpc(F);return{status:()=>t["status.get"]().catch(()=>{}),receipts:()=>t["receipts.list"]().catch(()=>{}),update:async a=>{try{return(await t["settings.set"](a)).ok}catch{return!1}},watchSettings:a=>t.events.on("settings-changed",()=>{a()})}}function $(e){const t=`${e.providerID}/${e.id}`;return e.variant===void 0?t:`${t}@${e.variant}`}function x(e){if(e===void 0)return"";const t=[];return e.health!=="healthy"&&t.push(e.health),e.breaker==="open"?t.push("breaker-open"):e.breaker==="half_open"&&t.push("half-open"),e.windowed&&t.push("windowed"),t.length===0?"":` [${t.join(", ")}]`}function j(e){switch(e.kind){case"apply":{const t=e.tier===void 0?"":` [${e.tier}]`;return`apply ${$(e.model)}${t} (${e.reason})`}case"defer":{const t=e.detail===void 0?"":` — ${e.detail}`;return`defer: ${e.reason}${t}`}case"park":{const t=e.detail===void 0?"":` — ${e.detail}`;return`park: ${e.reason}${t}`}case"escalate":return`escalate ${e.step} → ${$(e.target)} [${e.tier}]`;case"observe-only":return`observe: ${j(e.would)}`}}function z(e){return e===void 0?"pending":e.status==="succeeded"?"succeeded":e.status==="failed"?`failed (${e.category})`:`interrupted (${e.reason})`}function H(e){return`#${String(e.id)} ${j(e.decision)} — ${z(e.outcome)}`}const J="connection";function X(e){if(e===void 0)return[{id:J,label:"Server",value:"disconnected",tone:"warning"}];const t=[{id:"mode",label:"Mode",value:e.mode},{id:"pin",label:"Pin",value:e.pin===null?"none":$(e.pin)}];for(const a of G){const c=e.tiers[a],S=c.length===0?"empty":c.map(b=>`${$(b.ref)}${x(b)}`).join(", ");t.push({id:`tier-${a}`,label:`Tier ${a}`,value:S})}return t.push({id:"parked",label:"Parked",value:String(e.parked)}),t.push({id:"receipts",label:"Receipts",value:String(e.receipts)}),t}function B(e){return D.map(t=>({value:t,title:t===e?`${t} (current)`:t}))}function K(e){return D.find(t=>t===e)}function Q(e){return e.map(t=>H(t))}var U=n.template("<span class=adaptive-saved role=status>Saved"),Y=n.template("<div class=adaptive-receipts>"),Z=n.template('<div class=adaptive-page><table class=adaptive-status aria-label="OpenCode Adaptive status"><tbody></tbody></table><label class=adaptive-mode><span class=adaptive-row-label>Mode</span><select class=adaptive-mode-select>'),ee=n.template("<tr class=adaptive-row><td class=adaptive-row-label></td><td class=adaptive-row-value>"),te=n.template("<option>"),ne=n.template("<div class=adaptive-receipt-line>");const re=5;function y(e){const[t,a]=u.createSignal(void 0),[c,S]=u.createSignal("observe"),[b,R]=u.createSignal([]),[A,E]=u.createSignal(!1),_=()=>{e.api.status().then(s=>{a(s),s!==void 0&&S(s.mode)}),e.api.receipts().then(s=>{R(s??[])})};u.onCleanup(e.api.watchSettings(_)),_();const P=s=>{const p=K(s.value);s.value=c(),p!==void 0&&e.api.update({mode:p}).then(I=>{E(I),_()})};return(()=>{var s=Z(),p=s.firstChild,I=p.firstChild,T=p.nextSibling,k=T.firstChild,h=k.nextSibling;return n.insert(I,n.createComponent(u.For,{get each(){return X(t())},children:o=>(()=>{var d=ee(),v=d.firstChild,O=v.nextSibling;return n.insert(v,()=>o.label),n.insert(O,()=>o.value),n.effect(()=>n.setAttribute(d,"data-tone",o.tone)),d})()})),h.addEventListener("change",o=>{P(o.currentTarget)}),n.insert(h,n.createComponent(u.For,{get each(){return B(c())},children:o=>(()=>{var d=te();return n.insert(d,()=>o.title),n.effect(()=>d.value=o.value),d})()})),n.insert(s,n.createComponent(u.Show,{get when(){return A()},get children(){return U()}}),null),n.insert(s,n.createComponent(u.Show,{get when(){return t()!==void 0},get children(){var o=Y();return n.insert(o,n.createComponent(u.For,{get each(){return Q(b()).slice(0,re)},children:d=>(()=>{var v=ne();return n.insert(v,d),v})()})),o}}),null),n.effect(()=>h.disabled=t()===void 0),n.effect(()=>h.value=c()),s})()}const se=w.Plugin.define({setup(e){const t=W(e.client);e.add(w.SettingsPage,{id:"adaptive",title:"OpenCode Adaptive",entries:[{id:"adaptive",title:"OpenCode Adaptive",description:"Execution tier routing, operating mode and resource health"}],render:()=>n.createComponent(y,{api:t})}),e.add(w.Command,{id:"open",title:"OpenCode Adaptive",group:"Adaptive",run:()=>{e.layout.settings("adaptive")}})}});exports.AdaptiveStatusPage=y;exports.default=se;
|
package/dist/gui.d.ts
CHANGED
package/dist/gui.js
CHANGED
|
@@ -25,8 +25,11 @@ export function AdaptiveStatusPage(props) {
|
|
|
25
25
|
};
|
|
26
26
|
onCleanup(props.api.watchSettings(refresh));
|
|
27
27
|
refresh();
|
|
28
|
-
const pick = (
|
|
29
|
-
const value = parseModeValue(
|
|
28
|
+
const pick = (select) => {
|
|
29
|
+
const value = parseModeValue(select.value);
|
|
30
|
+
// The DOM changes before onChange, even if the signal stays unchanged
|
|
31
|
+
// after a rejected write. Keep the control on the confirmed server value.
|
|
32
|
+
select.value = mode();
|
|
30
33
|
if (value === undefined)
|
|
31
34
|
return;
|
|
32
35
|
void props.api.update({ mode: value }).then((ok) => {
|
|
@@ -35,7 +38,7 @@ export function AdaptiveStatusPage(props) {
|
|
|
35
38
|
});
|
|
36
39
|
};
|
|
37
40
|
return (_jsxs("div", { class: "adaptive-page", children: [_jsx("table", { class: "adaptive-status", "aria-label": "OpenCode Adaptive status", children: _jsx("tbody", { children: _jsx(For, { each: statusRows(snapshot()), children: (row) => (_jsxs("tr", { class: "adaptive-row", "data-tone": row.tone, children: [_jsx("td", { class: "adaptive-row-label", children: row.label }), _jsx("td", { class: "adaptive-row-value", children: row.value })] })) }) }) }), _jsxs("label", { class: "adaptive-mode", children: [_jsx("span", { class: "adaptive-row-label", children: "Mode" }), _jsx("select", { class: "adaptive-mode-select", disabled: snapshot() === undefined, value: mode(), onChange: (event) => {
|
|
38
|
-
pick(event.currentTarget
|
|
41
|
+
pick(event.currentTarget);
|
|
39
42
|
}, children: _jsx(For, { each: modeChoices(mode()), children: (choice) => _jsx("option", { value: choice.value, children: choice.title }) }) })] }), _jsx(Show, { when: saved(), children: _jsx("span", { class: "adaptive-saved", role: "status", children: "Saved" }) }), _jsx(Show, { when: snapshot() !== undefined, children: _jsx("div", { class: "adaptive-receipts", children: _jsx(For, { each: receiptLines(receipts()).slice(0, RECEIPTS_PREVIEW_LIMIT), children: (line) => _jsx("div", { class: "adaptive-receipt-line", children: line }) }) }) })] }));
|
|
40
43
|
}
|
|
41
44
|
/**
|
package/dist/gui.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gui.js","sourceRoot":"","sources":["../src/gui.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAgB,MAAM,sBAAsB,CAAA;AAClF,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAM7D,OAAO,EAAE,cAAc,EAAe,MAAM,iBAAiB,CAAA;AAC7D,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAExF,MAAM,sBAAsB,GAAG,CAAC,CAAA;AAEhC;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAsB;IACvD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,YAAY,CAA6B,SAAS,CAAC,CAAA;IACnF,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,YAAY,CAAgB,SAAS,CAAC,CAAA;IAC9D,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,YAAY,CAAY,EAAE,CAAC,CAAA;IAC3D,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;IAE7C,MAAM,OAAO,GAAG,GAAS,EAAE;QACzB,KAAK,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YACpC,WAAW,CAAC,IAAI,CAAC,CAAA;YACjB,IAAI,IAAI,KAAK,SAAS;gBAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC5C,CAAC,CAAC,CAAA;QACF,KAAK,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YACtC,WAAW,CAAC,IAAI,IAAI,EAAE,CAAC,CAAA;QACzB,CAAC,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAA;IAC3C,OAAO,EAAE,CAAA;IAET,MAAM,IAAI,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"gui.js","sourceRoot":"","sources":["../src/gui.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Command, Plugin, SettingsPage, type Context } from \"@opencode/plugin/gui\"\nimport { For, Show, createSignal, onCleanup } from \"solid-js\"\nimport type { JSX } from \"solid-js\"\n\nimport type { OperatingMode } from \"./core/scheduler/types.js\"\nimport type { Receipt } from \"./state/receipts/index.js\"\nimport type { StatusSnapshot } from \"./rpc.js\"\nimport { adaptiveGuiApi, type GuiApi } from \"./ui/gui/api.js\"\nimport { modeChoices, parseModeValue, receiptLines, statusRows } from \"./ui/gui/view.js\"\n\nconst RECEIPTS_PREVIEW_LIMIT = 5\n\n/**\n * Native GUI settings page body (ADP-034). All data comes from the typed RPC adapter; the component holds no\n * local settings state. A failed read renders the disconnected row instead of stale data.\n */\nexport function AdaptiveStatusPage(props: { api: GuiApi }): JSX.Element {\n const [snapshot, setSnapshot] = createSignal<StatusSnapshot | undefined>(undefined)\n const [mode, setMode] = createSignal<OperatingMode>(\"observe\")\n const [receipts, setReceipts] = createSignal<Receipt[]>([])\n const [saved, setSaved] = createSignal(false)\n\n const refresh = (): void => {\n void props.api.status().then((next) => {\n setSnapshot(next)\n if (next !== undefined) setMode(next.mode)\n })\n void props.api.receipts().then((next) => {\n setReceipts(next ?? [])\n })\n }\n\n onCleanup(props.api.watchSettings(refresh))\n refresh()\n\n const pick = (select: HTMLSelectElement): void => {\n const value = parseModeValue(select.value)\n // The DOM changes before onChange, even if the signal stays unchanged\n // after a rejected write. Keep the control on the confirmed server value.\n select.value = mode()\n if (value === undefined) return\n void props.api.update({ mode: value }).then((ok) => {\n setSaved(ok)\n refresh()\n })\n }\n\n return (\n <div class=\"adaptive-page\">\n <table class=\"adaptive-status\" aria-label=\"OpenCode Adaptive status\">\n <tbody>\n <For each={statusRows(snapshot())}>\n {(row) => (\n <tr class=\"adaptive-row\" data-tone={row.tone}>\n <td class=\"adaptive-row-label\">{row.label}</td>\n <td class=\"adaptive-row-value\">{row.value}</td>\n </tr>\n )}\n </For>\n </tbody>\n </table>\n <label class=\"adaptive-mode\">\n <span class=\"adaptive-row-label\">Mode</span>\n <select\n class=\"adaptive-mode-select\"\n disabled={snapshot() === undefined}\n value={mode()}\n onChange={(event) => {\n pick(event.currentTarget)\n }}\n >\n <For each={modeChoices(mode())}>\n {(choice) => <option value={choice.value}>{choice.title}</option>}\n </For>\n </select>\n </label>\n <Show when={saved()}>\n <span class=\"adaptive-saved\" role=\"status\">\n Saved\n </span>\n </Show>\n <Show when={snapshot() !== undefined}>\n <div class=\"adaptive-receipts\">\n <For each={receiptLines(receipts()).slice(0, RECEIPTS_PREVIEW_LIMIT)}>\n {(line) => <div class=\"adaptive-receipt-line\">{line}</div>}\n </For>\n </div>\n </Show>\n </div>\n )\n}\n\n/**\n * GUI plugin entry (the `./gui-experimental` bundle default export). Thin adapter: registers a native\n * SettingsPage and a palette command that opens it; no routing logic lives here (ADP-034/035).\n */\nexport default Plugin.define({\n setup(context: Context): void {\n const api = adaptiveGuiApi(context.client)\n context.add(SettingsPage, {\n id: \"adaptive\",\n title: \"OpenCode Adaptive\",\n entries: [\n {\n id: \"adaptive\",\n title: \"OpenCode Adaptive\",\n description: \"Execution tier routing, operating mode and resource health\",\n },\n ],\n render: () => <AdaptiveStatusPage api={api} />,\n })\n context.add(Command, {\n id: \"open\",\n title: \"OpenCode Adaptive\",\n group: \"Adaptive\",\n run: () => {\n context.layout.settings(\"adaptive\")\n },\n })\n },\n})\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/health/capacity/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/health/capacity/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA","sourcesContent":["export * from \"./merge.js\"\nexport * from \"./registry.js\"\nexport * from \"./types.js\"\n"]}
|
|
@@ -55,4 +55,3 @@ export declare function capacitySignals(reading: CapacityReading, config?: Capac
|
|
|
55
55
|
* scheduler wiring decides when to observe it; this function only shapes it.
|
|
56
56
|
*/
|
|
57
57
|
export declare function capacityHealthEvent(key: ResourceKey, reading: CapacityReading): HealthEvent;
|
|
58
|
-
//# sourceMappingURL=merge.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge.js","sourceRoot":"","sources":["../../../src/health/capacity/merge.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"merge.js","sourceRoot":"","sources":["../../../src/health/capacity/merge.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Deterministic capacity merge semantics (ADP-020).\n *\n * Several sensors may observe the same resource (e.g. passive headers and an\n * optional quota endpoint). The merge picks one coherent story instead of\n * synthesizing chimera numbers: readings are prioritized by confidence, then\n * by conservativeness (lower remaining ratio first), then by input order, and\n * each measured field is taken from the first reading in priority order that\n * supplies it. Trust is reduced, never amplified:\n *\n * - the merged confidence is the LOWEST confidence among all surviving fresh\n * readings, because any concurrent contradictory observation unsettles the\n * whole picture (a sensor that merely corroborates still shares its doubt);\n * - `observedAt` is the oldest surviving observation, so the merged reading\n * ages honestly;\n * - `evidence` follows the base (highest-priority) reading, which owns the\n * merged story.\n *\n * Exact bounds are facts, not estimates: `remainingRatio === 0` or\n * `usedRatio === 1` signals exhaustion at any confidence, while the softer\n * `draining` signal requires `high` confidence (ADP-021). Anything that is\n * not a well-formed measurement is rejected — untrusted data becomes \"no\n * estimate\", never a guess.\n */\nimport type { HealthEvent, ResourceKey } from \"../resource-health/types.js\"\nimport {\n CONFIDENCE_LEVELS,\n type CapacityConfig,\n type CapacityReading,\n type CapacitySignals,\n DEFAULT_CAPACITY_CONFIG,\n type Confidence,\n} from \"./types.js\"\n\n/** Evidence labels are bounded so unbounded header text cannot be persisted. */\nexport const MAX_EVIDENCE_LENGTH = 128\n\nexport function confidenceRank(confidence: Confidence): number {\n return CONFIDENCE_LEVELS.indexOf(confidence)\n}\n\nfunction isFiniteNumber(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value)\n}\n\nfunction isValidRatio(value: unknown): value is number {\n return isFiniteNumber(value) && value >= 0 && value <= 1\n}\n\n/**\n * Re-validates a reading field by field. A reading with an invalid ratio is\n * rejected entirely (its numbers cannot be partially trusted); invalid\n * `retryAfterMs`/`resetAt` values only drop their own field. A reading with\n * no measured field left is discarded as pure noise.\n */\nexport function normalizeReading(reading: unknown): CapacityReading | null {\n if (typeof reading !== \"object\" || reading === null) {\n return null\n }\n const candidate = reading as CapacityReading\n if (!CONFIDENCE_LEVELS.includes(candidate.confidence)) {\n return null\n }\n if (!isFiniteNumber(candidate.observedAt) || candidate.observedAt < 0) {\n return null\n }\n if (\n (candidate.usedRatio !== undefined && !isValidRatio(candidate.usedRatio)) ||\n (candidate.remainingRatio !== undefined && !isValidRatio(candidate.remainingRatio))\n ) {\n return null\n }\n const retryAfterMs =\n candidate.retryAfterMs !== undefined &&\n isFiniteNumber(candidate.retryAfterMs) &&\n Number.isInteger(candidate.retryAfterMs) &&\n candidate.retryAfterMs >= 0\n ? candidate.retryAfterMs\n : undefined\n const resetAt =\n isFiniteNumber(candidate.resetAt) && candidate.resetAt >= 0 ? candidate.resetAt : undefined\n const evidence =\n typeof candidate.evidence === \"string\"\n ? candidate.evidence.slice(0, MAX_EVIDENCE_LENGTH)\n : undefined\n if (\n candidate.usedRatio === undefined &&\n candidate.remainingRatio === undefined &&\n retryAfterMs === undefined &&\n resetAt === undefined\n ) {\n return null\n }\n return {\n ...(candidate.usedRatio !== undefined ? { usedRatio: candidate.usedRatio } : {}),\n ...(candidate.remainingRatio !== undefined ? { remainingRatio: candidate.remainingRatio } : {}),\n ...(retryAfterMs !== undefined ? { retryAfterMs } : {}),\n ...(resetAt !== undefined ? { resetAt } : {}),\n confidence: candidate.confidence,\n observedAt: candidate.observedAt,\n ...(evidence !== undefined ? { evidence } : {}),\n }\n}\n\nfunction isFresh(reading: CapacityReading, now: number, config: CapacityConfig): boolean {\n return now - reading.observedAt <= config.maxAgeMs\n}\n\n/**\n * Strict priority between two readings: higher confidence wins; on equal\n * confidence the more conservative remaining ratio wins (a missing remaining\n * ratio cannot prove scarcity, so it counts as the least conservative value).\n * Equal readings keep their relative order.\n */\nfunction strictlyHigherPriority(candidate: CapacityReading, incumbent: CapacityReading): boolean {\n const byConfidence = confidenceRank(candidate.confidence) - confidenceRank(incumbent.confidence)\n if (byConfidence !== 0) {\n return byConfidence > 0\n }\n const candidateRemaining = candidate.remainingRatio ?? 1\n const incumbentRemaining = incumbent.remainingRatio ?? 1\n return candidateRemaining < incumbentRemaining\n}\n\n/**\n * Merges concurrent readings for one resource. Returns `null` when nothing\n * survives normalization and the freshness window — an explicit \"no estimate\".\n *\n * Selection runs over the input order with a strict priority comparator, so\n * ties keep the earliest reading and both comparator outcomes stay reachable.\n */\nexport function mergeReadings(\n readings: readonly CapacityReading[],\n now: number,\n config: CapacityConfig = DEFAULT_CAPACITY_CONFIG,\n): CapacityReading | null {\n const survivors = readings\n .map(normalizeReading)\n .filter((reading): reading is CapacityReading => reading !== null)\n .filter((reading) => isFresh(reading, now, config))\n if (survivors.length === 0) {\n return null\n }\n const base = survivors.reduce((best, reading) =>\n strictlyHigherPriority(reading, best) ? reading : best,\n )\n const bestField = <T>(pick: (reading: CapacityReading) => T | undefined): T | undefined => {\n let best: CapacityReading | undefined\n let bestValue: T | undefined\n for (const reading of survivors) {\n const value = pick(reading)\n if (value === undefined) {\n continue\n }\n if (best === undefined || strictlyHigherPriority(reading, best)) {\n best = reading\n bestValue = value\n }\n }\n return bestValue\n }\n const usedRatio = bestField((reading) => reading.usedRatio)\n const remainingRatio = bestField((reading) => reading.remainingRatio)\n const retryAfterMs = bestField((reading) => reading.retryAfterMs)\n const resetAt = bestField((reading) => reading.resetAt)\n const confidence = survivors.reduce<Confidence>(\n (lowest, reading) =>\n confidenceRank(reading.confidence) < confidenceRank(lowest) ? reading.confidence : lowest,\n base.confidence,\n )\n const observedAt = Math.min(...survivors.map((reading) => reading.observedAt))\n return {\n ...(usedRatio !== undefined ? { usedRatio } : {}),\n ...(remainingRatio !== undefined ? { remainingRatio } : {}),\n ...(retryAfterMs !== undefined ? { retryAfterMs } : {}),\n ...(resetAt !== undefined ? { resetAt } : {}),\n confidence,\n observedAt,\n ...(base.evidence !== undefined ? { evidence: base.evidence } : {}),\n }\n}\n\n/**\n * Drain/exhaust derivation. Exhaustion is signaled by exact bounds at any\n * confidence (a header stating zero remaining is a fact, not a guess);\n * draining additionally requires `high` confidence because it withdraws new\n * work before hard evidence exists (ADP-021).\n */\nexport function capacitySignals(\n reading: CapacityReading,\n config: CapacityConfig = DEFAULT_CAPACITY_CONFIG,\n): CapacitySignals {\n const exhausted = reading.remainingRatio === 0 || reading.usedRatio === 1\n const draining =\n !exhausted &&\n reading.confidence === \"high\" &&\n ((reading.remainingRatio !== undefined &&\n reading.remainingRatio <= config.drainingRemainingThreshold) ||\n (reading.usedRatio !== undefined &&\n reading.usedRatio >= 1 - config.drainingRemainingThreshold))\n return { exhausted, draining }\n}\n\n/**\n * Pure bridge to the health layer: converts a merged reading into the\n * capacity event consumed by resource-health transitions (ADP-021). The\n * scheduler wiring decides when to observe it; this function only shapes it.\n */\nexport function capacityHealthEvent(key: ResourceKey, reading: CapacityReading): HealthEvent {\n return {\n kind: \"capacity\",\n key,\n exhausted: capacitySignals(reading).exhausted,\n ...(reading.retryAfterMs !== undefined ? { retryAfterMs: reading.retryAfterMs } : {}),\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/health/capacity/registry.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/health/capacity/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAGxE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAO7E,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAapD,MAAM,OAAO,gBAAgB;IAClB,MAAM,CAAO;IACb,OAAO,CAAgB;IACvB,QAAQ,GAAG,IAAI,GAAG,EAAuB,CAAA;IACzC,SAAS,GAAG,IAAI,GAAG,EAAU,CAAA;IAEtC,YAAY,KAAY,EAAE,SAAyB,uBAAuB;QACxE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAA;QACnB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;IACvB,CAAC;IAED,6EAA6E;IAC7E,QAAQ,CAAC,MAAsB;QAC7B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;IACxD,CAAC;IAED,0DAA0D;IAC1D,UAAU,CAAC,EAAU;QACnB,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IACjC,CAAC;IAED;;;;OAIG;IACH,QAAQ;QACN,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACjD,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ;YAC/B,MAAM,EAAE,KAAK,CAAC,MAAM;SACrB,CAAC,CAAC,CAAA;IACL,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,OAAO;QACX,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;QAC3C,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAC1E,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,KAAkB;QAClC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,CAAA;QAC1B,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YAC3B,OAAM;QACR,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACtB,IAAI,CAAC;YACH,IAAI,OAAO,GAA2B,IAAI,CAAA;YAC1C,IAAI,CAAC;gBACH,OAAO,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAA;YACrC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,GAAG,IAAI,CAAA;YAChB,CAAC;YACD,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YACrC,IAAI,OAAO,EAAE,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;gBACrC,OAAO,CAAC,MAAM,GAAG,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;YACtE,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QAC3B,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,OAAO,CAAC,GAAgB;QACtB,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAA;QAC/D,MAAM,UAAU,GAAsB,EAAE,CAAA;QACxC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YAC3C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;gBACxD,SAAQ;YACV,CAAC;YACD,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;gBAC1B,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;YAC/B,CAAC;QACH,CAAC;QACD,OAAO,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;IAC/D,CAAC;IAED;;;OAGG;IACH,UAAU,CAAC,GAAgB;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QACjC,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;QACzB,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAA;IACvF,CAAC;CACF","sourcesContent":["/**\n * Capacity registry: owns sensors, refreshes them, and answers scheduler\n * queries (ADP-020). Pull-based and timer-free — the wiring layer decides\n * when to refresh; queries sweep for staleness lazily, mirroring the\n * resource-health registry.\n *\n * Lookups are hierarchical: a sensor attached to any ancestor of the queried\n * key (provider → account → model → variant) contributes to it, so a\n * provider- or account-wide quota reading covers its models without each\n * model needing its own sensor.\n */\nimport { resourceChain, resourceKeyID } from \"../resource-health/key.js\"\nimport type { Clock } from \"../resource-health/types.js\"\nimport type { ResourceKey } from \"../resource-health/types.js\"\nimport { capacitySignals, mergeReadings, normalizeReading } from \"./merge.js\"\nimport type {\n CapacityAssessment,\n CapacityConfig,\n CapacityReading,\n CapacitySensor,\n} from \"./types.js\"\nimport { DEFAULT_CAPACITY_CONFIG } from \"./types.js\"\n\ninterface SensorEntry {\n readonly sensor: CapacitySensor\n latest: CapacityReading | null\n}\n\n/** One registry snapshot row: the sensor's resource and its latest reading. */\nexport interface SensorSnapshot {\n readonly resource: ResourceKey\n readonly latest: CapacityReading | null\n}\n\nexport class CapacityRegistry {\n readonly #clock: Clock\n readonly #config: CapacityConfig\n readonly #sensors = new Map<string, SensorEntry>()\n readonly #inFlight = new Set<string>()\n\n constructor(clock: Clock, config: CapacityConfig = DEFAULT_CAPACITY_CONFIG) {\n this.#clock = clock\n this.#config = config\n }\n\n /** Registers a sensor; re-registering an id replaces its previous sensor. */\n register(sensor: CapacitySensor): void {\n this.#sensors.set(sensor.id, { sensor, latest: null })\n }\n\n /** Removes a sensor; returns whether an entry existed. */\n unregister(id: string): boolean {\n return this.#sensors.delete(id)\n }\n\n /**\n * Every registered sensor's latest reading alongside the resource it\n * observes. The persisted-mirror path uses this to save what any instance\n * observed; an entry whose sensor has no reading yet carries `null`.\n */\n snapshot(): readonly SensorSnapshot[] {\n return [...this.#sensors.values()].map((entry) => ({\n resource: entry.sensor.resource,\n latest: entry.latest,\n }))\n }\n\n /**\n * Reads every sensor registered at call time once. A sensor already being\n * read is skipped (its in-flight result will land) so concurrent refreshes\n * never hammer a quota endpoint. A sensor that throws or returns malformed\n * data stores \"no observation\" — fail-open, never a guess. A sensor\n * unregistered or replaced while its read is in flight stores nothing.\n */\n async refresh(): Promise<void> {\n const entries = [...this.#sensors.values()]\n await Promise.all(entries.map(async (entry) => this.#readSensor(entry)))\n }\n\n async #readSensor(entry: SensorEntry): Promise<void> {\n const id = entry.sensor.id\n if (this.#inFlight.has(id)) {\n return\n }\n this.#inFlight.add(id)\n try {\n let reading: CapacityReading | null = null\n try {\n reading = await entry.sensor.read()\n } catch {\n reading = null\n }\n const current = this.#sensors.get(id)\n if (current?.sensor === entry.sensor) {\n current.latest = reading === null ? null : normalizeReading(reading)\n }\n } finally {\n this.#inFlight.delete(id)\n }\n }\n\n /**\n * Merged reading for a resource, from sensors at the key itself or any of\n * its ancestors. `null` means no fresh trustworthy estimate.\n */\n reading(key: ResourceKey): CapacityReading | null {\n const chainIDs = new Set(resourceChain(key).map(resourceKeyID))\n const candidates: CapacityReading[] = []\n for (const entry of this.#sensors.values()) {\n if (!chainIDs.has(resourceKeyID(entry.sensor.resource))) {\n continue\n }\n if (entry.latest !== null) {\n candidates.push(entry.latest)\n }\n }\n return mergeReadings(candidates, this.#clock(), this.#config)\n }\n\n /**\n * Scheduler-facing assessment for a resource. `none` is unknown capacity —\n * callers must not interpret it as healthy.\n */\n assessment(key: ResourceKey): CapacityAssessment {\n const reading = this.reading(key)\n if (reading === null) {\n return { kind: \"none\" }\n }\n return { kind: \"estimate\", reading, signals: capacitySignals(reading, this.#config) }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/health/capacity/types.ts"],"names":[],"mappings":"AAcA,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAsC,CAAA;AAgD/F,MAAM,CAAC,MAAM,uBAAuB,GAAmB;IACrD,QAAQ,EAAE,MAAM;IAChB,0BAA0B,EAAE,GAAG;CAChC,CAAA"}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/health/capacity/types.ts"],"names":[],"mappings":"AAcA,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAsC,CAAA;AAgD/F,MAAM,CAAC,MAAM,uBAAuB,GAAmB;IACrD,QAAQ,EAAE,MAAM;IAChB,0BAA0B,EAAE,GAAG;CAChC,CAAA","sourcesContent":["/**\n * Capacity sensor boundary (ADP-020).\n *\n * Capacity is observed, never inferred: a sensor reports what its telemetry\n * actually shows (used/remaining ratios, retry-after, reset time) and grades\n * its own confidence. A `null` reading or assessment means \"no trustworthy\n * estimate\" — callers must treat that as unknown, never as healthy. Provider\n * specific sensing (passive Codex headers, optional quota endpoints) lives in\n * adapters; this module owns the boundary type, the deterministic merge of\n * concurrent readings for one resource, and the derivation of the\n * draining/exhausted signals consumed by the health layer (ADP-021).\n */\nimport type { ResourceKey } from \"../resource-health/types.js\"\n\nexport const CONFIDENCE_LEVELS = [\"low\", \"medium\", \"high\"] as const satisfies readonly string[]\n\n/** How much a sensor trusts its own numbers. `high` is required for draining. */\nexport type Confidence = (typeof CONFIDENCE_LEVELS)[number]\n\n/**\n * One observation of a resource's capacity. Ratios are fractions in [0, 1].\n * A reading may carry any subset of the measured fields (e.g. a header that\n * only reports a Retry-After); a reading with none of them carries no\n * information and is discarded. `observedAt` is when the underlying telemetry\n * was seen, not when the sensor was asked.\n */\nexport interface CapacityReading {\n readonly usedRatio?: number | undefined\n readonly remainingRatio?: number | undefined\n readonly retryAfterMs?: number | undefined\n /** Epoch milliseconds at which capacity is expected to reset. */\n readonly resetAt?: number | undefined\n readonly confidence: Confidence\n readonly observedAt: number\n /** Bounded, secret-free label of the data source (e.g. a header name). */\n readonly evidence?: string | undefined\n}\n\n/** A source of capacity observations for exactly one resource. */\nexport interface CapacitySensor {\n readonly id: string\n readonly resource: ResourceKey\n /**\n * Returns the latest reading, or `null` when the sensor has no trustworthy\n * estimate. Expected \"no data\" must be returned as `null`, never thrown;\n * the registry still guards against throws (fail-open: a failing sensor is\n * no estimate, not an error).\n */\n read(): Promise<CapacityReading | null>\n}\n\nexport interface CapacityConfig {\n /** Readings older than this are treated as absent (no estimate). */\n readonly maxAgeMs: number\n /**\n * Near-exhaustion bound at or below which high-confidence evidence marks\n * the resource `draining` (ADP-021). A fixed product constant, deliberately\n * not user-configurable — no threshold sliders.\n */\n readonly drainingRemainingThreshold: number\n}\n\nexport const DEFAULT_CAPACITY_CONFIG: CapacityConfig = {\n maxAgeMs: 60_000,\n drainingRemainingThreshold: 0.1,\n}\n\n/** Drain/exhaust derivation for a merged reading. */\nexport interface CapacitySignals {\n readonly exhausted: boolean\n readonly draining: boolean\n}\n\n/**\n * Scheduler-facing view for one resource. `none` is the explicit \"no\n * estimate\" answer — unknown capacity, not zero capacity.\n */\nexport type CapacityAssessment =\n | { readonly kind: \"none\" }\n | {\n readonly kind: \"estimate\"\n readonly reading: CapacityReading\n readonly signals: CapacitySignals\n }\n"]}
|