open-multi-agent-kit 1.0.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +52 -1
- package/README.md +2 -2
- package/dist/approval-api.d.ts +5 -0
- package/dist/approval-api.d.ts.map +1 -0
- package/dist/approval-api.js +5 -0
- package/dist/approval-api.js.map +1 -0
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +1 -0
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/session-picker.d.ts +2 -2
- package/dist/cli/session-picker.d.ts.map +1 -1
- package/dist/cli/session-picker.js.map +1 -1
- package/dist/commands/verified-run-cli.d.ts.map +1 -1
- package/dist/commands/verified-run-cli.js +69 -22
- package/dist/commands/verified-run-cli.js.map +1 -1
- package/dist/commands/verified-run-signal.d.ts +3 -0
- package/dist/commands/verified-run-signal.d.ts.map +1 -0
- package/dist/commands/verified-run-signal.js +15 -0
- package/dist/commands/verified-run-signal.js.map +1 -0
- package/dist/coordination/awareness.d.ts +32 -0
- package/dist/coordination/awareness.d.ts.map +1 -0
- package/dist/coordination/awareness.js +55 -0
- package/dist/coordination/awareness.js.map +1 -0
- package/dist/coordination/broker.d.ts +79 -0
- package/dist/coordination/broker.d.ts.map +1 -0
- package/dist/coordination/broker.js +202 -0
- package/dist/coordination/broker.js.map +1 -0
- package/dist/coordination/index.d.ts +16 -0
- package/dist/coordination/index.d.ts.map +1 -0
- package/dist/coordination/index.js +16 -0
- package/dist/coordination/index.js.map +1 -0
- package/dist/coordination/integration.d.ts +59 -0
- package/dist/coordination/integration.d.ts.map +1 -0
- package/dist/coordination/integration.js +126 -0
- package/dist/coordination/integration.js.map +1 -0
- package/dist/coordination/operation.d.ts +107 -0
- package/dist/coordination/operation.d.ts.map +1 -0
- package/dist/coordination/operation.js +231 -0
- package/dist/coordination/operation.js.map +1 -0
- package/dist/coordination/resource.d.ts +33 -0
- package/dist/coordination/resource.d.ts.map +1 -0
- package/dist/coordination/resource.js +95 -0
- package/dist/coordination/resource.js.map +1 -0
- package/dist/coordination/session.d.ts +74 -0
- package/dist/coordination/session.d.ts.map +1 -0
- package/dist/coordination/session.js +143 -0
- package/dist/coordination/session.js.map +1 -0
- package/dist/coordination/types.d.ts +68 -0
- package/dist/coordination/types.d.ts.map +1 -0
- package/dist/coordination/types.js +26 -0
- package/dist/coordination/types.js.map +1 -0
- package/dist/core/adaptorch-bridge.d.ts +1 -1
- package/dist/core/adaptorch-bridge.d.ts.map +1 -1
- package/dist/core/adaptorch-bridge.js +1 -1
- package/dist/core/adaptorch-bridge.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +16 -16
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +35 -15
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/canonical-json.d.ts +3 -0
- package/dist/core/canonical-json.d.ts.map +1 -0
- package/dist/core/canonical-json.js +20 -0
- package/dist/core/canonical-json.js.map +1 -0
- package/dist/core/compaction/compaction.d.ts +7 -3
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +14 -29
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/control-state.d.ts +41 -0
- package/dist/core/compaction/control-state.d.ts.map +1 -0
- package/dist/core/compaction/control-state.js +85 -0
- package/dist/core/compaction/control-state.js.map +1 -0
- package/dist/core/compaction/fallback.d.ts +71 -0
- package/dist/core/compaction/fallback.d.ts.map +1 -0
- package/dist/core/compaction/fallback.js +118 -0
- package/dist/core/compaction/fallback.js.map +1 -0
- package/dist/core/compaction/index.d.ts +2 -0
- package/dist/core/compaction/index.d.ts.map +1 -1
- package/dist/core/compaction/index.js +2 -0
- package/dist/core/compaction/index.js.map +1 -1
- package/dist/core/compaction/model-failover.d.ts +21 -0
- package/dist/core/compaction/model-failover.d.ts.map +1 -0
- package/dist/core/compaction/model-failover.js +46 -0
- package/dist/core/compaction/model-failover.js.map +1 -0
- package/dist/core/compaction/session-summary.d.ts +21 -0
- package/dist/core/compaction/session-summary.d.ts.map +1 -0
- package/dist/core/compaction/session-summary.js +27 -0
- package/dist/core/compaction/session-summary.js.map +1 -0
- package/dist/core/context-budget-headroom-candidates.d.ts +16 -1
- package/dist/core/context-budget-headroom-candidates.d.ts.map +1 -1
- package/dist/core/context-budget-headroom-candidates.js +31 -13
- package/dist/core/context-budget-headroom-candidates.js.map +1 -1
- package/dist/core/context-budget-headroom-types.d.ts +7 -1
- package/dist/core/context-budget-headroom-types.d.ts.map +1 -1
- package/dist/core/context-budget-headroom-types.js +0 -1
- package/dist/core/context-budget-headroom-types.js.map +1 -1
- package/dist/core/context-budget-headroom.d.ts +10 -0
- package/dist/core/context-budget-headroom.d.ts.map +1 -1
- package/dist/core/context-budget-headroom.js +11 -2
- package/dist/core/context-budget-headroom.js.map +1 -1
- package/dist/core/context-budget-v2-global-pass.d.ts +21 -0
- package/dist/core/context-budget-v2-global-pass.d.ts.map +1 -0
- package/dist/core/context-budget-v2-global-pass.js +203 -0
- package/dist/core/context-budget-v2-global-pass.js.map +1 -0
- package/dist/core/context-budget-v2-planned-items.d.ts +12 -0
- package/dist/core/context-budget-v2-planned-items.d.ts.map +1 -1
- package/dist/core/context-budget-v2-planned-items.js +21 -2
- package/dist/core/context-budget-v2-planned-items.js.map +1 -1
- package/dist/core/context-budget-v2-planner.d.ts.map +1 -1
- package/dist/core/context-budget-v2-planner.js +18 -19
- package/dist/core/context-budget-v2-planner.js.map +1 -1
- package/dist/core/context-budget-v2-scoring.d.ts +7 -1
- package/dist/core/context-budget-v2-scoring.d.ts.map +1 -1
- package/dist/core/context-budget-v2-scoring.js.map +1 -1
- package/dist/core/context-budget-v2-selection.d.ts +3 -0
- package/dist/core/context-budget-v2-selection.d.ts.map +1 -1
- package/dist/core/context-budget-v2-selection.js +6 -2
- package/dist/core/context-budget-v2-selection.js.map +1 -1
- package/dist/core/context-budget-v2-types.d.ts +6 -1
- package/dist/core/context-budget-v2-types.d.ts.map +1 -1
- package/dist/core/context-budget-v2-types.js +6 -1
- package/dist/core/context-budget-v2-types.js.map +1 -1
- package/dist/core/export-html/template.js +14 -0
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/session-lifecycle-types.d.ts +14 -0
- package/dist/core/extensions/session-lifecycle-types.d.ts.map +1 -0
- package/dist/core/extensions/session-lifecycle-types.js +2 -0
- package/dist/core/extensions/session-lifecycle-types.js.map +1 -0
- package/dist/core/extensions/types.d.ts +4 -9
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js +10 -1
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +3 -6
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/legacy-resource-policy.d.ts +7 -0
- package/dist/core/legacy-resource-policy.d.ts.map +1 -0
- package/dist/core/legacy-resource-policy.js +9 -0
- package/dist/core/legacy-resource-policy.js.map +1 -0
- package/dist/core/mcp/config.d.ts.map +1 -1
- package/dist/core/mcp/config.js +17 -3
- package/dist/core/mcp/config.js.map +1 -1
- package/dist/core/mcp/connection-queue.d.ts +12 -0
- package/dist/core/mcp/connection-queue.d.ts.map +1 -0
- package/dist/core/mcp/connection-queue.js +46 -0
- package/dist/core/mcp/connection-queue.js.map +1 -0
- package/dist/core/mcp/manager-runtime.d.ts +55 -0
- package/dist/core/mcp/manager-runtime.d.ts.map +1 -0
- package/dist/core/mcp/manager-runtime.js +66 -0
- package/dist/core/mcp/manager-runtime.js.map +1 -0
- package/dist/core/mcp/manager.d.ts +12 -68
- package/dist/core/mcp/manager.d.ts.map +1 -1
- package/dist/core/mcp/manager.js +33 -113
- package/dist/core/mcp/manager.js.map +1 -1
- package/dist/core/mcp/protocol.d.ts.map +1 -1
- package/dist/core/mcp/protocol.js +70 -40
- package/dist/core/mcp/protocol.js.map +1 -1
- package/dist/core/package-manager.d.ts +4 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +59 -129
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/package-resource-patterns.d.ts +7 -0
- package/dist/core/package-resource-patterns.d.ts.map +1 -0
- package/dist/core/package-resource-patterns.js +99 -0
- package/dist/core/package-resource-patterns.js.map +1 -0
- package/dist/core/provider-default-models.d.ts +1 -0
- package/dist/core/provider-default-models.d.ts.map +1 -1
- package/dist/core/provider-default-models.js +1 -0
- package/dist/core/provider-default-models.js.map +1 -1
- package/dist/core/provider-display-names.d.ts.map +1 -1
- package/dist/core/provider-display-names.js +1 -0
- package/dist/core/provider-display-names.js.map +1 -1
- package/dist/core/provider-resilience.d.ts +9 -0
- package/dist/core/provider-resilience.d.ts.map +1 -1
- package/dist/core/provider-resilience.js +15 -0
- package/dist/core/provider-resilience.js.map +1 -1
- package/dist/core/reasoning-router-resolver.d.ts +7 -0
- package/dist/core/reasoning-router-resolver.d.ts.map +1 -1
- package/dist/core/reasoning-router-resolver.js +21 -3
- package/dist/core/reasoning-router-resolver.js.map +1 -1
- package/dist/core/reasoning-router-v4.d.ts +13 -7
- package/dist/core/reasoning-router-v4.d.ts.map +1 -1
- package/dist/core/reasoning-router-v4.js +8 -5
- package/dist/core/reasoning-router-v4.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +4 -8
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/run-execution-api.d.ts +8 -1
- package/dist/core/run-execution-api.d.ts.map +1 -1
- package/dist/core/run-execution-api.js +4 -0
- package/dist/core/run-execution-api.js.map +1 -1
- package/dist/core/run-journal.d.ts +1 -2
- package/dist/core/run-journal.d.ts.map +1 -1
- package/dist/core/run-journal.js +2 -19
- package/dist/core/run-journal.js.map +1 -1
- package/dist/core/session-compaction-service.d.ts +15 -0
- package/dist/core/session-compaction-service.d.ts.map +1 -1
- package/dist/core/session-compaction-service.js +17 -4
- package/dist/core/session-compaction-service.js.map +1 -1
- package/dist/core/session-listing.d.ts +51 -0
- package/dist/core/session-listing.d.ts.map +1 -0
- package/dist/core/session-listing.js +111 -0
- package/dist/core/session-listing.js.map +1 -0
- package/dist/core/session-manager.d.ts +12 -37
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +12 -118
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-message-text.d.ts +5 -0
- package/dist/core/session-message-text.d.ts.map +1 -0
- package/dist/core/session-message-text.js +9 -0
- package/dist/core/session-message-text.js.map +1 -0
- package/dist/core/skills-catalog-cache.d.ts +2 -0
- package/dist/core/skills-catalog-cache.d.ts.map +1 -1
- package/dist/core/skills-catalog-cache.js +71 -17
- package/dist/core/skills-catalog-cache.js.map +1 -1
- package/dist/core/todo-runtime-state.d.ts +12 -0
- package/dist/core/todo-runtime-state.d.ts.map +1 -1
- package/dist/core/todo-runtime-state.js +23 -0
- package/dist/core/todo-runtime-state.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +1 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/verified-run/authority-clock.d.ts +3 -0
- package/dist/core/verified-run/authority-clock.d.ts.map +1 -0
- package/dist/core/verified-run/authority-clock.js +25 -0
- package/dist/core/verified-run/authority-clock.js.map +1 -0
- package/dist/core/verified-run/authority-errors.d.ts +10 -0
- package/dist/core/verified-run/authority-errors.d.ts.map +1 -0
- package/dist/core/verified-run/authority-errors.js +17 -0
- package/dist/core/verified-run/authority-errors.js.map +1 -0
- package/dist/core/verified-run/authority-events.d.ts +126 -0
- package/dist/core/verified-run/authority-events.d.ts.map +1 -0
- package/dist/core/verified-run/authority-events.js +482 -0
- package/dist/core/verified-run/authority-events.js.map +1 -0
- package/dist/core/verified-run/authority-journal.d.ts +27 -0
- package/dist/core/verified-run/authority-journal.d.ts.map +1 -0
- package/dist/core/verified-run/authority-journal.js +83 -0
- package/dist/core/verified-run/authority-journal.js.map +1 -0
- package/dist/core/verified-run/authority-meaning.d.ts +13 -0
- package/dist/core/verified-run/authority-meaning.d.ts.map +1 -0
- package/dist/core/verified-run/authority-meaning.js +40 -0
- package/dist/core/verified-run/authority-meaning.js.map +1 -0
- package/dist/core/verified-run/authority-runtime.d.ts +82 -0
- package/dist/core/verified-run/authority-runtime.d.ts.map +1 -0
- package/dist/core/verified-run/authority-runtime.js +169 -0
- package/dist/core/verified-run/authority-runtime.js.map +1 -0
- package/dist/core/verified-run/authority-store.d.ts +204 -0
- package/dist/core/verified-run/authority-store.d.ts.map +1 -0
- package/dist/core/verified-run/authority-store.js +852 -0
- package/dist/core/verified-run/authority-store.js.map +1 -0
- package/dist/core/verified-run/broker.d.ts +8 -1
- package/dist/core/verified-run/broker.d.ts.map +1 -1
- package/dist/core/verified-run/broker.js +94 -90
- package/dist/core/verified-run/broker.js.map +1 -1
- package/dist/core/verified-run/candidate-policy.d.ts +10 -0
- package/dist/core/verified-run/candidate-policy.d.ts.map +1 -0
- package/dist/core/verified-run/candidate-policy.js +33 -0
- package/dist/core/verified-run/candidate-policy.js.map +1 -0
- package/dist/core/verified-run/candidate.d.ts.map +1 -1
- package/dist/core/verified-run/candidate.js +5 -10
- package/dist/core/verified-run/candidate.js.map +1 -1
- package/dist/core/verified-run/coordinator.d.ts +35 -17
- package/dist/core/verified-run/coordinator.d.ts.map +1 -1
- package/dist/core/verified-run/coordinator.js +111 -57
- package/dist/core/verified-run/coordinator.js.map +1 -1
- package/dist/core/verified-run/dag-phase.d.ts.map +1 -1
- package/dist/core/verified-run/dag-phase.js +1 -1
- package/dist/core/verified-run/dag-phase.js.map +1 -1
- package/dist/core/verified-run/dag-recovery.d.ts +5 -1
- package/dist/core/verified-run/dag-recovery.d.ts.map +1 -1
- package/dist/core/verified-run/dag-recovery.js +10 -4
- package/dist/core/verified-run/dag-recovery.js.map +1 -1
- package/dist/core/verified-run/event-parser.d.ts.map +1 -1
- package/dist/core/verified-run/event-parser.js +33 -0
- package/dist/core/verified-run/event-parser.js.map +1 -1
- package/dist/core/verified-run/evidence-read-projection.d.ts +4 -0
- package/dist/core/verified-run/evidence-read-projection.d.ts.map +1 -0
- package/dist/core/verified-run/evidence-read-projection.js +27 -0
- package/dist/core/verified-run/evidence-read-projection.js.map +1 -0
- package/dist/core/verified-run/evidence.d.ts +12 -1
- package/dist/core/verified-run/evidence.d.ts.map +1 -1
- package/dist/core/verified-run/evidence.js +51 -2
- package/dist/core/verified-run/evidence.js.map +1 -1
- package/dist/core/verified-run/git-candidate-preflight.d.ts +4 -0
- package/dist/core/verified-run/git-candidate-preflight.d.ts.map +1 -0
- package/dist/core/verified-run/git-candidate-preflight.js +34 -0
- package/dist/core/verified-run/git-candidate-preflight.js.map +1 -0
- package/dist/core/verified-run/git-effect-supervisor.d.ts +24 -0
- package/dist/core/verified-run/git-effect-supervisor.d.ts.map +1 -0
- package/dist/core/verified-run/git-effect-supervisor.js +174 -0
- package/dist/core/verified-run/git-effect-supervisor.js.map +1 -0
- package/dist/core/verified-run/git-execution.d.ts +27 -0
- package/dist/core/verified-run/git-execution.d.ts.map +1 -0
- package/dist/core/verified-run/git-execution.js +118 -0
- package/dist/core/verified-run/git-execution.js.map +1 -0
- package/dist/core/verified-run/git-plumbing.d.ts +37 -0
- package/dist/core/verified-run/git-plumbing.d.ts.map +1 -0
- package/dist/core/verified-run/git-plumbing.js +171 -0
- package/dist/core/verified-run/git-plumbing.js.map +1 -0
- package/dist/core/verified-run/git-publication-worker.d.ts +2 -0
- package/dist/core/verified-run/git-publication-worker.d.ts.map +1 -0
- package/dist/core/verified-run/git-publication-worker.js +54 -0
- package/dist/core/verified-run/git-publication-worker.js.map +1 -0
- package/dist/core/verified-run/git-sandbox-layout.d.ts +4 -0
- package/dist/core/verified-run/git-sandbox-layout.d.ts.map +1 -0
- package/dist/core/verified-run/git-sandbox-layout.js +29 -0
- package/dist/core/verified-run/git-sandbox-layout.js.map +1 -0
- package/dist/core/verified-run/git-worker-protocol.d.ts +19 -0
- package/dist/core/verified-run/git-worker-protocol.d.ts.map +1 -0
- package/dist/core/verified-run/git-worker-protocol.js +109 -0
- package/dist/core/verified-run/git-worker-protocol.js.map +1 -0
- package/dist/core/verified-run/git-worker-runtime.d.ts +19 -0
- package/dist/core/verified-run/git-worker-runtime.d.ts.map +1 -0
- package/dist/core/verified-run/git-worker-runtime.js +74 -0
- package/dist/core/verified-run/git-worker-runtime.js.map +1 -0
- package/dist/core/verified-run/journal.d.ts +2 -3
- package/dist/core/verified-run/journal.d.ts.map +1 -1
- package/dist/core/verified-run/journal.js.map +1 -1
- package/dist/core/verified-run/namespace-identity.d.ts.map +1 -1
- package/dist/core/verified-run/namespace-identity.js +1 -1
- package/dist/core/verified-run/namespace-identity.js.map +1 -1
- package/dist/core/verified-run/owned-execution.d.ts +10 -1
- package/dist/core/verified-run/owned-execution.d.ts.map +1 -1
- package/dist/core/verified-run/owned-execution.js +124 -31
- package/dist/core/verified-run/owned-execution.js.map +1 -1
- package/dist/core/verified-run/phase-context.d.ts +2 -0
- package/dist/core/verified-run/phase-context.d.ts.map +1 -1
- package/dist/core/verified-run/phase-context.js.map +1 -1
- package/dist/core/verified-run/projection.d.ts.map +1 -1
- package/dist/core/verified-run/projection.js +51 -1
- package/dist/core/verified-run/projection.js.map +1 -1
- package/dist/core/verified-run/publish-preflight.d.ts +12 -0
- package/dist/core/verified-run/publish-preflight.d.ts.map +1 -0
- package/dist/core/verified-run/publish-preflight.js +38 -0
- package/dist/core/verified-run/publish-preflight.js.map +1 -0
- package/dist/core/verified-run/publish-start.d.ts +5 -0
- package/dist/core/verified-run/publish-start.d.ts.map +1 -0
- package/dist/core/verified-run/publish-start.js +7 -0
- package/dist/core/verified-run/publish-start.js.map +1 -0
- package/dist/core/verified-run/recovery-projection.d.ts.map +1 -1
- package/dist/core/verified-run/recovery-projection.js +5 -0
- package/dist/core/verified-run/recovery-projection.js.map +1 -1
- package/dist/core/verified-run/recovery.d.ts +5 -1
- package/dist/core/verified-run/recovery.d.ts.map +1 -1
- package/dist/core/verified-run/recovery.js +10 -4
- package/dist/core/verified-run/recovery.js.map +1 -1
- package/dist/core/verified-run/run-plan.d.ts +17 -0
- package/dist/core/verified-run/run-plan.d.ts.map +1 -0
- package/dist/core/verified-run/run-plan.js +18 -0
- package/dist/core/verified-run/run-plan.js.map +1 -0
- package/dist/core/verified-run/run-publish-owned.d.ts +6 -0
- package/dist/core/verified-run/run-publish-owned.d.ts.map +1 -0
- package/dist/core/verified-run/run-publish-owned.js +199 -0
- package/dist/core/verified-run/run-publish-owned.js.map +1 -0
- package/dist/core/verified-run/run-publish.d.ts +19 -0
- package/dist/core/verified-run/run-publish.d.ts.map +1 -0
- package/dist/core/verified-run/run-publish.js +210 -0
- package/dist/core/verified-run/run-publish.js.map +1 -0
- package/dist/core/verified-run/run-status-owned.d.ts +4 -0
- package/dist/core/verified-run/run-status-owned.d.ts.map +1 -0
- package/dist/core/verified-run/run-status-owned.js +14 -0
- package/dist/core/verified-run/run-status-owned.js.map +1 -0
- package/dist/core/verified-run/run-status.d.ts +133 -0
- package/dist/core/verified-run/run-status.d.ts.map +1 -0
- package/dist/core/verified-run/run-status.js +193 -0
- package/dist/core/verified-run/run-status.js.map +1 -0
- package/dist/core/verified-run/run-types.d.ts +31 -0
- package/dist/core/verified-run/run-types.d.ts.map +1 -1
- package/dist/core/verified-run/run-types.js.map +1 -1
- package/dist/core/verified-run/storage.d.ts.map +1 -1
- package/dist/core/verified-run/storage.js +1 -1
- package/dist/core/verified-run/storage.js.map +1 -1
- package/dist/core/verified-run/supervisor-adapter.d.ts +77 -0
- package/dist/core/verified-run/supervisor-adapter.d.ts.map +1 -0
- package/dist/core/verified-run/supervisor-adapter.js +164 -0
- package/dist/core/verified-run/supervisor-adapter.js.map +1 -0
- package/dist/core/verified-run/verification-phase.d.ts.map +1 -1
- package/dist/core/verified-run/verification-phase.js +1 -1
- package/dist/core/verified-run/verification-phase.js.map +1 -1
- package/dist/core/verified-run/writer-phase.d.ts.map +1 -1
- package/dist/core/verified-run/writer-phase.js +1 -0
- package/dist/core/verified-run/writer-phase.js.map +1 -1
- package/dist/core/verified-run/writer-recovery.d.ts +2 -0
- package/dist/core/verified-run/writer-recovery.d.ts.map +1 -1
- package/dist/core/verified-run/writer-recovery.js +1 -0
- package/dist/core/verified-run/writer-recovery.js.map +1 -1
- package/dist/core/workload-shard-execution-types.d.ts +4 -1
- package/dist/core/workload-shard-execution-types.d.ts.map +1 -1
- package/dist/core/workload-shard-execution-types.js.map +1 -1
- package/dist/core/workload-shard-executor.d.ts +2 -2
- package/dist/core/workload-shard-executor.d.ts.map +1 -1
- package/dist/core/workload-shard-executor.js +16 -37
- package/dist/core/workload-shard-executor.js.map +1 -1
- package/dist/core/workload-shard-frontier.d.ts +5 -0
- package/dist/core/workload-shard-frontier.d.ts.map +1 -0
- package/dist/core/workload-shard-frontier.js +47 -0
- package/dist/core/workload-shard-frontier.js.map +1 -0
- package/dist/core/workload-shard-runner.d.ts.map +1 -1
- package/dist/core/workload-shard-runner.js +28 -17
- package/dist/core/workload-shard-runner.js.map +1 -1
- package/dist/index.d.ts +4 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +2 -1
- package/dist/main.js.map +1 -1
- package/dist/metacognition/bridge-result.d.ts +148 -0
- package/dist/metacognition/bridge-result.d.ts.map +1 -0
- package/dist/metacognition/bridge-result.js +46 -0
- package/dist/metacognition/bridge-result.js.map +1 -0
- package/dist/metacognition/calibration-selective.d.ts +78 -0
- package/dist/metacognition/calibration-selective.d.ts.map +1 -0
- package/dist/metacognition/calibration-selective.js +167 -0
- package/dist/metacognition/calibration-selective.js.map +1 -0
- package/dist/metacognition/calibration.d.ts +62 -0
- package/dist/metacognition/calibration.d.ts.map +1 -0
- package/dist/metacognition/calibration.js +122 -0
- package/dist/metacognition/calibration.js.map +1 -0
- package/dist/metacognition/checkpoint.d.ts +60 -0
- package/dist/metacognition/checkpoint.d.ts.map +1 -0
- package/dist/metacognition/checkpoint.js +57 -0
- package/dist/metacognition/checkpoint.js.map +1 -0
- package/dist/metacognition/context7.d.ts +48 -0
- package/dist/metacognition/context7.d.ts.map +1 -0
- package/dist/metacognition/context7.js +154 -0
- package/dist/metacognition/context7.js.map +1 -0
- package/dist/metacognition/decision.d.ts +44 -0
- package/dist/metacognition/decision.d.ts.map +1 -0
- package/dist/metacognition/decision.js +111 -0
- package/dist/metacognition/decision.js.map +1 -0
- package/dist/metacognition/evaluation.d.ts +73 -0
- package/dist/metacognition/evaluation.d.ts.map +1 -0
- package/dist/metacognition/evaluation.js +97 -0
- package/dist/metacognition/evaluation.js.map +1 -0
- package/dist/metacognition/index.d.ts +32 -0
- package/dist/metacognition/index.d.ts.map +1 -0
- package/dist/metacognition/index.js +32 -0
- package/dist/metacognition/index.js.map +1 -0
- package/dist/metacognition/knowledge-action.d.ts +43 -0
- package/dist/metacognition/knowledge-action.d.ts.map +1 -0
- package/dist/metacognition/knowledge-action.js +60 -0
- package/dist/metacognition/knowledge-action.js.map +1 -0
- package/dist/metacognition/knowledge.d.ts +84 -0
- package/dist/metacognition/knowledge.d.ts.map +1 -0
- package/dist/metacognition/knowledge.js +165 -0
- package/dist/metacognition/knowledge.js.map +1 -0
- package/dist/metacognition/obligations.d.ts +82 -0
- package/dist/metacognition/obligations.d.ts.map +1 -0
- package/dist/metacognition/obligations.js +139 -0
- package/dist/metacognition/obligations.js.map +1 -0
- package/dist/metacognition/observation-validity.d.ts +83 -0
- package/dist/metacognition/observation-validity.d.ts.map +1 -0
- package/dist/metacognition/observation-validity.js +118 -0
- package/dist/metacognition/observation-validity.js.map +1 -0
- package/dist/metacognition/observe.d.ts +45 -0
- package/dist/metacognition/observe.d.ts.map +1 -0
- package/dist/metacognition/observe.js +59 -0
- package/dist/metacognition/observe.js.map +1 -0
- package/dist/metacognition/policy.d.ts +53 -0
- package/dist/metacognition/policy.d.ts.map +1 -0
- package/dist/metacognition/policy.js +155 -0
- package/dist/metacognition/policy.js.map +1 -0
- package/dist/metacognition/predictions.d.ts +78 -0
- package/dist/metacognition/predictions.d.ts.map +1 -0
- package/dist/metacognition/predictions.js +181 -0
- package/dist/metacognition/predictions.js.map +1 -0
- package/dist/metacognition/retrieval.d.ts +53 -0
- package/dist/metacognition/retrieval.d.ts.map +1 -0
- package/dist/metacognition/retrieval.js +170 -0
- package/dist/metacognition/retrieval.js.map +1 -0
- package/dist/metacognition/risk.d.ts +48 -0
- package/dist/metacognition/risk.d.ts.map +1 -0
- package/dist/metacognition/risk.js +179 -0
- package/dist/metacognition/risk.js.map +1 -0
- package/dist/metacognition/route-economics.d.ts +95 -0
- package/dist/metacognition/route-economics.d.ts.map +1 -0
- package/dist/metacognition/route-economics.js +110 -0
- package/dist/metacognition/route-economics.js.map +1 -0
- package/dist/metacognition/runtime-bridge.d.ts +81 -0
- package/dist/metacognition/runtime-bridge.d.ts.map +1 -0
- package/dist/metacognition/runtime-bridge.js +458 -0
- package/dist/metacognition/runtime-bridge.js.map +1 -0
- package/dist/metacognition/skills.d.ts +42 -0
- package/dist/metacognition/skills.d.ts.map +1 -0
- package/dist/metacognition/skills.js +220 -0
- package/dist/metacognition/skills.js.map +1 -0
- package/dist/metacognition/state.d.ts +110 -0
- package/dist/metacognition/state.d.ts.map +1 -0
- package/dist/metacognition/state.js +52 -0
- package/dist/metacognition/state.js.map +1 -0
- package/dist/metacognition/validation.d.ts +19 -0
- package/dist/metacognition/validation.d.ts.map +1 -0
- package/dist/metacognition/validation.js +58 -0
- package/dist/metacognition/validation.js.map +1 -0
- package/dist/metacognition/verification.d.ts +93 -0
- package/dist/metacognition/verification.d.ts.map +1 -0
- package/dist/metacognition/verification.js +132 -0
- package/dist/metacognition/verification.js.map +1 -0
- package/dist/metacognition/verifier.d.ts +49 -0
- package/dist/metacognition/verifier.d.ts.map +1 -0
- package/dist/metacognition/verifier.js +88 -0
- package/dist/metacognition/verifier.js.map +1 -0
- package/dist/modes/interactive/components/assistant-message.d.ts +2 -0
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +42 -26
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/chat-container.d.ts +7 -0
- package/dist/modes/interactive/components/chat-container.d.ts.map +1 -0
- package/dist/modes/interactive/components/chat-container.js +14 -0
- package/dist/modes/interactive/components/chat-container.js.map +1 -0
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.js +4 -2
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +0 -1
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-async-search.d.ts +33 -0
- package/dist/modes/interactive/components/session-selector-async-search.d.ts.map +1 -0
- package/dist/modes/interactive/components/session-selector-async-search.js +109 -0
- package/dist/modes/interactive/components/session-selector-async-search.js.map +1 -0
- package/dist/modes/interactive/components/session-selector-loaders.d.ts +6 -0
- package/dist/modes/interactive/components/session-selector-loaders.d.ts.map +1 -0
- package/dist/modes/interactive/components/session-selector-loaders.js +9 -0
- package/dist/modes/interactive/components/session-selector-loaders.js.map +1 -0
- package/dist/modes/interactive/components/session-selector-search.d.ts +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-tree.d.ts +16 -0
- package/dist/modes/interactive/components/session-selector-tree.d.ts.map +1 -0
- package/dist/modes/interactive/components/session-selector-tree.js +46 -0
- package/dist/modes/interactive/components/session-selector-tree.js.map +1 -0
- package/dist/modes/interactive/components/session-selector.d.ts +6 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +36 -76
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution-images.d.ts +32 -0
- package/dist/modes/interactive/components/tool-execution-images.d.ts.map +1 -0
- package/dist/modes/interactive/components/tool-execution-images.js +144 -0
- package/dist/modes/interactive/components/tool-execution-images.js.map +1 -0
- package/dist/modes/interactive/components/tool-execution.d.ts +3 -4
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +22 -71
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +7 -9
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/tui-diagnostics.d.ts +8 -4
- package/dist/modes/interactive/tui-diagnostics.d.ts.map +1 -1
- package/dist/modes/interactive/tui-diagnostics.js +35 -1
- package/dist/modes/interactive/tui-diagnostics.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +14 -17
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-response.d.ts +5 -0
- package/dist/modes/rpc/rpc-response.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-response.js +17 -0
- package/dist/modes/rpc/rpc-response.js.map +1 -0
- package/dist/observation/identity.d.ts +14 -0
- package/dist/observation/identity.d.ts.map +1 -0
- package/dist/observation/identity.js +29 -0
- package/dist/observation/identity.js.map +1 -0
- package/dist/observation/index.d.ts +13 -0
- package/dist/observation/index.d.ts.map +1 -0
- package/dist/observation/index.js +13 -0
- package/dist/observation/index.js.map +1 -0
- package/dist/observation/observe-mode.d.ts +46 -0
- package/dist/observation/observe-mode.d.ts.map +1 -0
- package/dist/observation/observe-mode.js +83 -0
- package/dist/observation/observe-mode.js.map +1 -0
- package/dist/observation/store.d.ts +53 -0
- package/dist/observation/store.d.ts.map +1 -0
- package/dist/observation/store.js +126 -0
- package/dist/observation/store.js.map +1 -0
- package/dist/observation/types.d.ts +72 -0
- package/dist/observation/types.d.ts.map +1 -0
- package/dist/observation/types.js +9 -0
- package/dist/observation/types.js.map +1 -0
- package/dist/observation/view.d.ts +39 -0
- package/dist/observation/view.d.ts.map +1 -0
- package/dist/observation/view.js +173 -0
- package/dist/observation/view.js.map +1 -0
- package/dist/utils/exif-orientation.d.ts.map +1 -1
- package/dist/utils/exif-orientation.js +2 -3
- package/dist/utils/exif-orientation.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +3 -5
- package/dist/utils/tools-manager.js.map +1 -1
- package/docs/adaptorch-preview-spec.md +7 -7
- package/docs/atomic-commit-planning.md +69 -0
- package/docs/compaction.md +26 -1
- package/docs/extensions.md +14 -0
- package/docs/mcp.md +22 -0
- package/docs/metacognition.md +130 -0
- package/docs/model-catalog-refresh.md +218 -1
- package/docs/models.md +1 -1
- package/docs/providers.md +53 -0
- package/docs/runtime-algorithms.md +156 -7
- package/docs/session-format.md +8 -0
- package/docs/sessions.md +19 -0
- package/docs/skills.md +19 -0
- package/docs/terminal-setup.md +15 -0
- package/docs/tui.md +41 -0
- package/docs/verified-run-safety.md +75 -0
- package/examples/extensions/custom-provider-anthropic/index.ts +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/doom-overlay/wad-finder.ts +7 -3
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +18 -18
- package/package.json +6 -8
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control-state.d.ts","sourceRoot":"","sources":["../../../src/core/compaction/control-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAUH,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAWD,qGAAqG;AACrG,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,sBAAsB,GAAG,IAAI,GAAG,sBAAsB,GAAG,IAAI,CAcxG;AAED;;;;GAIG;AACH;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAO5D;AAED,kFAAkF;AAClF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,sBAAsB,GAAG,IAAI,GAAG;IAC7E,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,CAOA;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,sBAAsB,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAYtF","sourcesContent":["/**\n * Host control snapshot bound into a compaction envelope's preserved provenance.\n *\n * A natural-language summary cannot restore the obligation set: if the only\n * record of \"what is still open\" is prose the summarizer wrote, a dropped line\n * silently closes real work. The host supplies this structured snapshot\n * instead, and the compaction commit compares its digest so a summary generated\n * under different control state is discarded rather than committed.\n *\n * Producer output is untrusted input here: malformed shapes fail closed instead\n * of degrading into an empty-but-valid checkpoint, which would look like\n * \"nothing was open\" to every later reader.\n */\n\nimport { createHash } from \"node:crypto\";\nimport { sanitizeBinaryOutput } from \"../../utils/shell.ts\";\nimport { redactSensitiveTextForced } from \"../redaction.ts\";\nimport { redactCredentialShapedContent } from \"./transaction.ts\";\n\n/** Envelope validators reject credential shapes and control characters outright. */\nconst MAX_PROVENANCE_TEXT = 4096;\n\nexport interface CompactionControlState {\n\treadonly openTasks: readonly string[];\n\treadonly blockerReasons: readonly string[];\n\treadonly branch: string | null;\n}\n\nconst MAX_CONTROL_STATE_ITEMS = 1024;\nconst MAX_CONTROL_STATE_TEXT = 16_384;\n\nfunction assertControlStateText(value: unknown, field: string): asserts value is string {\n\tif (typeof value !== \"string\" || value.length > MAX_CONTROL_STATE_TEXT) {\n\t\tthrow new TypeError(`control state ${field} must be a bounded string`);\n\t}\n}\n\n/** Validate producer output; malformed input fails closed, never degrades to an empty checkpoint. */\nexport function validateControlState(value: CompactionControlState | null): CompactionControlState | null {\n\tif (value === null) return null;\n\tif (typeof value !== \"object\" || Array.isArray(value)) {\n\t\tthrow new TypeError(\"control state must be an object or null\");\n\t}\n\tfor (const field of [\"openTasks\", \"blockerReasons\"] as const) {\n\t\tconst list = value[field];\n\t\tif (!Array.isArray(list) || list.length > MAX_CONTROL_STATE_ITEMS) {\n\t\t\tthrow new TypeError(`control state ${field} must be a bounded array`);\n\t\t}\n\t\tfor (const item of list) assertControlStateText(item, `${field} item`);\n\t}\n\tif (value.branch !== null) assertControlStateText(value.branch, \"branch\");\n\treturn value;\n}\n\n/**\n * Digest the snapshot deterministically. Null stays null so \"no control\n * authority attached\" stays distinguishable from \"authority reporting nothing\n * open\" — the transition between them is itself a change worth discarding on.\n */\n/**\n * Make one control-state string safe for the envelope validators.\n *\n * Returns `[REDACTED]` rather than an empty string when sanitization consumes\n * everything: the validators reject empty entries, and dropping the entry would\n * quietly reduce the open-task count instead of preserving that work exists.\n */\nexport function sanitizeProvenanceText(value: string): string {\n\tconst sanitized = redactCredentialShapedContent(\n\t\tsanitizeBinaryOutput(redactSensitiveTextForced(value.trim()))\n\t\t\t.replace(/[\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f\\u007f]/gu, \"\")\n\t\t\t.slice(0, MAX_PROVENANCE_TEXT),\n\t);\n\treturn sanitized.length > 0 ? sanitized : \"[REDACTED]\";\n}\n\n/** Project a control snapshot onto the envelope's preserved-provenance fields. */\nexport function controlStateProvenance(state: CompactionControlState | null): {\n\treadonly openTasks: readonly string[];\n\treadonly blockerReasons: readonly string[];\n\treadonly branch: string | null;\n} {\n\tif (state === null) return { openTasks: [], blockerReasons: [], branch: null };\n\treturn {\n\t\topenTasks: state.openTasks.map(sanitizeProvenanceText),\n\t\tblockerReasons: state.blockerReasons.map(sanitizeProvenanceText),\n\t\tbranch: state.branch == null ? null : sanitizeProvenanceText(state.branch),\n\t};\n}\n\nexport function controlStateDigest(state: CompactionControlState | null): string | null {\n\tif (state === null) return null;\n\treturn createHash(\"sha256\")\n\t\t.update(\n\t\t\tJSON.stringify({\n\t\t\t\topenTasks: [...state.openTasks],\n\t\t\t\tblockerReasons: [...state.blockerReasons],\n\t\t\t\tbranch: state.branch,\n\t\t\t}),\n\t\t\t\"utf8\",\n\t\t)\n\t\t.digest(\"hex\");\n}\n"]}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host control snapshot bound into a compaction envelope's preserved provenance.
|
|
3
|
+
*
|
|
4
|
+
* A natural-language summary cannot restore the obligation set: if the only
|
|
5
|
+
* record of "what is still open" is prose the summarizer wrote, a dropped line
|
|
6
|
+
* silently closes real work. The host supplies this structured snapshot
|
|
7
|
+
* instead, and the compaction commit compares its digest so a summary generated
|
|
8
|
+
* under different control state is discarded rather than committed.
|
|
9
|
+
*
|
|
10
|
+
* Producer output is untrusted input here: malformed shapes fail closed instead
|
|
11
|
+
* of degrading into an empty-but-valid checkpoint, which would look like
|
|
12
|
+
* "nothing was open" to every later reader.
|
|
13
|
+
*/
|
|
14
|
+
import { createHash } from "node:crypto";
|
|
15
|
+
import { sanitizeBinaryOutput } from "../../utils/shell.js";
|
|
16
|
+
import { redactSensitiveTextForced } from "../redaction.js";
|
|
17
|
+
import { redactCredentialShapedContent } from "./transaction.js";
|
|
18
|
+
/** Envelope validators reject credential shapes and control characters outright. */
|
|
19
|
+
const MAX_PROVENANCE_TEXT = 4096;
|
|
20
|
+
const MAX_CONTROL_STATE_ITEMS = 1024;
|
|
21
|
+
const MAX_CONTROL_STATE_TEXT = 16_384;
|
|
22
|
+
function assertControlStateText(value, field) {
|
|
23
|
+
if (typeof value !== "string" || value.length > MAX_CONTROL_STATE_TEXT) {
|
|
24
|
+
throw new TypeError(`control state ${field} must be a bounded string`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/** Validate producer output; malformed input fails closed, never degrades to an empty checkpoint. */
|
|
28
|
+
export function validateControlState(value) {
|
|
29
|
+
if (value === null)
|
|
30
|
+
return null;
|
|
31
|
+
if (typeof value !== "object" || Array.isArray(value)) {
|
|
32
|
+
throw new TypeError("control state must be an object or null");
|
|
33
|
+
}
|
|
34
|
+
for (const field of ["openTasks", "blockerReasons"]) {
|
|
35
|
+
const list = value[field];
|
|
36
|
+
if (!Array.isArray(list) || list.length > MAX_CONTROL_STATE_ITEMS) {
|
|
37
|
+
throw new TypeError(`control state ${field} must be a bounded array`);
|
|
38
|
+
}
|
|
39
|
+
for (const item of list)
|
|
40
|
+
assertControlStateText(item, `${field} item`);
|
|
41
|
+
}
|
|
42
|
+
if (value.branch !== null)
|
|
43
|
+
assertControlStateText(value.branch, "branch");
|
|
44
|
+
return value;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Digest the snapshot deterministically. Null stays null so "no control
|
|
48
|
+
* authority attached" stays distinguishable from "authority reporting nothing
|
|
49
|
+
* open" — the transition between them is itself a change worth discarding on.
|
|
50
|
+
*/
|
|
51
|
+
/**
|
|
52
|
+
* Make one control-state string safe for the envelope validators.
|
|
53
|
+
*
|
|
54
|
+
* Returns `[REDACTED]` rather than an empty string when sanitization consumes
|
|
55
|
+
* everything: the validators reject empty entries, and dropping the entry would
|
|
56
|
+
* quietly reduce the open-task count instead of preserving that work exists.
|
|
57
|
+
*/
|
|
58
|
+
export function sanitizeProvenanceText(value) {
|
|
59
|
+
const sanitized = redactCredentialShapedContent(sanitizeBinaryOutput(redactSensitiveTextForced(value.trim()))
|
|
60
|
+
.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/gu, "")
|
|
61
|
+
.slice(0, MAX_PROVENANCE_TEXT));
|
|
62
|
+
return sanitized.length > 0 ? sanitized : "[REDACTED]";
|
|
63
|
+
}
|
|
64
|
+
/** Project a control snapshot onto the envelope's preserved-provenance fields. */
|
|
65
|
+
export function controlStateProvenance(state) {
|
|
66
|
+
if (state === null)
|
|
67
|
+
return { openTasks: [], blockerReasons: [], branch: null };
|
|
68
|
+
return {
|
|
69
|
+
openTasks: state.openTasks.map(sanitizeProvenanceText),
|
|
70
|
+
blockerReasons: state.blockerReasons.map(sanitizeProvenanceText),
|
|
71
|
+
branch: state.branch == null ? null : sanitizeProvenanceText(state.branch),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
export function controlStateDigest(state) {
|
|
75
|
+
if (state === null)
|
|
76
|
+
return null;
|
|
77
|
+
return createHash("sha256")
|
|
78
|
+
.update(JSON.stringify({
|
|
79
|
+
openTasks: [...state.openTasks],
|
|
80
|
+
blockerReasons: [...state.blockerReasons],
|
|
81
|
+
branch: state.branch,
|
|
82
|
+
}), "utf8")
|
|
83
|
+
.digest("hex");
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=control-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control-state.js","sourceRoot":"","sources":["../../../src/core/compaction/control-state.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Host control snapshot bound into a compaction envelope's preserved provenance.\n *\n * A natural-language summary cannot restore the obligation set: if the only\n * record of \"what is still open\" is prose the summarizer wrote, a dropped line\n * silently closes real work. The host supplies this structured snapshot\n * instead, and the compaction commit compares its digest so a summary generated\n * under different control state is discarded rather than committed.\n *\n * Producer output is untrusted input here: malformed shapes fail closed instead\n * of degrading into an empty-but-valid checkpoint, which would look like\n * \"nothing was open\" to every later reader.\n */\n\nimport { createHash } from \"node:crypto\";\nimport { sanitizeBinaryOutput } from \"../../utils/shell.ts\";\nimport { redactSensitiveTextForced } from \"../redaction.ts\";\nimport { redactCredentialShapedContent } from \"./transaction.ts\";\n\n/** Envelope validators reject credential shapes and control characters outright. */\nconst MAX_PROVENANCE_TEXT = 4096;\n\nexport interface CompactionControlState {\n\treadonly openTasks: readonly string[];\n\treadonly blockerReasons: readonly string[];\n\treadonly branch: string | null;\n}\n\nconst MAX_CONTROL_STATE_ITEMS = 1024;\nconst MAX_CONTROL_STATE_TEXT = 16_384;\n\nfunction assertControlStateText(value: unknown, field: string): asserts value is string {\n\tif (typeof value !== \"string\" || value.length > MAX_CONTROL_STATE_TEXT) {\n\t\tthrow new TypeError(`control state ${field} must be a bounded string`);\n\t}\n}\n\n/** Validate producer output; malformed input fails closed, never degrades to an empty checkpoint. */\nexport function validateControlState(value: CompactionControlState | null): CompactionControlState | null {\n\tif (value === null) return null;\n\tif (typeof value !== \"object\" || Array.isArray(value)) {\n\t\tthrow new TypeError(\"control state must be an object or null\");\n\t}\n\tfor (const field of [\"openTasks\", \"blockerReasons\"] as const) {\n\t\tconst list = value[field];\n\t\tif (!Array.isArray(list) || list.length > MAX_CONTROL_STATE_ITEMS) {\n\t\t\tthrow new TypeError(`control state ${field} must be a bounded array`);\n\t\t}\n\t\tfor (const item of list) assertControlStateText(item, `${field} item`);\n\t}\n\tif (value.branch !== null) assertControlStateText(value.branch, \"branch\");\n\treturn value;\n}\n\n/**\n * Digest the snapshot deterministically. Null stays null so \"no control\n * authority attached\" stays distinguishable from \"authority reporting nothing\n * open\" — the transition between them is itself a change worth discarding on.\n */\n/**\n * Make one control-state string safe for the envelope validators.\n *\n * Returns `[REDACTED]` rather than an empty string when sanitization consumes\n * everything: the validators reject empty entries, and dropping the entry would\n * quietly reduce the open-task count instead of preserving that work exists.\n */\nexport function sanitizeProvenanceText(value: string): string {\n\tconst sanitized = redactCredentialShapedContent(\n\t\tsanitizeBinaryOutput(redactSensitiveTextForced(value.trim()))\n\t\t\t.replace(/[\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f\\u007f]/gu, \"\")\n\t\t\t.slice(0, MAX_PROVENANCE_TEXT),\n\t);\n\treturn sanitized.length > 0 ? sanitized : \"[REDACTED]\";\n}\n\n/** Project a control snapshot onto the envelope's preserved-provenance fields. */\nexport function controlStateProvenance(state: CompactionControlState | null): {\n\treadonly openTasks: readonly string[];\n\treadonly blockerReasons: readonly string[];\n\treadonly branch: string | null;\n} {\n\tif (state === null) return { openTasks: [], blockerReasons: [], branch: null };\n\treturn {\n\t\topenTasks: state.openTasks.map(sanitizeProvenanceText),\n\t\tblockerReasons: state.blockerReasons.map(sanitizeProvenanceText),\n\t\tbranch: state.branch == null ? null : sanitizeProvenanceText(state.branch),\n\t};\n}\n\nexport function controlStateDigest(state: CompactionControlState | null): string | null {\n\tif (state === null) return null;\n\treturn createHash(\"sha256\")\n\t\t.update(\n\t\t\tJSON.stringify({\n\t\t\t\topenTasks: [...state.openTasks],\n\t\t\t\tblockerReasons: [...state.blockerReasons],\n\t\t\t\tbranch: state.branch,\n\t\t\t}),\n\t\t\t\"utf8\",\n\t\t)\n\t\t.digest(\"hex\");\n}\n"]}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What to do when compaction summarization cannot run.
|
|
3
|
+
*
|
|
4
|
+
* The resilience ladder, in order:
|
|
5
|
+
* 1. the resolved compaction model (caller's `summarize`),
|
|
6
|
+
* 2. the live session model — a pinned `compaction.model` can be quota-dead
|
|
7
|
+
* while the model the user is actively talking to still serves traffic,
|
|
8
|
+
* 3. a deterministic trim that needs no model at all.
|
|
9
|
+
*
|
|
10
|
+
* Step 3 exists because the alternative is stranding the run: once context is
|
|
11
|
+
* over the window, a failed compaction means no later turn can succeed until
|
|
12
|
+
* the billing cycle resets.
|
|
13
|
+
*
|
|
14
|
+
* Kept out of `compaction.ts` so the ladder is unit-testable without an
|
|
15
|
+
* AgentSession, and so neither module carries the other's growth.
|
|
16
|
+
*/
|
|
17
|
+
import type { Model } from "omk-ai";
|
|
18
|
+
import type { CompactionDetails, CompactionPreparation, CompactionResult } from "./compaction.ts";
|
|
19
|
+
/**
|
|
20
|
+
* Detail shape unique to the no-model path. Kept here rather than on
|
|
21
|
+
* `CompactionDetails` so a reader of a normal entry never has to wonder why a
|
|
22
|
+
* `deterministicEmergency` flag exists on it.
|
|
23
|
+
*/
|
|
24
|
+
export interface DeterministicCompactionDetails extends CompactionDetails {
|
|
25
|
+
readonly deterministicEmergency: true;
|
|
26
|
+
/** Sanitized, bounded reason the model path was unavailable. */
|
|
27
|
+
readonly deterministicReason: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Compact without a model.
|
|
31
|
+
*
|
|
32
|
+
* Keeps exactly what `prepareCompaction()` already derived deterministically —
|
|
33
|
+
* the prior summary, source-bound user rules, and file operations — plus the
|
|
34
|
+
* recent window the cut point preserved. It never claims to be a model summary:
|
|
35
|
+
* the heading and `details.deterministicEmergency` mark it as a trim, because
|
|
36
|
+
* the dropped turns were discarded without semantic summarization.
|
|
37
|
+
*
|
|
38
|
+
* Takes no model, key, or stream function: the signature itself proves no
|
|
39
|
+
* provider call can occur on this path.
|
|
40
|
+
*/
|
|
41
|
+
export declare function compactDeterministic(preparation: CompactionPreparation, reason: string): CompactionResult;
|
|
42
|
+
export interface SummarizationFallbackInput {
|
|
43
|
+
readonly preparation: CompactionPreparation;
|
|
44
|
+
readonly primaryModel: Model<any>;
|
|
45
|
+
/** The model the session is actually running, when known. */
|
|
46
|
+
readonly sessionModel: Model<any> | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* Summarize on one model, resolving that model's own credentials. A
|
|
49
|
+
* cross-provider rescue must not inherit the failed model's key or headers.
|
|
50
|
+
*/
|
|
51
|
+
readonly summarize: (model: Model<any>) => Promise<CompactionResult>;
|
|
52
|
+
readonly isAborted: () => boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Rescue on every summarization failure, not only quota exhaustion.
|
|
55
|
+
* Overflow recovery is the session's last chance before the provider
|
|
56
|
+
* 400 strands it, so a non-quota failure (e.g. a failover candidate's
|
|
57
|
+
* entitlement 403 surfaced mid-chain) must also reach the trim — a
|
|
58
|
+
* persistent per-provider permission failure will not heal on retry.
|
|
59
|
+
* Manual/threshold compaction keeps the quota-only gate: a transient
|
|
60
|
+
* primary failure there must propagate as an error, not silently
|
|
61
|
+
* degrade the summary.
|
|
62
|
+
*/
|
|
63
|
+
readonly alwaysRescue?: boolean;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Run the summarization ladder. Aborts and (without `alwaysRescue`)
|
|
67
|
+
* non-quota failures propagate unchanged — a transient 503 must retry its
|
|
68
|
+
* model, not silently degrade.
|
|
69
|
+
*/
|
|
70
|
+
export declare function summarizeWithFallback(input: SummarizationFallbackInput): Promise<CompactionResult>;
|
|
71
|
+
//# sourceMappingURL=fallback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fallback.d.ts","sourceRoot":"","sources":["../../../src/core/compaction/fallback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAGpC,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAYlG;;;;GAIG;AACH,MAAM,WAAW,8BAA+B,SAAQ,iBAAiB;IACxE,QAAQ,CAAC,sBAAsB,EAAE,IAAI,CAAC;IACtC,gEAAgE;IAChE,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;CACrC;AASD;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,qBAAqB,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAwDzG;AAED,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,WAAW,EAAE,qBAAqB,CAAC;IAC5C,QAAQ,CAAC,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,6DAA6D;IAC7D,QAAQ,CAAC,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IAC9C;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACrE,QAAQ,CAAC,SAAS,EAAE,MAAM,OAAO,CAAC;IAClC;;;;;;;;;OASG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;CAChC;AAMD;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAmBxG","sourcesContent":["/**\n * What to do when compaction summarization cannot run.\n *\n * The resilience ladder, in order:\n * 1. the resolved compaction model (caller's `summarize`),\n * 2. the live session model — a pinned `compaction.model` can be quota-dead\n * while the model the user is actively talking to still serves traffic,\n * 3. a deterministic trim that needs no model at all.\n *\n * Step 3 exists because the alternative is stranding the run: once context is\n * over the window, a failed compaction means no later turn can succeed until\n * the billing cycle resets.\n *\n * Kept out of `compaction.ts` so the ladder is unit-testable without an\n * AgentSession, and so neither module carries the other's growth.\n */\n\nimport type { Model } from \"omk-ai\";\nimport { isQuotaExhaustionMessage } from \"../provider-resilience.ts\";\nimport { redactSensitiveTextForced } from \"../redaction.ts\";\nimport type { CompactionDetails, CompactionPreparation, CompactionResult } from \"./compaction.ts\";\nimport { applyCompactionKnowledgeTriage } from \"./knowledge-triage.ts\";\nimport { redactCredentialShapedContent } from \"./transaction.ts\";\nimport { computeFileLists, formatFileOperations } from \"./utils.ts\";\n\n/** Upper bound on the reason text persisted into the compaction entry. */\nconst DETERMINISTIC_REASON_MAX_CHARS = 512;\n/** Upper bound on the prior summary carried forward verbatim. */\nconst CARRIED_SUMMARY_MAX_CHARS = 16_384;\n\nconst DETERMINISTIC_EMERGENCY_HEADING = \"## Deterministic emergency compaction\";\n\n/**\n * Detail shape unique to the no-model path. Kept here rather than on\n * `CompactionDetails` so a reader of a normal entry never has to wonder why a\n * `deterministicEmergency` flag exists on it.\n */\nexport interface DeterministicCompactionDetails extends CompactionDetails {\n\treadonly deterministicEmergency: true;\n\t/** Sanitized, bounded reason the model path was unavailable. */\n\treadonly deterministicReason: string;\n}\n\nfunction boundedSanitizedText(value: string, maxChars: number): string {\n\tconst sanitized = redactCredentialShapedContent(redactSensitiveTextForced(value))\n\t\t.replace(/[\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f\\u007f]/gu, \"\")\n\t\t.trim();\n\treturn sanitized.length <= maxChars ? sanitized : `${sanitized.slice(0, maxChars - 1)}\\u2026`;\n}\n\n/**\n * Compact without a model.\n *\n * Keeps exactly what `prepareCompaction()` already derived deterministically —\n * the prior summary, source-bound user rules, and file operations — plus the\n * recent window the cut point preserved. It never claims to be a model summary:\n * the heading and `details.deterministicEmergency` mark it as a trim, because\n * the dropped turns were discarded without semantic summarization.\n *\n * Takes no model, key, or stream function: the signature itself proves no\n * provider call can occur on this path.\n */\nexport function compactDeterministic(preparation: CompactionPreparation, reason: string): CompactionResult {\n\tconst {\n\t\tfirstKeptEntryId,\n\t\tmessagesToSummarize,\n\t\tturnPrefixMessages,\n\t\ttokensBefore,\n\t\tpreviousSummary,\n\t\tpreviousRuleHistory,\n\t\tcurrentRuleEntries,\n\t\tfileOps,\n\t} = preparation;\n\n\tif (!firstKeptEntryId) {\n\t\tthrow new Error(\"First kept entry has no UUID - session may need migration\");\n\t}\n\n\tconst safeReason = boundedSanitizedText(reason, DETERMINISTIC_REASON_MAX_CHARS);\n\tconst carried =\n\t\tpreviousSummary === undefined ? \"\" : boundedSanitizedText(previousSummary, CARRIED_SUMMARY_MAX_CHARS);\n\n\tconst sections = [\n\t\tDETERMINISTIC_EMERGENCY_HEADING,\n\t\t\"Model summarization was unavailable, so the context was trimmed deterministically \" +\n\t\t\t\"rather than leaving the session unable to continue. This is not a model-generated \" +\n\t\t\t\"summary: older turns were dropped without semantic summarization, and only the \" +\n\t\t\t\"structured state below plus the retained recent window survive.\",\n\t\t`Cause: ${safeReason.length > 0 ? safeReason : \"unspecified summarization failure\"}`,\n\t];\n\tif (carried.length > 0) {\n\t\tsections.push(`### Carried forward from the previous compaction\\n\\n${carried}`);\n\t}\n\n\tconst triage = applyCompactionKnowledgeTriage({\n\t\tgeneratedSummary: sections.join(\"\\n\\n\"),\n\t\tcurrentMessages: [...messagesToSummarize, ...turnPrefixMessages],\n\t\tcurrentEntries: currentRuleEntries,\n\t\tpreviousRules: previousRuleHistory?.rules,\n\t\tpreviousSummary,\n\t\tpreviousEntries: previousRuleHistory?.entries,\n\t});\n\n\tconst { readFiles, modifiedFiles } = computeFileLists(fileOps);\n\tconst summary = triage.summary + formatFileOperations(readFiles, modifiedFiles);\n\n\treturn {\n\t\tsummary,\n\t\tfirstKeptEntryId,\n\t\ttokensBefore,\n\t\tdetails: {\n\t\t\treadFiles,\n\t\t\tmodifiedFiles,\n\t\t\tpreservedRules: [...triage.preservedRules],\n\t\t\tdeterministicEmergency: true,\n\t\t\tdeterministicReason: safeReason,\n\t\t} satisfies DeterministicCompactionDetails,\n\t};\n}\n\nexport interface SummarizationFallbackInput {\n\treadonly preparation: CompactionPreparation;\n\treadonly primaryModel: Model<any>;\n\t/** The model the session is actually running, when known. */\n\treadonly sessionModel: Model<any> | undefined;\n\t/**\n\t * Summarize on one model, resolving that model's own credentials. A\n\t * cross-provider rescue must not inherit the failed model's key or headers.\n\t */\n\treadonly summarize: (model: Model<any>) => Promise<CompactionResult>;\n\treadonly isAborted: () => boolean;\n\t/**\n\t * Rescue on every summarization failure, not only quota exhaustion.\n\t * Overflow recovery is the session's last chance before the provider\n\t * 400 strands it, so a non-quota failure (e.g. a failover candidate's\n\t * entitlement 403 surfaced mid-chain) must also reach the trim — a\n\t * persistent per-provider permission failure will not heal on retry.\n\t * Manual/threshold compaction keeps the quota-only gate: a transient\n\t * primary failure there must propagate as an error, not silently\n\t * degrade the summary.\n\t */\n\treadonly alwaysRescue?: boolean;\n}\n\nfunction sameModel(a: Model<any>, b: Model<any>): boolean {\n\treturn a.provider === b.provider && a.id === b.id;\n}\n\n/**\n * Run the summarization ladder. Aborts and (without `alwaysRescue`)\n * non-quota failures propagate unchanged — a transient 503 must retry its\n * model, not silently degrade.\n */\nexport async function summarizeWithFallback(input: SummarizationFallbackInput): Promise<CompactionResult> {\n\ttry {\n\t\treturn await input.summarize(input.primaryModel);\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tif (input.isAborted()) throw error;\n\t\tif (!input.alwaysRescue && !isQuotaExhaustionMessage(message)) throw error;\n\n\t\tconst session = input.sessionModel;\n\t\tif (session !== undefined && !sameModel(session, input.primaryModel)) {\n\t\t\ttry {\n\t\t\t\treturn await input.summarize(session);\n\t\t\t} catch (rescueError) {\n\t\t\t\tif (input.isAborted()) throw rescueError;\n\t\t\t\t// Session model could not help either; fall through to the trim.\n\t\t\t}\n\t\t}\n\t\treturn compactDeterministic(input.preparation, message);\n\t}\n}\n"]}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What to do when compaction summarization cannot run.
|
|
3
|
+
*
|
|
4
|
+
* The resilience ladder, in order:
|
|
5
|
+
* 1. the resolved compaction model (caller's `summarize`),
|
|
6
|
+
* 2. the live session model — a pinned `compaction.model` can be quota-dead
|
|
7
|
+
* while the model the user is actively talking to still serves traffic,
|
|
8
|
+
* 3. a deterministic trim that needs no model at all.
|
|
9
|
+
*
|
|
10
|
+
* Step 3 exists because the alternative is stranding the run: once context is
|
|
11
|
+
* over the window, a failed compaction means no later turn can succeed until
|
|
12
|
+
* the billing cycle resets.
|
|
13
|
+
*
|
|
14
|
+
* Kept out of `compaction.ts` so the ladder is unit-testable without an
|
|
15
|
+
* AgentSession, and so neither module carries the other's growth.
|
|
16
|
+
*/
|
|
17
|
+
import { isQuotaExhaustionMessage } from "../provider-resilience.js";
|
|
18
|
+
import { redactSensitiveTextForced } from "../redaction.js";
|
|
19
|
+
import { applyCompactionKnowledgeTriage } from "./knowledge-triage.js";
|
|
20
|
+
import { redactCredentialShapedContent } from "./transaction.js";
|
|
21
|
+
import { computeFileLists, formatFileOperations } from "./utils.js";
|
|
22
|
+
/** Upper bound on the reason text persisted into the compaction entry. */
|
|
23
|
+
const DETERMINISTIC_REASON_MAX_CHARS = 512;
|
|
24
|
+
/** Upper bound on the prior summary carried forward verbatim. */
|
|
25
|
+
const CARRIED_SUMMARY_MAX_CHARS = 16_384;
|
|
26
|
+
const DETERMINISTIC_EMERGENCY_HEADING = "## Deterministic emergency compaction";
|
|
27
|
+
function boundedSanitizedText(value, maxChars) {
|
|
28
|
+
const sanitized = redactCredentialShapedContent(redactSensitiveTextForced(value))
|
|
29
|
+
.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/gu, "")
|
|
30
|
+
.trim();
|
|
31
|
+
return sanitized.length <= maxChars ? sanitized : `${sanitized.slice(0, maxChars - 1)}\u2026`;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Compact without a model.
|
|
35
|
+
*
|
|
36
|
+
* Keeps exactly what `prepareCompaction()` already derived deterministically —
|
|
37
|
+
* the prior summary, source-bound user rules, and file operations — plus the
|
|
38
|
+
* recent window the cut point preserved. It never claims to be a model summary:
|
|
39
|
+
* the heading and `details.deterministicEmergency` mark it as a trim, because
|
|
40
|
+
* the dropped turns were discarded without semantic summarization.
|
|
41
|
+
*
|
|
42
|
+
* Takes no model, key, or stream function: the signature itself proves no
|
|
43
|
+
* provider call can occur on this path.
|
|
44
|
+
*/
|
|
45
|
+
export function compactDeterministic(preparation, reason) {
|
|
46
|
+
const { firstKeptEntryId, messagesToSummarize, turnPrefixMessages, tokensBefore, previousSummary, previousRuleHistory, currentRuleEntries, fileOps, } = preparation;
|
|
47
|
+
if (!firstKeptEntryId) {
|
|
48
|
+
throw new Error("First kept entry has no UUID - session may need migration");
|
|
49
|
+
}
|
|
50
|
+
const safeReason = boundedSanitizedText(reason, DETERMINISTIC_REASON_MAX_CHARS);
|
|
51
|
+
const carried = previousSummary === undefined ? "" : boundedSanitizedText(previousSummary, CARRIED_SUMMARY_MAX_CHARS);
|
|
52
|
+
const sections = [
|
|
53
|
+
DETERMINISTIC_EMERGENCY_HEADING,
|
|
54
|
+
"Model summarization was unavailable, so the context was trimmed deterministically " +
|
|
55
|
+
"rather than leaving the session unable to continue. This is not a model-generated " +
|
|
56
|
+
"summary: older turns were dropped without semantic summarization, and only the " +
|
|
57
|
+
"structured state below plus the retained recent window survive.",
|
|
58
|
+
`Cause: ${safeReason.length > 0 ? safeReason : "unspecified summarization failure"}`,
|
|
59
|
+
];
|
|
60
|
+
if (carried.length > 0) {
|
|
61
|
+
sections.push(`### Carried forward from the previous compaction\n\n${carried}`);
|
|
62
|
+
}
|
|
63
|
+
const triage = applyCompactionKnowledgeTriage({
|
|
64
|
+
generatedSummary: sections.join("\n\n"),
|
|
65
|
+
currentMessages: [...messagesToSummarize, ...turnPrefixMessages],
|
|
66
|
+
currentEntries: currentRuleEntries,
|
|
67
|
+
previousRules: previousRuleHistory?.rules,
|
|
68
|
+
previousSummary,
|
|
69
|
+
previousEntries: previousRuleHistory?.entries,
|
|
70
|
+
});
|
|
71
|
+
const { readFiles, modifiedFiles } = computeFileLists(fileOps);
|
|
72
|
+
const summary = triage.summary + formatFileOperations(readFiles, modifiedFiles);
|
|
73
|
+
return {
|
|
74
|
+
summary,
|
|
75
|
+
firstKeptEntryId,
|
|
76
|
+
tokensBefore,
|
|
77
|
+
details: {
|
|
78
|
+
readFiles,
|
|
79
|
+
modifiedFiles,
|
|
80
|
+
preservedRules: [...triage.preservedRules],
|
|
81
|
+
deterministicEmergency: true,
|
|
82
|
+
deterministicReason: safeReason,
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function sameModel(a, b) {
|
|
87
|
+
return a.provider === b.provider && a.id === b.id;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Run the summarization ladder. Aborts and (without `alwaysRescue`)
|
|
91
|
+
* non-quota failures propagate unchanged — a transient 503 must retry its
|
|
92
|
+
* model, not silently degrade.
|
|
93
|
+
*/
|
|
94
|
+
export async function summarizeWithFallback(input) {
|
|
95
|
+
try {
|
|
96
|
+
return await input.summarize(input.primaryModel);
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
100
|
+
if (input.isAborted())
|
|
101
|
+
throw error;
|
|
102
|
+
if (!input.alwaysRescue && !isQuotaExhaustionMessage(message))
|
|
103
|
+
throw error;
|
|
104
|
+
const session = input.sessionModel;
|
|
105
|
+
if (session !== undefined && !sameModel(session, input.primaryModel)) {
|
|
106
|
+
try {
|
|
107
|
+
return await input.summarize(session);
|
|
108
|
+
}
|
|
109
|
+
catch (rescueError) {
|
|
110
|
+
if (input.isAborted())
|
|
111
|
+
throw rescueError;
|
|
112
|
+
// Session model could not help either; fall through to the trim.
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return compactDeterministic(input.preparation, message);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=fallback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fallback.js","sourceRoot":"","sources":["../../../src/core/compaction/fallback.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * What to do when compaction summarization cannot run.\n *\n * The resilience ladder, in order:\n * 1. the resolved compaction model (caller's `summarize`),\n * 2. the live session model — a pinned `compaction.model` can be quota-dead\n * while the model the user is actively talking to still serves traffic,\n * 3. a deterministic trim that needs no model at all.\n *\n * Step 3 exists because the alternative is stranding the run: once context is\n * over the window, a failed compaction means no later turn can succeed until\n * the billing cycle resets.\n *\n * Kept out of `compaction.ts` so the ladder is unit-testable without an\n * AgentSession, and so neither module carries the other's growth.\n */\n\nimport type { Model } from \"omk-ai\";\nimport { isQuotaExhaustionMessage } from \"../provider-resilience.ts\";\nimport { redactSensitiveTextForced } from \"../redaction.ts\";\nimport type { CompactionDetails, CompactionPreparation, CompactionResult } from \"./compaction.ts\";\nimport { applyCompactionKnowledgeTriage } from \"./knowledge-triage.ts\";\nimport { redactCredentialShapedContent } from \"./transaction.ts\";\nimport { computeFileLists, formatFileOperations } from \"./utils.ts\";\n\n/** Upper bound on the reason text persisted into the compaction entry. */\nconst DETERMINISTIC_REASON_MAX_CHARS = 512;\n/** Upper bound on the prior summary carried forward verbatim. */\nconst CARRIED_SUMMARY_MAX_CHARS = 16_384;\n\nconst DETERMINISTIC_EMERGENCY_HEADING = \"## Deterministic emergency compaction\";\n\n/**\n * Detail shape unique to the no-model path. Kept here rather than on\n * `CompactionDetails` so a reader of a normal entry never has to wonder why a\n * `deterministicEmergency` flag exists on it.\n */\nexport interface DeterministicCompactionDetails extends CompactionDetails {\n\treadonly deterministicEmergency: true;\n\t/** Sanitized, bounded reason the model path was unavailable. */\n\treadonly deterministicReason: string;\n}\n\nfunction boundedSanitizedText(value: string, maxChars: number): string {\n\tconst sanitized = redactCredentialShapedContent(redactSensitiveTextForced(value))\n\t\t.replace(/[\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f\\u007f]/gu, \"\")\n\t\t.trim();\n\treturn sanitized.length <= maxChars ? sanitized : `${sanitized.slice(0, maxChars - 1)}\\u2026`;\n}\n\n/**\n * Compact without a model.\n *\n * Keeps exactly what `prepareCompaction()` already derived deterministically —\n * the prior summary, source-bound user rules, and file operations — plus the\n * recent window the cut point preserved. It never claims to be a model summary:\n * the heading and `details.deterministicEmergency` mark it as a trim, because\n * the dropped turns were discarded without semantic summarization.\n *\n * Takes no model, key, or stream function: the signature itself proves no\n * provider call can occur on this path.\n */\nexport function compactDeterministic(preparation: CompactionPreparation, reason: string): CompactionResult {\n\tconst {\n\t\tfirstKeptEntryId,\n\t\tmessagesToSummarize,\n\t\tturnPrefixMessages,\n\t\ttokensBefore,\n\t\tpreviousSummary,\n\t\tpreviousRuleHistory,\n\t\tcurrentRuleEntries,\n\t\tfileOps,\n\t} = preparation;\n\n\tif (!firstKeptEntryId) {\n\t\tthrow new Error(\"First kept entry has no UUID - session may need migration\");\n\t}\n\n\tconst safeReason = boundedSanitizedText(reason, DETERMINISTIC_REASON_MAX_CHARS);\n\tconst carried =\n\t\tpreviousSummary === undefined ? \"\" : boundedSanitizedText(previousSummary, CARRIED_SUMMARY_MAX_CHARS);\n\n\tconst sections = [\n\t\tDETERMINISTIC_EMERGENCY_HEADING,\n\t\t\"Model summarization was unavailable, so the context was trimmed deterministically \" +\n\t\t\t\"rather than leaving the session unable to continue. This is not a model-generated \" +\n\t\t\t\"summary: older turns were dropped without semantic summarization, and only the \" +\n\t\t\t\"structured state below plus the retained recent window survive.\",\n\t\t`Cause: ${safeReason.length > 0 ? safeReason : \"unspecified summarization failure\"}`,\n\t];\n\tif (carried.length > 0) {\n\t\tsections.push(`### Carried forward from the previous compaction\\n\\n${carried}`);\n\t}\n\n\tconst triage = applyCompactionKnowledgeTriage({\n\t\tgeneratedSummary: sections.join(\"\\n\\n\"),\n\t\tcurrentMessages: [...messagesToSummarize, ...turnPrefixMessages],\n\t\tcurrentEntries: currentRuleEntries,\n\t\tpreviousRules: previousRuleHistory?.rules,\n\t\tpreviousSummary,\n\t\tpreviousEntries: previousRuleHistory?.entries,\n\t});\n\n\tconst { readFiles, modifiedFiles } = computeFileLists(fileOps);\n\tconst summary = triage.summary + formatFileOperations(readFiles, modifiedFiles);\n\n\treturn {\n\t\tsummary,\n\t\tfirstKeptEntryId,\n\t\ttokensBefore,\n\t\tdetails: {\n\t\t\treadFiles,\n\t\t\tmodifiedFiles,\n\t\t\tpreservedRules: [...triage.preservedRules],\n\t\t\tdeterministicEmergency: true,\n\t\t\tdeterministicReason: safeReason,\n\t\t} satisfies DeterministicCompactionDetails,\n\t};\n}\n\nexport interface SummarizationFallbackInput {\n\treadonly preparation: CompactionPreparation;\n\treadonly primaryModel: Model<any>;\n\t/** The model the session is actually running, when known. */\n\treadonly sessionModel: Model<any> | undefined;\n\t/**\n\t * Summarize on one model, resolving that model's own credentials. A\n\t * cross-provider rescue must not inherit the failed model's key or headers.\n\t */\n\treadonly summarize: (model: Model<any>) => Promise<CompactionResult>;\n\treadonly isAborted: () => boolean;\n\t/**\n\t * Rescue on every summarization failure, not only quota exhaustion.\n\t * Overflow recovery is the session's last chance before the provider\n\t * 400 strands it, so a non-quota failure (e.g. a failover candidate's\n\t * entitlement 403 surfaced mid-chain) must also reach the trim — a\n\t * persistent per-provider permission failure will not heal on retry.\n\t * Manual/threshold compaction keeps the quota-only gate: a transient\n\t * primary failure there must propagate as an error, not silently\n\t * degrade the summary.\n\t */\n\treadonly alwaysRescue?: boolean;\n}\n\nfunction sameModel(a: Model<any>, b: Model<any>): boolean {\n\treturn a.provider === b.provider && a.id === b.id;\n}\n\n/**\n * Run the summarization ladder. Aborts and (without `alwaysRescue`)\n * non-quota failures propagate unchanged — a transient 503 must retry its\n * model, not silently degrade.\n */\nexport async function summarizeWithFallback(input: SummarizationFallbackInput): Promise<CompactionResult> {\n\ttry {\n\t\treturn await input.summarize(input.primaryModel);\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tif (input.isAborted()) throw error;\n\t\tif (!input.alwaysRescue && !isQuotaExhaustionMessage(message)) throw error;\n\n\t\tconst session = input.sessionModel;\n\t\tif (session !== undefined && !sameModel(session, input.primaryModel)) {\n\t\t\ttry {\n\t\t\t\treturn await input.summarize(session);\n\t\t\t} catch (rescueError) {\n\t\t\t\tif (input.isAborted()) throw rescueError;\n\t\t\t\t// Session model could not help either; fall through to the trim.\n\t\t\t}\n\t\t}\n\t\treturn compactDeterministic(input.preparation, message);\n\t}\n}\n"]}
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export * from "./branch-summarization.ts";
|
|
5
5
|
export * from "./compaction.ts";
|
|
6
|
+
export * from "./control-state.ts";
|
|
7
|
+
export * from "./fallback.ts";
|
|
6
8
|
export * from "./hysteresis.ts";
|
|
7
9
|
export * from "./knowledge-triage.ts";
|
|
8
10
|
export * from "./model-policy.ts";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/compaction/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC","sourcesContent":["/**\n * Compaction and summarization utilities.\n */\n\nexport * from \"./branch-summarization.ts\";\nexport * from \"./compaction.ts\";\nexport * from \"./hysteresis.ts\";\nexport * from \"./knowledge-triage.ts\";\nexport * from \"./model-policy.ts\";\nexport * from \"./resume-policy.ts\";\nexport * from \"./transaction.ts\";\nexport * from \"./utils.ts\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/compaction/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC","sourcesContent":["/**\n * Compaction and summarization utilities.\n */\n\nexport * from \"./branch-summarization.ts\";\nexport * from \"./compaction.ts\";\nexport * from \"./control-state.ts\";\nexport * from \"./fallback.ts\";\nexport * from \"./hysteresis.ts\";\nexport * from \"./knowledge-triage.ts\";\nexport * from \"./model-policy.ts\";\nexport * from \"./resume-policy.ts\";\nexport * from \"./transaction.ts\";\nexport * from \"./utils.ts\";\n"]}
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export * from "./branch-summarization.js";
|
|
5
5
|
export * from "./compaction.js";
|
|
6
|
+
export * from "./control-state.js";
|
|
7
|
+
export * from "./fallback.js";
|
|
6
8
|
export * from "./hysteresis.js";
|
|
7
9
|
export * from "./knowledge-triage.js";
|
|
8
10
|
export * from "./model-policy.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/compaction/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC","sourcesContent":["/**\n * Compaction and summarization utilities.\n */\n\nexport * from \"./branch-summarization.ts\";\nexport * from \"./compaction.ts\";\nexport * from \"./hysteresis.ts\";\nexport * from \"./knowledge-triage.ts\";\nexport * from \"./model-policy.ts\";\nexport * from \"./resume-policy.ts\";\nexport * from \"./transaction.ts\";\nexport * from \"./utils.ts\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/compaction/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC","sourcesContent":["/**\n * Compaction and summarization utilities.\n */\n\nexport * from \"./branch-summarization.ts\";\nexport * from \"./compaction.ts\";\nexport * from \"./control-state.ts\";\nexport * from \"./fallback.ts\";\nexport * from \"./hysteresis.ts\";\nexport * from \"./knowledge-triage.ts\";\nexport * from \"./model-policy.ts\";\nexport * from \"./resume-policy.ts\";\nexport * from \"./transaction.ts\";\nexport * from \"./utils.ts\";\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Api, Model } from "omk-ai";
|
|
2
|
+
export interface CompactionRequestAuth {
|
|
3
|
+
readonly apiKey?: string;
|
|
4
|
+
readonly headers?: Record<string, string>;
|
|
5
|
+
}
|
|
6
|
+
export interface CompactFailoverOptions {
|
|
7
|
+
/** Cross-provider candidates need their own credential; never replay the primary key. */
|
|
8
|
+
readonly resolveCandidateAuth?: (candidate: Model<Api>) => Promise<CompactionRequestAuth>;
|
|
9
|
+
}
|
|
10
|
+
interface ModelFailoverInput<T> {
|
|
11
|
+
readonly model: Model<Api>;
|
|
12
|
+
readonly auth: CompactionRequestAuth;
|
|
13
|
+
readonly signal?: AbortSignal;
|
|
14
|
+
readonly candidates?: readonly Model<Api>[];
|
|
15
|
+
readonly options?: CompactFailoverOptions;
|
|
16
|
+
readonly run: (model: Model<Api>, auth: CompactionRequestAuth) => Promise<T>;
|
|
17
|
+
}
|
|
18
|
+
/** Preserve the primary quota failure when no authenticated candidate can serve. */
|
|
19
|
+
export declare function withCompactionModelFailover<T>(input: ModelFailoverInput<T>): Promise<T>;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=model-failover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-failover.d.ts","sourceRoot":"","sources":["../../../src/core/compaction/model-failover.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAGzC,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,sBAAsB;IACtC,yFAAyF;IACzF,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAC;CAC1F;AAED,UAAU,kBAAkB,CAAC,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;IAC5C,QAAQ,CAAC,OAAO,CAAC,EAAE,sBAAsB,CAAC;IAC1C,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,qBAAqB,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;CAC7E;AAED,oFAAoF;AACpF,wBAAsB,2BAA2B,CAAC,CAAC,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAiC7F","sourcesContent":["import type { Api, Model } from \"omk-ai\";\nimport { isQuotaExhaustionMessage, isTerminalProviderErrorMessage } from \"../provider-resilience.ts\";\n\nexport interface CompactionRequestAuth {\n\treadonly apiKey?: string;\n\treadonly headers?: Record<string, string>;\n}\n\nexport interface CompactFailoverOptions {\n\t/** Cross-provider candidates need their own credential; never replay the primary key. */\n\treadonly resolveCandidateAuth?: (candidate: Model<Api>) => Promise<CompactionRequestAuth>;\n}\n\ninterface ModelFailoverInput<T> {\n\treadonly model: Model<Api>;\n\treadonly auth: CompactionRequestAuth;\n\treadonly signal?: AbortSignal;\n\treadonly candidates?: readonly Model<Api>[];\n\treadonly options?: CompactFailoverOptions;\n\treadonly run: (model: Model<Api>, auth: CompactionRequestAuth) => Promise<T>;\n}\n\n/** Preserve the primary quota failure when no authenticated candidate can serve. */\nexport async function withCompactionModelFailover<T>(input: ModelFailoverInput<T>): Promise<T> {\n\ttry {\n\t\treturn await input.run(input.model, input.auth);\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tif (!isQuotaExhaustionMessage(message) || !input.candidates?.length) throw error;\n\t\tfor (const candidate of input.candidates) {\n\t\t\tif (candidate.provider === input.model.provider && candidate.id === input.model.id) continue;\n\t\t\tif (input.signal?.aborted) throw error;\n\t\t\tlet auth: CompactionRequestAuth;\n\t\t\tif (candidate.provider === input.model.provider && !input.options?.resolveCandidateAuth) {\n\t\t\t\tauth = input.auth;\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tauth = (await input.options?.resolveCandidateAuth?.(candidate)) ?? {};\n\t\t\t\t} catch {\n\t\t\t\t\t// An unavailable credential excludes this candidate, not the remaining chain.\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (!auth.apiKey) continue;\n\t\t\t}\n\t\t\tif (input.signal?.aborted) throw error;\n\t\t\ttry {\n\t\t\t\treturn await input.run(candidate, auth);\n\t\t\t} catch (candidateError) {\n\t\t\t\tconst candidateMessage = candidateError instanceof Error ? candidateError.message : String(candidateError);\n\t\t\t\tif (!isTerminalProviderErrorMessage(candidateMessage)) {\n\t\t\t\t\tthrow new Error(`Failover candidate ${candidate.provider}/${candidate.id} failed: ${candidateMessage}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthrow error;\n\t}\n}\n"]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { isQuotaExhaustionMessage, isTerminalProviderErrorMessage } from "../provider-resilience.js";
|
|
2
|
+
/** Preserve the primary quota failure when no authenticated candidate can serve. */
|
|
3
|
+
export async function withCompactionModelFailover(input) {
|
|
4
|
+
try {
|
|
5
|
+
return await input.run(input.model, input.auth);
|
|
6
|
+
}
|
|
7
|
+
catch (error) {
|
|
8
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
9
|
+
if (!isQuotaExhaustionMessage(message) || !input.candidates?.length)
|
|
10
|
+
throw error;
|
|
11
|
+
for (const candidate of input.candidates) {
|
|
12
|
+
if (candidate.provider === input.model.provider && candidate.id === input.model.id)
|
|
13
|
+
continue;
|
|
14
|
+
if (input.signal?.aborted)
|
|
15
|
+
throw error;
|
|
16
|
+
let auth;
|
|
17
|
+
if (candidate.provider === input.model.provider && !input.options?.resolveCandidateAuth) {
|
|
18
|
+
auth = input.auth;
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
try {
|
|
22
|
+
auth = (await input.options?.resolveCandidateAuth?.(candidate)) ?? {};
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
// An unavailable credential excludes this candidate, not the remaining chain.
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (!auth.apiKey)
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (input.signal?.aborted)
|
|
32
|
+
throw error;
|
|
33
|
+
try {
|
|
34
|
+
return await input.run(candidate, auth);
|
|
35
|
+
}
|
|
36
|
+
catch (candidateError) {
|
|
37
|
+
const candidateMessage = candidateError instanceof Error ? candidateError.message : String(candidateError);
|
|
38
|
+
if (!isTerminalProviderErrorMessage(candidateMessage)) {
|
|
39
|
+
throw new Error(`Failover candidate ${candidate.provider}/${candidate.id} failed: ${candidateMessage}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=model-failover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-failover.js","sourceRoot":"","sources":["../../../src/core/compaction/model-failover.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAC;AAqBrG,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAI,KAA4B,EAAc;IAC9F,IAAI,CAAC;QACJ,OAAO,MAAM,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,MAAM;YAAE,MAAM,KAAK,CAAC;QACjF,KAAK,MAAM,SAAS,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YAC1C,IAAI,SAAS,CAAC,QAAQ,KAAK,KAAK,CAAC,KAAK,CAAC,QAAQ,IAAI,SAAS,CAAC,EAAE,KAAK,KAAK,CAAC,KAAK,CAAC,EAAE;gBAAE,SAAS;YAC7F,IAAI,KAAK,CAAC,MAAM,EAAE,OAAO;gBAAE,MAAM,KAAK,CAAC;YACvC,IAAI,IAA2B,CAAC;YAChC,IAAI,SAAS,CAAC,QAAQ,KAAK,KAAK,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,oBAAoB,EAAE,CAAC;gBACzF,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;YACnB,CAAC;iBAAM,CAAC;gBACP,IAAI,CAAC;oBACJ,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,OAAO,EAAE,oBAAoB,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC;gBACvE,CAAC;gBAAC,MAAM,CAAC;oBACR,8EAA8E;oBAC9E,SAAS;gBACV,CAAC;gBACD,IAAI,CAAC,IAAI,CAAC,MAAM;oBAAE,SAAS;YAC5B,CAAC;YACD,IAAI,KAAK,CAAC,MAAM,EAAE,OAAO;gBAAE,MAAM,KAAK,CAAC;YACvC,IAAI,CAAC;gBACJ,OAAO,MAAM,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YACzC,CAAC;YAAC,OAAO,cAAc,EAAE,CAAC;gBACzB,MAAM,gBAAgB,GAAG,cAAc,YAAY,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;gBAC3G,IAAI,CAAC,8BAA8B,CAAC,gBAAgB,CAAC,EAAE,CAAC;oBACvD,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,CAAC,QAAQ,IAAI,SAAS,CAAC,EAAE,YAAY,gBAAgB,EAAE,CAAC,CAAC;gBACzG,CAAC;YACF,CAAC;QACF,CAAC;QACD,MAAM,KAAK,CAAC;IACb,CAAC;AAAA,CACD","sourcesContent":["import type { Api, Model } from \"omk-ai\";\nimport { isQuotaExhaustionMessage, isTerminalProviderErrorMessage } from \"../provider-resilience.ts\";\n\nexport interface CompactionRequestAuth {\n\treadonly apiKey?: string;\n\treadonly headers?: Record<string, string>;\n}\n\nexport interface CompactFailoverOptions {\n\t/** Cross-provider candidates need their own credential; never replay the primary key. */\n\treadonly resolveCandidateAuth?: (candidate: Model<Api>) => Promise<CompactionRequestAuth>;\n}\n\ninterface ModelFailoverInput<T> {\n\treadonly model: Model<Api>;\n\treadonly auth: CompactionRequestAuth;\n\treadonly signal?: AbortSignal;\n\treadonly candidates?: readonly Model<Api>[];\n\treadonly options?: CompactFailoverOptions;\n\treadonly run: (model: Model<Api>, auth: CompactionRequestAuth) => Promise<T>;\n}\n\n/** Preserve the primary quota failure when no authenticated candidate can serve. */\nexport async function withCompactionModelFailover<T>(input: ModelFailoverInput<T>): Promise<T> {\n\ttry {\n\t\treturn await input.run(input.model, input.auth);\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tif (!isQuotaExhaustionMessage(message) || !input.candidates?.length) throw error;\n\t\tfor (const candidate of input.candidates) {\n\t\t\tif (candidate.provider === input.model.provider && candidate.id === input.model.id) continue;\n\t\t\tif (input.signal?.aborted) throw error;\n\t\t\tlet auth: CompactionRequestAuth;\n\t\t\tif (candidate.provider === input.model.provider && !input.options?.resolveCandidateAuth) {\n\t\t\t\tauth = input.auth;\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tauth = (await input.options?.resolveCandidateAuth?.(candidate)) ?? {};\n\t\t\t\t} catch {\n\t\t\t\t\t// An unavailable credential excludes this candidate, not the remaining chain.\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (!auth.apiKey) continue;\n\t\t\t}\n\t\t\tif (input.signal?.aborted) throw error;\n\t\t\ttry {\n\t\t\t\treturn await input.run(candidate, auth);\n\t\t\t} catch (candidateError) {\n\t\t\t\tconst candidateMessage = candidateError instanceof Error ? candidateError.message : String(candidateError);\n\t\t\t\tif (!isTerminalProviderErrorMessage(candidateMessage)) {\n\t\t\t\t\tthrow new Error(`Failover candidate ${candidate.provider}/${candidate.id} failed: ${candidateMessage}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthrow error;\n\t}\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Api, Model } from "omk-ai";
|
|
2
|
+
import type { CompactionPreparation, CompactionResult } from "./compaction.ts";
|
|
3
|
+
import type { CompactionRequestAuth } from "./model-failover.ts";
|
|
4
|
+
export interface CompactionSummaryInput {
|
|
5
|
+
readonly preparation: CompactionPreparation;
|
|
6
|
+
readonly model: Model<Api>;
|
|
7
|
+
readonly apiKey: string | undefined;
|
|
8
|
+
readonly headers: Record<string, string> | undefined;
|
|
9
|
+
readonly customInstructions?: string;
|
|
10
|
+
readonly signal: AbortSignal;
|
|
11
|
+
readonly reason: "manual" | "overflow" | "threshold";
|
|
12
|
+
}
|
|
13
|
+
interface SessionSummaryInput extends CompactionSummaryInput {
|
|
14
|
+
readonly sessionModel: Model<Api> | undefined;
|
|
15
|
+
readonly resolveAuth: (model: Model<Api>) => Promise<CompactionRequestAuth>;
|
|
16
|
+
readonly summarize: (input: CompactionSummaryInput) => Promise<CompactionResult>;
|
|
17
|
+
}
|
|
18
|
+
/** Manual and automatic compaction share one credential-bound rescue ladder. */
|
|
19
|
+
export declare function summarizeSessionCompaction(input: SessionSummaryInput): Promise<CompactionResult>;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=session-summary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-summary.d.ts","sourceRoot":"","sources":["../../../src/core/compaction/session-summary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,KAAK,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAE/E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAEjE,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,WAAW,EAAE,qBAAqB,CAAC;IAC5C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IACrD,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,QAAQ,GAAG,UAAU,GAAG,WAAW,CAAC;CACrD;AAED,UAAU,mBAAoB,SAAQ,sBAAsB;IAC3D,QAAQ,CAAC,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IAC9C,QAAQ,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAC5E,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACjF;AAED,gFAAgF;AAChF,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAwBhG","sourcesContent":["import type { Api, Model } from \"omk-ai\";\nimport type { CompactionPreparation, CompactionResult } from \"./compaction.ts\";\nimport { summarizeWithFallback } from \"./fallback.ts\";\nimport type { CompactionRequestAuth } from \"./model-failover.ts\";\n\nexport interface CompactionSummaryInput {\n\treadonly preparation: CompactionPreparation;\n\treadonly model: Model<Api>;\n\treadonly apiKey: string | undefined;\n\treadonly headers: Record<string, string> | undefined;\n\treadonly customInstructions?: string;\n\treadonly signal: AbortSignal;\n\treadonly reason: \"manual\" | \"overflow\" | \"threshold\";\n}\n\ninterface SessionSummaryInput extends CompactionSummaryInput {\n\treadonly sessionModel: Model<Api> | undefined;\n\treadonly resolveAuth: (model: Model<Api>) => Promise<CompactionRequestAuth>;\n\treadonly summarize: (input: CompactionSummaryInput) => Promise<CompactionResult>;\n}\n\n/** Manual and automatic compaction share one credential-bound rescue ladder. */\nexport function summarizeSessionCompaction(input: SessionSummaryInput): Promise<CompactionResult> {\n\treturn summarizeWithFallback({\n\t\tpreparation: input.preparation,\n\t\tprimaryModel: input.model,\n\t\tsessionModel: input.sessionModel,\n\t\tisAborted: () => input.signal.aborted,\n\t\talwaysRescue: input.reason === \"overflow\",\n\t\tsummarize: async (model) => {\n\t\t\tconst auth =\n\t\t\t\tmodel.provider === input.model.provider && model.id === input.model.id\n\t\t\t\t\t? { apiKey: input.apiKey, headers: input.headers }\n\t\t\t\t\t: await input.resolveAuth(model);\n\t\t\tinput.signal.throwIfAborted();\n\t\t\treturn input.summarize({\n\t\t\t\tpreparation: input.preparation,\n\t\t\t\tmodel,\n\t\t\t\tapiKey: auth.apiKey,\n\t\t\t\theaders: auth.headers,\n\t\t\t\tcustomInstructions: input.customInstructions,\n\t\t\t\tsignal: input.signal,\n\t\t\t\treason: input.reason,\n\t\t\t});\n\t\t},\n\t});\n}\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { summarizeWithFallback } from "./fallback.js";
|
|
2
|
+
/** Manual and automatic compaction share one credential-bound rescue ladder. */
|
|
3
|
+
export function summarizeSessionCompaction(input) {
|
|
4
|
+
return summarizeWithFallback({
|
|
5
|
+
preparation: input.preparation,
|
|
6
|
+
primaryModel: input.model,
|
|
7
|
+
sessionModel: input.sessionModel,
|
|
8
|
+
isAborted: () => input.signal.aborted,
|
|
9
|
+
alwaysRescue: input.reason === "overflow",
|
|
10
|
+
summarize: async (model) => {
|
|
11
|
+
const auth = model.provider === input.model.provider && model.id === input.model.id
|
|
12
|
+
? { apiKey: input.apiKey, headers: input.headers }
|
|
13
|
+
: await input.resolveAuth(model);
|
|
14
|
+
input.signal.throwIfAborted();
|
|
15
|
+
return input.summarize({
|
|
16
|
+
preparation: input.preparation,
|
|
17
|
+
model,
|
|
18
|
+
apiKey: auth.apiKey,
|
|
19
|
+
headers: auth.headers,
|
|
20
|
+
customInstructions: input.customInstructions,
|
|
21
|
+
signal: input.signal,
|
|
22
|
+
reason: input.reason,
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=session-summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-summary.js","sourceRoot":"","sources":["../../../src/core/compaction/session-summary.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAmBtD,gFAAgF;AAChF,MAAM,UAAU,0BAA0B,CAAC,KAA0B,EAA6B;IACjG,OAAO,qBAAqB,CAAC;QAC5B,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,YAAY,EAAE,KAAK,CAAC,KAAK;QACzB,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO;QACrC,YAAY,EAAE,KAAK,CAAC,MAAM,KAAK,UAAU;QACzC,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC;YAC3B,MAAM,IAAI,GACT,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,EAAE,KAAK,KAAK,CAAC,KAAK,CAAC,EAAE;gBACrE,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE;gBAClD,CAAC,CAAC,MAAM,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YACnC,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC,SAAS,CAAC;gBACtB,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,KAAK;gBACL,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,kBAAkB,EAAE,KAAK,CAAC,kBAAkB;gBAC5C,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,MAAM,EAAE,KAAK,CAAC,MAAM;aACpB,CAAC,CAAC;QAAA,CACH;KACD,CAAC,CAAC;AAAA,CACH","sourcesContent":["import type { Api, Model } from \"omk-ai\";\nimport type { CompactionPreparation, CompactionResult } from \"./compaction.ts\";\nimport { summarizeWithFallback } from \"./fallback.ts\";\nimport type { CompactionRequestAuth } from \"./model-failover.ts\";\n\nexport interface CompactionSummaryInput {\n\treadonly preparation: CompactionPreparation;\n\treadonly model: Model<Api>;\n\treadonly apiKey: string | undefined;\n\treadonly headers: Record<string, string> | undefined;\n\treadonly customInstructions?: string;\n\treadonly signal: AbortSignal;\n\treadonly reason: \"manual\" | \"overflow\" | \"threshold\";\n}\n\ninterface SessionSummaryInput extends CompactionSummaryInput {\n\treadonly sessionModel: Model<Api> | undefined;\n\treadonly resolveAuth: (model: Model<Api>) => Promise<CompactionRequestAuth>;\n\treadonly summarize: (input: CompactionSummaryInput) => Promise<CompactionResult>;\n}\n\n/** Manual and automatic compaction share one credential-bound rescue ladder. */\nexport function summarizeSessionCompaction(input: SessionSummaryInput): Promise<CompactionResult> {\n\treturn summarizeWithFallback({\n\t\tpreparation: input.preparation,\n\t\tprimaryModel: input.model,\n\t\tsessionModel: input.sessionModel,\n\t\tisAborted: () => input.signal.aborted,\n\t\talwaysRescue: input.reason === \"overflow\",\n\t\tsummarize: async (model) => {\n\t\t\tconst auth =\n\t\t\t\tmodel.provider === input.model.provider && model.id === input.model.id\n\t\t\t\t\t? { apiKey: input.apiKey, headers: input.headers }\n\t\t\t\t\t: await input.resolveAuth(model);\n\t\t\tinput.signal.throwIfAborted();\n\t\t\treturn input.summarize({\n\t\t\t\tpreparation: input.preparation,\n\t\t\t\tmodel,\n\t\t\t\tapiKey: auth.apiKey,\n\t\t\t\theaders: auth.headers,\n\t\t\t\tcustomInstructions: input.customInstructions,\n\t\t\t\tsignal: input.signal,\n\t\t\t\treason: input.reason,\n\t\t\t});\n\t\t},\n\t});\n}\n"]}
|
|
@@ -1,3 +1,18 @@
|
|
|
1
1
|
import { type ContextBudgetItemV2, type ContextRepresentationCandidateV2, type HeadroomQualityPolicyV2 } from "./context-budget-headroom-types.ts";
|
|
2
|
-
|
|
2
|
+
/** Prices one materialized representation string; must be the counter that produced the item's full-text cost. */
|
|
3
|
+
export type RepresentationTokenCounter = (text: string) => number;
|
|
4
|
+
/**
|
|
5
|
+
* Derive the representations the selector may choose for one item.
|
|
6
|
+
*
|
|
7
|
+
* Every non-full candidate is priced by counting the string it actually
|
|
8
|
+
* materializes with `countTokens` — the same counter that priced the full
|
|
9
|
+
* text — so the cost the selector checks against the budget is the cost of
|
|
10
|
+
* the text that would be sent. A compression ratio is never a cost: a summary
|
|
11
|
+
* that returns its source unchanged saves nothing, and a representation whose
|
|
12
|
+
* materialized text is not cheaper than the full text is not offered at all.
|
|
13
|
+
* Pass the counter that produced `item.tokenEstimate`; mixing an exact
|
|
14
|
+
* tokenizer for the full text with the heuristic for its alternatives makes
|
|
15
|
+
* the candidates incomparable.
|
|
16
|
+
*/
|
|
17
|
+
export declare function deriveRepresentationCandidates(item: ContextBudgetItemV2, policy?: HeadroomQualityPolicyV2, countTokens?: RepresentationTokenCounter): readonly ContextRepresentationCandidateV2[];
|
|
3
18
|
//# sourceMappingURL=context-budget-headroom-candidates.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-budget-headroom-candidates.d.ts","sourceRoot":"","sources":["../../src/core/context-budget-headroom-candidates.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,mBAAmB,EACxB,KAAK,gCAAgC,EAKrC,KAAK,uBAAuB,EAE5B,MAAM,oCAAoC,CAAC;AAK5C,wBAAgB,8BAA8B,CAC7C,IAAI,EAAE,mBAAmB,EACzB,MAAM,GAAE,uBAAyD,
|
|
1
|
+
{"version":3,"file":"context-budget-headroom-candidates.d.ts","sourceRoot":"","sources":["../../src/core/context-budget-headroom-candidates.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,mBAAmB,EACxB,KAAK,gCAAgC,EAKrC,KAAK,uBAAuB,EAE5B,MAAM,oCAAoC,CAAC;AAK5C,kHAAkH;AAClH,MAAM,MAAM,0BAA0B,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;AAElE;;;;;;;;;;;;GAYG;AACH,wBAAgB,8BAA8B,CAC7C,IAAI,EAAE,mBAAmB,EACzB,MAAM,GAAE,uBAAyD,EACjE,WAAW,GAAE,0BAAgD,GAC3D,SAAS,gCAAgC,EAAE,CAgE7C","sourcesContent":["import {\n\ttype ContextBudgetItemV2,\n\ttype ContextRepresentationCandidateV2,\n\ttype ContextSourceRefV2,\n\tDEFAULT_HEADROOM_QUALITY_POLICY,\n\tfnv1aHex,\n\tfullTextTokens,\n\ttype HeadroomQualityPolicyV2,\n\theuristicTokenCount,\n} from \"./context-budget-headroom-types.ts\";\n\nconst SUMMARY_HEAD_CHARS = 160;\nconst HEADROOM_HEAD_CHARS = 120;\n\n/** Prices one materialized representation string; must be the counter that produced the item's full-text cost. */\nexport type RepresentationTokenCounter = (text: string) => number;\n\n/**\n * Derive the representations the selector may choose for one item.\n *\n * Every non-full candidate is priced by counting the string it actually\n * materializes with `countTokens` — the same counter that priced the full\n * text — so the cost the selector checks against the budget is the cost of\n * the text that would be sent. A compression ratio is never a cost: a summary\n * that returns its source unchanged saves nothing, and a representation whose\n * materialized text is not cheaper than the full text is not offered at all.\n * Pass the counter that produced `item.tokenEstimate`; mixing an exact\n * tokenizer for the full text with the heuristic for its alternatives makes\n * the candidates incomparable.\n */\nexport function deriveRepresentationCandidates(\n\titem: ContextBudgetItemV2,\n\tpolicy: HeadroomQualityPolicyV2 = DEFAULT_HEADROOM_QUALITY_POLICY,\n\tcountTokens: RepresentationTokenCounter = heuristicTokenCount,\n): readonly ContextRepresentationCandidateV2[] {\n\tconst full = fullTextTokens(item);\n\tconst sourceRef = item.sourceRef;\n\tconst retrievable = sourceRef?.retrievable === true;\n\tconst candidates: ContextRepresentationCandidateV2[] = [];\n\tconst offerIfCheaper = (candidate: ContextRepresentationCandidateV2): void => {\n\t\tif (candidate.text !== item.text && candidate.estimatedTokens < full) candidates.push(candidate);\n\t};\n\n\tcandidates.push({\n\t\tkind: \"full\",\n\t\ttext: item.text,\n\t\testimatedTokens: full,\n\t\tfidelity: item.tokenEstimate !== undefined ? \"exact\" : \"bounded\",\n\t\tsourceRef,\n\t});\n\n\tif (retrievable && sourceRef) {\n\t\tconst pointerText = formatPointer(sourceRef);\n\t\tofferIfCheaper({\n\t\t\tkind: \"pointer\",\n\t\t\ttext: pointerText,\n\t\t\testimatedTokens: countTokens(pointerText),\n\t\t\tfidelity: \"bounded\",\n\t\t\tsourceRef,\n\t\t});\n\t}\n\n\tif (isSummaryEligible(item, full, policy)) {\n\t\tconst summaryText = summarizeText(item.text);\n\t\tofferIfCheaper({\n\t\t\tkind: \"summary\",\n\t\t\ttext: summaryText,\n\t\t\testimatedTokens: countTokens(summaryText),\n\t\t\tfidelity: \"lossy\",\n\t\t\tsummaryHash: fnv1aHex(item.text),\n\t\t});\n\t}\n\n\tif (full > policy.headroomThresholdTokens && retrievable) {\n\t\tconst headroomText = formatHeadroom(item.text, sourceRef);\n\t\t// The shadow compressor's reversible payload is larger than the visible\n\t\t// head, so its price keeps a floor above the counted head text.\n\t\tofferIfCheaper({\n\t\t\tkind: \"headroom-compressed\",\n\t\t\ttext: headroomText,\n\t\t\testimatedTokens: Math.max(Math.ceil(full * 0.35) + 16, countTokens(headroomText)),\n\t\t\tfidelity: \"reversible\",\n\t\t\tsourceRef,\n\t\t\tcompressorId: \"headroom-shadow\",\n\t\t});\n\t}\n\n\tif (policy.allowOmit) {\n\t\tcandidates.push({\n\t\t\tkind: \"omit\",\n\t\t\ttext: \"\",\n\t\t\testimatedTokens: 0,\n\t\t\tfidelity: \"lossy\",\n\t\t\tsourceRef,\n\t\t});\n\t}\n\n\treturn candidates;\n}\n\nfunction isSummaryEligible(item: ContextBudgetItemV2, fullTokens: number, policy: HeadroomQualityPolicyV2): boolean {\n\treturn (\n\t\titem.tier === \"history\" ||\n\t\titem.tier === \"evidence\" ||\n\t\titem.tier === \"scratch\" ||\n\t\t(item.ageTurns ?? 0) >= policy.summaryMaxAgeTurns ||\n\t\tfullTokens > policy.headroomThresholdTokens\n\t);\n}\n\nfunction formatPointer(ref: ContextSourceRefV2): string {\n\tconst parts: string[] = [`uri=\"${escapeMetadataValue(ref.uri)}\"`];\n\tif (ref.symbol) parts.push(`symbol=\"${escapeMetadataValue(ref.symbol)}\"`);\n\tif (ref.range) parts.push(`lines=\"${ref.range.startLine}-${ref.range.endLine}\"`);\n\tparts.push(`hash=\"${escapeMetadataValue(ref.contentHash)}\"`);\n\treturn `<pointer ${parts.join(\" \")} />`;\n}\n\nfunction summarizeText(text: string): string {\n\tif (text.length <= SUMMARY_HEAD_CHARS) {\n\t\treturn text;\n\t}\n\treturn `${text.slice(0, SUMMARY_HEAD_CHARS)} …[summary]`;\n}\n\nfunction formatHeadroom(text: string, ref?: ContextSourceRefV2): string {\n\tconst head = text.slice(0, HEADROOM_HEAD_CHARS);\n\tconst hash = fnv1aHex(text);\n\tconst where = ref ? ` uri=\"${escapeMetadataValue(ref.uri)}\"` : \"\";\n\treturn `${head} …[headroom-compressed${where} hash=\"${hash}\"]`;\n}\n\nfunction escapeMetadataValue(value: string): string {\n\treturn value\n\t\t.replace(/&/g, \"&\")\n\t\t.replace(/</g, \"<\")\n\t\t.replace(/>/g, \">\")\n\t\t.replace(/\"/g, \""\")\n\t\t.replace(/'/g, \"'\");\n}\n"]}
|