@substrate-ai/factory 0.19.54
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/config.test.d.ts +11 -0
- package/dist/__tests__/config.test.d.ts.map +1 -0
- package/dist/__tests__/config.test.js +215 -0
- package/dist/__tests__/config.test.js.map +1 -0
- package/dist/__tests__/factory-run-command.test.d.ts +12 -0
- package/dist/__tests__/factory-run-command.test.d.ts.map +1 -0
- package/dist/__tests__/factory-run-command.test.js +454 -0
- package/dist/__tests__/factory-run-command.test.js.map +1 -0
- package/dist/__tests__/factory-validate-command.test.d.ts +15 -0
- package/dist/__tests__/factory-validate-command.test.d.ts.map +1 -0
- package/dist/__tests__/factory-validate-command.test.js +339 -0
- package/dist/__tests__/factory-validate-command.test.js.map +1 -0
- package/dist/__tests__/fixtures/advanced-cross-project-validation.dot.d.ts +72 -0
- package/dist/__tests__/fixtures/advanced-cross-project-validation.dot.d.ts.map +1 -0
- package/dist/__tests__/fixtures/advanced-cross-project-validation.dot.js +121 -0
- package/dist/__tests__/fixtures/advanced-cross-project-validation.dot.js.map +1 -0
- package/dist/__tests__/fixtures/llm-edge-routing.dot.d.ts +28 -0
- package/dist/__tests__/fixtures/llm-edge-routing.dot.d.ts.map +1 -0
- package/dist/__tests__/fixtures/llm-edge-routing.dot.js +55 -0
- package/dist/__tests__/fixtures/llm-edge-routing.dot.js.map +1 -0
- package/dist/__tests__/fixtures/manager-loop.dot.d.ts +34 -0
- package/dist/__tests__/fixtures/manager-loop.dot.d.ts.map +1 -0
- package/dist/__tests__/fixtures/manager-loop.dot.js +61 -0
- package/dist/__tests__/fixtures/manager-loop.dot.js.map +1 -0
- package/dist/__tests__/fixtures/parallel-fan-out-fan-in.dot.d.ts +42 -0
- package/dist/__tests__/fixtures/parallel-fan-out-fan-in.dot.d.ts.map +1 -0
- package/dist/__tests__/fixtures/parallel-fan-out-fan-in.dot.js +118 -0
- package/dist/__tests__/fixtures/parallel-fan-out-fan-in.dot.js.map +1 -0
- package/dist/__tests__/fixtures/subgraph-parent.dot.d.ts +35 -0
- package/dist/__tests__/fixtures/subgraph-parent.dot.d.ts.map +1 -0
- package/dist/__tests__/fixtures/subgraph-parent.dot.js +69 -0
- package/dist/__tests__/fixtures/subgraph-parent.dot.js.map +1 -0
- package/dist/__tests__/integration/advanced-graph-events.test.d.ts +19 -0
- package/dist/__tests__/integration/advanced-graph-events.test.d.ts.map +1 -0
- package/dist/__tests__/integration/advanced-graph-events.test.js +288 -0
- package/dist/__tests__/integration/advanced-graph-events.test.js.map +1 -0
- package/dist/__tests__/integration/checkpoint-resume.test.d.ts +10 -0
- package/dist/__tests__/integration/checkpoint-resume.test.d.ts.map +1 -0
- package/dist/__tests__/integration/checkpoint-resume.test.js +125 -0
- package/dist/__tests__/integration/checkpoint-resume.test.js.map +1 -0
- package/dist/__tests__/integration/conditional-pipeline.test.d.ts +10 -0
- package/dist/__tests__/integration/conditional-pipeline.test.d.ts.map +1 -0
- package/dist/__tests__/integration/conditional-pipeline.test.js +106 -0
- package/dist/__tests__/integration/conditional-pipeline.test.js.map +1 -0
- package/dist/__tests__/integration/convergence-validation.test.d.ts +14 -0
- package/dist/__tests__/integration/convergence-validation.test.d.ts.map +1 -0
- package/dist/__tests__/integration/convergence-validation.test.js +449 -0
- package/dist/__tests__/integration/convergence-validation.test.js.map +1 -0
- package/dist/__tests__/integration/epic44-coverage-gate.test.d.ts +12 -0
- package/dist/__tests__/integration/epic44-coverage-gate.test.d.ts.map +1 -0
- package/dist/__tests__/integration/epic44-coverage-gate.test.js +58 -0
- package/dist/__tests__/integration/epic44-coverage-gate.test.js.map +1 -0
- package/dist/__tests__/integration/epic45-coverage-gate.test.d.ts +11 -0
- package/dist/__tests__/integration/epic45-coverage-gate.test.d.ts.map +1 -0
- package/dist/__tests__/integration/epic45-coverage-gate.test.js +64 -0
- package/dist/__tests__/integration/epic45-coverage-gate.test.js.map +1 -0
- package/dist/__tests__/integration/epic46-scenario-primary-executor.test.d.ts +2 -0
- package/dist/__tests__/integration/epic46-scenario-primary-executor.test.d.ts.map +1 -0
- package/dist/__tests__/integration/epic46-scenario-primary-executor.test.js +285 -0
- package/dist/__tests__/integration/epic46-scenario-primary-executor.test.js.map +1 -0
- package/dist/__tests__/integration/events.test.d.ts +8 -0
- package/dist/__tests__/integration/events.test.d.ts.map +1 -0
- package/dist/__tests__/integration/events.test.js +194 -0
- package/dist/__tests__/integration/events.test.js.map +1 -0
- package/dist/__tests__/integration/graphs.d.ts +59 -0
- package/dist/__tests__/integration/graphs.d.ts.map +1 -0
- package/dist/__tests__/integration/graphs.js +164 -0
- package/dist/__tests__/integration/graphs.js.map +1 -0
- package/dist/__tests__/integration/helpers.d.ts +127 -0
- package/dist/__tests__/integration/helpers.d.ts.map +1 -0
- package/dist/__tests__/integration/helpers.js +167 -0
- package/dist/__tests__/integration/helpers.js.map +1 -0
- package/dist/__tests__/integration/integrity.test.d.ts +8 -0
- package/dist/__tests__/integration/integrity.test.d.ts.map +1 -0
- package/dist/__tests__/integration/integrity.test.js +198 -0
- package/dist/__tests__/integration/integrity.test.js.map +1 -0
- package/dist/__tests__/integration/llm-edge-routing.test.d.ts +21 -0
- package/dist/__tests__/integration/llm-edge-routing.test.d.ts.map +1 -0
- package/dist/__tests__/integration/llm-edge-routing.test.js +341 -0
- package/dist/__tests__/integration/llm-edge-routing.test.js.map +1 -0
- package/dist/__tests__/integration/manager-loop.test.d.ts +24 -0
- package/dist/__tests__/integration/manager-loop.test.d.ts.map +1 -0
- package/dist/__tests__/integration/manager-loop.test.js +276 -0
- package/dist/__tests__/integration/manager-loop.test.js.map +1 -0
- package/dist/__tests__/integration/multi-type-graph.test.d.ts +10 -0
- package/dist/__tests__/integration/multi-type-graph.test.d.ts.map +1 -0
- package/dist/__tests__/integration/multi-type-graph.test.js +100 -0
- package/dist/__tests__/integration/multi-type-graph.test.js.map +1 -0
- package/dist/__tests__/integration/parallel-fan-out-fan-in.test.d.ts +22 -0
- package/dist/__tests__/integration/parallel-fan-out-fan-in.test.d.ts.map +1 -0
- package/dist/__tests__/integration/parallel-fan-out-fan-in.test.js +515 -0
- package/dist/__tests__/integration/parallel-fan-out-fan-in.test.js.map +1 -0
- package/dist/__tests__/integration/persistence.test.d.ts +8 -0
- package/dist/__tests__/integration/persistence.test.d.ts.map +1 -0
- package/dist/__tests__/integration/persistence.test.js +129 -0
- package/dist/__tests__/integration/persistence.test.js.map +1 -0
- package/dist/__tests__/integration/pipeline-templates-integration.test.d.ts +16 -0
- package/dist/__tests__/integration/pipeline-templates-integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/pipeline-templates-integration.test.js +171 -0
- package/dist/__tests__/integration/pipeline-templates-integration.test.js.map +1 -0
- package/dist/__tests__/integration/scenario-pipeline.test.d.ts +11 -0
- package/dist/__tests__/integration/scenario-pipeline.test.d.ts.map +1 -0
- package/dist/__tests__/integration/scenario-pipeline.test.js +243 -0
- package/dist/__tests__/integration/scenario-pipeline.test.js.map +1 -0
- package/dist/__tests__/integration/stylesheet-application.test.d.ts +12 -0
- package/dist/__tests__/integration/stylesheet-application.test.d.ts.map +1 -0
- package/dist/__tests__/integration/stylesheet-application.test.js +119 -0
- package/dist/__tests__/integration/stylesheet-application.test.js.map +1 -0
- package/dist/__tests__/integration/subgraph-execution.test.d.ts +24 -0
- package/dist/__tests__/integration/subgraph-execution.test.d.ts.map +1 -0
- package/dist/__tests__/integration/subgraph-execution.test.js +291 -0
- package/dist/__tests__/integration/subgraph-execution.test.js.map +1 -0
- package/dist/__tests__/integration/validation-errors.test.d.ts +8 -0
- package/dist/__tests__/integration/validation-errors.test.d.ts.map +1 -0
- package/dist/__tests__/integration/validation-errors.test.js +150 -0
- package/dist/__tests__/integration/validation-errors.test.js.map +1 -0
- package/dist/agent/__tests__/loop-detection.test.d.ts +2 -0
- package/dist/agent/__tests__/loop-detection.test.d.ts.map +1 -0
- package/dist/agent/__tests__/loop-detection.test.js +236 -0
- package/dist/agent/__tests__/loop-detection.test.js.map +1 -0
- package/dist/agent/__tests__/loop.test.d.ts +2 -0
- package/dist/agent/__tests__/loop.test.d.ts.map +1 -0
- package/dist/agent/__tests__/loop.test.js +868 -0
- package/dist/agent/__tests__/loop.test.js.map +1 -0
- package/dist/agent/__tests__/truncation.test.d.ts +2 -0
- package/dist/agent/__tests__/truncation.test.d.ts.map +1 -0
- package/dist/agent/__tests__/truncation.test.js +276 -0
- package/dist/agent/__tests__/truncation.test.js.map +1 -0
- package/dist/agent/index.d.ts +11 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +13 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/loop-detection.d.ts +21 -0
- package/dist/agent/loop-detection.d.ts.map +1 -0
- package/dist/agent/loop-detection.js +61 -0
- package/dist/agent/loop-detection.js.map +1 -0
- package/dist/agent/loop.d.ts +88 -0
- package/dist/agent/loop.d.ts.map +1 -0
- package/dist/agent/loop.js +411 -0
- package/dist/agent/loop.js.map +1 -0
- package/dist/agent/tools/__tests__/anthropic-tools.test.d.ts +6 -0
- package/dist/agent/tools/__tests__/anthropic-tools.test.d.ts.map +1 -0
- package/dist/agent/tools/__tests__/anthropic-tools.test.js +49 -0
- package/dist/agent/tools/__tests__/anthropic-tools.test.js.map +1 -0
- package/dist/agent/tools/__tests__/environment.test.d.ts +6 -0
- package/dist/agent/tools/__tests__/environment.test.d.ts.map +1 -0
- package/dist/agent/tools/__tests__/environment.test.js +33 -0
- package/dist/agent/tools/__tests__/environment.test.js.map +1 -0
- package/dist/agent/tools/__tests__/gemini-tools.test.d.ts +6 -0
- package/dist/agent/tools/__tests__/gemini-tools.test.d.ts.map +1 -0
- package/dist/agent/tools/__tests__/gemini-tools.test.js +98 -0
- package/dist/agent/tools/__tests__/gemini-tools.test.js.map +1 -0
- package/dist/agent/tools/__tests__/openai-tools.test.d.ts +6 -0
- package/dist/agent/tools/__tests__/openai-tools.test.d.ts.map +1 -0
- package/dist/agent/tools/__tests__/openai-tools.test.js +53 -0
- package/dist/agent/tools/__tests__/openai-tools.test.js.map +1 -0
- package/dist/agent/tools/__tests__/patch.test.d.ts +6 -0
- package/dist/agent/tools/__tests__/patch.test.d.ts.map +1 -0
- package/dist/agent/tools/__tests__/patch.test.js +116 -0
- package/dist/agent/tools/__tests__/patch.test.js.map +1 -0
- package/dist/agent/tools/__tests__/profiles.test.d.ts +6 -0
- package/dist/agent/tools/__tests__/profiles.test.d.ts.map +1 -0
- package/dist/agent/tools/__tests__/profiles.test.js +125 -0
- package/dist/agent/tools/__tests__/profiles.test.js.map +1 -0
- package/dist/agent/tools/__tests__/registry.test.d.ts +6 -0
- package/dist/agent/tools/__tests__/registry.test.d.ts.map +1 -0
- package/dist/agent/tools/__tests__/registry.test.js +94 -0
- package/dist/agent/tools/__tests__/registry.test.js.map +1 -0
- package/dist/agent/tools/__tests__/shared.test.d.ts +6 -0
- package/dist/agent/tools/__tests__/shared.test.d.ts.map +1 -0
- package/dist/agent/tools/__tests__/shared.test.js +131 -0
- package/dist/agent/tools/__tests__/shared.test.js.map +1 -0
- package/dist/agent/tools/anthropic-tools.d.ts +15 -0
- package/dist/agent/tools/anthropic-tools.d.ts.map +1 -0
- package/dist/agent/tools/anthropic-tools.js +45 -0
- package/dist/agent/tools/anthropic-tools.js.map +1 -0
- package/dist/agent/tools/environment.d.ts +11 -0
- package/dist/agent/tools/environment.d.ts.map +1 -0
- package/dist/agent/tools/environment.js +35 -0
- package/dist/agent/tools/environment.js.map +1 -0
- package/dist/agent/tools/gemini-tools.d.ts +29 -0
- package/dist/agent/tools/gemini-tools.d.ts.map +1 -0
- package/dist/agent/tools/gemini-tools.js +112 -0
- package/dist/agent/tools/gemini-tools.js.map +1 -0
- package/dist/agent/tools/index.d.ts +13 -0
- package/dist/agent/tools/index.d.ts.map +1 -0
- package/dist/agent/tools/index.js +13 -0
- package/dist/agent/tools/index.js.map +1 -0
- package/dist/agent/tools/openai-tools.d.ts +18 -0
- package/dist/agent/tools/openai-tools.d.ts.map +1 -0
- package/dist/agent/tools/openai-tools.js +208 -0
- package/dist/agent/tools/openai-tools.js.map +1 -0
- package/dist/agent/tools/profiles.d.ts +66 -0
- package/dist/agent/tools/profiles.d.ts.map +1 -0
- package/dist/agent/tools/profiles.js +121 -0
- package/dist/agent/tools/profiles.js.map +1 -0
- package/dist/agent/tools/registry.d.ts +16 -0
- package/dist/agent/tools/registry.d.ts.map +1 -0
- package/dist/agent/tools/registry.js +55 -0
- package/dist/agent/tools/registry.js.map +1 -0
- package/dist/agent/tools/shared.d.ts +10 -0
- package/dist/agent/tools/shared.d.ts.map +1 -0
- package/dist/agent/tools/shared.js +207 -0
- package/dist/agent/tools/shared.js.map +1 -0
- package/dist/agent/tools/types.d.ts +55 -0
- package/dist/agent/tools/types.d.ts.map +1 -0
- package/dist/agent/tools/types.js +14 -0
- package/dist/agent/tools/types.js.map +1 -0
- package/dist/agent/truncation.d.ts +29 -0
- package/dist/agent/truncation.d.ts.map +1 -0
- package/dist/agent/truncation.js +76 -0
- package/dist/agent/truncation.js.map +1 -0
- package/dist/agent/types.d.ts +91 -0
- package/dist/agent/types.d.ts.map +1 -0
- package/dist/agent/types.js +45 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/backend/__tests__/direct-backend.test.d.ts +14 -0
- package/dist/backend/__tests__/direct-backend.test.d.ts.map +1 -0
- package/dist/backend/__tests__/direct-backend.test.js +393 -0
- package/dist/backend/__tests__/direct-backend.test.js.map +1 -0
- package/dist/backend/__tests__/direct-bootstrap.test.d.ts +7 -0
- package/dist/backend/__tests__/direct-bootstrap.test.d.ts.map +1 -0
- package/dist/backend/__tests__/direct-bootstrap.test.js +177 -0
- package/dist/backend/__tests__/direct-bootstrap.test.js.map +1 -0
- package/dist/backend/__tests__/mock-backend.test.d.ts +7 -0
- package/dist/backend/__tests__/mock-backend.test.d.ts.map +1 -0
- package/dist/backend/__tests__/mock-backend.test.js +273 -0
- package/dist/backend/__tests__/mock-backend.test.js.map +1 -0
- package/dist/backend/__tests__/parity.test.d.ts +17 -0
- package/dist/backend/__tests__/parity.test.d.ts.map +1 -0
- package/dist/backend/__tests__/parity.test.js +411 -0
- package/dist/backend/__tests__/parity.test.js.map +1 -0
- package/dist/backend/direct-backend.d.ts +27 -0
- package/dist/backend/direct-backend.d.ts.map +1 -0
- package/dist/backend/direct-backend.js +76 -0
- package/dist/backend/direct-backend.js.map +1 -0
- package/dist/backend/direct-bootstrap.d.ts +29 -0
- package/dist/backend/direct-bootstrap.d.ts.map +1 -0
- package/dist/backend/direct-bootstrap.js +109 -0
- package/dist/backend/direct-bootstrap.js.map +1 -0
- package/dist/backend/index.d.ts +11 -0
- package/dist/backend/index.d.ts.map +1 -0
- package/dist/backend/index.js +8 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/mock-backend.d.ts +49 -0
- package/dist/backend/mock-backend.d.ts.map +1 -0
- package/dist/backend/mock-backend.js +87 -0
- package/dist/backend/mock-backend.js.map +1 -0
- package/dist/backend/types.d.ts +74 -0
- package/dist/backend/types.d.ts.map +1 -0
- package/dist/backend/types.js +12 -0
- package/dist/backend/types.js.map +1 -0
- package/dist/config.d.ts +196 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +140 -0
- package/dist/config.js.map +1 -0
- package/dist/context/__tests__/auto-summarizer.test.d.ts +14 -0
- package/dist/context/__tests__/auto-summarizer.test.d.ts.map +1 -0
- package/dist/context/__tests__/auto-summarizer.test.js +189 -0
- package/dist/context/__tests__/auto-summarizer.test.js.map +1 -0
- package/dist/context/__tests__/context-cli-command.test.d.ts +7 -0
- package/dist/context/__tests__/context-cli-command.test.d.ts.map +1 -0
- package/dist/context/__tests__/context-cli-command.test.js +331 -0
- package/dist/context/__tests__/context-cli-command.test.js.map +1 -0
- package/dist/context/__tests__/pyramid-summary-integration.test.d.ts +2 -0
- package/dist/context/__tests__/pyramid-summary-integration.test.d.ts.map +1 -0
- package/dist/context/__tests__/pyramid-summary-integration.test.js +533 -0
- package/dist/context/__tests__/pyramid-summary-integration.test.js.map +1 -0
- package/dist/context/__tests__/summarizer.test.d.ts +2 -0
- package/dist/context/__tests__/summarizer.test.d.ts.map +1 -0
- package/dist/context/__tests__/summarizer.test.js +189 -0
- package/dist/context/__tests__/summarizer.test.js.map +1 -0
- package/dist/context/__tests__/summary-cache.test.d.ts +2 -0
- package/dist/context/__tests__/summary-cache.test.d.ts.map +1 -0
- package/dist/context/__tests__/summary-cache.test.js +214 -0
- package/dist/context/__tests__/summary-cache.test.js.map +1 -0
- package/dist/context/__tests__/summary-metrics.test.d.ts +2 -0
- package/dist/context/__tests__/summary-metrics.test.d.ts.map +1 -0
- package/dist/context/__tests__/summary-metrics.test.js +172 -0
- package/dist/context/__tests__/summary-metrics.test.js.map +1 -0
- package/dist/context/__tests__/summary-types.test.d.ts +2 -0
- package/dist/context/__tests__/summary-types.test.d.ts.map +1 -0
- package/dist/context/__tests__/summary-types.test.js +130 -0
- package/dist/context/__tests__/summary-types.test.js.map +1 -0
- package/dist/context/auto-summarizer.d.ts +120 -0
- package/dist/context/auto-summarizer.d.ts.map +1 -0
- package/dist/context/auto-summarizer.js +91 -0
- package/dist/context/auto-summarizer.js.map +1 -0
- package/dist/context/cli-command.d.ts +109 -0
- package/dist/context/cli-command.d.ts.map +1 -0
- package/dist/context/cli-command.js +382 -0
- package/dist/context/cli-command.js.map +1 -0
- package/dist/context/index.d.ts +8 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +8 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/summarizer.d.ts +12 -0
- package/dist/context/summarizer.d.ts.map +1 -0
- package/dist/context/summarizer.js +105 -0
- package/dist/context/summarizer.js.map +1 -0
- package/dist/context/summary-cache.d.ts +41 -0
- package/dist/context/summary-cache.d.ts.map +1 -0
- package/dist/context/summary-cache.js +80 -0
- package/dist/context/summary-cache.js.map +1 -0
- package/dist/context/summary-engine.d.ts +46 -0
- package/dist/context/summary-engine.d.ts.map +1 -0
- package/dist/context/summary-engine.js +2 -0
- package/dist/context/summary-engine.js.map +1 -0
- package/dist/context/summary-metrics.d.ts +75 -0
- package/dist/context/summary-metrics.d.ts.map +1 -0
- package/dist/context/summary-metrics.js +160 -0
- package/dist/context/summary-metrics.js.map +1 -0
- package/dist/context/summary-types.d.ts +103 -0
- package/dist/context/summary-types.d.ts.map +1 -0
- package/dist/context/summary-types.js +39 -0
- package/dist/context/summary-types.js.map +1 -0
- package/dist/convergence/__tests__/budget.test.d.ts +6 -0
- package/dist/convergence/__tests__/budget.test.d.ts.map +1 -0
- package/dist/convergence/__tests__/budget.test.js +187 -0
- package/dist/convergence/__tests__/budget.test.js.map +1 -0
- package/dist/convergence/__tests__/controller.test.d.ts +9 -0
- package/dist/convergence/__tests__/controller.test.d.ts.map +1 -0
- package/dist/convergence/__tests__/controller.test.js +585 -0
- package/dist/convergence/__tests__/controller.test.js.map +1 -0
- package/dist/convergence/__tests__/dual-signal.test.d.ts +14 -0
- package/dist/convergence/__tests__/dual-signal.test.d.ts.map +1 -0
- package/dist/convergence/__tests__/dual-signal.test.js +123 -0
- package/dist/convergence/__tests__/dual-signal.test.js.map +1 -0
- package/dist/convergence/__tests__/epic46-integration.test.d.ts +15 -0
- package/dist/convergence/__tests__/epic46-integration.test.d.ts.map +1 -0
- package/dist/convergence/__tests__/epic46-integration.test.js +522 -0
- package/dist/convergence/__tests__/epic46-integration.test.js.map +1 -0
- package/dist/convergence/__tests__/plateau.test.d.ts +6 -0
- package/dist/convergence/__tests__/plateau.test.d.ts.map +1 -0
- package/dist/convergence/__tests__/plateau.test.js +163 -0
- package/dist/convergence/__tests__/plateau.test.js.map +1 -0
- package/dist/convergence/__tests__/remediation.test.d.ts +11 -0
- package/dist/convergence/__tests__/remediation.test.d.ts.map +1 -0
- package/dist/convergence/__tests__/remediation.test.js +209 -0
- package/dist/convergence/__tests__/remediation.test.js.map +1 -0
- package/dist/convergence/__tests__/scenario-primary.test.d.ts +13 -0
- package/dist/convergence/__tests__/scenario-primary.test.d.ts.map +1 -0
- package/dist/convergence/__tests__/scenario-primary.test.js +183 -0
- package/dist/convergence/__tests__/scenario-primary.test.js.map +1 -0
- package/dist/convergence/budget.d.ts +181 -0
- package/dist/convergence/budget.d.ts.map +1 -0
- package/dist/convergence/budget.js +218 -0
- package/dist/convergence/budget.js.map +1 -0
- package/dist/convergence/controller.d.ts +133 -0
- package/dist/convergence/controller.d.ts.map +1 -0
- package/dist/convergence/controller.js +102 -0
- package/dist/convergence/controller.js.map +1 -0
- package/dist/convergence/dual-signal.d.ts +73 -0
- package/dist/convergence/dual-signal.d.ts.map +1 -0
- package/dist/convergence/dual-signal.js +78 -0
- package/dist/convergence/dual-signal.js.map +1 -0
- package/dist/convergence/index.d.ts +17 -0
- package/dist/convergence/index.d.ts.map +1 -0
- package/dist/convergence/index.js +11 -0
- package/dist/convergence/index.js.map +1 -0
- package/dist/convergence/plateau.d.ts +99 -0
- package/dist/convergence/plateau.d.ts.map +1 -0
- package/dist/convergence/plateau.js +83 -0
- package/dist/convergence/plateau.js.map +1 -0
- package/dist/convergence/remediation.d.ts +105 -0
- package/dist/convergence/remediation.d.ts.map +1 -0
- package/dist/convergence/remediation.js +117 -0
- package/dist/convergence/remediation.js.map +1 -0
- package/dist/events.d.ts +331 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +13 -0
- package/dist/events.js.map +1 -0
- package/dist/factory-command.d.ts +40 -0
- package/dist/factory-command.d.ts.map +1 -0
- package/dist/factory-command.js +626 -0
- package/dist/factory-command.js.map +1 -0
- package/dist/factory-command.test.d.ts +8 -0
- package/dist/factory-command.test.d.ts.map +1 -0
- package/dist/factory-command.test.js +304 -0
- package/dist/factory-command.test.js.map +1 -0
- package/dist/graph/__tests__/attractor-compliance.test.d.ts +10 -0
- package/dist/graph/__tests__/attractor-compliance.test.d.ts.map +1 -0
- package/dist/graph/__tests__/attractor-compliance.test.js +766 -0
- package/dist/graph/__tests__/attractor-compliance.test.js.map +1 -0
- package/dist/graph/__tests__/checkpoint.test.d.ts +8 -0
- package/dist/graph/__tests__/checkpoint.test.d.ts.map +1 -0
- package/dist/graph/__tests__/checkpoint.test.js +329 -0
- package/dist/graph/__tests__/checkpoint.test.js.map +1 -0
- package/dist/graph/__tests__/condition-parser.test.d.ts +14 -0
- package/dist/graph/__tests__/condition-parser.test.d.ts.map +1 -0
- package/dist/graph/__tests__/condition-parser.test.js +406 -0
- package/dist/graph/__tests__/condition-parser.test.js.map +1 -0
- package/dist/graph/__tests__/context.test.d.ts +14 -0
- package/dist/graph/__tests__/context.test.d.ts.map +1 -0
- package/dist/graph/__tests__/context.test.js +276 -0
- package/dist/graph/__tests__/context.test.js.map +1 -0
- package/dist/graph/__tests__/edge-selector-events.test.d.ts +11 -0
- package/dist/graph/__tests__/edge-selector-events.test.d.ts.map +1 -0
- package/dist/graph/__tests__/edge-selector-events.test.js +184 -0
- package/dist/graph/__tests__/edge-selector-events.test.js.map +1 -0
- package/dist/graph/__tests__/edge-selector.test.d.ts +6 -0
- package/dist/graph/__tests__/edge-selector.test.d.ts.map +1 -0
- package/dist/graph/__tests__/edge-selector.test.js +452 -0
- package/dist/graph/__tests__/edge-selector.test.js.map +1 -0
- package/dist/graph/__tests__/executor-convergence.test.d.ts +12 -0
- package/dist/graph/__tests__/executor-convergence.test.d.ts.map +1 -0
- package/dist/graph/__tests__/executor-convergence.test.js +432 -0
- package/dist/graph/__tests__/executor-convergence.test.js.map +1 -0
- package/dist/graph/__tests__/executor-fidelity.test.d.ts +13 -0
- package/dist/graph/__tests__/executor-fidelity.test.d.ts.map +1 -0
- package/dist/graph/__tests__/executor-fidelity.test.js +335 -0
- package/dist/graph/__tests__/executor-fidelity.test.js.map +1 -0
- package/dist/graph/__tests__/executor.test.d.ts +14 -0
- package/dist/graph/__tests__/executor.test.d.ts.map +1 -0
- package/dist/graph/__tests__/executor.test.js +901 -0
- package/dist/graph/__tests__/executor.test.js.map +1 -0
- package/dist/graph/__tests__/fidelity.test.d.ts +8 -0
- package/dist/graph/__tests__/fidelity.test.d.ts.map +1 -0
- package/dist/graph/__tests__/fidelity.test.js +135 -0
- package/dist/graph/__tests__/fidelity.test.js.map +1 -0
- package/dist/graph/__tests__/llm-evaluator.test.d.ts +7 -0
- package/dist/graph/__tests__/llm-evaluator.test.d.ts.map +1 -0
- package/dist/graph/__tests__/llm-evaluator.test.js +106 -0
- package/dist/graph/__tests__/llm-evaluator.test.js.map +1 -0
- package/dist/graph/__tests__/parser-chaining.test.d.ts +13 -0
- package/dist/graph/__tests__/parser-chaining.test.d.ts.map +1 -0
- package/dist/graph/__tests__/parser-chaining.test.js +215 -0
- package/dist/graph/__tests__/parser-chaining.test.js.map +1 -0
- package/dist/graph/__tests__/parser.test.d.ts +22 -0
- package/dist/graph/__tests__/parser.test.d.ts.map +1 -0
- package/dist/graph/__tests__/parser.test.js +452 -0
- package/dist/graph/__tests__/parser.test.js.map +1 -0
- package/dist/graph/__tests__/run-state.test.d.ts +13 -0
- package/dist/graph/__tests__/run-state.test.d.ts.map +1 -0
- package/dist/graph/__tests__/run-state.test.js +189 -0
- package/dist/graph/__tests__/run-state.test.js.map +1 -0
- package/dist/graph/__tests__/transformer.test.d.ts +16 -0
- package/dist/graph/__tests__/transformer.test.d.ts.map +1 -0
- package/dist/graph/__tests__/transformer.test.js +350 -0
- package/dist/graph/__tests__/transformer.test.js.map +1 -0
- package/dist/graph/__tests__/validator-errors.test.d.ts +15 -0
- package/dist/graph/__tests__/validator-errors.test.d.ts.map +1 -0
- package/dist/graph/__tests__/validator-errors.test.js +572 -0
- package/dist/graph/__tests__/validator-errors.test.js.map +1 -0
- package/dist/graph/__tests__/validator-warnings.test.d.ts +15 -0
- package/dist/graph/__tests__/validator-warnings.test.d.ts.map +1 -0
- package/dist/graph/__tests__/validator-warnings.test.js +363 -0
- package/dist/graph/__tests__/validator-warnings.test.js.map +1 -0
- package/dist/graph/checkpoint.d.ts +61 -0
- package/dist/graph/checkpoint.d.ts.map +1 -0
- package/dist/graph/checkpoint.js +80 -0
- package/dist/graph/checkpoint.js.map +1 -0
- package/dist/graph/condition-parser.d.ts +55 -0
- package/dist/graph/condition-parser.d.ts.map +1 -0
- package/dist/graph/condition-parser.js +213 -0
- package/dist/graph/condition-parser.js.map +1 -0
- package/dist/graph/context.d.ts +53 -0
- package/dist/graph/context.d.ts.map +1 -0
- package/dist/graph/context.js +90 -0
- package/dist/graph/context.js.map +1 -0
- package/dist/graph/edge-selector.d.ts +74 -0
- package/dist/graph/edge-selector.d.ts.map +1 -0
- package/dist/graph/edge-selector.js +178 -0
- package/dist/graph/edge-selector.js.map +1 -0
- package/dist/graph/executor.d.ts +133 -0
- package/dist/graph/executor.d.ts.map +1 -0
- package/dist/graph/executor.js +787 -0
- package/dist/graph/executor.js.map +1 -0
- package/dist/graph/fidelity.d.ts +27 -0
- package/dist/graph/fidelity.d.ts.map +1 -0
- package/dist/graph/fidelity.js +38 -0
- package/dist/graph/fidelity.js.map +1 -0
- package/dist/graph/index.d.ts +13 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +9 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/llm-evaluator.d.ts +61 -0
- package/dist/graph/llm-evaluator.d.ts.map +1 -0
- package/dist/graph/llm-evaluator.js +106 -0
- package/dist/graph/llm-evaluator.js.map +1 -0
- package/dist/graph/parser.d.ts +28 -0
- package/dist/graph/parser.d.ts.map +1 -0
- package/dist/graph/parser.js +370 -0
- package/dist/graph/parser.js.map +1 -0
- package/dist/graph/rules/error-rules.d.ts +19 -0
- package/dist/graph/rules/error-rules.d.ts.map +1 -0
- package/dist/graph/rules/error-rules.js +264 -0
- package/dist/graph/rules/error-rules.js.map +1 -0
- package/dist/graph/rules/warning-rules.d.ts +7 -0
- package/dist/graph/rules/warning-rules.d.ts.map +1 -0
- package/dist/graph/rules/warning-rules.js +165 -0
- package/dist/graph/rules/warning-rules.js.map +1 -0
- package/dist/graph/run-state.d.ts +62 -0
- package/dist/graph/run-state.d.ts.map +1 -0
- package/dist/graph/run-state.js +79 -0
- package/dist/graph/run-state.js.map +1 -0
- package/dist/graph/transformer.d.ts +31 -0
- package/dist/graph/transformer.d.ts.map +1 -0
- package/dist/graph/transformer.js +64 -0
- package/dist/graph/transformer.js.map +1 -0
- package/dist/graph/types.d.ts +320 -0
- package/dist/graph/types.d.ts.map +1 -0
- package/dist/graph/types.js +6 -0
- package/dist/graph/types.js.map +1 -0
- package/dist/graph/validator.d.ts +16 -0
- package/dist/graph/validator.d.ts.map +1 -0
- package/dist/graph/validator.js +40 -0
- package/dist/graph/validator.js.map +1 -0
- package/dist/handlers/__tests__/codergen-handler.test.d.ts +14 -0
- package/dist/handlers/__tests__/codergen-handler.test.d.ts.map +1 -0
- package/dist/handlers/__tests__/codergen-handler.test.js +442 -0
- package/dist/handlers/__tests__/codergen-handler.test.js.map +1 -0
- package/dist/handlers/__tests__/fan-in.test.d.ts +14 -0
- package/dist/handlers/__tests__/fan-in.test.d.ts.map +1 -0
- package/dist/handlers/__tests__/fan-in.test.js +399 -0
- package/dist/handlers/__tests__/fan-in.test.js.map +1 -0
- package/dist/handlers/__tests__/join-policy.test.d.ts +9 -0
- package/dist/handlers/__tests__/join-policy.test.d.ts.map +1 -0
- package/dist/handlers/__tests__/join-policy.test.js +201 -0
- package/dist/handlers/__tests__/join-policy.test.js.map +1 -0
- package/dist/handlers/__tests__/manager-loop.test.d.ts +14 -0
- package/dist/handlers/__tests__/manager-loop.test.d.ts.map +1 -0
- package/dist/handlers/__tests__/manager-loop.test.js +322 -0
- package/dist/handlers/__tests__/manager-loop.test.js.map +1 -0
- package/dist/handlers/__tests__/parallel-events.test.d.ts +12 -0
- package/dist/handlers/__tests__/parallel-events.test.d.ts.map +1 -0
- package/dist/handlers/__tests__/parallel-events.test.js +252 -0
- package/dist/handlers/__tests__/parallel-events.test.js.map +1 -0
- package/dist/handlers/__tests__/parallel-handler.test.d.ts +14 -0
- package/dist/handlers/__tests__/parallel-handler.test.d.ts.map +1 -0
- package/dist/handlers/__tests__/parallel-handler.test.js +337 -0
- package/dist/handlers/__tests__/parallel-handler.test.js.map +1 -0
- package/dist/handlers/__tests__/parallel-join.test.d.ts +9 -0
- package/dist/handlers/__tests__/parallel-join.test.d.ts.map +1 -0
- package/dist/handlers/__tests__/parallel-join.test.js +267 -0
- package/dist/handlers/__tests__/parallel-join.test.js.map +1 -0
- package/dist/handlers/__tests__/registry.test.d.ts +14 -0
- package/dist/handlers/__tests__/registry.test.d.ts.map +1 -0
- package/dist/handlers/__tests__/registry.test.js +315 -0
- package/dist/handlers/__tests__/registry.test.js.map +1 -0
- package/dist/handlers/__tests__/subgraph-events.test.d.ts +10 -0
- package/dist/handlers/__tests__/subgraph-events.test.d.ts.map +1 -0
- package/dist/handlers/__tests__/subgraph-events.test.js +189 -0
- package/dist/handlers/__tests__/subgraph-events.test.js.map +1 -0
- package/dist/handlers/__tests__/subgraph-inheritance.test.d.ts +14 -0
- package/dist/handlers/__tests__/subgraph-inheritance.test.d.ts.map +1 -0
- package/dist/handlers/__tests__/subgraph-inheritance.test.js +267 -0
- package/dist/handlers/__tests__/subgraph-inheritance.test.js.map +1 -0
- package/dist/handlers/__tests__/subgraph.test.d.ts +14 -0
- package/dist/handlers/__tests__/subgraph.test.d.ts.map +1 -0
- package/dist/handlers/__tests__/subgraph.test.js +369 -0
- package/dist/handlers/__tests__/subgraph.test.js.map +1 -0
- package/dist/handlers/__tests__/tool-handler.test.d.ts +11 -0
- package/dist/handlers/__tests__/tool-handler.test.d.ts.map +1 -0
- package/dist/handlers/__tests__/tool-handler.test.js +184 -0
- package/dist/handlers/__tests__/tool-handler.test.js.map +1 -0
- package/dist/handlers/__tests__/tool-scenario.test.d.ts +12 -0
- package/dist/handlers/__tests__/tool-scenario.test.d.ts.map +1 -0
- package/dist/handlers/__tests__/tool-scenario.test.js +222 -0
- package/dist/handlers/__tests__/tool-scenario.test.js.map +1 -0
- package/dist/handlers/__tests__/wait-human-handler.test.d.ts +11 -0
- package/dist/handlers/__tests__/wait-human-handler.test.d.ts.map +1 -0
- package/dist/handlers/__tests__/wait-human-handler.test.js +251 -0
- package/dist/handlers/__tests__/wait-human-handler.test.js.map +1 -0
- package/dist/handlers/codergen-handler.d.ts +83 -0
- package/dist/handlers/codergen-handler.d.ts.map +1 -0
- package/dist/handlers/codergen-handler.js +152 -0
- package/dist/handlers/codergen-handler.js.map +1 -0
- package/dist/handlers/conditional.d.ts +15 -0
- package/dist/handlers/conditional.d.ts.map +1 -0
- package/dist/handlers/conditional.js +16 -0
- package/dist/handlers/conditional.js.map +1 -0
- package/dist/handlers/exit.d.ts +10 -0
- package/dist/handlers/exit.d.ts.map +1 -0
- package/dist/handlers/exit.js +11 -0
- package/dist/handlers/exit.js.map +1 -0
- package/dist/handlers/fan-in.d.ts +74 -0
- package/dist/handlers/fan-in.d.ts.map +1 -0
- package/dist/handlers/fan-in.js +191 -0
- package/dist/handlers/fan-in.js.map +1 -0
- package/dist/handlers/index.d.ts +29 -0
- package/dist/handlers/index.d.ts.map +1 -0
- package/dist/handlers/index.js +22 -0
- package/dist/handlers/index.js.map +1 -0
- package/dist/handlers/join-policy.d.ts +117 -0
- package/dist/handlers/join-policy.d.ts.map +1 -0
- package/dist/handlers/join-policy.js +129 -0
- package/dist/handlers/join-policy.js.map +1 -0
- package/dist/handlers/manager-loop.d.ts +54 -0
- package/dist/handlers/manager-loop.d.ts.map +1 -0
- package/dist/handlers/manager-loop.js +177 -0
- package/dist/handlers/manager-loop.js.map +1 -0
- package/dist/handlers/parallel.d.ts +31 -0
- package/dist/handlers/parallel.d.ts.map +1 -0
- package/dist/handlers/parallel.js +362 -0
- package/dist/handlers/parallel.js.map +1 -0
- package/dist/handlers/registry.d.ts +75 -0
- package/dist/handlers/registry.d.ts.map +1 -0
- package/dist/handlers/registry.js +132 -0
- package/dist/handlers/registry.js.map +1 -0
- package/dist/handlers/start.d.ts +10 -0
- package/dist/handlers/start.d.ts.map +1 -0
- package/dist/handlers/start.js +11 -0
- package/dist/handlers/start.js.map +1 -0
- package/dist/handlers/subgraph.d.ts +46 -0
- package/dist/handlers/subgraph.d.ts.map +1 -0
- package/dist/handlers/subgraph.js +178 -0
- package/dist/handlers/subgraph.js.map +1 -0
- package/dist/handlers/tool.d.ts +36 -0
- package/dist/handlers/tool.d.ts.map +1 -0
- package/dist/handlers/tool.js +99 -0
- package/dist/handlers/tool.js.map +1 -0
- package/dist/handlers/types.d.ts +98 -0
- package/dist/handlers/types.d.ts.map +1 -0
- package/dist/handlers/types.js +6 -0
- package/dist/handlers/types.js.map +1 -0
- package/dist/handlers/wait-human.d.ts +65 -0
- package/dist/handlers/wait-human.d.ts.map +1 -0
- package/dist/handlers/wait-human.js +124 -0
- package/dist/handlers/wait-human.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/__tests__/client.test.d.ts +2 -0
- package/dist/llm/__tests__/client.test.d.ts.map +1 -0
- package/dist/llm/__tests__/client.test.js +198 -0
- package/dist/llm/__tests__/client.test.js.map +1 -0
- package/dist/llm/__tests__/types.test.d.ts +2 -0
- package/dist/llm/__tests__/types.test.d.ts.map +1 -0
- package/dist/llm/__tests__/types.test.js +289 -0
- package/dist/llm/__tests__/types.test.js.map +1 -0
- package/dist/llm/client.d.ts +19 -0
- package/dist/llm/client.d.ts.map +1 -0
- package/dist/llm/client.js +50 -0
- package/dist/llm/client.js.map +1 -0
- package/dist/llm/index.d.ts +6 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +6 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/middleware/__tests__/cost-tracking.test.d.ts +2 -0
- package/dist/llm/middleware/__tests__/cost-tracking.test.d.ts.map +1 -0
- package/dist/llm/middleware/__tests__/cost-tracking.test.js +73 -0
- package/dist/llm/middleware/__tests__/cost-tracking.test.js.map +1 -0
- package/dist/llm/middleware/__tests__/logging.test.d.ts +2 -0
- package/dist/llm/middleware/__tests__/logging.test.d.ts.map +1 -0
- package/dist/llm/middleware/__tests__/logging.test.js +127 -0
- package/dist/llm/middleware/__tests__/logging.test.js.map +1 -0
- package/dist/llm/middleware/__tests__/retry.test.d.ts +2 -0
- package/dist/llm/middleware/__tests__/retry.test.d.ts.map +1 -0
- package/dist/llm/middleware/__tests__/retry.test.js +126 -0
- package/dist/llm/middleware/__tests__/retry.test.js.map +1 -0
- package/dist/llm/middleware/cost-tracking.d.ts +8 -0
- package/dist/llm/middleware/cost-tracking.d.ts.map +1 -0
- package/dist/llm/middleware/cost-tracking.js +34 -0
- package/dist/llm/middleware/cost-tracking.js.map +1 -0
- package/dist/llm/middleware/index.d.ts +5 -0
- package/dist/llm/middleware/index.d.ts.map +1 -0
- package/dist/llm/middleware/index.js +6 -0
- package/dist/llm/middleware/index.js.map +1 -0
- package/dist/llm/middleware/logging.d.ts +6 -0
- package/dist/llm/middleware/logging.d.ts.map +1 -0
- package/dist/llm/middleware/logging.js +54 -0
- package/dist/llm/middleware/logging.js.map +1 -0
- package/dist/llm/middleware/retry.d.ts +14 -0
- package/dist/llm/middleware/retry.d.ts.map +1 -0
- package/dist/llm/middleware/retry.js +40 -0
- package/dist/llm/middleware/retry.js.map +1 -0
- package/dist/llm/middleware/types.d.ts +23 -0
- package/dist/llm/middleware/types.d.ts.map +1 -0
- package/dist/llm/middleware/types.js +24 -0
- package/dist/llm/middleware/types.js.map +1 -0
- package/dist/llm/model-registry.d.ts +14 -0
- package/dist/llm/model-registry.d.ts.map +1 -0
- package/dist/llm/model-registry.js +32 -0
- package/dist/llm/model-registry.js.map +1 -0
- package/dist/llm/providers/__tests__/anthropic.test.d.ts +2 -0
- package/dist/llm/providers/__tests__/anthropic.test.d.ts.map +1 -0
- package/dist/llm/providers/__tests__/anthropic.test.js +412 -0
- package/dist/llm/providers/__tests__/anthropic.test.js.map +1 -0
- package/dist/llm/providers/__tests__/gemini.test.d.ts +2 -0
- package/dist/llm/providers/__tests__/gemini.test.d.ts.map +1 -0
- package/dist/llm/providers/__tests__/gemini.test.js +591 -0
- package/dist/llm/providers/__tests__/gemini.test.js.map +1 -0
- package/dist/llm/providers/__tests__/openai.test.d.ts +2 -0
- package/dist/llm/providers/__tests__/openai.test.d.ts.map +1 -0
- package/dist/llm/providers/__tests__/openai.test.js +546 -0
- package/dist/llm/providers/__tests__/openai.test.js.map +1 -0
- package/dist/llm/providers/anthropic.d.ts +25 -0
- package/dist/llm/providers/anthropic.d.ts.map +1 -0
- package/dist/llm/providers/anthropic.js +315 -0
- package/dist/llm/providers/anthropic.js.map +1 -0
- package/dist/llm/providers/gemini.d.ts +28 -0
- package/dist/llm/providers/gemini.d.ts.map +1 -0
- package/dist/llm/providers/gemini.js +429 -0
- package/dist/llm/providers/gemini.js.map +1 -0
- package/dist/llm/providers/index.d.ts +7 -0
- package/dist/llm/providers/index.d.ts.map +1 -0
- package/dist/llm/providers/index.js +4 -0
- package/dist/llm/providers/index.js.map +1 -0
- package/dist/llm/providers/openai.d.ts +28 -0
- package/dist/llm/providers/openai.d.ts.map +1 -0
- package/dist/llm/providers/openai.js +426 -0
- package/dist/llm/providers/openai.js.map +1 -0
- package/dist/llm/types.d.ts +127 -0
- package/dist/llm/types.d.ts.map +1 -0
- package/dist/llm/types.js +21 -0
- package/dist/llm/types.js.map +1 -0
- package/dist/persistence/__tests__/factory-queries.test.d.ts +9 -0
- package/dist/persistence/__tests__/factory-queries.test.d.ts.map +1 -0
- package/dist/persistence/__tests__/factory-queries.test.js +372 -0
- package/dist/persistence/__tests__/factory-queries.test.js.map +1 -0
- package/dist/persistence/__tests__/factory-schema.test.d.ts +6 -0
- package/dist/persistence/__tests__/factory-schema.test.d.ts.map +1 -0
- package/dist/persistence/__tests__/factory-schema.test.js +105 -0
- package/dist/persistence/__tests__/factory-schema.test.js.map +1 -0
- package/dist/persistence/factory-queries.d.ts +204 -0
- package/dist/persistence/factory-queries.d.ts.map +1 -0
- package/dist/persistence/factory-queries.js +186 -0
- package/dist/persistence/factory-queries.js.map +1 -0
- package/dist/persistence/factory-schema.d.ts +16 -0
- package/dist/persistence/factory-schema.d.ts.map +1 -0
- package/dist/persistence/factory-schema.js +89 -0
- package/dist/persistence/factory-schema.js.map +1 -0
- package/dist/scenarios/__tests__/cli-command-list.test.d.ts +7 -0
- package/dist/scenarios/__tests__/cli-command-list.test.d.ts.map +1 -0
- package/dist/scenarios/__tests__/cli-command-list.test.js +237 -0
- package/dist/scenarios/__tests__/cli-command-list.test.js.map +1 -0
- package/dist/scenarios/__tests__/cli-command.test.d.ts +11 -0
- package/dist/scenarios/__tests__/cli-command.test.d.ts.map +1 -0
- package/dist/scenarios/__tests__/cli-command.test.js +275 -0
- package/dist/scenarios/__tests__/cli-command.test.js.map +1 -0
- package/dist/scenarios/__tests__/integrity-pipeline.test.d.ts +15 -0
- package/dist/scenarios/__tests__/integrity-pipeline.test.d.ts.map +1 -0
- package/dist/scenarios/__tests__/integrity-pipeline.test.js +318 -0
- package/dist/scenarios/__tests__/integrity-pipeline.test.js.map +1 -0
- package/dist/scenarios/__tests__/runner-twins.test.d.ts +13 -0
- package/dist/scenarios/__tests__/runner-twins.test.d.ts.map +1 -0
- package/dist/scenarios/__tests__/runner-twins.test.js +205 -0
- package/dist/scenarios/__tests__/runner-twins.test.js.map +1 -0
- package/dist/scenarios/__tests__/scorer.test.d.ts +11 -0
- package/dist/scenarios/__tests__/scorer.test.d.ts.map +1 -0
- package/dist/scenarios/__tests__/scorer.test.js +225 -0
- package/dist/scenarios/__tests__/scorer.test.js.map +1 -0
- package/dist/scenarios/__tests__/scoring-integration.test.d.ts +8 -0
- package/dist/scenarios/__tests__/scoring-integration.test.d.ts.map +1 -0
- package/dist/scenarios/__tests__/scoring-integration.test.js +178 -0
- package/dist/scenarios/__tests__/scoring-integration.test.js.map +1 -0
- package/dist/scenarios/__tests__/store.test.d.ts +5 -0
- package/dist/scenarios/__tests__/store.test.d.ts.map +1 -0
- package/dist/scenarios/__tests__/store.test.js +169 -0
- package/dist/scenarios/__tests__/store.test.js.map +1 -0
- package/dist/scenarios/cli-command.d.ts +20 -0
- package/dist/scenarios/cli-command.d.ts.map +1 -0
- package/dist/scenarios/cli-command.js +66 -0
- package/dist/scenarios/cli-command.js.map +1 -0
- package/dist/scenarios/index.d.ts +11 -0
- package/dist/scenarios/index.d.ts.map +1 -0
- package/dist/scenarios/index.js +11 -0
- package/dist/scenarios/index.js.map +1 -0
- package/dist/scenarios/runner.d.ts +64 -0
- package/dist/scenarios/runner.d.ts.map +1 -0
- package/dist/scenarios/runner.js +205 -0
- package/dist/scenarios/runner.js.map +1 -0
- package/dist/scenarios/scorer.d.ts +69 -0
- package/dist/scenarios/scorer.d.ts.map +1 -0
- package/dist/scenarios/scorer.js +66 -0
- package/dist/scenarios/scorer.js.map +1 -0
- package/dist/scenarios/store.d.ts +33 -0
- package/dist/scenarios/store.d.ts.map +1 -0
- package/dist/scenarios/store.js +92 -0
- package/dist/scenarios/store.js.map +1 -0
- package/dist/scenarios/types.d.ts +40 -0
- package/dist/scenarios/types.d.ts.map +1 -0
- package/dist/scenarios/types.js +5 -0
- package/dist/scenarios/types.js.map +1 -0
- package/dist/stylesheet/__tests__/stylesheet.test.d.ts +17 -0
- package/dist/stylesheet/__tests__/stylesheet.test.d.ts.map +1 -0
- package/dist/stylesheet/__tests__/stylesheet.test.js +368 -0
- package/dist/stylesheet/__tests__/stylesheet.test.js.map +1 -0
- package/dist/stylesheet/parser.d.ts +44 -0
- package/dist/stylesheet/parser.d.ts.map +1 -0
- package/dist/stylesheet/parser.js +190 -0
- package/dist/stylesheet/parser.js.map +1 -0
- package/dist/stylesheet/resolver.d.ts +38 -0
- package/dist/stylesheet/resolver.d.ts.map +1 -0
- package/dist/stylesheet/resolver.js +96 -0
- package/dist/stylesheet/resolver.js.map +1 -0
- package/dist/templates/__tests__/templates.test.d.ts +7 -0
- package/dist/templates/__tests__/templates.test.d.ts.map +1 -0
- package/dist/templates/__tests__/templates.test.js +92 -0
- package/dist/templates/__tests__/templates.test.js.map +1 -0
- package/dist/templates/index.d.ts +38 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +153 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/twins/__tests__/docker-compose.test.d.ts +13 -0
- package/dist/twins/__tests__/docker-compose.test.d.ts.map +1 -0
- package/dist/twins/__tests__/docker-compose.test.js +247 -0
- package/dist/twins/__tests__/docker-compose.test.js.map +1 -0
- package/dist/twins/__tests__/health-monitor.test.d.ts +19 -0
- package/dist/twins/__tests__/health-monitor.test.d.ts.map +1 -0
- package/dist/twins/__tests__/health-monitor.test.js +301 -0
- package/dist/twins/__tests__/health-monitor.test.js.map +1 -0
- package/dist/twins/__tests__/integration/e2e.test.d.ts +18 -0
- package/dist/twins/__tests__/integration/e2e.test.d.ts.map +1 -0
- package/dist/twins/__tests__/integration/e2e.test.js +146 -0
- package/dist/twins/__tests__/integration/e2e.test.js.map +1 -0
- package/dist/twins/__tests__/integration/health-monitor-integration.test.d.ts +16 -0
- package/dist/twins/__tests__/integration/health-monitor-integration.test.d.ts.map +1 -0
- package/dist/twins/__tests__/integration/health-monitor-integration.test.js +183 -0
- package/dist/twins/__tests__/integration/health-monitor-integration.test.js.map +1 -0
- package/dist/twins/__tests__/integration/helpers.d.ts +32 -0
- package/dist/twins/__tests__/integration/helpers.d.ts.map +1 -0
- package/dist/twins/__tests__/integration/helpers.js +67 -0
- package/dist/twins/__tests__/integration/helpers.js.map +1 -0
- package/dist/twins/__tests__/integration/lifecycle.test.d.ts +14 -0
- package/dist/twins/__tests__/integration/lifecycle.test.d.ts.map +1 -0
- package/dist/twins/__tests__/integration/lifecycle.test.js +127 -0
- package/dist/twins/__tests__/integration/lifecycle.test.js.map +1 -0
- package/dist/twins/__tests__/integration/persistence-integration.test.d.ts +14 -0
- package/dist/twins/__tests__/integration/persistence-integration.test.d.ts.map +1 -0
- package/dist/twins/__tests__/integration/persistence-integration.test.js +132 -0
- package/dist/twins/__tests__/integration/persistence-integration.test.js.map +1 -0
- package/dist/twins/__tests__/persistence.test.d.ts +10 -0
- package/dist/twins/__tests__/persistence.test.d.ts.map +1 -0
- package/dist/twins/__tests__/persistence.test.js +300 -0
- package/dist/twins/__tests__/persistence.test.js.map +1 -0
- package/dist/twins/__tests__/registry.test.d.ts +7 -0
- package/dist/twins/__tests__/registry.test.d.ts.map +1 -0
- package/dist/twins/__tests__/registry.test.js +282 -0
- package/dist/twins/__tests__/registry.test.js.map +1 -0
- package/dist/twins/__tests__/run-state.test.d.ts +9 -0
- package/dist/twins/__tests__/run-state.test.d.ts.map +1 -0
- package/dist/twins/__tests__/run-state.test.js +112 -0
- package/dist/twins/__tests__/run-state.test.js.map +1 -0
- package/dist/twins/__tests__/templates-cli.test.d.ts +10 -0
- package/dist/twins/__tests__/templates-cli.test.d.ts.map +1 -0
- package/dist/twins/__tests__/templates-cli.test.js +187 -0
- package/dist/twins/__tests__/templates-cli.test.js.map +1 -0
- package/dist/twins/__tests__/templates.test.d.ts +7 -0
- package/dist/twins/__tests__/templates.test.d.ts.map +1 -0
- package/dist/twins/__tests__/templates.test.js +87 -0
- package/dist/twins/__tests__/templates.test.js.map +1 -0
- package/dist/twins/__tests__/twins-cli.test.d.ts +11 -0
- package/dist/twins/__tests__/twins-cli.test.d.ts.map +1 -0
- package/dist/twins/__tests__/twins-cli.test.js +365 -0
- package/dist/twins/__tests__/twins-cli.test.js.map +1 -0
- package/dist/twins/docker-compose.d.ts +48 -0
- package/dist/twins/docker-compose.d.ts.map +1 -0
- package/dist/twins/docker-compose.js +172 -0
- package/dist/twins/docker-compose.js.map +1 -0
- package/dist/twins/health-monitor.d.ts +36 -0
- package/dist/twins/health-monitor.d.ts.map +1 -0
- package/dist/twins/health-monitor.js +114 -0
- package/dist/twins/health-monitor.js.map +1 -0
- package/dist/twins/index.d.ts +22 -0
- package/dist/twins/index.d.ts.map +1 -0
- package/dist/twins/index.js +19 -0
- package/dist/twins/index.js.map +1 -0
- package/dist/twins/persistence.d.ts +100 -0
- package/dist/twins/persistence.d.ts.map +1 -0
- package/dist/twins/persistence.js +120 -0
- package/dist/twins/persistence.js.map +1 -0
- package/dist/twins/registry.d.ts +40 -0
- package/dist/twins/registry.d.ts.map +1 -0
- package/dist/twins/registry.js +175 -0
- package/dist/twins/registry.js.map +1 -0
- package/dist/twins/run-state.d.ts +47 -0
- package/dist/twins/run-state.d.ts.map +1 -0
- package/dist/twins/run-state.js +70 -0
- package/dist/twins/run-state.js.map +1 -0
- package/dist/twins/schema.d.ts +40 -0
- package/dist/twins/schema.d.ts.map +1 -0
- package/dist/twins/schema.js +46 -0
- package/dist/twins/schema.js.map +1 -0
- package/dist/twins/templates.d.ts +27 -0
- package/dist/twins/templates.d.ts.map +1 -0
- package/dist/twins/templates.js +63 -0
- package/dist/twins/templates.js.map +1 -0
- package/dist/twins/types.d.ts +55 -0
- package/dist/twins/types.d.ts.map +1 -0
- package/dist/twins/types.js +26 -0
- package/dist/twins/types.js.map +1 -0
- package/package.json +28 -0
|
@@ -0,0 +1,787 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph executor — drives end-to-end traversal of a factory graph.
|
|
3
|
+
*
|
|
4
|
+
* Dispatches handlers, applies retry logic, writes checkpoints, selects edges,
|
|
5
|
+
* and emits FactoryEvents at each stage of execution.
|
|
6
|
+
*
|
|
7
|
+
* Story 42-14 (base executor).
|
|
8
|
+
* Story 42-16 (allowPartial demotion + ConvergenceController goal gate evaluation).
|
|
9
|
+
*
|
|
10
|
+
* NOTE: The executor uses `events.ts:Outcome` (StageStatus: 'SUCCESS' | 'FAIL' | ...)
|
|
11
|
+
* rather than `types.ts:Outcome` (OutcomeStatus: 'SUCCESS' | 'FAILURE' | ...) because:
|
|
12
|
+
* 1. The acceptance criteria specify status: 'FAIL' (from StageStatus, not OutcomeStatus)
|
|
13
|
+
* 2. All FactoryEvents payloads (graph:node-completed) use events.ts:Outcome
|
|
14
|
+
* NodeHandler returns types.ts:Outcome, which is cast via `as unknown as Outcome` where needed.
|
|
15
|
+
*/
|
|
16
|
+
import path from 'node:path';
|
|
17
|
+
import { GraphContext } from './context.js';
|
|
18
|
+
import { selectEdge } from './edge-selector.js';
|
|
19
|
+
import { CheckpointManager } from './checkpoint.js';
|
|
20
|
+
import { RunStateManager } from './run-state.js';
|
|
21
|
+
import { createConvergenceController, SessionBudgetManager, PipelineBudgetManager, createPlateauDetector, checkPlateauAndEmit, buildRemediationContext, injectRemediationContext, computeBackoffDelay, createDualSignalCoordinator, CONTEXT_KEY_CODE_REVIEW_VERDICT, } from '../convergence/index.js';
|
|
22
|
+
import { computeSatisfactionScore } from '../scenarios/scorer.js';
|
|
23
|
+
import { upsertGraphRun, insertGraphNodeResult, insertScenarioResult } from '../persistence/factory-queries.js';
|
|
24
|
+
import { parseFidelityLevel, resolveFidelity } from './fidelity.js';
|
|
25
|
+
import { applyStylesheet } from './transformer.js';
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// normalizeOutcomeStatus
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
/**
|
|
30
|
+
* Normalize a types.ts:Outcome (OutcomeStatus) to an events.ts:Outcome (StageStatus).
|
|
31
|
+
*
|
|
32
|
+
* NodeHandler returns `types.ts:Outcome` whose status is `OutcomeStatus`
|
|
33
|
+
* ('SUCCESS' | 'PARTIAL_SUCCESS' | 'FAILURE' | 'NEEDS_RETRY' | 'ESCALATE').
|
|
34
|
+
* The executor operates on `events.ts:Outcome` whose status is `StageStatus`
|
|
35
|
+
* ('SUCCESS' | 'FAIL' | 'PARTIAL_SUCCESS' | 'RETRY' | 'SKIPPED').
|
|
36
|
+
*
|
|
37
|
+
* Mapping:
|
|
38
|
+
* OutcomeStatus.FAILURE → StageStatus.FAIL
|
|
39
|
+
* OutcomeStatus.NEEDS_RETRY → StageStatus.FAIL (retry exhausted at this level)
|
|
40
|
+
* OutcomeStatus.ESCALATE → StageStatus.FAIL (treated as failure for routing)
|
|
41
|
+
* OutcomeStatus.SUCCESS → StageStatus.SUCCESS
|
|
42
|
+
* OutcomeStatus.PARTIAL_SUCCESS → StageStatus.PARTIAL_SUCCESS
|
|
43
|
+
*/
|
|
44
|
+
function normalizeOutcomeStatus(raw) {
|
|
45
|
+
let status;
|
|
46
|
+
switch (raw.status) {
|
|
47
|
+
case 'SUCCESS':
|
|
48
|
+
status = 'SUCCESS';
|
|
49
|
+
break;
|
|
50
|
+
case 'PARTIAL_SUCCESS':
|
|
51
|
+
status = 'PARTIAL_SUCCESS';
|
|
52
|
+
break;
|
|
53
|
+
case 'FAILURE':
|
|
54
|
+
case 'NEEDS_RETRY':
|
|
55
|
+
case 'ESCALATE':
|
|
56
|
+
default:
|
|
57
|
+
status = 'FAIL';
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
...raw,
|
|
62
|
+
status,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
// dispatchWithRetry
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
/**
|
|
69
|
+
* Dispatch a node handler with exponential backoff retry on FAIL outcomes.
|
|
70
|
+
*
|
|
71
|
+
* Emits `graph:node-retried` before each retry attempt.
|
|
72
|
+
* Does NOT emit `graph:node-completed` or `graph:node-failed` — those are
|
|
73
|
+
* emitted by the main loop in `createGraphExecutor` AFTER the `allowPartial`
|
|
74
|
+
* demotion check, ensuring correct event semantics for demoted PARTIAL_SUCCESS.
|
|
75
|
+
*
|
|
76
|
+
* @param node - Node to dispatch (may have fidelity override applied).
|
|
77
|
+
* @param context - Current graph execution context.
|
|
78
|
+
* @param graph - The full factory graph.
|
|
79
|
+
* @param config - Executor configuration (handlerRegistry, eventBus, runId).
|
|
80
|
+
* @param nodeRetries - Mutable retry counter map; mutated in place.
|
|
81
|
+
* @returns The final Outcome after all retry attempts.
|
|
82
|
+
*/
|
|
83
|
+
async function dispatchWithRetry(node, context, graph, config, nodeRetries) {
|
|
84
|
+
const maxRetries = node.maxRetries ?? 0;
|
|
85
|
+
const maxAttempts = maxRetries + 1;
|
|
86
|
+
let attempt = 0;
|
|
87
|
+
while (true) {
|
|
88
|
+
let outcome;
|
|
89
|
+
try {
|
|
90
|
+
const handler = config.handlerRegistry.resolve(node);
|
|
91
|
+
// NodeHandler returns types.ts:Outcome (OutcomeStatus).
|
|
92
|
+
// normalizeOutcomeStatus() maps to events.ts:Outcome (StageStatus) so that
|
|
93
|
+
// 'FAILURE' → 'FAIL', 'NEEDS_RETRY' → 'FAIL', 'ESCALATE' → 'FAIL',
|
|
94
|
+
// while 'SUCCESS' and 'PARTIAL_SUCCESS' pass through unchanged.
|
|
95
|
+
outcome = normalizeOutcomeStatus(await handler(node, context, graph));
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
99
|
+
outcome = { status: 'FAIL', failureReason: msg };
|
|
100
|
+
}
|
|
101
|
+
const isFail = outcome.status === 'FAIL';
|
|
102
|
+
if (!isFail || attempt >= maxRetries) {
|
|
103
|
+
// Done: either succeeded or exhausted all retries.
|
|
104
|
+
// NOTE: event emission (graph:node-completed / graph:node-failed) is intentionally
|
|
105
|
+
// deferred to the main loop in createGraphExecutor, where it occurs AFTER the
|
|
106
|
+
// allowPartial demotion check. Emitting here would produce graph:node-completed
|
|
107
|
+
// for PARTIAL_SUCCESS outcomes that are subsequently demoted to FAIL (violating
|
|
108
|
+
// Dev Notes §"allow_partial Demotion — Placement in Executor").
|
|
109
|
+
return outcome;
|
|
110
|
+
}
|
|
111
|
+
// Retry path: increment counter, compute delay, emit event, await delay
|
|
112
|
+
nodeRetries[node.id] = (nodeRetries[node.id] ?? 0) + 1;
|
|
113
|
+
const delayMs = computeBackoffDelay(attempt);
|
|
114
|
+
config.eventBus?.emit('graph:node-retried', {
|
|
115
|
+
runId: config.runId,
|
|
116
|
+
nodeId: node.id,
|
|
117
|
+
attempt: attempt + 1, // 1-indexed: first retry = 1
|
|
118
|
+
maxAttempts,
|
|
119
|
+
delayMs,
|
|
120
|
+
});
|
|
121
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
122
|
+
attempt++;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
// createGraphExecutor
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
/**
|
|
129
|
+
* Create a new graph executor instance.
|
|
130
|
+
*
|
|
131
|
+
* The returned executor's `run()` method drives a factory graph from start node
|
|
132
|
+
* to exit node (or resumes from a checkpoint if `config.checkpointPath` is set),
|
|
133
|
+
* dispatching handlers, applying retry logic, writing checkpoints, and emitting
|
|
134
|
+
* FactoryEvents for full observability.
|
|
135
|
+
*/
|
|
136
|
+
export function createGraphExecutor() {
|
|
137
|
+
return {
|
|
138
|
+
async run(graph, config) {
|
|
139
|
+
// Apply model stylesheet to all nodes before any handler is dispatched.
|
|
140
|
+
// This is idempotent: nodes with explicit llmModel/llmProvider/reasoningEffort
|
|
141
|
+
// are never overwritten, so calling it twice (e.g., on resume) is safe.
|
|
142
|
+
applyStylesheet(graph, config.inheritedStylesheet);
|
|
143
|
+
const checkpointManager = new CheckpointManager();
|
|
144
|
+
// Checkpoint is always written to this path (filename is fixed by convention)
|
|
145
|
+
const checkpointFilePath = path.join(config.logsRoot, 'checkpoint.json');
|
|
146
|
+
// ConvergenceController for goal gate evaluation (story 42-16)
|
|
147
|
+
const controller = createConvergenceController();
|
|
148
|
+
// Convergence budget and plateau managers (story 45-8)
|
|
149
|
+
const sessionManager = new SessionBudgetManager();
|
|
150
|
+
const pipelineManager = new PipelineBudgetManager();
|
|
151
|
+
const plateauDetector = createPlateauDetector({
|
|
152
|
+
...(config.plateauWindow !== undefined ? { window: config.plateauWindow } : {}),
|
|
153
|
+
...(config.plateauThreshold !== undefined ? { threshold: config.plateauThreshold } : {}),
|
|
154
|
+
});
|
|
155
|
+
let convergenceIteration = 0;
|
|
156
|
+
// Persistence state (story 46-3)
|
|
157
|
+
const runStartedAt = new Date().toISOString();
|
|
158
|
+
// Tracks which node is currently executing — used by scenario:completed handler
|
|
159
|
+
// to populate node_id in scenario_results rows (event payload has no nodeId field).
|
|
160
|
+
let lastScenarioNodeId = '';
|
|
161
|
+
// Helper: persist a run exit (success or failure) when adapter is present.
|
|
162
|
+
// Called at every `return` path that terminates the run.
|
|
163
|
+
// Persistence errors must not crash the executor — log as warnings.
|
|
164
|
+
const persistExit = async (finalStatus, finalOutcome) => {
|
|
165
|
+
if (!config.adapter)
|
|
166
|
+
return;
|
|
167
|
+
try {
|
|
168
|
+
await upsertGraphRun(config.adapter, {
|
|
169
|
+
id: config.runId,
|
|
170
|
+
graph_file: graph.id || config.runId,
|
|
171
|
+
...(graph.goal ? { graph_goal: graph.goal } : {}),
|
|
172
|
+
status: finalStatus,
|
|
173
|
+
started_at: runStartedAt,
|
|
174
|
+
completed_at: new Date().toISOString(),
|
|
175
|
+
final_outcome: finalOutcome,
|
|
176
|
+
total_cost_usd: pipelineManager.getTotalCost(),
|
|
177
|
+
node_count: graph.nodes.size,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
catch (persistErr) {
|
|
181
|
+
const msg = persistErr instanceof Error ? persistErr.message : String(persistErr);
|
|
182
|
+
console.warn(`[executor] graph_runs upsert failed for run ${config.runId}: ${msg}`);
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
// Execution state
|
|
186
|
+
let completedNodes = [];
|
|
187
|
+
let nodeRetries = {};
|
|
188
|
+
let context = new GraphContext(config.initialContext);
|
|
189
|
+
let step = 0;
|
|
190
|
+
// Cycle detection: counts how many times each node is visited
|
|
191
|
+
const visitCount = new Map();
|
|
192
|
+
// Tracks FAIL-outcome conditional edge routing count per node (bounds review loops)
|
|
193
|
+
const failRouteCount = new Map();
|
|
194
|
+
// Resume state (non-null when config.checkpointPath is set)
|
|
195
|
+
let resumeCompletedSet = null;
|
|
196
|
+
// Fidelity override for the first resumed node ('summary:high' or '')
|
|
197
|
+
let firstResumedFidelity = '';
|
|
198
|
+
// loopRestart flags: suppress cycle check / completed push for intentional loops
|
|
199
|
+
let skipCycleCheck = false;
|
|
200
|
+
let skipCompletedPush = false;
|
|
201
|
+
// Tracks the edge that led to the current node (for fidelity resolution). Story 49-5.
|
|
202
|
+
let lastIncomingEdge = undefined;
|
|
203
|
+
// Capture scenario manifest for integrity checks (story 44-4).
|
|
204
|
+
// Only runs when scenarioStore is configured; otherwise skipped (backward-compatible).
|
|
205
|
+
let scenarioManifest = null;
|
|
206
|
+
if (config.scenarioStore) {
|
|
207
|
+
scenarioManifest = await config.scenarioStore.discover();
|
|
208
|
+
}
|
|
209
|
+
// RunStateManager for per-run artifact persistence (story 44-7).
|
|
210
|
+
// Opt-in: only instantiated when dotSource is provided. Backward-compatible.
|
|
211
|
+
const runStateManager = config.dotSource
|
|
212
|
+
? new RunStateManager({ runDir: config.logsRoot })
|
|
213
|
+
: null;
|
|
214
|
+
if (runStateManager) {
|
|
215
|
+
await runStateManager.initRun(config.dotSource);
|
|
216
|
+
}
|
|
217
|
+
// -----------------------------------------------------------------------
|
|
218
|
+
// Persistence: subscribe to scenario:completed for score tracking (story 46-3)
|
|
219
|
+
// The event payload does not include nodeId, so we use lastScenarioNodeId
|
|
220
|
+
// which is set to currentNode.id each time a node starts executing.
|
|
221
|
+
// -----------------------------------------------------------------------
|
|
222
|
+
if (config.adapter && config.eventBus) {
|
|
223
|
+
const persistAdapter = config.adapter;
|
|
224
|
+
const scenarioHandler = (payload) => {
|
|
225
|
+
const threshold = config.satisfactionThreshold ?? 0.8;
|
|
226
|
+
const scored = computeSatisfactionScore(payload.results, threshold);
|
|
227
|
+
insertScenarioResult(persistAdapter, {
|
|
228
|
+
run_id: config.runId,
|
|
229
|
+
node_id: lastScenarioNodeId || 'unknown',
|
|
230
|
+
iteration: payload.iteration,
|
|
231
|
+
total_scenarios: payload.results.summary.total,
|
|
232
|
+
passed: payload.results.summary.passed,
|
|
233
|
+
failed: payload.results.summary.failed,
|
|
234
|
+
satisfaction_score: scored.score,
|
|
235
|
+
threshold: scored.threshold,
|
|
236
|
+
passes: scored.passes,
|
|
237
|
+
details: JSON.stringify(scored.breakdown),
|
|
238
|
+
executed_at: new Date().toISOString(),
|
|
239
|
+
}).catch((err) => {
|
|
240
|
+
// Persistence errors must not crash the executor — log at debug level only
|
|
241
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
242
|
+
console.warn(`[executor] scenario_results persistence failed for run ${config.runId}: ${msg}`);
|
|
243
|
+
});
|
|
244
|
+
};
|
|
245
|
+
config.eventBus.on('scenario:completed', scenarioHandler);
|
|
246
|
+
}
|
|
247
|
+
// -----------------------------------------------------------------------
|
|
248
|
+
// Persistence: insert graph_runs row at run start (story 46-3)
|
|
249
|
+
// Persistence errors must not crash the executor — swallow silently.
|
|
250
|
+
// -----------------------------------------------------------------------
|
|
251
|
+
if (config.adapter) {
|
|
252
|
+
try {
|
|
253
|
+
await upsertGraphRun(config.adapter, {
|
|
254
|
+
id: config.runId,
|
|
255
|
+
graph_file: graph.id || config.runId,
|
|
256
|
+
...(graph.goal ? { graph_goal: graph.goal } : {}),
|
|
257
|
+
status: 'running',
|
|
258
|
+
started_at: runStartedAt,
|
|
259
|
+
node_count: graph.nodes.size,
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
catch (persistErr) {
|
|
263
|
+
const msg = persistErr instanceof Error ? persistErr.message : String(persistErr);
|
|
264
|
+
console.warn(`[executor] graph_runs insert failed for run ${config.runId}: ${msg}`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
// -----------------------------------------------------------------------
|
|
268
|
+
// Determine starting node (normal start or resume)
|
|
269
|
+
// -----------------------------------------------------------------------
|
|
270
|
+
let currentNode;
|
|
271
|
+
if (config.checkpointPath) {
|
|
272
|
+
const checkpoint = await checkpointManager.load(config.checkpointPath);
|
|
273
|
+
const resumeState = checkpointManager.resume(graph, checkpoint);
|
|
274
|
+
context = resumeState.context;
|
|
275
|
+
completedNodes = [...resumeState.completedNodes];
|
|
276
|
+
nodeRetries = { ...resumeState.nodeRetries };
|
|
277
|
+
firstResumedFidelity = resumeState.firstResumedNodeFidelity;
|
|
278
|
+
resumeCompletedSet = resumeState.completedNodes;
|
|
279
|
+
if (resumeState.completedNodes.has(checkpoint.currentNode)) {
|
|
280
|
+
// Last checkpoint node was fully completed — resume from the NEXT node
|
|
281
|
+
const lastNode = graph.nodes.get(checkpoint.currentNode);
|
|
282
|
+
if (lastNode) {
|
|
283
|
+
// KNOWN LIMITATION: The Checkpoint type does not store the final outcome
|
|
284
|
+
// status of the last completed node, so we must assume SUCCESS when calling
|
|
285
|
+
// selectEdge() to advance past it during resume. If the checkpointed node's
|
|
286
|
+
// actual last outcome was non-SUCCESS (e.g., FAILURE with a dedicated failure
|
|
287
|
+
// edge), resume will select the SUCCESS edge rather than the FAILURE edge,
|
|
288
|
+
// diverging from the original execution path. Storing `lastOutcomeStatus` in
|
|
289
|
+
// the Checkpoint type would allow a faithful replay.
|
|
290
|
+
const nextEdge = await selectEdge(lastNode, { status: 'SUCCESS' }, context, graph, {
|
|
291
|
+
...(config.eventBus !== undefined ? { eventBus: config.eventBus } : {}),
|
|
292
|
+
runId: config.runId,
|
|
293
|
+
});
|
|
294
|
+
if (nextEdge) {
|
|
295
|
+
const nextNode = graph.nodes.get(nextEdge.toNode);
|
|
296
|
+
if (!nextNode) {
|
|
297
|
+
throw new Error(`Edge target node "${nextEdge.toNode}" not found in graph`);
|
|
298
|
+
}
|
|
299
|
+
currentNode = nextNode;
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
// No outgoing edge from last completed node — may already be done
|
|
303
|
+
currentNode = graph.startNode();
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
307
|
+
currentNode = graph.startNode();
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
// Last checkpoint node was NOT completed (process was interrupted mid-node)
|
|
312
|
+
// Re-dispatch it from the resumed run
|
|
313
|
+
const resumeNode = graph.nodes.get(checkpoint.currentNode);
|
|
314
|
+
if (resumeNode) {
|
|
315
|
+
currentNode = resumeNode;
|
|
316
|
+
}
|
|
317
|
+
else {
|
|
318
|
+
currentNode = graph.startNode();
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
currentNode = graph.startNode();
|
|
324
|
+
}
|
|
325
|
+
// -----------------------------------------------------------------------
|
|
326
|
+
// Write runId to context so handlers can read it via context.getString("__runId")
|
|
327
|
+
// Set here (after all context assignments) so it covers both fresh-start and resume.
|
|
328
|
+
// Story 50-9 (AC4).
|
|
329
|
+
// -----------------------------------------------------------------------
|
|
330
|
+
context.set('__runId', config.runId ?? 'unknown');
|
|
331
|
+
// -----------------------------------------------------------------------
|
|
332
|
+
// Main traversal loop
|
|
333
|
+
// -----------------------------------------------------------------------
|
|
334
|
+
while (true) {
|
|
335
|
+
// --- Budget checks (story 45-8): session budget (highest priority), then pipeline ---
|
|
336
|
+
// Budget enforcement priority order: session > pipeline > per-node retries (dispatchWithRetry)
|
|
337
|
+
const sessionResult = sessionManager.checkBudget((config.wallClockCapMs ?? 0) / 1000);
|
|
338
|
+
if (!sessionResult.allowed) {
|
|
339
|
+
config.eventBus?.emit('convergence:budget-exhausted', {
|
|
340
|
+
runId: config.runId,
|
|
341
|
+
level: 'session',
|
|
342
|
+
reason: sessionResult.reason,
|
|
343
|
+
});
|
|
344
|
+
await persistExit('failed', `Session budget exceeded: ${sessionResult.reason}`);
|
|
345
|
+
return { status: 'FAIL', failureReason: `Session budget exceeded: ${sessionResult.reason}` };
|
|
346
|
+
}
|
|
347
|
+
const pipelineResult = pipelineManager.checkBudget(config.pipelineBudgetCapUsd ?? 0);
|
|
348
|
+
if (!pipelineResult.allowed) {
|
|
349
|
+
config.eventBus?.emit('convergence:budget-exhausted', {
|
|
350
|
+
runId: config.runId,
|
|
351
|
+
level: 'pipeline',
|
|
352
|
+
reason: pipelineResult.reason,
|
|
353
|
+
});
|
|
354
|
+
await persistExit('failed', `Pipeline budget exceeded: ${pipelineResult.reason}`);
|
|
355
|
+
return { status: 'FAIL', failureReason: `Pipeline budget exceeded: ${pipelineResult.reason}` };
|
|
356
|
+
}
|
|
357
|
+
// Exit condition: arrived at the exit node → evaluate goal gates (story 42-16)
|
|
358
|
+
const exitNode = graph.exitNode();
|
|
359
|
+
if (currentNode.id === exitNode.id) {
|
|
360
|
+
// scenario-primary mode forces satisfaction score as the authoritative gate signal (story 46-6)
|
|
361
|
+
const useScenarioPrimary = config.qualityMode === 'scenario-primary';
|
|
362
|
+
const gateResult = controller.checkGoalGates(graph, config.runId, config.eventBus, (useScenarioPrimary || config.satisfactionThreshold !== undefined)
|
|
363
|
+
? { context, satisfactionThreshold: config.satisfactionThreshold ?? 0.8 }
|
|
364
|
+
: undefined);
|
|
365
|
+
// Emit scenario:advisory-computed when code review verdict is in context and mode is scenario-primary (story 46-6)
|
|
366
|
+
if (useScenarioPrimary && config.eventBus) {
|
|
367
|
+
const rawVerdict = context.getString(CONTEXT_KEY_CODE_REVIEW_VERDICT, '');
|
|
368
|
+
if (rawVerdict !== '') {
|
|
369
|
+
const codeReviewVerdict = rawVerdict;
|
|
370
|
+
const coordinator = createDualSignalCoordinator({
|
|
371
|
+
eventBus: config.eventBus,
|
|
372
|
+
threshold: config.satisfactionThreshold ?? 0.8,
|
|
373
|
+
qualityMode: 'scenario-primary',
|
|
374
|
+
});
|
|
375
|
+
const score = context.getNumber('satisfaction_score', 0);
|
|
376
|
+
coordinator.evaluate(codeReviewVerdict, score, config.runId);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
if (!gateResult.satisfied) {
|
|
380
|
+
// Use ConvergenceController.resolveRetryTarget (story 45-8 — replaces inline 4-step chain)
|
|
381
|
+
const failingNodeId = gateResult.failedGates[0];
|
|
382
|
+
const failingGateNode = graph.nodes.get(failingNodeId);
|
|
383
|
+
const retryTargetId = failingGateNode
|
|
384
|
+
? controller.resolveRetryTarget(failingGateNode, graph)
|
|
385
|
+
: null;
|
|
386
|
+
if (!retryTargetId) {
|
|
387
|
+
await persistExit('failed', 'Goal gate failed: no retry target');
|
|
388
|
+
return { status: 'FAIL', failureReason: 'Goal gate failed: no retry target' };
|
|
389
|
+
}
|
|
390
|
+
const retryNode = graph.nodes.get(retryTargetId);
|
|
391
|
+
if (!retryNode) {
|
|
392
|
+
throw new Error(`Retry target node "${retryTargetId}" not found in graph`);
|
|
393
|
+
}
|
|
394
|
+
// Increment convergence iteration and record satisfaction score for plateau detection
|
|
395
|
+
convergenceIteration++;
|
|
396
|
+
const satisfactionScore = context.getNumber('satisfaction_score', 0.0);
|
|
397
|
+
plateauDetector.recordScore(convergenceIteration, satisfactionScore);
|
|
398
|
+
// Check for plateau (story 45-8, AC5)
|
|
399
|
+
const plateauResult = checkPlateauAndEmit(plateauDetector, {
|
|
400
|
+
runId: config.runId,
|
|
401
|
+
nodeId: retryTargetId,
|
|
402
|
+
...(config.eventBus ? { eventBus: config.eventBus } : {}),
|
|
403
|
+
});
|
|
404
|
+
if (plateauResult.plateaued) {
|
|
405
|
+
await persistExit('failed', `Convergence plateau detected after ${convergenceIteration} iteration(s)`);
|
|
406
|
+
return {
|
|
407
|
+
status: 'FAIL',
|
|
408
|
+
failureReason: `Convergence plateau detected after ${convergenceIteration} iteration(s): scores plateaued at [${plateauResult.scores.join(', ')}]`,
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
// Build and inject remediation context before routing to retry target (story 45-8, AC6)
|
|
412
|
+
const remediation = buildRemediationContext({
|
|
413
|
+
previousFailureReason: `Goal gate unsatisfied: ${gateResult.failedGates.join(', ')}`,
|
|
414
|
+
iterationCount: convergenceIteration,
|
|
415
|
+
satisfactionScoreHistory: plateauResult.scores,
|
|
416
|
+
});
|
|
417
|
+
injectRemediationContext(context, remediation);
|
|
418
|
+
// Compress old iteration contexts if auto-summarizer threshold
|
|
419
|
+
// exceeded (story 49-3). This prevents unbounded token growth in
|
|
420
|
+
// long convergence loops by summarizing earlier iterations.
|
|
421
|
+
await controller.prepareForIteration(convergenceIteration);
|
|
422
|
+
// Route to retry target; suppress cycle check for convergence loop retry
|
|
423
|
+
skipCycleCheck = true;
|
|
424
|
+
currentNode = retryNode;
|
|
425
|
+
continue;
|
|
426
|
+
}
|
|
427
|
+
await persistExit('completed', 'SUCCESS');
|
|
428
|
+
return { status: 'SUCCESS' };
|
|
429
|
+
}
|
|
430
|
+
// Resume skip: nodes already completed in a prior run are advanced over
|
|
431
|
+
// without dispatching their handler again
|
|
432
|
+
if (resumeCompletedSet?.has(currentNode.id)) {
|
|
433
|
+
// Cast to GraphOutcome (types.ts:Outcome) as required by selectEdge API.
|
|
434
|
+
const skipEdge = await selectEdge(currentNode, { status: 'SUCCESS' }, context, graph, {
|
|
435
|
+
...(config.eventBus !== undefined ? { eventBus: config.eventBus } : {}),
|
|
436
|
+
runId: config.runId,
|
|
437
|
+
});
|
|
438
|
+
if (!skipEdge) {
|
|
439
|
+
await persistExit('failed', `No outgoing edge from node ${currentNode.id}`);
|
|
440
|
+
return {
|
|
441
|
+
status: 'FAIL',
|
|
442
|
+
failureReason: `No outgoing edge from node ${currentNode.id}`,
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
config.eventBus?.emit('graph:edge-selected', {
|
|
446
|
+
runId: config.runId,
|
|
447
|
+
fromNode: currentNode.id,
|
|
448
|
+
toNode: skipEdge.toNode,
|
|
449
|
+
step,
|
|
450
|
+
...(skipEdge.label !== '' ? { edgeLabel: skipEdge.label } : {}),
|
|
451
|
+
});
|
|
452
|
+
step++;
|
|
453
|
+
const skipNextNode = graph.nodes.get(skipEdge.toNode);
|
|
454
|
+
if (!skipNextNode) {
|
|
455
|
+
throw new Error(`Edge target node "${skipEdge.toNode}" not found in graph`);
|
|
456
|
+
}
|
|
457
|
+
currentNode = skipNextNode;
|
|
458
|
+
continue;
|
|
459
|
+
}
|
|
460
|
+
// Cycle detection — exempt for nodes reached via loopRestart edges
|
|
461
|
+
if (!skipCycleCheck) {
|
|
462
|
+
const count = (visitCount.get(currentNode.id) ?? 0) + 1;
|
|
463
|
+
visitCount.set(currentNode.id, count);
|
|
464
|
+
if (count > graph.nodes.size * 3) {
|
|
465
|
+
throw new Error(`Graph cycle detected: node ${currentNode.id} visited ${count} times`);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
skipCycleCheck = false;
|
|
469
|
+
// Integrity check: verify scenario files before dispatching any tool node (story 44-4)
|
|
470
|
+
if (currentNode.type === 'tool' && config.scenarioStore && scenarioManifest) {
|
|
471
|
+
const integrityResult = await config.scenarioStore.verifyIntegrity(scenarioManifest);
|
|
472
|
+
if (!integrityResult.valid) {
|
|
473
|
+
config.eventBus?.emit('scenario:integrity-failed', {
|
|
474
|
+
runId: config.runId,
|
|
475
|
+
nodeId: currentNode.id,
|
|
476
|
+
tampered: integrityResult.tampered,
|
|
477
|
+
});
|
|
478
|
+
await persistExit('failed', `Scenario integrity violation before node "${currentNode.id}"`);
|
|
479
|
+
return {
|
|
480
|
+
status: 'FAIL',
|
|
481
|
+
failureReason: `Scenario integrity violation detected before node "${currentNode.id}": tampered files: ${integrityResult.tampered.join(', ')}`,
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
config.eventBus?.emit('scenario:integrity-passed', {
|
|
485
|
+
runId: config.runId,
|
|
486
|
+
nodeId: currentNode.id,
|
|
487
|
+
scenarioCount: scenarioManifest.scenarios.length,
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
// ----------------------------------------------------------------
|
|
491
|
+
// Track current node ID for scenario:completed event handler (story 46-3)
|
|
492
|
+
// The scenario:completed event payload has no nodeId field, so we capture it here.
|
|
493
|
+
// ----------------------------------------------------------------
|
|
494
|
+
lastScenarioNodeId = currentNode.id;
|
|
495
|
+
// ----------------------------------------------------------------
|
|
496
|
+
// Emit graph:node-started before handler invocation
|
|
497
|
+
// ----------------------------------------------------------------
|
|
498
|
+
config.eventBus?.emit('graph:node-started', {
|
|
499
|
+
runId: config.runId,
|
|
500
|
+
nodeId: currentNode.id,
|
|
501
|
+
nodeType: currentNode.type,
|
|
502
|
+
});
|
|
503
|
+
// ----------------------------------------------------------------
|
|
504
|
+
// Fidelity override for the first resumed node
|
|
505
|
+
// ----------------------------------------------------------------
|
|
506
|
+
const nodeToDispatch = firstResumedFidelity !== ''
|
|
507
|
+
? { ...currentNode, fidelity: firstResumedFidelity }
|
|
508
|
+
: currentNode;
|
|
509
|
+
firstResumedFidelity = ''; // clear after first use
|
|
510
|
+
// ----------------------------------------------------------------
|
|
511
|
+
// Pre-dispatch context summarization based on node fidelity (story 49-5)
|
|
512
|
+
// ----------------------------------------------------------------
|
|
513
|
+
if (config.summaryEngine) {
|
|
514
|
+
const effectiveFidelity = resolveFidelity(nodeToDispatch, lastIncomingEdge, graph);
|
|
515
|
+
const summaryLevel = parseFidelityLevel(effectiveFidelity);
|
|
516
|
+
if (summaryLevel !== null) {
|
|
517
|
+
const nodeContextContent = context.getString('factory.nodeContext', '');
|
|
518
|
+
if (nodeContextContent !== '') {
|
|
519
|
+
const summary = await config.summaryEngine.summarize(nodeContextContent, summaryLevel);
|
|
520
|
+
context.set('factory.compressedNodeContext', summary.content);
|
|
521
|
+
// Replace the primary context so downstream handlers use the
|
|
522
|
+
// compressed version. The original is preserved in
|
|
523
|
+
// factory.compressedNodeContext.originalHash for cache expansion.
|
|
524
|
+
context.set('factory.nodeContext', summary.content);
|
|
525
|
+
config.eventBus?.emit('graph:context-summarized', {
|
|
526
|
+
runId: config.runId,
|
|
527
|
+
nodeId: nodeToDispatch.id,
|
|
528
|
+
level: summaryLevel,
|
|
529
|
+
originalTokenCount: summary.originalTokenCount ?? 0,
|
|
530
|
+
summaryTokenCount: summary.summaryTokenCount ?? 0,
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
// Record dispatch start time for artifact timing (story 44-7)
|
|
536
|
+
const startedAt = Date.now();
|
|
537
|
+
// ----------------------------------------------------------------
|
|
538
|
+
// Dispatch handler with retry logic
|
|
539
|
+
// ----------------------------------------------------------------
|
|
540
|
+
let outcome = await dispatchWithRetry(nodeToDispatch, context, graph, config, nodeRetries);
|
|
541
|
+
// ----------------------------------------------------------------
|
|
542
|
+
// Hot-spin guard: if the handler completed in under 50ms (e.g., default
|
|
543
|
+
// handler returning instantly), yield the event loop to prevent CPU
|
|
544
|
+
// saturation in convergence loops with no-op handlers. In real pipelines
|
|
545
|
+
// handlers take minutes, so this never fires.
|
|
546
|
+
// ----------------------------------------------------------------
|
|
547
|
+
if (Date.now() - startedAt < 50) {
|
|
548
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
549
|
+
}
|
|
550
|
+
// ----------------------------------------------------------------
|
|
551
|
+
// allowPartial demotion (story 42-16, AC2/AC3)
|
|
552
|
+
// After the retry loop exits and the final outcome is determined:
|
|
553
|
+
// if the node does not accept PARTIAL_SUCCESS, demote to FAIL.
|
|
554
|
+
// This check uses nodeToDispatch (which has the correct allowPartial value).
|
|
555
|
+
// ----------------------------------------------------------------
|
|
556
|
+
if (outcome.status === 'PARTIAL_SUCCESS' && !nodeToDispatch.allowPartial) {
|
|
557
|
+
outcome = {
|
|
558
|
+
...outcome,
|
|
559
|
+
status: 'FAIL',
|
|
560
|
+
failureReason: outcome.failureReason
|
|
561
|
+
? `${outcome.failureReason} (PARTIAL_SUCCESS not accepted: allowPartial=false)`
|
|
562
|
+
: 'PARTIAL_SUCCESS not accepted: allowPartial=false',
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
// ----------------------------------------------------------------
|
|
566
|
+
// Write per-node artifacts (story 44-7)
|
|
567
|
+
// Called after allowPartial demotion so the persisted status reflects the final outcome.
|
|
568
|
+
// ----------------------------------------------------------------
|
|
569
|
+
if (runStateManager) {
|
|
570
|
+
const completedAt = Date.now();
|
|
571
|
+
const nodeArtifacts = {
|
|
572
|
+
nodeId: nodeToDispatch.id,
|
|
573
|
+
nodeType: nodeToDispatch.type,
|
|
574
|
+
status: outcome.status,
|
|
575
|
+
startedAt,
|
|
576
|
+
completedAt,
|
|
577
|
+
durationMs: completedAt - startedAt,
|
|
578
|
+
};
|
|
579
|
+
if (nodeToDispatch.type === 'codergen') {
|
|
580
|
+
const rawPrompt = nodeToDispatch.prompt || nodeToDispatch.label;
|
|
581
|
+
if (rawPrompt)
|
|
582
|
+
nodeArtifacts.prompt = rawPrompt;
|
|
583
|
+
if (typeof outcome.notes === 'string')
|
|
584
|
+
nodeArtifacts.response = outcome.notes;
|
|
585
|
+
}
|
|
586
|
+
await runStateManager.writeNodeArtifacts(nodeArtifacts);
|
|
587
|
+
}
|
|
588
|
+
// ----------------------------------------------------------------
|
|
589
|
+
// Emit node completion/failure event AFTER allowPartial demotion (story 42-16)
|
|
590
|
+
// This placement ensures graph:node-failed is emitted when PARTIAL_SUCCESS is
|
|
591
|
+
// demoted to FAIL, and graph:node-completed is never emitted for a demoted node.
|
|
592
|
+
// ----------------------------------------------------------------
|
|
593
|
+
if (outcome.status === 'FAIL') {
|
|
594
|
+
config.eventBus?.emit('graph:node-failed', {
|
|
595
|
+
runId: config.runId,
|
|
596
|
+
nodeId: nodeToDispatch.id,
|
|
597
|
+
failureReason: outcome.failureReason ?? 'Unknown failure',
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
else {
|
|
601
|
+
config.eventBus?.emit('graph:node-completed', {
|
|
602
|
+
runId: config.runId,
|
|
603
|
+
nodeId: nodeToDispatch.id,
|
|
604
|
+
outcome,
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
// ----------------------------------------------------------------
|
|
608
|
+
// Record outcome with ConvergenceController (story 42-16)
|
|
609
|
+
// Map events.ts StageStatus to types.ts OutcomeStatus for the controller.
|
|
610
|
+
// ----------------------------------------------------------------
|
|
611
|
+
{
|
|
612
|
+
const controllerStatus = outcome.status === 'SUCCESS' ? 'SUCCESS'
|
|
613
|
+
: outcome.status === 'PARTIAL_SUCCESS' ? 'PARTIAL_SUCCESS'
|
|
614
|
+
: 'FAILURE';
|
|
615
|
+
controller.recordOutcome(nodeToDispatch.id, controllerStatus);
|
|
616
|
+
// Record iteration context for auto-summarization (story 49-3).
|
|
617
|
+
// The context string captures the outcome so compression can
|
|
618
|
+
// preserve key facts from earlier iterations.
|
|
619
|
+
const iterContent = context.getString('factory.nodeContext', '');
|
|
620
|
+
controller.recordIterationContext({
|
|
621
|
+
index: convergenceIteration,
|
|
622
|
+
content: iterContent,
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
// ----------------------------------------------------------------
|
|
626
|
+
// Apply context updates from outcome
|
|
627
|
+
// ----------------------------------------------------------------
|
|
628
|
+
if (outcome.contextUpdates) {
|
|
629
|
+
for (const [key, value] of Object.entries(outcome.contextUpdates)) {
|
|
630
|
+
context.set(key, value);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
// Set 'outcome' in context so conditional edges (e.g. condition="outcome=success")
|
|
634
|
+
// can reference the handler's result. Status is lowercased for consistency with
|
|
635
|
+
// DOT convention (outcome=success, outcome=fail).
|
|
636
|
+
// NOTE: This overwrites on every node. For sequential graphs this is correct — each
|
|
637
|
+
// node's outcome is available to its outgoing edge conditions. For future parallel
|
|
638
|
+
// subgraphs (Epic 50), this would need to be scoped per-subgraph to avoid clobbering.
|
|
639
|
+
context.set('outcome', outcome.status.toLowerCase());
|
|
640
|
+
// ----------------------------------------------------------------
|
|
641
|
+
// Accumulate per-node cost for pipeline budget tracking (story 45-8)
|
|
642
|
+
// Convention: CodergenBackend writes 'factory.lastNodeCostUsd' to contextUpdates.
|
|
643
|
+
// The key holds only the LAST node's cost; PipelineBudgetManager owns the running total.
|
|
644
|
+
// This must run AFTER contextUpdates are applied so context.getNumber reflects latest output.
|
|
645
|
+
// ----------------------------------------------------------------
|
|
646
|
+
const nodeCost = context.getNumber('factory.lastNodeCostUsd', 0);
|
|
647
|
+
if (nodeCost > 0) {
|
|
648
|
+
pipelineManager.addCost(nodeCost);
|
|
649
|
+
}
|
|
650
|
+
// ----------------------------------------------------------------
|
|
651
|
+
// Persistence: write per-node result row (story 46-3, AC4)
|
|
652
|
+
// Written after allowPartial demotion (outcome.status is final here)
|
|
653
|
+
// and after cost accumulation so cost_usd reflects the actual node cost.
|
|
654
|
+
// ----------------------------------------------------------------
|
|
655
|
+
if (config.adapter) {
|
|
656
|
+
const nodeCompletedAt = Date.now();
|
|
657
|
+
try {
|
|
658
|
+
await insertGraphNodeResult(config.adapter, {
|
|
659
|
+
run_id: config.runId,
|
|
660
|
+
node_id: nodeToDispatch.id,
|
|
661
|
+
attempt: (nodeRetries[nodeToDispatch.id] ?? 0) + 1,
|
|
662
|
+
status: outcome.status,
|
|
663
|
+
started_at: new Date(startedAt).toISOString(),
|
|
664
|
+
completed_at: new Date(nodeCompletedAt).toISOString(),
|
|
665
|
+
duration_ms: nodeCompletedAt - startedAt,
|
|
666
|
+
cost_usd: nodeCost,
|
|
667
|
+
...(outcome.failureReason !== undefined ? { failure_reason: outcome.failureReason } : {}),
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
catch (persistErr) {
|
|
671
|
+
const msg = persistErr instanceof Error ? persistErr.message : String(persistErr);
|
|
672
|
+
console.warn(`[executor] graph_node_results insert failed for node ${currentNode.id}: ${msg}`);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
// ----------------------------------------------------------------
|
|
676
|
+
// Push completed node (skip for loopRestart re-entry nodes)
|
|
677
|
+
// ----------------------------------------------------------------
|
|
678
|
+
if (!skipCompletedPush) {
|
|
679
|
+
completedNodes.push(currentNode.id);
|
|
680
|
+
}
|
|
681
|
+
skipCompletedPush = false;
|
|
682
|
+
// ----------------------------------------------------------------
|
|
683
|
+
// Save checkpoint after each node completion
|
|
684
|
+
// ----------------------------------------------------------------
|
|
685
|
+
await checkpointManager.save(config.logsRoot, {
|
|
686
|
+
currentNode: currentNode.id,
|
|
687
|
+
completedNodes,
|
|
688
|
+
nodeRetries,
|
|
689
|
+
context,
|
|
690
|
+
});
|
|
691
|
+
config.eventBus?.emit('graph:checkpoint-saved', {
|
|
692
|
+
runId: config.runId,
|
|
693
|
+
nodeId: currentNode.id,
|
|
694
|
+
checkpointPath: checkpointFilePath,
|
|
695
|
+
});
|
|
696
|
+
// ----------------------------------------------------------------
|
|
697
|
+
// FAIL routing (story 42-16)
|
|
698
|
+
// When outcome is FAIL (including demoted PARTIAL_SUCCESS), route to
|
|
699
|
+
// the node-level retryTarget chain or return FAIL immediately.
|
|
700
|
+
// ----------------------------------------------------------------
|
|
701
|
+
if (outcome.status === 'FAIL') {
|
|
702
|
+
// Resolves via 4-level chain: node.retryTarget → node.fallbackRetryTarget → graph.retryTarget → graph.fallbackRetryTarget → null (story 45-2)
|
|
703
|
+
const retryTarget = controller.resolveRetryTarget(currentNode, graph);
|
|
704
|
+
if (retryTarget) {
|
|
705
|
+
const retryNode = graph.nodes.get(retryTarget);
|
|
706
|
+
if (!retryNode) {
|
|
707
|
+
throw new Error(`Retry target node "${retryTarget}" not found in graph`);
|
|
708
|
+
}
|
|
709
|
+
skipCycleCheck = true;
|
|
710
|
+
currentNode = retryNode;
|
|
711
|
+
continue;
|
|
712
|
+
}
|
|
713
|
+
// No retry target found. If this node has conditional outgoing edges
|
|
714
|
+
// (e.g. code_review with shape=diamond), fall through to edge selection so
|
|
715
|
+
// condition-based routing can handle the FAIL outcome. Otherwise return FAIL.
|
|
716
|
+
const outgoing = graph.edges.filter((e) => e.fromNode === currentNode.id);
|
|
717
|
+
const hasConditionalEdge = outgoing.some((e) => e.condition && e.condition.trim() !== '');
|
|
718
|
+
if (!hasConditionalEdge) {
|
|
719
|
+
await persistExit('failed', outcome.failureReason ?? 'FAIL');
|
|
720
|
+
return {
|
|
721
|
+
status: 'FAIL',
|
|
722
|
+
...(outcome.failureReason !== undefined && { failureReason: outcome.failureReason }),
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
// Fall through to edge selection for conditional routing.
|
|
726
|
+
// The cycle detection (visitCount) bounds this loop — conditional edge targets
|
|
727
|
+
// with maxRetries>0 (e.g. dev_story set by --max-review-cycles) will eventually
|
|
728
|
+
// hit the visit limit. Additionally, track fail-route count as a safeguard.
|
|
729
|
+
const routeCount = (failRouteCount.get(currentNode.id) ?? 0) + 1;
|
|
730
|
+
failRouteCount.set(currentNode.id, routeCount);
|
|
731
|
+
// Safeguard: cap fail-route loops at graph.defaultMaxRetries or 3 (whichever is higher)
|
|
732
|
+
if (routeCount > Math.max(graph.defaultMaxRetries || 0, 3)) {
|
|
733
|
+
await persistExit('failed', outcome.failureReason ?? 'FAIL');
|
|
734
|
+
return {
|
|
735
|
+
status: 'FAIL',
|
|
736
|
+
...(outcome.failureReason !== undefined && { failureReason: outcome.failureReason }),
|
|
737
|
+
};
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
// ----------------------------------------------------------------
|
|
741
|
+
// Select next edge
|
|
742
|
+
// ----------------------------------------------------------------
|
|
743
|
+
// Cast outcome to GraphOutcome (types.ts:Outcome) as required by selectEdge API.
|
|
744
|
+
const edge = await selectEdge(currentNode, outcome, context, graph, {
|
|
745
|
+
...(config.eventBus !== undefined ? { eventBus: config.eventBus } : {}),
|
|
746
|
+
runId: config.runId,
|
|
747
|
+
});
|
|
748
|
+
if (!edge) {
|
|
749
|
+
await persistExit('failed', `No outgoing edge from node ${currentNode.id}`);
|
|
750
|
+
return {
|
|
751
|
+
status: 'FAIL',
|
|
752
|
+
failureReason: `No outgoing edge from node ${currentNode.id}`,
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
// ----------------------------------------------------------------
|
|
756
|
+
// Emit graph:edge-selected after edge selection
|
|
757
|
+
// ----------------------------------------------------------------
|
|
758
|
+
config.eventBus?.emit('graph:edge-selected', {
|
|
759
|
+
runId: config.runId,
|
|
760
|
+
fromNode: currentNode.id,
|
|
761
|
+
toNode: edge.toNode,
|
|
762
|
+
step,
|
|
763
|
+
...(edge.label !== '' ? { edgeLabel: edge.label } : {}),
|
|
764
|
+
});
|
|
765
|
+
step++;
|
|
766
|
+
// ----------------------------------------------------------------
|
|
767
|
+
// Handle loopRestart: next iteration skips cycle check and
|
|
768
|
+
// completed push (treating target as a fresh re-entry)
|
|
769
|
+
// ----------------------------------------------------------------
|
|
770
|
+
if (edge.loopRestart) {
|
|
771
|
+
skipCycleCheck = true;
|
|
772
|
+
skipCompletedPush = true;
|
|
773
|
+
}
|
|
774
|
+
// ----------------------------------------------------------------
|
|
775
|
+
// Advance to next node
|
|
776
|
+
// ----------------------------------------------------------------
|
|
777
|
+
const nextNode = graph.nodes.get(edge.toNode);
|
|
778
|
+
if (!nextNode) {
|
|
779
|
+
throw new Error(`Edge target node "${edge.toNode}" not found in graph`);
|
|
780
|
+
}
|
|
781
|
+
lastIncomingEdge = edge;
|
|
782
|
+
currentNode = nextNode;
|
|
783
|
+
}
|
|
784
|
+
},
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
//# sourceMappingURL=executor.js.map
|