attocode 0.2.4 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +88 -1
- package/dist/src/adapters.d.ts +39 -1
- package/dist/src/adapters.d.ts.map +1 -1
- package/dist/src/adapters.js +201 -16
- package/dist/src/adapters.js.map +1 -1
- package/dist/src/agent/agent-builder.d.ts +117 -0
- package/dist/src/agent/agent-builder.d.ts.map +1 -0
- package/dist/src/agent/agent-builder.js +204 -0
- package/dist/src/agent/agent-builder.js.map +1 -0
- package/dist/src/agent/feature-initializer.d.ts +80 -0
- package/dist/src/agent/feature-initializer.d.ts.map +1 -0
- package/dist/src/agent/feature-initializer.js +676 -0
- package/dist/src/agent/feature-initializer.js.map +1 -0
- package/dist/src/agent/index.d.ts +13 -0
- package/dist/src/agent/index.d.ts.map +1 -0
- package/dist/src/agent/index.js +13 -0
- package/dist/src/agent/index.js.map +1 -0
- package/dist/src/agent/message-builder.d.ts +50 -0
- package/dist/src/agent/message-builder.d.ts.map +1 -0
- package/dist/src/agent/message-builder.js +176 -0
- package/dist/src/agent/message-builder.js.map +1 -0
- package/dist/src/agent/session-api.d.ts +94 -0
- package/dist/src/agent/session-api.d.ts.map +1 -0
- package/dist/src/agent/session-api.js +264 -0
- package/dist/src/agent/session-api.js.map +1 -0
- package/dist/src/agent-tools/lsp-file-tools.d.ts +1 -1
- package/dist/src/agent-tools/lsp-file-tools.d.ts.map +1 -1
- package/dist/src/agent-tools/lsp-file-tools.js +17 -13
- package/dist/src/agent-tools/lsp-file-tools.js.map +1 -1
- package/dist/src/agent.d.ts +26 -117
- package/dist/src/agent.d.ts.map +1 -1
- package/dist/src/agent.js +239 -1249
- package/dist/src/agent.js.map +1 -1
- package/dist/src/analysis/feedback-loop.d.ts.map +1 -1
- package/dist/src/analysis/feedback-loop.js +13 -9
- package/dist/src/analysis/feedback-loop.js.map +1 -1
- package/dist/src/analysis/index.d.ts +1 -1
- package/dist/src/analysis/index.d.ts.map +1 -1
- package/dist/src/analysis/index.js +1 -1
- package/dist/src/analysis/index.js.map +1 -1
- package/dist/src/analysis/prompt-templates.d.ts.map +1 -1
- package/dist/src/analysis/prompt-templates.js.map +1 -1
- package/dist/src/analysis/trace-summary.d.ts.map +1 -1
- package/dist/src/analysis/trace-summary.js +25 -9
- package/dist/src/analysis/trace-summary.js.map +1 -1
- package/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +4 -2
- package/dist/src/cli.js.map +1 -1
- package/dist/src/commands/agents-commands.d.ts.map +1 -1
- package/dist/src/commands/agents-commands.js +3 -3
- package/dist/src/commands/agents-commands.js.map +1 -1
- package/dist/src/commands/handler.d.ts.map +1 -1
- package/dist/src/commands/handler.js +68 -44
- package/dist/src/commands/handler.js.map +1 -1
- package/dist/src/commands/init-commands.d.ts.map +1 -1
- package/dist/src/commands/init-commands.js +8 -10
- package/dist/src/commands/init-commands.js.map +1 -1
- package/dist/src/commands/init.js +17 -17
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/skills-commands.d.ts.map +1 -1
- package/dist/src/commands/skills-commands.js +10 -7
- package/dist/src/commands/skills-commands.js.map +1 -1
- package/dist/src/commands/types.d.ts.map +1 -1
- package/dist/src/config/config-manager.d.ts.map +1 -1
- package/dist/src/config/config-manager.js +4 -1
- package/dist/src/config/config-manager.js.map +1 -1
- package/dist/src/config/index.d.ts +1 -1
- package/dist/src/config/index.d.ts.map +1 -1
- package/dist/src/config/schema.d.ts +6 -6
- package/dist/src/config/schema.d.ts.map +1 -1
- package/dist/src/config/schema.js +6 -2
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/core/agent-state-machine.d.ts.map +1 -1
- package/dist/src/core/agent-state-machine.js +5 -2
- package/dist/src/core/agent-state-machine.js.map +1 -1
- package/dist/src/core/completion-analyzer.d.ts.map +1 -1
- package/dist/src/core/completion-analyzer.js +2 -2
- package/dist/src/core/completion-analyzer.js.map +1 -1
- package/dist/src/core/execution-loop.d.ts +172 -1
- package/dist/src/core/execution-loop.d.ts.map +1 -1
- package/dist/src/core/execution-loop.js +597 -360
- package/dist/src/core/execution-loop.js.map +1 -1
- package/dist/src/core/index.d.ts +2 -2
- package/dist/src/core/index.d.ts.map +1 -1
- package/dist/src/core/index.js +1 -1
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/core/queues/event-queue.d.ts.map +1 -1
- package/dist/src/core/queues/event-queue.js.map +1 -1
- package/dist/src/core/response-handler.d.ts.map +1 -1
- package/dist/src/core/response-handler.js +20 -10
- package/dist/src/core/response-handler.js.map +1 -1
- package/dist/src/core/subagent-spawner.d.ts.map +1 -1
- package/dist/src/core/subagent-spawner.js +98 -59
- package/dist/src/core/subagent-spawner.js.map +1 -1
- package/dist/src/core/tool-executor.d.ts.map +1 -1
- package/dist/src/core/tool-executor.js +63 -27
- package/dist/src/core/tool-executor.js.map +1 -1
- package/dist/src/core/types.d.ts +1 -0
- package/dist/src/core/types.d.ts.map +1 -1
- package/dist/src/core/types.js.map +1 -1
- package/dist/src/costs/model-registry.js +6 -6
- package/dist/src/costs/model-registry.js.map +1 -1
- package/dist/src/defaults.d.ts.map +1 -1
- package/dist/src/defaults.js +67 -20
- package/dist/src/defaults.js.map +1 -1
- package/dist/src/errors/index.d.ts.map +1 -1
- package/dist/src/errors/index.js +6 -8
- package/dist/src/errors/index.js.map +1 -1
- package/dist/src/first-run.d.ts.map +1 -1
- package/dist/src/first-run.js +11 -11
- package/dist/src/first-run.js.map +1 -1
- package/dist/src/integrations/agents/agent-registry.d.ts +262 -0
- package/dist/src/integrations/agents/agent-registry.d.ts.map +1 -0
- package/dist/src/integrations/agents/agent-registry.js +686 -0
- package/dist/src/integrations/agents/agent-registry.js.map +1 -0
- package/dist/src/integrations/agents/async-subagent.d.ts +135 -0
- package/dist/src/integrations/agents/async-subagent.d.ts.map +1 -0
- package/dist/src/integrations/agents/async-subagent.js +211 -0
- package/dist/src/integrations/agents/async-subagent.js.map +1 -0
- package/dist/src/integrations/agents/complexity-classifier.d.ts +86 -0
- package/dist/src/integrations/agents/complexity-classifier.d.ts.map +1 -0
- package/dist/src/integrations/agents/complexity-classifier.js +264 -0
- package/dist/src/integrations/agents/complexity-classifier.js.map +1 -0
- package/dist/src/integrations/agents/delegation-protocol.d.ts +86 -0
- package/dist/src/integrations/agents/delegation-protocol.d.ts.map +1 -0
- package/dist/src/integrations/agents/delegation-protocol.js +127 -0
- package/dist/src/integrations/agents/delegation-protocol.js.map +1 -0
- package/dist/src/integrations/agents/multi-agent.d.ts +150 -0
- package/dist/src/integrations/agents/multi-agent.d.ts.map +1 -0
- package/dist/src/integrations/agents/multi-agent.js +302 -0
- package/dist/src/integrations/agents/multi-agent.js.map +1 -0
- package/dist/src/integrations/agents/result-synthesizer.d.ts +389 -0
- package/dist/src/integrations/agents/result-synthesizer.d.ts.map +1 -0
- package/dist/src/integrations/agents/result-synthesizer.js +953 -0
- package/dist/src/integrations/agents/result-synthesizer.js.map +1 -0
- package/dist/src/integrations/agents/shared-blackboard.d.ts +406 -0
- package/dist/src/integrations/agents/shared-blackboard.d.ts.map +1 -0
- package/dist/src/integrations/agents/shared-blackboard.js +757 -0
- package/dist/src/integrations/agents/shared-blackboard.js.map +1 -0
- package/dist/src/integrations/agents/subagent-output-store.d.ts +91 -0
- package/dist/src/integrations/agents/subagent-output-store.d.ts.map +1 -0
- package/dist/src/integrations/agents/subagent-output-store.js +256 -0
- package/dist/src/integrations/agents/subagent-output-store.js.map +1 -0
- package/dist/src/integrations/budget/budget-pool.d.ts +115 -0
- package/dist/src/integrations/budget/budget-pool.d.ts.map +1 -0
- package/dist/src/integrations/budget/budget-pool.js +201 -0
- package/dist/src/integrations/budget/budget-pool.js.map +1 -0
- package/dist/src/integrations/budget/cancellation.d.ts +229 -0
- package/dist/src/integrations/budget/cancellation.d.ts.map +1 -0
- package/dist/src/integrations/budget/cancellation.js +534 -0
- package/dist/src/integrations/budget/cancellation.js.map +1 -0
- package/dist/src/integrations/budget/dynamic-budget.d.ts +81 -0
- package/dist/src/integrations/budget/dynamic-budget.d.ts.map +1 -0
- package/dist/src/integrations/budget/dynamic-budget.js +149 -0
- package/dist/src/integrations/budget/dynamic-budget.js.map +1 -0
- package/dist/src/integrations/budget/economics.d.ts +435 -0
- package/dist/src/integrations/budget/economics.d.ts.map +1 -0
- package/dist/src/integrations/budget/economics.js +1039 -0
- package/dist/src/integrations/budget/economics.js.map +1 -0
- package/dist/src/integrations/budget/injection-budget.d.ts +71 -0
- package/dist/src/integrations/budget/injection-budget.d.ts.map +1 -0
- package/dist/src/integrations/budget/injection-budget.js +137 -0
- package/dist/src/integrations/budget/injection-budget.js.map +1 -0
- package/dist/src/integrations/budget/loop-detector.d.ts +105 -0
- package/dist/src/integrations/budget/loop-detector.d.ts.map +1 -0
- package/dist/src/integrations/budget/loop-detector.js +304 -0
- package/dist/src/integrations/budget/loop-detector.js.map +1 -0
- package/dist/src/integrations/budget/phase-tracker.d.ts +114 -0
- package/dist/src/integrations/budget/phase-tracker.d.ts.map +1 -0
- package/dist/src/integrations/budget/phase-tracker.js +265 -0
- package/dist/src/integrations/budget/phase-tracker.js.map +1 -0
- package/dist/src/integrations/budget/resources.d.ts +182 -0
- package/dist/src/integrations/budget/resources.d.ts.map +1 -0
- package/dist/src/integrations/budget/resources.js +362 -0
- package/dist/src/integrations/budget/resources.js.map +1 -0
- package/dist/src/integrations/context/auto-compaction.d.ts +210 -0
- package/dist/src/integrations/context/auto-compaction.d.ts.map +1 -0
- package/dist/src/integrations/context/auto-compaction.js +485 -0
- package/dist/src/integrations/context/auto-compaction.js.map +1 -0
- package/dist/src/integrations/context/code-analyzer.d.ts +71 -0
- package/dist/src/integrations/context/code-analyzer.d.ts.map +1 -0
- package/dist/src/integrations/context/code-analyzer.js +445 -0
- package/dist/src/integrations/context/code-analyzer.js.map +1 -0
- package/dist/src/integrations/context/code-selector.d.ts +78 -0
- package/dist/src/integrations/context/code-selector.d.ts.map +1 -0
- package/dist/src/integrations/context/code-selector.js +668 -0
- package/dist/src/integrations/context/code-selector.js.map +1 -0
- package/dist/src/integrations/context/codebase-ast.d.ts +138 -0
- package/dist/src/integrations/context/codebase-ast.d.ts.map +1 -0
- package/dist/src/integrations/context/codebase-ast.js +881 -0
- package/dist/src/integrations/context/codebase-ast.js.map +1 -0
- package/dist/src/integrations/context/codebase-context.d.ts +473 -0
- package/dist/src/integrations/context/codebase-context.d.ts.map +1 -0
- package/dist/src/integrations/context/codebase-context.js +694 -0
- package/dist/src/integrations/context/codebase-context.js.map +1 -0
- package/dist/src/integrations/context/compaction.d.ts +191 -0
- package/dist/src/integrations/context/compaction.d.ts.map +1 -0
- package/dist/src/integrations/context/compaction.js +391 -0
- package/dist/src/integrations/context/compaction.js.map +1 -0
- package/dist/src/integrations/context/context-engineering.d.ts +274 -0
- package/dist/src/integrations/context/context-engineering.d.ts.map +1 -0
- package/dist/src/integrations/context/context-engineering.js +437 -0
- package/dist/src/integrations/context/context-engineering.js.map +1 -0
- package/dist/src/integrations/context/file-cache.d.ts +97 -0
- package/dist/src/integrations/context/file-cache.d.ts.map +1 -0
- package/dist/src/integrations/context/file-cache.js +218 -0
- package/dist/src/integrations/context/file-cache.js.map +1 -0
- package/dist/src/integrations/context/semantic-cache.d.ts +178 -0
- package/dist/src/integrations/context/semantic-cache.d.ts.map +1 -0
- package/dist/src/integrations/context/semantic-cache.js +377 -0
- package/dist/src/integrations/context/semantic-cache.js.map +1 -0
- package/dist/src/integrations/index.d.ts +72 -68
- package/dist/src/integrations/index.d.ts.map +1 -1
- package/dist/src/integrations/index.js +76 -68
- package/dist/src/integrations/index.js.map +1 -1
- package/dist/src/integrations/lsp/lsp.d.ts +196 -0
- package/dist/src/integrations/lsp/lsp.d.ts.map +1 -0
- package/dist/src/integrations/lsp/lsp.js +583 -0
- package/dist/src/integrations/lsp/lsp.js.map +1 -0
- package/dist/src/integrations/mcp/mcp-client.d.ts +279 -0
- package/dist/src/integrations/mcp/mcp-client.d.ts.map +1 -0
- package/dist/src/integrations/mcp/mcp-client.js +776 -0
- package/dist/src/integrations/mcp/mcp-client.js.map +1 -0
- package/dist/src/integrations/mcp/mcp-custom-tools.d.ts +102 -0
- package/dist/src/integrations/mcp/mcp-custom-tools.d.ts.map +1 -0
- package/dist/src/integrations/mcp/mcp-custom-tools.js +232 -0
- package/dist/src/integrations/mcp/mcp-custom-tools.js.map +1 -0
- package/dist/src/integrations/mcp/mcp-tool-search.d.ts +77 -0
- package/dist/src/integrations/mcp/mcp-tool-search.d.ts.map +1 -0
- package/dist/src/integrations/mcp/mcp-tool-search.js +220 -0
- package/dist/src/integrations/mcp/mcp-tool-search.js.map +1 -0
- package/dist/src/integrations/mcp/mcp-tool-validator.d.ts +60 -0
- package/dist/src/integrations/mcp/mcp-tool-validator.d.ts.map +1 -0
- package/dist/src/integrations/mcp/mcp-tool-validator.js +139 -0
- package/dist/src/integrations/mcp/mcp-tool-validator.js.map +1 -0
- package/dist/src/integrations/persistence/codebase-repository.d.ts +45 -0
- package/dist/src/integrations/persistence/codebase-repository.d.ts.map +1 -0
- package/dist/src/integrations/persistence/codebase-repository.js +85 -0
- package/dist/src/integrations/persistence/codebase-repository.js.map +1 -0
- package/dist/src/integrations/persistence/goal-repository.d.ts +71 -0
- package/dist/src/integrations/persistence/goal-repository.d.ts.map +1 -0
- package/dist/src/integrations/persistence/goal-repository.js +187 -0
- package/dist/src/integrations/persistence/goal-repository.js.map +1 -0
- package/dist/src/integrations/persistence/history.d.ts +72 -0
- package/dist/src/integrations/persistence/history.d.ts.map +1 -0
- package/dist/src/integrations/persistence/history.js +163 -0
- package/dist/src/integrations/persistence/history.js.map +1 -0
- package/dist/src/integrations/persistence/persistence.d.ts +49 -0
- package/dist/src/integrations/persistence/persistence.d.ts.map +1 -0
- package/dist/src/integrations/persistence/persistence.js +200 -0
- package/dist/src/integrations/persistence/persistence.js.map +1 -0
- package/dist/src/integrations/persistence/session-repository.d.ts +212 -0
- package/dist/src/integrations/persistence/session-repository.d.ts.map +1 -0
- package/dist/src/integrations/persistence/session-repository.js +781 -0
- package/dist/src/integrations/persistence/session-repository.js.map +1 -0
- package/dist/src/integrations/persistence/session-store.d.ts +184 -0
- package/dist/src/integrations/persistence/session-store.d.ts.map +1 -0
- package/dist/src/integrations/persistence/session-store.js +346 -0
- package/dist/src/integrations/persistence/session-store.js.map +1 -0
- package/dist/src/integrations/persistence/sqlite-store.d.ts +453 -0
- package/dist/src/integrations/persistence/sqlite-store.d.ts.map +1 -0
- package/dist/src/integrations/persistence/sqlite-store.js +680 -0
- package/dist/src/integrations/persistence/sqlite-store.js.map +1 -0
- package/dist/src/integrations/persistence/worker-repository.d.ts +65 -0
- package/dist/src/integrations/persistence/worker-repository.d.ts.map +1 -0
- package/dist/src/integrations/persistence/worker-repository.js +181 -0
- package/dist/src/integrations/persistence/worker-repository.js.map +1 -0
- package/dist/src/integrations/quality/auto-checkpoint.d.ts +98 -0
- package/dist/src/integrations/quality/auto-checkpoint.d.ts.map +1 -0
- package/dist/src/integrations/quality/auto-checkpoint.js +250 -0
- package/dist/src/integrations/quality/auto-checkpoint.js.map +1 -0
- package/dist/src/integrations/quality/dead-letter-queue.d.ts +233 -0
- package/dist/src/integrations/quality/dead-letter-queue.d.ts.map +1 -0
- package/dist/src/integrations/quality/dead-letter-queue.js +549 -0
- package/dist/src/integrations/quality/dead-letter-queue.js.map +1 -0
- package/dist/src/integrations/quality/health-check.d.ts +218 -0
- package/dist/src/integrations/quality/health-check.d.ts.map +1 -0
- package/dist/src/integrations/quality/health-check.js +418 -0
- package/dist/src/integrations/quality/health-check.js.map +1 -0
- package/dist/src/integrations/quality/learning-store.d.ts +291 -0
- package/dist/src/integrations/quality/learning-store.d.ts.map +1 -0
- package/dist/src/integrations/quality/learning-store.js +723 -0
- package/dist/src/integrations/quality/learning-store.js.map +1 -0
- package/dist/src/integrations/quality/self-improvement.d.ts +90 -0
- package/dist/src/integrations/quality/self-improvement.d.ts.map +1 -0
- package/dist/src/integrations/quality/self-improvement.js +229 -0
- package/dist/src/integrations/quality/self-improvement.js.map +1 -0
- package/dist/src/integrations/quality/tool-recommendation.d.ts +61 -0
- package/dist/src/integrations/quality/tool-recommendation.d.ts.map +1 -0
- package/dist/src/integrations/quality/tool-recommendation.js +298 -0
- package/dist/src/integrations/quality/tool-recommendation.js.map +1 -0
- package/dist/src/integrations/safety/bash-policy.d.ts +33 -0
- package/dist/src/integrations/safety/bash-policy.d.ts.map +1 -0
- package/dist/src/integrations/safety/bash-policy.js +147 -0
- package/dist/src/integrations/safety/bash-policy.js.map +1 -0
- package/dist/src/integrations/safety/edit-validator.d.ts +30 -0
- package/dist/src/integrations/safety/edit-validator.d.ts.map +1 -0
- package/dist/src/integrations/safety/edit-validator.js +87 -0
- package/dist/src/integrations/safety/edit-validator.js.map +1 -0
- package/dist/src/integrations/safety/execution-policy.d.ts +189 -0
- package/dist/src/integrations/safety/execution-policy.d.ts.map +1 -0
- package/dist/src/integrations/safety/execution-policy.js +362 -0
- package/dist/src/integrations/safety/execution-policy.js.map +1 -0
- package/dist/src/integrations/safety/policy-engine.d.ts +55 -0
- package/dist/src/integrations/safety/policy-engine.d.ts.map +1 -0
- package/dist/src/integrations/safety/policy-engine.js +287 -0
- package/dist/src/integrations/safety/policy-engine.js.map +1 -0
- package/dist/src/integrations/safety/safety.d.ts +174 -0
- package/dist/src/integrations/safety/safety.d.ts.map +1 -0
- package/dist/src/integrations/safety/safety.js +473 -0
- package/dist/src/integrations/safety/safety.js.map +1 -0
- package/dist/src/integrations/safety/sandbox/basic.d.ts +81 -0
- package/dist/src/integrations/safety/sandbox/basic.d.ts.map +1 -0
- package/dist/src/integrations/safety/sandbox/basic.js +333 -0
- package/dist/src/integrations/safety/sandbox/basic.js.map +1 -0
- package/dist/src/integrations/safety/sandbox/docker.d.ts +94 -0
- package/dist/src/integrations/safety/sandbox/docker.d.ts.map +1 -0
- package/dist/src/integrations/safety/sandbox/docker.js +294 -0
- package/dist/src/integrations/safety/sandbox/docker.js.map +1 -0
- package/dist/src/integrations/safety/sandbox/index.d.ts +188 -0
- package/dist/src/integrations/safety/sandbox/index.d.ts.map +1 -0
- package/dist/src/integrations/safety/sandbox/index.js +410 -0
- package/dist/src/integrations/safety/sandbox/index.js.map +1 -0
- package/dist/src/integrations/safety/sandbox/landlock.d.ts +59 -0
- package/dist/src/integrations/safety/sandbox/landlock.d.ts.map +1 -0
- package/dist/src/integrations/safety/sandbox/landlock.js +333 -0
- package/dist/src/integrations/safety/sandbox/landlock.js.map +1 -0
- package/dist/src/integrations/safety/sandbox/seatbelt.d.ts +68 -0
- package/dist/src/integrations/safety/sandbox/seatbelt.d.ts.map +1 -0
- package/dist/src/integrations/safety/sandbox/seatbelt.js +291 -0
- package/dist/src/integrations/safety/sandbox/seatbelt.js.map +1 -0
- package/dist/src/integrations/safety/type-checker.d.ts +53 -0
- package/dist/src/integrations/safety/type-checker.d.ts.map +1 -0
- package/dist/src/integrations/safety/type-checker.js +146 -0
- package/dist/src/integrations/safety/type-checker.js.map +1 -0
- package/dist/src/integrations/skills/skill-executor.d.ts +113 -0
- package/dist/src/integrations/skills/skill-executor.d.ts.map +1 -0
- package/dist/src/integrations/skills/skill-executor.js +266 -0
- package/dist/src/integrations/skills/skill-executor.js.map +1 -0
- package/dist/src/integrations/skills/skills.d.ts +262 -0
- package/dist/src/integrations/skills/skills.d.ts.map +1 -0
- package/dist/src/integrations/skills/skills.js +611 -0
- package/dist/src/integrations/skills/skills.js.map +1 -0
- package/dist/src/integrations/streaming/pty-shell.d.ts +169 -0
- package/dist/src/integrations/streaming/pty-shell.d.ts.map +1 -0
- package/dist/src/integrations/streaming/pty-shell.js +371 -0
- package/dist/src/integrations/streaming/pty-shell.js.map +1 -0
- package/dist/src/integrations/streaming/streaming.d.ts +102 -0
- package/dist/src/integrations/streaming/streaming.d.ts.map +1 -0
- package/dist/src/integrations/streaming/streaming.js +364 -0
- package/dist/src/integrations/streaming/streaming.js.map +1 -0
- package/dist/src/integrations/swarm/failure-classifier.d.ts.map +1 -1
- package/dist/src/integrations/swarm/failure-classifier.js +18 -3
- package/dist/src/integrations/swarm/failure-classifier.js.map +1 -1
- package/dist/src/integrations/swarm/index.d.ts +6 -5
- package/dist/src/integrations/swarm/index.d.ts.map +1 -1
- package/dist/src/integrations/swarm/index.js +5 -3
- package/dist/src/integrations/swarm/index.js.map +1 -1
- package/dist/src/integrations/swarm/model-selector.d.ts.map +1 -1
- package/dist/src/integrations/swarm/model-selector.js +21 -24
- package/dist/src/integrations/swarm/model-selector.js.map +1 -1
- package/dist/src/integrations/swarm/request-throttle.d.ts.map +1 -1
- package/dist/src/integrations/swarm/request-throttle.js +7 -4
- package/dist/src/integrations/swarm/request-throttle.js.map +1 -1
- package/dist/src/integrations/swarm/swarm-budget.d.ts +1 -1
- package/dist/src/integrations/swarm/swarm-budget.d.ts.map +1 -1
- package/dist/src/integrations/swarm/swarm-budget.js +1 -1
- package/dist/src/integrations/swarm/swarm-budget.js.map +1 -1
- package/dist/src/integrations/swarm/swarm-config-loader.d.ts.map +1 -1
- package/dist/src/integrations/swarm/swarm-config-loader.js +53 -17
- package/dist/src/integrations/swarm/swarm-config-loader.js.map +1 -1
- package/dist/src/integrations/swarm/swarm-event-bridge.d.ts.map +1 -1
- package/dist/src/integrations/swarm/swarm-event-bridge.js +69 -23
- package/dist/src/integrations/swarm/swarm-event-bridge.js.map +1 -1
- package/dist/src/integrations/swarm/swarm-events.d.ts +1 -1
- package/dist/src/integrations/swarm/swarm-events.d.ts.map +1 -1
- package/dist/src/integrations/swarm/swarm-events.js +1 -1
- package/dist/src/integrations/swarm/swarm-events.js.map +1 -1
- package/dist/src/integrations/swarm/swarm-execution.d.ts +27 -0
- package/dist/src/integrations/swarm/swarm-execution.d.ts.map +1 -0
- package/dist/src/integrations/swarm/swarm-execution.js +1071 -0
- package/dist/src/integrations/swarm/swarm-execution.js.map +1 -0
- package/dist/src/integrations/swarm/swarm-helpers.d.ts +26 -0
- package/dist/src/integrations/swarm/swarm-helpers.d.ts.map +1 -0
- package/dist/src/integrations/swarm/swarm-helpers.js +108 -0
- package/dist/src/integrations/swarm/swarm-helpers.js.map +1 -0
- package/dist/src/integrations/swarm/swarm-lifecycle.d.ts +100 -0
- package/dist/src/integrations/swarm/swarm-lifecycle.d.ts.map +1 -0
- package/dist/src/integrations/swarm/swarm-lifecycle.js +977 -0
- package/dist/src/integrations/swarm/swarm-lifecycle.js.map +1 -0
- package/dist/src/integrations/swarm/swarm-orchestrator.d.ts +84 -203
- package/dist/src/integrations/swarm/swarm-orchestrator.d.ts.map +1 -1
- package/dist/src/integrations/swarm/swarm-orchestrator.js +338 -2899
- package/dist/src/integrations/swarm/swarm-orchestrator.js.map +1 -1
- package/dist/src/integrations/swarm/swarm-quality-gate.d.ts.map +1 -1
- package/dist/src/integrations/swarm/swarm-quality-gate.js +19 -15
- package/dist/src/integrations/swarm/swarm-quality-gate.js.map +1 -1
- package/dist/src/integrations/swarm/swarm-recovery.d.ts +75 -0
- package/dist/src/integrations/swarm/swarm-recovery.d.ts.map +1 -0
- package/dist/src/integrations/swarm/swarm-recovery.js +563 -0
- package/dist/src/integrations/swarm/swarm-recovery.js.map +1 -0
- package/dist/src/integrations/swarm/swarm-state-store.d.ts.map +1 -1
- package/dist/src/integrations/swarm/swarm-state-store.js +8 -0
- package/dist/src/integrations/swarm/swarm-state-store.js.map +1 -1
- package/dist/src/integrations/swarm/task-queue.d.ts +8 -2
- package/dist/src/integrations/swarm/task-queue.d.ts.map +1 -1
- package/dist/src/integrations/swarm/task-queue.js +60 -26
- package/dist/src/integrations/swarm/task-queue.js.map +1 -1
- package/dist/src/integrations/swarm/types.d.ts +17 -5
- package/dist/src/integrations/swarm/types.d.ts.map +1 -1
- package/dist/src/integrations/swarm/types.js +89 -12
- package/dist/src/integrations/swarm/types.js.map +1 -1
- package/dist/src/integrations/swarm/worker-pool.d.ts +1 -1
- package/dist/src/integrations/swarm/worker-pool.d.ts.map +1 -1
- package/dist/src/integrations/swarm/worker-pool.js +43 -31
- package/dist/src/integrations/swarm/worker-pool.js.map +1 -1
- package/dist/src/integrations/tasks/dependency-analyzer.d.ts +34 -0
- package/dist/src/integrations/tasks/dependency-analyzer.d.ts.map +1 -0
- package/dist/src/integrations/tasks/dependency-analyzer.js +231 -0
- package/dist/src/integrations/tasks/dependency-analyzer.js.map +1 -0
- package/dist/src/integrations/tasks/interactive-planning.d.ts +322 -0
- package/dist/src/integrations/tasks/interactive-planning.d.ts.map +1 -0
- package/dist/src/integrations/tasks/interactive-planning.js +648 -0
- package/dist/src/integrations/tasks/interactive-planning.js.map +1 -0
- package/dist/src/integrations/tasks/pending-plan.d.ts +196 -0
- package/dist/src/integrations/tasks/pending-plan.d.ts.map +1 -0
- package/dist/src/integrations/tasks/pending-plan.js +431 -0
- package/dist/src/integrations/tasks/pending-plan.js.map +1 -0
- package/dist/src/integrations/tasks/planning.d.ts +115 -0
- package/dist/src/integrations/tasks/planning.d.ts.map +1 -0
- package/dist/src/integrations/tasks/planning.js +432 -0
- package/dist/src/integrations/tasks/planning.js.map +1 -0
- package/dist/src/integrations/tasks/smart-decomposer.d.ts +316 -0
- package/dist/src/integrations/tasks/smart-decomposer.d.ts.map +1 -0
- package/dist/src/integrations/tasks/smart-decomposer.js +668 -0
- package/dist/src/integrations/tasks/smart-decomposer.js.map +1 -0
- package/dist/src/integrations/tasks/task-manager.d.ts +164 -0
- package/dist/src/integrations/tasks/task-manager.d.ts.map +1 -0
- package/dist/src/integrations/tasks/task-manager.js +390 -0
- package/dist/src/integrations/tasks/task-manager.js.map +1 -0
- package/dist/src/integrations/tasks/task-splitter.d.ts +56 -0
- package/dist/src/integrations/tasks/task-splitter.d.ts.map +1 -0
- package/dist/src/integrations/tasks/task-splitter.js +542 -0
- package/dist/src/integrations/tasks/task-splitter.js.map +1 -0
- package/dist/src/integrations/tasks/verification-gate.d.ts +103 -0
- package/dist/src/integrations/tasks/verification-gate.d.ts.map +1 -0
- package/dist/src/integrations/tasks/verification-gate.js +195 -0
- package/dist/src/integrations/tasks/verification-gate.js.map +1 -0
- package/dist/src/integrations/tasks/work-log.d.ts +87 -0
- package/dist/src/integrations/tasks/work-log.d.ts.map +1 -0
- package/dist/src/integrations/tasks/work-log.js +287 -0
- package/dist/src/integrations/tasks/work-log.js.map +1 -0
- package/dist/src/integrations/utilities/capabilities.d.ts +160 -0
- package/dist/src/integrations/utilities/capabilities.d.ts.map +1 -0
- package/dist/src/integrations/utilities/capabilities.js +464 -0
- package/dist/src/integrations/utilities/capabilities.js.map +1 -0
- package/dist/src/integrations/utilities/diff-utils.d.ts +105 -0
- package/dist/src/integrations/utilities/diff-utils.d.ts.map +1 -0
- package/dist/src/integrations/utilities/diff-utils.js +496 -0
- package/dist/src/integrations/utilities/diff-utils.js.map +1 -0
- package/dist/src/integrations/utilities/environment-facts.d.ts +52 -0
- package/dist/src/integrations/utilities/environment-facts.d.ts.map +1 -0
- package/dist/src/integrations/utilities/environment-facts.js +94 -0
- package/dist/src/integrations/utilities/environment-facts.js.map +1 -0
- package/dist/src/integrations/utilities/file-change-tracker.d.ts +162 -0
- package/dist/src/integrations/utilities/file-change-tracker.d.ts.map +1 -0
- package/dist/src/integrations/utilities/file-change-tracker.js +537 -0
- package/dist/src/integrations/utilities/file-change-tracker.js.map +1 -0
- package/dist/src/integrations/utilities/graph-visualization.d.ts +72 -0
- package/dist/src/integrations/utilities/graph-visualization.d.ts.map +1 -0
- package/dist/src/integrations/utilities/graph-visualization.js +385 -0
- package/dist/src/integrations/utilities/graph-visualization.js.map +1 -0
- package/dist/src/integrations/utilities/hierarchical-config.d.ts +215 -0
- package/dist/src/integrations/utilities/hierarchical-config.d.ts.map +1 -0
- package/dist/src/integrations/utilities/hierarchical-config.js +508 -0
- package/dist/src/integrations/utilities/hierarchical-config.js.map +1 -0
- package/dist/src/integrations/utilities/hooks.d.ts +116 -0
- package/dist/src/integrations/utilities/hooks.d.ts.map +1 -0
- package/dist/src/integrations/utilities/hooks.js +410 -0
- package/dist/src/integrations/utilities/hooks.js.map +1 -0
- package/dist/src/integrations/utilities/ignore.d.ts +143 -0
- package/dist/src/integrations/utilities/ignore.d.ts.map +1 -0
- package/dist/src/integrations/utilities/ignore.js +417 -0
- package/dist/src/integrations/utilities/ignore.js.map +1 -0
- package/dist/src/integrations/utilities/image-renderer.d.ts +119 -0
- package/dist/src/integrations/utilities/image-renderer.d.ts.map +1 -0
- package/dist/src/integrations/utilities/image-renderer.js +301 -0
- package/dist/src/integrations/utilities/image-renderer.js.map +1 -0
- package/dist/src/integrations/utilities/logger.d.ts +104 -0
- package/dist/src/integrations/utilities/logger.d.ts.map +1 -0
- package/dist/src/integrations/utilities/logger.js +217 -0
- package/dist/src/integrations/utilities/logger.js.map +1 -0
- package/dist/src/integrations/utilities/memory.d.ts +116 -0
- package/dist/src/integrations/utilities/memory.d.ts.map +1 -0
- package/dist/src/integrations/utilities/memory.js +309 -0
- package/dist/src/integrations/utilities/memory.js.map +1 -0
- package/dist/src/integrations/utilities/observability.d.ts +162 -0
- package/dist/src/integrations/utilities/observability.d.ts.map +1 -0
- package/dist/src/integrations/utilities/observability.js +408 -0
- package/dist/src/integrations/utilities/observability.js.map +1 -0
- package/dist/src/integrations/utilities/openrouter-pricing.d.ts +67 -0
- package/dist/src/integrations/utilities/openrouter-pricing.d.ts.map +1 -0
- package/dist/src/integrations/utilities/openrouter-pricing.js +166 -0
- package/dist/src/integrations/utilities/openrouter-pricing.js.map +1 -0
- package/dist/src/integrations/utilities/react.d.ts +139 -0
- package/dist/src/integrations/utilities/react.d.ts.map +1 -0
- package/dist/src/integrations/utilities/react.js +269 -0
- package/dist/src/integrations/utilities/react.js.map +1 -0
- package/dist/src/integrations/utilities/retry.d.ts +132 -0
- package/dist/src/integrations/utilities/retry.d.ts.map +1 -0
- package/dist/src/integrations/utilities/retry.js +233 -0
- package/dist/src/integrations/utilities/retry.js.map +1 -0
- package/dist/src/integrations/utilities/routing.d.ts +118 -0
- package/dist/src/integrations/utilities/routing.d.ts.map +1 -0
- package/dist/src/integrations/utilities/routing.js +360 -0
- package/dist/src/integrations/utilities/routing.js.map +1 -0
- package/dist/src/integrations/utilities/rules.d.ts +131 -0
- package/dist/src/integrations/utilities/rules.d.ts.map +1 -0
- package/dist/src/integrations/utilities/rules.js +282 -0
- package/dist/src/integrations/utilities/rules.js.map +1 -0
- package/dist/src/integrations/utilities/sourcegraph.d.ts +169 -0
- package/dist/src/integrations/utilities/sourcegraph.d.ts.map +1 -0
- package/dist/src/integrations/utilities/sourcegraph.js +377 -0
- package/dist/src/integrations/utilities/sourcegraph.js.map +1 -0
- package/dist/src/integrations/utilities/thinking-strategy.d.ts +52 -0
- package/dist/src/integrations/utilities/thinking-strategy.d.ts.map +1 -0
- package/dist/src/integrations/utilities/thinking-strategy.js +129 -0
- package/dist/src/integrations/utilities/thinking-strategy.js.map +1 -0
- package/dist/src/integrations/utilities/thread-manager.d.ts +199 -0
- package/dist/src/integrations/utilities/thread-manager.d.ts.map +1 -0
- package/dist/src/integrations/utilities/thread-manager.js +359 -0
- package/dist/src/integrations/utilities/thread-manager.js.map +1 -0
- package/dist/src/integrations/utilities/token-estimate.d.ts +16 -0
- package/dist/src/integrations/utilities/token-estimate.d.ts.map +1 -0
- package/dist/src/integrations/utilities/token-estimate.js +20 -0
- package/dist/src/integrations/utilities/token-estimate.js.map +1 -0
- package/dist/src/main.js +50 -27
- package/dist/src/main.js.map +1 -1
- package/dist/src/modes/repl.d.ts.map +1 -1
- package/dist/src/modes/repl.js +73 -22
- package/dist/src/modes/repl.js.map +1 -1
- package/dist/src/modes/tui.d.ts.map +1 -1
- package/dist/src/modes/tui.js +93 -16
- package/dist/src/modes/tui.js.map +1 -1
- package/dist/src/modes.d.ts.map +1 -1
- package/dist/src/modes.js +14 -14
- package/dist/src/modes.js.map +1 -1
- package/dist/src/observability/tracer.d.ts.map +1 -1
- package/dist/src/observability/tracer.js +8 -4
- package/dist/src/observability/tracer.js.map +1 -1
- package/dist/src/observability/types.d.ts.map +1 -1
- package/dist/src/observability/types.js.map +1 -1
- package/dist/src/paths.d.ts.map +1 -1
- package/dist/src/paths.js +2 -6
- package/dist/src/paths.js.map +1 -1
- package/dist/src/persistence/migrator.d.ts.map +1 -1
- package/dist/src/persistence/migrator.js +7 -7
- package/dist/src/persistence/migrator.js.map +1 -1
- package/dist/src/persistence/schema.d.ts +2 -0
- package/dist/src/persistence/schema.d.ts.map +1 -1
- package/dist/src/persistence/schema.js +31 -0
- package/dist/src/persistence/schema.js.map +1 -1
- package/dist/src/providers/adapters/anthropic.d.ts +6 -0
- package/dist/src/providers/adapters/anthropic.d.ts.map +1 -1
- package/dist/src/providers/adapters/anthropic.js +132 -36
- package/dist/src/providers/adapters/anthropic.js.map +1 -1
- package/dist/src/providers/adapters/azure.d.ts +74 -0
- package/dist/src/providers/adapters/azure.d.ts.map +1 -0
- package/dist/src/providers/adapters/azure.js +369 -0
- package/dist/src/providers/adapters/azure.js.map +1 -0
- package/dist/src/providers/adapters/mock.d.ts +16 -2
- package/dist/src/providers/adapters/mock.d.ts.map +1 -1
- package/dist/src/providers/adapters/mock.js +51 -10
- package/dist/src/providers/adapters/mock.js.map +1 -1
- package/dist/src/providers/adapters/openai.d.ts +6 -1
- package/dist/src/providers/adapters/openai.d.ts.map +1 -1
- package/dist/src/providers/adapters/openai.js +57 -19
- package/dist/src/providers/adapters/openai.js.map +1 -1
- package/dist/src/providers/adapters/openrouter.d.ts +6 -0
- package/dist/src/providers/adapters/openrouter.d.ts.map +1 -1
- package/dist/src/providers/adapters/openrouter.js +127 -30
- package/dist/src/providers/adapters/openrouter.js.map +1 -1
- package/dist/src/providers/circuit-breaker.d.ts.map +1 -1
- package/dist/src/providers/circuit-breaker.js +4 -3
- package/dist/src/providers/circuit-breaker.js.map +1 -1
- package/dist/src/providers/fallback-chain.d.ts.map +1 -1
- package/dist/src/providers/fallback-chain.js +3 -3
- package/dist/src/providers/fallback-chain.js.map +1 -1
- package/dist/src/providers/llm-resilience.d.ts.map +1 -1
- package/dist/src/providers/llm-resilience.js +2 -2
- package/dist/src/providers/llm-resilience.js.map +1 -1
- package/dist/src/providers/provider.d.ts.map +1 -1
- package/dist/src/providers/provider.js +2 -3
- package/dist/src/providers/provider.js.map +1 -1
- package/dist/src/providers/resilient-fetch.d.ts.map +1 -1
- package/dist/src/providers/resilient-fetch.js +3 -4
- package/dist/src/providers/resilient-fetch.js.map +1 -1
- package/dist/src/providers/resilient-provider.d.ts.map +1 -1
- package/dist/src/providers/resilient-provider.js +9 -6
- package/dist/src/providers/resilient-provider.js.map +1 -1
- package/dist/src/providers/types.d.ts +23 -2
- package/dist/src/providers/types.d.ts.map +1 -1
- package/dist/src/session-picker.d.ts +1 -1
- package/dist/src/session-picker.d.ts.map +1 -1
- package/dist/src/session-picker.js +10 -6
- package/dist/src/session-picker.js.map +1 -1
- package/dist/src/shared/budget-tracker.d.ts.map +1 -1
- package/dist/src/shared/budget-tracker.js +2 -2
- package/dist/src/shared/budget-tracker.js.map +1 -1
- package/dist/src/shared/context-engine.d.ts.map +1 -1
- package/dist/src/shared/context-engine.js +1 -1
- package/dist/src/shared/context-engine.js.map +1 -1
- package/dist/src/shared/persistence.d.ts.map +1 -1
- package/dist/src/shared/persistence.js +2 -6
- package/dist/src/shared/persistence.js.map +1 -1
- package/dist/src/shared/shared-context-state.d.ts.map +1 -1
- package/dist/src/shared/shared-context-state.js.map +1 -1
- package/dist/src/shared/shared-economics-state.d.ts.map +1 -1
- package/dist/src/shared/shared-economics-state.js.map +1 -1
- package/dist/src/tools/agent.d.ts +2 -2
- package/dist/src/tools/agent.d.ts.map +1 -1
- package/dist/src/tools/agent.js +10 -7
- package/dist/src/tools/agent.js.map +1 -1
- package/dist/src/tools/bash.d.ts.map +1 -1
- package/dist/src/tools/bash.js +1 -1
- package/dist/src/tools/bash.js.map +1 -1
- package/dist/src/tools/coercion.js +1 -1
- package/dist/src/tools/coercion.js.map +1 -1
- package/dist/src/tools/file.d.ts.map +1 -1
- package/dist/src/tools/file.js +2 -2
- package/dist/src/tools/file.js.map +1 -1
- package/dist/src/tools/permission.js +7 -8
- package/dist/src/tools/permission.js.map +1 -1
- package/dist/src/tools/registry.d.ts +1 -1
- package/dist/src/tools/registry.d.ts.map +1 -1
- package/dist/src/tools/registry.js +4 -6
- package/dist/src/tools/registry.js.map +1 -1
- package/dist/src/tools/standard.d.ts.map +1 -1
- package/dist/src/tools/standard.js +1 -3
- package/dist/src/tools/standard.js.map +1 -1
- package/dist/src/tools/tasks.d.ts +1 -1
- package/dist/src/tools/tasks.d.ts.map +1 -1
- package/dist/src/tools/tasks.js +4 -4
- package/dist/src/tools/tasks.js.map +1 -1
- package/dist/src/tools/types.d.ts.map +1 -1
- package/dist/src/tools/types.js +5 -1
- package/dist/src/tools/types.js.map +1 -1
- package/dist/src/tools/undo.d.ts +1 -1
- package/dist/src/tools/undo.d.ts.map +1 -1
- package/dist/src/tools/undo.js +4 -2
- package/dist/src/tools/undo.js.map +1 -1
- package/dist/src/tracing/cache-boundary-tracker.d.ts.map +1 -1
- package/dist/src/tracing/cache-boundary-tracker.js +9 -13
- package/dist/src/tracing/cache-boundary-tracker.js.map +1 -1
- package/dist/src/tracing/trace-collector.d.ts +22 -0
- package/dist/src/tracing/trace-collector.d.ts.map +1 -1
- package/dist/src/tracing/trace-collector.js +55 -31
- package/dist/src/tracing/trace-collector.js.map +1 -1
- package/dist/src/tracing/types.d.ts +17 -1
- package/dist/src/tracing/types.d.ts.map +1 -1
- package/dist/src/tracing/types.js.map +1 -1
- package/dist/src/tricks/failure-evidence.d.ts.map +1 -1
- package/dist/src/tricks/failure-evidence.js +17 -27
- package/dist/src/tricks/failure-evidence.js.map +1 -1
- package/dist/src/tricks/json-utils.d.ts.map +1 -1
- package/dist/src/tricks/json-utils.js +1 -4
- package/dist/src/tricks/json-utils.js.map +1 -1
- package/dist/src/tricks/kv-cache-context.d.ts.map +1 -1
- package/dist/src/tricks/kv-cache-context.js +2 -3
- package/dist/src/tricks/kv-cache-context.js.map +1 -1
- package/dist/src/tricks/recitation.d.ts.map +1 -1
- package/dist/src/tricks/recitation.js +24 -19
- package/dist/src/tricks/recitation.js.map +1 -1
- package/dist/src/tricks/recursive-context.d.ts.map +1 -1
- package/dist/src/tricks/recursive-context.js +10 -7
- package/dist/src/tricks/recursive-context.js.map +1 -1
- package/dist/src/tricks/reversible-compaction.d.ts.map +1 -1
- package/dist/src/tricks/reversible-compaction.js +17 -9
- package/dist/src/tricks/reversible-compaction.js.map +1 -1
- package/dist/src/tricks/serialization-diversity.d.ts.map +1 -1
- package/dist/src/tricks/serialization-diversity.js +12 -12
- package/dist/src/tricks/serialization-diversity.js.map +1 -1
- package/dist/src/tui/app.d.ts +9 -5
- package/dist/src/tui/app.d.ts.map +1 -1
- package/dist/src/tui/app.js +690 -565
- package/dist/src/tui/app.js.map +1 -1
- package/dist/src/tui/components/ActiveAgentsPanel.d.ts +2 -0
- package/dist/src/tui/components/ActiveAgentsPanel.d.ts.map +1 -1
- package/dist/src/tui/components/ActiveAgentsPanel.js +5 -5
- package/dist/src/tui/components/ActiveAgentsPanel.js.map +1 -1
- package/dist/src/tui/components/ApprovalDialog.d.ts.map +1 -1
- package/dist/src/tui/components/ApprovalDialog.js +14 -0
- package/dist/src/tui/components/ApprovalDialog.js.map +1 -1
- package/dist/src/tui/components/BudgetExtensionDialog.d.ts +18 -0
- package/dist/src/tui/components/BudgetExtensionDialog.d.ts.map +1 -0
- package/dist/src/tui/components/BudgetExtensionDialog.js +40 -0
- package/dist/src/tui/components/BudgetExtensionDialog.js.map +1 -0
- package/dist/src/tui/components/CollapsibleDiffView.d.ts +1 -1
- package/dist/src/tui/components/CollapsibleDiffView.d.ts.map +1 -1
- package/dist/src/tui/components/CollapsibleDiffView.js +18 -13
- package/dist/src/tui/components/CollapsibleDiffView.js.map +1 -1
- package/dist/src/tui/components/DebugPanel.d.ts.map +1 -1
- package/dist/src/tui/components/DebugPanel.js +46 -26
- package/dist/src/tui/components/DebugPanel.js.map +1 -1
- package/dist/src/tui/components/DiagnosticsPanel.d.ts +24 -0
- package/dist/src/tui/components/DiagnosticsPanel.d.ts.map +1 -0
- package/dist/src/tui/components/DiagnosticsPanel.js +63 -0
- package/dist/src/tui/components/DiagnosticsPanel.js.map +1 -0
- package/dist/src/tui/components/DiffView.d.ts +1 -1
- package/dist/src/tui/components/DiffView.d.ts.map +1 -1
- package/dist/src/tui/components/DiffView.js +21 -14
- package/dist/src/tui/components/DiffView.js.map +1 -1
- package/dist/src/tui/components/ErrorBoundary.d.ts.map +1 -1
- package/dist/src/tui/components/ErrorBoundary.js +8 -3
- package/dist/src/tui/components/ErrorBoundary.js.map +1 -1
- package/dist/src/tui/components/ErrorDetailPanel.d.ts.map +1 -1
- package/dist/src/tui/components/ErrorDetailPanel.js +4 -4
- package/dist/src/tui/components/ErrorDetailPanel.js.map +1 -1
- package/dist/src/tui/components/FileChangeSummary.d.ts.map +1 -1
- package/dist/src/tui/components/FileChangeSummary.js +3 -3
- package/dist/src/tui/components/FileChangeSummary.js.map +1 -1
- package/dist/src/tui/components/InputArea.d.ts.map +1 -1
- package/dist/src/tui/components/InputArea.js +32 -15
- package/dist/src/tui/components/InputArea.js.map +1 -1
- package/dist/src/tui/components/LearningValidationDialog.d.ts +25 -0
- package/dist/src/tui/components/LearningValidationDialog.d.ts.map +1 -0
- package/dist/src/tui/components/LearningValidationDialog.js +35 -0
- package/dist/src/tui/components/LearningValidationDialog.js.map +1 -0
- package/dist/src/tui/components/MessageItem.d.ts.map +1 -1
- package/dist/src/tui/components/MessageItem.js.map +1 -1
- package/dist/src/tui/components/PlanPanel.d.ts +27 -0
- package/dist/src/tui/components/PlanPanel.d.ts.map +1 -0
- package/dist/src/tui/components/PlanPanel.js +45 -0
- package/dist/src/tui/components/PlanPanel.js.map +1 -0
- package/dist/src/tui/components/ScrollableBox.d.ts.map +1 -1
- package/dist/src/tui/components/ScrollableBox.js +2 -2
- package/dist/src/tui/components/ScrollableBox.js.map +1 -1
- package/dist/src/tui/components/SideBySideDiff.d.ts.map +1 -1
- package/dist/src/tui/components/SideBySideDiff.js +20 -18
- package/dist/src/tui/components/SideBySideDiff.js.map +1 -1
- package/dist/src/tui/components/StatusBar.d.ts +41 -0
- package/dist/src/tui/components/StatusBar.d.ts.map +1 -0
- package/dist/src/tui/components/StatusBar.js +114 -0
- package/dist/src/tui/components/StatusBar.js.map +1 -0
- package/dist/src/tui/components/SwarmStatusPanel.d.ts.map +1 -1
- package/dist/src/tui/components/SwarmStatusPanel.js +25 -17
- package/dist/src/tui/components/SwarmStatusPanel.js.map +1 -1
- package/dist/src/tui/components/TasksPanel.d.ts +1 -1
- package/dist/src/tui/components/TasksPanel.d.ts.map +1 -1
- package/dist/src/tui/components/TasksPanel.js +12 -11
- package/dist/src/tui/components/TasksPanel.js.map +1 -1
- package/dist/src/tui/components/ToolCallItem.d.ts.map +1 -1
- package/dist/src/tui/components/ToolCallItem.js +19 -6
- package/dist/src/tui/components/ToolCallItem.js.map +1 -1
- package/dist/src/tui/components/ToolCallsPanel.d.ts +15 -0
- package/dist/src/tui/components/ToolCallsPanel.d.ts.map +1 -0
- package/dist/src/tui/components/ToolCallsPanel.js +34 -0
- package/dist/src/tui/components/ToolCallsPanel.js.map +1 -0
- package/dist/src/tui/components/TransparencyPanel.d.ts +15 -0
- package/dist/src/tui/components/TransparencyPanel.d.ts.map +1 -0
- package/dist/src/tui/components/TransparencyPanel.js +46 -0
- package/dist/src/tui/components/TransparencyPanel.js.map +1 -0
- package/dist/src/tui/components/index.d.ts +8 -2
- package/dist/src/tui/components/index.d.ts.map +1 -1
- package/dist/src/tui/components/index.js +14 -2
- package/dist/src/tui/components/index.js.map +1 -1
- package/dist/src/tui/event-display.d.ts.map +1 -1
- package/dist/src/tui/event-display.js +13 -4
- package/dist/src/tui/event-display.js.map +1 -1
- package/dist/src/tui/hooks/index.d.ts +1 -0
- package/dist/src/tui/hooks/index.d.ts.map +1 -1
- package/dist/src/tui/hooks/index.js +1 -0
- package/dist/src/tui/hooks/index.js.map +1 -1
- package/dist/src/tui/hooks/use-agent-events.d.ts +53 -0
- package/dist/src/tui/hooks/use-agent-events.d.ts.map +1 -0
- package/dist/src/tui/hooks/use-agent-events.js +444 -0
- package/dist/src/tui/hooks/use-agent-events.js.map +1 -0
- package/dist/src/tui/hooks/use-throttled-state.d.ts +18 -0
- package/dist/src/tui/hooks/use-throttled-state.d.ts.map +1 -0
- package/dist/src/tui/hooks/use-throttled-state.js +93 -0
- package/dist/src/tui/hooks/use-throttled-state.js.map +1 -0
- package/dist/src/tui/hooks/useMessagePruning.d.ts.map +1 -1
- package/dist/src/tui/hooks/useMessagePruning.js.map +1 -1
- package/dist/src/tui/index.d.ts +2 -2
- package/dist/src/tui/index.d.ts.map +1 -1
- package/dist/src/tui/index.js +102 -7
- package/dist/src/tui/index.js.map +1 -1
- package/dist/src/tui/input/CommandPalette.d.ts.map +1 -1
- package/dist/src/tui/input/CommandPalette.js +2 -2
- package/dist/src/tui/input/CommandPalette.js.map +1 -1
- package/dist/src/tui/input/index.d.ts +1 -1
- package/dist/src/tui/input/index.d.ts.map +1 -1
- package/dist/src/tui/input/index.js +1 -1
- package/dist/src/tui/input/index.js.map +1 -1
- package/dist/src/tui/syntax/languages/bash.js +94 -16
- package/dist/src/tui/syntax/languages/bash.js.map +1 -1
- package/dist/src/tui/syntax/languages/javascript.js +65 -12
- package/dist/src/tui/syntax/languages/javascript.js.map +1 -1
- package/dist/src/tui/syntax/languages/json.js.map +1 -1
- package/dist/src/tui/syntax/languages/python.js +81 -15
- package/dist/src/tui/syntax/languages/python.js.map +1 -1
- package/dist/src/tui/theme/index.js.map +1 -1
- package/dist/src/tui/transparency-aggregator.d.ts +13 -0
- package/dist/src/tui/transparency-aggregator.d.ts.map +1 -1
- package/dist/src/tui/transparency-aggregator.js +39 -4
- package/dist/src/tui/transparency-aggregator.js.map +1 -1
- package/dist/src/tui/types.d.ts.map +1 -1
- package/dist/src/tui/types.js.map +1 -1
- package/dist/src/tui/utils/keyboard.d.ts.map +1 -1
- package/dist/src/tui/utils/keyboard.js.map +1 -1
- package/dist/src/types.d.ts +39 -2
- package/dist/src/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -8,21 +8,43 @@
|
|
|
8
8
|
* resilience handling, tool execution, and compaction.
|
|
9
9
|
*/
|
|
10
10
|
import { isFeatureEnabled } from '../defaults.js';
|
|
11
|
+
import { estimateTokenCount, estimateTokensFromCharCount } from '../integrations/utilities/token-estimate.js';
|
|
11
12
|
import { callLLM } from './response-handler.js';
|
|
12
13
|
import { executeToolCalls } from './tool-executor.js';
|
|
13
14
|
import { TIMEOUT_WRAPUP_PROMPT, stableStringify, } from '../integrations/index.js';
|
|
14
15
|
import { detectIncompleteActionResponse } from './completion-analyzer.js';
|
|
15
16
|
export { detectIncompleteActionResponse } from './completion-analyzer.js';
|
|
16
|
-
import { createComponentLogger } from '../integrations/logger.js';
|
|
17
|
-
import { validateSyntax } from '../integrations/edit-validator.js';
|
|
17
|
+
import { createComponentLogger } from '../integrations/utilities/logger.js';
|
|
18
|
+
import { validateSyntax } from '../integrations/safety/edit-validator.js';
|
|
19
|
+
import { runTypeCheck, formatTypeCheckNudge } from '../integrations/safety/type-checker.js';
|
|
20
|
+
import { invalidateAST } from '../integrations/context/codebase-ast.js';
|
|
18
21
|
import * as fs from 'node:fs';
|
|
19
22
|
const log = createComponentLogger('ExecutionLoop');
|
|
20
23
|
// =============================================================================
|
|
24
|
+
// EXECUTION LOOP DEFAULTS
|
|
25
|
+
// =============================================================================
|
|
26
|
+
export const EXECUTION_LOOP_DEFAULTS = {
|
|
27
|
+
/** Preview length when compacting long tool outputs */
|
|
28
|
+
COMPACT_PREVIEW_LENGTH: 200,
|
|
29
|
+
/** Max expensive results preserved from compaction */
|
|
30
|
+
MAX_PRESERVED_EXPENSIVE_RESULTS: 6,
|
|
31
|
+
/** Messages to keep during emergency truncation */
|
|
32
|
+
PRESERVE_RECENT: 10,
|
|
33
|
+
/** Max chars per tool output before truncation */
|
|
34
|
+
MAX_TOOL_OUTPUT_CHARS: 8000,
|
|
35
|
+
/** Number of TS edits before triggering a type check */
|
|
36
|
+
TYPE_CHECK_EDIT_THRESHOLD: 5,
|
|
37
|
+
/** Safety margin ratio for context overflow guard */
|
|
38
|
+
CONTEXT_SAFETY_RATIO: 0.9,
|
|
39
|
+
/** Per-result budget safety margin */
|
|
40
|
+
PER_RESULT_BUDGET_RATIO: 0.95,
|
|
41
|
+
};
|
|
42
|
+
// =============================================================================
|
|
21
43
|
// HELPER FUNCTIONS (extracted from ProductionAgent private methods)
|
|
22
44
|
// =============================================================================
|
|
23
45
|
/**
|
|
24
46
|
* Estimate total tokens in a message array.
|
|
25
|
-
*
|
|
47
|
+
* Delegates to the shared token estimation utility (~3.5 chars/token).
|
|
26
48
|
*/
|
|
27
49
|
export function estimateContextTokens(messages) {
|
|
28
50
|
let totalChars = 0;
|
|
@@ -37,14 +59,13 @@ export function estimateContextTokens(messages) {
|
|
|
37
59
|
}
|
|
38
60
|
}
|
|
39
61
|
}
|
|
40
|
-
return
|
|
62
|
+
return estimateTokensFromCharCount(totalChars);
|
|
41
63
|
}
|
|
42
64
|
/**
|
|
43
65
|
* Compact tool outputs to save context.
|
|
44
66
|
*/
|
|
45
67
|
export function compactToolOutputs(messages) {
|
|
46
|
-
const COMPACT_PREVIEW_LENGTH =
|
|
47
|
-
const MAX_PRESERVED_EXPENSIVE_RESULTS = 6;
|
|
68
|
+
const { COMPACT_PREVIEW_LENGTH, MAX_PRESERVED_EXPENSIVE_RESULTS } = EXECUTION_LOOP_DEFAULTS;
|
|
48
69
|
let compactedCount = 0;
|
|
49
70
|
let savedChars = 0;
|
|
50
71
|
const preservedExpensiveIndexes = messages
|
|
@@ -66,7 +87,10 @@ export function compactToolOutputs(messages) {
|
|
|
66
87
|
}
|
|
67
88
|
}
|
|
68
89
|
if (compactedCount > 0 && process.env.DEBUG) {
|
|
69
|
-
log.debug('Compacted tool outputs', {
|
|
90
|
+
log.debug('Compacted tool outputs', {
|
|
91
|
+
compactedCount,
|
|
92
|
+
savedTokens: estimateTokensFromCharCount(savedChars),
|
|
93
|
+
});
|
|
70
94
|
}
|
|
71
95
|
}
|
|
72
96
|
/**
|
|
@@ -83,21 +107,303 @@ export function isRequestedArtifactMissing(requestedArtifact, executedToolNames)
|
|
|
83
107
|
if (!requestedArtifact)
|
|
84
108
|
return false;
|
|
85
109
|
const artifactWriteTools = ['write_file', 'edit_file', 'apply_patch', 'append_file'];
|
|
86
|
-
return !artifactWriteTools.some(toolName => executedToolNames.has(toolName));
|
|
110
|
+
return !artifactWriteTools.some((toolName) => executedToolNames.has(toolName));
|
|
87
111
|
}
|
|
88
112
|
function getOpenTaskSummary(ctx) {
|
|
89
113
|
if (!ctx.taskManager)
|
|
90
114
|
return undefined;
|
|
91
115
|
const tasks = ctx.taskManager.list();
|
|
92
|
-
const pending = tasks.filter(t => t.status === 'pending').length;
|
|
93
|
-
const inProgress = tasks.filter(t => t.status === 'in_progress').length;
|
|
94
|
-
const blocked = tasks.filter(t => t.status === 'pending' && ctx.taskManager?.isBlocked(t.id)).length;
|
|
116
|
+
const pending = tasks.filter((t) => t.status === 'pending').length;
|
|
117
|
+
const inProgress = tasks.filter((t) => t.status === 'in_progress').length;
|
|
118
|
+
const blocked = tasks.filter((t) => t.status === 'pending' && ctx.taskManager?.isBlocked(t.id)).length;
|
|
95
119
|
return { pending, inProgress, blocked };
|
|
96
120
|
}
|
|
97
121
|
function getPendingWithOwnerCount(ctx) {
|
|
98
122
|
if (!ctx.taskManager)
|
|
99
123
|
return 0;
|
|
100
|
-
return ctx.taskManager.list().filter(t => t.status === 'pending' && !!t.owner).length;
|
|
124
|
+
return ctx.taskManager.list().filter((t) => t.status === 'pending' && !!t.owner).length;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Check economics/iteration budget before an iteration.
|
|
128
|
+
* Returns whether to continue, stop, or whether recovery succeeded.
|
|
129
|
+
*/
|
|
130
|
+
export function checkIterationBudget(deps, messages) {
|
|
131
|
+
if (deps.economics) {
|
|
132
|
+
const budgetCheck = deps.economics.checkBudget();
|
|
133
|
+
const forceTextOnly = budgetCheck.forceTextOnly ?? false;
|
|
134
|
+
const budgetInjectedPrompt = budgetCheck.injectedPrompt;
|
|
135
|
+
const budgetAllowsTaskContinuation = budgetCheck.allowTaskContinuation ?? true;
|
|
136
|
+
deps.traceCollector?.record({
|
|
137
|
+
type: 'budget.check',
|
|
138
|
+
data: {
|
|
139
|
+
iteration: deps.state.iteration,
|
|
140
|
+
canContinue: budgetCheck.canContinue,
|
|
141
|
+
percentUsed: budgetCheck.percentUsed,
|
|
142
|
+
budgetType: budgetCheck.budgetType,
|
|
143
|
+
budgetMode: budgetCheck.budgetMode,
|
|
144
|
+
forceTextOnly,
|
|
145
|
+
allowTaskContinuation: budgetAllowsTaskContinuation,
|
|
146
|
+
enforcementMode: deps.economics.getBudget().enforcementMode ?? 'strict',
|
|
147
|
+
tokenUsage: deps.economics.getUsage().tokens,
|
|
148
|
+
maxTokens: deps.economics.getBudget().maxTokens,
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
if (!budgetCheck.canContinue) {
|
|
152
|
+
// RECOVERY ATTEMPT: Try emergency context reduction
|
|
153
|
+
const isTokenLimit = budgetCheck.budgetType === 'tokens' || budgetCheck.budgetType === 'cost';
|
|
154
|
+
const alreadyTriedRecovery = deps.state._recoveryAttempted === true;
|
|
155
|
+
if (isTokenLimit && !alreadyTriedRecovery) {
|
|
156
|
+
deps.observability?.logger?.info('Budget limit reached, attempting recovery via context reduction', { reason: budgetCheck.reason, percentUsed: budgetCheck.percentUsed });
|
|
157
|
+
deps.emit({
|
|
158
|
+
type: 'resilience.retry',
|
|
159
|
+
reason: 'budget_limit_compaction',
|
|
160
|
+
attempt: 1,
|
|
161
|
+
maxAttempts: 1,
|
|
162
|
+
});
|
|
163
|
+
deps.state.metrics.retryCount = (deps.state.metrics.retryCount ?? 0) + 1;
|
|
164
|
+
deps.state._recoveryAttempted = true;
|
|
165
|
+
const tokensBefore = estimateContextTokens(messages);
|
|
166
|
+
// Step 1: Compact tool outputs aggressively
|
|
167
|
+
compactToolOutputs(deps.state.messages);
|
|
168
|
+
// Step 2: Emergency truncation - keep system + last N messages
|
|
169
|
+
const PRESERVE_RECENT = EXECUTION_LOOP_DEFAULTS.PRESERVE_RECENT;
|
|
170
|
+
if (messages.length > PRESERVE_RECENT + 2) {
|
|
171
|
+
const systemMessage = messages.find((m) => m.role === 'system');
|
|
172
|
+
const recentMessages = messages.slice(-PRESERVE_RECENT);
|
|
173
|
+
messages.length = 0;
|
|
174
|
+
if (systemMessage) {
|
|
175
|
+
messages.push(systemMessage);
|
|
176
|
+
}
|
|
177
|
+
messages.push({
|
|
178
|
+
role: 'system',
|
|
179
|
+
content: `[CONTEXT REDUCED: Earlier messages were removed to stay within budget. Conversation continues from recent context.]`,
|
|
180
|
+
});
|
|
181
|
+
messages.push(...recentMessages);
|
|
182
|
+
// Inject work log after emergency truncation
|
|
183
|
+
if (deps.workLog?.hasContent()) {
|
|
184
|
+
messages.push({ role: 'user', content: deps.workLog.toCompactString() });
|
|
185
|
+
}
|
|
186
|
+
// Update state messages too
|
|
187
|
+
deps.state.messages.length = 0;
|
|
188
|
+
deps.state.messages.push(...messages);
|
|
189
|
+
}
|
|
190
|
+
const tokensAfter = estimateContextTokens(messages);
|
|
191
|
+
const reduction = Math.round((1 - tokensAfter / tokensBefore) * 100);
|
|
192
|
+
if (tokensAfter < tokensBefore * 0.8) {
|
|
193
|
+
deps.observability?.logger?.info('Context reduction successful, continuing execution', { tokensBefore, tokensAfter, reduction });
|
|
194
|
+
deps.emit({ type: 'resilience.recovered', reason: 'budget_limit_compaction', attempts: 1 });
|
|
195
|
+
deps.emit({ type: 'compaction.auto', tokensBefore, tokensAfter, messagesCompacted: tokensBefore - tokensAfter });
|
|
196
|
+
deps.economics?.updateBaseline(tokensAfter);
|
|
197
|
+
return { action: 'recovery_success' };
|
|
198
|
+
}
|
|
199
|
+
deps.observability?.logger?.warn('Context reduction insufficient', {
|
|
200
|
+
tokensBefore, tokensAfter, reduction,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
// Hard limit reached and recovery failed
|
|
204
|
+
deps.observability?.logger?.warn('Budget limit reached', {
|
|
205
|
+
reason: budgetCheck.reason,
|
|
206
|
+
budgetType: budgetCheck.budgetType,
|
|
207
|
+
});
|
|
208
|
+
if (budgetCheck.budgetType === 'iterations') {
|
|
209
|
+
const totalIter = deps.getTotalIterations();
|
|
210
|
+
const iterMsg = deps.parentIterations > 0
|
|
211
|
+
? `${deps.state.iteration} + ${deps.parentIterations} parent = ${totalIter}`
|
|
212
|
+
: `${deps.state.iteration}`;
|
|
213
|
+
const reason = `Max iterations reached (${iterMsg})`;
|
|
214
|
+
deps.emit({ type: 'error', error: reason });
|
|
215
|
+
return { action: 'stop', result: { success: false, terminationReason: 'max_iterations', failureReason: reason } };
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
const reason = budgetCheck.reason || 'Budget exceeded';
|
|
219
|
+
deps.emit({ type: 'error', error: reason });
|
|
220
|
+
return { action: 'stop', result: { success: false, terminationReason: 'budget_limit', failureReason: reason } };
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
// Check for soft limits
|
|
224
|
+
if (budgetCheck.isSoftLimit && budgetCheck.suggestedAction === 'request_extension') {
|
|
225
|
+
deps.observability?.logger?.info('Approaching budget limit', {
|
|
226
|
+
reason: budgetCheck.reason,
|
|
227
|
+
percentUsed: budgetCheck.percentUsed,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
return { action: 'continue', forceTextOnly, budgetInjectedPrompt, budgetAllowsTaskContinuation };
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
// Fallback to simple iteration check
|
|
234
|
+
if (deps.getTotalIterations() >= deps.maxIterations) {
|
|
235
|
+
const totalIter = deps.getTotalIterations();
|
|
236
|
+
const reason = `Max iterations reached (${totalIter})`;
|
|
237
|
+
deps.observability?.logger?.warn('Max iterations reached', {
|
|
238
|
+
iteration: deps.state.iteration,
|
|
239
|
+
parentIterations: deps.parentIterations,
|
|
240
|
+
total: totalIter,
|
|
241
|
+
});
|
|
242
|
+
deps.emit({ type: 'error', error: reason });
|
|
243
|
+
return { action: 'stop', result: { success: false, terminationReason: 'max_iterations', failureReason: reason } };
|
|
244
|
+
}
|
|
245
|
+
return { action: 'continue', forceTextOnly: false, budgetAllowsTaskContinuation: true };
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Handle auto-compaction of context when approaching token limits.
|
|
250
|
+
* Returns the compaction status and whether messages were modified.
|
|
251
|
+
*/
|
|
252
|
+
export async function handleAutoCompaction(deps, messages, stateMessages, setCompactionPending) {
|
|
253
|
+
const currentContextTokens = estimateContextTokens(messages);
|
|
254
|
+
if (deps.autoCompactionManager) {
|
|
255
|
+
const compactionResult = await deps.autoCompactionManager.checkAndMaybeCompact({
|
|
256
|
+
currentTokens: currentContextTokens,
|
|
257
|
+
messages: messages,
|
|
258
|
+
});
|
|
259
|
+
if (compactionResult.status === 'compacted' && compactionResult.compactedMessages) {
|
|
260
|
+
if (!deps.compactionPending) {
|
|
261
|
+
setCompactionPending(true);
|
|
262
|
+
const preCompactionMsg = {
|
|
263
|
+
role: 'user',
|
|
264
|
+
content: '[SYSTEM] Context compaction is imminent. Summarize your current progress, key findings, and next steps into a single concise message. This will be preserved after compaction.',
|
|
265
|
+
};
|
|
266
|
+
messages.push(preCompactionMsg);
|
|
267
|
+
stateMessages.push(preCompactionMsg);
|
|
268
|
+
deps.observability?.logger?.info('Pre-compaction agentic turn: injected summary request');
|
|
269
|
+
return { status: 'compaction_prompt_injected' };
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
setCompactionPending(false);
|
|
273
|
+
// Replace messages with compacted version
|
|
274
|
+
messages.length = 0;
|
|
275
|
+
messages.push(...compactionResult.compactedMessages);
|
|
276
|
+
stateMessages.length = 0;
|
|
277
|
+
stateMessages.push(...compactionResult.compactedMessages);
|
|
278
|
+
// Inject work log after compaction
|
|
279
|
+
if (deps.workLog?.hasContent()) {
|
|
280
|
+
const workLogMessage = { role: 'user', content: deps.workLog.toCompactString() };
|
|
281
|
+
messages.push(workLogMessage);
|
|
282
|
+
stateMessages.push(workLogMessage);
|
|
283
|
+
}
|
|
284
|
+
// Context recovery
|
|
285
|
+
const recoveryParts = [];
|
|
286
|
+
if (deps.store) {
|
|
287
|
+
const goalsSummary = deps.store.getGoalsSummary();
|
|
288
|
+
if (goalsSummary && goalsSummary !== 'No active goals.' && goalsSummary !== 'Goals feature not available.') {
|
|
289
|
+
recoveryParts.push(goalsSummary);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
if (deps.store) {
|
|
293
|
+
const juncturesSummary = deps.store.getJuncturesSummary(undefined, 5);
|
|
294
|
+
if (juncturesSummary) {
|
|
295
|
+
recoveryParts.push(juncturesSummary);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (deps.learningStore) {
|
|
299
|
+
const learnings = deps.learningStore.getLearningContext({ maxLearnings: 3 });
|
|
300
|
+
if (learnings) {
|
|
301
|
+
recoveryParts.push(learnings);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
if (recoveryParts.length > 0) {
|
|
305
|
+
const recoveryMessage = {
|
|
306
|
+
role: 'user',
|
|
307
|
+
content: `[CONTEXT RECOVERY — Re-injected after compaction]\n\n${recoveryParts.join('\n\n')}`,
|
|
308
|
+
};
|
|
309
|
+
messages.push(recoveryMessage);
|
|
310
|
+
stateMessages.push(recoveryMessage);
|
|
311
|
+
}
|
|
312
|
+
const compactionTokensAfter = estimateContextTokens(messages);
|
|
313
|
+
deps.economics?.updateBaseline(compactionTokensAfter);
|
|
314
|
+
const compactionEvent = {
|
|
315
|
+
type: 'context.compacted',
|
|
316
|
+
tokensBefore: currentContextTokens,
|
|
317
|
+
tokensAfter: compactionTokensAfter,
|
|
318
|
+
recoveryInjected: recoveryParts.length > 0,
|
|
319
|
+
};
|
|
320
|
+
deps.emit(compactionEvent);
|
|
321
|
+
deps.traceCollector?.record({
|
|
322
|
+
type: 'context.compacted',
|
|
323
|
+
data: {
|
|
324
|
+
tokensBefore: currentContextTokens,
|
|
325
|
+
tokensAfter: compactionTokensAfter,
|
|
326
|
+
recoveryInjected: recoveryParts.length > 0,
|
|
327
|
+
},
|
|
328
|
+
});
|
|
329
|
+
return { status: 'compacted', tokensBefore: currentContextTokens, tokensAfter: compactionTokensAfter };
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
else if (compactionResult.status === 'hard_limit') {
|
|
333
|
+
const reason = `Context hard limit reached (${Math.round(compactionResult.ratio * 100)}% of max tokens)`;
|
|
334
|
+
deps.emit({ type: 'error', error: reason });
|
|
335
|
+
return {
|
|
336
|
+
status: 'hard_limit',
|
|
337
|
+
result: { success: false, terminationReason: 'hard_context_limit', failureReason: reason },
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
else if (deps.economics) {
|
|
342
|
+
// Fallback to simple compaction
|
|
343
|
+
const currentUsage = deps.economics.getUsage();
|
|
344
|
+
const budget = deps.economics.getBudget();
|
|
345
|
+
const percentUsed = (currentUsage.tokens / budget.maxTokens) * 100;
|
|
346
|
+
if (percentUsed >= 70) {
|
|
347
|
+
deps.observability?.logger?.info('Proactive compaction triggered', {
|
|
348
|
+
percentUsed: Math.round(percentUsed),
|
|
349
|
+
currentTokens: currentUsage.tokens,
|
|
350
|
+
maxTokens: budget.maxTokens,
|
|
351
|
+
});
|
|
352
|
+
compactToolOutputs(stateMessages);
|
|
353
|
+
return { status: 'simple_compaction_triggered' };
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
return { status: 'ok' };
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Guard against mass tool results overflowing the context window.
|
|
360
|
+
* Truncates tool results that would push total context beyond budget.
|
|
361
|
+
* Mutates toolResults in-place.
|
|
362
|
+
*/
|
|
363
|
+
export function applyContextOverflowGuard(deps, messages, toolResults) {
|
|
364
|
+
if (!deps.economics || toolResults.length <= 10)
|
|
365
|
+
return 0;
|
|
366
|
+
const preAccumTokens = estimateContextTokens(messages);
|
|
367
|
+
const budget = deps.economics.getBudget();
|
|
368
|
+
const availableTokens = budget.maxTokens * EXECUTION_LOOP_DEFAULTS.CONTEXT_SAFETY_RATIO - preAccumTokens;
|
|
369
|
+
const MAX_TOOL_OUTPUT_CHARS = EXECUTION_LOOP_DEFAULTS.MAX_TOOL_OUTPUT_CHARS;
|
|
370
|
+
let totalResultTokens = 0;
|
|
371
|
+
for (const r of toolResults) {
|
|
372
|
+
const c = typeof r.result === 'string' ? r.result : stableStringify(r.result);
|
|
373
|
+
totalResultTokens += estimateTokensFromCharCount(Math.min(c.length, MAX_TOOL_OUTPUT_CHARS));
|
|
374
|
+
}
|
|
375
|
+
if (totalResultTokens > availableTokens && availableTokens > 0) {
|
|
376
|
+
log.warn('Tool results would exceed context budget — truncating batch', {
|
|
377
|
+
resultCount: toolResults.length,
|
|
378
|
+
estimatedTokens: totalResultTokens,
|
|
379
|
+
availableTokens: Math.round(availableTokens),
|
|
380
|
+
});
|
|
381
|
+
let tokenBudget = availableTokens;
|
|
382
|
+
for (let i = 0; i < toolResults.length; i++) {
|
|
383
|
+
const c = typeof toolResults[i].result === 'string'
|
|
384
|
+
? toolResults[i].result
|
|
385
|
+
: stableStringify(toolResults[i].result);
|
|
386
|
+
const tokens = estimateTokensFromCharCount(Math.min(c.length, MAX_TOOL_OUTPUT_CHARS));
|
|
387
|
+
if (tokens > tokenBudget) {
|
|
388
|
+
const skipped = toolResults.length - i;
|
|
389
|
+
for (let j = i; j < toolResults.length; j++) {
|
|
390
|
+
toolResults[j] = {
|
|
391
|
+
callId: toolResults[j].callId,
|
|
392
|
+
result: `[Result omitted: context overflow guard — ${skipped} of ${toolResults.length} results skipped]`,
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
deps.emit({
|
|
396
|
+
type: 'safeguard.context_overflow_guard',
|
|
397
|
+
estimatedTokens: totalResultTokens,
|
|
398
|
+
maxTokens: budget.maxTokens,
|
|
399
|
+
toolResultsSkipped: skipped,
|
|
400
|
+
});
|
|
401
|
+
return skipped;
|
|
402
|
+
}
|
|
403
|
+
tokenBudget -= tokens;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
return 0;
|
|
101
407
|
}
|
|
102
408
|
// =============================================================================
|
|
103
409
|
// MAIN EXECUTION LOOP
|
|
@@ -132,12 +438,8 @@ export async function executeDirectly(task, messages, ctx, mutators) {
|
|
|
132
438
|
const reflectionConfig = ctx.config.reflection;
|
|
133
439
|
const reflectionEnabled = isFeatureEnabled(reflectionConfig);
|
|
134
440
|
const autoReflect = reflectionEnabled && reflectionConfig.autoReflect;
|
|
135
|
-
const maxReflectionAttempts = reflectionEnabled
|
|
136
|
-
|
|
137
|
-
: 1;
|
|
138
|
-
const confidenceThreshold = reflectionEnabled
|
|
139
|
-
? (reflectionConfig.confidenceThreshold || 0.8)
|
|
140
|
-
: 0.8;
|
|
441
|
+
const maxReflectionAttempts = reflectionEnabled ? reflectionConfig.maxAttempts || 3 : 1;
|
|
442
|
+
const confidenceThreshold = reflectionEnabled ? reflectionConfig.confidenceThreshold || 0.8 : 0.8;
|
|
141
443
|
let reflectionAttempt = 0;
|
|
142
444
|
let lastResponse = '';
|
|
143
445
|
let incompleteActionRetries = 0;
|
|
@@ -191,142 +493,33 @@ export async function executeDirectly(task, messages, ctx, mutators) {
|
|
|
191
493
|
}
|
|
192
494
|
}
|
|
193
495
|
// =======================================================================
|
|
194
|
-
// ECONOMICS CHECK (Token Budget)
|
|
496
|
+
// ECONOMICS CHECK (Token Budget) — delegated to checkIterationBudget()
|
|
195
497
|
// =======================================================================
|
|
196
498
|
let forceTextOnly = false;
|
|
197
499
|
let budgetInjectedPrompt;
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
});
|
|
217
|
-
ctx.state.metrics.retryCount = (ctx.state.metrics.retryCount ?? 0) + 1;
|
|
218
|
-
ctx.state._recoveryAttempted = true;
|
|
219
|
-
const tokensBefore = estimateContextTokens(messages);
|
|
220
|
-
// Step 1: Compact tool outputs aggressively
|
|
221
|
-
compactToolOutputs(ctx.state.messages);
|
|
222
|
-
// Step 2: Emergency truncation - keep system + last N messages
|
|
223
|
-
const PRESERVE_RECENT = 10;
|
|
224
|
-
if (messages.length > PRESERVE_RECENT + 2) {
|
|
225
|
-
const systemMessage = messages.find(m => m.role === 'system');
|
|
226
|
-
const recentMessages = messages.slice(-(PRESERVE_RECENT));
|
|
227
|
-
messages.length = 0;
|
|
228
|
-
if (systemMessage) {
|
|
229
|
-
messages.push(systemMessage);
|
|
230
|
-
}
|
|
231
|
-
messages.push({
|
|
232
|
-
role: 'system',
|
|
233
|
-
content: `[CONTEXT REDUCED: Earlier messages were removed to stay within budget. Conversation continues from recent context.]`,
|
|
234
|
-
});
|
|
235
|
-
messages.push(...recentMessages);
|
|
236
|
-
// Inject work log after emergency truncation
|
|
237
|
-
if (ctx.workLog?.hasContent()) {
|
|
238
|
-
const workLogMessage = {
|
|
239
|
-
role: 'user',
|
|
240
|
-
content: ctx.workLog.toCompactString(),
|
|
241
|
-
};
|
|
242
|
-
messages.push(workLogMessage);
|
|
243
|
-
}
|
|
244
|
-
// Update state messages too
|
|
245
|
-
ctx.state.messages.length = 0;
|
|
246
|
-
ctx.state.messages.push(...messages);
|
|
247
|
-
}
|
|
248
|
-
const tokensAfter = estimateContextTokens(messages);
|
|
249
|
-
const reduction = Math.round((1 - tokensAfter / tokensBefore) * 100);
|
|
250
|
-
if (tokensAfter < tokensBefore * 0.8) {
|
|
251
|
-
ctx.observability?.logger?.info('Context reduction successful, continuing execution', {
|
|
252
|
-
tokensBefore,
|
|
253
|
-
tokensAfter,
|
|
254
|
-
reduction,
|
|
255
|
-
});
|
|
256
|
-
ctx.emit({
|
|
257
|
-
type: 'resilience.recovered',
|
|
258
|
-
reason: 'budget_limit_compaction',
|
|
259
|
-
attempts: 1,
|
|
260
|
-
});
|
|
261
|
-
ctx.emit({
|
|
262
|
-
type: 'compaction.auto',
|
|
263
|
-
tokensBefore,
|
|
264
|
-
tokensAfter,
|
|
265
|
-
messagesCompacted: tokensBefore - tokensAfter,
|
|
266
|
-
});
|
|
267
|
-
continue;
|
|
268
|
-
}
|
|
269
|
-
ctx.observability?.logger?.warn('Context reduction insufficient', {
|
|
270
|
-
tokensBefore,
|
|
271
|
-
tokensAfter,
|
|
272
|
-
reduction,
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
|
-
// Hard limit reached and recovery failed
|
|
276
|
-
ctx.observability?.logger?.warn('Budget limit reached', {
|
|
277
|
-
reason: budgetCheck.reason,
|
|
278
|
-
budgetType: budgetCheck.budgetType,
|
|
279
|
-
});
|
|
280
|
-
if (budgetCheck.budgetType === 'iterations') {
|
|
281
|
-
const totalIter = ctx.getTotalIterations();
|
|
282
|
-
const iterMsg = ctx.parentIterations > 0
|
|
283
|
-
? `${ctx.state.iteration} + ${ctx.parentIterations} parent = ${totalIter}`
|
|
284
|
-
: `${ctx.state.iteration}`;
|
|
285
|
-
const reason = `Max iterations reached (${iterMsg})`;
|
|
286
|
-
ctx.emit({ type: 'error', error: reason });
|
|
287
|
-
result = {
|
|
288
|
-
success: false,
|
|
289
|
-
terminationReason: 'max_iterations',
|
|
290
|
-
failureReason: reason,
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
else {
|
|
294
|
-
const reason = budgetCheck.reason || 'Budget exceeded';
|
|
295
|
-
ctx.emit({ type: 'error', error: reason });
|
|
296
|
-
result = {
|
|
297
|
-
success: false,
|
|
298
|
-
terminationReason: 'budget_limit',
|
|
299
|
-
failureReason: reason,
|
|
300
|
-
};
|
|
301
|
-
}
|
|
302
|
-
break;
|
|
303
|
-
}
|
|
304
|
-
// Check for soft limits and potential extension
|
|
305
|
-
if (budgetCheck.isSoftLimit && budgetCheck.suggestedAction === 'request_extension') {
|
|
306
|
-
ctx.observability?.logger?.info('Approaching budget limit', {
|
|
307
|
-
reason: budgetCheck.reason,
|
|
308
|
-
percentUsed: budgetCheck.percentUsed,
|
|
309
|
-
});
|
|
310
|
-
}
|
|
500
|
+
let budgetAllowsTaskContinuation = true;
|
|
501
|
+
const budgetResult = checkIterationBudget({
|
|
502
|
+
economics: ctx.economics,
|
|
503
|
+
getTotalIterations: () => ctx.getTotalIterations(),
|
|
504
|
+
maxIterations: ctx.config.maxIterations,
|
|
505
|
+
parentIterations: ctx.parentIterations,
|
|
506
|
+
state: ctx.state,
|
|
507
|
+
workLog: ctx.workLog,
|
|
508
|
+
observability: ctx.observability,
|
|
509
|
+
traceCollector: ctx.traceCollector,
|
|
510
|
+
emit: (event) => ctx.emit(event),
|
|
511
|
+
}, messages);
|
|
512
|
+
if (budgetResult.action === 'recovery_success') {
|
|
513
|
+
continue;
|
|
514
|
+
}
|
|
515
|
+
else if (budgetResult.action === 'stop') {
|
|
516
|
+
result = budgetResult.result;
|
|
517
|
+
break;
|
|
311
518
|
}
|
|
312
519
|
else {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
const reason = `Max iterations reached (${totalIter})`;
|
|
317
|
-
ctx.observability?.logger?.warn('Max iterations reached', {
|
|
318
|
-
iteration: ctx.state.iteration,
|
|
319
|
-
parentIterations: ctx.parentIterations,
|
|
320
|
-
total: totalIter,
|
|
321
|
-
});
|
|
322
|
-
ctx.emit({ type: 'error', error: reason });
|
|
323
|
-
result = {
|
|
324
|
-
success: false,
|
|
325
|
-
terminationReason: 'max_iterations',
|
|
326
|
-
failureReason: reason,
|
|
327
|
-
};
|
|
328
|
-
break;
|
|
329
|
-
}
|
|
520
|
+
forceTextOnly = budgetResult.forceTextOnly;
|
|
521
|
+
budgetInjectedPrompt = budgetResult.budgetInjectedPrompt;
|
|
522
|
+
budgetAllowsTaskContinuation = budgetResult.budgetAllowsTaskContinuation;
|
|
330
523
|
}
|
|
331
524
|
// =======================================================================
|
|
332
525
|
// GRACEFUL WRAPUP CHECK
|
|
@@ -372,15 +565,17 @@ export async function executeDirectly(task, messages, ctx, mutators) {
|
|
|
372
565
|
}
|
|
373
566
|
const enrichedMessages = ctx.contextEngineering.injectRecitation(messages, {
|
|
374
567
|
goal: task,
|
|
375
|
-
plan: ctx.state.plan
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
568
|
+
plan: ctx.state.plan
|
|
569
|
+
? {
|
|
570
|
+
description: ctx.state.plan.goal || task,
|
|
571
|
+
tasks: ctx.state.plan.tasks.map((t) => ({
|
|
572
|
+
id: t.id,
|
|
573
|
+
description: t.description,
|
|
574
|
+
status: t.status,
|
|
575
|
+
})),
|
|
576
|
+
currentTaskIndex: ctx.state.plan.tasks.findIndex((t) => t.status === 'in_progress'),
|
|
577
|
+
}
|
|
578
|
+
: undefined,
|
|
384
579
|
activeFiles: ctx.economics?.getProgress().filesModified
|
|
385
580
|
? [`${ctx.economics.getProgress().filesModified} files modified`]
|
|
386
581
|
: undefined,
|
|
@@ -388,7 +583,9 @@ export async function executeDirectly(task, messages, ctx, mutators) {
|
|
|
388
583
|
});
|
|
389
584
|
if (process.env.DEBUG_LLM) {
|
|
390
585
|
if (process.env.DEBUG)
|
|
391
|
-
log.debug('Recitation after', {
|
|
586
|
+
log.debug('Recitation after', {
|
|
587
|
+
messageCount: enrichedMessages?.length ?? 'null/undefined',
|
|
588
|
+
});
|
|
392
589
|
}
|
|
393
590
|
if (enrichedMessages && enrichedMessages !== messages && enrichedMessages.length > 0) {
|
|
394
591
|
messages.length = 0;
|
|
@@ -397,7 +594,7 @@ export async function executeDirectly(task, messages, ctx, mutators) {
|
|
|
397
594
|
else if (!enrichedMessages || enrichedMessages.length === 0) {
|
|
398
595
|
log.warn('Recitation returned empty/null messages, keeping original');
|
|
399
596
|
}
|
|
400
|
-
const contextTokens = messages
|
|
597
|
+
const contextTokens = estimateContextTokens(messages);
|
|
401
598
|
ctx.contextEngineering.updateRecitationFrequency(contextTokens);
|
|
402
599
|
}
|
|
403
600
|
// =======================================================================
|
|
@@ -424,7 +621,9 @@ export async function executeDirectly(task, messages, ctx, mutators) {
|
|
|
424
621
|
// =======================================================================
|
|
425
622
|
// RESUME ORIENTATION — after compaction, nudge the agent to act, not re-summarize
|
|
426
623
|
// =======================================================================
|
|
427
|
-
const hasCompactionSummary = messages.some(m => m.role === 'system' &&
|
|
624
|
+
const hasCompactionSummary = messages.some((m) => m.role === 'system' &&
|
|
625
|
+
typeof m.content === 'string' &&
|
|
626
|
+
m.content.includes('[Conversation Summary'));
|
|
428
627
|
if (hasCompactionSummary && ctx.state.iteration <= 2) {
|
|
429
628
|
messages.push({
|
|
430
629
|
role: 'user',
|
|
@@ -437,31 +636,48 @@ export async function executeDirectly(task, messages, ctx, mutators) {
|
|
|
437
636
|
if (ctx.injectionBudget) {
|
|
438
637
|
const proposals = [];
|
|
439
638
|
if (budgetInjectedPrompt) {
|
|
440
|
-
proposals.push({
|
|
639
|
+
proposals.push({
|
|
640
|
+
name: 'budget_warning',
|
|
641
|
+
priority: 0,
|
|
642
|
+
maxTokens: 500,
|
|
643
|
+
content: budgetInjectedPrompt,
|
|
644
|
+
});
|
|
441
645
|
}
|
|
442
646
|
if (ctx.contextEngineering) {
|
|
443
647
|
const failureCtx = ctx.contextEngineering.getFailureContext(5);
|
|
444
648
|
if (failureCtx) {
|
|
445
|
-
proposals.push({
|
|
649
|
+
proposals.push({
|
|
650
|
+
name: 'failure_context',
|
|
651
|
+
priority: 2,
|
|
652
|
+
maxTokens: 300,
|
|
653
|
+
content: failureCtx,
|
|
654
|
+
});
|
|
446
655
|
}
|
|
447
656
|
}
|
|
448
657
|
if (proposals.length > 0) {
|
|
449
658
|
const accepted = ctx.injectionBudget.allocate(proposals);
|
|
450
659
|
const stats = ctx.injectionBudget.getLastStats();
|
|
451
660
|
if (stats && stats.droppedNames.length > 0 && process.env.DEBUG) {
|
|
452
|
-
log.debug('Injection budget dropped items', {
|
|
661
|
+
log.debug('Injection budget dropped items', {
|
|
662
|
+
droppedNames: stats.droppedNames.join(', '),
|
|
663
|
+
proposedTokens: stats.proposedTokens,
|
|
664
|
+
acceptedTokens: stats.acceptedTokens,
|
|
665
|
+
});
|
|
453
666
|
}
|
|
454
667
|
if (stats && process.env.DEBUG_LLM) {
|
|
455
|
-
log.debug('Injection budget summary', {
|
|
668
|
+
log.debug('Injection budget summary', {
|
|
669
|
+
iteration: ctx.state.iteration,
|
|
670
|
+
accepted: accepted.length,
|
|
671
|
+
total: proposals.length,
|
|
672
|
+
tokens: stats.acceptedTokens,
|
|
673
|
+
});
|
|
456
674
|
}
|
|
457
675
|
}
|
|
458
676
|
}
|
|
459
677
|
// =======================================================================
|
|
460
678
|
// RESILIENT LLM CALL
|
|
461
679
|
// =======================================================================
|
|
462
|
-
const resilienceConfig = typeof ctx.config.resilience === 'object'
|
|
463
|
-
? ctx.config.resilience
|
|
464
|
-
: {};
|
|
680
|
+
const resilienceConfig = typeof ctx.config.resilience === 'object' ? ctx.config.resilience : {};
|
|
465
681
|
const resilienceEnabled = isFeatureEnabled(ctx.config.resilience);
|
|
466
682
|
const MAX_EMPTY_RETRIES = resilienceConfig.maxEmptyRetries ?? 2;
|
|
467
683
|
const MAX_CONTINUATIONS = resilienceConfig.maxContinuations ?? 3;
|
|
@@ -475,6 +691,7 @@ export async function executeDirectly(task, messages, ctx, mutators) {
|
|
|
475
691
|
const estimatedInputTokens = estimateContextTokens(messages);
|
|
476
692
|
const currentUsage = ctx.economics.getUsage();
|
|
477
693
|
const budget = ctx.economics.getBudget();
|
|
694
|
+
const isStrictEnforcement = (budget.enforcementMode ?? 'strict') === 'strict';
|
|
478
695
|
// Use proportional output estimate: 10% of remaining budget, capped at 4096, floored at 512.
|
|
479
696
|
// The old hardcoded 4096 caused premature wrapup for subagents with smaller budgets.
|
|
480
697
|
const remainingTokens = budget.maxTokens - currentUsage.tokens - estimatedInputTokens;
|
|
@@ -486,21 +703,67 @@ export async function executeDirectly(task, messages, ctx, mutators) {
|
|
|
486
703
|
estimatedInput: estimatedInputTokens,
|
|
487
704
|
projectedTotal,
|
|
488
705
|
maxTokens: budget.maxTokens,
|
|
706
|
+
enforcementMode: budget.enforcementMode ?? 'strict',
|
|
489
707
|
});
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
708
|
+
// Only force text-only in strict mode. In doomloop_only mode,
|
|
709
|
+
// the pre-flight check warns but does not kill the agent.
|
|
710
|
+
// NEVER force text-only on the first iteration — an agent that hasn't
|
|
711
|
+
// made a single tool call yet should always get at least one chance.
|
|
712
|
+
// This prevents swarm workers from being killed before they can work.
|
|
713
|
+
if (isStrictEnforcement && ctx.state.iteration > 1) {
|
|
714
|
+
if (!budgetInjectedPrompt) {
|
|
715
|
+
messages.push({
|
|
716
|
+
role: 'user',
|
|
717
|
+
content: '[System] BUDGET CRITICAL: This is your LAST response. Summarize findings concisely and stop. Do NOT call tools.',
|
|
718
|
+
});
|
|
719
|
+
ctx.state.messages.push({
|
|
720
|
+
role: 'user',
|
|
721
|
+
content: '[System] BUDGET CRITICAL: This is your LAST response. Summarize findings concisely and stop. Do NOT call tools.',
|
|
722
|
+
});
|
|
723
|
+
}
|
|
724
|
+
forceTextOnly = true;
|
|
499
725
|
}
|
|
500
|
-
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
// EARLY EXIT: When forceTextOnly is set but task continuation is allowed,
|
|
729
|
+
// skip the expensive LLM call (whose tool calls would be discarded) and
|
|
730
|
+
// go directly to the task continuation gate. Only allowed once per
|
|
731
|
+
// forceTextOnly episode to prevent tight loops.
|
|
732
|
+
if (forceTextOnly &&
|
|
733
|
+
budgetAllowsTaskContinuation &&
|
|
734
|
+
ctx.taskManager &&
|
|
735
|
+
!ctx.state._lastSkippedLLMIteration) {
|
|
736
|
+
const availableTasks = ctx.taskManager.getAvailableTasks();
|
|
737
|
+
if (availableTasks.length > 0) {
|
|
738
|
+
log.info('Skipping LLM call — forceTextOnly with tasks available, going to task continuation', {
|
|
739
|
+
availableTasks: availableTasks.length,
|
|
740
|
+
iteration: ctx.state.iteration,
|
|
741
|
+
});
|
|
742
|
+
// Mark that we skipped so we don't skip again on the next iteration
|
|
743
|
+
ctx.state._lastSkippedLLMIteration =
|
|
744
|
+
ctx.state.iteration;
|
|
745
|
+
// Reset forceTextOnly for the next iteration so the task can run normally
|
|
746
|
+
forceTextOnly = false;
|
|
747
|
+
const nextTask = availableTasks[0];
|
|
748
|
+
ctx.taskManager.claim(nextTask.id, ctx.agentId);
|
|
749
|
+
const taskPrompt = {
|
|
750
|
+
role: 'user',
|
|
751
|
+
content: `[System] Budget warning noted. Continuing with next task:\n\n**Task ${nextTask.id}: ${nextTask.subject}**\n${nextTask.description}\n\nStart working on this task now using your tools.`,
|
|
752
|
+
};
|
|
753
|
+
messages.push(taskPrompt);
|
|
754
|
+
ctx.state.messages.push(taskPrompt);
|
|
755
|
+
ctx.emit({
|
|
756
|
+
type: 'iteration.after',
|
|
757
|
+
iteration: ctx.state.iteration,
|
|
758
|
+
hadToolCalls: false,
|
|
759
|
+
completionCandidate: false,
|
|
760
|
+
});
|
|
761
|
+
continue; // Re-enter main loop for next task without wasting an LLM call
|
|
501
762
|
}
|
|
502
763
|
}
|
|
503
764
|
let response = await callLLM(messages, ctx);
|
|
765
|
+
// Clear the LLM-skip guard now that we've made a real LLM call
|
|
766
|
+
delete ctx.state._lastSkippedLLMIteration;
|
|
504
767
|
let emptyRetries = 0;
|
|
505
768
|
let continuations = 0;
|
|
506
769
|
// Phase 1: Handle empty responses with retry
|
|
@@ -570,7 +833,10 @@ export async function executeDirectly(task, messages, ctx, mutators) {
|
|
|
570
833
|
response = await callLLM(messages, ctx);
|
|
571
834
|
}
|
|
572
835
|
// Phase 2: Handle max_tokens truncation with continuation
|
|
573
|
-
if (resilienceEnabled &&
|
|
836
|
+
if (resilienceEnabled &&
|
|
837
|
+
AUTO_CONTINUE &&
|
|
838
|
+
response.stopReason === 'max_tokens' &&
|
|
839
|
+
!response.toolCalls?.length) {
|
|
574
840
|
let accumulatedContent = response.content || '';
|
|
575
841
|
while (continuations < MAX_CONTINUATIONS && response.stopReason === 'max_tokens') {
|
|
576
842
|
continuations++;
|
|
@@ -614,10 +880,10 @@ export async function executeDirectly(task, messages, ctx, mutators) {
|
|
|
614
880
|
if (resilienceEnabled && response.stopReason === 'max_tokens' && response.toolCalls?.length) {
|
|
615
881
|
ctx.emit({
|
|
616
882
|
type: 'resilience.truncated_tool_call',
|
|
617
|
-
toolNames: response.toolCalls.map(tc => tc.name),
|
|
883
|
+
toolNames: response.toolCalls.map((tc) => tc.name),
|
|
618
884
|
});
|
|
619
885
|
ctx.observability?.logger?.warn('Tool call truncated at max_tokens', {
|
|
620
|
-
toolNames: response.toolCalls.map(tc => tc.name),
|
|
886
|
+
toolNames: response.toolCalls.map((tc) => tc.name),
|
|
621
887
|
outputTokens: response.usage?.outputTokens,
|
|
622
888
|
});
|
|
623
889
|
const truncatedResponse = response;
|
|
@@ -637,7 +903,7 @@ export async function executeDirectly(task, messages, ctx, mutators) {
|
|
|
637
903
|
}
|
|
638
904
|
// Record LLM usage for economics
|
|
639
905
|
if (ctx.economics && response.usage) {
|
|
640
|
-
ctx.economics.recordLLMUsage(response.usage.inputTokens, response.usage.outputTokens, ctx.config.model, response.usage.cost);
|
|
906
|
+
ctx.economics.recordLLMUsage(response.usage.inputTokens, response.usage.outputTokens, ctx.config.model, response.usage.cost, response.usage.cacheReadTokens);
|
|
641
907
|
// POST-LLM BUDGET CHECK
|
|
642
908
|
if (!forceTextOnly) {
|
|
643
909
|
const postCheck = ctx.economics.checkBudget();
|
|
@@ -660,9 +926,12 @@ export async function executeDirectly(task, messages, ctx, mutators) {
|
|
|
660
926
|
ctx.state.messages.push(assistantMessage);
|
|
661
927
|
lastResponse = response.content || (response.thinking ? response.thinking : '');
|
|
662
928
|
// Plan mode: capture exploration findings
|
|
663
|
-
if (ctx.modeManager.getMode() === 'plan' &&
|
|
664
|
-
|
|
665
|
-
|
|
929
|
+
if (ctx.modeManager.getMode() === 'plan' &&
|
|
930
|
+
response.content &&
|
|
931
|
+
response.content.length > 50) {
|
|
932
|
+
const hasReadOnlyTools = response.toolCalls?.every((tc) => ['read_file', 'list_files', 'glob', 'grep', 'search', 'mcp_'].some((prefix) => tc.name.startsWith(prefix) || tc.name === prefix));
|
|
933
|
+
if (hasReadOnlyTools &&
|
|
934
|
+
!response.content.match(/^(Let me|I'll|I will|I need to|First,)/i)) {
|
|
666
935
|
ctx.pendingPlanManager.appendExplorationFinding(response.content.slice(0, 1000));
|
|
667
936
|
}
|
|
668
937
|
}
|
|
@@ -683,10 +952,10 @@ export async function executeDirectly(task, messages, ctx, mutators) {
|
|
|
683
952
|
const missingRequiredArtifact = ENFORCE_REQUESTED_ARTIFACTS
|
|
684
953
|
? isRequestedArtifactMissing(requestedArtifact, executedToolNames)
|
|
685
954
|
: false;
|
|
686
|
-
const shouldRecoverIncompleteAction = resilienceEnabled
|
|
687
|
-
&&
|
|
688
|
-
|
|
689
|
-
|
|
955
|
+
const shouldRecoverIncompleteAction = resilienceEnabled &&
|
|
956
|
+
INCOMPLETE_ACTION_RECOVERY &&
|
|
957
|
+
!forceTextOnly &&
|
|
958
|
+
(incompleteAction || missingRequiredArtifact);
|
|
690
959
|
if (shouldRecoverIncompleteAction) {
|
|
691
960
|
ctx.emit({
|
|
692
961
|
type: 'completion.before',
|
|
@@ -778,6 +1047,45 @@ export async function executeDirectly(task, messages, ctx, mutators) {
|
|
|
778
1047
|
});
|
|
779
1048
|
incompleteActionRetries = 0;
|
|
780
1049
|
}
|
|
1050
|
+
// TypeScript compilation gate — block completion if TS files edited and errors exist
|
|
1051
|
+
if (ctx.typeCheckerState?.tsconfigDir &&
|
|
1052
|
+
!forceTextOnly &&
|
|
1053
|
+
(ctx.typeCheckerState.tsEditsSinceLastCheck > 0 || !ctx.typeCheckerState.hasRunOnce)) {
|
|
1054
|
+
const tscResult = await runTypeCheck(ctx.typeCheckerState.tsconfigDir);
|
|
1055
|
+
ctx.typeCheckerState.tsEditsSinceLastCheck = 0;
|
|
1056
|
+
ctx.typeCheckerState.lastResult = tscResult;
|
|
1057
|
+
ctx.typeCheckerState.hasRunOnce = true;
|
|
1058
|
+
ctx.verificationGate?.recordCompilationResult(tscResult.success, tscResult.errorCount);
|
|
1059
|
+
ctx.emit({
|
|
1060
|
+
type: 'diagnostics.tsc-check',
|
|
1061
|
+
errorCount: tscResult.errorCount,
|
|
1062
|
+
duration: tscResult.duration,
|
|
1063
|
+
trigger: 'completion',
|
|
1064
|
+
});
|
|
1065
|
+
if (!tscResult.success) {
|
|
1066
|
+
const vState = ctx.verificationGate?.getState();
|
|
1067
|
+
const maxCompNudges = 8;
|
|
1068
|
+
if (!vState || (vState.compilationNudgeCount ?? 0) < maxCompNudges) {
|
|
1069
|
+
const nudge = formatTypeCheckNudge(tscResult);
|
|
1070
|
+
const nudgeMessage = { role: 'user', content: nudge };
|
|
1071
|
+
messages.push(nudgeMessage);
|
|
1072
|
+
ctx.state.messages.push(nudgeMessage);
|
|
1073
|
+
ctx.verificationGate?.incrementCompilationNudge();
|
|
1074
|
+
log.info('Compilation gate blocked completion', {
|
|
1075
|
+
count: tscResult.errorCount,
|
|
1076
|
+
nudgeCount: ctx.verificationGate?.getState().compilationNudgeCount,
|
|
1077
|
+
});
|
|
1078
|
+
ctx.emit({
|
|
1079
|
+
type: 'iteration.after',
|
|
1080
|
+
iteration: ctx.state.iteration,
|
|
1081
|
+
hadToolCalls: false,
|
|
1082
|
+
completionCandidate: false,
|
|
1083
|
+
});
|
|
1084
|
+
continue; // Re-enter main loop — agent must fix errors
|
|
1085
|
+
}
|
|
1086
|
+
// If exceeded max nudges, fall through to verification gate (which will forceAllow)
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
781
1089
|
// Verification gate
|
|
782
1090
|
if (ctx.verificationGate && !forceTextOnly) {
|
|
783
1091
|
const vResult = ctx.verificationGate.check();
|
|
@@ -851,7 +1159,7 @@ export async function executeDirectly(task, messages, ctx, mutators) {
|
|
|
851
1159
|
});
|
|
852
1160
|
const pendingWithOwner = getPendingWithOwnerCount(ctx);
|
|
853
1161
|
const availableTasks = ctx.taskManager.getAvailableTasks();
|
|
854
|
-
if (!forceTextOnly && availableTasks.length > 0) {
|
|
1162
|
+
if ((!forceTextOnly || budgetAllowsTaskContinuation) && availableTasks.length > 0) {
|
|
855
1163
|
const nextTask = availableTasks[0];
|
|
856
1164
|
ctx.taskManager.claim(nextTask.id, ctx.agentId);
|
|
857
1165
|
log.info('Picking up next task from task list', {
|
|
@@ -896,7 +1204,9 @@ export async function executeDirectly(task, messages, ctx, mutators) {
|
|
|
896
1204
|
}
|
|
897
1205
|
const reasons = [
|
|
898
1206
|
`Open tasks remain: ${openTasks.pending} pending, ${openTasks.inProgress} in_progress`,
|
|
899
|
-
openTasks.blocked > 0
|
|
1207
|
+
openTasks.blocked > 0
|
|
1208
|
+
? `${openTasks.blocked} pending tasks are currently blocked`
|
|
1209
|
+
: '',
|
|
900
1210
|
].filter(Boolean);
|
|
901
1211
|
ctx.emit({
|
|
902
1212
|
type: 'completion.blocked',
|
|
@@ -926,7 +1236,7 @@ export async function executeDirectly(task, messages, ctx, mutators) {
|
|
|
926
1236
|
log.warn('Tool call explosion detected — capping', {
|
|
927
1237
|
requested: toolCalls.length,
|
|
928
1238
|
cap: maxToolCallsPerResponse,
|
|
929
|
-
toolNames: [...new Set(toolCalls.map(tc => tc.name))],
|
|
1239
|
+
toolNames: [...new Set(toolCalls.map((tc) => tc.name))],
|
|
930
1240
|
});
|
|
931
1241
|
ctx.emit({
|
|
932
1242
|
type: 'safeguard.tool_call_cap',
|
|
@@ -953,7 +1263,9 @@ export async function executeDirectly(task, messages, ctx, mutators) {
|
|
|
953
1263
|
// Record in work log
|
|
954
1264
|
const toolOutput = result?.result && typeof result.result === 'object' && 'output' in result.result
|
|
955
1265
|
? String(result.result.output)
|
|
956
|
-
: typeof result?.result === 'string'
|
|
1266
|
+
: typeof result?.result === 'string'
|
|
1267
|
+
? result.result
|
|
1268
|
+
: undefined;
|
|
957
1269
|
ctx.workLog?.recordToolExecution(toolCall.name, toolCall.arguments, toolOutput);
|
|
958
1270
|
// Record in verification gate
|
|
959
1271
|
if (ctx.verificationGate) {
|
|
@@ -961,9 +1273,11 @@ export async function executeDirectly(task, messages, ctx, mutators) {
|
|
|
961
1273
|
const toolRes = result?.result;
|
|
962
1274
|
const output = toolRes && typeof toolRes === 'object' && 'output' in toolRes
|
|
963
1275
|
? String(toolRes.output)
|
|
964
|
-
: typeof toolRes === 'string'
|
|
1276
|
+
: typeof toolRes === 'string'
|
|
1277
|
+
? toolRes
|
|
1278
|
+
: '';
|
|
965
1279
|
const exitCode = toolRes && typeof toolRes === 'object' && toolRes.metadata
|
|
966
|
-
? toolRes.metadata.exitCode ?? null
|
|
1280
|
+
? (toolRes.metadata.exitCode ?? null)
|
|
967
1281
|
: null;
|
|
968
1282
|
ctx.verificationGate.recordBashExecution(String(toolCall.arguments.command || ''), output, exitCode);
|
|
969
1283
|
}
|
|
@@ -971,201 +1285,100 @@ export async function executeDirectly(task, messages, ctx, mutators) {
|
|
|
971
1285
|
ctx.verificationGate.recordFileChange();
|
|
972
1286
|
}
|
|
973
1287
|
}
|
|
974
|
-
// Phase 5.1: Post-edit syntax validation
|
|
975
|
-
if (['write_file', 'edit_file'].includes(toolCall.name) &&
|
|
1288
|
+
// Phase 5.1: Post-edit syntax validation + AST cache invalidation
|
|
1289
|
+
if (['write_file', 'edit_file'].includes(toolCall.name) &&
|
|
1290
|
+
result?.result &&
|
|
1291
|
+
result.result.success) {
|
|
976
1292
|
const filePath = String(toolCall.arguments.path || '');
|
|
977
1293
|
if (filePath) {
|
|
1294
|
+
// Invalidate stale AST cache entry so next analysis/validation reparses
|
|
1295
|
+
invalidateAST(filePath);
|
|
978
1296
|
try {
|
|
979
1297
|
const content = toolCall.name === 'write_file'
|
|
980
1298
|
? String(toolCall.arguments.content || '')
|
|
981
1299
|
: await fs.promises.readFile(filePath, 'utf-8');
|
|
1300
|
+
// Update codebase context first — fullReparse caches the AST tree,
|
|
1301
|
+
// so validateSyntax below will use the cached tree (no double-parse)
|
|
1302
|
+
if (ctx.codebaseContext) {
|
|
1303
|
+
try {
|
|
1304
|
+
await ctx.codebaseContext.updateFile(filePath, content);
|
|
1305
|
+
}
|
|
1306
|
+
catch {
|
|
1307
|
+
/* non-blocking */
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
982
1310
|
const validation = validateSyntax(content, filePath);
|
|
983
1311
|
if (!validation.valid && result.result && typeof result.result === 'object') {
|
|
984
1312
|
const errorSummary = validation.errors
|
|
985
1313
|
.slice(0, 3)
|
|
986
|
-
.map(e => ` L${e.line}:${e.column}: ${e.message}`)
|
|
1314
|
+
.map((e) => ` L${e.line}:${e.column}: ${e.message}`)
|
|
987
1315
|
.join('\n');
|
|
988
|
-
result.result.output +=
|
|
1316
|
+
result.result.output +=
|
|
1317
|
+
`\n\n⚠ Syntax validation warning:\n${errorSummary}`;
|
|
1318
|
+
// Emit diagnostic events for each syntax error
|
|
1319
|
+
for (const err of validation.errors.slice(0, 5)) {
|
|
1320
|
+
ctx.emit({
|
|
1321
|
+
type: 'diagnostics.syntax-error',
|
|
1322
|
+
file: filePath,
|
|
1323
|
+
line: err.line,
|
|
1324
|
+
message: err.message,
|
|
1325
|
+
});
|
|
1326
|
+
}
|
|
989
1327
|
}
|
|
990
1328
|
}
|
|
991
1329
|
catch {
|
|
992
1330
|
// Validation failure is non-blocking
|
|
993
1331
|
}
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
// Add tool results to messages (with truncation and proactive budget management)
|
|
998
|
-
const MAX_TOOL_OUTPUT_CHARS = 8000;
|
|
999
|
-
// PROACTIVE BUDGET CHECK
|
|
1000
|
-
const currentContextTokens = estimateContextTokens(messages);
|
|
1001
|
-
if (ctx.autoCompactionManager) {
|
|
1002
|
-
const compactionResult = await ctx.autoCompactionManager.checkAndMaybeCompact({
|
|
1003
|
-
currentTokens: currentContextTokens,
|
|
1004
|
-
messages: messages,
|
|
1005
|
-
});
|
|
1006
|
-
if (compactionResult.status === 'compacted' && compactionResult.compactedMessages) {
|
|
1007
|
-
if (!ctx.compactionPending) {
|
|
1008
|
-
mutators.setCompactionPending(true);
|
|
1009
|
-
const preCompactionMsg = {
|
|
1010
|
-
role: 'user',
|
|
1011
|
-
content: '[SYSTEM] Context compaction is imminent. Summarize your current progress, key findings, and next steps into a single concise message. This will be preserved after compaction.',
|
|
1012
|
-
};
|
|
1013
|
-
messages.push(preCompactionMsg);
|
|
1014
|
-
ctx.state.messages.push(preCompactionMsg);
|
|
1015
|
-
ctx.observability?.logger?.info('Pre-compaction agentic turn: injected summary request');
|
|
1016
|
-
}
|
|
1017
|
-
else {
|
|
1018
|
-
mutators.setCompactionPending(false);
|
|
1019
|
-
// Pre-compaction checkpoint
|
|
1020
|
-
// NOTE: autoCheckpoint is called via the agent's method, not directly here
|
|
1021
|
-
// The agent wires this through the mutators pattern
|
|
1022
|
-
// Replace messages with compacted version
|
|
1023
|
-
messages.length = 0;
|
|
1024
|
-
messages.push(...compactionResult.compactedMessages);
|
|
1025
|
-
ctx.state.messages.length = 0;
|
|
1026
|
-
ctx.state.messages.push(...compactionResult.compactedMessages);
|
|
1027
|
-
// Inject work log after compaction
|
|
1028
|
-
if (ctx.workLog?.hasContent()) {
|
|
1029
|
-
const workLogMessage = {
|
|
1030
|
-
role: 'user',
|
|
1031
|
-
content: ctx.workLog.toCompactString(),
|
|
1032
|
-
};
|
|
1033
|
-
messages.push(workLogMessage);
|
|
1034
|
-
ctx.state.messages.push(workLogMessage);
|
|
1035
|
-
}
|
|
1036
|
-
// Context recovery
|
|
1037
|
-
const recoveryParts = [];
|
|
1038
|
-
if (ctx.store) {
|
|
1039
|
-
const goalsSummary = ctx.store.getGoalsSummary();
|
|
1040
|
-
if (goalsSummary && goalsSummary !== 'No active goals.' && goalsSummary !== 'Goals feature not available.') {
|
|
1041
|
-
recoveryParts.push(goalsSummary);
|
|
1042
|
-
}
|
|
1043
|
-
}
|
|
1044
|
-
if (ctx.store) {
|
|
1045
|
-
const juncturesSummary = ctx.store.getJuncturesSummary(undefined, 5);
|
|
1046
|
-
if (juncturesSummary) {
|
|
1047
|
-
recoveryParts.push(juncturesSummary);
|
|
1048
|
-
}
|
|
1049
|
-
}
|
|
1050
|
-
if (ctx.learningStore) {
|
|
1051
|
-
const learnings = ctx.learningStore.getLearningContext({ maxLearnings: 3 });
|
|
1052
|
-
if (learnings) {
|
|
1053
|
-
recoveryParts.push(learnings);
|
|
1054
|
-
}
|
|
1055
|
-
}
|
|
1056
|
-
if (recoveryParts.length > 0) {
|
|
1057
|
-
const recoveryMessage = {
|
|
1058
|
-
role: 'user',
|
|
1059
|
-
content: `[CONTEXT RECOVERY — Re-injected after compaction]\n\n${recoveryParts.join('\n\n')}`,
|
|
1060
|
-
};
|
|
1061
|
-
messages.push(recoveryMessage);
|
|
1062
|
-
ctx.state.messages.push(recoveryMessage);
|
|
1063
|
-
}
|
|
1064
|
-
// Emit compaction event
|
|
1065
|
-
const compactionTokensAfter = estimateContextTokens(messages);
|
|
1066
|
-
const compactionRecoveryInjected = recoveryParts.length > 0;
|
|
1067
|
-
const compactionEvent = {
|
|
1068
|
-
type: 'context.compacted',
|
|
1069
|
-
tokensBefore: currentContextTokens,
|
|
1070
|
-
tokensAfter: compactionTokensAfter,
|
|
1071
|
-
recoveryInjected: compactionRecoveryInjected,
|
|
1072
|
-
};
|
|
1073
|
-
ctx.emit(compactionEvent);
|
|
1074
|
-
if (ctx.traceCollector) {
|
|
1075
|
-
ctx.traceCollector.record({
|
|
1076
|
-
type: 'context.compacted',
|
|
1077
|
-
data: {
|
|
1078
|
-
tokensBefore: currentContextTokens,
|
|
1079
|
-
tokensAfter: compactionTokensAfter,
|
|
1080
|
-
recoveryInjected: compactionRecoveryInjected,
|
|
1081
|
-
},
|
|
1082
|
-
});
|
|
1332
|
+
// Track .ts/.tsx edits for periodic type checking
|
|
1333
|
+
if (ctx.typeCheckerState?.tsconfigDir && /\.(ts|tsx)$/.test(filePath)) {
|
|
1334
|
+
ctx.typeCheckerState.tsEditsSinceLastCheck++;
|
|
1083
1335
|
}
|
|
1084
1336
|
}
|
|
1085
1337
|
}
|
|
1086
|
-
else if (compactionResult.status === 'hard_limit') {
|
|
1087
|
-
const reason = `Context hard limit reached (${Math.round(compactionResult.ratio * 100)}% of max tokens)`;
|
|
1088
|
-
ctx.emit({ type: 'error', error: reason });
|
|
1089
|
-
result = {
|
|
1090
|
-
success: false,
|
|
1091
|
-
terminationReason: 'hard_context_limit',
|
|
1092
|
-
failureReason: reason,
|
|
1093
|
-
};
|
|
1094
|
-
break;
|
|
1095
|
-
}
|
|
1096
1338
|
}
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
}
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
const budget = ctx.economics.getBudget();
|
|
1115
|
-
const availableTokens = budget.maxTokens * 0.90 - preAccumTokens;
|
|
1116
|
-
// Estimate total result tokens
|
|
1117
|
-
let totalResultTokens = 0;
|
|
1118
|
-
for (const r of toolResults) {
|
|
1119
|
-
const c = typeof r.result === 'string' ? r.result : stableStringify(r.result);
|
|
1120
|
-
totalResultTokens += Math.ceil(Math.min(c.length, MAX_TOOL_OUTPUT_CHARS) / 4);
|
|
1121
|
-
}
|
|
1122
|
-
if (totalResultTokens > availableTokens && availableTokens > 0) {
|
|
1123
|
-
log.warn('Tool results would exceed context budget — truncating batch', {
|
|
1124
|
-
resultCount: toolResults.length,
|
|
1125
|
-
estimatedTokens: totalResultTokens,
|
|
1126
|
-
availableTokens: Math.round(availableTokens),
|
|
1127
|
-
});
|
|
1128
|
-
let tokenBudget = availableTokens;
|
|
1129
|
-
for (let i = 0; i < toolResults.length; i++) {
|
|
1130
|
-
const c = typeof toolResults[i].result === 'string'
|
|
1131
|
-
? toolResults[i].result
|
|
1132
|
-
: stableStringify(toolResults[i].result);
|
|
1133
|
-
const tokens = Math.ceil(Math.min(c.length, MAX_TOOL_OUTPUT_CHARS) / 4);
|
|
1134
|
-
if (tokens > tokenBudget) {
|
|
1135
|
-
const skipped = toolResults.length - i;
|
|
1136
|
-
for (let j = i; j < toolResults.length; j++) {
|
|
1137
|
-
toolResults[j] = {
|
|
1138
|
-
callId: toolResults[j].callId,
|
|
1139
|
-
result: `[Result omitted: context overflow guard — ${skipped} of ${toolResults.length} results skipped]`,
|
|
1140
|
-
};
|
|
1141
|
-
}
|
|
1142
|
-
ctx.emit({
|
|
1143
|
-
type: 'safeguard.context_overflow_guard',
|
|
1144
|
-
estimatedTokens: totalResultTokens,
|
|
1145
|
-
maxTokens: budget.maxTokens,
|
|
1146
|
-
toolResultsSkipped: skipped,
|
|
1147
|
-
});
|
|
1148
|
-
break;
|
|
1149
|
-
}
|
|
1150
|
-
tokenBudget -= tokens;
|
|
1151
|
-
}
|
|
1152
|
-
}
|
|
1339
|
+
// Add tool results to messages (with truncation and proactive budget management)
|
|
1340
|
+
const MAX_TOOL_OUTPUT_CHARS = EXECUTION_LOOP_DEFAULTS.MAX_TOOL_OUTPUT_CHARS;
|
|
1341
|
+
// PROACTIVE BUDGET CHECK — delegate to extracted function
|
|
1342
|
+
const compactionStatus = await handleAutoCompaction({
|
|
1343
|
+
autoCompactionManager: ctx.autoCompactionManager ?? null,
|
|
1344
|
+
compactionPending: ctx.compactionPending,
|
|
1345
|
+
economics: ctx.economics,
|
|
1346
|
+
workLog: ctx.workLog,
|
|
1347
|
+
store: ctx.store,
|
|
1348
|
+
learningStore: ctx.learningStore,
|
|
1349
|
+
observability: ctx.observability,
|
|
1350
|
+
traceCollector: ctx.traceCollector,
|
|
1351
|
+
emit: (event) => ctx.emit(event),
|
|
1352
|
+
}, messages, ctx.state.messages, (v) => mutators.setCompactionPending(v));
|
|
1353
|
+
if (compactionStatus.status === 'hard_limit') {
|
|
1354
|
+
result = compactionStatus.result;
|
|
1355
|
+
break;
|
|
1153
1356
|
}
|
|
1154
|
-
|
|
1357
|
+
// SAFEGUARD: Aggregate context guard — delegate to extracted function
|
|
1358
|
+
applyContextOverflowGuard({ economics: ctx.economics, emit: (event) => ctx.emit(event) }, messages, toolResults);
|
|
1359
|
+
const toolCallNameById = new Map(toolCalls.map((tc) => [tc.id, tc.name]));
|
|
1155
1360
|
for (const result of toolResults) {
|
|
1156
|
-
let content = typeof result.result === 'string'
|
|
1361
|
+
let content = typeof result.result === 'string'
|
|
1362
|
+
? result.result
|
|
1363
|
+
: ctx.contextEngineering
|
|
1364
|
+
? ctx.contextEngineering.serialize(result.result)
|
|
1365
|
+
: stableStringify(result.result);
|
|
1157
1366
|
const sourceToolName = toolCallNameById.get(result.callId);
|
|
1158
1367
|
const isExpensiveResult = sourceToolName === 'spawn_agent' || sourceToolName === 'spawn_agents_parallel';
|
|
1159
|
-
const effectiveMaxChars = isExpensiveResult
|
|
1368
|
+
const effectiveMaxChars = isExpensiveResult
|
|
1369
|
+
? MAX_TOOL_OUTPUT_CHARS * 2
|
|
1370
|
+
: MAX_TOOL_OUTPUT_CHARS;
|
|
1160
1371
|
if (content.length > effectiveMaxChars) {
|
|
1161
|
-
content =
|
|
1372
|
+
content =
|
|
1373
|
+
content.slice(0, effectiveMaxChars) +
|
|
1374
|
+
`\n\n... [truncated ${content.length - effectiveMaxChars} chars]`;
|
|
1162
1375
|
}
|
|
1163
1376
|
// Check if adding this result would exceed budget
|
|
1164
1377
|
if (ctx.economics) {
|
|
1165
|
-
const estimatedNewTokens =
|
|
1378
|
+
const estimatedNewTokens = estimateTokenCount(content);
|
|
1166
1379
|
const currentCtxTokens = estimateContextTokens(messages);
|
|
1167
1380
|
const budget = ctx.economics.getBudget();
|
|
1168
|
-
if (currentCtxTokens + estimatedNewTokens > budget.maxTokens *
|
|
1381
|
+
if (currentCtxTokens + estimatedNewTokens > budget.maxTokens * EXECUTION_LOOP_DEFAULTS.PER_RESULT_BUDGET_RATIO) {
|
|
1169
1382
|
ctx.observability?.logger?.warn('Skipping tool result to stay within budget', {
|
|
1170
1383
|
toolCallId: result.callId,
|
|
1171
1384
|
estimatedTokens: estimatedNewTokens,
|
|
@@ -1199,6 +1412,30 @@ export async function executeDirectly(task, messages, ctx, mutators) {
|
|
|
1199
1412
|
messages.push(toolMessage);
|
|
1200
1413
|
ctx.state.messages.push(toolMessage);
|
|
1201
1414
|
}
|
|
1415
|
+
// Periodic TypeScript compilation check (every 5 TS edits)
|
|
1416
|
+
const TYPE_CHECK_EDIT_THRESHOLD = EXECUTION_LOOP_DEFAULTS.TYPE_CHECK_EDIT_THRESHOLD;
|
|
1417
|
+
if (ctx.typeCheckerState?.tsconfigDir &&
|
|
1418
|
+
ctx.typeCheckerState.tsEditsSinceLastCheck >= TYPE_CHECK_EDIT_THRESHOLD &&
|
|
1419
|
+
!forceTextOnly) {
|
|
1420
|
+
const tscResult = await runTypeCheck(ctx.typeCheckerState.tsconfigDir);
|
|
1421
|
+
ctx.typeCheckerState.tsEditsSinceLastCheck = 0;
|
|
1422
|
+
ctx.typeCheckerState.lastResult = tscResult;
|
|
1423
|
+
ctx.typeCheckerState.hasRunOnce = true;
|
|
1424
|
+
ctx.verificationGate?.recordCompilationResult(tscResult.success, tscResult.errorCount);
|
|
1425
|
+
ctx.emit({
|
|
1426
|
+
type: 'diagnostics.tsc-check',
|
|
1427
|
+
errorCount: tscResult.errorCount,
|
|
1428
|
+
duration: tscResult.duration,
|
|
1429
|
+
trigger: 'periodic',
|
|
1430
|
+
});
|
|
1431
|
+
if (!tscResult.success) {
|
|
1432
|
+
const nudge = formatTypeCheckNudge(tscResult);
|
|
1433
|
+
const infoMsg = { role: 'user', content: nudge };
|
|
1434
|
+
messages.push(infoMsg);
|
|
1435
|
+
ctx.state.messages.push(infoMsg);
|
|
1436
|
+
log.info('Periodic tsc check found errors', { count: tscResult.errorCount });
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1202
1439
|
// Emit context health
|
|
1203
1440
|
const currentTokenEstimate = estimateContextTokens(messages);
|
|
1204
1441
|
const contextLimit = ctx.getMaxContextTokens();
|