@wrongstack/core 0.284.1 → 0.286.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-status-tracker.d.ts +74 -0
- package/dist/agent-status-tracker.d.ts.map +1 -0
- package/dist/autophase/auto-phase-planner.d.ts +79 -0
- package/dist/autophase/auto-phase-planner.d.ts.map +1 -0
- package/dist/autophase/auto-phase-runner.d.ts +79 -0
- package/dist/autophase/auto-phase-runner.d.ts.map +1 -0
- package/dist/autophase/checkpoint.d.ts +49 -0
- package/dist/autophase/checkpoint.d.ts.map +1 -0
- package/dist/autophase/index.d.ts +9 -0
- package/dist/autophase/index.d.ts.map +1 -0
- package/dist/autophase/phase-graph-builder.d.ts +46 -0
- package/dist/autophase/phase-graph-builder.d.ts.map +1 -0
- package/dist/autophase/phase-orchestrator.d.ts +150 -0
- package/dist/autophase/phase-orchestrator.d.ts.map +1 -0
- package/dist/autophase/phase-store.d.ts +29 -0
- package/dist/autophase/phase-store.d.ts.map +1 -0
- package/dist/autophase/types.d.ts +329 -0
- package/dist/autophase/types.d.ts.map +1 -0
- package/dist/boot.d.ts +73 -0
- package/dist/boot.d.ts.map +1 -0
- package/dist/coordination/adaptive-concurrency.d.ts +63 -0
- package/dist/coordination/adaptive-concurrency.d.ts.map +1 -0
- package/dist/coordination/agent-bridge.d.ts +24 -0
- package/dist/coordination/agent-bridge.d.ts.map +1 -0
- package/dist/coordination/agent-monitor.d.ts +129 -0
- package/dist/coordination/agent-monitor.d.ts.map +1 -0
- package/dist/coordination/agent-subagent-runner.d.ts +74 -0
- package/dist/coordination/agent-subagent-runner.d.ts.map +1 -0
- package/dist/coordination/agents/agent-prompts.d.ts +2 -0
- package/dist/coordination/agents/agent-prompts.d.ts.map +1 -0
- package/dist/coordination/agents/index.d.ts +35 -0
- package/dist/coordination/agents/index.d.ts.map +1 -0
- package/dist/coordination/agents/phase1-discovery.d.ts +4 -0
- package/dist/coordination/agents/phase1-discovery.d.ts.map +1 -0
- package/dist/coordination/agents/phase2-planning.d.ts +4 -0
- package/dist/coordination/agents/phase2-planning.d.ts.map +1 -0
- package/dist/coordination/agents/phase3-build.d.ts +4 -0
- package/dist/coordination/agents/phase3-build.d.ts.map +1 -0
- package/dist/coordination/agents/phase3-techstack.d.ts +13 -0
- package/dist/coordination/agents/phase3-techstack.d.ts.map +1 -0
- package/dist/coordination/agents/phase4-verify.d.ts +4 -0
- package/dist/coordination/agents/phase4-verify.d.ts.map +1 -0
- package/dist/coordination/agents/phase5-review.d.ts +4 -0
- package/dist/coordination/agents/phase5-review.d.ts.map +1 -0
- package/dist/coordination/agents/phase6-domain.d.ts +4 -0
- package/dist/coordination/agents/phase6-domain.d.ts.map +1 -0
- package/dist/coordination/agents/phase7-knowledge.d.ts +4 -0
- package/dist/coordination/agents/phase7-knowledge.d.ts.map +1 -0
- package/dist/coordination/agents/phase8-delivery.d.ts +4 -0
- package/dist/coordination/agents/phase8-delivery.d.ts.map +1 -0
- package/dist/coordination/agents/phase9-meta.d.ts +4 -0
- package/dist/coordination/agents/phase9-meta.d.ts.map +1 -0
- package/dist/coordination/agents/types.d.ts +79 -0
- package/dist/coordination/agents/types.d.ts.map +1 -0
- package/dist/coordination/agents.d.ts +8 -0
- package/dist/coordination/agents.d.ts.map +1 -0
- package/dist/coordination/auto-extend.d.ts +46 -0
- package/dist/coordination/auto-extend.d.ts.map +1 -0
- package/dist/coordination/autonomous-brain.d.ts +152 -0
- package/dist/coordination/autonomous-brain.d.ts.map +1 -0
- package/dist/coordination/autonomous-coordinator.d.ts +243 -0
- package/dist/coordination/autonomous-coordinator.d.ts.map +1 -0
- package/dist/coordination/brain-ledger.d.ts +142 -0
- package/dist/coordination/brain-ledger.d.ts.map +1 -0
- package/dist/coordination/brain-monitor.d.ts +103 -0
- package/dist/coordination/brain-monitor.d.ts.map +1 -0
- package/dist/coordination/brain.d.ts +147 -0
- package/dist/coordination/brain.d.ts.map +1 -0
- package/dist/coordination/change-manager.d.ts +151 -0
- package/dist/coordination/change-manager.d.ts.map +1 -0
- package/dist/coordination/checkpoint-wiring.d.ts +61 -0
- package/dist/coordination/checkpoint-wiring.d.ts.map +1 -0
- package/dist/coordination/collab-bus.d.ts +132 -0
- package/dist/coordination/collab-bus.d.ts.map +1 -0
- package/dist/coordination/collab-debug.d.ts +302 -0
- package/dist/coordination/collab-debug.d.ts.map +1 -0
- package/dist/coordination/commit-safety.d.ts +72 -0
- package/dist/coordination/commit-safety.d.ts.map +1 -0
- package/dist/coordination/consensus-protocol.d.ts +106 -0
- package/dist/coordination/consensus-protocol.d.ts.map +1 -0
- package/dist/coordination/coordinator/error-classifier.d.ts +15 -0
- package/dist/coordination/coordinator/error-classifier.d.ts.map +1 -0
- package/dist/coordination/delegate-tool.d.ts +101 -0
- package/dist/coordination/delegate-tool.d.ts.map +1 -0
- package/dist/coordination/dep-watcher-bridge.d.ts +47 -0
- package/dist/coordination/dep-watcher-bridge.d.ts.map +1 -0
- package/dist/coordination/dep-watcher.d.ts +74 -0
- package/dist/coordination/dep-watcher.d.ts.map +1 -0
- package/dist/coordination/director/director-errors.d.ts +29 -0
- package/dist/coordination/director/director-errors.d.ts.map +1 -0
- package/dist/coordination/director-construction.d.ts +90 -0
- package/dist/coordination/director-construction.d.ts.map +1 -0
- package/dist/coordination/director-prompts.d.ts +119 -0
- package/dist/coordination/director-prompts.d.ts.map +1 -0
- package/dist/coordination/director-session.d.ts +68 -0
- package/dist/coordination/director-session.d.ts.map +1 -0
- package/dist/coordination/director-tools.d.ts +65 -0
- package/dist/coordination/director-tools.d.ts.map +1 -0
- package/dist/coordination/director.d.ts +802 -0
- package/dist/coordination/director.d.ts.map +1 -0
- package/dist/coordination/dispatcher.d.ts +82 -0
- package/dist/coordination/dispatcher.d.ts.map +1 -0
- package/dist/coordination/file-author-tracker.d.ts +76 -0
- package/dist/coordination/file-author-tracker.d.ts.map +1 -0
- package/dist/coordination/fleet-bus.d.ts +122 -0
- package/dist/coordination/fleet-bus.d.ts.map +1 -0
- package/dist/coordination/fleet-event-validation.d.ts +10 -0
- package/dist/coordination/fleet-event-validation.d.ts.map +1 -0
- package/dist/coordination/fleet-manager.d.ts +234 -0
- package/dist/coordination/fleet-manager.d.ts.map +1 -0
- package/dist/coordination/fleet-spawn.d.ts +102 -0
- package/dist/coordination/fleet-spawn.d.ts.map +1 -0
- package/dist/coordination/fleet-status-tool.d.ts +36 -0
- package/dist/coordination/fleet-status-tool.d.ts.map +1 -0
- package/dist/coordination/fleet-supervisor.d.ts +157 -0
- package/dist/coordination/fleet-supervisor.d.ts.map +1 -0
- package/dist/coordination/fleet.d.ts +96 -0
- package/dist/coordination/fleet.d.ts.map +1 -0
- package/dist/coordination/global-mailbox.d.ts +295 -0
- package/dist/coordination/global-mailbox.d.ts.map +1 -0
- package/dist/coordination/icoordinator.d.ts +97 -0
- package/dist/coordination/icoordinator.d.ts.map +1 -0
- package/dist/coordination/ifleet-manager.d.ts +177 -0
- package/dist/coordination/ifleet-manager.d.ts.map +1 -0
- package/dist/coordination/in-memory-transport.d.ts +12 -0
- package/dist/coordination/in-memory-transport.d.ts.map +1 -0
- package/dist/coordination/index.d.ts +79 -2587
- package/dist/coordination/index.d.ts.map +1 -0
- package/dist/coordination/index.js +2262 -673
- package/dist/coordination/index.js.map +7 -1
- package/dist/coordination/knowledge-graph.d.ts +229 -0
- package/dist/coordination/knowledge-graph.d.ts.map +1 -0
- package/dist/coordination/large-answer-store.d.ts +61 -0
- package/dist/coordination/large-answer-store.d.ts.map +1 -0
- package/dist/coordination/mail-tools.d.ts +34 -0
- package/dist/coordination/mail-tools.d.ts.map +1 -0
- package/dist/coordination/mailbox-actions.d.ts +67 -0
- package/dist/coordination/mailbox-actions.d.ts.map +1 -0
- package/dist/coordination/mailbox-constants.d.ts +64 -0
- package/dist/coordination/mailbox-constants.d.ts.map +1 -0
- package/dist/coordination/mailbox-events.d.ts +32 -0
- package/dist/coordination/mailbox-events.d.ts.map +1 -0
- package/dist/coordination/mailbox-health.d.ts +131 -0
- package/dist/coordination/mailbox-health.d.ts.map +1 -0
- package/dist/coordination/mailbox-hooks.d.ts +55 -0
- package/dist/coordination/mailbox-hooks.d.ts.map +1 -0
- package/dist/coordination/mailbox-message-codec.d.ts +8 -0
- package/dist/coordination/mailbox-message-codec.d.ts.map +1 -0
- package/dist/coordination/mailbox-tool.d.ts +75 -0
- package/dist/coordination/mailbox-tool.d.ts.map +1 -0
- package/dist/{mailbox-types-BGZWrYTJ.d.ts → coordination/mailbox-types.d.ts} +125 -26
- package/dist/coordination/mailbox-types.d.ts.map +1 -0
- package/dist/coordination/mailbox.d.ts +88 -0
- package/dist/coordination/mailbox.d.ts.map +1 -0
- package/dist/coordination/model-matrix.d.ts +98 -0
- package/dist/coordination/model-matrix.d.ts.map +1 -0
- package/dist/coordination/multi-agent-coordinator.d.ts +202 -0
- package/dist/coordination/multi-agent-coordinator.d.ts.map +1 -0
- package/dist/coordination/null-fleet-bus.d.ts +10 -0
- package/dist/coordination/null-fleet-bus.d.ts.map +1 -0
- package/dist/coordination/package-author-tracker.d.ts +87 -0
- package/dist/coordination/package-author-tracker.d.ts.map +1 -0
- package/dist/coordination/package-outdated-watcher.d.ts +83 -0
- package/dist/coordination/package-outdated-watcher.d.ts.map +1 -0
- package/dist/coordination/single-instance-mailbox.d.ts +154 -0
- package/dist/coordination/single-instance-mailbox.d.ts.map +1 -0
- package/dist/coordination/spawn-budget.d.ts +6 -0
- package/dist/coordination/spawn-budget.d.ts.map +1 -0
- package/dist/coordination/subagent-budget.d.ts +323 -0
- package/dist/coordination/subagent-budget.d.ts.map +1 -0
- package/dist/coordination/subagent-nicknames.d.ts +42 -0
- package/dist/coordination/subagent-nicknames.d.ts.map +1 -0
- package/dist/coordination/subagent-result-tool.d.ts +20 -0
- package/dist/coordination/subagent-result-tool.d.ts.map +1 -0
- package/dist/coordination/task-auctioneer.d.ts +143 -0
- package/dist/coordination/task-auctioneer.d.ts.map +1 -0
- package/dist/coordination/task-dag.d.ts +147 -0
- package/dist/coordination/task-dag.d.ts.map +1 -0
- package/dist/coordination/techstack-mailbox-consumer.d.ts +50 -0
- package/dist/coordination/techstack-mailbox-consumer.d.ts.map +1 -0
- package/dist/coordination/transport.d.ts +2 -0
- package/dist/coordination/transport.d.ts.map +1 -0
- package/dist/coordination/worktree-task-runner.d.ts +45 -0
- package/dist/coordination/worktree-task-runner.d.ts.map +1 -0
- package/dist/core/agent-internals.d.ts +41 -0
- package/dist/core/agent-internals.d.ts.map +1 -0
- package/dist/core/agent-loop.d.ts +18 -0
- package/dist/core/agent-loop.d.ts.map +1 -0
- package/dist/core/agent-response.d.ts +21 -0
- package/dist/core/agent-response.d.ts.map +1 -0
- package/dist/core/agent-tools.d.ts +21 -0
- package/dist/core/agent-tools.d.ts.map +1 -0
- package/dist/core/agent-types.d.ts +95 -0
- package/dist/core/agent-types.d.ts.map +1 -0
- package/dist/core/agent.d.ts +54 -0
- package/dist/core/agent.d.ts.map +1 -0
- package/dist/core/btw.d.ts +40 -0
- package/dist/core/btw.d.ts.map +1 -0
- package/dist/core/context.d.ts +269 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/continue-intent.d.ts +92 -0
- package/dist/core/continue-intent.d.ts.map +1 -0
- package/dist/core/continue-to-next-iteration.d.ts +96 -0
- package/dist/core/continue-to-next-iteration.d.ts.map +1 -0
- package/dist/core/conversation-state.d.ts +96 -0
- package/dist/core/conversation-state.d.ts.map +1 -0
- package/dist/core/fallback-model.d.ts +94 -0
- package/dist/core/fallback-model.d.ts.map +1 -0
- package/dist/core/fleet-pulse.d.ts +42 -0
- package/dist/core/fleet-pulse.d.ts.map +1 -0
- package/dist/core/input-builder.d.ts +95 -0
- package/dist/core/input-builder.d.ts.map +1 -0
- package/dist/core/instruction-bundle.d.ts +22 -0
- package/dist/core/instruction-bundle.d.ts.map +1 -0
- package/dist/core/iteration-limit.d.ts +35 -0
- package/dist/core/iteration-limit.d.ts.map +1 -0
- package/dist/core/mailbox-loop.d.ts +63 -0
- package/dist/core/mailbox-loop.d.ts.map +1 -0
- package/dist/core/modes/brief.d.ts +2 -0
- package/dist/core/modes/brief.d.ts.map +1 -0
- package/dist/core/modes/default.d.ts +8 -0
- package/dist/core/modes/default.d.ts.map +1 -0
- package/dist/core/modes/teach.d.ts +2 -0
- package/dist/core/modes/teach.d.ts.map +1 -0
- package/dist/core/provider-runner.d.ts +24 -0
- package/dist/core/provider-runner.d.ts.map +1 -0
- package/dist/core/queued-messages.d.ts +55 -0
- package/dist/core/queued-messages.d.ts.map +1 -0
- package/dist/core/run-env.d.ts +49 -0
- package/dist/core/run-env.d.ts.map +1 -0
- package/dist/core/streaming-response-builder.d.ts +78 -0
- package/dist/core/streaming-response-builder.d.ts.map +1 -0
- package/dist/core/system-prompt-builder.d.ts +213 -0
- package/dist/core/system-prompt-builder.d.ts.map +1 -0
- package/dist/defaults/index.d.ts +68 -158
- package/dist/defaults/index.d.ts.map +1 -0
- package/dist/defaults/index.js +2061 -1300
- package/dist/defaults/index.js.map +7 -1
- package/dist/execution/auto-compaction-middleware.d.ts +123 -0
- package/dist/execution/auto-compaction-middleware.d.ts.map +1 -0
- package/dist/execution/autonomous-runner.d.ts +61 -0
- package/dist/execution/autonomous-runner.d.ts.map +1 -0
- package/dist/execution/autonomy-brain.d.ts +151 -0
- package/dist/execution/autonomy-brain.d.ts.map +1 -0
- package/dist/execution/autonomy-prompt-contributor.d.ts +39 -0
- package/dist/execution/autonomy-prompt-contributor.d.ts.map +1 -0
- package/dist/execution/brain-chain.d.ts +53 -0
- package/dist/execution/brain-chain.d.ts.map +1 -0
- package/dist/execution/brain-evaluation.d.ts +66 -0
- package/dist/execution/brain-evaluation.d.ts.map +1 -0
- package/dist/execution/brain-runtime.d.ts +171 -0
- package/dist/execution/brain-runtime.d.ts.map +1 -0
- package/dist/execution/compaction-core.d.ts +103 -0
- package/dist/execution/compaction-core.d.ts.map +1 -0
- package/dist/execution/compactor.d.ts +56 -0
- package/dist/execution/compactor.d.ts.map +1 -0
- package/dist/execution/council-brain.d.ts +79 -0
- package/dist/execution/council-brain.d.ts.map +1 -0
- package/dist/execution/design-color.d.ts +31 -0
- package/dist/execution/design-color.d.ts.map +1 -0
- package/dist/execution/design-detect.d.ts +96 -0
- package/dist/execution/design-detect.d.ts.map +1 -0
- package/dist/execution/design-kit-loader.d.ts +53 -0
- package/dist/execution/design-kit-loader.d.ts.map +1 -0
- package/dist/execution/design-materialize.d.ts +32 -0
- package/dist/execution/design-materialize.d.ts.map +1 -0
- package/dist/execution/design-project-store.d.ts +57 -0
- package/dist/execution/design-project-store.d.ts.map +1 -0
- package/dist/execution/design-verify.d.ts +44 -0
- package/dist/execution/design-verify.d.ts.map +1 -0
- package/dist/execution/error-handler.d.ts +34 -0
- package/dist/execution/error-handler.d.ts.map +1 -0
- package/dist/{parallel-eternal-engine-HUrtePLd.d.ts → execution/eternal-autonomy.d.ts} +22 -225
- package/dist/execution/eternal-autonomy.d.ts.map +1 -0
- package/dist/execution/goal-preamble.d.ts +2 -0
- package/dist/execution/goal-preamble.d.ts.map +1 -0
- package/dist/execution/index.d.ts +25 -180
- package/dist/execution/index.d.ts.map +1 -0
- package/dist/execution/index.js +1748 -490
- package/dist/execution/index.js.map +7 -1
- package/dist/execution/intelligent-compactor.d.ts +85 -0
- package/dist/execution/intelligent-compactor.d.ts.map +1 -0
- package/dist/execution/model-runtime.d.ts +75 -0
- package/dist/execution/model-runtime.d.ts.map +1 -0
- package/dist/execution/parallel-eternal-engine.d.ts +142 -0
- package/dist/execution/parallel-eternal-engine.d.ts.map +1 -0
- package/dist/execution/prompt-enhancer.d.ts +12 -13
- package/dist/execution/prompt-enhancer.d.ts.map +1 -0
- package/dist/execution/prompt-enhancer.js +13 -7
- package/dist/execution/prompt-enhancer.js.map +7 -1
- package/dist/execution/prompt-loader.d.ts +52 -0
- package/dist/execution/prompt-loader.d.ts.map +1 -0
- package/dist/execution/provider-runner-impl.d.ts +14 -0
- package/dist/execution/provider-runner-impl.d.ts.map +1 -0
- package/dist/execution/regex-patterns.d.ts +7 -0
- package/dist/execution/regex-patterns.d.ts.map +1 -0
- package/dist/execution/retry-policy.d.ts +35 -0
- package/dist/execution/retry-policy.d.ts.map +1 -0
- package/dist/execution/selective-compactor.d.ts +94 -0
- package/dist/execution/selective-compactor.d.ts.map +1 -0
- package/dist/execution/skill-loader.d.ts +43 -0
- package/dist/execution/skill-loader.d.ts.map +1 -0
- package/dist/execution/strategy-compactor.d.ts +43 -0
- package/dist/execution/strategy-compactor.d.ts.map +1 -0
- package/dist/execution/tool-executor.d.ts +112 -0
- package/dist/execution/tool-executor.d.ts.map +1 -0
- package/dist/extension/extension-points.d.ts +121 -0
- package/dist/extension/extension-points.d.ts.map +1 -0
- package/dist/extension/index.d.ts +3 -10
- package/dist/extension/index.d.ts.map +1 -0
- package/dist/extension/index.js +59 -5
- package/dist/extension/index.js.map +7 -1
- package/dist/extension/registry.d.ts +86 -0
- package/dist/extension/registry.d.ts.map +1 -0
- package/dist/fleet-notifier.d.ts +28 -0
- package/dist/fleet-notifier.d.ts.map +1 -0
- package/dist/hooks/http-executor.d.ts +11 -0
- package/dist/hooks/http-executor.d.ts.map +1 -0
- package/dist/hooks/index.d.ts +10 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/registry.d.ts +71 -0
- package/dist/hooks/registry.d.ts.map +1 -0
- package/dist/hooks/runner.d.ts +65 -0
- package/dist/hooks/runner.d.ts.map +1 -0
- package/dist/hooks/shell-executor.d.ts +33 -0
- package/dist/hooks/shell-executor.d.ts.map +1 -0
- package/dist/hooks/shell-hooks-equal.d.ts +15 -0
- package/dist/hooks/shell-hooks-equal.d.ts.map +1 -0
- package/dist/hq/agent-bridge.d.ts +27 -0
- package/dist/hq/agent-bridge.d.ts.map +1 -0
- package/dist/hq/alerts.d.ts +67 -0
- package/dist/hq/alerts.d.ts.map +1 -0
- package/dist/hq/auth-store.d.ts +179 -0
- package/dist/hq/auth-store.d.ts.map +1 -0
- package/dist/hq/brain-bridge.d.ts +37 -0
- package/dist/hq/brain-bridge.d.ts.map +1 -0
- package/dist/hq/commands.d.ts +122 -0
- package/dist/hq/commands.d.ts.map +1 -0
- package/dist/hq/cost-bridge.d.ts +36 -0
- package/dist/hq/cost-bridge.d.ts.map +1 -0
- package/dist/hq/factory.d.ts +69 -0
- package/dist/hq/factory.d.ts.map +1 -0
- package/dist/hq/fleet-bridge.d.ts +39 -0
- package/dist/hq/fleet-bridge.d.ts.map +1 -0
- package/dist/hq/index.d.ts +18 -816
- package/dist/hq/index.d.ts.map +1 -0
- package/dist/hq/index.js +1043 -192
- package/dist/hq/index.js.map +7 -1
- package/dist/hq/mailbox-mapper.d.ts +27 -0
- package/dist/hq/mailbox-mapper.d.ts.map +1 -0
- package/dist/hq/persistence.d.ts +121 -0
- package/dist/hq/persistence.d.ts.map +1 -0
- package/dist/hq/protocol.d.ts +612 -0
- package/dist/hq/protocol.d.ts.map +1 -0
- package/dist/hq/publisher.d.ts +181 -0
- package/dist/hq/publisher.d.ts.map +1 -0
- package/dist/hq/redaction.d.ts +30 -0
- package/dist/hq/redaction.d.ts.map +1 -0
- package/dist/hq/session-bridge.d.ts +29 -0
- package/dist/hq/session-bridge.d.ts.map +1 -0
- package/dist/hq/tool-bridge.d.ts +41 -0
- package/dist/hq/tool-bridge.d.ts.map +1 -0
- package/dist/hq/transcript-mapper.d.ts +36 -0
- package/dist/hq/transcript-mapper.d.ts.map +1 -0
- package/dist/hq/worktree-bridge.d.ts +34 -0
- package/dist/hq/worktree-bridge.d.ts.map +1 -0
- package/dist/index.d.ts +114 -2872
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6104 -2737
- package/dist/index.js.map +7 -1
- package/dist/infrastructure/context-manager.d.ts +92 -0
- package/dist/infrastructure/context-manager.d.ts.map +1 -0
- package/dist/infrastructure/index.d.ts +6 -64
- package/dist/infrastructure/index.d.ts.map +1 -0
- package/dist/infrastructure/index.js +39 -12
- package/dist/infrastructure/index.js.map +7 -1
- package/dist/infrastructure/logger.d.ts +99 -0
- package/dist/infrastructure/logger.d.ts.map +1 -0
- package/dist/infrastructure/mcp-servers.d.ts +83 -0
- package/dist/infrastructure/mcp-servers.d.ts.map +1 -0
- package/dist/{path-resolver-CMS5307d.d.ts → infrastructure/path-resolver.d.ts} +3 -5
- package/dist/infrastructure/path-resolver.d.ts.map +1 -0
- package/dist/infrastructure/token-counter.d.ts +57 -0
- package/dist/infrastructure/token-counter.d.ts.map +1 -0
- package/dist/kernel/container.d.ts +84 -0
- package/dist/kernel/container.d.ts.map +1 -0
- package/dist/{events-Bgnh43r9.d.ts → kernel/events.d.ts} +134 -210
- package/dist/kernel/events.d.ts.map +1 -0
- package/dist/kernel/index.d.ts +6 -107
- package/dist/kernel/index.d.ts.map +1 -0
- package/dist/kernel/index.js +56 -4
- package/dist/kernel/index.js.map +7 -1
- package/dist/kernel/pipeline.d.ts +105 -0
- package/dist/kernel/pipeline.d.ts.map +1 -0
- package/dist/kernel/run-controller.d.ts +55 -0
- package/dist/kernel/run-controller.d.ts.map +1 -0
- package/dist/kernel/tokens.d.ts +53 -0
- package/dist/kernel/tokens.d.ts.map +1 -0
- package/dist/mailbox-attach.d.ts +27 -0
- package/dist/mailbox-attach.d.ts.map +1 -0
- package/dist/middleware/collab-pause.d.ts +73 -0
- package/dist/middleware/collab-pause.d.ts.map +1 -0
- package/dist/models/codex-catalog.d.ts +41 -0
- package/dist/models/codex-catalog.d.ts.map +1 -0
- package/dist/models/index.d.ts +8 -163
- package/dist/models/index.d.ts.map +1 -0
- package/dist/models/index.js +150 -51
- package/dist/models/index.js.map +7 -1
- package/dist/models/llm-selector.d.ts +47 -0
- package/dist/models/llm-selector.d.ts.map +1 -0
- package/dist/models/mode-store.d.ts +22 -0
- package/dist/models/mode-store.d.ts.map +1 -0
- package/dist/models/model-intelligence.d.ts +56 -0
- package/dist/models/model-intelligence.d.ts.map +1 -0
- package/dist/models/model-router.d.ts +100 -0
- package/dist/models/model-router.d.ts.map +1 -0
- package/dist/models/models-registry.d.ts +106 -0
- package/dist/models/models-registry.d.ts.map +1 -0
- package/dist/models/provider-model-resolve.d.ts +69 -0
- package/dist/models/provider-model-resolve.d.ts.map +1 -0
- package/dist/observability/event-bridge.d.ts +10 -0
- package/dist/observability/event-bridge.d.ts.map +1 -0
- package/dist/observability/health.d.ts +18 -0
- package/dist/observability/health.d.ts.map +1 -0
- package/dist/observability/index.d.ts +9 -354
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +37 -23
- package/dist/observability/index.js.map +7 -1
- package/dist/observability/metrics.d.ts +26 -0
- package/dist/observability/metrics.d.ts.map +1 -0
- package/dist/observability/otel-tracer.d.ts +41 -0
- package/dist/observability/otel-tracer.d.ts.map +1 -0
- package/dist/observability/otlp-metrics.d.ts +111 -0
- package/dist/observability/otlp-metrics.d.ts.map +1 -0
- package/dist/observability/otlp-traces.d.ts +95 -0
- package/dist/observability/otlp-traces.d.ts.map +1 -0
- package/dist/observability/prometheus.d.ts +49 -0
- package/dist/observability/prometheus.d.ts.map +1 -0
- package/dist/observability/tracer.d.ts +9 -0
- package/dist/observability/tracer.d.ts.map +1 -0
- package/dist/plugin/api.d.ts +226 -0
- package/dist/plugin/api.d.ts.map +1 -0
- package/dist/plugin/loader.d.ts +73 -0
- package/dist/plugin/loader.d.ts.map +1 -0
- package/dist/plugins/chimera-plugin.d.ts +37 -0
- package/dist/plugins/chimera-plugin.d.ts.map +1 -0
- package/dist/plugins/prompts-plugin.d.ts +26 -0
- package/dist/plugins/prompts-plugin.d.ts.map +1 -0
- package/dist/plugins/security-plugin.d.ts +19 -0
- package/dist/plugins/security-plugin.d.ts.map +1 -0
- package/dist/plugins/skills-plugin.d.ts +42 -0
- package/dist/plugins/skills-plugin.d.ts.map +1 -0
- package/dist/plugins/sync-plugin.d.ts +22 -0
- package/dist/plugins/sync-plugin.d.ts.map +1 -0
- package/dist/prompts/index.d.ts +3 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/prompt-installer.d.ts +50 -0
- package/dist/prompts/prompt-installer.d.ts.map +1 -0
- package/dist/prompts/prompt-manifest-store.d.ts +18 -0
- package/dist/prompts/prompt-manifest-store.d.ts.map +1 -0
- package/dist/registry/provider-registry.d.ts +51 -0
- package/dist/registry/provider-registry.d.ts.map +1 -0
- package/dist/registry/slash-command-registry.d.ts +61 -0
- package/dist/registry/slash-command-registry.d.ts.map +1 -0
- package/dist/registry/tool-registry.d.ts +154 -0
- package/dist/registry/tool-registry.d.ts.map +1 -0
- package/dist/replay/hash.d.ts +31 -0
- package/dist/replay/hash.d.ts.map +1 -0
- package/dist/replay/replay-provider-runner.d.ts +53 -0
- package/dist/replay/replay-provider-runner.d.ts.map +1 -0
- package/dist/{index-CbyuOE5y.d.ts → security/capabilities.d.ts} +31 -34
- package/dist/security/capabilities.d.ts.map +1 -0
- package/dist/security/config-secrets.d.ts +25 -0
- package/dist/security/config-secrets.d.ts.map +1 -0
- package/dist/security/index.d.ts +7 -8
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +354 -401
- package/dist/security/index.js.map +7 -1
- package/dist/security/permission-policy-schema.d.ts +77 -0
- package/dist/security/permission-policy-schema.d.ts.map +1 -0
- package/dist/security/permission-policy.d.ts +158 -0
- package/dist/security/permission-policy.d.ts.map +1 -0
- package/dist/security/secret-scrubber.d.ts +14 -0
- package/dist/security/secret-scrubber.d.ts.map +1 -0
- package/dist/security/secret-vault.d.ts +96 -0
- package/dist/security/secret-vault.d.ts.map +1 -0
- package/dist/security/yolo-risk.d.ts +11 -0
- package/dist/security/yolo-risk.d.ts.map +1 -0
- package/dist/{session-registry-Dvg7i_IA.d.ts → session-registry.d.ts} +8 -9
- package/dist/session-registry.d.ts.map +1 -0
- package/dist/skills/foreign-sources.d.ts +59 -0
- package/dist/skills/foreign-sources.d.ts.map +1 -0
- package/dist/skills/frontmatter.d.ts +44 -0
- package/dist/skills/frontmatter.d.ts.map +1 -0
- package/dist/skills/github-fetcher.d.ts +38 -0
- package/dist/skills/github-fetcher.d.ts.map +1 -0
- package/dist/skills/index.d.ts +11 -582
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +81 -43
- package/dist/skills/index.js.map +7 -1
- package/dist/skills/limits.d.ts +92 -0
- package/dist/skills/limits.d.ts.map +1 -0
- package/dist/skills/manifest-store.d.ts +42 -0
- package/dist/skills/manifest-store.d.ts.map +1 -0
- package/dist/skills/registry/github-direct-adapter.d.ts +17 -0
- package/dist/skills/registry/github-direct-adapter.d.ts.map +1 -0
- package/dist/skills/registry/registry-adapter.d.ts +84 -0
- package/dist/skills/registry/registry-adapter.d.ts.map +1 -0
- package/dist/skills/registry/skills-sh-adapter.d.ts +13 -0
- package/dist/skills/registry/skills-sh-adapter.d.ts.map +1 -0
- package/dist/skills/skill-generator.d.ts +82 -0
- package/dist/skills/skill-generator.d.ts.map +1 -0
- package/dist/skills/skill-installer.d.ts +124 -0
- package/dist/skills/skill-installer.d.ts.map +1 -0
- package/dist/storage/annotations-store.d.ts +118 -0
- package/dist/storage/annotations-store.d.ts.map +1 -0
- package/dist/storage/attachment-store.d.ts +31 -0
- package/dist/storage/attachment-store.d.ts.map +1 -0
- package/dist/storage/cloud-sync.d.ts +44 -0
- package/dist/storage/cloud-sync.d.ts.map +1 -0
- package/dist/storage/completed-work-checkpoint.d.ts +11 -0
- package/dist/storage/completed-work-checkpoint.d.ts.map +1 -0
- package/dist/storage/config-loader.d.ts +114 -0
- package/dist/storage/config-loader.d.ts.map +1 -0
- package/dist/storage/config-migration.d.ts +87 -0
- package/dist/storage/config-migration.d.ts.map +1 -0
- package/dist/storage/config-store.d.ts +22 -0
- package/dist/storage/config-store.d.ts.map +1 -0
- package/dist/{director-state-CMS_bMs4.d.ts → storage/director-state.d.ts} +28 -8
- package/dist/storage/director-state.d.ts.map +1 -0
- package/dist/storage/file-session-writer.d.ts +169 -0
- package/dist/storage/file-session-writer.d.ts.map +1 -0
- package/dist/{goal-store-Datpp-ar.d.ts → storage/goal-store.d.ts} +26 -19
- package/dist/storage/goal-store.d.ts.map +1 -0
- package/dist/storage/index.d.ts +39 -1031
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +783 -443
- package/dist/storage/index.js.map +7 -1
- package/dist/storage/input-history-store.d.ts +56 -0
- package/dist/storage/input-history-store.d.ts.map +1 -0
- package/dist/storage/memory-backend.d.ts +66 -0
- package/dist/storage/memory-backend.d.ts.map +1 -0
- package/dist/storage/memory-consolidator.d.ts +50 -0
- package/dist/storage/memory-consolidator.d.ts.map +1 -0
- package/dist/storage/memory-graph-backend.d.ts +117 -0
- package/dist/storage/memory-graph-backend.d.ts.map +1 -0
- package/dist/storage/memory-store.d.ts +119 -0
- package/dist/storage/memory-store.d.ts.map +1 -0
- package/dist/storage/plan-store.d.ts +78 -0
- package/dist/storage/plan-store.d.ts.map +1 -0
- package/dist/storage/plan-templates.d.ts +21 -0
- package/dist/storage/plan-templates.d.ts.map +1 -0
- package/dist/storage/prompt-store.d.ts +37 -0
- package/dist/storage/prompt-store.d.ts.map +1 -0
- package/dist/storage/prompt-usage-store.d.ts +29 -0
- package/dist/storage/prompt-usage-store.d.ts.map +1 -0
- package/dist/storage/provider-config-watcher.d.ts +34 -0
- package/dist/storage/provider-config-watcher.d.ts.map +1 -0
- package/dist/storage/queue-store.d.ts +41 -0
- package/dist/storage/queue-store.d.ts.map +1 -0
- package/dist/storage/recovery-lock.d.ts +79 -0
- package/dist/storage/recovery-lock.d.ts.map +1 -0
- package/dist/storage/replay-log-store.d.ts +97 -0
- package/dist/storage/replay-log-store.d.ts.map +1 -0
- package/dist/storage/session-analyzer.d.ts +48 -0
- package/dist/storage/session-analyzer.d.ts.map +1 -0
- package/dist/storage/session-checkpoint-cas.d.ts +37 -0
- package/dist/storage/session-checkpoint-cas.d.ts.map +1 -0
- package/dist/{session-event-bridge-D_z_mBwk.d.ts → storage/session-event-bridge.d.ts} +14 -15
- package/dist/storage/session-event-bridge.d.ts.map +1 -0
- package/dist/storage/session-helpers.d.ts +9 -0
- package/dist/storage/session-helpers.d.ts.map +1 -0
- package/dist/storage/session-id.d.ts +18 -0
- package/dist/storage/session-id.d.ts.map +1 -0
- package/dist/storage/session-reader.d.ts +21 -0
- package/dist/storage/session-reader.d.ts.map +1 -0
- package/dist/storage/session-recovery.d.ts +93 -0
- package/dist/storage/session-recovery.d.ts.map +1 -0
- package/dist/storage/session-resume-validation.d.ts +6 -0
- package/dist/storage/session-resume-validation.d.ts.map +1 -0
- package/dist/storage/session-rewinder.d.ts +21 -0
- package/dist/storage/session-rewinder.d.ts.map +1 -0
- package/dist/storage/session-store.d.ts +219 -0
- package/dist/storage/session-store.d.ts.map +1 -0
- package/dist/storage/session-summary.d.ts +12 -0
- package/dist/storage/session-summary.d.ts.map +1 -0
- package/dist/storage/session-tool-call-ends.d.ts +5 -0
- package/dist/storage/session-tool-call-ends.d.ts.map +1 -0
- package/dist/storage/storage-concurrency.d.ts +2 -0
- package/dist/storage/storage-concurrency.d.ts.map +1 -0
- package/dist/storage/task-store.d.ts +33 -0
- package/dist/storage/task-store.d.ts.map +1 -0
- package/dist/storage/todos-checkpoint.d.ts +39 -0
- package/dist/storage/todos-checkpoint.d.ts.map +1 -0
- package/dist/storage/tool-audit-log.d.ts +141 -0
- package/dist/storage/tool-audit-log.d.ts.map +1 -0
- package/dist/tasking/index.d.ts +3 -124
- package/dist/tasking/index.d.ts.map +1 -0
- package/dist/tasking/index.js +57 -4
- package/dist/tasking/index.js.map +7 -1
- package/dist/tasking/task-store.d.ts +22 -0
- package/dist/tasking/task-store.d.ts.map +1 -0
- package/dist/tasking/task-tracker.d.ts +102 -0
- package/dist/tasking/task-tracker.d.ts.map +1 -0
- package/dist/tools/index.d.ts +2 -59
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +93 -14
- package/dist/tools/index.js.map +7 -1
- package/dist/tools/mcp-control.d.ts +53 -0
- package/dist/tools/mcp-control.d.ts.map +1 -0
- package/dist/tools/mcp-use.d.ts +24 -0
- package/dist/tools/mcp-use.d.ts.map +1 -0
- package/dist/types/agent-bridge.d.ts +42 -0
- package/dist/types/agent-bridge.d.ts.map +1 -0
- package/dist/types/attachment.d.ts +54 -0
- package/dist/types/attachment.d.ts.map +1 -0
- package/dist/types/autonomy.d.ts +5 -0
- package/dist/types/autonomy.d.ts.map +1 -0
- package/dist/types/blocks.d.ts +76 -0
- package/dist/types/blocks.d.ts.map +1 -0
- package/dist/{compactor-DQLL4HTo.d.ts → types/compactor.d.ts} +5 -7
- package/dist/types/compactor.d.ts.map +1 -0
- package/dist/{config-MRqn1V-u.d.ts → types/config.d.ts} +344 -355
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/context-evidence.d.ts +68 -0
- package/dist/types/context-evidence.d.ts.map +1 -0
- package/dist/types/context-window.d.ts +35 -0
- package/dist/types/context-window.d.ts.map +1 -0
- package/dist/{default-config-B79_gJYv.d.ts → types/default-config.d.ts} +10 -11
- package/dist/types/default-config.d.ts.map +1 -0
- package/dist/types/design-kit.d.ts +91 -0
- package/dist/types/design-kit.d.ts.map +1 -0
- package/dist/{retry-policy-CQ7KwXJa.d.ts → types/error-handler.d.ts} +5 -12
- package/dist/types/error-handler.d.ts.map +1 -0
- package/dist/types/errors.d.ts +277 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/hooks.d.ts +167 -0
- package/dist/types/hooks.d.ts.map +1 -0
- package/dist/types/index.d.ts +40 -244
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +101 -12
- package/dist/types/index.js.map +7 -1
- package/dist/{input-reader-E-ffP2ee.d.ts → types/input-reader.d.ts} +3 -4
- package/dist/types/input-reader.d.ts.map +1 -0
- package/dist/{logger-B63L5bTg.d.ts → types/logger.d.ts} +3 -4
- package/dist/types/logger.d.ts.map +1 -0
- package/dist/types/memory.d.ts +89 -0
- package/dist/types/memory.d.ts.map +1 -0
- package/dist/types/messages.d.ts +24 -0
- package/dist/types/messages.d.ts.map +1 -0
- package/dist/types/mode-prompts.d.ts +2 -0
- package/dist/types/mode-prompts.d.ts.map +1 -0
- package/dist/{mode-CZlO9iU1.d.ts → types/mode.d.ts} +6 -7
- package/dist/types/mode.d.ts.map +1 -0
- package/dist/types/models-registry.d.ts +105 -0
- package/dist/types/models-registry.d.ts.map +1 -0
- package/dist/types/multi-agent.d.ts +443 -0
- package/dist/types/multi-agent.d.ts.map +1 -0
- package/dist/{observability-D-HZN_mF.d.ts → types/observability.d.ts} +17 -13
- package/dist/types/observability.d.ts.map +1 -0
- package/dist/{path-resolver-CPRj4bFY.d.ts → types/path-resolver.d.ts} +2 -3
- package/dist/types/path-resolver.d.ts.map +1 -0
- package/dist/{permission-ByDKXEcG.d.ts → types/permission.d.ts} +8 -9
- package/dist/types/permission.d.ts.map +1 -0
- package/dist/types/plugin.d.ts +385 -0
- package/dist/types/plugin.d.ts.map +1 -0
- package/dist/types/prompt-registry.d.ts +81 -0
- package/dist/types/prompt-registry.d.ts.map +1 -0
- package/dist/{prompt-DLd35n4Q.d.ts → types/prompt.d.ts} +14 -15
- package/dist/types/prompt.d.ts.map +1 -0
- package/dist/{provider-runner-ChL-kVg6.d.ts → types/provider-runner.d.ts} +9 -10
- package/dist/types/provider-runner.d.ts.map +1 -0
- package/dist/types/provider.d.ts +387 -0
- package/dist/types/provider.d.ts.map +1 -0
- package/dist/types/renderer.d.ts +23 -0
- package/dist/types/renderer.d.ts.map +1 -0
- package/dist/types/retry-policy.d.ts +7 -0
- package/dist/types/retry-policy.d.ts.map +1 -0
- package/dist/types/secret-scrubber.d.ts +5 -0
- package/dist/types/secret-scrubber.d.ts.map +1 -0
- package/dist/{secret-vault-BAKpgFw_.d.ts → types/secret-vault.d.ts} +13 -7
- package/dist/types/secret-vault.d.ts.map +1 -0
- package/dist/{selector-D8O6B_Rm.d.ts → types/selector.d.ts} +4 -6
- package/dist/types/selector.d.ts.map +1 -0
- package/dist/types/session-reader.d.ts +81 -0
- package/dist/types/session-reader.d.ts.map +1 -0
- package/dist/{session-rewinder-C9HnMkhP.d.ts → types/session-rewinder.d.ts} +5 -6
- package/dist/types/session-rewinder.d.ts.map +1 -0
- package/dist/types/session.d.ts +650 -0
- package/dist/types/session.d.ts.map +1 -0
- package/dist/types/side-effect.d.ts +34 -0
- package/dist/types/side-effect.d.ts.map +1 -0
- package/dist/{skill-DHniprNl.d.ts → types/skill.d.ts} +4 -5
- package/dist/types/skill.d.ts.map +1 -0
- package/dist/types/slash-command.d.ts +59 -0
- package/dist/types/slash-command.d.ts.map +1 -0
- package/dist/types/spec.d.ts +77 -0
- package/dist/types/spec.d.ts.map +1 -0
- package/dist/types/system-prompt-contributor.d.ts +20 -0
- package/dist/types/system-prompt-contributor.d.ts.map +1 -0
- package/dist/types/system-prompt.d.ts +51 -0
- package/dist/types/system-prompt.d.ts.map +1 -0
- package/dist/{task-graph-CH3acNQ7.d.ts → types/task-graph.d.ts} +21 -22
- package/dist/types/task-graph.d.ts.map +1 -0
- package/dist/types/token-counter.d.ts +42 -0
- package/dist/types/token-counter.d.ts.map +1 -0
- package/dist/types/tool-executor.d.ts +133 -0
- package/dist/types/tool-executor.d.ts.map +1 -0
- package/dist/types/tool-markers.d.ts +23 -0
- package/dist/types/tool-markers.d.ts.map +1 -0
- package/dist/types/tool.d.ts +252 -0
- package/dist/types/tool.d.ts.map +1 -0
- package/dist/types/utility-types.d.ts +31 -0
- package/dist/types/utility-types.d.ts.map +1 -0
- package/dist/utils/assert-never.d.ts +14 -0
- package/dist/utils/assert-never.d.ts.map +1 -0
- package/dist/utils/atomic-write.d.ts +12 -0
- package/dist/utils/atomic-write.d.ts.map +1 -0
- package/dist/utils/child-env.d.ts +67 -0
- package/dist/utils/child-env.d.ts.map +1 -0
- package/dist/utils/color.d.ts +20 -0
- package/dist/utils/color.d.ts.map +1 -0
- package/dist/utils/config-json.d.ts +14 -0
- package/dist/utils/config-json.d.ts.map +1 -0
- package/dist/utils/context-evidence.d.ts +47 -0
- package/dist/utils/context-evidence.d.ts.map +1 -0
- package/dist/utils/deep-merge.d.ts +64 -0
- package/dist/utils/deep-merge.d.ts.map +1 -0
- package/dist/utils/diff.d.ts +11 -0
- package/dist/utils/diff.d.ts.map +1 -0
- package/dist/utils/error.d.ts +2 -3
- package/dist/utils/error.d.ts.map +1 -0
- package/dist/utils/error.js +3 -3
- package/dist/utils/error.js.map +7 -1
- package/dist/utils/expect-defined.d.ts +2 -3
- package/dist/utils/expect-defined.d.ts.map +1 -0
- package/dist/utils/expect-defined.js +3 -3
- package/dist/utils/expect-defined.js.map +7 -1
- package/dist/utils/glob-expand.d.ts +10 -0
- package/dist/utils/glob-expand.d.ts.map +1 -0
- package/dist/utils/glob-match.d.ts +4 -0
- package/dist/utils/glob-match.d.ts.map +1 -0
- package/dist/utils/incoming-images.d.ts +39 -0
- package/dist/utils/incoming-images.d.ts.map +1 -0
- package/dist/utils/index.d.ts +38 -920
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +323 -36
- package/dist/utils/index.js.map +7 -1
- package/dist/utils/instruction-file.d.ts +3 -0
- package/dist/utils/instruction-file.d.ts.map +1 -0
- package/dist/utils/ip-guard.d.ts +34 -0
- package/dist/utils/ip-guard.d.ts.map +1 -0
- package/dist/utils/json-repair.d.ts +23 -0
- package/dist/utils/json-repair.d.ts.map +1 -0
- package/dist/utils/json-schema-validate.d.ts +42 -0
- package/dist/utils/json-schema-validate.d.ts.map +1 -0
- package/dist/utils/lru-cache.d.ts +29 -0
- package/dist/utils/lru-cache.d.ts.map +1 -0
- package/dist/utils/merge-custom-models.d.ts +12 -0
- package/dist/utils/merge-custom-models.d.ts.map +1 -0
- package/dist/utils/merge-models-payload.d.ts +20 -0
- package/dist/utils/merge-models-payload.d.ts.map +1 -0
- package/dist/utils/message-invariants.d.ts +22 -0
- package/dist/utils/message-invariants.d.ts.map +1 -0
- package/dist/utils/newline-normalize.d.ts +5 -0
- package/dist/utils/newline-normalize.d.ts.map +1 -0
- package/dist/utils/regex-guard.d.ts +21 -0
- package/dist/utils/regex-guard.d.ts.map +1 -0
- package/dist/utils/safe-json.d.ts +31 -0
- package/dist/utils/safe-json.d.ts.map +1 -0
- package/dist/utils/session-scoped-path.d.ts +13 -0
- package/dist/utils/session-scoped-path.d.ts.map +1 -0
- package/dist/utils/sleep.d.ts +5 -0
- package/dist/utils/sleep.d.ts.map +1 -0
- package/dist/utils/slug.d.ts +13 -0
- package/dist/utils/slug.d.ts.map +1 -0
- package/dist/utils/string.d.ts +9 -0
- package/dist/utils/string.d.ts.map +1 -0
- package/dist/utils/task-format.d.ts +22 -0
- package/dist/utils/task-format.d.ts.map +1 -0
- package/dist/utils/term.d.ts +133 -0
- package/dist/utils/term.d.ts.map +1 -0
- package/dist/utils/todos-format.d.ts +30 -0
- package/dist/utils/todos-format.d.ts.map +1 -0
- package/dist/utils/token-estimate.d.ts +112 -0
- package/dist/utils/token-estimate.d.ts.map +1 -0
- package/dist/utils/tool-description-mode.d.ts +28 -0
- package/dist/utils/tool-description-mode.d.ts.map +1 -0
- package/dist/utils/tool-output-serializer.d.ts +40 -0
- package/dist/utils/tool-output-serializer.d.ts.map +1 -0
- package/dist/utils/tool-result-render-mode.d.ts +55 -0
- package/dist/utils/tool-result-render-mode.d.ts.map +1 -0
- package/dist/utils/tool-subject.d.ts +5 -0
- package/dist/utils/tool-subject.d.ts.map +1 -0
- package/dist/utils/tool-wire-compact.d.ts +28 -0
- package/dist/utils/tool-wire-compact.d.ts.map +1 -0
- package/dist/utils/ulid.d.ts +11 -0
- package/dist/utils/ulid.d.ts.map +1 -0
- package/dist/{wstack-paths-C3K40Qst.d.ts → utils/wstack-paths.d.ts} +7 -8
- package/dist/utils/wstack-paths.d.ts.map +1 -0
- package/dist/worktree/index.d.ts +2 -0
- package/dist/worktree/index.d.ts.map +1 -0
- package/dist/{worktree-manager-DzwxKE35.d.ts → worktree/worktree-manager.d.ts} +32 -17
- package/dist/worktree/worktree-manager.d.ts.map +1 -0
- package/instructions/agents/browser.md +25 -16
- package/instructions/autonomy/active-mission.md +2 -4
- package/instructions/coordination/subagent-baseline.md +16 -2
- package/instructions/leader-after-task.md +3 -1
- package/instructions/sections/tool/common-patterns.md +7 -1
- package/instructions/sections/tool/delegation-full.md +1 -1
- package/instructions/system.md +47 -0
- package/package.json +4 -5
- package/skills/docker-deploy/SKILL.md +1 -1
- package/skills/node-modern/SKILL.md +2 -2
- package/skills/plugin-author/SKILL.md +9 -16
- package/skills/wrongstack-mailbox/SKILL.md +51 -12
- package/dist/dispatcher-types.d-BBeXBQgS.d.ts +0 -66
- package/dist/global-mailbox-sZwyI6CS.d.ts +0 -959
- package/dist/index--Gm41aBJ.d.ts +0 -671
- package/dist/mcp-servers-DEV4s6Ks.d.ts +0 -259
- package/dist/multi-agent-coordinator-4RCRZKjN.d.ts +0 -1770
- package/dist/null-fleet-bus-CFoNVQEK.d.ts +0 -2127
- package/dist/pipeline-DGDyIohT.d.ts +0 -331
- package/dist/provider-model-resolve-o2hHLs79.d.ts +0 -263
- package/dist/secret-scrubber-3MHDDAtm.d.ts +0 -6
- package/dist/secret-vault-DxohkUBc.d.ts +0 -272
- package/dist/session-reader-7Esxrkpw.d.ts +0 -155
- package/dist/task-format-GX0B1mMC.d.ts +0 -23
- package/dist/todos-checkpoint-FY7PjmMx.d.ts +0 -850
- package/dist/tool-BNlnIJvo.d.ts +0 -2190
- package/dist/tool-executor-CckSCM5E.d.ts +0 -906
package/dist/execution/index.js
CHANGED
|
@@ -1,25 +1,20 @@
|
|
|
1
|
-
import { randomUUID, randomInt, createHash, randomBytes } from 'crypto';
|
|
2
|
-
import * as fs from 'fs/promises';
|
|
3
|
-
import * as path3 from 'path';
|
|
4
|
-
import * as os from 'os';
|
|
5
|
-
import { readFileSync, statSync, existsSync } from 'fs';
|
|
6
|
-
import { fileURLToPath } from 'url';
|
|
7
|
-
import { execFile } from 'child_process';
|
|
8
|
-
import { promisify, isDeepStrictEqual } from 'util';
|
|
9
|
-
import { EventEmitter } from 'events';
|
|
10
|
-
|
|
11
1
|
// src/utils/assert-never.ts
|
|
12
2
|
function assertNever(x, message) {
|
|
13
3
|
const err = new Error(
|
|
14
|
-
`Unhandled case: ${JSON.stringify(x)}`
|
|
4
|
+
message ?? `Unhandled case: ${JSON.stringify(x)}`
|
|
15
5
|
);
|
|
16
6
|
err.name = "AssertNeverError";
|
|
17
7
|
throw err;
|
|
18
8
|
}
|
|
9
|
+
|
|
10
|
+
// src/utils/atomic-write.ts
|
|
11
|
+
import { randomBytes } from "node:crypto";
|
|
12
|
+
import * as fs from "node:fs/promises";
|
|
13
|
+
import * as path from "node:path";
|
|
19
14
|
async function atomicWrite(targetPath, content, opts = {}) {
|
|
20
|
-
const dir =
|
|
15
|
+
const dir = path.dirname(targetPath);
|
|
21
16
|
await fs.mkdir(dir, { recursive: true });
|
|
22
|
-
const tmp =
|
|
17
|
+
const tmp = path.join(dir, `.${path.basename(targetPath)}.${randomBytes(6).toString("hex")}.tmp`);
|
|
23
18
|
try {
|
|
24
19
|
if (typeof content === "string") {
|
|
25
20
|
await fs.writeFile(tmp, content, { flag: "wx", encoding: opts.encoding ?? "utf8" });
|
|
@@ -81,11 +76,13 @@ async function renameWithRetry(from, to) {
|
|
|
81
76
|
if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {
|
|
82
77
|
throw err;
|
|
83
78
|
}
|
|
84
|
-
await new Promise((
|
|
79
|
+
await new Promise((resolve4) => setTimeout(resolve4, delays[i]));
|
|
85
80
|
}
|
|
86
81
|
}
|
|
87
82
|
throw lastErr;
|
|
88
83
|
}
|
|
84
|
+
|
|
85
|
+
// src/utils/context-evidence.ts
|
|
89
86
|
var MAX_DIGEST_CHARS = 4e3;
|
|
90
87
|
function createContextEvidenceState() {
|
|
91
88
|
return {
|
|
@@ -170,7 +167,7 @@ function toErrorMessage(err) {
|
|
|
170
167
|
// src/utils/expect-defined.ts
|
|
171
168
|
function expectDefined(value, label) {
|
|
172
169
|
if (value === null || value === void 0) {
|
|
173
|
-
const err = new Error("Expected value to be defined");
|
|
170
|
+
const err = new Error(label ? `Expected ${label} to be defined` : "Expected value to be defined");
|
|
174
171
|
err.name = "ExpectDefinedError";
|
|
175
172
|
throw err;
|
|
176
173
|
}
|
|
@@ -184,10 +181,10 @@ function validateAgainstSchema(value, schema) {
|
|
|
184
181
|
return { ok: errors.length === 0, errors };
|
|
185
182
|
}
|
|
186
183
|
var MAX_SCHEMA_DEPTH = 64;
|
|
187
|
-
function walk(value, schema,
|
|
184
|
+
function walk(value, schema, path11, errors, depth) {
|
|
188
185
|
if (depth > MAX_SCHEMA_DEPTH) {
|
|
189
186
|
errors.push({
|
|
190
|
-
path:
|
|
187
|
+
path: path11 || "<root>",
|
|
191
188
|
message: `schema nesting exceeds maximum depth (${MAX_SCHEMA_DEPTH})`
|
|
192
189
|
});
|
|
193
190
|
return;
|
|
@@ -195,7 +192,7 @@ function walk(value, schema, path12, errors, depth) {
|
|
|
195
192
|
if (schema.enum !== void 0) {
|
|
196
193
|
if (!enumIncludes(schema.enum, value)) {
|
|
197
194
|
errors.push({
|
|
198
|
-
path:
|
|
195
|
+
path: path11 || "<root>",
|
|
199
196
|
message: `expected one of ${JSON.stringify(schema.enum)}, got ${JSON.stringify(value)}`
|
|
200
197
|
});
|
|
201
198
|
return;
|
|
@@ -204,7 +201,7 @@ function walk(value, schema, path12, errors, depth) {
|
|
|
204
201
|
if (typeof schema.type === "string") {
|
|
205
202
|
if (!checkType(value, schema.type)) {
|
|
206
203
|
errors.push({
|
|
207
|
-
path:
|
|
204
|
+
path: path11 || "<root>",
|
|
208
205
|
message: `expected ${schema.type}, got ${describeType(value)} (${previewValue(value)})`
|
|
209
206
|
});
|
|
210
207
|
return;
|
|
@@ -216,7 +213,7 @@ function walk(value, schema, path12, errors, depth) {
|
|
|
216
213
|
if (!(req in obj)) {
|
|
217
214
|
const expected = schema.properties?.[req]?.type;
|
|
218
215
|
errors.push({
|
|
219
|
-
path: joinPath(
|
|
216
|
+
path: joinPath(path11, req),
|
|
220
217
|
message: `required property missing${typeof expected === "string" ? ` (expected ${expected})` : ""}`
|
|
221
218
|
});
|
|
222
219
|
}
|
|
@@ -224,14 +221,14 @@ function walk(value, schema, path12, errors, depth) {
|
|
|
224
221
|
if (schema.properties) {
|
|
225
222
|
for (const [key, subSchema] of Object.entries(schema.properties)) {
|
|
226
223
|
if (key in obj) {
|
|
227
|
-
walk(obj[key], subSchema, joinPath(
|
|
224
|
+
walk(obj[key], subSchema, joinPath(path11, key), errors, depth + 1);
|
|
228
225
|
}
|
|
229
226
|
}
|
|
230
227
|
}
|
|
231
228
|
}
|
|
232
229
|
if (schema.type === "array" && Array.isArray(value) && schema.items) {
|
|
233
230
|
for (let i = 0; i < value.length; i++) {
|
|
234
|
-
walk(value[i], schema.items, `${
|
|
231
|
+
walk(value[i], schema.items, `${path11}[${i}]`, errors, depth + 1);
|
|
235
232
|
}
|
|
236
233
|
}
|
|
237
234
|
}
|
|
@@ -508,6 +505,9 @@ function safeParse(input, maxBytes = 5e6) {
|
|
|
508
505
|
function slugify(name, fallback = "prompt", maxLen = 64) {
|
|
509
506
|
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, maxLen).replace(/-+$/g, "") || fallback;
|
|
510
507
|
}
|
|
508
|
+
|
|
509
|
+
// src/utils/ulid.ts
|
|
510
|
+
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
511
511
|
var ENCODING = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
512
512
|
var ENCODING_LEN = ENCODING.length;
|
|
513
513
|
var TIME_LEN = 10;
|
|
@@ -523,7 +523,7 @@ function encodeTime(now, len) {
|
|
|
523
523
|
return str;
|
|
524
524
|
}
|
|
525
525
|
function encodeRandom(len) {
|
|
526
|
-
const bytes =
|
|
526
|
+
const bytes = randomBytes2(len);
|
|
527
527
|
let str = "";
|
|
528
528
|
for (let i = 0; i < len; i++) {
|
|
529
529
|
str += ENCODING[bytes[i] % ENCODING_LEN];
|
|
@@ -536,7 +536,7 @@ function ulid(seedTime = Date.now()) {
|
|
|
536
536
|
|
|
537
537
|
// src/utils/sleep.ts
|
|
538
538
|
function sleep(ms) {
|
|
539
|
-
return new Promise((
|
|
539
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
540
540
|
}
|
|
541
541
|
|
|
542
542
|
// src/utils/string.ts
|
|
@@ -1498,12 +1498,17 @@ function normalizeToolResultRenderMode(value) {
|
|
|
1498
1498
|
function resolveToolResultRenderMode(modes, toolName) {
|
|
1499
1499
|
return normalizeToolResultRenderMode(modes?.[toolName]) ?? DEFAULT_TOOL_RESULT_RENDER_MODE;
|
|
1500
1500
|
}
|
|
1501
|
+
|
|
1502
|
+
// src/utils/wstack-paths.ts
|
|
1503
|
+
import { createHash } from "node:crypto";
|
|
1504
|
+
import * as os from "node:os";
|
|
1505
|
+
import * as path2 from "node:path";
|
|
1501
1506
|
function projectHash(absRoot) {
|
|
1502
|
-
return createHash("sha256").update(
|
|
1507
|
+
return createHash("sha256").update(path2.resolve(absRoot)).digest("hex").slice(0, 12);
|
|
1503
1508
|
}
|
|
1504
1509
|
function projectSlug(absRoot) {
|
|
1505
|
-
const base = slugify2(
|
|
1506
|
-
const hash = createHash("sha256").update(
|
|
1510
|
+
const base = slugify2(path2.basename(absRoot));
|
|
1511
|
+
const hash = createHash("sha256").update(path2.resolve(absRoot)).digest("hex").slice(0, 6);
|
|
1507
1512
|
return `${base}-${hash}`;
|
|
1508
1513
|
}
|
|
1509
1514
|
function slugify2(name) {
|
|
@@ -1511,61 +1516,61 @@ function slugify2(name) {
|
|
|
1511
1516
|
}
|
|
1512
1517
|
function wstackGlobalRoot() {
|
|
1513
1518
|
const fromEnv = process.env["WRONGSTACK_HOME"];
|
|
1514
|
-
if (fromEnv && fromEnv.trim().length > 0) return
|
|
1515
|
-
return
|
|
1519
|
+
if (fromEnv && fromEnv.trim().length > 0) return path2.resolve(fromEnv);
|
|
1520
|
+
return path2.join(os.homedir(), ".wrongstack");
|
|
1516
1521
|
}
|
|
1517
1522
|
function resolveWstackPaths(opts) {
|
|
1518
|
-
const globalRoot = opts.globalRoot ?? (opts.userHome ?
|
|
1523
|
+
const globalRoot = opts.globalRoot ?? (opts.userHome ? path2.join(opts.userHome, ".wrongstack") : wstackGlobalRoot());
|
|
1519
1524
|
const homeDir = opts.userHome ?? os.homedir();
|
|
1520
1525
|
const hash = projectHash(opts.projectRoot);
|
|
1521
1526
|
const slug = projectSlug(opts.projectRoot);
|
|
1522
|
-
const projectDir =
|
|
1527
|
+
const projectDir = path2.join(globalRoot, "projects", slug);
|
|
1523
1528
|
return {
|
|
1524
1529
|
globalRoot,
|
|
1525
1530
|
projectRoot: opts.projectRoot,
|
|
1526
1531
|
homeDir,
|
|
1527
1532
|
configDir: globalRoot,
|
|
1528
|
-
globalConfig:
|
|
1529
|
-
secretsKey:
|
|
1530
|
-
globalMemory:
|
|
1531
|
-
globalSkills:
|
|
1532
|
-
globalClaudeSkills:
|
|
1533
|
-
globalDesignKits:
|
|
1534
|
-
globalPrompts:
|
|
1535
|
-
globalInstructions:
|
|
1536
|
-
promptUsage:
|
|
1537
|
-
cacheDir:
|
|
1538
|
-
modelsCache:
|
|
1539
|
-
modelsOverlayCache:
|
|
1540
|
-
historyFile:
|
|
1541
|
-
logFile:
|
|
1533
|
+
globalConfig: path2.join(globalRoot, "config.json"),
|
|
1534
|
+
secretsKey: path2.join(globalRoot, ".key"),
|
|
1535
|
+
globalMemory: path2.join(globalRoot, "memory.md"),
|
|
1536
|
+
globalSkills: path2.join(globalRoot, "skills"),
|
|
1537
|
+
globalClaudeSkills: path2.join(homeDir, ".claude", "skills"),
|
|
1538
|
+
globalDesignKits: path2.join(globalRoot, "design-kits"),
|
|
1539
|
+
globalPrompts: path2.join(globalRoot, "prompts"),
|
|
1540
|
+
globalInstructions: path2.join(globalRoot, "instructions"),
|
|
1541
|
+
promptUsage: path2.join(globalRoot, "prompt-usage.json"),
|
|
1542
|
+
cacheDir: path2.join(globalRoot, "cache"),
|
|
1543
|
+
modelsCache: path2.join(globalRoot, "cache", "models.dev.json"),
|
|
1544
|
+
modelsOverlayCache: path2.join(globalRoot, "cache", "models-overlay.json"),
|
|
1545
|
+
historyFile: path2.join(globalRoot, "history"),
|
|
1546
|
+
logFile: path2.join(globalRoot, "logs", "wrongstack.log"),
|
|
1542
1547
|
projectDir,
|
|
1543
|
-
projectCodebaseIndex:
|
|
1544
|
-
projectMemory:
|
|
1545
|
-
projectSessions:
|
|
1546
|
-
projectTrust:
|
|
1547
|
-
projectMeta:
|
|
1548
|
-
projectLocalConfig:
|
|
1549
|
-
inProjectConfig:
|
|
1550
|
-
inProjectAgentsFile:
|
|
1551
|
-
inProjectSkills:
|
|
1552
|
-
inProjectClaudeSkills:
|
|
1553
|
-
inProjectPrompts:
|
|
1554
|
-
inProjectInstructions:
|
|
1555
|
-
inProjectDesignKits:
|
|
1556
|
-
inProjectWorktrees:
|
|
1548
|
+
projectCodebaseIndex: path2.join(projectDir, "codebase-index"),
|
|
1549
|
+
projectMemory: path2.join(projectDir, "memory.md"),
|
|
1550
|
+
projectSessions: path2.join(projectDir, "sessions"),
|
|
1551
|
+
projectTrust: path2.join(projectDir, "trust.json"),
|
|
1552
|
+
projectMeta: path2.join(projectDir, "meta.json"),
|
|
1553
|
+
projectLocalConfig: path2.join(projectDir, "config.local.json"),
|
|
1554
|
+
inProjectConfig: path2.join(opts.projectRoot, ".wrongstack", "config.json"),
|
|
1555
|
+
inProjectAgentsFile: path2.join(opts.projectRoot, ".wrongstack", "AGENTS.md"),
|
|
1556
|
+
inProjectSkills: path2.join(opts.projectRoot, ".wrongstack", "skills"),
|
|
1557
|
+
inProjectClaudeSkills: path2.join(opts.projectRoot, ".claude", "skills"),
|
|
1558
|
+
inProjectPrompts: path2.join(opts.projectRoot, ".wrongstack", "prompts"),
|
|
1559
|
+
inProjectInstructions: path2.join(opts.projectRoot, ".wrongstack", "instructions"),
|
|
1560
|
+
inProjectDesignKits: path2.join(opts.projectRoot, ".wrongstack", "design-kits"),
|
|
1561
|
+
inProjectWorktrees: path2.join(opts.projectRoot, ".wrongstack", "worktrees"),
|
|
1557
1562
|
projectHash: hash,
|
|
1558
1563
|
projectSlug: slug,
|
|
1559
|
-
projectGoal:
|
|
1560
|
-
projectInputHistory:
|
|
1561
|
-
projectSpecs:
|
|
1562
|
-
projectTaskGraphs:
|
|
1563
|
-
projectSddSession:
|
|
1564
|
-
projectPlan:
|
|
1565
|
-
projectAutophase:
|
|
1566
|
-
projectSddBoards:
|
|
1567
|
-
syncConfig:
|
|
1568
|
-
projectStatus: (projectHash2) =>
|
|
1564
|
+
projectGoal: path2.join(projectDir, "goal.json"),
|
|
1565
|
+
projectInputHistory: path2.join(projectDir, "input-history.json"),
|
|
1566
|
+
projectSpecs: path2.join(projectDir, "specs"),
|
|
1567
|
+
projectTaskGraphs: path2.join(projectDir, "task-graphs"),
|
|
1568
|
+
projectSddSession: path2.join(projectDir, "sdd-session.json"),
|
|
1569
|
+
projectPlan: path2.join(projectDir, "plan.json"),
|
|
1570
|
+
projectAutophase: path2.join(projectDir, "autophase"),
|
|
1571
|
+
projectSddBoards: path2.join(projectDir, "sdd-boards"),
|
|
1572
|
+
syncConfig: path2.join(globalRoot, "sync.json"),
|
|
1573
|
+
projectStatus: (projectHash2) => path2.join(globalRoot, "projects", projectHash2, "status.json")
|
|
1569
1574
|
};
|
|
1570
1575
|
}
|
|
1571
1576
|
|
|
@@ -2064,19 +2069,27 @@ function adaptThresholdsForSignals(thresholds, signals) {
|
|
|
2064
2069
|
|
|
2065
2070
|
// src/execution/autonomous-runner.ts
|
|
2066
2071
|
var DoneConditionChecker = class {
|
|
2067
|
-
constructor(condition) {
|
|
2072
|
+
constructor(condition, opts) {
|
|
2068
2073
|
this.condition = condition;
|
|
2074
|
+
this.logger = opts?.logger;
|
|
2069
2075
|
if (condition.type === "output_match" && condition.pattern) {
|
|
2070
2076
|
const result = compileUserRegex(condition.pattern, "");
|
|
2071
2077
|
this.compiledRegex = result.ok ? result.regex : null;
|
|
2072
2078
|
if (!result.ok) {
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2079
|
+
if (this.logger) {
|
|
2080
|
+
this.logger.warn(
|
|
2081
|
+
"Done condition has invalid regex \u2014 will never match",
|
|
2082
|
+
{ event: "autonomous.done_condition_invalid_regex", pattern: condition.pattern, reason: result.reason }
|
|
2083
|
+
);
|
|
2084
|
+
} else {
|
|
2085
|
+
console.warn(JSON.stringify({
|
|
2086
|
+
level: "warn",
|
|
2087
|
+
event: "autonomous.done_condition_invalid_regex",
|
|
2088
|
+
pattern: condition.pattern,
|
|
2089
|
+
reason: result.reason,
|
|
2090
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2091
|
+
}));
|
|
2092
|
+
}
|
|
2080
2093
|
}
|
|
2081
2094
|
} else {
|
|
2082
2095
|
this.compiledRegex = null;
|
|
@@ -2084,6 +2097,7 @@ var DoneConditionChecker = class {
|
|
|
2084
2097
|
}
|
|
2085
2098
|
condition;
|
|
2086
2099
|
compiledRegex;
|
|
2100
|
+
logger;
|
|
2087
2101
|
check(state) {
|
|
2088
2102
|
switch (this.condition.type) {
|
|
2089
2103
|
case "iterations":
|
|
@@ -2134,7 +2148,7 @@ var DoneConditionChecker = class {
|
|
|
2134
2148
|
var AutonomousRunner = class {
|
|
2135
2149
|
constructor(opts) {
|
|
2136
2150
|
this.opts = opts;
|
|
2137
|
-
this.doneChecker = new DoneConditionChecker(opts.doneCondition);
|
|
2151
|
+
this.doneChecker = new DoneConditionChecker(opts.doneCondition, { logger: opts.logger });
|
|
2138
2152
|
}
|
|
2139
2153
|
opts;
|
|
2140
2154
|
iterations = 0;
|
|
@@ -2238,6 +2252,11 @@ var AutonomousRunner = class {
|
|
|
2238
2252
|
this.stopped = true;
|
|
2239
2253
|
}
|
|
2240
2254
|
};
|
|
2255
|
+
|
|
2256
|
+
// src/utils/instruction-file.ts
|
|
2257
|
+
import { readFileSync, statSync } from "node:fs";
|
|
2258
|
+
import * as path3 from "node:path";
|
|
2259
|
+
import { fileURLToPath } from "node:url";
|
|
2241
2260
|
var textCache = /* @__PURE__ */ new Map();
|
|
2242
2261
|
var rootCandidates;
|
|
2243
2262
|
function readBundledInstructionText(relativePath) {
|
|
@@ -2290,12 +2309,25 @@ function createTieredBrainArbiter(opts) {
|
|
|
2290
2309
|
return {
|
|
2291
2310
|
async decide(request) {
|
|
2292
2311
|
const policyDecision = await opts.policy.decide(request);
|
|
2293
|
-
|
|
2312
|
+
const provisionalContinue = policyDecision.type === "answer" && policyDecision.optionId === void 0 && request.fallback === "continue";
|
|
2313
|
+
if (policyDecision.type !== "ask_human" && !provisionalContinue) return policyDecision;
|
|
2294
2314
|
const ceiling = opts.getMaxAutoRisk?.() ?? "medium";
|
|
2295
|
-
if (
|
|
2315
|
+
if (ceiling === "off") return policyDecision;
|
|
2296
2316
|
const ceilingLevel = ceiling === "all" ? 3 : RISK_LEVELS[ceiling] ?? 1;
|
|
2297
2317
|
const requestLevel = RISK_LEVELS[request.risk] ?? 2;
|
|
2298
2318
|
if (requestLevel > ceilingLevel) return policyDecision;
|
|
2319
|
+
if (opts.council) {
|
|
2320
|
+
const floor = opts.getCouncilMinRisk?.() ?? "high";
|
|
2321
|
+
const floorLevel = RISK_LEVELS[floor] ?? 2;
|
|
2322
|
+
if (requestLevel >= floorLevel) {
|
|
2323
|
+
try {
|
|
2324
|
+
const councilDecision = await opts.council.decide(request);
|
|
2325
|
+
if (councilDecision.type !== "ask_human") return councilDecision;
|
|
2326
|
+
} catch {
|
|
2327
|
+
}
|
|
2328
|
+
}
|
|
2329
|
+
}
|
|
2330
|
+
if (!opts.autonomous) return policyDecision;
|
|
2299
2331
|
try {
|
|
2300
2332
|
const llmDecision = await opts.autonomous.decide(request);
|
|
2301
2333
|
if (llmDecision.type === "answer") return llmDecision;
|
|
@@ -2309,6 +2341,12 @@ function createAutonomyBrain(opts) {
|
|
|
2309
2341
|
const maxRisk = opts.maxAutoRisk ?? "high";
|
|
2310
2342
|
const maxRiskLevel = RISK_LEVELS[maxRisk] ?? 2;
|
|
2311
2343
|
const timeoutMs = opts.decisionTimeoutMs ?? 15e3;
|
|
2344
|
+
const targets = opts.targets && opts.targets.length > 0 ? opts.targets : opts.provider && opts.model ? [{ provider: opts.provider, model: opts.model }] : [];
|
|
2345
|
+
if (targets.length === 0) {
|
|
2346
|
+
throw new Error("createAutonomyBrain: provide `targets` or `provider` + `model`.");
|
|
2347
|
+
}
|
|
2348
|
+
const strategy = opts.strategy ?? "fallback";
|
|
2349
|
+
let rrCursor = 0;
|
|
2312
2350
|
return {
|
|
2313
2351
|
async decide(request) {
|
|
2314
2352
|
const requestLevel = RISK_LEVELS[request.risk] ?? 2;
|
|
@@ -2327,7 +2365,10 @@ function createAutonomyBrain(opts) {
|
|
|
2327
2365
|
opts.onDecision?.(formatDecisionSummary(heuristic, request), heuristic, request);
|
|
2328
2366
|
return heuristic;
|
|
2329
2367
|
}
|
|
2330
|
-
const
|
|
2368
|
+
const start = strategy === "round-robin" ? rrCursor++ % targets.length : 0;
|
|
2369
|
+
const ordered = [...targets.slice(start), ...targets.slice(0, start)];
|
|
2370
|
+
const digest = opts.getDecisionDigest?.(request);
|
|
2371
|
+
const llmDecision = await llmDecide(request, ordered, timeoutMs, digest);
|
|
2331
2372
|
opts.onDecision?.(formatDecisionSummary(llmDecision, request), llmDecision, request);
|
|
2332
2373
|
return llmDecision;
|
|
2333
2374
|
}
|
|
@@ -2345,6 +2386,7 @@ function formatDecisionSummary(decision, request) {
|
|
|
2345
2386
|
return `\u{1F9E0} Brain: ASKED HUMAN \u2014 "${question}"`;
|
|
2346
2387
|
}
|
|
2347
2388
|
function quickDecide(request) {
|
|
2389
|
+
if (request.options?.length) return null;
|
|
2348
2390
|
const q = request.question.toLowerCase();
|
|
2349
2391
|
const ctx = request.context?.toLowerCase() ?? "";
|
|
2350
2392
|
if (q.includes("deadlock") && ctx.includes("failed")) {
|
|
@@ -2354,7 +2396,7 @@ function quickDecide(request) {
|
|
|
2354
2396
|
rationale: "Heuristic: deadlocked tasks blocked by failed dependencies \u2014 skipping unblocks remaining work."
|
|
2355
2397
|
};
|
|
2356
2398
|
}
|
|
2357
|
-
if ((q.includes("failed") || q.includes("retry")) && (ctx
|
|
2399
|
+
if ((q.includes("failed") || q.includes("retry")) && (/\bexhausted\b/.test(ctx) || /\b(?:[3-9]|\d{2,})\s+(?:consecutive\s+)?(?:times|attempts|retries|failures)\b/.test(ctx) || /\b(?:attempt|retr(?:y|ies)|failure)s?\W{0,3}(?:[3-9]|\d{2,})\b/.test(ctx))) {
|
|
2358
2400
|
return {
|
|
2359
2401
|
type: "answer",
|
|
2360
2402
|
text: "Mark as failed and move on. Note the failure for the final report.",
|
|
@@ -2364,7 +2406,7 @@ function quickDecide(request) {
|
|
|
2364
2406
|
if (q.includes("goal complete") || q.includes("mission complete")) {
|
|
2365
2407
|
return null;
|
|
2366
2408
|
}
|
|
2367
|
-
if (
|
|
2409
|
+
if (request.fallback === "continue" && /\b(?:continue|proceed)\b/.test(q) && !/\b(?:stop|abort|halt|cancel|pause|rollback)\b/.test(q) && !/\bor\b/.test(q)) {
|
|
2368
2410
|
return {
|
|
2369
2411
|
type: "answer",
|
|
2370
2412
|
text: "Continue execution. Do not stop.",
|
|
@@ -2373,46 +2415,54 @@ function quickDecide(request) {
|
|
|
2373
2415
|
}
|
|
2374
2416
|
return null;
|
|
2375
2417
|
}
|
|
2376
|
-
|
|
2418
|
+
function buildBrainUserMessage(request) {
|
|
2377
2419
|
const optionsText = request.options?.length ? "\nOptions:\n" + request.options.map(
|
|
2378
2420
|
(o) => ` [${o.id}] ${o.label}${o.consequence ? ` \u2014 ${o.consequence}` : ""}${o.recommended ? " \u2605 recommended" : ""}`
|
|
2379
2421
|
).join("\n") : "";
|
|
2380
|
-
|
|
2381
|
-
const userMessage = [
|
|
2422
|
+
return [
|
|
2382
2423
|
`Question: ${request.question}`,
|
|
2383
2424
|
request.context ? `
|
|
2384
2425
|
Context:
|
|
2385
2426
|
${request.context}` : "",
|
|
2386
2427
|
optionsText
|
|
2387
2428
|
].filter(Boolean).join("\n");
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2429
|
+
}
|
|
2430
|
+
function withDecisionDigest(user, digest) {
|
|
2431
|
+
if (!digest?.trim()) return user;
|
|
2432
|
+
return `${user}
|
|
2433
|
+
|
|
2434
|
+
Outcome history of similar past decisions (learn from it):
|
|
2435
|
+
${digest}`;
|
|
2436
|
+
}
|
|
2437
|
+
async function completeBrainLlm(target, input) {
|
|
2438
|
+
const signal = AbortSignal.timeout(input.timeoutMs);
|
|
2439
|
+
const response = await target.provider.complete(
|
|
2440
|
+
{
|
|
2441
|
+
model: target.model,
|
|
2442
|
+
system: [{ type: "text", text: input.system }],
|
|
2443
|
+
messages: [{ role: "user", content: input.user || "Decide." }],
|
|
2444
|
+
maxTokens: input.maxTokens ?? 200
|
|
2445
|
+
},
|
|
2446
|
+
{ signal }
|
|
2447
|
+
);
|
|
2448
|
+
return extractText(response).trim();
|
|
2449
|
+
}
|
|
2450
|
+
async function llmDecide(request, targets, timeoutMs, digest) {
|
|
2451
|
+
const systemPrompt = readBundledInstructionText("llm/autonomy-brain.md");
|
|
2452
|
+
const userMessage = withDecisionDigest(buildBrainUserMessage(request), digest);
|
|
2453
|
+
let text = null;
|
|
2454
|
+
for (const target of targets) {
|
|
2455
|
+
try {
|
|
2456
|
+
text = await completeBrainLlm(target, {
|
|
2457
|
+
system: systemPrompt,
|
|
2458
|
+
user: userMessage,
|
|
2459
|
+
timeoutMs
|
|
2460
|
+
});
|
|
2461
|
+
break;
|
|
2462
|
+
} catch {
|
|
2409
2463
|
}
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
text: text || (request.fallback === "continue" ? "Continue execution." : "Denied by autonomy policy."),
|
|
2413
|
-
rationale: text || void 0
|
|
2414
|
-
};
|
|
2415
|
-
} catch {
|
|
2464
|
+
}
|
|
2465
|
+
if (text === null) {
|
|
2416
2466
|
if (request.fallback === "continue") {
|
|
2417
2467
|
return {
|
|
2418
2468
|
type: "answer",
|
|
@@ -2421,6 +2471,21 @@ ${request.context}` : "",
|
|
|
2421
2471
|
}
|
|
2422
2472
|
return { type: "deny", reason: "Autonomy Brain LLM unavailable for decision." };
|
|
2423
2473
|
}
|
|
2474
|
+
if (request.options?.length) {
|
|
2475
|
+
const parsed = parseOptionDecision(text, request.options);
|
|
2476
|
+
if (parsed) {
|
|
2477
|
+
return parsed;
|
|
2478
|
+
}
|
|
2479
|
+
return {
|
|
2480
|
+
type: "deny",
|
|
2481
|
+
reason: "Autonomy Brain returned no exact valid option id."
|
|
2482
|
+
};
|
|
2483
|
+
}
|
|
2484
|
+
return {
|
|
2485
|
+
type: "answer",
|
|
2486
|
+
text: text || (request.fallback === "continue" ? "Continue execution." : "Denied by autonomy policy."),
|
|
2487
|
+
rationale: text || void 0
|
|
2488
|
+
};
|
|
2424
2489
|
}
|
|
2425
2490
|
function parseOptionDecision(rawText, options) {
|
|
2426
2491
|
const text = rawText.trim();
|
|
@@ -2456,20 +2521,1066 @@ function extractText(result) {
|
|
|
2456
2521
|
if (Array.isArray(r.content)) {
|
|
2457
2522
|
return r.content.filter((b) => b.type === "text").map((b) => b.text ?? "").join("");
|
|
2458
2523
|
}
|
|
2459
|
-
if (Array.isArray(r.choices)) {
|
|
2460
|
-
return r.choices[0]?.message?.content ?? "";
|
|
2524
|
+
if (Array.isArray(r.choices)) {
|
|
2525
|
+
return r.choices[0]?.message?.content ?? "";
|
|
2526
|
+
}
|
|
2527
|
+
return typeof r.text === "string" ? r.text : "";
|
|
2528
|
+
}
|
|
2529
|
+
|
|
2530
|
+
// src/types/provider.ts
|
|
2531
|
+
var CONTEXT_OVERFLOW_RE = /context.length|context.window|max.*tokens?.*exceeded|prompt is too long|too long|exceeds the context|\btokens\b.*exceed|context_length_exceeded/i;
|
|
2532
|
+
var CONTENT_FILTER_RE = /content.(filter|policy|moderation)|safety (system|filter)/i;
|
|
2533
|
+
function classifyProviderError(status, body, message) {
|
|
2534
|
+
const type = body?.type;
|
|
2535
|
+
if (status === 0) return "network";
|
|
2536
|
+
if (status === 408) return "timeout";
|
|
2537
|
+
if (status === 599) return "stream_hang";
|
|
2538
|
+
if (type === "rate_limit_error" || status === 429) return "rate_limit";
|
|
2539
|
+
if (type === "overloaded_error" || status === 529) return "overloaded";
|
|
2540
|
+
if (status >= 500) return "server";
|
|
2541
|
+
if (type === "authentication_error" || type === "permission_error" || status === 401 || status === 403) {
|
|
2542
|
+
return "auth";
|
|
2543
|
+
}
|
|
2544
|
+
const text = [message, body?.message, type, body?.raw].filter(Boolean).join("\n");
|
|
2545
|
+
if (type === "content_filter" || CONTENT_FILTER_RE.test(text)) return "content_filter";
|
|
2546
|
+
if (status === 413 || status >= 400 && CONTEXT_OVERFLOW_RE.test(text)) {
|
|
2547
|
+
return "context_overflow";
|
|
2548
|
+
}
|
|
2549
|
+
if (status >= 400) return "invalid_request";
|
|
2550
|
+
return "unknown";
|
|
2551
|
+
}
|
|
2552
|
+
function isRetryableKind(kind) {
|
|
2553
|
+
return RETRYABLE_BY_KIND[kind];
|
|
2554
|
+
}
|
|
2555
|
+
var RETRYABLE_BY_KIND = {
|
|
2556
|
+
rate_limit: true,
|
|
2557
|
+
overloaded: true,
|
|
2558
|
+
server: true,
|
|
2559
|
+
timeout: true,
|
|
2560
|
+
network: true,
|
|
2561
|
+
stream_hang: true,
|
|
2562
|
+
auth: false,
|
|
2563
|
+
context_overflow: false,
|
|
2564
|
+
content_filter: false,
|
|
2565
|
+
invalid_request: false,
|
|
2566
|
+
unknown: false
|
|
2567
|
+
};
|
|
2568
|
+
var ProviderError = class extends WrongStackError {
|
|
2569
|
+
status;
|
|
2570
|
+
retryable;
|
|
2571
|
+
providerId;
|
|
2572
|
+
/** Canonical failure classification — see {@link ProviderErrorKind}. */
|
|
2573
|
+
kind;
|
|
2574
|
+
body;
|
|
2575
|
+
constructor(message, status, retryable, providerId, opts = {}) {
|
|
2576
|
+
const kind = opts.kind ?? classifyProviderError(status, opts.body, message);
|
|
2577
|
+
super({
|
|
2578
|
+
message,
|
|
2579
|
+
code: kindToCode(kind),
|
|
2580
|
+
subsystem: "provider",
|
|
2581
|
+
severity: status >= 500 ? "error" : "warning",
|
|
2582
|
+
recoverable: retryable,
|
|
2583
|
+
context: { providerId, status },
|
|
2584
|
+
cause: opts.cause
|
|
2585
|
+
});
|
|
2586
|
+
this.name = "ProviderError";
|
|
2587
|
+
this.status = status;
|
|
2588
|
+
this.retryable = retryable;
|
|
2589
|
+
this.providerId = providerId;
|
|
2590
|
+
this.kind = kind;
|
|
2591
|
+
this.body = opts.body;
|
|
2592
|
+
}
|
|
2593
|
+
/**
|
|
2594
|
+
* Render a one-line, user-facing description. Designed for the CLI/TUI
|
|
2595
|
+
* status line and the agent's retry warning. Avoids dumping raw JSON
|
|
2596
|
+
* (which is what users see today when a 529 lands and the log message
|
|
2597
|
+
* includes the full `{"type":"error",...}` body).
|
|
2598
|
+
*
|
|
2599
|
+
* Examples:
|
|
2600
|
+
* "minimax-coding-plan overloaded (529): High traffic detected. Upgrade for highspeed model. [req 06534785201de9c0…]"
|
|
2601
|
+
* "openai rate limited (429): Retry after 12s"
|
|
2602
|
+
* "anthropic invalid request (400): messages.0.role must be one of 'user'|'assistant'"
|
|
2603
|
+
* "groq HTTP 500 (server error)"
|
|
2604
|
+
*/
|
|
2605
|
+
describe() {
|
|
2606
|
+
const kind = describeStatus(this.status, this.body?.type);
|
|
2607
|
+
const head = `${this.providerId} ${kind}`;
|
|
2608
|
+
const detail = this.body?.message?.trim();
|
|
2609
|
+
const reqId = this.body?.requestId ? ` [req ${this.body.requestId.slice(0, 16)}${this.body.requestId.length > 16 ? "\u2026" : ""}]` : "";
|
|
2610
|
+
if (detail && detail.length > 0) {
|
|
2611
|
+
return `${head}: ${truncate(detail, 240)}${reqId}`;
|
|
2612
|
+
}
|
|
2613
|
+
return `${head}${reqId}`;
|
|
2614
|
+
}
|
|
2615
|
+
};
|
|
2616
|
+
function describeStatus(status, type) {
|
|
2617
|
+
if (status === 0) return "network error";
|
|
2618
|
+
if (status === 599) return `stream hang (${status})`;
|
|
2619
|
+
if (type === "overloaded_error" || status === 529) return `overloaded (${status})`;
|
|
2620
|
+
if (type === "rate_limit_error" || status === 429) return `rate limited (${status})`;
|
|
2621
|
+
if (type === "authentication_error" || status === 401) return `auth failed (${status})`;
|
|
2622
|
+
if (type === "permission_error" || status === 403) return `forbidden (${status})`;
|
|
2623
|
+
if (type === "not_found_error" || status === 404) return `not found (${status})`;
|
|
2624
|
+
if (type === "content_filter") return `content filtered (${status})`;
|
|
2625
|
+
if (type === "invalid_request_error" || status === 400) return `invalid request (${status})`;
|
|
2626
|
+
if (status === 408) return `timeout (${status})`;
|
|
2627
|
+
if (status >= 500 && status < 600) return `HTTP ${status} (server error)`;
|
|
2628
|
+
if (type) return `${type} (${status})`;
|
|
2629
|
+
return `HTTP ${status}`;
|
|
2630
|
+
}
|
|
2631
|
+
var KIND_TO_CODE = {
|
|
2632
|
+
network: ERROR_CODES.PROVIDER_NETWORK_ERROR,
|
|
2633
|
+
timeout: ERROR_CODES.PROVIDER_NETWORK_ERROR,
|
|
2634
|
+
rate_limit: ERROR_CODES.PROVIDER_RATE_LIMITED,
|
|
2635
|
+
auth: ERROR_CODES.PROVIDER_AUTH_FAILED,
|
|
2636
|
+
overloaded: ERROR_CODES.PROVIDER_OVERLOADED,
|
|
2637
|
+
context_overflow: ERROR_CODES.PROVIDER_CONTEXT_OVERFLOW,
|
|
2638
|
+
server: ERROR_CODES.PROVIDER_SERVER_ERROR,
|
|
2639
|
+
stream_hang: ERROR_CODES.PROVIDER_SERVER_ERROR,
|
|
2640
|
+
content_filter: ERROR_CODES.PROVIDER_INVALID_REQUEST,
|
|
2641
|
+
invalid_request: ERROR_CODES.PROVIDER_INVALID_REQUEST,
|
|
2642
|
+
unknown: ERROR_CODES.PROVIDER_INVALID_REQUEST
|
|
2643
|
+
};
|
|
2644
|
+
function kindToCode(kind) {
|
|
2645
|
+
return KIND_TO_CODE[kind];
|
|
2646
|
+
}
|
|
2647
|
+
|
|
2648
|
+
// src/core/fallback-model.ts
|
|
2649
|
+
function parseModelRef(ref) {
|
|
2650
|
+
const trimmed = ref.trim();
|
|
2651
|
+
const slash = trimmed.indexOf("/");
|
|
2652
|
+
if (slash !== -1) {
|
|
2653
|
+
return {
|
|
2654
|
+
provider: trimmed.slice(0, slash) || void 0,
|
|
2655
|
+
model: trimmed.slice(slash + 1).trim()
|
|
2656
|
+
};
|
|
2657
|
+
}
|
|
2658
|
+
const parts = trimmed.split(/\s+/);
|
|
2659
|
+
if (parts.length >= 2) {
|
|
2660
|
+
return { provider: parts[0], model: parts.slice(1).join(" ") };
|
|
2661
|
+
}
|
|
2662
|
+
return { model: trimmed };
|
|
2663
|
+
}
|
|
2664
|
+
var DEFAULT_PRIMARY_COOLDOWN_MAX_MS = 10 * 6e4;
|
|
2665
|
+
|
|
2666
|
+
// src/execution/council-brain.ts
|
|
2667
|
+
var COUNCIL_REFUSE_OPTION_ID = "council_refuse";
|
|
2668
|
+
var BUILTIN_PERSONAS = {
|
|
2669
|
+
executor: "PERSONA: You hold the EXECUTOR seat. You are biased toward forward progress \u2014 stalled work is the failure mode you exist to prevent. Favor the option that keeps the system moving, unless doing so is clearly reckless.",
|
|
2670
|
+
skeptic: "PERSONA: You hold the SKEPTIC seat. Your job is to find the concrete reason the proposed action is wrong, unsafe, or based on a false premise. If you find one, vote against it or refuse. Do not oppose for its own sake \u2014 a sound proposal deserves your vote.",
|
|
2671
|
+
auditor: "PERSONA: You hold the AUDITOR seat. You judge through the cost/waste lens: budget already burned, expected cost of each option, and the odds of throwing resources at a dead end. Prefer the option with the best expected value per token spent."
|
|
2672
|
+
};
|
|
2673
|
+
function personaText(persona) {
|
|
2674
|
+
if (!persona) return BUILTIN_PERSONAS["executor"] ?? "";
|
|
2675
|
+
return BUILTIN_PERSONAS[persona] ?? `PERSONA: ${persona}`;
|
|
2676
|
+
}
|
|
2677
|
+
function voterLabel(voter, index) {
|
|
2678
|
+
return voter.label ?? `${voter.persona ?? "voter"}#${index + 1} (${voter.model})`;
|
|
2679
|
+
}
|
|
2680
|
+
function ballotOptions(request) {
|
|
2681
|
+
const options = request.options ?? [];
|
|
2682
|
+
if (options.some((o) => o.id === COUNCIL_REFUSE_OPTION_ID)) return options;
|
|
2683
|
+
return [
|
|
2684
|
+
...options,
|
|
2685
|
+
{
|
|
2686
|
+
id: COUNCIL_REFUSE_OPTION_ID,
|
|
2687
|
+
label: "Refuse \u2014 none of these options should be taken",
|
|
2688
|
+
consequence: "The proposed action is not taken at all."
|
|
2689
|
+
}
|
|
2690
|
+
];
|
|
2691
|
+
}
|
|
2692
|
+
function createCouncilBrainArbiter(opts) {
|
|
2693
|
+
if (opts.voters.length === 0) {
|
|
2694
|
+
throw new Error("createCouncilBrainArbiter: at least one voter is required.");
|
|
2695
|
+
}
|
|
2696
|
+
const quorumFraction = opts.quorumFraction ?? 0.5;
|
|
2697
|
+
const approvalFraction = opts.approvalFraction ?? 0.5;
|
|
2698
|
+
const timeoutMs = opts.decisionTimeoutMs ?? 15e3;
|
|
2699
|
+
const baseSystem = readBundledInstructionText("llm/autonomy-brain.md");
|
|
2700
|
+
const abstain = (request, why) => ({
|
|
2701
|
+
type: "ask_human",
|
|
2702
|
+
prompt: `Council abstained (${why}): ${request.question}`,
|
|
2703
|
+
options: request.options,
|
|
2704
|
+
rationale: `Council could not reach a decision: ${why}.`
|
|
2705
|
+
});
|
|
2706
|
+
const finish = (request, decision) => {
|
|
2707
|
+
opts.onDecision?.(formatDecisionSummary(decision, request), decision, request);
|
|
2708
|
+
return decision;
|
|
2709
|
+
};
|
|
2710
|
+
async function collectVotes(request, ballot, digest) {
|
|
2711
|
+
const ballotRequest = { ...request, options: ballot };
|
|
2712
|
+
const user = withDecisionDigest(buildBrainUserMessage(ballotRequest), digest);
|
|
2713
|
+
const settled = await Promise.allSettled(
|
|
2714
|
+
opts.voters.map(
|
|
2715
|
+
(voter) => completeBrainLlm(voter, {
|
|
2716
|
+
system: `${baseSystem}
|
|
2717
|
+
|
|
2718
|
+
${personaText(voter.persona)}`,
|
|
2719
|
+
user,
|
|
2720
|
+
timeoutMs
|
|
2721
|
+
})
|
|
2722
|
+
)
|
|
2723
|
+
);
|
|
2724
|
+
const votes = [];
|
|
2725
|
+
settled.forEach((result, i) => {
|
|
2726
|
+
const voter = opts.voters[i];
|
|
2727
|
+
if (!voter || result.status !== "fulfilled") return;
|
|
2728
|
+
const parsed = parseOptionDecision(result.value, ballot);
|
|
2729
|
+
if (parsed?.type !== "answer" || !parsed.optionId) return;
|
|
2730
|
+
votes.push({ voter, optionId: parsed.optionId, rationale: parsed.rationale });
|
|
2731
|
+
});
|
|
2732
|
+
return votes;
|
|
2733
|
+
}
|
|
2734
|
+
async function judgeRound(request, ballot, votes, reason) {
|
|
2735
|
+
if (!opts.judge) return null;
|
|
2736
|
+
const voteLines = votes.map(
|
|
2737
|
+
(v, i) => `- ${voterLabel(v.voter, i)} voted [${v.optionId}]` + (v.rationale ? ` \u2014 ${v.rationale}` : "")
|
|
2738
|
+
).join("\n");
|
|
2739
|
+
const judgeRequest = {
|
|
2740
|
+
...request,
|
|
2741
|
+
options: ballot,
|
|
2742
|
+
context: [
|
|
2743
|
+
request.context ?? "",
|
|
2744
|
+
"",
|
|
2745
|
+
`Council votes (${reason} \u2014 you are the judge; issue the final decision):`,
|
|
2746
|
+
voteLines
|
|
2747
|
+
].join("\n").trim()
|
|
2748
|
+
};
|
|
2749
|
+
try {
|
|
2750
|
+
const text = await completeBrainLlm(opts.judge, {
|
|
2751
|
+
system: `${baseSystem}
|
|
2752
|
+
|
|
2753
|
+
PERSONA: You are the council JUDGE. The voting seats disagreed or were too close to call. Weigh their rationales and issue the single final decision.`,
|
|
2754
|
+
user: buildBrainUserMessage(judgeRequest),
|
|
2755
|
+
timeoutMs,
|
|
2756
|
+
maxTokens: 300
|
|
2757
|
+
});
|
|
2758
|
+
const parsed = parseOptionDecision(text, ballot);
|
|
2759
|
+
if (parsed?.type === "answer" && parsed.optionId) return parsed;
|
|
2760
|
+
return null;
|
|
2761
|
+
} catch {
|
|
2762
|
+
return null;
|
|
2763
|
+
}
|
|
2764
|
+
}
|
|
2765
|
+
return {
|
|
2766
|
+
async decide(request) {
|
|
2767
|
+
const digest = opts.getDecisionDigest?.(request);
|
|
2768
|
+
if (!request.options?.length) {
|
|
2769
|
+
const user = withDecisionDigest(buildBrainUserMessage(request), digest);
|
|
2770
|
+
const settled = await Promise.allSettled(
|
|
2771
|
+
opts.voters.map(
|
|
2772
|
+
(voter) => completeBrainLlm(voter, {
|
|
2773
|
+
system: `${baseSystem}
|
|
2774
|
+
|
|
2775
|
+
${personaText(voter.persona)}`,
|
|
2776
|
+
user,
|
|
2777
|
+
timeoutMs
|
|
2778
|
+
})
|
|
2779
|
+
)
|
|
2780
|
+
);
|
|
2781
|
+
const stances = [];
|
|
2782
|
+
settled.forEach((result, i) => {
|
|
2783
|
+
const voter = opts.voters[i];
|
|
2784
|
+
if (!voter || result.status !== "fulfilled" || !result.value.trim()) return;
|
|
2785
|
+
stances.push({ voter, text: result.value.trim() });
|
|
2786
|
+
});
|
|
2787
|
+
if (stances.length / opts.voters.length < quorumFraction) {
|
|
2788
|
+
return finish(request, abstain(request, "quorum not met"));
|
|
2789
|
+
}
|
|
2790
|
+
if (opts.judge) {
|
|
2791
|
+
const stanceLines = stances.map((s, i) => `- ${voterLabel(s.voter, i)}: ${s.text}`).join("\n");
|
|
2792
|
+
try {
|
|
2793
|
+
const text = await completeBrainLlm(opts.judge, {
|
|
2794
|
+
system: `${baseSystem}
|
|
2795
|
+
|
|
2796
|
+
PERSONA: You are the council JUDGE. Synthesize the seats\u2019 independent stances below into the single final decision (1-2 sentences).`,
|
|
2797
|
+
user: `${buildBrainUserMessage(request)}
|
|
2798
|
+
|
|
2799
|
+
Council stances:
|
|
2800
|
+
${stanceLines}`,
|
|
2801
|
+
timeoutMs,
|
|
2802
|
+
maxTokens: 300
|
|
2803
|
+
});
|
|
2804
|
+
if (text) {
|
|
2805
|
+
return finish(request, {
|
|
2806
|
+
type: "answer",
|
|
2807
|
+
text,
|
|
2808
|
+
rationale: `Council synthesis of ${stances.length}/${opts.voters.length} stances.`
|
|
2809
|
+
});
|
|
2810
|
+
}
|
|
2811
|
+
} catch {
|
|
2812
|
+
}
|
|
2813
|
+
}
|
|
2814
|
+
const first = stances[0];
|
|
2815
|
+
if (first) {
|
|
2816
|
+
return finish(request, {
|
|
2817
|
+
type: "answer",
|
|
2818
|
+
text: first.text,
|
|
2819
|
+
rationale: `Council (no judge): stance of ${voterLabel(first.voter, 0)}.`
|
|
2820
|
+
});
|
|
2821
|
+
}
|
|
2822
|
+
return finish(request, abstain(request, "no usable stance"));
|
|
2823
|
+
}
|
|
2824
|
+
const ballot = ballotOptions(request);
|
|
2825
|
+
const votes = await collectVotes(request, ballot, digest);
|
|
2826
|
+
if (votes.length / opts.voters.length < quorumFraction) {
|
|
2827
|
+
return finish(request, abstain(request, `quorum not met (${votes.length}/${opts.voters.length} votes)`));
|
|
2828
|
+
}
|
|
2829
|
+
const vetoRefusal = votes.find(
|
|
2830
|
+
(v) => v.voter.veto === true && v.optionId === COUNCIL_REFUSE_OPTION_ID
|
|
2831
|
+
);
|
|
2832
|
+
if (vetoRefusal) {
|
|
2833
|
+
return finish(request, {
|
|
2834
|
+
type: "deny",
|
|
2835
|
+
reason: `Council veto by ${voterLabel(vetoRefusal.voter, 0)}` + (vetoRefusal.rationale ? `: ${vetoRefusal.rationale}` : ".")
|
|
2836
|
+
});
|
|
2837
|
+
}
|
|
2838
|
+
const weightByOption = /* @__PURE__ */ new Map();
|
|
2839
|
+
let castWeight = 0;
|
|
2840
|
+
for (const v of votes) {
|
|
2841
|
+
const w = v.voter.weight ?? 1;
|
|
2842
|
+
castWeight += w;
|
|
2843
|
+
weightByOption.set(v.optionId, (weightByOption.get(v.optionId) ?? 0) + w);
|
|
2844
|
+
}
|
|
2845
|
+
let winner = null;
|
|
2846
|
+
let contested = false;
|
|
2847
|
+
for (const [optionId, weight] of weightByOption) {
|
|
2848
|
+
if (!winner || weight > winner.weight) {
|
|
2849
|
+
winner = { optionId, weight };
|
|
2850
|
+
contested = false;
|
|
2851
|
+
} else if (weight === winner.weight) {
|
|
2852
|
+
contested = true;
|
|
2853
|
+
}
|
|
2854
|
+
}
|
|
2855
|
+
const decisive = winner !== null && !contested && winner.weight > approvalFraction * castWeight;
|
|
2856
|
+
let finalOptionId = decisive && winner ? winner.optionId : null;
|
|
2857
|
+
let viaJudge = false;
|
|
2858
|
+
if (!finalOptionId) {
|
|
2859
|
+
const judged = await judgeRound(
|
|
2860
|
+
request,
|
|
2861
|
+
ballot,
|
|
2862
|
+
votes,
|
|
2863
|
+
contested ? "tie" : "no option cleared the approval threshold"
|
|
2864
|
+
);
|
|
2865
|
+
if (judged?.type === "answer" && judged.optionId) {
|
|
2866
|
+
finalOptionId = judged.optionId;
|
|
2867
|
+
viaJudge = true;
|
|
2868
|
+
}
|
|
2869
|
+
}
|
|
2870
|
+
if (!finalOptionId) {
|
|
2871
|
+
return finish(request, abstain(request, "split vote and no judge verdict"));
|
|
2872
|
+
}
|
|
2873
|
+
const supporting = votes.filter((v) => v.optionId === finalOptionId);
|
|
2874
|
+
const voteSummary = votes.map((v, i) => `${voterLabel(v.voter, i)}\u2192[${v.optionId}]`).join(", ");
|
|
2875
|
+
const rationale = (supporting.find((v) => v.rationale)?.rationale ?? "") + ` (council${viaJudge ? " via judge" : ""}: ${voteSummary})`;
|
|
2876
|
+
if (finalOptionId === COUNCIL_REFUSE_OPTION_ID) {
|
|
2877
|
+
return finish(request, {
|
|
2878
|
+
type: "deny",
|
|
2879
|
+
reason: `Council refused the proposed action.${rationale}`
|
|
2880
|
+
});
|
|
2881
|
+
}
|
|
2882
|
+
const option = request.options.find((o) => o.id === finalOptionId);
|
|
2883
|
+
return finish(request, {
|
|
2884
|
+
type: "answer",
|
|
2885
|
+
optionId: finalOptionId,
|
|
2886
|
+
text: option?.label ?? finalOptionId,
|
|
2887
|
+
rationale: rationale.trim()
|
|
2888
|
+
});
|
|
2889
|
+
}
|
|
2890
|
+
};
|
|
2891
|
+
}
|
|
2892
|
+
|
|
2893
|
+
// src/execution/brain-chain.ts
|
|
2894
|
+
var DEFAULT_SEATS = [
|
|
2895
|
+
{ persona: "executor" },
|
|
2896
|
+
{ persona: "skeptic", veto: true },
|
|
2897
|
+
{ persona: "auditor" }
|
|
2898
|
+
];
|
|
2899
|
+
function assembleBrainTiers(opts) {
|
|
2900
|
+
const brainCfg = opts.brainConfig;
|
|
2901
|
+
const toEntry = (entry) => typeof entry === "string" ? parseModelRef(entry) : entry;
|
|
2902
|
+
const buildTarget = (entry) => {
|
|
2903
|
+
if (!entry.model) return null;
|
|
2904
|
+
const providerId = entry.provider ?? opts.defaultProviderId;
|
|
2905
|
+
try {
|
|
2906
|
+
const provider = providerId === opts.defaultProviderId ? opts.sessionProvider() : opts.resolveProvider(providerId, entry.model);
|
|
2907
|
+
if (!provider) return null;
|
|
2908
|
+
return { provider, model: entry.model, label: `${providerId}/${entry.model}` };
|
|
2909
|
+
} catch {
|
|
2910
|
+
return null;
|
|
2911
|
+
}
|
|
2912
|
+
};
|
|
2913
|
+
const poolTargets = (brainCfg?.models ?? []).map(toEntry).map(buildTarget).filter((t) => t !== null);
|
|
2914
|
+
const autonomous = poolTargets.length > 0 ? createAutonomyBrain({
|
|
2915
|
+
targets: poolTargets,
|
|
2916
|
+
strategy: brainCfg?.strategy ?? "fallback",
|
|
2917
|
+
maxAutoRisk: "all",
|
|
2918
|
+
// the tiered ceiling gates risk — keep inner permissive
|
|
2919
|
+
decisionTimeoutMs: brainCfg?.decisionTimeoutMs,
|
|
2920
|
+
getDecisionDigest: opts.getDecisionDigest
|
|
2921
|
+
}) : {
|
|
2922
|
+
decide: (request) => createAutonomyBrain({
|
|
2923
|
+
provider: opts.sessionProvider(),
|
|
2924
|
+
model: opts.sessionModel(),
|
|
2925
|
+
maxAutoRisk: "all",
|
|
2926
|
+
decisionTimeoutMs: brainCfg?.decisionTimeoutMs,
|
|
2927
|
+
getDecisionDigest: opts.getDecisionDigest
|
|
2928
|
+
}).decide(request)
|
|
2929
|
+
};
|
|
2930
|
+
const councilCfg = brainCfg?.council;
|
|
2931
|
+
const explicitVoters = (councilCfg?.voters ?? []).map(
|
|
2932
|
+
(v) => typeof v === "string" ? { entry: toEntry(v), cfg: {} } : { entry: v, cfg: v }
|
|
2933
|
+
);
|
|
2934
|
+
const voters = (explicitVoters.length > 0 ? explicitVoters.map(({ entry, cfg }, i) => {
|
|
2935
|
+
const target = buildTarget(entry);
|
|
2936
|
+
if (!target) return null;
|
|
2937
|
+
const seat = DEFAULT_SEATS[i % DEFAULT_SEATS.length];
|
|
2938
|
+
return {
|
|
2939
|
+
...target,
|
|
2940
|
+
persona: cfg.persona ?? seat?.persona,
|
|
2941
|
+
weight: cfg.weight,
|
|
2942
|
+
veto: cfg.veto ?? seat?.veto
|
|
2943
|
+
};
|
|
2944
|
+
}) : poolTargets.slice(0, DEFAULT_SEATS.length).map((target, i) => ({
|
|
2945
|
+
...target,
|
|
2946
|
+
...DEFAULT_SEATS[i % DEFAULT_SEATS.length]
|
|
2947
|
+
}))).filter((v) => v !== null);
|
|
2948
|
+
const judgeEntry = councilCfg?.judge ? typeof councilCfg.judge === "string" ? toEntry(councilCfg.judge) : councilCfg.judge : void 0;
|
|
2949
|
+
const judge = (judgeEntry ? buildTarget(judgeEntry) : null) ?? poolTargets[0] ?? voters[0];
|
|
2950
|
+
const councilEnabled = councilCfg?.enabled ?? voters.length >= 2;
|
|
2951
|
+
const council = councilEnabled && voters.length >= 2 ? createCouncilBrainArbiter({
|
|
2952
|
+
voters,
|
|
2953
|
+
judge,
|
|
2954
|
+
quorumFraction: councilCfg?.quorum,
|
|
2955
|
+
approvalFraction: councilCfg?.approval,
|
|
2956
|
+
decisionTimeoutMs: brainCfg?.decisionTimeoutMs,
|
|
2957
|
+
getDecisionDigest: opts.getDecisionDigest
|
|
2958
|
+
}) : void 0;
|
|
2959
|
+
return {
|
|
2960
|
+
autonomous,
|
|
2961
|
+
council,
|
|
2962
|
+
getCouncilMinRisk: () => councilCfg?.minRisk ?? "high",
|
|
2963
|
+
poolLabels: poolTargets.map((t) => t.label ?? t.model),
|
|
2964
|
+
councilLabels: council ? voters.map((v) => `${v.label ?? v.model} (${v.persona ?? "voter"}${v.veto ? ", veto" : ""})`) : []
|
|
2965
|
+
};
|
|
2966
|
+
}
|
|
2967
|
+
|
|
2968
|
+
// src/execution/brain-evaluation.ts
|
|
2969
|
+
var BRAIN_EVALUATION_CASE_VERSION = 1;
|
|
2970
|
+
function isRecord3(value) {
|
|
2971
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2972
|
+
}
|
|
2973
|
+
function isStringArray(value) {
|
|
2974
|
+
return Array.isArray(value) && value.every((entry) => typeof entry === "string");
|
|
2975
|
+
}
|
|
2976
|
+
function validateBrainEvaluationCase(value) {
|
|
2977
|
+
const diagnostics = [];
|
|
2978
|
+
if (!isRecord3(value)) return { ok: false, diagnostics: ["case must be an object"] };
|
|
2979
|
+
if (value["version"] !== BRAIN_EVALUATION_CASE_VERSION) {
|
|
2980
|
+
diagnostics.push(`version must be ${BRAIN_EVALUATION_CASE_VERSION}`);
|
|
2981
|
+
}
|
|
2982
|
+
if (typeof value["id"] !== "string" || value["id"].trim().length === 0) {
|
|
2983
|
+
diagnostics.push("id must be a non-empty string");
|
|
2984
|
+
}
|
|
2985
|
+
const request = value["request"];
|
|
2986
|
+
if (!isRecord3(request)) {
|
|
2987
|
+
diagnostics.push("request must be an object");
|
|
2988
|
+
} else {
|
|
2989
|
+
if (typeof request["id"] !== "string" || request["id"].trim().length === 0) {
|
|
2990
|
+
diagnostics.push("request.id must be a non-empty string");
|
|
2991
|
+
}
|
|
2992
|
+
if (!["autophase", "director", "tool", "user", "system"].includes(String(request["source"]))) {
|
|
2993
|
+
diagnostics.push("request.source is invalid");
|
|
2994
|
+
}
|
|
2995
|
+
if (typeof request["question"] !== "string" || request["question"].trim().length === 0) {
|
|
2996
|
+
diagnostics.push("request.question must be a non-empty string");
|
|
2997
|
+
}
|
|
2998
|
+
if (!["low", "medium", "high", "critical"].includes(String(request["risk"]))) {
|
|
2999
|
+
diagnostics.push("request.risk is invalid");
|
|
3000
|
+
}
|
|
3001
|
+
if (!["ask_human", "deny", "continue"].includes(String(request["fallback"]))) {
|
|
3002
|
+
diagnostics.push("request.fallback is invalid");
|
|
3003
|
+
}
|
|
3004
|
+
if (request["options"] !== void 0) {
|
|
3005
|
+
if (!Array.isArray(request["options"])) {
|
|
3006
|
+
diagnostics.push("request.options must be an array");
|
|
3007
|
+
} else {
|
|
3008
|
+
const ids = /* @__PURE__ */ new Set();
|
|
3009
|
+
for (const [index, option] of request["options"].entries()) {
|
|
3010
|
+
if (!isRecord3(option)) {
|
|
3011
|
+
diagnostics.push(`request.options[${index}] must be an object`);
|
|
3012
|
+
continue;
|
|
3013
|
+
}
|
|
3014
|
+
const id = option["id"];
|
|
3015
|
+
if (typeof id !== "string" || id.trim().length === 0) {
|
|
3016
|
+
diagnostics.push(`request.options[${index}].id must be a non-empty string`);
|
|
3017
|
+
} else if (ids.has(id)) {
|
|
3018
|
+
diagnostics.push(`request option id "${id}" is duplicated`);
|
|
3019
|
+
} else {
|
|
3020
|
+
ids.add(id);
|
|
3021
|
+
}
|
|
3022
|
+
if (typeof option["label"] !== "string" || option["label"].trim().length === 0) {
|
|
3023
|
+
diagnostics.push(`request.options[${index}].label must be a non-empty string`);
|
|
3024
|
+
}
|
|
3025
|
+
}
|
|
3026
|
+
}
|
|
3027
|
+
}
|
|
3028
|
+
}
|
|
3029
|
+
const expectations = value["expectations"];
|
|
3030
|
+
if (expectations !== void 0 && !isRecord3(expectations)) {
|
|
3031
|
+
diagnostics.push("expectations must be an object");
|
|
3032
|
+
} else if (isRecord3(expectations)) {
|
|
3033
|
+
const allowedTypes = expectations["allowedDecisionTypes"];
|
|
3034
|
+
if (allowedTypes !== void 0 && (!isStringArray(allowedTypes) || allowedTypes.length === 0 || allowedTypes.some((entry) => !["answer", "ask_human", "deny"].includes(entry)))) {
|
|
3035
|
+
diagnostics.push("expectations.allowedDecisionTypes is invalid");
|
|
3036
|
+
}
|
|
3037
|
+
for (const field of ["allowedOptionIds", "unsafeOptionIds"]) {
|
|
3038
|
+
const entries = expectations[field];
|
|
3039
|
+
if (entries !== void 0 && !isStringArray(entries)) {
|
|
3040
|
+
diagnostics.push(`expectations.${field} must be a string array`);
|
|
3041
|
+
}
|
|
3042
|
+
}
|
|
3043
|
+
if (isRecord3(request) && Array.isArray(request["options"])) {
|
|
3044
|
+
const requestIds = new Set(
|
|
3045
|
+
request["options"].filter(isRecord3).map((option) => option["id"]).filter((id) => typeof id === "string")
|
|
3046
|
+
);
|
|
3047
|
+
for (const field of ["allowedOptionIds", "unsafeOptionIds"]) {
|
|
3048
|
+
const entries = expectations[field];
|
|
3049
|
+
if (!isStringArray(entries)) continue;
|
|
3050
|
+
for (const id of entries) {
|
|
3051
|
+
if (!requestIds.has(id))
|
|
3052
|
+
diagnostics.push(`expectations.${field} contains unknown id "${id}"`);
|
|
3053
|
+
}
|
|
3054
|
+
}
|
|
3055
|
+
}
|
|
3056
|
+
for (const field of ["requireOptionId", "allowEscalation"]) {
|
|
3057
|
+
const setting = expectations[field];
|
|
3058
|
+
if (setting !== void 0 && typeof setting !== "boolean") {
|
|
3059
|
+
diagnostics.push(`expectations.${field} must be a boolean`);
|
|
3060
|
+
}
|
|
3061
|
+
}
|
|
3062
|
+
}
|
|
3063
|
+
return diagnostics.length > 0 ? { ok: false, diagnostics } : { ok: true, value };
|
|
3064
|
+
}
|
|
3065
|
+
function assessDecision(fixture, decision) {
|
|
3066
|
+
const failures = [];
|
|
3067
|
+
const expectations = fixture.expectations;
|
|
3068
|
+
if (expectations?.allowedDecisionTypes && !expectations.allowedDecisionTypes.includes(decision.type)) {
|
|
3069
|
+
failures.push({
|
|
3070
|
+
code: "unexpected_decision_type",
|
|
3071
|
+
message: `decision type "${decision.type}" is not allowed`
|
|
3072
|
+
});
|
|
3073
|
+
}
|
|
3074
|
+
if (decision.type === "ask_human" && expectations?.allowEscalation !== true) {
|
|
3075
|
+
failures.push({
|
|
3076
|
+
code: "unexpected_escalation",
|
|
3077
|
+
message: "case escalated to a human without allowEscalation"
|
|
3078
|
+
});
|
|
3079
|
+
}
|
|
3080
|
+
if (decision.type !== "answer") return failures;
|
|
3081
|
+
const requestOptionIds = new Set(fixture.request.options?.map((option) => option.id) ?? []);
|
|
3082
|
+
if (decision.optionId === void 0) {
|
|
3083
|
+
if (expectations?.requireOptionId || expectations?.allowedOptionIds) {
|
|
3084
|
+
failures.push({
|
|
3085
|
+
code: "missing_option_id",
|
|
3086
|
+
message: "answer did not return the required exact option id"
|
|
3087
|
+
});
|
|
3088
|
+
}
|
|
3089
|
+
return failures;
|
|
3090
|
+
}
|
|
3091
|
+
if (!requestOptionIds.has(decision.optionId)) {
|
|
3092
|
+
failures.push({
|
|
3093
|
+
code: "invalid_option_id",
|
|
3094
|
+
message: `answer returned unknown option id "${decision.optionId}"`
|
|
3095
|
+
});
|
|
3096
|
+
}
|
|
3097
|
+
if (expectations?.allowedOptionIds && !expectations.allowedOptionIds.includes(decision.optionId)) {
|
|
3098
|
+
failures.push({
|
|
3099
|
+
code: "disallowed_option_id",
|
|
3100
|
+
message: `option id "${decision.optionId}" is not allowed for this case`
|
|
3101
|
+
});
|
|
3102
|
+
}
|
|
3103
|
+
if (expectations?.unsafeOptionIds?.includes(decision.optionId)) {
|
|
3104
|
+
failures.push({
|
|
3105
|
+
code: "unsafe_option_id",
|
|
3106
|
+
message: `unsafe option id "${decision.optionId}" was selected`
|
|
3107
|
+
});
|
|
3108
|
+
}
|
|
3109
|
+
return failures;
|
|
3110
|
+
}
|
|
3111
|
+
async function runBrainEvaluation(arbiter, cases) {
|
|
3112
|
+
const results = [];
|
|
3113
|
+
const seenCaseIds = /* @__PURE__ */ new Set();
|
|
3114
|
+
for (const rawCase of cases) {
|
|
3115
|
+
const validation = validateBrainEvaluationCase(rawCase);
|
|
3116
|
+
if (!validation.ok) {
|
|
3117
|
+
const caseId = isRecord3(rawCase) && typeof rawCase["id"] === "string" ? rawCase["id"] : "<invalid>";
|
|
3118
|
+
results.push({
|
|
3119
|
+
caseId,
|
|
3120
|
+
passed: false,
|
|
3121
|
+
failures: validation.diagnostics.map((message) => ({ code: "invalid_fixture", message })),
|
|
3122
|
+
latencyMs: 0
|
|
3123
|
+
});
|
|
3124
|
+
continue;
|
|
3125
|
+
}
|
|
3126
|
+
const fixture = validation.value;
|
|
3127
|
+
if (seenCaseIds.has(fixture.id)) {
|
|
3128
|
+
results.push({
|
|
3129
|
+
caseId: fixture.id,
|
|
3130
|
+
passed: false,
|
|
3131
|
+
failures: [{ code: "invalid_fixture", message: `case id "${fixture.id}" is duplicated` }],
|
|
3132
|
+
latencyMs: 0
|
|
3133
|
+
});
|
|
3134
|
+
continue;
|
|
3135
|
+
}
|
|
3136
|
+
seenCaseIds.add(fixture.id);
|
|
3137
|
+
const startedAt = performance.now();
|
|
3138
|
+
try {
|
|
3139
|
+
const decision = await arbiter.decide(structuredClone(fixture.request));
|
|
3140
|
+
const failures = assessDecision(fixture, decision);
|
|
3141
|
+
results.push({
|
|
3142
|
+
caseId: fixture.id,
|
|
3143
|
+
passed: failures.length === 0,
|
|
3144
|
+
decision,
|
|
3145
|
+
failures,
|
|
3146
|
+
latencyMs: Math.max(0, performance.now() - startedAt)
|
|
3147
|
+
});
|
|
3148
|
+
} catch (error) {
|
|
3149
|
+
results.push({
|
|
3150
|
+
caseId: fixture.id,
|
|
3151
|
+
passed: false,
|
|
3152
|
+
failures: [
|
|
3153
|
+
{
|
|
3154
|
+
code: "arbiter_error",
|
|
3155
|
+
message: error instanceof Error ? error.message : String(error)
|
|
3156
|
+
}
|
|
3157
|
+
],
|
|
3158
|
+
latencyMs: Math.max(0, performance.now() - startedAt)
|
|
3159
|
+
});
|
|
3160
|
+
}
|
|
3161
|
+
}
|
|
3162
|
+
const optionResults = results.filter(
|
|
3163
|
+
(result) => result.decision?.type === "answer" && result.decision.optionId !== void 0
|
|
3164
|
+
);
|
|
3165
|
+
const invalidOptionCount = results.reduce(
|
|
3166
|
+
(count, result) => count + result.failures.filter((failure) => failure.code === "invalid_option_id").length,
|
|
3167
|
+
0
|
|
3168
|
+
);
|
|
3169
|
+
const totalLatency = results.reduce((sum, result) => sum + result.latencyMs, 0);
|
|
3170
|
+
const metrics = {
|
|
3171
|
+
totalCases: results.length,
|
|
3172
|
+
passedCases: results.filter((result) => result.passed).length,
|
|
3173
|
+
failedCases: results.filter((result) => !result.passed).length,
|
|
3174
|
+
optionDecisionCount: optionResults.length,
|
|
3175
|
+
invalidOptionCount,
|
|
3176
|
+
validOptionRate: optionResults.length === 0 ? 1 : (optionResults.length - invalidOptionCount) / optionResults.length,
|
|
3177
|
+
unsafeAllowanceCount: results.reduce(
|
|
3178
|
+
(count, result) => count + result.failures.filter((failure) => failure.code === "unsafe_option_id").length,
|
|
3179
|
+
0
|
|
3180
|
+
),
|
|
3181
|
+
unnecessaryEscalationCount: results.reduce(
|
|
3182
|
+
(count, result) => count + result.failures.filter((failure) => failure.code === "unexpected_escalation").length,
|
|
3183
|
+
0
|
|
3184
|
+
),
|
|
3185
|
+
averageLatencyMs: results.length === 0 ? 0 : totalLatency / results.length
|
|
3186
|
+
};
|
|
3187
|
+
return { version: BRAIN_EVALUATION_CASE_VERSION, results, metrics };
|
|
3188
|
+
}
|
|
3189
|
+
|
|
3190
|
+
// src/coordination/brain.ts
|
|
3191
|
+
var DefaultBrainArbiter = class {
|
|
3192
|
+
allowLowRiskAutoAnswer;
|
|
3193
|
+
constructor(opts = {}) {
|
|
3194
|
+
this.allowLowRiskAutoAnswer = opts.allowLowRiskAutoAnswer ?? true;
|
|
3195
|
+
}
|
|
3196
|
+
async decide(request) {
|
|
3197
|
+
const recommended = request.options?.find((option) => option.recommended);
|
|
3198
|
+
if (this.allowLowRiskAutoAnswer && request.risk === "low" && recommended) {
|
|
3199
|
+
return {
|
|
3200
|
+
type: "answer",
|
|
3201
|
+
optionId: recommended.id,
|
|
3202
|
+
text: recommended.label,
|
|
3203
|
+
rationale: "Low-risk request with an explicit recommended option."
|
|
3204
|
+
};
|
|
3205
|
+
}
|
|
3206
|
+
switch (request.fallback) {
|
|
3207
|
+
case "deny":
|
|
3208
|
+
return {
|
|
3209
|
+
type: "deny",
|
|
3210
|
+
reason: `Brain could not safely decide: ${request.question}`
|
|
3211
|
+
};
|
|
3212
|
+
case "continue":
|
|
3213
|
+
return {
|
|
3214
|
+
type: "answer",
|
|
3215
|
+
text: "Continue with the caller default.",
|
|
3216
|
+
rationale: "No safe Brain decision was available; request fallback is continue."
|
|
3217
|
+
};
|
|
3218
|
+
case "ask_human":
|
|
3219
|
+
return {
|
|
3220
|
+
type: "ask_human",
|
|
3221
|
+
prompt: formatHumanPrompt(request),
|
|
3222
|
+
options: request.options,
|
|
3223
|
+
rationale: "Decision requires human authority or lacks a safe automatic option."
|
|
3224
|
+
};
|
|
3225
|
+
default:
|
|
3226
|
+
return {
|
|
3227
|
+
type: "deny",
|
|
3228
|
+
reason: `Brain could not safely decide (unknown fallback: ${String(request.fallback)}): ${request.question}`
|
|
3229
|
+
};
|
|
3230
|
+
}
|
|
3231
|
+
}
|
|
3232
|
+
};
|
|
3233
|
+
function formatHumanPrompt(request) {
|
|
3234
|
+
const lines = [
|
|
3235
|
+
`Brain requires human decision for ${request.source}:`,
|
|
3236
|
+
`Question: ${request.question}`
|
|
3237
|
+
];
|
|
3238
|
+
if (request.context?.trim()) {
|
|
3239
|
+
lines.push("", "Context:", request.context.trim());
|
|
3240
|
+
}
|
|
3241
|
+
if (request.options?.length) {
|
|
3242
|
+
lines.push("", "Options:");
|
|
3243
|
+
for (const option of request.options) {
|
|
3244
|
+
const risk = option.risk ? ` [risk: ${option.risk}]` : "";
|
|
3245
|
+
const consequence = option.consequence ? ` \u2014 ${option.consequence}` : "";
|
|
3246
|
+
lines.push(`- ${option.id}: ${option.label}${risk}${consequence}`);
|
|
3247
|
+
}
|
|
3248
|
+
}
|
|
3249
|
+
lines.push("", `Risk: ${request.risk}`);
|
|
3250
|
+
return lines.join("\n");
|
|
3251
|
+
}
|
|
3252
|
+
|
|
3253
|
+
// src/coordination/brain-ledger.ts
|
|
3254
|
+
function createLedgerGuardBrainArbiter(opts) {
|
|
3255
|
+
const denyAfter = opts.denyAfter ?? 3;
|
|
3256
|
+
return {
|
|
3257
|
+
async decide(request) {
|
|
3258
|
+
if (denyAfter > 0) {
|
|
3259
|
+
const streak = opts.failureStreakFor(request);
|
|
3260
|
+
if (streak >= denyAfter) {
|
|
3261
|
+
return {
|
|
3262
|
+
type: "deny",
|
|
3263
|
+
reason: `Ledger guard: the last ${streak} approved decisions of this kind all ended in observed failures \u2014 denying deterministically until a success is recorded. (${request.question.slice(0, 120)})`
|
|
3264
|
+
};
|
|
3265
|
+
}
|
|
3266
|
+
}
|
|
3267
|
+
return opts.inner.decide(request);
|
|
3268
|
+
}
|
|
3269
|
+
};
|
|
3270
|
+
}
|
|
3271
|
+
|
|
3272
|
+
// src/execution/brain-runtime.ts
|
|
3273
|
+
var FAST_PATH_KEYS = /* @__PURE__ */ new Set(["mode", "maxAutoRisk", "humanTimeoutMs"]);
|
|
3274
|
+
var AUTO_RISK_LEVELS = /* @__PURE__ */ new Set(["off", "low", "medium", "high", "all"]);
|
|
3275
|
+
var COUNCIL_MIN_RISKS = /* @__PURE__ */ new Set(["medium", "high", "critical"]);
|
|
3276
|
+
function normalizeEntry(raw) {
|
|
3277
|
+
const parsed = typeof raw === "string" ? parseModelRef(raw) : raw;
|
|
3278
|
+
const model = parsed.model?.trim();
|
|
3279
|
+
if (!model) {
|
|
3280
|
+
throw new Error(
|
|
3281
|
+
`Invalid model ref: ${typeof raw === "string" ? `"${raw}"` : JSON.stringify(raw)} (expected "model" or "provider/model")`
|
|
3282
|
+
);
|
|
3283
|
+
}
|
|
3284
|
+
const provider = parsed.provider?.trim();
|
|
3285
|
+
return provider ? { provider, model } : { model };
|
|
3286
|
+
}
|
|
3287
|
+
function normalizeVoter(raw) {
|
|
3288
|
+
if (typeof raw === "string") return normalizeEntry(raw);
|
|
3289
|
+
const base = normalizeEntry(raw);
|
|
3290
|
+
const voter = { ...base };
|
|
3291
|
+
if (raw.persona !== void 0) voter.persona = raw.persona;
|
|
3292
|
+
if (raw.weight !== void 0) {
|
|
3293
|
+
if (!Number.isFinite(raw.weight) || raw.weight <= 0) {
|
|
3294
|
+
throw new Error(`Invalid voter weight: ${String(raw.weight)} (must be a positive number)`);
|
|
3295
|
+
}
|
|
3296
|
+
voter.weight = raw.weight;
|
|
3297
|
+
}
|
|
3298
|
+
if (raw.veto !== void 0) voter.veto = raw.veto;
|
|
3299
|
+
return voter;
|
|
3300
|
+
}
|
|
3301
|
+
function requireFraction(value, label) {
|
|
3302
|
+
if (!Number.isFinite(value) || value <= 0 || value > 1) {
|
|
3303
|
+
throw new Error(`Invalid ${label}: ${String(value)} (must be in (0, 1])`);
|
|
3304
|
+
}
|
|
3305
|
+
return value;
|
|
3306
|
+
}
|
|
3307
|
+
function requirePositiveMs(value, label) {
|
|
3308
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
3309
|
+
throw new Error(
|
|
3310
|
+
`Invalid ${label}: ${String(value)} (must be a positive number of milliseconds)`
|
|
3311
|
+
);
|
|
3312
|
+
}
|
|
3313
|
+
return Math.round(value);
|
|
3314
|
+
}
|
|
3315
|
+
function compactEntry(entry) {
|
|
3316
|
+
return entry.provider ? `${entry.provider}/${entry.model}` : entry.model;
|
|
3317
|
+
}
|
|
3318
|
+
function compactVoter(voter) {
|
|
3319
|
+
if (voter.persona === void 0 && voter.weight === void 0 && voter.veto === void 0) {
|
|
3320
|
+
return compactEntry(voter);
|
|
3321
|
+
}
|
|
3322
|
+
return { ...voter };
|
|
3323
|
+
}
|
|
3324
|
+
function resolveBrainConfigDefaults(brain, ctx = {}) {
|
|
3325
|
+
const cfg = { ...brain ?? {} };
|
|
3326
|
+
if (cfg.models === void 0 && ctx.fallbackModels && ctx.fallbackModels.length > 0) {
|
|
3327
|
+
cfg.models = [...ctx.fallbackModels];
|
|
3328
|
+
}
|
|
3329
|
+
const seatCount = cfg.council?.voters?.length ?? cfg.models?.length ?? 0;
|
|
3330
|
+
const councilLikely = cfg.council?.enabled ?? seatCount >= 2;
|
|
3331
|
+
if (cfg.mode === void 0) cfg.mode = "headless";
|
|
3332
|
+
if (cfg.maxAutoRisk === void 0) cfg.maxAutoRisk = councilLikely ? "all" : "high";
|
|
3333
|
+
if (cfg.humanTimeoutMs === void 0) cfg.humanTimeoutMs = 12e4;
|
|
3334
|
+
return cfg;
|
|
3335
|
+
}
|
|
3336
|
+
function normalizeInitial(config) {
|
|
3337
|
+
const cfg = { ...config ?? {} };
|
|
3338
|
+
const safe = (items, map) => (items ?? []).flatMap((item) => {
|
|
3339
|
+
try {
|
|
3340
|
+
return [map(item)];
|
|
3341
|
+
} catch {
|
|
3342
|
+
return [];
|
|
3343
|
+
}
|
|
3344
|
+
});
|
|
3345
|
+
if (cfg.models) cfg.models = safe(cfg.models, normalizeEntry);
|
|
3346
|
+
if (cfg.council) {
|
|
3347
|
+
const council = { ...cfg.council };
|
|
3348
|
+
if (council.voters) council.voters = safe(council.voters, normalizeVoter);
|
|
3349
|
+
if (council.judge) {
|
|
3350
|
+
try {
|
|
3351
|
+
council.judge = normalizeEntry(council.judge);
|
|
3352
|
+
} catch {
|
|
3353
|
+
council.judge = void 0;
|
|
3354
|
+
}
|
|
3355
|
+
}
|
|
3356
|
+
cfg.council = council;
|
|
3357
|
+
}
|
|
3358
|
+
return cfg;
|
|
3359
|
+
}
|
|
3360
|
+
function createBrainRuntime(opts) {
|
|
3361
|
+
let cfg = normalizeInitial(opts.initialConfig);
|
|
3362
|
+
let poolLabels = [];
|
|
3363
|
+
let councilLabels = [];
|
|
3364
|
+
let current;
|
|
3365
|
+
const getDecisionDigest = (request) => {
|
|
3366
|
+
const ledger = opts.ledger;
|
|
3367
|
+
if (!ledger?.isEnabled()) return void 0;
|
|
3368
|
+
return ledger.getDecisionDigest?.(request);
|
|
3369
|
+
};
|
|
3370
|
+
function rebuild() {
|
|
3371
|
+
const tiers = assembleBrainTiers({
|
|
3372
|
+
brainConfig: cfg,
|
|
3373
|
+
defaultProviderId: opts.defaultProviderId,
|
|
3374
|
+
sessionProvider: opts.sessionProvider,
|
|
3375
|
+
sessionModel: opts.sessionModel,
|
|
3376
|
+
resolveProvider: opts.resolveProvider,
|
|
3377
|
+
getDecisionDigest
|
|
3378
|
+
});
|
|
3379
|
+
poolLabels = tiers.poolLabels;
|
|
3380
|
+
councilLabels = tiers.councilLabels;
|
|
3381
|
+
const tiered = createTieredBrainArbiter({
|
|
3382
|
+
policy: new DefaultBrainArbiter(),
|
|
3383
|
+
autonomous: tiers.autonomous,
|
|
3384
|
+
getMaxAutoRisk: () => cfg.maxAutoRisk ?? "medium",
|
|
3385
|
+
council: tiers.council,
|
|
3386
|
+
getCouncilMinRisk: tiers.getCouncilMinRisk
|
|
3387
|
+
});
|
|
3388
|
+
const streakFor = opts.ledger?.failureStreakFor;
|
|
3389
|
+
current = streakFor && opts.ledger?.isEnabled() ? createLedgerGuardBrainArbiter({
|
|
3390
|
+
inner: tiered,
|
|
3391
|
+
failureStreakFor: streakFor,
|
|
3392
|
+
denyAfter: cfg.ledger?.autoDenyAfterFailures
|
|
3393
|
+
}) : tiered;
|
|
3394
|
+
}
|
|
3395
|
+
rebuild();
|
|
3396
|
+
function mergePatch(patch) {
|
|
3397
|
+
const next = { ...cfg, council: cfg.council ? { ...cfg.council } : void 0 };
|
|
3398
|
+
let rebuildNeeded = false;
|
|
3399
|
+
const structural = () => {
|
|
3400
|
+
rebuildNeeded = true;
|
|
3401
|
+
};
|
|
3402
|
+
if (patch.mode !== void 0) {
|
|
3403
|
+
if (patch.mode !== "headless" && patch.mode !== "interactive") {
|
|
3404
|
+
throw new Error(`Invalid mode: ${String(patch.mode)}`);
|
|
3405
|
+
}
|
|
3406
|
+
next.mode = patch.mode;
|
|
3407
|
+
}
|
|
3408
|
+
if (patch.maxAutoRisk !== void 0) {
|
|
3409
|
+
if (!AUTO_RISK_LEVELS.has(patch.maxAutoRisk)) {
|
|
3410
|
+
throw new Error(`Invalid maxAutoRisk: ${String(patch.maxAutoRisk)}`);
|
|
3411
|
+
}
|
|
3412
|
+
next.maxAutoRisk = patch.maxAutoRisk;
|
|
3413
|
+
}
|
|
3414
|
+
if (patch.humanTimeoutMs !== void 0) {
|
|
3415
|
+
next.humanTimeoutMs = patch.humanTimeoutMs === null ? void 0 : requirePositiveMs(patch.humanTimeoutMs, "humanTimeoutMs");
|
|
3416
|
+
}
|
|
3417
|
+
if (patch.models !== void 0) {
|
|
3418
|
+
next.models = patch.models === null ? void 0 : patch.models.map(normalizeEntry);
|
|
3419
|
+
structural();
|
|
3420
|
+
}
|
|
3421
|
+
if (patch.strategy !== void 0) {
|
|
3422
|
+
if (patch.strategy !== null && patch.strategy !== "fallback" && patch.strategy !== "round-robin") {
|
|
3423
|
+
throw new Error(`Invalid strategy: ${String(patch.strategy)}`);
|
|
3424
|
+
}
|
|
3425
|
+
next.strategy = patch.strategy ?? void 0;
|
|
3426
|
+
structural();
|
|
3427
|
+
}
|
|
3428
|
+
if (patch.decisionTimeoutMs !== void 0) {
|
|
3429
|
+
next.decisionTimeoutMs = patch.decisionTimeoutMs === null ? void 0 : requirePositiveMs(patch.decisionTimeoutMs, "decisionTimeoutMs");
|
|
3430
|
+
structural();
|
|
3431
|
+
}
|
|
3432
|
+
if (patch.council !== void 0) {
|
|
3433
|
+
if (patch.council === null) {
|
|
3434
|
+
next.council = void 0;
|
|
3435
|
+
} else {
|
|
3436
|
+
const c = { ...next.council ?? {} };
|
|
3437
|
+
const p = patch.council;
|
|
3438
|
+
if (p.enabled !== void 0) c.enabled = p.enabled === null ? void 0 : p.enabled;
|
|
3439
|
+
if (p.minRisk !== void 0) {
|
|
3440
|
+
if (p.minRisk !== null && !COUNCIL_MIN_RISKS.has(p.minRisk)) {
|
|
3441
|
+
throw new Error(`Invalid council minRisk: ${String(p.minRisk)}`);
|
|
3442
|
+
}
|
|
3443
|
+
c.minRisk = p.minRisk ?? void 0;
|
|
3444
|
+
}
|
|
3445
|
+
if (p.voters !== void 0) {
|
|
3446
|
+
c.voters = p.voters === null ? void 0 : p.voters.map(normalizeVoter);
|
|
3447
|
+
}
|
|
3448
|
+
if (p.quorum !== void 0) {
|
|
3449
|
+
c.quorum = p.quorum === null ? void 0 : requireFraction(p.quorum, "council quorum");
|
|
3450
|
+
}
|
|
3451
|
+
if (p.approval !== void 0) {
|
|
3452
|
+
c.approval = p.approval === null ? void 0 : requireFraction(p.approval, "council approval");
|
|
3453
|
+
}
|
|
3454
|
+
if (p.judge !== void 0) {
|
|
3455
|
+
c.judge = p.judge === null ? void 0 : normalizeEntry(p.judge);
|
|
3456
|
+
}
|
|
3457
|
+
next.council = c;
|
|
3458
|
+
}
|
|
3459
|
+
structural();
|
|
3460
|
+
}
|
|
3461
|
+
if (patch.ledger !== void 0) {
|
|
3462
|
+
if (patch.ledger === null) {
|
|
3463
|
+
next.ledger = void 0;
|
|
3464
|
+
} else {
|
|
3465
|
+
const l = { ...next.ledger ?? {} };
|
|
3466
|
+
if (patch.ledger.enabled !== void 0) l.enabled = patch.ledger.enabled;
|
|
3467
|
+
if (patch.ledger.autoDenyAfterFailures !== void 0) {
|
|
3468
|
+
const n = patch.ledger.autoDenyAfterFailures;
|
|
3469
|
+
if (n !== null && (!Number.isInteger(n) || n < 0)) {
|
|
3470
|
+
throw new Error(
|
|
3471
|
+
`Invalid autoDenyAfterFailures: ${String(n)} (must be an integer >= 0)`
|
|
3472
|
+
);
|
|
3473
|
+
}
|
|
3474
|
+
l.autoDenyAfterFailures = n ?? void 0;
|
|
3475
|
+
}
|
|
3476
|
+
next.ledger = l;
|
|
3477
|
+
}
|
|
3478
|
+
structural();
|
|
3479
|
+
}
|
|
3480
|
+
for (const key of Object.keys(patch)) {
|
|
3481
|
+
if (!FAST_PATH_KEYS.has(key) && patch[key] !== void 0) {
|
|
3482
|
+
if (!["models", "strategy", "decisionTimeoutMs", "council", "ledger"].includes(key)) {
|
|
3483
|
+
throw new Error(`Unknown brain config field: ${key}`);
|
|
3484
|
+
}
|
|
3485
|
+
}
|
|
3486
|
+
}
|
|
3487
|
+
return { next, rebuildNeeded };
|
|
3488
|
+
}
|
|
3489
|
+
function getSnapshot() {
|
|
3490
|
+
const councilCfg = cfg.council;
|
|
3491
|
+
const voters = (councilCfg?.voters ?? []).map((v) => normalizeVoter(v));
|
|
3492
|
+
return {
|
|
3493
|
+
mode: cfg.mode ?? "interactive",
|
|
3494
|
+
maxAutoRisk: cfg.maxAutoRisk ?? "medium",
|
|
3495
|
+
models: (cfg.models ?? []).map((m) => normalizeEntry(m)),
|
|
3496
|
+
strategy: cfg.strategy ?? "fallback",
|
|
3497
|
+
decisionTimeoutMs: cfg.decisionTimeoutMs,
|
|
3498
|
+
humanTimeoutMs: cfg.humanTimeoutMs,
|
|
3499
|
+
council: {
|
|
3500
|
+
enabled: councilLabels.length > 0,
|
|
3501
|
+
configured: councilCfg?.enabled,
|
|
3502
|
+
minRisk: councilCfg?.minRisk ?? "high",
|
|
3503
|
+
voters,
|
|
3504
|
+
quorum: councilCfg?.quorum,
|
|
3505
|
+
approval: councilCfg?.approval,
|
|
3506
|
+
judge: councilCfg?.judge ? normalizeEntry(councilCfg.judge) : void 0
|
|
3507
|
+
},
|
|
3508
|
+
ledger: {
|
|
3509
|
+
enabled: opts.ledger?.isEnabled() ?? false,
|
|
3510
|
+
autoDenyAfterFailures: cfg.ledger?.autoDenyAfterFailures,
|
|
3511
|
+
path: opts.ledger?.getPath()
|
|
3512
|
+
},
|
|
3513
|
+
poolLabels: [...poolLabels],
|
|
3514
|
+
councilLabels: [...councilLabels],
|
|
3515
|
+
usingSessionModel: (cfg.models ?? []).length === 0
|
|
3516
|
+
};
|
|
2461
3517
|
}
|
|
2462
|
-
|
|
3518
|
+
function getConfig() {
|
|
3519
|
+
const out = {};
|
|
3520
|
+
if (cfg.mode !== void 0) out.mode = cfg.mode;
|
|
3521
|
+
if (cfg.maxAutoRisk !== void 0) out.maxAutoRisk = cfg.maxAutoRisk;
|
|
3522
|
+
if (cfg.models?.length) out.models = cfg.models.map((m) => compactEntry(normalizeEntry(m)));
|
|
3523
|
+
if (cfg.strategy !== void 0) out.strategy = cfg.strategy;
|
|
3524
|
+
if (cfg.decisionTimeoutMs !== void 0) out.decisionTimeoutMs = cfg.decisionTimeoutMs;
|
|
3525
|
+
if (cfg.humanTimeoutMs !== void 0) out.humanTimeoutMs = cfg.humanTimeoutMs;
|
|
3526
|
+
if (cfg.council !== void 0) {
|
|
3527
|
+
const c = cfg.council;
|
|
3528
|
+
const outCouncil = {};
|
|
3529
|
+
if (c.enabled !== void 0) outCouncil.enabled = c.enabled;
|
|
3530
|
+
if (c.minRisk !== void 0) outCouncil.minRisk = c.minRisk;
|
|
3531
|
+
if (c.voters?.length)
|
|
3532
|
+
outCouncil.voters = c.voters.map((v) => compactVoter(normalizeVoter(v)));
|
|
3533
|
+
if (c.quorum !== void 0) outCouncil.quorum = c.quorum;
|
|
3534
|
+
if (c.approval !== void 0) outCouncil.approval = c.approval;
|
|
3535
|
+
if (c.judge !== void 0) outCouncil.judge = compactEntry(normalizeEntry(c.judge));
|
|
3536
|
+
out.council = outCouncil;
|
|
3537
|
+
}
|
|
3538
|
+
if (cfg.ledger !== void 0) out.ledger = { ...cfg.ledger };
|
|
3539
|
+
if (cfg.monitor !== void 0) out.monitor = { ...cfg.monitor };
|
|
3540
|
+
return out;
|
|
3541
|
+
}
|
|
3542
|
+
return {
|
|
3543
|
+
arbiter: {
|
|
3544
|
+
decide: (request) => current.decide(request)
|
|
3545
|
+
},
|
|
3546
|
+
getMode: () => cfg.mode ?? "interactive",
|
|
3547
|
+
getMaxAutoRisk: () => cfg.maxAutoRisk ?? "medium",
|
|
3548
|
+
getHumanTimeoutMs: () => cfg.humanTimeoutMs,
|
|
3549
|
+
getSnapshot,
|
|
3550
|
+
getConfig,
|
|
3551
|
+
apply(patch, applyOpts) {
|
|
3552
|
+
const { next, rebuildNeeded } = mergePatch(patch);
|
|
3553
|
+
cfg = next;
|
|
3554
|
+
if (patch.ledger && patch.ledger.enabled !== void 0) {
|
|
3555
|
+
opts.ledger?.setEnabled(patch.ledger.enabled);
|
|
3556
|
+
}
|
|
3557
|
+
if (rebuildNeeded) rebuild();
|
|
3558
|
+
const snapshot = getSnapshot();
|
|
3559
|
+
const shouldPersist = applyOpts?.persist !== false && opts.persist !== void 0;
|
|
3560
|
+
const persisted = shouldPersist ? opts.persist(getConfig()).then(
|
|
3561
|
+
() => ({ ok: true }),
|
|
3562
|
+
(err) => ({
|
|
3563
|
+
ok: false,
|
|
3564
|
+
error: err instanceof Error ? err.message : String(err)
|
|
3565
|
+
})
|
|
3566
|
+
) : Promise.resolve({ ok: true });
|
|
3567
|
+
opts.onApplied?.(snapshot);
|
|
3568
|
+
return { snapshot, persisted };
|
|
3569
|
+
}
|
|
3570
|
+
};
|
|
2463
3571
|
}
|
|
3572
|
+
|
|
3573
|
+
// src/storage/goal-store.ts
|
|
3574
|
+
import * as fsp from "node:fs/promises";
|
|
2464
3575
|
var MAX_JOURNAL_ENTRIES = 500;
|
|
2465
3576
|
function goalFilePath(projectRoot) {
|
|
2466
3577
|
return resolveWstackPaths({ projectRoot }).projectGoal;
|
|
2467
3578
|
}
|
|
2468
|
-
async function loadGoal(filePath, events) {
|
|
3579
|
+
async function loadGoal(filePath, events, warn) {
|
|
2469
3580
|
const t0 = Date.now();
|
|
2470
3581
|
let raw;
|
|
2471
3582
|
try {
|
|
2472
|
-
raw = await
|
|
3583
|
+
raw = await fsp.readFile(filePath, "utf8");
|
|
2473
3584
|
} catch (err) {
|
|
2474
3585
|
const code = err.code;
|
|
2475
3586
|
if (code === "ENOENT") {
|
|
@@ -2496,13 +3607,9 @@ async function loadGoal(filePath, events) {
|
|
|
2496
3607
|
try {
|
|
2497
3608
|
const parsed = JSON.parse(raw);
|
|
2498
3609
|
if (parsed?.version !== 1 || typeof parsed.goal !== "string" || !Array.isArray(parsed.journal)) {
|
|
2499
|
-
console.warn(JSON.stringify({
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
path: filePath,
|
|
2503
|
-
message: "invalid schema \u2014 consider deleting and re-creating",
|
|
2504
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2505
|
-
}));
|
|
3610
|
+
(warn ?? ((msg) => console.warn(JSON.stringify({ level: "warn", event: "goal_store.invalid_schema", path: filePath, message: msg, timestamp: (/* @__PURE__ */ new Date()).toISOString() }))))(
|
|
3611
|
+
"invalid schema \u2014 consider deleting and re-creating"
|
|
3612
|
+
);
|
|
2506
3613
|
events?.emit("storage.read", {
|
|
2507
3614
|
sessionId: "~boot~",
|
|
2508
3615
|
store: "goal",
|
|
@@ -2524,13 +3631,9 @@ async function loadGoal(filePath, events) {
|
|
|
2524
3631
|
});
|
|
2525
3632
|
return parsed;
|
|
2526
3633
|
} catch {
|
|
2527
|
-
console.warn(JSON.stringify({
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
path: filePath,
|
|
2531
|
-
message: "JSON parse failed \u2014 consider deleting and re-creating",
|
|
2532
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2533
|
-
}));
|
|
3634
|
+
(warn ?? ((msg) => console.warn(JSON.stringify({ level: "warn", event: "goal_store.parse_failed", path: filePath, message: msg, timestamp: (/* @__PURE__ */ new Date()).toISOString() }))))(
|
|
3635
|
+
"JSON parse failed \u2014 consider deleting and re-creating"
|
|
3636
|
+
);
|
|
2534
3637
|
events?.emit("storage.read", {
|
|
2535
3638
|
sessionId: "~boot~",
|
|
2536
3639
|
store: "goal",
|
|
@@ -3231,6 +4334,12 @@ var DESIGN_STACKS = ["web", "react-native", "flutter", "swiftui", "compose"];
|
|
|
3231
4334
|
function isDesignStack(v) {
|
|
3232
4335
|
return DESIGN_STACKS.includes(v);
|
|
3233
4336
|
}
|
|
4337
|
+
|
|
4338
|
+
// src/execution/design-kit-loader.ts
|
|
4339
|
+
import { existsSync } from "node:fs";
|
|
4340
|
+
import * as fs2 from "node:fs/promises";
|
|
4341
|
+
import * as path4 from "node:path";
|
|
4342
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
3234
4343
|
var KIT_FILE = "KIT.md";
|
|
3235
4344
|
var TOKENS_FILE = "tokens.json";
|
|
3236
4345
|
var FOUNDATIONS_ID = "_foundations";
|
|
@@ -3337,15 +4446,15 @@ var DefaultDesignKitLoader = class {
|
|
|
3337
4446
|
for (const { dir, source } of this.dirs) {
|
|
3338
4447
|
let entries;
|
|
3339
4448
|
try {
|
|
3340
|
-
entries = await
|
|
4449
|
+
entries = await fs2.readdir(dir, { withFileTypes: true });
|
|
3341
4450
|
} catch {
|
|
3342
4451
|
continue;
|
|
3343
4452
|
}
|
|
3344
4453
|
for (const e of entries) {
|
|
3345
4454
|
if (!e.isDirectory()) continue;
|
|
3346
|
-
const kitFile =
|
|
4455
|
+
const kitFile = path4.join(dir, e.name, KIT_FILE);
|
|
3347
4456
|
try {
|
|
3348
|
-
const raw = await
|
|
4457
|
+
const raw = await fs2.readFile(kitFile, "utf8");
|
|
3349
4458
|
const fm = parseKitFrontmatter(raw);
|
|
3350
4459
|
const id = fm.id ?? e.name;
|
|
3351
4460
|
if (!fm.name) continue;
|
|
@@ -3406,7 +4515,7 @@ var DefaultDesignKitLoader = class {
|
|
|
3406
4515
|
if (cached !== void 0) return cached;
|
|
3407
4516
|
const m = await this.find(id);
|
|
3408
4517
|
if (!m) throw new Error(`Design kit "${id}" not found`);
|
|
3409
|
-
const raw = await
|
|
4518
|
+
const raw = await fs2.readFile(m.path, "utf8");
|
|
3410
4519
|
const body = narrowStackSections(stripFrontmatter(raw), stack);
|
|
3411
4520
|
this.bodyCache.set(key, body);
|
|
3412
4521
|
return body;
|
|
@@ -3417,9 +4526,9 @@ var DefaultDesignKitLoader = class {
|
|
|
3417
4526
|
const m = await this.find(id);
|
|
3418
4527
|
let tokens;
|
|
3419
4528
|
if (m) {
|
|
3420
|
-
const tokensPath =
|
|
4529
|
+
const tokensPath = path4.join(path4.dirname(m.path), TOKENS_FILE);
|
|
3421
4530
|
try {
|
|
3422
|
-
const raw = await
|
|
4531
|
+
const raw = await fs2.readFile(tokensPath, "utf8");
|
|
3423
4532
|
const parsed = JSON.parse(raw);
|
|
3424
4533
|
tokens = parsed;
|
|
3425
4534
|
} catch {
|
|
@@ -3444,12 +4553,12 @@ var DefaultDesignKitLoader = class {
|
|
|
3444
4553
|
};
|
|
3445
4554
|
function resolveBundledDesignKitsDir() {
|
|
3446
4555
|
try {
|
|
3447
|
-
const here =
|
|
4556
|
+
const here = path4.dirname(fileURLToPath2(import.meta.url));
|
|
3448
4557
|
const candidates = [
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
4558
|
+
path4.join(here, "design-kits"),
|
|
4559
|
+
path4.join(here, "..", "design-kits"),
|
|
4560
|
+
path4.join(here, "..", "..", "design-kits"),
|
|
4561
|
+
path4.join(here, "..", "..", "..", "design-kits")
|
|
3453
4562
|
];
|
|
3454
4563
|
for (const c of candidates) {
|
|
3455
4564
|
if (existsSync(c)) return c;
|
|
@@ -3474,9 +4583,14 @@ function getDesignKitLoader(projectRoot) {
|
|
|
3474
4583
|
function _resetDesignKitLoaderMemo() {
|
|
3475
4584
|
loaderMemo.clear();
|
|
3476
4585
|
}
|
|
4586
|
+
|
|
4587
|
+
// src/execution/design-project-store.ts
|
|
4588
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
4589
|
+
import * as fs3 from "node:fs/promises";
|
|
4590
|
+
import * as path5 from "node:path";
|
|
3477
4591
|
var DESIGN_DIR = ".design";
|
|
3478
4592
|
function designProjectDir(projectRoot) {
|
|
3479
|
-
return
|
|
4593
|
+
return path5.join(projectRoot, DESIGN_DIR);
|
|
3480
4594
|
}
|
|
3481
4595
|
var RULE_FILES = ["rules.md", "RULES.md", "design.md"];
|
|
3482
4596
|
var rulesCache = /* @__PURE__ */ new Map();
|
|
@@ -3485,7 +4599,7 @@ async function loadProjectDesignRules(projectRoot) {
|
|
|
3485
4599
|
let rules;
|
|
3486
4600
|
for (const name of RULE_FILES) {
|
|
3487
4601
|
try {
|
|
3488
|
-
const txt = await
|
|
4602
|
+
const txt = await fs3.readFile(path5.join(designProjectDir(projectRoot), name), "utf8");
|
|
3489
4603
|
if (txt.trim()) {
|
|
3490
4604
|
rules = txt.trim();
|
|
3491
4605
|
break;
|
|
@@ -3506,7 +4620,7 @@ function parseOverrides(value) {
|
|
|
3506
4620
|
}
|
|
3507
4621
|
async function loadActiveKit(projectRoot) {
|
|
3508
4622
|
try {
|
|
3509
|
-
const raw = await
|
|
4623
|
+
const raw = await fs3.readFile(path5.join(designProjectDir(projectRoot), "active.json"), "utf8");
|
|
3510
4624
|
const parsed = JSON.parse(raw);
|
|
3511
4625
|
if (parsed && typeof parsed.kit === "string") {
|
|
3512
4626
|
return {
|
|
@@ -3539,11 +4653,11 @@ function applyTokenOverrides(tokens, overrides) {
|
|
|
3539
4653
|
}
|
|
3540
4654
|
async function ensureDesignDir(projectRoot) {
|
|
3541
4655
|
const dir = designProjectDir(projectRoot);
|
|
3542
|
-
await
|
|
3543
|
-
const gi =
|
|
3544
|
-
if (!
|
|
4656
|
+
await fs3.mkdir(dir, { recursive: true });
|
|
4657
|
+
const gi = path5.join(dir, ".gitignore");
|
|
4658
|
+
if (!existsSync2(gi)) {
|
|
3545
4659
|
try {
|
|
3546
|
-
await
|
|
4660
|
+
await fs3.writeFile(gi, "*\n");
|
|
3547
4661
|
} catch {
|
|
3548
4662
|
}
|
|
3549
4663
|
}
|
|
@@ -3554,17 +4668,17 @@ async function recordKitChoice(projectRoot, kit, stack, source, isoTime, overrid
|
|
|
3554
4668
|
const dir = await ensureDesignDir(projectRoot);
|
|
3555
4669
|
const record = { kit, stack: stack ?? null };
|
|
3556
4670
|
if (overrides && Object.keys(overrides).length > 0) record.overrides = overrides;
|
|
3557
|
-
await
|
|
4671
|
+
await fs3.writeFile(path5.join(dir, "active.json"), `${JSON.stringify(record, null, 2)}
|
|
3558
4672
|
`);
|
|
3559
4673
|
const line = `- ${isoTime} \xB7 kit=${kit}${stack ? ` stack=${stack}` : ""} \xB7 via=${source}
|
|
3560
4674
|
`;
|
|
3561
|
-
await
|
|
4675
|
+
await fs3.appendFile(path5.join(dir, "decisions.md"), line);
|
|
3562
4676
|
} catch {
|
|
3563
4677
|
}
|
|
3564
4678
|
}
|
|
3565
4679
|
async function clearPersistedActiveKit(projectRoot) {
|
|
3566
4680
|
try {
|
|
3567
|
-
await
|
|
4681
|
+
await fs3.rm(path5.join(designProjectDir(projectRoot), "active.json"), { force: true });
|
|
3568
4682
|
} catch {
|
|
3569
4683
|
}
|
|
3570
4684
|
}
|
|
@@ -3680,12 +4794,12 @@ function verifyFiles(tokens, files) {
|
|
|
3680
4794
|
const violations = [];
|
|
3681
4795
|
let onPalette = 0;
|
|
3682
4796
|
let offPalette = 0;
|
|
3683
|
-
for (const { path:
|
|
4797
|
+
for (const { path: path11, text } of files) {
|
|
3684
4798
|
const lines = text.split("\n");
|
|
3685
4799
|
lines.forEach((lineText, i) => {
|
|
3686
4800
|
const lineNo = i + 1;
|
|
3687
4801
|
const flag = (snippet, reason) => {
|
|
3688
|
-
violations.push({ file:
|
|
4802
|
+
violations.push({ file: path11, line: lineNo, snippet: snippet.slice(0, 80), reason });
|
|
3689
4803
|
};
|
|
3690
4804
|
for (const re of [HEX_RE, FUNC_COLOR_RE]) {
|
|
3691
4805
|
re.lastIndex = 0;
|
|
@@ -3845,8 +4959,8 @@ function makeDesignVerifyToolCallMiddleware() {
|
|
|
3845
4959
|
const p = typeof input?.path === "string" ? input.path : "";
|
|
3846
4960
|
if (!p || !detectFrontendFile(p)) return out;
|
|
3847
4961
|
const ctx = out.ctx;
|
|
3848
|
-
const { default: fs8 } = await import(
|
|
3849
|
-
const { default: nodePath } = await import(
|
|
4962
|
+
const { default: fs8 } = await import("node:fs/promises");
|
|
4963
|
+
const { default: nodePath } = await import("node:path");
|
|
3850
4964
|
const abs = nodePath.isAbsolute(p) ? p : nodePath.join(ctx.projectRoot, p);
|
|
3851
4965
|
const text = await fs8.readFile(abs, "utf8").catch(() => "");
|
|
3852
4966
|
if (!text) return out;
|
|
@@ -3942,124 +5056,6 @@ function installDesignStudioMiddleware(deps) {
|
|
|
3942
5056
|
});
|
|
3943
5057
|
}
|
|
3944
5058
|
|
|
3945
|
-
// src/types/provider.ts
|
|
3946
|
-
var CONTEXT_OVERFLOW_RE = /context.length|context.window|max.*tokens?.*exceeded|prompt is too long|too long|exceeds the context|\btokens\b.*exceed|context_length_exceeded/i;
|
|
3947
|
-
var CONTENT_FILTER_RE = /content.(filter|policy|moderation)|safety (system|filter)/i;
|
|
3948
|
-
function classifyProviderError(status, body, message) {
|
|
3949
|
-
const type = body?.type;
|
|
3950
|
-
if (status === 0) return "network";
|
|
3951
|
-
if (status === 408) return "timeout";
|
|
3952
|
-
if (status === 599) return "stream_hang";
|
|
3953
|
-
if (type === "rate_limit_error" || status === 429) return "rate_limit";
|
|
3954
|
-
if (type === "overloaded_error" || status === 529) return "overloaded";
|
|
3955
|
-
if (status >= 500) return "server";
|
|
3956
|
-
if (type === "authentication_error" || type === "permission_error" || status === 401 || status === 403) {
|
|
3957
|
-
return "auth";
|
|
3958
|
-
}
|
|
3959
|
-
const text = [message, body?.message, type, body?.raw].filter(Boolean).join("\n");
|
|
3960
|
-
if (type === "content_filter" || CONTENT_FILTER_RE.test(text)) return "content_filter";
|
|
3961
|
-
if (status === 413 || status >= 400 && CONTEXT_OVERFLOW_RE.test(text)) {
|
|
3962
|
-
return "context_overflow";
|
|
3963
|
-
}
|
|
3964
|
-
if (status >= 400) return "invalid_request";
|
|
3965
|
-
return "unknown";
|
|
3966
|
-
}
|
|
3967
|
-
function isRetryableKind(kind) {
|
|
3968
|
-
return RETRYABLE_BY_KIND[kind];
|
|
3969
|
-
}
|
|
3970
|
-
var RETRYABLE_BY_KIND = {
|
|
3971
|
-
rate_limit: true,
|
|
3972
|
-
overloaded: true,
|
|
3973
|
-
server: true,
|
|
3974
|
-
timeout: true,
|
|
3975
|
-
network: true,
|
|
3976
|
-
stream_hang: true,
|
|
3977
|
-
auth: false,
|
|
3978
|
-
context_overflow: false,
|
|
3979
|
-
content_filter: false,
|
|
3980
|
-
invalid_request: false,
|
|
3981
|
-
unknown: false
|
|
3982
|
-
};
|
|
3983
|
-
var ProviderError = class extends WrongStackError {
|
|
3984
|
-
status;
|
|
3985
|
-
retryable;
|
|
3986
|
-
providerId;
|
|
3987
|
-
/** Canonical failure classification — see {@link ProviderErrorKind}. */
|
|
3988
|
-
kind;
|
|
3989
|
-
body;
|
|
3990
|
-
constructor(message, status, retryable, providerId, opts = {}) {
|
|
3991
|
-
const kind = opts.kind ?? classifyProviderError(status, opts.body, message);
|
|
3992
|
-
super({
|
|
3993
|
-
message,
|
|
3994
|
-
code: kindToCode(kind),
|
|
3995
|
-
subsystem: "provider",
|
|
3996
|
-
severity: status >= 500 ? "error" : "warning",
|
|
3997
|
-
recoverable: retryable,
|
|
3998
|
-
context: { providerId, status },
|
|
3999
|
-
cause: opts.cause
|
|
4000
|
-
});
|
|
4001
|
-
this.name = "ProviderError";
|
|
4002
|
-
this.status = status;
|
|
4003
|
-
this.retryable = retryable;
|
|
4004
|
-
this.providerId = providerId;
|
|
4005
|
-
this.kind = kind;
|
|
4006
|
-
this.body = opts.body;
|
|
4007
|
-
}
|
|
4008
|
-
/**
|
|
4009
|
-
* Render a one-line, user-facing description. Designed for the CLI/TUI
|
|
4010
|
-
* status line and the agent's retry warning. Avoids dumping raw JSON
|
|
4011
|
-
* (which is what users see today when a 529 lands and the log message
|
|
4012
|
-
* includes the full `{"type":"error",...}` body).
|
|
4013
|
-
*
|
|
4014
|
-
* Examples:
|
|
4015
|
-
* "minimax-coding-plan overloaded (529): High traffic detected. Upgrade for highspeed model. [req 06534785201de9c0…]"
|
|
4016
|
-
* "openai rate limited (429): Retry after 12s"
|
|
4017
|
-
* "anthropic invalid request (400): messages.0.role must be one of 'user'|'assistant'"
|
|
4018
|
-
* "groq HTTP 500 (server error)"
|
|
4019
|
-
*/
|
|
4020
|
-
describe() {
|
|
4021
|
-
const kind = describeStatus(this.status, this.body?.type);
|
|
4022
|
-
const head = `${this.providerId} ${kind}`;
|
|
4023
|
-
const detail = this.body?.message?.trim();
|
|
4024
|
-
const reqId = this.body?.requestId ? ` [req ${this.body.requestId.slice(0, 16)}${this.body.requestId.length > 16 ? "\u2026" : ""}]` : "";
|
|
4025
|
-
if (detail && detail.length > 0) {
|
|
4026
|
-
return `${head}: ${truncate(detail, 240)}${reqId}`;
|
|
4027
|
-
}
|
|
4028
|
-
return `${head}${reqId}`;
|
|
4029
|
-
}
|
|
4030
|
-
};
|
|
4031
|
-
function describeStatus(status, type) {
|
|
4032
|
-
if (status === 0) return "network error";
|
|
4033
|
-
if (status === 599) return `stream hang (${status})`;
|
|
4034
|
-
if (type === "overloaded_error" || status === 529) return `overloaded (${status})`;
|
|
4035
|
-
if (type === "rate_limit_error" || status === 429) return `rate limited (${status})`;
|
|
4036
|
-
if (type === "authentication_error" || status === 401) return `auth failed (${status})`;
|
|
4037
|
-
if (type === "permission_error" || status === 403) return `forbidden (${status})`;
|
|
4038
|
-
if (type === "not_found_error" || status === 404) return `not found (${status})`;
|
|
4039
|
-
if (type === "content_filter") return `content filtered (${status})`;
|
|
4040
|
-
if (type === "invalid_request_error" || status === 400) return `invalid request (${status})`;
|
|
4041
|
-
if (status === 408) return `timeout (${status})`;
|
|
4042
|
-
if (status >= 500 && status < 600) return `HTTP ${status} (server error)`;
|
|
4043
|
-
if (type) return `${type} (${status})`;
|
|
4044
|
-
return `HTTP ${status}`;
|
|
4045
|
-
}
|
|
4046
|
-
var KIND_TO_CODE = {
|
|
4047
|
-
network: ERROR_CODES.PROVIDER_NETWORK_ERROR,
|
|
4048
|
-
timeout: ERROR_CODES.PROVIDER_NETWORK_ERROR,
|
|
4049
|
-
rate_limit: ERROR_CODES.PROVIDER_RATE_LIMITED,
|
|
4050
|
-
auth: ERROR_CODES.PROVIDER_AUTH_FAILED,
|
|
4051
|
-
overloaded: ERROR_CODES.PROVIDER_OVERLOADED,
|
|
4052
|
-
context_overflow: ERROR_CODES.PROVIDER_CONTEXT_OVERFLOW,
|
|
4053
|
-
server: ERROR_CODES.PROVIDER_SERVER_ERROR,
|
|
4054
|
-
stream_hang: ERROR_CODES.PROVIDER_SERVER_ERROR,
|
|
4055
|
-
content_filter: ERROR_CODES.PROVIDER_INVALID_REQUEST,
|
|
4056
|
-
invalid_request: ERROR_CODES.PROVIDER_INVALID_REQUEST,
|
|
4057
|
-
unknown: ERROR_CODES.PROVIDER_INVALID_REQUEST
|
|
4058
|
-
};
|
|
4059
|
-
function kindToCode(kind) {
|
|
4060
|
-
return KIND_TO_CODE[kind];
|
|
4061
|
-
}
|
|
4062
|
-
|
|
4063
5059
|
// src/execution/regex-patterns.ts
|
|
4064
5060
|
var NETWORK_ERR_RE = /ECONN|ETIMEDOUT|ETIME|ENOTFOUND|EAI_AGAIN|fetch failed/i;
|
|
4065
5061
|
|
|
@@ -4219,6 +5215,10 @@ var DefaultErrorHandler = class {
|
|
|
4219
5215
|
return null;
|
|
4220
5216
|
}
|
|
4221
5217
|
};
|
|
5218
|
+
|
|
5219
|
+
// src/execution/eternal-autonomy.ts
|
|
5220
|
+
import { execFile } from "node:child_process";
|
|
5221
|
+
import { promisify } from "node:util";
|
|
4222
5222
|
var execFileP = promisify(execFile);
|
|
4223
5223
|
var BRAINSTORM_DONE = /* @__PURE__ */ Symbol("brainstorm-done");
|
|
4224
5224
|
var GOAL_COMPLETE_MARKER = /^\s*\[goal[_\s-]*complete\]\s*$/im;
|
|
@@ -4243,22 +5243,40 @@ var EternalAutonomyEngine = class {
|
|
|
4243
5243
|
currentCtrl = null;
|
|
4244
5244
|
iterationsSinceCompact = 0;
|
|
4245
5245
|
goalPath;
|
|
5246
|
+
/**
|
|
5247
|
+
* Emit a structured error. Uses the configured Logger when available;
|
|
5248
|
+
* falls back to console.error(JSON) so events are never silently dropped.
|
|
5249
|
+
*/
|
|
5250
|
+
logError(msg, ctx) {
|
|
5251
|
+
if (this.opts.logger) {
|
|
5252
|
+
this.opts.logger.error(msg, ctx);
|
|
5253
|
+
} else {
|
|
5254
|
+
console.error(JSON.stringify({ ...ctx, message: msg, timestamp: (/* @__PURE__ */ new Date()).toISOString() }));
|
|
5255
|
+
}
|
|
5256
|
+
}
|
|
4246
5257
|
/** Current engine state — readable for UIs. */
|
|
4247
5258
|
get currentState() {
|
|
4248
5259
|
return this.state;
|
|
4249
5260
|
}
|
|
5261
|
+
/**
|
|
5262
|
+
* Load the goal file with structured logging for parse/schema warnings.
|
|
5263
|
+
*/
|
|
5264
|
+
loadGoal() {
|
|
5265
|
+
return loadGoal(
|
|
5266
|
+
this.goalPath,
|
|
5267
|
+
this.opts.events,
|
|
5268
|
+
this.opts.logger ? (msg) => this.opts.logger.warn(msg) : void 0
|
|
5269
|
+
);
|
|
5270
|
+
}
|
|
4250
5271
|
/** Synchronously request stop. Resolves once the running iteration aborts. */
|
|
4251
5272
|
stop() {
|
|
4252
5273
|
this.stopRequested = true;
|
|
4253
5274
|
this.currentCtrl?.abort();
|
|
4254
5275
|
void this.persistEngineState("stopped").catch((err) => {
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
event: "engine.persist_state_failed",
|
|
4258
|
-
|
|
4259
|
-
context: { expectedState: "stopped" },
|
|
4260
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
4261
|
-
}));
|
|
5276
|
+
this.logError(
|
|
5277
|
+
"Engine persist state failed",
|
|
5278
|
+
{ event: "engine.persist_state_failed", message: toErrorMessage(err), context: { expectedState: "stopped" } }
|
|
5279
|
+
);
|
|
4262
5280
|
});
|
|
4263
5281
|
this.state = "stopped";
|
|
4264
5282
|
}
|
|
@@ -4314,7 +5332,7 @@ var EternalAutonomyEngine = class {
|
|
|
4314
5332
|
const emit = (stage) => {
|
|
4315
5333
|
this.opts.onStage?.(stage);
|
|
4316
5334
|
};
|
|
4317
|
-
const goal = await loadGoal(
|
|
5335
|
+
const goal = await this.loadGoal();
|
|
4318
5336
|
if (!goal) {
|
|
4319
5337
|
emit({ phase: "stopped" });
|
|
4320
5338
|
this.stopRequested = true;
|
|
@@ -4418,16 +5436,13 @@ var EternalAutonomyEngine = class {
|
|
|
4418
5436
|
emit({ phase: "reflect", status, note });
|
|
4419
5437
|
let iterationIndex = 0;
|
|
4420
5438
|
try {
|
|
4421
|
-
const reloaded = await loadGoal(
|
|
5439
|
+
const reloaded = await this.loadGoal();
|
|
4422
5440
|
iterationIndex = reloaded?.iterations ?? 0;
|
|
4423
5441
|
} catch (err) {
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
event: "autonomy.goal_reload_failed",
|
|
4427
|
-
|
|
4428
|
-
context: { goalPath: this.goalPath },
|
|
4429
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
4430
|
-
}));
|
|
5442
|
+
this.logError(
|
|
5443
|
+
"Goal reload failed",
|
|
5444
|
+
{ event: "autonomy.goal_reload_failed", message: toErrorMessage(err), context: { goalPath: this.goalPath } }
|
|
5445
|
+
);
|
|
4431
5446
|
}
|
|
4432
5447
|
this.opts.onIteration?.({
|
|
4433
5448
|
at: (this.opts.now?.() ?? /* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -4663,13 +5678,10 @@ ${lastFew}` : "No prior iterations yet.",
|
|
|
4663
5678
|
clearTimeout(timer);
|
|
4664
5679
|
}
|
|
4665
5680
|
} catch (err) {
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
event: "autonomy.brainstorm_failed",
|
|
4669
|
-
|
|
4670
|
-
context: { goal: goal.goal.slice(0, 100) },
|
|
4671
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
4672
|
-
}));
|
|
5681
|
+
this.logError(
|
|
5682
|
+
"Brainstorm failed",
|
|
5683
|
+
{ event: "autonomy.brainstorm_failed", message: toErrorMessage(err), context: { goal: goal.goal.slice(0, 100) } }
|
|
5684
|
+
);
|
|
4673
5685
|
return null;
|
|
4674
5686
|
}
|
|
4675
5687
|
}
|
|
@@ -4697,8 +5709,8 @@ ${recentJournal}` : "No prior iterations.",
|
|
|
4697
5709
|
" \u2022 When this iteration's Task is finished (real artifact / passing",
|
|
4698
5710
|
" test / applied diff / clean output), emit `[done]` on its own line.",
|
|
4699
5711
|
" \u2022 Do not stop on the first obstacle \u2014 try at least 3 distinct",
|
|
4700
|
-
" approaches before giving up. YOLO is active
|
|
4701
|
-
"
|
|
5712
|
+
" approaches before giving up. YOLO is active unless an explicit",
|
|
5713
|
+
" deny rule blocks the call.",
|
|
4702
5714
|
"",
|
|
4703
5715
|
"2. UPDATE TODO STATE (when Source is `todo`)",
|
|
4704
5716
|
" \u2022 Mark this todo `in_progress` via the todos tool before tool work.",
|
|
@@ -4752,7 +5764,7 @@ ${recentJournal}` : "No prior iterations.",
|
|
|
4752
5764
|
}
|
|
4753
5765
|
}
|
|
4754
5766
|
async appendIterationEntry(entry) {
|
|
4755
|
-
const current = await loadGoal(
|
|
5767
|
+
const current = await this.loadGoal();
|
|
4756
5768
|
if (!current) {
|
|
4757
5769
|
return;
|
|
4758
5770
|
}
|
|
@@ -4766,7 +5778,7 @@ ${recentJournal}` : "No prior iterations.",
|
|
|
4766
5778
|
* the counter to rotate past stuck todos once they cross `todoMaxAttempts`.
|
|
4767
5779
|
*/
|
|
4768
5780
|
async bumpTodoAttempt(todoId) {
|
|
4769
|
-
const current = await loadGoal(
|
|
5781
|
+
const current = await this.loadGoal();
|
|
4770
5782
|
if (!current) return;
|
|
4771
5783
|
const attempts = { ...current.todoAttempts ?? {} };
|
|
4772
5784
|
attempts[todoId] = (attempts[todoId] ?? 0) + 1;
|
|
@@ -4780,7 +5792,7 @@ ${recentJournal}` : "No prior iterations.",
|
|
|
4780
5792
|
* goal is already `completed`.
|
|
4781
5793
|
*/
|
|
4782
5794
|
async markGoalCompleted(action, note) {
|
|
4783
|
-
const current = await loadGoal(
|
|
5795
|
+
const current = await this.loadGoal();
|
|
4784
5796
|
if (!current) return;
|
|
4785
5797
|
if (current.goalState === "completed") return;
|
|
4786
5798
|
const withFlag = { ...current, goalState: "completed" };
|
|
@@ -4791,6 +5803,11 @@ ${recentJournal}` : "No prior iterations.",
|
|
|
4791
5803
|
note: note.slice(0, 240)
|
|
4792
5804
|
});
|
|
4793
5805
|
await saveGoal(this.goalPath, withEntry, this.opts.events);
|
|
5806
|
+
try {
|
|
5807
|
+
const { unlink: unlink4 } = await import("node:fs/promises");
|
|
5808
|
+
await unlink4(this.goalPath);
|
|
5809
|
+
} catch {
|
|
5810
|
+
}
|
|
4794
5811
|
this.opts.onEternalStop?.();
|
|
4795
5812
|
}
|
|
4796
5813
|
/**
|
|
@@ -4799,13 +5816,13 @@ ${recentJournal}` : "No prior iterations.",
|
|
|
4799
5816
|
* `onEternalStop` so the REPL returns to normal mode.
|
|
4800
5817
|
*/
|
|
4801
5818
|
async clearGoalManually(note) {
|
|
4802
|
-
const current = await loadGoal(
|
|
5819
|
+
const current = await this.loadGoal();
|
|
4803
5820
|
if (current) {
|
|
4804
5821
|
const abandoned = { ...current, goalState: "abandoned" };
|
|
4805
5822
|
await saveGoal(this.goalPath, abandoned, this.opts.events);
|
|
4806
5823
|
}
|
|
4807
5824
|
try {
|
|
4808
|
-
const { unlink: unlink4 } = await import(
|
|
5825
|
+
const { unlink: unlink4 } = await import("node:fs/promises");
|
|
4809
5826
|
await unlink4(this.goalPath);
|
|
4810
5827
|
} catch {
|
|
4811
5828
|
}
|
|
@@ -4847,7 +5864,23 @@ Recent work:
|
|
|
4847
5864
|
${recentJournal}` : ""
|
|
4848
5865
|
].join("\n"),
|
|
4849
5866
|
risk: "high",
|
|
4850
|
-
fallback: "continue"
|
|
5867
|
+
fallback: "continue",
|
|
5868
|
+
// Structured verdict — completion is control-plane input, decided by
|
|
5869
|
+
// exact option id rather than sniffing prose for "done"/"complete".
|
|
5870
|
+
options: [
|
|
5871
|
+
{
|
|
5872
|
+
id: "goal_complete",
|
|
5873
|
+
label: "The goal is complete \u2014 stop the eternal run",
|
|
5874
|
+
consequence: "The engine stops and the goal file is archived.",
|
|
5875
|
+
risk: "high"
|
|
5876
|
+
},
|
|
5877
|
+
{
|
|
5878
|
+
id: "keep_working",
|
|
5879
|
+
label: "Not complete yet \u2014 keep working",
|
|
5880
|
+
consequence: "The engine continues iterating on the goal.",
|
|
5881
|
+
risk: "low"
|
|
5882
|
+
}
|
|
5883
|
+
]
|
|
4851
5884
|
});
|
|
4852
5885
|
const summary = formatDecisionSummary(decision, {
|
|
4853
5886
|
id: `goal-done-${goal.iterations}`,
|
|
@@ -4867,8 +5900,7 @@ ${recentJournal}` : ""
|
|
|
4867
5900
|
return false;
|
|
4868
5901
|
}
|
|
4869
5902
|
if (decision.type === "answer") {
|
|
4870
|
-
|
|
4871
|
-
return text.includes("complete") || text.includes("done") || text.includes("yes");
|
|
5903
|
+
return decision.optionId === "goal_complete";
|
|
4872
5904
|
}
|
|
4873
5905
|
return true;
|
|
4874
5906
|
} catch {
|
|
@@ -4879,13 +5911,13 @@ ${recentJournal}` : ""
|
|
|
4879
5911
|
* Persist a progress update from the agent's [PROGRESS: N%] output.
|
|
4880
5912
|
*/
|
|
4881
5913
|
async updateProgress(progress, note) {
|
|
4882
|
-
const current = await loadGoal(
|
|
5914
|
+
const current = await this.loadGoal();
|
|
4883
5915
|
if (!current) return;
|
|
4884
5916
|
const updated = recordProgress(current, progress, note);
|
|
4885
5917
|
await saveGoal(this.goalPath, updated, this.opts.events);
|
|
4886
5918
|
}
|
|
4887
5919
|
async persistEngineState(state) {
|
|
4888
|
-
const current = await loadGoal(
|
|
5920
|
+
const current = await this.loadGoal();
|
|
4889
5921
|
if (!current) return;
|
|
4890
5922
|
if (current.engineState === state) return;
|
|
4891
5923
|
await saveGoal(this.goalPath, { ...current, engineState: state }, this.opts.events);
|
|
@@ -5063,8 +6095,8 @@ function resolveModelRuntime(settings, reasoning, capabilities) {
|
|
|
5063
6095
|
return { reasoning: void 0, cache: void 0, parameters: void 0, warnings };
|
|
5064
6096
|
}
|
|
5065
6097
|
const reasoningField = resolveReasoningForRequest(settings, reasoning, warnings);
|
|
5066
|
-
const cacheField = resolveCacheForRequest(settings);
|
|
5067
|
-
const paramsField = resolveParametersForRequest(settings.parameters, capabilities);
|
|
6098
|
+
const cacheField = resolveCacheForRequest(settings, warnings);
|
|
6099
|
+
const paramsField = resolveParametersForRequest(settings.parameters, capabilities, warnings);
|
|
5068
6100
|
return {
|
|
5069
6101
|
reasoning: reasoningField,
|
|
5070
6102
|
cache: cacheField,
|
|
@@ -5089,7 +6121,8 @@ function resolveReasoningForRequest(settings, rc, warnings) {
|
|
|
5089
6121
|
warnings.push('reasoning "off" requested, but this model does not support disabling thinking; the setting was omitted.');
|
|
5090
6122
|
}
|
|
5091
6123
|
} else if (cfg.mode === "on") {
|
|
5092
|
-
if (!capKnown)
|
|
6124
|
+
if (!capKnown) {
|
|
6125
|
+
} else if (!supportsReasoning && rc?.default === "disabled") {
|
|
5093
6126
|
warnings.push('reasoning "on" requested, but this model has reasoning disabled by default and does not advertise support; the setting was omitted.');
|
|
5094
6127
|
} else {
|
|
5095
6128
|
out.enabled = true;
|
|
@@ -5168,6 +6201,9 @@ function applyModelRuntime(req, opts) {
|
|
|
5168
6201
|
return next;
|
|
5169
6202
|
}
|
|
5170
6203
|
|
|
6204
|
+
// src/execution/parallel-eternal-engine.ts
|
|
6205
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
6206
|
+
|
|
5171
6207
|
// src/coordination/subagent-budget.ts
|
|
5172
6208
|
var TIMEOUT_PREEMPT_FRACTION = 0.85;
|
|
5173
6209
|
var DECISION_TIMEOUT_MS = 6e4;
|
|
@@ -5475,13 +6511,13 @@ var SubagentBudget = class _SubagentBudget {
|
|
|
5475
6511
|
if (!bus?.hasListenerFor("budget.threshold_reached")) {
|
|
5476
6512
|
return Promise.resolve("stop");
|
|
5477
6513
|
}
|
|
5478
|
-
return new Promise((
|
|
6514
|
+
return new Promise((resolve4) => {
|
|
5479
6515
|
let resolved = false;
|
|
5480
6516
|
const respond = (d) => {
|
|
5481
6517
|
if (resolved) return;
|
|
5482
6518
|
resolved = true;
|
|
5483
6519
|
clearTimeout(fallback);
|
|
5484
|
-
|
|
6520
|
+
resolve4(d);
|
|
5485
6521
|
};
|
|
5486
6522
|
const fallback = setTimeout(() => respond("stop"), _SubagentBudget.DECISION_TIMEOUT_MS);
|
|
5487
6523
|
const sessionId = this.currentSessionId();
|
|
@@ -5624,12 +6660,24 @@ var ToolCapabilities = {
|
|
|
5624
6660
|
SHELL_RESTRICTED: "shell.restricted",
|
|
5625
6661
|
/** Can run a restricted project formatter/linter-style command. */
|
|
5626
6662
|
SHELL_EXEC: "shell.exec",
|
|
6663
|
+
/** Can read files inside the project (and possibly outside via symlinks if not guarded). */
|
|
6664
|
+
FS_READ: "fs.read",
|
|
5627
6665
|
/** Can write / modify / delete files inside the project. */
|
|
5628
6666
|
FS_WRITE: "fs.write",
|
|
5629
6667
|
/** Can write files outside the current project root (very high risk). */
|
|
5630
6668
|
FS_WRITE_OUTSIDE_PROJECT: "fs.write.outside-project",
|
|
6669
|
+
/** Can perform outbound network requests. */
|
|
6670
|
+
NET_OUTBOUND: "net.outbound",
|
|
6671
|
+
/** Can mutate in-memory session todos only. */
|
|
6672
|
+
SESSION_TODO: "session.todo",
|
|
6673
|
+
/** Can mutate in-memory session mode only. */
|
|
6674
|
+
SESSION_MODE: "session.mode",
|
|
6675
|
+
/** Can inspect registered tool metadata. */
|
|
6676
|
+
TOOL_META: "tool.meta",
|
|
5631
6677
|
/** Can invoke arbitrary registered tools through a meta-tool. */
|
|
5632
6678
|
TOOL_MUTATE_ANY: "tool.mutate.any",
|
|
6679
|
+
/** Can read persistent memory. */
|
|
6680
|
+
MEMORY_READ: "memory.read",
|
|
5633
6681
|
/** Can write persistent memory. */
|
|
5634
6682
|
MEMORY_WRITE: "memory.write",
|
|
5635
6683
|
/** Can delete persistent memory. */
|
|
@@ -5638,6 +6686,16 @@ var ToolCapabilities = {
|
|
|
5638
6686
|
MCP_PROXY: "mcp.proxy",
|
|
5639
6687
|
/** Can spawn or manage subagents / multi-agent tasks. */
|
|
5640
6688
|
SUBAGENT_SPAWN: "subagent.spawn",
|
|
6689
|
+
/** Can inspect fleet/subagent coordination state without mutating it. */
|
|
6690
|
+
COORDINATION_FLEET_READ: "coordination.fleet.read",
|
|
6691
|
+
/** Can publish attributed, schema-checked events onto the fleet bus. */
|
|
6692
|
+
COORDINATION_FLEET_EMIT: "coordination.fleet.emit",
|
|
6693
|
+
/** Can submit a task-local structured result to the parent Director. */
|
|
6694
|
+
COORDINATION_RESULT_SUBMIT: "coordination.result.submit",
|
|
6695
|
+
/** Can read or write inter-agent mailbox messages. */
|
|
6696
|
+
COORDINATION_MAIL: "coordination.mail",
|
|
6697
|
+
/** Can schedule, inspect, or cancel in-session cron jobs. */
|
|
6698
|
+
COORDINATION_CRON: "coordination.cron",
|
|
5641
6699
|
/** Can mutate global or session configuration / trust state. */
|
|
5642
6700
|
CONFIG_MUTATE: "config.mutate",
|
|
5643
6701
|
/** Can install packages or run package managers with side effects. */
|
|
@@ -5657,6 +6715,22 @@ var DANGEROUS_FOR_SUBAGENTS = [
|
|
|
5657
6715
|
ToolCapabilities.CONFIG_MUTATE,
|
|
5658
6716
|
ToolCapabilities.PACKAGE_INSTALL
|
|
5659
6717
|
];
|
|
6718
|
+
var WIDE_SUBAGENT_CAPABILITIES = [
|
|
6719
|
+
ToolCapabilities.FS_READ,
|
|
6720
|
+
ToolCapabilities.FS_WRITE,
|
|
6721
|
+
ToolCapabilities.NET_OUTBOUND,
|
|
6722
|
+
ToolCapabilities.SESSION_TODO,
|
|
6723
|
+
ToolCapabilities.TOOL_META,
|
|
6724
|
+
ToolCapabilities.MEMORY_READ,
|
|
6725
|
+
ToolCapabilities.SHELL_ARBITRARY,
|
|
6726
|
+
ToolCapabilities.SHELL_RESTRICTED,
|
|
6727
|
+
ToolCapabilities.SHELL_EXEC,
|
|
6728
|
+
ToolCapabilities.PACKAGE_INSTALL,
|
|
6729
|
+
// Read-only fleet visibility (fleet_status) — peer awareness has no blast
|
|
6730
|
+
// radius and every fleet worker should coordinate around its peers.
|
|
6731
|
+
ToolCapabilities.COORDINATION_FLEET_READ,
|
|
6732
|
+
ToolCapabilities.COORDINATION_RESULT_SUBMIT
|
|
6733
|
+
];
|
|
5660
6734
|
function hasDangerousCapabilityForSubagents(toolOrCaps) {
|
|
5661
6735
|
if (!toolOrCaps) return false;
|
|
5662
6736
|
const input = toolOrCaps;
|
|
@@ -5681,15 +6755,17 @@ var MAX_FILES = 64;
|
|
|
5681
6755
|
var MAX_NEXT_STEPS = 12;
|
|
5682
6756
|
var MAX_ITEM_CHARS = 500;
|
|
5683
6757
|
function normalizeSubagentStructuredReport(value) {
|
|
5684
|
-
if (!
|
|
6758
|
+
if (!isRecord4(value)) return void 0;
|
|
5685
6759
|
const summary = nonEmptyString(value["summary"]);
|
|
5686
6760
|
const findings = stringArray(value["findings"]);
|
|
5687
6761
|
const filesExamined = stringArray(value["files_examined"]);
|
|
5688
6762
|
const nextSteps = stringArray(value["suggested_next_steps"]);
|
|
5689
6763
|
const confidence = value["confidence"];
|
|
6764
|
+
const completion = value["completion"];
|
|
6765
|
+
const remainingWork = optionalString(value["remaining_work"]);
|
|
5690
6766
|
if (!summary || summary.length > MAX_SUMMARY_CHARS || !findings || findings.length > MAX_FINDINGS || !filesExamined || filesExamined.length > MAX_FILES || !nextSteps || nextSteps.length > MAX_NEXT_STEPS || [...findings, ...filesExamined, ...nextSteps].some(
|
|
5691
6767
|
(item) => item.trim().length > MAX_ITEM_CHARS
|
|
5692
|
-
) || typeof confidence !== "number" || !Number.isFinite(confidence) || confidence < 0 || confidence > 1) {
|
|
6768
|
+
) || typeof confidence !== "number" || !Number.isFinite(confidence) || confidence < 0 || confidence > 1 || completion !== void 0 && completion !== "complete" && completion !== "partial" || completion === "partial" && !remainingWork || remainingWork !== void 0 && remainingWork.length > MAX_SUMMARY_CHARS) {
|
|
5693
6769
|
return void 0;
|
|
5694
6770
|
}
|
|
5695
6771
|
const report = {
|
|
@@ -5697,19 +6773,24 @@ function normalizeSubagentStructuredReport(value) {
|
|
|
5697
6773
|
findings: findings.map((item) => item.trim()).filter(Boolean),
|
|
5698
6774
|
files_examined: filesExamined.map((item) => item.trim()).filter(Boolean),
|
|
5699
6775
|
confidence,
|
|
5700
|
-
suggested_next_steps: nextSteps.map((item) => item.trim()).filter(Boolean)
|
|
6776
|
+
suggested_next_steps: nextSteps.map((item) => item.trim()).filter(Boolean),
|
|
6777
|
+
...completion === "complete" || completion === "partial" ? { completion } : {},
|
|
6778
|
+
...remainingWork ? { remaining_work: remainingWork } : {}
|
|
5701
6779
|
};
|
|
5702
6780
|
return JSON.stringify(report).length <= MAX_SUBAGENT_STRUCTURED_REPORT_CHARS ? report : void 0;
|
|
5703
6781
|
}
|
|
5704
6782
|
function readSubagentStructuredReport(ctx) {
|
|
5705
6783
|
return normalizeSubagentStructuredReport(ctx?.meta?.[SUBAGENT_STRUCTURED_REPORT_META_KEY]);
|
|
5706
6784
|
}
|
|
5707
|
-
function
|
|
6785
|
+
function isRecord4(value) {
|
|
5708
6786
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5709
6787
|
}
|
|
5710
6788
|
function nonEmptyString(value) {
|
|
5711
6789
|
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
5712
6790
|
}
|
|
6791
|
+
function optionalString(value) {
|
|
6792
|
+
return value === void 0 ? void 0 : nonEmptyString(value);
|
|
6793
|
+
}
|
|
5713
6794
|
function stringArray(value) {
|
|
5714
6795
|
return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : void 0;
|
|
5715
6796
|
}
|
|
@@ -5990,6 +7071,12 @@ var TOOLS = {
|
|
|
5990
7071
|
/** Web research. */
|
|
5991
7072
|
research: ["read", "grep", "glob", "search", "fetch", "mailbox"]
|
|
5992
7073
|
};
|
|
7074
|
+
|
|
7075
|
+
// src/coordination/agents/agent-prompts.ts
|
|
7076
|
+
import { readFileSync as readFileSync2, statSync as statSync2 } from "node:fs";
|
|
7077
|
+
import * as os2 from "node:os";
|
|
7078
|
+
import * as path6 from "node:path";
|
|
7079
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
5993
7080
|
var promptCache = /* @__PURE__ */ new Map();
|
|
5994
7081
|
var candidateCache = /* @__PURE__ */ new Map();
|
|
5995
7082
|
function agentPrompt(id) {
|
|
@@ -6001,7 +7088,7 @@ function agentPrompt(id) {
|
|
|
6001
7088
|
let resolved = "";
|
|
6002
7089
|
for (const dir of agentPromptDirCandidates(envDir)) {
|
|
6003
7090
|
try {
|
|
6004
|
-
resolved =
|
|
7091
|
+
resolved = readFileSync2(path6.join(dir, fileName), "utf8").trimEnd();
|
|
6005
7092
|
break;
|
|
6006
7093
|
} catch {
|
|
6007
7094
|
}
|
|
@@ -6010,20 +7097,20 @@ function agentPrompt(id) {
|
|
|
6010
7097
|
return resolved;
|
|
6011
7098
|
}
|
|
6012
7099
|
function agentPromptDirCandidates(envDir) {
|
|
6013
|
-
const globalRoot = process.env["WRONGSTACK_HOME"] ||
|
|
7100
|
+
const globalRoot = process.env["WRONGSTACK_HOME"] || path6.join(os2.homedir(), ".wrongstack");
|
|
6014
7101
|
const candKey = `${envDir}\0${globalRoot}`;
|
|
6015
7102
|
const cached = candidateCache.get(candKey);
|
|
6016
7103
|
if (cached !== void 0) return cached;
|
|
6017
|
-
const here =
|
|
7104
|
+
const here = path6.dirname(fileURLToPath3(import.meta.url));
|
|
6018
7105
|
const explicitDir = envDir || void 0;
|
|
6019
7106
|
const candidates = [
|
|
6020
|
-
...explicitDir ? [
|
|
6021
|
-
|
|
6022
|
-
|
|
6023
|
-
|
|
6024
|
-
|
|
6025
|
-
|
|
6026
|
-
|
|
7107
|
+
...explicitDir ? [path6.resolve(explicitDir)] : [],
|
|
7108
|
+
path6.join(globalRoot, "instructions", "agents"),
|
|
7109
|
+
path6.resolve(here, "../../../../instructions/agents"),
|
|
7110
|
+
path6.resolve(here, "../../../instructions/agents"),
|
|
7111
|
+
path6.resolve(here, "../../instructions/agents"),
|
|
7112
|
+
path6.resolve(here, "../instructions/agents"),
|
|
7113
|
+
path6.resolve(here, "instructions/agents")
|
|
6027
7114
|
];
|
|
6028
7115
|
const ordered = candidates.sort((a, b) => Number(!isDirectory2(a)) - Number(!isDirectory2(b)));
|
|
6029
7116
|
candidateCache.set(candKey, ordered);
|
|
@@ -6031,7 +7118,7 @@ function agentPromptDirCandidates(envDir) {
|
|
|
6031
7118
|
}
|
|
6032
7119
|
function isDirectory2(candidate) {
|
|
6033
7120
|
try {
|
|
6034
|
-
return
|
|
7121
|
+
return statSync2(candidate).isDirectory();
|
|
6035
7122
|
} catch {
|
|
6036
7123
|
return false;
|
|
6037
7124
|
}
|
|
@@ -7609,6 +8696,10 @@ async function dispatchAgent(task, opts = {}) {
|
|
|
7609
8696
|
};
|
|
7610
8697
|
}
|
|
7611
8698
|
|
|
8699
|
+
// src/coordination/multi-agent-coordinator.ts
|
|
8700
|
+
import { randomUUID } from "node:crypto";
|
|
8701
|
+
import { EventEmitter } from "node:events";
|
|
8702
|
+
|
|
7612
8703
|
// src/coordination/coordinator/error-classifier.ts
|
|
7613
8704
|
function classifySubagentError(err, hints = {}) {
|
|
7614
8705
|
if (err instanceof AgentError && err.cause) {
|
|
@@ -7689,46 +8780,39 @@ function providerErrorToSubagentError(err, message, cause) {
|
|
|
7689
8780
|
}
|
|
7690
8781
|
|
|
7691
8782
|
// src/coordination/fleet.ts
|
|
7692
|
-
({
|
|
7693
|
-
|
|
7694
|
-
|
|
7695
|
-
|
|
7696
|
-
|
|
7697
|
-
|
|
7698
|
-
|
|
7699
|
-
}
|
|
7700
|
-
|
|
7701
|
-
|
|
7702
|
-
|
|
7703
|
-
|
|
7704
|
-
(
|
|
7705
|
-
|
|
7706
|
-
|
|
7707
|
-
|
|
7708
|
-
|
|
7709
|
-
|
|
7710
|
-
|
|
7711
|
-
|
|
7712
|
-
|
|
7713
|
-
|
|
7714
|
-
// Budgets are set by the orchestrator per task — see fleet.ts header.
|
|
7715
|
-
});
|
|
7716
|
-
({
|
|
7717
|
-
prompt: agentPrompt("critic")
|
|
7718
|
-
// Budgets are set by the orchestrator per task — see fleet.ts header.
|
|
7719
|
-
});
|
|
7720
|
-
({
|
|
8783
|
+
function defineAgent(id, name, promptRole = id, provider) {
|
|
8784
|
+
return {
|
|
8785
|
+
id,
|
|
8786
|
+
name,
|
|
8787
|
+
role: id,
|
|
8788
|
+
prompt: agentPrompt(promptRole),
|
|
8789
|
+
...provider === void 0 ? {} : { provider }
|
|
8790
|
+
};
|
|
8791
|
+
}
|
|
8792
|
+
var AUDIT_LOG_AGENT = defineAgent("audit-log", "Audit Log");
|
|
8793
|
+
var BUG_HUNTER_AGENT = defineAgent("bug-hunter", "Bug Hunter");
|
|
8794
|
+
var REFACTOR_PLANNER_AGENT = defineAgent("refactor-planner", "Refactor Planner");
|
|
8795
|
+
var SECURITY_SCANNER_AGENT = defineAgent("security-scanner", "Security Scanner");
|
|
8796
|
+
var SHADOW_AGENT = defineAgent("shadow-agent", "Shadow");
|
|
8797
|
+
var CRITIC_AGENT = defineAgent("critic", "Critic");
|
|
8798
|
+
var FLEET_ROSTER = {
|
|
8799
|
+
"audit-log": AUDIT_LOG_AGENT,
|
|
8800
|
+
"bug-hunter": BUG_HUNTER_AGENT,
|
|
8801
|
+
"refactor-planner": REFACTOR_PLANNER_AGENT,
|
|
8802
|
+
"security-scanner": SECURITY_SCANNER_AGENT,
|
|
8803
|
+
critic: CRITIC_AGENT,
|
|
8804
|
+
"shadow-agent": SHADOW_AGENT,
|
|
7721
8805
|
...Object.fromEntries(
|
|
7722
8806
|
ALL_AGENT_DEFINITIONS.map((d) => [d.config.role, d.config])
|
|
7723
8807
|
)
|
|
7724
|
-
}
|
|
8808
|
+
};
|
|
7725
8809
|
var DEFAULT_IDLE_TIMEOUT_MS = 15 * 60 * 1e3;
|
|
7726
8810
|
var FLEET_ROSTER_BUDGETS = {
|
|
7727
8811
|
"audit-log": { timeoutMs: 7.5 * 60 * 60 * 1e3, maxIterations: 5e3, maxToolCalls: 15e3 },
|
|
7728
8812
|
"bug-hunter": { timeoutMs: 10 * 60 * 60 * 1e3, maxIterations: 8e3, maxToolCalls: 2e4 },
|
|
7729
8813
|
"refactor-planner": { timeoutMs: 7.5 * 60 * 60 * 1e3, maxIterations: 6e3, maxToolCalls: 18e3 },
|
|
7730
8814
|
"security-scanner": { timeoutMs: 10 * 60 * 60 * 1e3, maxIterations: 8e3, maxToolCalls: 2e4 },
|
|
7731
|
-
|
|
8815
|
+
critic: { timeoutMs: 5 * 60 * 60 * 1e3, maxIterations: 4e3, maxToolCalls: 12e3 },
|
|
7732
8816
|
"shadow-agent": {
|
|
7733
8817
|
idleTimeoutMs: DEFAULT_IDLE_TIMEOUT_MS,
|
|
7734
8818
|
maxIterations: 2e3,
|
|
@@ -7764,41 +8848,12 @@ function applyRosterBudget(cfg) {
|
|
|
7764
8848
|
maxCostUsd: cfg.maxCostUsd ?? defaultBudget.maxCostUsd
|
|
7765
8849
|
};
|
|
7766
8850
|
}
|
|
7767
|
-
var
|
|
7768
|
-
|
|
7769
|
-
|
|
7770
|
-
|
|
7771
|
-
|
|
7772
|
-
|
|
7773
|
-
};
|
|
7774
|
-
var GEMINI_CLI_AGENT = {
|
|
7775
|
-
id: "gemini-cli",
|
|
7776
|
-
name: "Gemini CLI",
|
|
7777
|
-
role: "gemini-cli",
|
|
7778
|
-
prompt: agentPrompt("acp-gemini-cli"),
|
|
7779
|
-
provider: "acp"
|
|
7780
|
-
};
|
|
7781
|
-
var COPILOT_AGENT = {
|
|
7782
|
-
id: "copilot",
|
|
7783
|
-
name: "GitHub Copilot",
|
|
7784
|
-
role: "copilot",
|
|
7785
|
-
prompt: agentPrompt("acp-copilot"),
|
|
7786
|
-
provider: "acp"
|
|
7787
|
-
};
|
|
7788
|
-
var OPENHANDS_AGENT = {
|
|
7789
|
-
id: "openhands",
|
|
7790
|
-
name: "OpenHands",
|
|
7791
|
-
role: "openhands",
|
|
7792
|
-
prompt: agentPrompt("acp-openhands"),
|
|
7793
|
-
provider: "acp"
|
|
7794
|
-
};
|
|
7795
|
-
var GOOSE_AGENT = {
|
|
7796
|
-
id: "goose",
|
|
7797
|
-
name: "Goose",
|
|
7798
|
-
role: "goose",
|
|
7799
|
-
prompt: agentPrompt("acp-goose"),
|
|
7800
|
-
provider: "acp"
|
|
7801
|
-
};
|
|
8851
|
+
var ALL_FLEET_AGENTS = Object.values(FLEET_ROSTER);
|
|
8852
|
+
var CLINE_AGENT = defineAgent("cline", "Cline", "acp-cline", "acp");
|
|
8853
|
+
var GEMINI_CLI_AGENT = defineAgent("gemini-cli", "Gemini CLI", "acp-gemini-cli", "acp");
|
|
8854
|
+
var COPILOT_AGENT = defineAgent("copilot", "GitHub Copilot", "acp-copilot", "acp");
|
|
8855
|
+
var OPENHANDS_AGENT = defineAgent("openhands", "OpenHands", "acp-openhands", "acp");
|
|
8856
|
+
var GOOSE_AGENT = defineAgent("goose", "Goose", "acp-goose", "acp");
|
|
7802
8857
|
var ACP_AGENTS = [
|
|
7803
8858
|
CLINE_AGENT,
|
|
7804
8859
|
GEMINI_CLI_AGENT,
|
|
@@ -7806,14 +8861,18 @@ var ACP_AGENTS = [
|
|
|
7806
8861
|
OPENHANDS_AGENT,
|
|
7807
8862
|
GOOSE_AGENT
|
|
7808
8863
|
];
|
|
7809
|
-
|
|
7810
|
-
|
|
7811
|
-
|
|
7812
|
-
|
|
7813
|
-
|
|
7814
|
-
({
|
|
8864
|
+
var ACP_AGENT_BUDGET = {
|
|
8865
|
+
timeoutMs: 10 * 60 * 60 * 1e3,
|
|
8866
|
+
maxIterations: 8e3,
|
|
8867
|
+
maxToolCalls: 2e4
|
|
8868
|
+
};
|
|
8869
|
+
for (const agent of ACP_AGENTS) {
|
|
8870
|
+
FLEET_ROSTER_BUDGETS[agent.role] = { ...ACP_AGENT_BUDGET };
|
|
8871
|
+
}
|
|
8872
|
+
var FLEET_ROSTER_WITHACP = {
|
|
8873
|
+
...FLEET_ROSTER,
|
|
7815
8874
|
...Object.fromEntries(ACP_AGENTS.map((a) => [a.role, a]))
|
|
7816
|
-
}
|
|
8875
|
+
};
|
|
7817
8876
|
|
|
7818
8877
|
// src/coordination/subagent-nicknames.ts
|
|
7819
8878
|
var NICKNAME_POOL = {
|
|
@@ -7872,7 +8931,7 @@ var NICKNAME_POOL = {
|
|
|
7872
8931
|
"mendeleev": { name: "Mendeleev", domain: "chemistry" }
|
|
7873
8932
|
};
|
|
7874
8933
|
var ALL_NICKNAMES = Object.entries(NICKNAME_POOL);
|
|
7875
|
-
Object.fromEntries(
|
|
8934
|
+
var NAME_TO_KEY = Object.fromEntries(
|
|
7876
8935
|
ALL_NICKNAMES.map(([key, entry]) => [entry.name, key])
|
|
7877
8936
|
);
|
|
7878
8937
|
var DOMAIN_PREFERENCES = {
|
|
@@ -8190,7 +9249,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
8190
9249
|
taskIds.map((id) => {
|
|
8191
9250
|
const cached = this.completedResults.find((r) => r.taskId === id);
|
|
8192
9251
|
if (cached) return cached;
|
|
8193
|
-
return new Promise((
|
|
9252
|
+
return new Promise((resolve4, reject) => {
|
|
8194
9253
|
const timeout = setTimeout(() => {
|
|
8195
9254
|
this.off("task.completed", handler);
|
|
8196
9255
|
reject(new Error(`awaitTasks timed out waiting for task "${id}"`));
|
|
@@ -8199,7 +9258,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
8199
9258
|
if (result.taskId === id) {
|
|
8200
9259
|
clearTimeout(timeout);
|
|
8201
9260
|
this.off("task.completed", handler);
|
|
8202
|
-
|
|
9261
|
+
resolve4(result);
|
|
8203
9262
|
}
|
|
8204
9263
|
};
|
|
8205
9264
|
this.on("task.completed", handler);
|
|
@@ -8224,13 +9283,13 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
8224
9283
|
const done = new Set(completed.map((r) => r.taskId));
|
|
8225
9284
|
return { completed, pending: taskIds.filter((id) => !done.has(id)) };
|
|
8226
9285
|
}
|
|
8227
|
-
return new Promise((
|
|
9286
|
+
return new Promise((resolve4) => {
|
|
8228
9287
|
let timer;
|
|
8229
9288
|
const handler = ({ result }) => {
|
|
8230
9289
|
if (!ids.has(result.taskId)) return;
|
|
8231
9290
|
if (timer) clearTimeout(timer);
|
|
8232
9291
|
this.off("task.completed", handler);
|
|
8233
|
-
|
|
9292
|
+
resolve4({
|
|
8234
9293
|
completed: [result],
|
|
8235
9294
|
pending: taskIds.filter((id) => id !== result.taskId)
|
|
8236
9295
|
});
|
|
@@ -8238,7 +9297,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
8238
9297
|
if (opts?.timeoutMs !== void 0) {
|
|
8239
9298
|
timer = setTimeout(() => {
|
|
8240
9299
|
this.off("task.completed", handler);
|
|
8241
|
-
|
|
9300
|
+
resolve4({ completed: [], pending: [...taskIds], timedOut: true });
|
|
8242
9301
|
}, opts.timeoutMs);
|
|
8243
9302
|
}
|
|
8244
9303
|
this.on("task.completed", handler);
|
|
@@ -8520,12 +9579,12 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
8520
9579
|
}
|
|
8521
9580
|
return new Promise((resolveDecision) => {
|
|
8522
9581
|
let settled = false;
|
|
8523
|
-
const
|
|
9582
|
+
const resolve4 = (d) => {
|
|
8524
9583
|
if (settled) return;
|
|
8525
9584
|
settled = true;
|
|
8526
9585
|
resolveDecision(d);
|
|
8527
9586
|
};
|
|
8528
|
-
const fallback = setTimeout(() =>
|
|
9587
|
+
const fallback = setTimeout(() => resolve4("stop"), DECISION_TIMEOUT_MS);
|
|
8529
9588
|
const sessionId = this.currentSessionId();
|
|
8530
9589
|
budget._events?.emit("budget.threshold_reached", {
|
|
8531
9590
|
...sessionId ? { sessionId } : {},
|
|
@@ -8543,11 +9602,11 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
8543
9602
|
// disagreeing, resolves as a stop). Async grants still resolve.
|
|
8544
9603
|
extend: (extra) => {
|
|
8545
9604
|
clearTimeout(fallback);
|
|
8546
|
-
queueMicrotask(() =>
|
|
9605
|
+
queueMicrotask(() => resolve4({ extend: extra }));
|
|
8547
9606
|
},
|
|
8548
9607
|
deny: () => {
|
|
8549
9608
|
clearTimeout(fallback);
|
|
8550
|
-
|
|
9609
|
+
resolve4("stop");
|
|
8551
9610
|
}
|
|
8552
9611
|
});
|
|
8553
9612
|
});
|
|
@@ -8683,8 +9742,9 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
8683
9742
|
}
|
|
8684
9743
|
const subagent = this.subagents.get(result.subagentId);
|
|
8685
9744
|
if (subagent && subagent.status !== "stopped") {
|
|
8686
|
-
result.status === "failed" || result.status === "timeout";
|
|
9745
|
+
const failed = result.status === "failed" || result.status === "timeout";
|
|
8687
9746
|
subagent.status = "idle";
|
|
9747
|
+
void failed;
|
|
8688
9748
|
subagent.currentTask = void 0;
|
|
8689
9749
|
if (subagent.abortController.signal.aborted) {
|
|
8690
9750
|
subagent.abortController = new AbortController();
|
|
@@ -8802,6 +9862,27 @@ var ParallelEternalEngine = class {
|
|
|
8802
9862
|
agentFactory;
|
|
8803
9863
|
dispatchEnabled;
|
|
8804
9864
|
dispatchClassifier;
|
|
9865
|
+
/**
|
|
9866
|
+
* Emit a structured error. Uses the configured Logger when available;
|
|
9867
|
+
* falls back to console.error(JSON) so events are never silently dropped.
|
|
9868
|
+
*/
|
|
9869
|
+
logError(msg, ctx) {
|
|
9870
|
+
if (this.opts.logger) {
|
|
9871
|
+
this.opts.logger.error(msg, ctx);
|
|
9872
|
+
} else {
|
|
9873
|
+
console.error(JSON.stringify({ ...ctx, message: msg, timestamp: (/* @__PURE__ */ new Date()).toISOString() }));
|
|
9874
|
+
}
|
|
9875
|
+
}
|
|
9876
|
+
/**
|
|
9877
|
+
* Load the goal file with structured logging for parse/schema warnings.
|
|
9878
|
+
*/
|
|
9879
|
+
loadGoal() {
|
|
9880
|
+
return loadGoal(
|
|
9881
|
+
this.goalPath,
|
|
9882
|
+
this.opts.events,
|
|
9883
|
+
this.opts.logger ? (msg) => this.opts.logger.warn(msg) : void 0
|
|
9884
|
+
);
|
|
9885
|
+
}
|
|
8805
9886
|
get currentState() {
|
|
8806
9887
|
return this.state;
|
|
8807
9888
|
}
|
|
@@ -8814,13 +9895,10 @@ var ParallelEternalEngine = class {
|
|
|
8814
9895
|
stop() {
|
|
8815
9896
|
this.stopRequested = true;
|
|
8816
9897
|
void this.persistState("stopped").catch((err) => {
|
|
8817
|
-
|
|
8818
|
-
|
|
8819
|
-
event: "engine.persist_state_failed",
|
|
8820
|
-
|
|
8821
|
-
context: { expectedState: "stopped" },
|
|
8822
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
8823
|
-
}));
|
|
9898
|
+
this.logError(
|
|
9899
|
+
"Engine persist state failed",
|
|
9900
|
+
{ event: "engine.persist_state_failed", message: toErrorMessage(err), context: { expectedState: "stopped" } }
|
|
9901
|
+
);
|
|
8824
9902
|
});
|
|
8825
9903
|
this.state = "stopped";
|
|
8826
9904
|
}
|
|
@@ -8833,7 +9911,7 @@ var ParallelEternalEngine = class {
|
|
|
8833
9911
|
this.state = "running";
|
|
8834
9912
|
await this.persistState("running");
|
|
8835
9913
|
const config = {
|
|
8836
|
-
coordinatorId: `parallel-${
|
|
9914
|
+
coordinatorId: `parallel-${randomUUID2().slice(0, 8)}`,
|
|
8837
9915
|
maxConcurrent: this.slots,
|
|
8838
9916
|
doneCondition: { type: "all_tasks_done" }
|
|
8839
9917
|
};
|
|
@@ -8874,7 +9952,7 @@ var ParallelEternalEngine = class {
|
|
|
8874
9952
|
this.opts.onStage?.(stage);
|
|
8875
9953
|
};
|
|
8876
9954
|
this.iterations++;
|
|
8877
|
-
const goal = await loadGoal(
|
|
9955
|
+
const goal = await this.loadGoal();
|
|
8878
9956
|
if (!goal) {
|
|
8879
9957
|
this.stopRequested = true;
|
|
8880
9958
|
emit({ phase: "stopped" });
|
|
@@ -8887,7 +9965,7 @@ var ParallelEternalEngine = class {
|
|
|
8887
9965
|
}
|
|
8888
9966
|
if (!this.coordinator) {
|
|
8889
9967
|
const config = {
|
|
8890
|
-
coordinatorId: `parallel-${
|
|
9968
|
+
coordinatorId: `parallel-${randomUUID2().slice(0, 8)}`,
|
|
8891
9969
|
maxConcurrent: this.slots,
|
|
8892
9970
|
doneCondition: { type: "all_tasks_done" }
|
|
8893
9971
|
};
|
|
@@ -8961,8 +10039,7 @@ ${recentJournal}` : "No prior iterations.",
|
|
|
8961
10039
|
"\u2500\u2500 EXECUTION PROTOCOL \u2500\u2500",
|
|
8962
10040
|
"\u2022 Execute the assigned task end-to-end using multiple tool calls.",
|
|
8963
10041
|
"\u2022 Emit `[done]` on its own line when the task is complete.",
|
|
8964
|
-
"\u2022 Do not ask before
|
|
8965
|
-
"\u2022 If a destructive-gated confirmation appears, wait for the permission flow.",
|
|
10042
|
+
"\u2022 Do not ask before tool use \u2014 YOLO is active unless an explicit deny rule blocks the call.",
|
|
8966
10043
|
"\u2022 If the overall Mission is accomplished, emit `[GOAL_COMPLETE]` followed by a verification recipe.",
|
|
8967
10044
|
"\u2022 Keep output concise \u2014 summarize findings, do not transcribe files."
|
|
8968
10045
|
].join("\n");
|
|
@@ -8974,7 +10051,7 @@ ${recentJournal}` : "No prior iterations.",
|
|
|
8974
10051
|
const task = expectDefined(tasks[i]);
|
|
8975
10052
|
const route = routes[i] ?? null;
|
|
8976
10053
|
const subagentId = `parallel-${this.iterations}-${i}`;
|
|
8977
|
-
const taskId =
|
|
10054
|
+
const taskId = randomUUID2();
|
|
8978
10055
|
const personaLine = route ? `Acting agent: ${route.definition.config.name} \u2014 ${route.definition.capability.summary}
|
|
8979
10056
|
` : "";
|
|
8980
10057
|
const spec = {
|
|
@@ -9019,13 +10096,10 @@ ${personaLine}Task: ${task}
|
|
|
9019
10096
|
taskIds.push(taskId);
|
|
9020
10097
|
await coordinator.assign(spec);
|
|
9021
10098
|
} catch (err) {
|
|
9022
|
-
|
|
9023
|
-
|
|
9024
|
-
event: "parallel_engine.spawn_failed",
|
|
9025
|
-
|
|
9026
|
-
context: { slot: i, task, subagentId },
|
|
9027
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
9028
|
-
}));
|
|
10099
|
+
this.logError(
|
|
10100
|
+
"Parallel spawn failed",
|
|
10101
|
+
{ event: "parallel_engine.spawn_failed", message: toErrorMessage(err), context: { slot: i, task, subagentId } }
|
|
10102
|
+
);
|
|
9029
10103
|
}
|
|
9030
10104
|
})()
|
|
9031
10105
|
);
|
|
@@ -9051,13 +10125,10 @@ ${personaLine}Task: ${task}
|
|
|
9051
10125
|
clearTimeout(timer);
|
|
9052
10126
|
}
|
|
9053
10127
|
} catch (err) {
|
|
9054
|
-
|
|
9055
|
-
|
|
9056
|
-
event: "parallel_engine.brainstorm_results_failed",
|
|
9057
|
-
|
|
9058
|
-
context: { slotCount, taskIds },
|
|
9059
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
9060
|
-
}));
|
|
10128
|
+
this.logError(
|
|
10129
|
+
"Brainstorm results failed",
|
|
10130
|
+
{ event: "parallel_engine.brainstorm_results_failed", message: toErrorMessage(err), context: { slotCount, taskIds } }
|
|
10131
|
+
);
|
|
9061
10132
|
results = coordinator.results().slice(-taskIds.length);
|
|
9062
10133
|
}
|
|
9063
10134
|
await Promise.allSettled(subagentIds.map((id) => coordinator.remove(id)));
|
|
@@ -9092,13 +10163,10 @@ ${personaLine}Task: ${task}
|
|
|
9092
10163
|
}
|
|
9093
10164
|
}
|
|
9094
10165
|
} catch (err) {
|
|
9095
|
-
|
|
9096
|
-
|
|
9097
|
-
event: "parallel_engine.git_status_failed",
|
|
9098
|
-
|
|
9099
|
-
context: { projectRoot: this.opts.projectRoot },
|
|
9100
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
9101
|
-
}));
|
|
10166
|
+
this.logError(
|
|
10167
|
+
"Git status failed",
|
|
10168
|
+
{ event: "parallel_engine.git_status_failed", message: toErrorMessage(err), context: { projectRoot: this.opts.projectRoot } }
|
|
10169
|
+
);
|
|
9102
10170
|
}
|
|
9103
10171
|
}
|
|
9104
10172
|
if (tasks.length < this.slots) {
|
|
@@ -9109,8 +10177,8 @@ ${personaLine}Task: ${task}
|
|
|
9109
10177
|
return tasks.length > 0 ? tasks.slice(0, this.slots) : null;
|
|
9110
10178
|
}
|
|
9111
10179
|
async readGitStatus() {
|
|
9112
|
-
const { execFile: execFile2 } = await import(
|
|
9113
|
-
const { promisify: promisify2 } = await import(
|
|
10180
|
+
const { execFile: execFile2 } = await import("node:child_process");
|
|
10181
|
+
const { promisify: promisify2 } = await import("node:util");
|
|
9114
10182
|
const execFileP2 = promisify2(execFile2);
|
|
9115
10183
|
const { stdout } = await execFileP2("git", ["status", "--porcelain"], {
|
|
9116
10184
|
cwd: this.opts.projectRoot,
|
|
@@ -9179,7 +10247,7 @@ ${lastFew}` : "No prior iterations.",
|
|
|
9179
10247
|
// Helpers
|
|
9180
10248
|
// -------------------------------------------------------------------------
|
|
9181
10249
|
async appendIterationEntry(entry) {
|
|
9182
|
-
const current = await loadGoal(
|
|
10250
|
+
const current = await this.loadGoal();
|
|
9183
10251
|
if (!current) return;
|
|
9184
10252
|
const updated = appendJournal(current, entry);
|
|
9185
10253
|
await saveGoal(this.goalPath, updated, this.opts.events);
|
|
@@ -9194,12 +10262,15 @@ ${lastFew}` : "No prior iterations.",
|
|
|
9194
10262
|
await this.appendIterationEntry({ source: "manual", task, status: "failure", note });
|
|
9195
10263
|
}
|
|
9196
10264
|
async persistState(state) {
|
|
9197
|
-
const current = await loadGoal(
|
|
10265
|
+
const current = await this.loadGoal();
|
|
9198
10266
|
if (!current) return;
|
|
9199
10267
|
if (current.engineState === state) return;
|
|
9200
10268
|
await saveGoal(this.goalPath, { ...current, engineState: state }, this.opts.events);
|
|
9201
10269
|
}
|
|
9202
10270
|
};
|
|
10271
|
+
|
|
10272
|
+
// src/execution/retry-policy.ts
|
|
10273
|
+
import { randomInt } from "node:crypto";
|
|
9203
10274
|
var MAX_RETRY_AFTER_MS = 6e4;
|
|
9204
10275
|
var MAX_ATTEMPTS_BY_KIND = {
|
|
9205
10276
|
rate_limit: 5,
|
|
@@ -9653,6 +10724,10 @@ Summarize the following message range:`;
|
|
|
9653
10724
|
}
|
|
9654
10725
|
};
|
|
9655
10726
|
|
|
10727
|
+
// src/execution/skill-loader.ts
|
|
10728
|
+
import * as fs4 from "node:fs/promises";
|
|
10729
|
+
import * as path7 from "node:path";
|
|
10730
|
+
|
|
9656
10731
|
// src/skills/foreign-sources.ts
|
|
9657
10732
|
var FOREIGN_SKILL_TOOLS = [
|
|
9658
10733
|
{ id: "agents", subdir: "skills" },
|
|
@@ -9768,6 +10843,56 @@ function isValidSkillNameFormat(name) {
|
|
|
9768
10843
|
|
|
9769
10844
|
// src/skills/limits.ts
|
|
9770
10845
|
var SKILL_LIMITS = {
|
|
10846
|
+
/**
|
|
10847
|
+
* Per-skill body cap when injecting a full skill body into the system prompt
|
|
10848
|
+
* (eager mode), and when returning a skill body from the `skill` tool.
|
|
10849
|
+
* ~4k tokens. Oversized bodies are truncated at a paragraph boundary.
|
|
10850
|
+
*
|
|
10851
|
+
* Consumers: `system-prompt-builder.capSkillBody`, `skill` tool body return.
|
|
10852
|
+
*/
|
|
10853
|
+
MAX_SKILL_BODY_CHARS: 16e3,
|
|
10854
|
+
/**
|
|
10855
|
+
* Per-resource cap when the `skill` tool loads a bundled file
|
|
10856
|
+
* (`scripts/`, `references/`, `assets/`). ~8k tokens.
|
|
10857
|
+
*
|
|
10858
|
+
* Consumer: `skill` tool `loadResource`.
|
|
10859
|
+
*/
|
|
10860
|
+
MAX_RESOURCE_CHARS: 32e3,
|
|
10861
|
+
/**
|
|
10862
|
+
* Maximum number of bundled resource paths the `skill` tool lists in one
|
|
10863
|
+
* response. Caps a pathological skill (huge `assets/` tree) from blowing up
|
|
10864
|
+
* the tool result.
|
|
10865
|
+
*
|
|
10866
|
+
* Consumer: `skill` tool resource listing.
|
|
10867
|
+
*/
|
|
10868
|
+
MAX_LISTED_RESOURCES: 100,
|
|
10869
|
+
/**
|
|
10870
|
+
* Max size of a single installed skill file (SKILL.md or a bundled resource).
|
|
10871
|
+
* Guards against a malicious registry skill shipping a multi-MB blob that
|
|
10872
|
+
* then flows into the prompt. 100KB.
|
|
10873
|
+
*
|
|
10874
|
+
* Consumer: `SkillInstaller.install` / `importFromDir`.
|
|
10875
|
+
*/
|
|
10876
|
+
MAX_SKILL_FILE_SIZE: 100 * 1024,
|
|
10877
|
+
/**
|
|
10878
|
+
* Max size of a GitHub tarball downloaded by the skill installer. Guards
|
|
10879
|
+
* against a repo accidentally (or maliciously) shipping a giant tarball that
|
|
10880
|
+
* would be extracted into a temp dir. 50MB.
|
|
10881
|
+
*
|
|
10882
|
+
* Consumer: `downloadGitHubTarball`.
|
|
10883
|
+
*/
|
|
10884
|
+
MAX_TARBALL_SIZE: 50 * 1024 * 1024,
|
|
10885
|
+
/**
|
|
10886
|
+
* Default total char budget for skill bodies injected in eager mode when
|
|
10887
|
+
* `config.skills.eagerMaxChars` is unset. ~6k tokens. Skills are injected
|
|
10888
|
+
* highest-priority first; once the budget is exhausted the remaining skills
|
|
10889
|
+
* are listed as a manifest the agent loads via the `skill` tool. Set very
|
|
10890
|
+
* high to effectively disable budgeting.
|
|
10891
|
+
*
|
|
10892
|
+
* Consumer: `DefaultSystemPromptBuilder.buildMemoryAndSkills` (default for
|
|
10893
|
+
* `skillEagerMaxChars`).
|
|
10894
|
+
*/
|
|
10895
|
+
EAGER_DEFAULT_MAX_CHARS: 24e3,
|
|
9771
10896
|
/**
|
|
9772
10897
|
* Auto-compact body limits (the token-saving fallback used when a skill has
|
|
9773
10898
|
* no hand-crafted `SKILL.save.md`). The Overview and Rules sections are
|
|
@@ -9777,7 +10902,24 @@ var SKILL_LIMITS = {
|
|
|
9777
10902
|
*/
|
|
9778
10903
|
COMPACT_OVERVIEW_MAX: 200,
|
|
9779
10904
|
COMPACT_RULES_MAX: 350,
|
|
9780
|
-
COMPACT_TOTAL_MAX: 450
|
|
10905
|
+
COMPACT_TOTAL_MAX: 450,
|
|
10906
|
+
/**
|
|
10907
|
+
* Max length of a skill name (agentskills.io spec). Enforced by the
|
|
10908
|
+
* frontmatter validator's format regex plus this length bound.
|
|
10909
|
+
*
|
|
10910
|
+
* Consumer: `isValidSkillNameFormat`.
|
|
10911
|
+
*/
|
|
10912
|
+
SKILL_NAME_MAX_LEN: 64,
|
|
10913
|
+
/**
|
|
10914
|
+
* Soft line limit for a SKILL.md body, per the bundled `skill-creator` rule.
|
|
10915
|
+
* Not enforced in code (a skill can exceed it) — surfaced by `/skill-gen
|
|
10916
|
+
* validate` and the `skill-creator` skill as guidance to move deep material
|
|
10917
|
+
* into `references/`.
|
|
10918
|
+
*
|
|
10919
|
+
* Consumer: `skill-creator` skill, `/skill-gen validate` advisory.
|
|
10920
|
+
*/
|
|
10921
|
+
SKILL_BODY_LINE_LIMIT: 500
|
|
10922
|
+
};
|
|
9781
10923
|
|
|
9782
10924
|
// src/execution/skill-loader.ts
|
|
9783
10925
|
function stripFrontmatter2(raw) {
|
|
@@ -9814,7 +10956,7 @@ async function entryIsDirectory(dir, entry) {
|
|
|
9814
10956
|
if (entry.isDirectory()) return true;
|
|
9815
10957
|
if (entry.isSymbolicLink()) {
|
|
9816
10958
|
try {
|
|
9817
|
-
return (await
|
|
10959
|
+
return (await fs4.stat(path7.join(dir, entry.name))).isDirectory();
|
|
9818
10960
|
} catch {
|
|
9819
10961
|
return false;
|
|
9820
10962
|
}
|
|
@@ -9835,7 +10977,7 @@ var DefaultSkillLoader = class {
|
|
|
9835
10977
|
for (const tool of FOREIGN_SKILL_TOOLS) {
|
|
9836
10978
|
if (!foreignIds.includes(tool.id)) continue;
|
|
9837
10979
|
dirs.push({
|
|
9838
|
-
dir:
|
|
10980
|
+
dir: path7.join(root, "." + tool.id, tool.subdir),
|
|
9839
10981
|
source: "foreign",
|
|
9840
10982
|
originTool: tool.id
|
|
9841
10983
|
});
|
|
@@ -9857,12 +10999,12 @@ var DefaultSkillLoader = class {
|
|
|
9857
10999
|
const seen = /* @__PURE__ */ new Set();
|
|
9858
11000
|
for (const { dir, source, originTool } of this.dirs) {
|
|
9859
11001
|
try {
|
|
9860
|
-
const entries = await
|
|
11002
|
+
const entries = await fs4.readdir(dir, { withFileTypes: true });
|
|
9861
11003
|
for (const e of entries) {
|
|
9862
11004
|
if (!await entryIsDirectory(dir, e)) continue;
|
|
9863
|
-
const skillFile =
|
|
11005
|
+
const skillFile = path7.join(dir, e.name, "SKILL.md");
|
|
9864
11006
|
try {
|
|
9865
|
-
const raw = await
|
|
11007
|
+
const raw = await fs4.readFile(skillFile, "utf8");
|
|
9866
11008
|
const fm = parseSkillFrontmatter(raw);
|
|
9867
11009
|
if (!fm.name || !fm.description) continue;
|
|
9868
11010
|
if (!isValidSkillNameFormat(fm.name)) continue;
|
|
@@ -9934,7 +11076,7 @@ var DefaultSkillLoader = class {
|
|
|
9934
11076
|
if (cached !== void 0) return cached;
|
|
9935
11077
|
const m = await this.find(name);
|
|
9936
11078
|
if (!m) throw new Error(`Skill "${name}" not found`);
|
|
9937
|
-
const body = await
|
|
11079
|
+
const body = await fs4.readFile(m.path, "utf8");
|
|
9938
11080
|
this.bodyCache.set(key, body);
|
|
9939
11081
|
return body;
|
|
9940
11082
|
}
|
|
@@ -9944,12 +11086,12 @@ var DefaultSkillLoader = class {
|
|
|
9944
11086
|
if (cached !== void 0) return cached;
|
|
9945
11087
|
const m = await this.find(name);
|
|
9946
11088
|
if (!m) throw new Error(`Skill "${name}" not found`);
|
|
9947
|
-
const savePath =
|
|
11089
|
+
const savePath = path7.join(path7.dirname(m.path), "SKILL.save.md");
|
|
9948
11090
|
let result;
|
|
9949
11091
|
try {
|
|
9950
|
-
result = await
|
|
11092
|
+
result = await fs4.readFile(savePath, "utf8");
|
|
9951
11093
|
} catch {
|
|
9952
|
-
const full = await
|
|
11094
|
+
const full = await fs4.readFile(m.path, "utf8");
|
|
9953
11095
|
const body = stripFrontmatter2(full);
|
|
9954
11096
|
const compact = compactSkillBody(body);
|
|
9955
11097
|
if (compact) {
|
|
@@ -9975,6 +11117,14 @@ function parseDescriptionFromText(desc) {
|
|
|
9975
11117
|
}
|
|
9976
11118
|
return { trigger, scope };
|
|
9977
11119
|
}
|
|
11120
|
+
|
|
11121
|
+
// src/execution/prompt-loader.ts
|
|
11122
|
+
import * as fs6 from "node:fs/promises";
|
|
11123
|
+
import * as path9 from "node:path";
|
|
11124
|
+
|
|
11125
|
+
// src/storage/prompt-store.ts
|
|
11126
|
+
import * as fs5 from "node:fs/promises";
|
|
11127
|
+
import * as path8 from "node:path";
|
|
9978
11128
|
var SCHEMA_VERSION = 2;
|
|
9979
11129
|
function migratePromptEntry(raw) {
|
|
9980
11130
|
if (!raw || typeof raw !== "object") return null;
|
|
@@ -10035,12 +11185,12 @@ var DefaultPromptStore = class {
|
|
|
10035
11185
|
await ensureDir(this.dir);
|
|
10036
11186
|
const entries = [];
|
|
10037
11187
|
try {
|
|
10038
|
-
const files = await
|
|
11188
|
+
const files = await fs5.readdir(this.dir);
|
|
10039
11189
|
for (const file of files) {
|
|
10040
11190
|
if (!file.endsWith(".json")) continue;
|
|
10041
11191
|
try {
|
|
10042
11192
|
const raw = JSON.parse(
|
|
10043
|
-
await
|
|
11193
|
+
await fs5.readFile(path8.join(this.dir, file), "utf8")
|
|
10044
11194
|
);
|
|
10045
11195
|
const migrated = migratePromptEntry(raw.entry);
|
|
10046
11196
|
if (migrated) entries.push(migrated);
|
|
@@ -10054,9 +11204,9 @@ var DefaultPromptStore = class {
|
|
|
10054
11204
|
);
|
|
10055
11205
|
}
|
|
10056
11206
|
async get(id) {
|
|
10057
|
-
const file =
|
|
11207
|
+
const file = path8.join(this.dir, `${id}.json`);
|
|
10058
11208
|
try {
|
|
10059
|
-
const raw = JSON.parse(await
|
|
11209
|
+
const raw = JSON.parse(await fs5.readFile(file, "utf8"));
|
|
10060
11210
|
return migratePromptEntry(raw.entry);
|
|
10061
11211
|
} catch {
|
|
10062
11212
|
return null;
|
|
@@ -10064,14 +11214,14 @@ var DefaultPromptStore = class {
|
|
|
10064
11214
|
}
|
|
10065
11215
|
async save(entry) {
|
|
10066
11216
|
await ensureDir(this.dir);
|
|
10067
|
-
const file =
|
|
11217
|
+
const file = path8.join(this.dir, `${entry.id}.json`);
|
|
10068
11218
|
const raw = { version: SCHEMA_VERSION, entry };
|
|
10069
11219
|
await atomicWrite(file, JSON.stringify(raw, null, 2));
|
|
10070
11220
|
}
|
|
10071
11221
|
async delete(id) {
|
|
10072
|
-
const file =
|
|
11222
|
+
const file = path8.join(this.dir, `${id}.json`);
|
|
10073
11223
|
try {
|
|
10074
|
-
await
|
|
11224
|
+
await fs5.unlink(file);
|
|
10075
11225
|
return true;
|
|
10076
11226
|
} catch {
|
|
10077
11227
|
return false;
|
|
@@ -10158,7 +11308,7 @@ var DefaultPromptLoader = class {
|
|
|
10158
11308
|
constructor(opts) {
|
|
10159
11309
|
this.projectStore = typeof opts.paths.inProjectPrompts === "string" ? new DefaultPromptStore(opts.paths.inProjectPrompts) : void 0;
|
|
10160
11310
|
this.userStore = typeof opts.paths.globalPrompts === "string" ? new DefaultPromptStore(opts.paths.globalPrompts) : void 0;
|
|
10161
|
-
this.builtinDir = opts.bundledDir ?
|
|
11311
|
+
this.builtinDir = opts.bundledDir ? path9.join(opts.bundledDir, "prompts") : void 0;
|
|
10162
11312
|
}
|
|
10163
11313
|
async list() {
|
|
10164
11314
|
if (this.cache) return this.cache;
|
|
@@ -10271,7 +11421,7 @@ var DefaultPromptLoader = class {
|
|
|
10271
11421
|
const files = await walkJson(dir);
|
|
10272
11422
|
for (const file of files) {
|
|
10273
11423
|
try {
|
|
10274
|
-
const parsed = JSON.parse(await
|
|
11424
|
+
const parsed = JSON.parse(await fs6.readFile(file, "utf8"));
|
|
10275
11425
|
const migrated = migratePromptEntry(parsed);
|
|
10276
11426
|
if (migrated) out.push({ ...migrated, source: "builtin" });
|
|
10277
11427
|
} catch {
|
|
@@ -10285,12 +11435,12 @@ async function walkJson(dir) {
|
|
|
10285
11435
|
const out = [];
|
|
10286
11436
|
let entries;
|
|
10287
11437
|
try {
|
|
10288
|
-
entries = await
|
|
11438
|
+
entries = await fs6.readdir(dir, { withFileTypes: true });
|
|
10289
11439
|
} catch {
|
|
10290
11440
|
return out;
|
|
10291
11441
|
}
|
|
10292
11442
|
for (const e of entries) {
|
|
10293
|
-
const full =
|
|
11443
|
+
const full = path9.join(dir, e.name);
|
|
10294
11444
|
if (e.isDirectory()) {
|
|
10295
11445
|
out.push(...await walkJson(full));
|
|
10296
11446
|
} else if (e.name.endsWith(".json") && e.name !== "index.json" && e.name !== "schema.json") {
|
|
@@ -10474,6 +11624,12 @@ function readPolicy(ctx) {
|
|
|
10474
11624
|
return candidate;
|
|
10475
11625
|
}
|
|
10476
11626
|
|
|
11627
|
+
// src/execution/tool-executor.ts
|
|
11628
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
11629
|
+
import { isDeepStrictEqual } from "node:util";
|
|
11630
|
+
import * as fs7 from "node:fs/promises";
|
|
11631
|
+
import * as path10 from "node:path";
|
|
11632
|
+
|
|
10477
11633
|
// src/types/tool-markers.ts
|
|
10478
11634
|
var MALFORMED_ARG_MARKERS = ["__raw", "__raw_arguments", "_raw"];
|
|
10479
11635
|
|
|
@@ -10693,12 +11849,33 @@ ${errorDetails}`,
|
|
|
10693
11849
|
}
|
|
10694
11850
|
if (effectivePermission === "confirm") {
|
|
10695
11851
|
if (this.opts.confirmAwaiter) {
|
|
10696
|
-
const
|
|
11852
|
+
const awaiter = this.opts.confirmAwaiter;
|
|
11853
|
+
const choice = await new Promise(
|
|
11854
|
+
(resolve4, reject) => {
|
|
11855
|
+
const signal = ctx.signal;
|
|
11856
|
+
const onAbort = () => resolve4("abort");
|
|
11857
|
+
if (signal.aborted) {
|
|
11858
|
+
resolve4("abort");
|
|
11859
|
+
return;
|
|
11860
|
+
}
|
|
11861
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
11862
|
+
awaiter(tool, use.input, use.id, tool.name).then(
|
|
11863
|
+
(c) => {
|
|
11864
|
+
signal.removeEventListener("abort", onAbort);
|
|
11865
|
+
resolve4(c);
|
|
11866
|
+
},
|
|
11867
|
+
(e) => {
|
|
11868
|
+
signal.removeEventListener("abort", onAbort);
|
|
11869
|
+
reject(e);
|
|
11870
|
+
}
|
|
11871
|
+
);
|
|
11872
|
+
}
|
|
11873
|
+
);
|
|
10697
11874
|
if (choice !== "yes" && choice !== "always") {
|
|
10698
11875
|
const result = {
|
|
10699
11876
|
type: "tool_result",
|
|
10700
11877
|
tool_use_id: use.id,
|
|
10701
|
-
content: `Tool "${tool.name}" denied by user.`,
|
|
11878
|
+
content: choice === "abort" ? `Tool "${tool.name}" was not executed \u2014 the run was aborted while awaiting confirmation.` : `Tool "${tool.name}" denied by user.`,
|
|
10702
11879
|
is_error: true
|
|
10703
11880
|
};
|
|
10704
11881
|
budget = this.budgetForString(result.content, budget);
|
|
@@ -10804,6 +11981,9 @@ ${post.additionalContext}`;
|
|
|
10804
11981
|
is_error: true
|
|
10805
11982
|
};
|
|
10806
11983
|
budget = this.budgetForString(result.content, budget);
|
|
11984
|
+
void category;
|
|
11985
|
+
void retryable;
|
|
11986
|
+
void detail;
|
|
10807
11987
|
return { result, tool, durationMs: 0 };
|
|
10808
11988
|
}
|
|
10809
11989
|
};
|
|
@@ -10903,22 +12083,40 @@ ${post.additionalContext}`;
|
|
|
10903
12083
|
if (parentSignal.reason instanceof Error) throw parentSignal.reason;
|
|
10904
12084
|
throw new Error(typeof parentSignal.reason === "string" ? parentSignal.reason : "aborted");
|
|
10905
12085
|
}
|
|
10906
|
-
const
|
|
10907
|
-
|
|
10908
|
-
|
|
10909
|
-
|
|
10910
|
-
|
|
10911
|
-
|
|
12086
|
+
const combined = tool.managesOwnTimeout ? parentSignal : AbortSignal.any([
|
|
12087
|
+
parentSignal,
|
|
12088
|
+
AbortSignal.timeout(
|
|
12089
|
+
clampTimeoutMs(tool.timeoutMs ?? this.iterationTimeoutMs, this.maxToolTimeoutMs)
|
|
12090
|
+
)
|
|
12091
|
+
]);
|
|
10912
12092
|
let output;
|
|
12093
|
+
const toolPromise = typeof tool.executeStream === "function" ? this.runStreamedTool(tool, input, ctx, combined, toolUseId) : (async () => tool.execute(input, ctx, { signal: combined }))();
|
|
12094
|
+
toolPromise.catch(() => {
|
|
12095
|
+
});
|
|
10913
12096
|
try {
|
|
10914
|
-
output =
|
|
12097
|
+
output = await new Promise((resolve4, reject) => {
|
|
12098
|
+
const onAbort = () => {
|
|
12099
|
+
setTimeout(() => reject(abortReasonToError(combined.reason)), 0);
|
|
12100
|
+
};
|
|
12101
|
+
combined.addEventListener("abort", onAbort, { once: true });
|
|
12102
|
+
toolPromise.then(
|
|
12103
|
+
(v) => {
|
|
12104
|
+
combined.removeEventListener("abort", onAbort);
|
|
12105
|
+
resolve4(v);
|
|
12106
|
+
},
|
|
12107
|
+
(e) => {
|
|
12108
|
+
combined.removeEventListener("abort", onAbort);
|
|
12109
|
+
reject(e);
|
|
12110
|
+
}
|
|
12111
|
+
);
|
|
12112
|
+
});
|
|
10915
12113
|
} catch (err) {
|
|
10916
12114
|
if (combined.aborted) await this.runToolCleanup(tool, input, ctx);
|
|
10917
12115
|
throw err;
|
|
10918
12116
|
}
|
|
10919
12117
|
if (combined.aborted) {
|
|
10920
12118
|
await this.runToolCleanup(tool, input, ctx);
|
|
10921
|
-
throw
|
|
12119
|
+
throw abortReasonToError(combined.reason);
|
|
10922
12120
|
}
|
|
10923
12121
|
return output;
|
|
10924
12122
|
}
|
|
@@ -11079,6 +12277,9 @@ function clampTimeoutMs(timeoutMs, maxTimeoutMs) {
|
|
|
11079
12277
|
const finiteMax = Number.isFinite(maxTimeoutMs) && maxTimeoutMs > 0 ? maxTimeoutMs : fallback;
|
|
11080
12278
|
return Math.max(1, Math.min(finiteTimeout, finiteMax));
|
|
11081
12279
|
}
|
|
12280
|
+
function abortReasonToError(reason) {
|
|
12281
|
+
return reason instanceof Error ? reason : new Error(typeof reason === "string" ? reason : "tool timeout");
|
|
12282
|
+
}
|
|
11082
12283
|
function hasMalformedArguments(input) {
|
|
11083
12284
|
if (!input || typeof input !== "object" || Array.isArray(input)) return false;
|
|
11084
12285
|
const obj = input;
|
|
@@ -11177,12 +12378,12 @@ async function maybePersistLargeToolOutput(toolName, content, budget) {
|
|
|
11177
12378
|
return content;
|
|
11178
12379
|
}
|
|
11179
12380
|
try {
|
|
11180
|
-
const dir =
|
|
11181
|
-
await
|
|
12381
|
+
const dir = path10.join(wstackGlobalRoot(), "tool-output");
|
|
12382
|
+
await fs7.mkdir(dir, { recursive: true });
|
|
11182
12383
|
const safeTool = toolName.replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 40) || "tool";
|
|
11183
12384
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
11184
|
-
const filePath =
|
|
11185
|
-
await
|
|
12385
|
+
const filePath = path10.join(dir, `${stamp}-${safeTool}-${randomUUID3()}.log`);
|
|
12386
|
+
await fs7.writeFile(filePath, content, "utf8");
|
|
11186
12387
|
const marker = `[full tool output: ${bytes} bytes at ${filePath}; read/grep that file selectively instead of re-running or requesting more output]`;
|
|
11187
12388
|
const fixedBytes = Buffer.byteLength(marker + TOOL_OUTPUT_ARTIFACT_OMISSION, "utf8");
|
|
11188
12389
|
const previewBytes = Math.min(
|
|
@@ -11230,7 +12431,64 @@ function sliceUtf8Suffix(text, maxBytes) {
|
|
|
11230
12431
|
if (first >= 56320 && first <= 57343) start++;
|
|
11231
12432
|
return text.slice(start);
|
|
11232
12433
|
}
|
|
11233
|
-
|
|
11234
|
-
|
|
12434
|
+
export {
|
|
12435
|
+
AutoCompactionMiddleware,
|
|
12436
|
+
AutonomousRunner,
|
|
12437
|
+
BRAIN_EVALUATION_CASE_VERSION,
|
|
12438
|
+
COUNCIL_REFUSE_OPTION_ID,
|
|
12439
|
+
DEFAULT_RECOVERY_STRATEGIES,
|
|
12440
|
+
DefaultDesignKitLoader,
|
|
12441
|
+
DefaultErrorHandler,
|
|
12442
|
+
DefaultPromptLoader,
|
|
12443
|
+
DefaultRetryPolicy,
|
|
12444
|
+
DefaultSkillLoader,
|
|
12445
|
+
DoneConditionChecker,
|
|
12446
|
+
EternalAutonomyEngine,
|
|
12447
|
+
HybridCompactor,
|
|
12448
|
+
IntelligentCompactor,
|
|
12449
|
+
ParallelEternalEngine,
|
|
12450
|
+
SelectiveCompactor,
|
|
12451
|
+
ToolExecutor,
|
|
12452
|
+
_resetDesignKitLoaderMemo,
|
|
12453
|
+
_resetDesignRulesCache,
|
|
12454
|
+
activateDesign,
|
|
12455
|
+
applyModelRuntime,
|
|
12456
|
+
assembleBrainTiers,
|
|
12457
|
+
buildBrainUserMessage,
|
|
12458
|
+
buildGoalPreamble,
|
|
12459
|
+
buildRecoveryStrategies,
|
|
12460
|
+
clearActiveKit,
|
|
12461
|
+
clearPersistedActiveKit,
|
|
12462
|
+
completeBrainLlm,
|
|
12463
|
+
createAutonomyBrain,
|
|
12464
|
+
createBrainRuntime,
|
|
12465
|
+
createCouncilBrainArbiter,
|
|
12466
|
+
createStrategyCompactor,
|
|
12467
|
+
createTieredBrainArbiter,
|
|
12468
|
+
designProjectDir,
|
|
12469
|
+
detectFrontendFile,
|
|
12470
|
+
detectFrontendIntent,
|
|
12471
|
+
formatDecisionSummary,
|
|
12472
|
+
getDesignKitLoader,
|
|
12473
|
+
getDesignState,
|
|
12474
|
+
installDesignStudioMiddleware,
|
|
12475
|
+
loadActiveKit,
|
|
12476
|
+
loadProjectDesignRules,
|
|
12477
|
+
makeAutonomyPromptContributor,
|
|
12478
|
+
makeDesignDetectToolCallMiddleware,
|
|
12479
|
+
makeDesignDetectUserInputMiddleware,
|
|
12480
|
+
makeDesignStudioRequestMiddleware,
|
|
12481
|
+
mergeModelRuntime,
|
|
12482
|
+
parseOptionDecision,
|
|
12483
|
+
recordKitChoice,
|
|
12484
|
+
renderPrompt,
|
|
12485
|
+
resolveBrainConfigDefaults,
|
|
12486
|
+
resolveBundledDesignKitsDir,
|
|
12487
|
+
resolveCacheForRequest,
|
|
12488
|
+
resolveModelRuntime,
|
|
12489
|
+
resolveReasoningForRequest,
|
|
12490
|
+
runBrainEvaluation,
|
|
12491
|
+
setActiveKit,
|
|
12492
|
+
validateBrainEvaluationCase
|
|
12493
|
+
};
|
|
11235
12494
|
//# sourceMappingURL=index.js.map
|
|
11236
|
-
//# sourceMappingURL=index.js.map
|