@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,901 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for the graph executor (story 42-14).
|
|
3
|
+
*
|
|
4
|
+
* Covers all 7 acceptance criteria:
|
|
5
|
+
* AC1 — 3-node graph traversal returns SUCCESS
|
|
6
|
+
* AC2 — handler exceptions converted to FAIL outcome
|
|
7
|
+
* AC3 — retry with exponential backoff (via fake timers)
|
|
8
|
+
* AC4 — checkpoint saved after each node; resume from checkpoint
|
|
9
|
+
* AC5 — all 6 FactoryEvents emitted with correct payloads
|
|
10
|
+
* AC6 — per-node transition overhead < 100ms for 20-node graph
|
|
11
|
+
* AC7 — all unit tests pass
|
|
12
|
+
*/
|
|
13
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
14
|
+
import { mkdtemp, rm, readFile } from 'node:fs/promises';
|
|
15
|
+
import path from 'node:path';
|
|
16
|
+
import os from 'node:os';
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// Hoist mock factories so they are available when vi.mock() runs
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
const { mockSave, mockLoad, mockResume } = vi.hoisted(() => ({
|
|
21
|
+
mockSave: vi.fn().mockResolvedValue(undefined),
|
|
22
|
+
mockLoad: vi.fn(),
|
|
23
|
+
mockResume: vi.fn(),
|
|
24
|
+
}));
|
|
25
|
+
const { mockEvaluateGates, mockRecordOutcome, mockCheckGoalGates, mockResolveRetryTarget, mockRecordIterationContext, mockPrepareForIteration } = vi.hoisted(() => ({
|
|
26
|
+
mockEvaluateGates: vi.fn().mockReturnValue({ satisfied: true, failingNodes: [] }),
|
|
27
|
+
mockRecordOutcome: vi.fn(),
|
|
28
|
+
mockCheckGoalGates: vi.fn().mockReturnValue({ satisfied: true, failedGates: [] }),
|
|
29
|
+
mockResolveRetryTarget: vi.fn().mockReturnValue(null),
|
|
30
|
+
mockRecordIterationContext: vi.fn(),
|
|
31
|
+
mockPrepareForIteration: vi.fn().mockResolvedValue([]),
|
|
32
|
+
}));
|
|
33
|
+
// Mock CheckpointManager to avoid real file I/O in executor tests
|
|
34
|
+
vi.mock('../checkpoint.js', () => ({
|
|
35
|
+
CheckpointManager: vi.fn().mockImplementation(() => ({
|
|
36
|
+
save: mockSave,
|
|
37
|
+
load: mockLoad,
|
|
38
|
+
resume: mockResume,
|
|
39
|
+
})),
|
|
40
|
+
}));
|
|
41
|
+
// Mock ConvergenceController to avoid implicit reliance on goalGate=false for all nodes.
|
|
42
|
+
// Explicit mock ensures tests are not fragile to future nodes with goalGate=true.
|
|
43
|
+
// Path is relative to this test file: __tests__/../../convergence/index.js → src/convergence/index.js
|
|
44
|
+
// Budget/plateau managers are mocked as no-ops so existing traversal tests are not affected (story 45-8).
|
|
45
|
+
vi.mock('../../convergence/index.js', () => ({
|
|
46
|
+
createConvergenceController: vi.fn().mockImplementation(() => ({
|
|
47
|
+
evaluateGates: mockEvaluateGates,
|
|
48
|
+
recordOutcome: mockRecordOutcome,
|
|
49
|
+
checkGoalGates: mockCheckGoalGates,
|
|
50
|
+
resolveRetryTarget: mockResolveRetryTarget,
|
|
51
|
+
recordIterationContext: mockRecordIterationContext,
|
|
52
|
+
prepareForIteration: mockPrepareForIteration,
|
|
53
|
+
getStoredContexts: vi.fn().mockReturnValue([]),
|
|
54
|
+
})),
|
|
55
|
+
SessionBudgetManager: vi.fn().mockImplementation(() => ({
|
|
56
|
+
checkBudget: vi.fn().mockReturnValue({ allowed: true }),
|
|
57
|
+
getElapsedMs: vi.fn().mockReturnValue(0),
|
|
58
|
+
reset: vi.fn(),
|
|
59
|
+
})),
|
|
60
|
+
PipelineBudgetManager: vi.fn().mockImplementation(() => ({
|
|
61
|
+
checkBudget: vi.fn().mockReturnValue({ allowed: true }),
|
|
62
|
+
addCost: vi.fn(),
|
|
63
|
+
getTotalCost: vi.fn().mockReturnValue(0),
|
|
64
|
+
reset: vi.fn(),
|
|
65
|
+
})),
|
|
66
|
+
createPlateauDetector: vi.fn().mockReturnValue({
|
|
67
|
+
recordScore: vi.fn(),
|
|
68
|
+
isPlateaued: vi.fn().mockReturnValue(false),
|
|
69
|
+
getWindow: vi.fn().mockReturnValue(3),
|
|
70
|
+
getScores: vi.fn().mockReturnValue([]),
|
|
71
|
+
}),
|
|
72
|
+
checkPlateauAndEmit: vi.fn().mockReturnValue({ plateaued: false, scores: [] }),
|
|
73
|
+
buildRemediationContext: vi.fn().mockReturnValue({
|
|
74
|
+
previousFailureReason: '',
|
|
75
|
+
scenarioDiff: '',
|
|
76
|
+
iterationCount: 0,
|
|
77
|
+
satisfactionScoreHistory: [],
|
|
78
|
+
fixScope: '',
|
|
79
|
+
}),
|
|
80
|
+
injectRemediationContext: vi.fn(),
|
|
81
|
+
computeBackoffDelay: vi.fn().mockImplementation((attempt) => Math.min(1000 * 2 ** attempt, 30000)),
|
|
82
|
+
}));
|
|
83
|
+
// Import AFTER mocking
|
|
84
|
+
import { createGraphExecutor } from '../executor.js';
|
|
85
|
+
import { GraphContext } from '../context.js';
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
// Test helpers
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
const minimalNode = {
|
|
90
|
+
id: '',
|
|
91
|
+
label: '',
|
|
92
|
+
shape: '',
|
|
93
|
+
type: '',
|
|
94
|
+
prompt: '',
|
|
95
|
+
maxRetries: 0,
|
|
96
|
+
goalGate: false,
|
|
97
|
+
retryTarget: '',
|
|
98
|
+
fallbackRetryTarget: '',
|
|
99
|
+
fidelity: '',
|
|
100
|
+
threadId: '',
|
|
101
|
+
class: '',
|
|
102
|
+
timeout: 0,
|
|
103
|
+
llmModel: '',
|
|
104
|
+
llmProvider: '',
|
|
105
|
+
reasoningEffort: '',
|
|
106
|
+
autoStatus: false,
|
|
107
|
+
allowPartial: false,
|
|
108
|
+
toolCommand: '',
|
|
109
|
+
backend: '',
|
|
110
|
+
};
|
|
111
|
+
function makeNode(id, overrides) {
|
|
112
|
+
return { ...minimalNode, id, ...overrides };
|
|
113
|
+
}
|
|
114
|
+
function makeEdge(fromNode, toNode, overrides) {
|
|
115
|
+
return {
|
|
116
|
+
fromNode,
|
|
117
|
+
toNode,
|
|
118
|
+
label: '',
|
|
119
|
+
condition: '',
|
|
120
|
+
weight: 0,
|
|
121
|
+
fidelity: '',
|
|
122
|
+
threadId: '',
|
|
123
|
+
loopRestart: false,
|
|
124
|
+
...overrides,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Build a minimal Graph stub conforming to the Graph interface.
|
|
129
|
+
* startNodeId and exitNodeId designate which nodes play those roles.
|
|
130
|
+
*/
|
|
131
|
+
function makeGraph(nodeList, edgeList, startNodeId, exitNodeId) {
|
|
132
|
+
const nodeMap = new Map(nodeList.map((n) => [n.id, n]));
|
|
133
|
+
return {
|
|
134
|
+
id: '',
|
|
135
|
+
goal: '',
|
|
136
|
+
label: '',
|
|
137
|
+
modelStylesheet: '',
|
|
138
|
+
defaultMaxRetries: 0,
|
|
139
|
+
retryTarget: '',
|
|
140
|
+
fallbackRetryTarget: '',
|
|
141
|
+
defaultFidelity: '',
|
|
142
|
+
nodes: nodeMap,
|
|
143
|
+
edges: edgeList,
|
|
144
|
+
outgoingEdges: (nodeId) => edgeList.filter((e) => e.fromNode === nodeId),
|
|
145
|
+
startNode: () => nodeMap.get(startNodeId),
|
|
146
|
+
exitNode: () => nodeMap.get(exitNodeId),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/** Build a mock IHandlerRegistry that returns the given handler for all nodes. */
|
|
150
|
+
function makeRegistry(handler) {
|
|
151
|
+
return {
|
|
152
|
+
register: vi.fn(),
|
|
153
|
+
registerShape: vi.fn(),
|
|
154
|
+
setDefault: vi.fn(),
|
|
155
|
+
resolve: vi.fn().mockReturnValue(handler),
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
/** Build a mock TypedEventBus<FactoryEvents> with a spy on emit(). */
|
|
159
|
+
function makeEventBus() {
|
|
160
|
+
const emit = vi.fn();
|
|
161
|
+
const bus = {
|
|
162
|
+
emit,
|
|
163
|
+
on: vi.fn(),
|
|
164
|
+
off: vi.fn(),
|
|
165
|
+
};
|
|
166
|
+
return { bus, emit };
|
|
167
|
+
}
|
|
168
|
+
/** Minimal config with fake logsRoot. */
|
|
169
|
+
function makeConfig(registry, overrides) {
|
|
170
|
+
return {
|
|
171
|
+
runId: 'test-run-id',
|
|
172
|
+
logsRoot: '/tmp/executor-test',
|
|
173
|
+
handlerRegistry: registry,
|
|
174
|
+
...overrides,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
// ---------------------------------------------------------------------------
|
|
178
|
+
// Setup
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
180
|
+
beforeEach(() => {
|
|
181
|
+
vi.clearAllMocks();
|
|
182
|
+
mockSave.mockResolvedValue(undefined);
|
|
183
|
+
// Reset convergence mocks to default passing state
|
|
184
|
+
mockEvaluateGates.mockReturnValue({ satisfied: true, failingNodes: [] });
|
|
185
|
+
mockCheckGoalGates.mockReturnValue({ satisfied: true, failedGates: [] });
|
|
186
|
+
mockResolveRetryTarget.mockReturnValue(null);
|
|
187
|
+
});
|
|
188
|
+
// ---------------------------------------------------------------------------
|
|
189
|
+
// AC1: 3-node graph traversal returns SUCCESS
|
|
190
|
+
// ---------------------------------------------------------------------------
|
|
191
|
+
describe('AC1: 3-node graph traversal', () => {
|
|
192
|
+
it('dispatches handlers in order and returns SUCCESS', async () => {
|
|
193
|
+
const successHandler = vi.fn().mockResolvedValue({ status: 'SUCCESS' });
|
|
194
|
+
const registry = makeRegistry(successHandler);
|
|
195
|
+
const { bus, emit } = makeEventBus();
|
|
196
|
+
const startNode = makeNode('start');
|
|
197
|
+
const codergenNode = makeNode('codergen');
|
|
198
|
+
const exitNode = makeNode('exit');
|
|
199
|
+
const edges = [makeEdge('start', 'codergen'), makeEdge('codergen', 'exit')];
|
|
200
|
+
const graph = makeGraph([startNode, codergenNode, exitNode], edges, 'start', 'exit');
|
|
201
|
+
const executor = createGraphExecutor();
|
|
202
|
+
const outcome = await executor.run(graph, makeConfig(registry, { eventBus: bus }));
|
|
203
|
+
expect(outcome.status).toBe('SUCCESS');
|
|
204
|
+
// Handler dispatched for start and codergen (not exit — exit terminates loop)
|
|
205
|
+
expect(successHandler).toHaveBeenCalledTimes(2);
|
|
206
|
+
// graph:node-started emitted once per dispatched node (start, codergen)
|
|
207
|
+
const nodeStartedCalls = emit.mock.calls.filter(([event]) => event === 'graph:node-started');
|
|
208
|
+
expect(nodeStartedCalls).toHaveLength(2);
|
|
209
|
+
// graph:checkpoint-saved emitted once per completed node
|
|
210
|
+
const checkpointSavedCalls = emit.mock.calls.filter(([event]) => event === 'graph:checkpoint-saved');
|
|
211
|
+
expect(checkpointSavedCalls).toHaveLength(2);
|
|
212
|
+
// CheckpointManager.save called once per node
|
|
213
|
+
expect(mockSave).toHaveBeenCalledTimes(2);
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
// ---------------------------------------------------------------------------
|
|
217
|
+
// AC2: Handler exceptions converted to FAIL outcome
|
|
218
|
+
// ---------------------------------------------------------------------------
|
|
219
|
+
describe('AC2: handler exception converted to FAIL', () => {
|
|
220
|
+
it('catches thrown Error and returns { status: FAIL, failureReason }', async () => {
|
|
221
|
+
const throwingHandler = vi.fn().mockRejectedValue(new Error('boom'));
|
|
222
|
+
const registry = makeRegistry(throwingHandler);
|
|
223
|
+
const { bus, emit } = makeEventBus();
|
|
224
|
+
// Use a graph where the retry-node has no outgoing edges so the FAIL propagates
|
|
225
|
+
const retryNode = makeNode('start');
|
|
226
|
+
const exitNode = makeNode('exit');
|
|
227
|
+
// No edge from start → exit: forces FAIL from "No outgoing edge"
|
|
228
|
+
const graph = makeGraph([retryNode, exitNode], [], 'start', 'exit');
|
|
229
|
+
const executor = createGraphExecutor();
|
|
230
|
+
const outcome = await executor.run(graph, makeConfig(registry, { eventBus: bus }));
|
|
231
|
+
// Handler throws; exception is caught and converted to FAIL
|
|
232
|
+
expect(outcome.status).toBe('FAIL');
|
|
233
|
+
// failureReason should come from either the exception or the no-edge message
|
|
234
|
+
expect(typeof outcome.failureReason).toBe('string');
|
|
235
|
+
// graph:node-failed should be emitted for the exception case
|
|
236
|
+
const failedCalls = emit.mock.calls.filter(([event]) => event === 'graph:node-failed');
|
|
237
|
+
expect(failedCalls).toHaveLength(1);
|
|
238
|
+
expect(failedCalls[0][1]).toMatchObject({ nodeId: 'start', failureReason: 'boom' });
|
|
239
|
+
});
|
|
240
|
+
it('catches non-Error throws and converts to FAIL with string failureReason', async () => {
|
|
241
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
242
|
+
const throwingHandler = vi.fn().mockRejectedValue('string error');
|
|
243
|
+
const registry = makeRegistry(throwingHandler);
|
|
244
|
+
const { bus, emit } = makeEventBus();
|
|
245
|
+
const startNode = makeNode('start');
|
|
246
|
+
const exitNode = makeNode('exit');
|
|
247
|
+
// No edge from start → executor returns FAIL (no outgoing edge)
|
|
248
|
+
const graph = makeGraph([startNode, exitNode], [], 'start', 'exit');
|
|
249
|
+
const executor = createGraphExecutor();
|
|
250
|
+
const outcome = await executor.run(graph, makeConfig(registry, { eventBus: bus }));
|
|
251
|
+
// run() returns FAIL (no outgoing edge after the exception)
|
|
252
|
+
expect(outcome.status).toBe('FAIL');
|
|
253
|
+
// The node-failed event carries the original exception failureReason
|
|
254
|
+
const failedCalls = emit.mock.calls.filter(([e]) => e === 'graph:node-failed');
|
|
255
|
+
expect(failedCalls).toHaveLength(1);
|
|
256
|
+
expect(failedCalls[0][1]).toMatchObject({ failureReason: 'string error' });
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
// ---------------------------------------------------------------------------
|
|
260
|
+
// AC3: Retry with exponential backoff
|
|
261
|
+
// ---------------------------------------------------------------------------
|
|
262
|
+
describe('AC3: retry with exponential backoff', () => {
|
|
263
|
+
it('retries up to max_retries=2 times (3 total attempts) and emits node-retried twice', async () => {
|
|
264
|
+
vi.useFakeTimers();
|
|
265
|
+
const failHandler = vi.fn().mockResolvedValue({ status: 'FAIL' });
|
|
266
|
+
const registry = makeRegistry(failHandler);
|
|
267
|
+
const { bus, emit } = makeEventBus();
|
|
268
|
+
// Node with maxRetries=2 (3 total attempts): 1 initial + 2 retries
|
|
269
|
+
const retryNode = makeNode('retry-node', { maxRetries: 2 });
|
|
270
|
+
const exitNode = makeNode('exit');
|
|
271
|
+
// No outgoing edge from retry-node → final run() returns FAIL
|
|
272
|
+
const graph = makeGraph([retryNode, exitNode], [], 'retry-node', 'exit');
|
|
273
|
+
const executor = createGraphExecutor();
|
|
274
|
+
// Start the run — it will pause at each setTimeout
|
|
275
|
+
const runPromise = executor.run(graph, makeConfig(registry, { eventBus: bus }));
|
|
276
|
+
// Advance all fake timers to allow retries to complete
|
|
277
|
+
await vi.runAllTimersAsync();
|
|
278
|
+
const outcome = await runPromise;
|
|
279
|
+
// Handler called 3 times total (1 initial + 2 retries)
|
|
280
|
+
expect(failHandler).toHaveBeenCalledTimes(3);
|
|
281
|
+
// graph:node-retried emitted once per retry (before each retry attempt)
|
|
282
|
+
const retriedCalls = emit.mock.calls.filter(([event]) => event === 'graph:node-retried');
|
|
283
|
+
expect(retriedCalls).toHaveLength(2);
|
|
284
|
+
// First retry: attempt=1
|
|
285
|
+
expect(retriedCalls[0][1]).toMatchObject({
|
|
286
|
+
runId: 'test-run-id',
|
|
287
|
+
nodeId: 'retry-node',
|
|
288
|
+
attempt: 1,
|
|
289
|
+
maxAttempts: 3,
|
|
290
|
+
});
|
|
291
|
+
// Second retry: attempt=2
|
|
292
|
+
expect(retriedCalls[1][1]).toMatchObject({ attempt: 2, maxAttempts: 3 });
|
|
293
|
+
// Final outcome is FAIL (no outgoing edge from retry-node)
|
|
294
|
+
expect(outcome.status).toBe('FAIL');
|
|
295
|
+
vi.useRealTimers();
|
|
296
|
+
});
|
|
297
|
+
it('increments nodeRetries counter for each retry', async () => {
|
|
298
|
+
vi.useFakeTimers();
|
|
299
|
+
const failHandler = vi.fn().mockResolvedValue({ status: 'FAIL' });
|
|
300
|
+
const registry = makeRegistry(failHandler);
|
|
301
|
+
const retryNode = makeNode('my-node', { maxRetries: 1 });
|
|
302
|
+
const exitNode = makeNode('exit');
|
|
303
|
+
const graph = makeGraph([retryNode, exitNode], [], 'my-node', 'exit');
|
|
304
|
+
const executor = createGraphExecutor();
|
|
305
|
+
const runPromise = executor.run(graph, makeConfig(registry));
|
|
306
|
+
await vi.runAllTimersAsync();
|
|
307
|
+
await runPromise;
|
|
308
|
+
// save should have been called after the final failed attempt
|
|
309
|
+
expect(mockSave).toHaveBeenCalled();
|
|
310
|
+
const lastSaveCall = mockSave.mock.calls[mockSave.mock.calls.length - 1];
|
|
311
|
+
const saveParams = lastSaveCall[1];
|
|
312
|
+
// nodeRetries['my-node'] should be 1 (one retry was done)
|
|
313
|
+
expect(saveParams.nodeRetries['my-node']).toBe(1);
|
|
314
|
+
vi.useRealTimers();
|
|
315
|
+
});
|
|
316
|
+
it('does not retry when maxRetries=0 (default)', async () => {
|
|
317
|
+
const failHandler = vi.fn().mockResolvedValue({ status: 'FAIL' });
|
|
318
|
+
const registry = makeRegistry(failHandler);
|
|
319
|
+
const { bus, emit } = makeEventBus();
|
|
320
|
+
const startNode = makeNode('start'); // maxRetries: 0 (default)
|
|
321
|
+
const exitNode = makeNode('exit');
|
|
322
|
+
const graph = makeGraph([startNode, exitNode], [], 'start', 'exit');
|
|
323
|
+
const executor = createGraphExecutor();
|
|
324
|
+
await executor.run(graph, makeConfig(registry, { eventBus: bus }));
|
|
325
|
+
// Handler called exactly once (no retries)
|
|
326
|
+
expect(failHandler).toHaveBeenCalledTimes(1);
|
|
327
|
+
const retriedCalls = emit.mock.calls.filter(([event]) => event === 'graph:node-retried');
|
|
328
|
+
expect(retriedCalls).toHaveLength(0);
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
// ---------------------------------------------------------------------------
|
|
332
|
+
// AC4: Checkpoint save and resume
|
|
333
|
+
// ---------------------------------------------------------------------------
|
|
334
|
+
describe('AC4: checkpoint save', () => {
|
|
335
|
+
it('calls checkpointManager.save once per completed node with correct currentNode', async () => {
|
|
336
|
+
const successHandler = vi.fn().mockResolvedValue({ status: 'SUCCESS' });
|
|
337
|
+
const registry = makeRegistry(successHandler);
|
|
338
|
+
const startNode = makeNode('start');
|
|
339
|
+
const codergenNode = makeNode('codergen');
|
|
340
|
+
const exitNode = makeNode('exit');
|
|
341
|
+
const edges = [makeEdge('start', 'codergen'), makeEdge('codergen', 'exit')];
|
|
342
|
+
const graph = makeGraph([startNode, codergenNode, exitNode], edges, 'start', 'exit');
|
|
343
|
+
const executor = createGraphExecutor();
|
|
344
|
+
await executor.run(graph, makeConfig(registry));
|
|
345
|
+
// 2 saves: after start, after codergen (not after exit)
|
|
346
|
+
expect(mockSave).toHaveBeenCalledTimes(2);
|
|
347
|
+
const firstSave = mockSave.mock.calls[0][1];
|
|
348
|
+
expect(firstSave.currentNode).toBe('start');
|
|
349
|
+
expect(firstSave.completedNodes).toContain('start');
|
|
350
|
+
const secondSave = mockSave.mock.calls[1][1];
|
|
351
|
+
expect(secondSave.currentNode).toBe('codergen');
|
|
352
|
+
expect(secondSave.completedNodes).toContain('start');
|
|
353
|
+
expect(secondSave.completedNodes).toContain('codergen');
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
describe('AC4: checkpoint resume', () => {
|
|
357
|
+
it('skips completed nodes and dispatches from the resumed node', async () => {
|
|
358
|
+
const handlerSpy = vi.fn().mockResolvedValue({ status: 'SUCCESS' });
|
|
359
|
+
const registry = makeRegistry(handlerSpy);
|
|
360
|
+
// Graph: start → codergen → exit
|
|
361
|
+
const startNode = makeNode('start');
|
|
362
|
+
const codergenNode = makeNode('codergen');
|
|
363
|
+
const exitNode = makeNode('exit');
|
|
364
|
+
const edges = [makeEdge('start', 'codergen'), makeEdge('codergen', 'exit')];
|
|
365
|
+
const graph = makeGraph([startNode, codergenNode, exitNode], edges, 'start', 'exit');
|
|
366
|
+
// Checkpoint: start was already completed
|
|
367
|
+
mockLoad.mockResolvedValue({
|
|
368
|
+
timestamp: Date.now(),
|
|
369
|
+
currentNode: 'start',
|
|
370
|
+
completedNodes: ['start'],
|
|
371
|
+
nodeRetries: {},
|
|
372
|
+
contextValues: {},
|
|
373
|
+
logs: [],
|
|
374
|
+
});
|
|
375
|
+
// resume() returns a state with start in completedNodes
|
|
376
|
+
mockResume.mockReturnValue({
|
|
377
|
+
context: new GraphContext(),
|
|
378
|
+
completedNodes: new Set(['start']),
|
|
379
|
+
nodeRetries: {},
|
|
380
|
+
firstResumedNodeFidelity: '',
|
|
381
|
+
});
|
|
382
|
+
const executor = createGraphExecutor();
|
|
383
|
+
const outcome = await executor.run(graph, makeConfig(registry, { checkpointPath: '/tmp/checkpoint.json' }));
|
|
384
|
+
expect(outcome.status).toBe('SUCCESS');
|
|
385
|
+
// 'start' should NOT have been dispatched (it was already completed)
|
|
386
|
+
// Only 'codergen' should have been dispatched
|
|
387
|
+
expect(handlerSpy).toHaveBeenCalledTimes(1);
|
|
388
|
+
const dispatchedNode = handlerSpy.mock.calls[0][0];
|
|
389
|
+
expect(dispatchedNode.id).toBe('codergen');
|
|
390
|
+
});
|
|
391
|
+
it('re-dispatches currentNode if it was not in completedNodes', async () => {
|
|
392
|
+
const handlerSpy = vi.fn().mockResolvedValue({ status: 'SUCCESS' });
|
|
393
|
+
const registry = makeRegistry(handlerSpy);
|
|
394
|
+
const startNode = makeNode('start');
|
|
395
|
+
const codergenNode = makeNode('codergen');
|
|
396
|
+
const exitNode = makeNode('exit');
|
|
397
|
+
const edges = [makeEdge('start', 'codergen'), makeEdge('codergen', 'exit')];
|
|
398
|
+
const graph = makeGraph([startNode, codergenNode, exitNode], edges, 'start', 'exit');
|
|
399
|
+
// Checkpoint: start was NOT completed (process interrupted mid-start)
|
|
400
|
+
mockLoad.mockResolvedValue({
|
|
401
|
+
timestamp: Date.now(),
|
|
402
|
+
currentNode: 'start',
|
|
403
|
+
completedNodes: [], // start not in completedNodes
|
|
404
|
+
nodeRetries: {},
|
|
405
|
+
contextValues: {},
|
|
406
|
+
logs: [],
|
|
407
|
+
});
|
|
408
|
+
mockResume.mockReturnValue({
|
|
409
|
+
context: new GraphContext(),
|
|
410
|
+
completedNodes: new Set(), // empty set
|
|
411
|
+
nodeRetries: {},
|
|
412
|
+
firstResumedNodeFidelity: '',
|
|
413
|
+
});
|
|
414
|
+
const executor = createGraphExecutor();
|
|
415
|
+
const outcome = await executor.run(graph, makeConfig(registry, { checkpointPath: '/tmp/checkpoint.json' }));
|
|
416
|
+
expect(outcome.status).toBe('SUCCESS');
|
|
417
|
+
// start AND codergen should have been dispatched (start was re-dispatched)
|
|
418
|
+
expect(handlerSpy).toHaveBeenCalledTimes(2);
|
|
419
|
+
const firstDispatch = handlerSpy.mock.calls[0][0];
|
|
420
|
+
expect(firstDispatch.id).toBe('start');
|
|
421
|
+
});
|
|
422
|
+
});
|
|
423
|
+
// ---------------------------------------------------------------------------
|
|
424
|
+
// AC5: All 6 FactoryEvents emitted at the correct points
|
|
425
|
+
// ---------------------------------------------------------------------------
|
|
426
|
+
describe('AC5: all 6 FactoryEvents emitted correctly', () => {
|
|
427
|
+
it('emits all required events with correct runId and payloads', async () => {
|
|
428
|
+
const successHandler = vi.fn().mockResolvedValue({ status: 'SUCCESS' });
|
|
429
|
+
const registry = makeRegistry(successHandler);
|
|
430
|
+
const { bus, emit } = makeEventBus();
|
|
431
|
+
// 2-node graph: start → exit
|
|
432
|
+
const startNode = makeNode('start', { type: 'start' });
|
|
433
|
+
const exitNode = makeNode('exit', { type: 'exit' });
|
|
434
|
+
const edges = [makeEdge('start', 'exit', { label: 'proceed' })];
|
|
435
|
+
const graph = makeGraph([startNode, exitNode], edges, 'start', 'exit');
|
|
436
|
+
const config = makeConfig(registry, { eventBus: bus, runId: 'run-42' });
|
|
437
|
+
const executor = createGraphExecutor();
|
|
438
|
+
await executor.run(graph, config);
|
|
439
|
+
// --- graph:node-started ---
|
|
440
|
+
const nodeStarted = emit.mock.calls.filter(([e]) => e === 'graph:node-started');
|
|
441
|
+
expect(nodeStarted).toHaveLength(1);
|
|
442
|
+
expect(nodeStarted[0][1]).toEqual({ runId: 'run-42', nodeId: 'start', nodeType: 'start' });
|
|
443
|
+
// --- graph:node-completed ---
|
|
444
|
+
const nodeCompleted = emit.mock.calls.filter(([e]) => e === 'graph:node-completed');
|
|
445
|
+
expect(nodeCompleted).toHaveLength(1);
|
|
446
|
+
expect(nodeCompleted[0][1]).toMatchObject({ runId: 'run-42', nodeId: 'start' });
|
|
447
|
+
// --- graph:checkpoint-saved ---
|
|
448
|
+
const checkpointSaved = emit.mock.calls.filter(([e]) => e === 'graph:checkpoint-saved');
|
|
449
|
+
expect(checkpointSaved).toHaveLength(1);
|
|
450
|
+
expect(checkpointSaved[0][1]).toMatchObject({
|
|
451
|
+
runId: 'run-42',
|
|
452
|
+
nodeId: 'start',
|
|
453
|
+
checkpointPath: '/tmp/executor-test/checkpoint.json',
|
|
454
|
+
});
|
|
455
|
+
// --- graph:edge-selected ---
|
|
456
|
+
const edgeSelected = emit.mock.calls.filter(([e]) => e === 'graph:edge-selected');
|
|
457
|
+
expect(edgeSelected).toHaveLength(1);
|
|
458
|
+
expect(edgeSelected[0][1]).toMatchObject({
|
|
459
|
+
runId: 'run-42',
|
|
460
|
+
fromNode: 'start',
|
|
461
|
+
toNode: 'exit',
|
|
462
|
+
step: 0,
|
|
463
|
+
edgeLabel: 'proceed',
|
|
464
|
+
});
|
|
465
|
+
// --- graph:node-retried: not emitted (no retries) ---
|
|
466
|
+
const nodeRetried = emit.mock.calls.filter(([e]) => e === 'graph:node-retried');
|
|
467
|
+
expect(nodeRetried).toHaveLength(0);
|
|
468
|
+
// --- graph:node-failed: not emitted (success) ---
|
|
469
|
+
const nodeFailed = emit.mock.calls.filter(([e]) => e === 'graph:node-failed');
|
|
470
|
+
expect(nodeFailed).toHaveLength(0);
|
|
471
|
+
});
|
|
472
|
+
it('emits graph:node-failed for final FAIL after retries (not graph:node-completed)', async () => {
|
|
473
|
+
vi.useFakeTimers();
|
|
474
|
+
const failHandler = vi.fn().mockResolvedValue({ status: 'FAIL' });
|
|
475
|
+
const registry = makeRegistry(failHandler);
|
|
476
|
+
const { bus, emit } = makeEventBus();
|
|
477
|
+
const retryNode = makeNode('fail-node', { maxRetries: 1 });
|
|
478
|
+
const exitNode = makeNode('exit');
|
|
479
|
+
const graph = makeGraph([retryNode, exitNode], [], 'fail-node', 'exit');
|
|
480
|
+
const executor = createGraphExecutor();
|
|
481
|
+
const runPromise = executor.run(graph, makeConfig(registry, { eventBus: bus }));
|
|
482
|
+
await vi.runAllTimersAsync();
|
|
483
|
+
await runPromise;
|
|
484
|
+
const nodeFailed = emit.mock.calls.filter(([e]) => e === 'graph:node-failed');
|
|
485
|
+
expect(nodeFailed).toHaveLength(1);
|
|
486
|
+
expect(nodeFailed[0][1]).toMatchObject({
|
|
487
|
+
runId: 'test-run-id',
|
|
488
|
+
nodeId: 'fail-node',
|
|
489
|
+
});
|
|
490
|
+
// graph:node-completed must NOT be emitted when final outcome is FAIL
|
|
491
|
+
const nodeCompleted = emit.mock.calls.filter(([e]) => e === 'graph:node-completed');
|
|
492
|
+
expect(nodeCompleted).toHaveLength(0);
|
|
493
|
+
vi.useRealTimers();
|
|
494
|
+
});
|
|
495
|
+
it('does not include edgeLabel when edge label is empty', async () => {
|
|
496
|
+
const successHandler = vi.fn().mockResolvedValue({ status: 'SUCCESS' });
|
|
497
|
+
const registry = makeRegistry(successHandler);
|
|
498
|
+
const { bus, emit } = makeEventBus();
|
|
499
|
+
const startNode = makeNode('start');
|
|
500
|
+
const exitNode = makeNode('exit');
|
|
501
|
+
// Edge with empty label
|
|
502
|
+
const edges = [makeEdge('start', 'exit', { label: '' })];
|
|
503
|
+
const graph = makeGraph([startNode, exitNode], edges, 'start', 'exit');
|
|
504
|
+
const executor = createGraphExecutor();
|
|
505
|
+
await executor.run(graph, makeConfig(registry, { eventBus: bus }));
|
|
506
|
+
const edgeSelected = emit.mock.calls.filter(([e]) => e === 'graph:edge-selected');
|
|
507
|
+
expect(edgeSelected).toHaveLength(1);
|
|
508
|
+
// edgeLabel should not be present (not even as undefined due to exactOptionalPropertyTypes)
|
|
509
|
+
expect(edgeSelected[0][1]).not.toHaveProperty('edgeLabel');
|
|
510
|
+
});
|
|
511
|
+
});
|
|
512
|
+
// ---------------------------------------------------------------------------
|
|
513
|
+
// AC6: Per-node transition overhead under 100ms
|
|
514
|
+
// ---------------------------------------------------------------------------
|
|
515
|
+
describe('AC6: performance — per-node overhead < 100ms', () => {
|
|
516
|
+
it('20-node linear graph with instant handlers completes within 2000ms total', async () => {
|
|
517
|
+
// Build 20-node linear graph: node0 → node1 → ... → node19 → exit
|
|
518
|
+
const nodeCount = 20;
|
|
519
|
+
const nodes = [];
|
|
520
|
+
const edges = [];
|
|
521
|
+
for (let i = 0; i < nodeCount; i++) {
|
|
522
|
+
nodes.push(makeNode(`node${i}`));
|
|
523
|
+
if (i < nodeCount - 1) {
|
|
524
|
+
edges.push(makeEdge(`node${i}`, `node${i + 1}`));
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
const exitNode = makeNode('exit');
|
|
528
|
+
nodes.push(exitNode);
|
|
529
|
+
edges.push(makeEdge(`node${nodeCount - 1}`, 'exit'));
|
|
530
|
+
const graph = makeGraph(nodes, edges, 'node0', 'exit');
|
|
531
|
+
const instantHandler = vi.fn().mockResolvedValue({ status: 'SUCCESS' });
|
|
532
|
+
const registry = makeRegistry(instantHandler);
|
|
533
|
+
const executor = createGraphExecutor();
|
|
534
|
+
const startTime = Date.now();
|
|
535
|
+
const outcome = await executor.run(graph, makeConfig(registry));
|
|
536
|
+
const elapsed = Date.now() - startTime;
|
|
537
|
+
expect(outcome.status).toBe('SUCCESS');
|
|
538
|
+
// Per-node overhead = total time / 20 nodes (handlers return instantly, so elapsed ≈ overhead)
|
|
539
|
+
const avgPerNode = elapsed / nodeCount;
|
|
540
|
+
expect(avgPerNode).toBeLessThan(100);
|
|
541
|
+
});
|
|
542
|
+
});
|
|
543
|
+
// ---------------------------------------------------------------------------
|
|
544
|
+
// AC7 / Edge cases (Task 7)
|
|
545
|
+
// ---------------------------------------------------------------------------
|
|
546
|
+
describe('Edge case: cycle detection', () => {
|
|
547
|
+
it('throws when a node is visited more than nodes.size * 3 times', async () => {
|
|
548
|
+
const successHandler = vi.fn().mockResolvedValue({ status: 'SUCCESS' });
|
|
549
|
+
const registry = makeRegistry(successHandler);
|
|
550
|
+
// 2-node graph that forms an infinite loop: start → back → start → ...
|
|
551
|
+
// (loopRestart: false so cycle detection triggers)
|
|
552
|
+
const startNode = makeNode('start');
|
|
553
|
+
const backNode = makeNode('back');
|
|
554
|
+
const exitNode = makeNode('exit');
|
|
555
|
+
const edges = [
|
|
556
|
+
makeEdge('start', 'back'),
|
|
557
|
+
makeEdge('back', 'start'), // forms cycle WITHOUT loopRestart
|
|
558
|
+
];
|
|
559
|
+
const graph = makeGraph([startNode, backNode, exitNode], edges, 'start', 'exit');
|
|
560
|
+
const executor = createGraphExecutor();
|
|
561
|
+
await expect(executor.run(graph, makeConfig(registry))).rejects.toThrow('Graph cycle detected');
|
|
562
|
+
});
|
|
563
|
+
});
|
|
564
|
+
describe('Edge case: missing target node', () => {
|
|
565
|
+
it('throws descriptive error when edge target node is not in graph', async () => {
|
|
566
|
+
const successHandler = vi.fn().mockResolvedValue({ status: 'SUCCESS' });
|
|
567
|
+
const registry = makeRegistry(successHandler);
|
|
568
|
+
// Edge points to a non-existent node
|
|
569
|
+
const startNode = makeNode('start');
|
|
570
|
+
const exitNode = makeNode('exit');
|
|
571
|
+
const edges = [makeEdge('start', 'nonexistent-node')];
|
|
572
|
+
const graph = makeGraph([startNode, exitNode], edges, 'start', 'exit');
|
|
573
|
+
const executor = createGraphExecutor();
|
|
574
|
+
await expect(executor.run(graph, makeConfig(registry))).rejects.toThrow('Edge target node "nonexistent-node" not found in graph');
|
|
575
|
+
});
|
|
576
|
+
});
|
|
577
|
+
describe('Edge case: no outgoing edges returns FAIL', () => {
|
|
578
|
+
it('returns FAIL with descriptive failureReason when edge selection returns null', async () => {
|
|
579
|
+
const successHandler = vi.fn().mockResolvedValue({ status: 'SUCCESS' });
|
|
580
|
+
const registry = makeRegistry(successHandler);
|
|
581
|
+
const startNode = makeNode('start');
|
|
582
|
+
const exitNode = makeNode('exit');
|
|
583
|
+
// No edges from start
|
|
584
|
+
const graph = makeGraph([startNode, exitNode], [], 'start', 'exit');
|
|
585
|
+
const executor = createGraphExecutor();
|
|
586
|
+
const outcome = await executor.run(graph, makeConfig(registry));
|
|
587
|
+
expect(outcome.status).toBe('FAIL');
|
|
588
|
+
expect(outcome.failureReason).toContain('No outgoing edge from node start');
|
|
589
|
+
});
|
|
590
|
+
});
|
|
591
|
+
describe('Edge case: omitted eventBus is safe (no-op)', () => {
|
|
592
|
+
it('runs without errors when eventBus is undefined', async () => {
|
|
593
|
+
const successHandler = vi.fn().mockResolvedValue({ status: 'SUCCESS' });
|
|
594
|
+
const registry = makeRegistry(successHandler);
|
|
595
|
+
const startNode = makeNode('start');
|
|
596
|
+
const exitNode = makeNode('exit');
|
|
597
|
+
const edges = [makeEdge('start', 'exit')];
|
|
598
|
+
const graph = makeGraph([startNode, exitNode], edges, 'start', 'exit');
|
|
599
|
+
// No eventBus in config
|
|
600
|
+
const config = makeConfig(registry); // eventBus is undefined
|
|
601
|
+
const executor = createGraphExecutor();
|
|
602
|
+
const outcome = await executor.run(graph, config);
|
|
603
|
+
expect(outcome.status).toBe('SUCCESS');
|
|
604
|
+
});
|
|
605
|
+
});
|
|
606
|
+
describe('Context updates: applied after each node', () => {
|
|
607
|
+
it('applies outcome.contextUpdates to context and makes them available for edge selection', async () => {
|
|
608
|
+
// First node sets context, second reads it (via condition on edge)
|
|
609
|
+
let callCount = 0;
|
|
610
|
+
const handler = vi.fn().mockImplementation(async () => {
|
|
611
|
+
callCount++;
|
|
612
|
+
if (callCount === 1) {
|
|
613
|
+
return { status: 'SUCCESS', contextUpdates: { myKey: 'myValue' } };
|
|
614
|
+
}
|
|
615
|
+
return { status: 'SUCCESS' };
|
|
616
|
+
});
|
|
617
|
+
const registry = makeRegistry(handler);
|
|
618
|
+
const startNode = makeNode('start');
|
|
619
|
+
const midNode = makeNode('mid');
|
|
620
|
+
const exitNode = makeNode('exit');
|
|
621
|
+
const edges = [makeEdge('start', 'mid'), makeEdge('mid', 'exit')];
|
|
622
|
+
const graph = makeGraph([startNode, midNode, exitNode], edges, 'start', 'exit');
|
|
623
|
+
const executor = createGraphExecutor();
|
|
624
|
+
const outcome = await executor.run(graph, makeConfig(registry));
|
|
625
|
+
expect(outcome.status).toBe('SUCCESS');
|
|
626
|
+
expect(callCount).toBe(2);
|
|
627
|
+
});
|
|
628
|
+
});
|
|
629
|
+
// ---------------------------------------------------------------------------
|
|
630
|
+
// allowPartial semantics (story 42-16, AC2/AC3)
|
|
631
|
+
// ---------------------------------------------------------------------------
|
|
632
|
+
// ---------------------------------------------------------------------------
|
|
633
|
+
// AC6: RunStateManager integration — graph.dot and per-node artifacts
|
|
634
|
+
// ---------------------------------------------------------------------------
|
|
635
|
+
describe('AC6: RunStateManager integration — dotSource writes graph.dot and node artifacts', () => {
|
|
636
|
+
let tmpDir;
|
|
637
|
+
beforeEach(async () => {
|
|
638
|
+
tmpDir = await mkdtemp(path.join(os.tmpdir(), 'executor-ac6-test-'));
|
|
639
|
+
});
|
|
640
|
+
afterEach(async () => {
|
|
641
|
+
await rm(tmpDir, { recursive: true, force: true });
|
|
642
|
+
});
|
|
643
|
+
it('writes graph.dot with dotSource content and per-node status.json for each dispatched node', async () => {
|
|
644
|
+
const dotSource = 'digraph G { start -> exit }';
|
|
645
|
+
const successHandler = vi.fn().mockResolvedValue({ status: 'SUCCESS' });
|
|
646
|
+
const registry = makeRegistry(successHandler);
|
|
647
|
+
const startNode = makeNode('start');
|
|
648
|
+
const exitNode = makeNode('exit');
|
|
649
|
+
const edges = [makeEdge('start', 'exit')];
|
|
650
|
+
const graph = makeGraph([startNode, exitNode], edges, 'start', 'exit');
|
|
651
|
+
const executor = createGraphExecutor();
|
|
652
|
+
const outcome = await executor.run(graph, makeConfig(registry, { logsRoot: tmpDir, dotSource }));
|
|
653
|
+
expect(outcome.status).toBe('SUCCESS');
|
|
654
|
+
// AC6 behavior 1: RunStateManager instantiated with logsRoot and initRun called
|
|
655
|
+
// before main loop → graph.dot written with dotSource content
|
|
656
|
+
const graphDotContent = await readFile(path.join(tmpDir, 'graph.dot'), 'utf8');
|
|
657
|
+
expect(graphDotContent).toBe(dotSource);
|
|
658
|
+
// AC6 behavior 2: writeNodeArtifacts called per completed node → status.json written
|
|
659
|
+
// Only 'start' is dispatched (exit terminates the loop without dispatch)
|
|
660
|
+
const statusJsonRaw = await readFile(path.join(tmpDir, 'start', 'status.json'), 'utf8');
|
|
661
|
+
const statusJson = JSON.parse(statusJsonRaw);
|
|
662
|
+
expect(statusJson).toMatchObject({
|
|
663
|
+
nodeId: 'start',
|
|
664
|
+
status: 'SUCCESS',
|
|
665
|
+
});
|
|
666
|
+
expect(typeof statusJson['startedAt']).toBe('number');
|
|
667
|
+
expect(typeof statusJson['completedAt']).toBe('number');
|
|
668
|
+
expect(typeof statusJson['durationMs']).toBe('number');
|
|
669
|
+
});
|
|
670
|
+
it('does not write graph.dot when dotSource is omitted (backward-compatible)', async () => {
|
|
671
|
+
const successHandler = vi.fn().mockResolvedValue({ status: 'SUCCESS' });
|
|
672
|
+
const registry = makeRegistry(successHandler);
|
|
673
|
+
const startNode = makeNode('start');
|
|
674
|
+
const exitNode = makeNode('exit');
|
|
675
|
+
const edges = [makeEdge('start', 'exit')];
|
|
676
|
+
const graph = makeGraph([startNode, exitNode], edges, 'start', 'exit');
|
|
677
|
+
// No dotSource — RunStateManager should not be instantiated
|
|
678
|
+
const executor = createGraphExecutor();
|
|
679
|
+
const outcome = await executor.run(graph, makeConfig(registry, { logsRoot: tmpDir }));
|
|
680
|
+
expect(outcome.status).toBe('SUCCESS');
|
|
681
|
+
// graph.dot must NOT exist (RunStateManager was never created)
|
|
682
|
+
await expect(readFile(path.join(tmpDir, 'graph.dot'), 'utf8')).rejects.toThrow();
|
|
683
|
+
});
|
|
684
|
+
});
|
|
685
|
+
describe('allowPartial semantics', () => {
|
|
686
|
+
it('node with allowPartial=false, handler returns PARTIAL_SUCCESS → executor treats final node outcome as FAILURE (run returns FAIL)', async () => {
|
|
687
|
+
// maxRetries=1 exposes a regression where demotion only fires when attempt >= maxRetries:
|
|
688
|
+
// PARTIAL_SUCCESS exits the retry loop immediately (it is not a FAIL, so no retries),
|
|
689
|
+
// so the handler is called once at attempt=0 (which is < maxRetries=1). A buggy
|
|
690
|
+
// implementation conditioned on attempt >= maxRetries would NOT demote and this test
|
|
691
|
+
// would fail (outcome would be PARTIAL_SUCCESS, not FAIL).
|
|
692
|
+
const workNode = makeNode('work', { allowPartial: false, maxRetries: 1 });
|
|
693
|
+
const exitNode = makeNode('exit');
|
|
694
|
+
// Include an edge work → exit, but FAIL routing will short-circuit before edge selection.
|
|
695
|
+
const edges = [makeEdge('work', 'exit')];
|
|
696
|
+
const graph = makeGraph([workNode, exitNode], edges, 'work', 'exit');
|
|
697
|
+
const partialHandler = vi.fn().mockResolvedValue({ status: 'PARTIAL_SUCCESS' });
|
|
698
|
+
const registry = makeRegistry(partialHandler);
|
|
699
|
+
const executor = createGraphExecutor();
|
|
700
|
+
const outcome = await executor.run(graph, makeConfig(registry));
|
|
701
|
+
// PARTIAL_SUCCESS exits the loop on the first call (no retries triggered for PARTIAL_SUCCESS).
|
|
702
|
+
expect(partialHandler).toHaveBeenCalledTimes(1);
|
|
703
|
+
// PARTIAL_SUCCESS is demoted to FAIL because allowPartial=false.
|
|
704
|
+
expect(outcome.status).toBe('FAIL');
|
|
705
|
+
expect(outcome.failureReason).toContain('allowPartial=false');
|
|
706
|
+
});
|
|
707
|
+
it('node with allowPartial=true, handler returns PARTIAL_SUCCESS → executor accepts PARTIAL_SUCCESS and continues to exit', async () => {
|
|
708
|
+
const workNode = makeNode('work', { allowPartial: true });
|
|
709
|
+
const exitNode = makeNode('exit');
|
|
710
|
+
const edges = [makeEdge('work', 'exit')];
|
|
711
|
+
const graph = makeGraph([workNode, exitNode], edges, 'work', 'exit');
|
|
712
|
+
const partialHandler = vi.fn().mockResolvedValue({ status: 'PARTIAL_SUCCESS' });
|
|
713
|
+
const registry = makeRegistry(partialHandler);
|
|
714
|
+
const executor = createGraphExecutor();
|
|
715
|
+
const outcome = await executor.run(graph, makeConfig(registry));
|
|
716
|
+
// PARTIAL_SUCCESS is accepted (allowPartial=true); execution continues to exit → SUCCESS.
|
|
717
|
+
expect(outcome.status).toBe('SUCCESS');
|
|
718
|
+
// Verify PARTIAL_SUCCESS travels to ConvergenceController unchanged (not promoted to SUCCESS),
|
|
719
|
+
// directly validating AC3: "not promoted to SUCCESS… goal gates receive the PARTIAL_SUCCESS
|
|
720
|
+
// status unchanged".
|
|
721
|
+
expect(mockRecordOutcome).toHaveBeenCalledWith('work', 'PARTIAL_SUCCESS');
|
|
722
|
+
});
|
|
723
|
+
it('node with allowPartial=false, handler returns SUCCESS → normal success, unaffected by allowPartial flag', async () => {
|
|
724
|
+
const workNode = makeNode('work', { allowPartial: false });
|
|
725
|
+
const exitNode = makeNode('exit');
|
|
726
|
+
const edges = [makeEdge('work', 'exit')];
|
|
727
|
+
const graph = makeGraph([workNode, exitNode], edges, 'work', 'exit');
|
|
728
|
+
const successHandler = vi.fn().mockResolvedValue({ status: 'SUCCESS' });
|
|
729
|
+
const registry = makeRegistry(successHandler);
|
|
730
|
+
const executor = createGraphExecutor();
|
|
731
|
+
const outcome = await executor.run(graph, makeConfig(registry));
|
|
732
|
+
// SUCCESS is never demoted regardless of allowPartial.
|
|
733
|
+
expect(outcome.status).toBe('SUCCESS');
|
|
734
|
+
});
|
|
735
|
+
});
|
|
736
|
+
// ---------------------------------------------------------------------------
|
|
737
|
+
// outcome context injection: executor sets 'outcome' key in context
|
|
738
|
+
// ---------------------------------------------------------------------------
|
|
739
|
+
describe('outcome context injection', () => {
|
|
740
|
+
it('sets outcome=success in context after SUCCESS handler, enabling condition="outcome=success" edges', async () => {
|
|
741
|
+
// Graph: start → conditional_node → exit (condition="outcome=success")
|
|
742
|
+
const startNode = makeNode('start');
|
|
743
|
+
const conditionalNode = makeNode('conditional');
|
|
744
|
+
const exitNode = makeNode('exit');
|
|
745
|
+
const edges = [
|
|
746
|
+
makeEdge('start', 'conditional'),
|
|
747
|
+
makeEdge('conditional', 'exit', { condition: 'outcome=success' }),
|
|
748
|
+
];
|
|
749
|
+
const graph = makeGraph([startNode, conditionalNode, exitNode], edges, 'start', 'exit');
|
|
750
|
+
const successHandler = vi.fn().mockResolvedValue({ status: 'SUCCESS' });
|
|
751
|
+
const registry = makeRegistry(successHandler);
|
|
752
|
+
const executor = createGraphExecutor();
|
|
753
|
+
const outcome = await executor.run(graph, makeConfig(registry));
|
|
754
|
+
// Edge condition "outcome=success" matches because executor sets context.outcome = "success"
|
|
755
|
+
expect(outcome.status).toBe('SUCCESS');
|
|
756
|
+
});
|
|
757
|
+
it('sets outcome=fail in context after FAIL handler, enabling condition="outcome=fail" edges', async () => {
|
|
758
|
+
// Graph: start → conditional_node → retry_node (condition="outcome=fail") → exit
|
|
759
|
+
const startNode = makeNode('start');
|
|
760
|
+
const conditionalNode = makeNode('conditional');
|
|
761
|
+
const retryNode = makeNode('retry');
|
|
762
|
+
const exitNode = makeNode('exit');
|
|
763
|
+
const edges = [
|
|
764
|
+
makeEdge('start', 'conditional'),
|
|
765
|
+
makeEdge('conditional', 'retry', { condition: 'outcome=fail' }),
|
|
766
|
+
makeEdge('conditional', 'exit', { condition: 'outcome=success' }),
|
|
767
|
+
makeEdge('retry', 'exit'),
|
|
768
|
+
];
|
|
769
|
+
const graph = makeGraph([startNode, conditionalNode, retryNode, exitNode], edges, 'start', 'exit');
|
|
770
|
+
let callCount = 0;
|
|
771
|
+
const handler = vi.fn().mockImplementation(async () => {
|
|
772
|
+
callCount++;
|
|
773
|
+
// First call (start): SUCCESS. Second call (conditional): FAIL. Third (retry): SUCCESS.
|
|
774
|
+
if (callCount === 2)
|
|
775
|
+
return { status: 'FAILURE' };
|
|
776
|
+
return { status: 'SUCCESS' };
|
|
777
|
+
});
|
|
778
|
+
const registry = makeRegistry(handler);
|
|
779
|
+
const executor = createGraphExecutor();
|
|
780
|
+
const outcome = await executor.run(graph, makeConfig(registry));
|
|
781
|
+
// conditional returned FAIL → outcome=fail edge routes to retry → retry SUCCESS → exit
|
|
782
|
+
expect(outcome.status).toBe('SUCCESS');
|
|
783
|
+
expect(handler).toHaveBeenCalledTimes(3); // start, conditional, retry
|
|
784
|
+
});
|
|
785
|
+
});
|
|
786
|
+
// ---------------------------------------------------------------------------
|
|
787
|
+
// FAIL routing: conditional edge fallthrough
|
|
788
|
+
// ---------------------------------------------------------------------------
|
|
789
|
+
describe('FAIL routing conditional edge fallthrough', () => {
|
|
790
|
+
it('returns FAIL immediately when node has no conditional outgoing edges', async () => {
|
|
791
|
+
const startNode = makeNode('start');
|
|
792
|
+
const exitNode = makeNode('exit');
|
|
793
|
+
const edges = [makeEdge('start', 'exit')];
|
|
794
|
+
const graph = makeGraph([startNode, exitNode], edges, 'start', 'exit');
|
|
795
|
+
const failHandler = vi.fn().mockResolvedValue({ status: 'FAILURE', failureReason: 'test fail' });
|
|
796
|
+
const registry = makeRegistry(failHandler);
|
|
797
|
+
const executor = createGraphExecutor();
|
|
798
|
+
const outcome = await executor.run(graph, makeConfig(registry));
|
|
799
|
+
expect(outcome.status).toBe('FAIL');
|
|
800
|
+
});
|
|
801
|
+
it('falls through to edge selection when node has conditional edges', async () => {
|
|
802
|
+
// Graph: start → conditional (FAIL) → fallback (condition=outcome=fail) → exit
|
|
803
|
+
const startNode = makeNode('start');
|
|
804
|
+
const conditionalNode = makeNode('conditional');
|
|
805
|
+
const fallbackNode = makeNode('fallback');
|
|
806
|
+
const exitNode = makeNode('exit');
|
|
807
|
+
const edges = [
|
|
808
|
+
makeEdge('start', 'conditional'),
|
|
809
|
+
makeEdge('conditional', 'fallback', { condition: 'outcome=fail' }),
|
|
810
|
+
makeEdge('conditional', 'exit', { condition: 'outcome=success' }),
|
|
811
|
+
makeEdge('fallback', 'exit'),
|
|
812
|
+
];
|
|
813
|
+
const graph = makeGraph([startNode, conditionalNode, fallbackNode, exitNode], edges, 'start', 'exit');
|
|
814
|
+
let callCount = 0;
|
|
815
|
+
const handler = vi.fn().mockImplementation(async () => {
|
|
816
|
+
callCount++;
|
|
817
|
+
if (callCount === 2)
|
|
818
|
+
return { status: 'FAILURE', failureReason: 'needs fixes' };
|
|
819
|
+
return { status: 'SUCCESS' };
|
|
820
|
+
});
|
|
821
|
+
const registry = makeRegistry(handler);
|
|
822
|
+
const executor = createGraphExecutor();
|
|
823
|
+
const outcome = await executor.run(graph, makeConfig(registry));
|
|
824
|
+
// conditional FAIL → falls through to edge selection → outcome=fail → fallback → exit
|
|
825
|
+
expect(outcome.status).toBe('SUCCESS');
|
|
826
|
+
});
|
|
827
|
+
it('failRouteCount caps at defaultMaxRetries and returns FAIL', async () => {
|
|
828
|
+
// Graph with a loop: start → conditional (always FAIL) → conditional (condition=outcome=fail)
|
|
829
|
+
const startNode = makeNode('start');
|
|
830
|
+
const conditionalNode = makeNode('conditional');
|
|
831
|
+
const exitNode = makeNode('exit');
|
|
832
|
+
const edges = [
|
|
833
|
+
makeEdge('start', 'conditional'),
|
|
834
|
+
makeEdge('conditional', 'conditional', { condition: 'outcome=fail' }),
|
|
835
|
+
makeEdge('conditional', 'exit', { condition: 'outcome=success' }),
|
|
836
|
+
];
|
|
837
|
+
// defaultMaxRetries=2 → failRouteCount cap = max(2, 3) = 3
|
|
838
|
+
const graph = makeGraph([startNode, conditionalNode, exitNode], edges, 'start', 'exit');
|
|
839
|
+
graph.defaultMaxRetries = 2;
|
|
840
|
+
let callCount = 0;
|
|
841
|
+
const handler = vi.fn().mockImplementation(async () => {
|
|
842
|
+
callCount++;
|
|
843
|
+
// start (call 1) → SUCCESS, conditional (all subsequent) → FAILURE
|
|
844
|
+
if (callCount === 1)
|
|
845
|
+
return { status: 'SUCCESS' };
|
|
846
|
+
return { status: 'FAILURE', failureReason: 'always fails' };
|
|
847
|
+
});
|
|
848
|
+
const registry = makeRegistry(handler);
|
|
849
|
+
const executor = createGraphExecutor();
|
|
850
|
+
const outcome = await executor.run(graph, makeConfig(registry));
|
|
851
|
+
// Should return FAIL after exhausting fail route count (cap = max(2, 3) = 3)
|
|
852
|
+
expect(outcome.status).toBe('FAIL');
|
|
853
|
+
// start(1) + conditional initial(1) + 3 conditional retries via edge = 5
|
|
854
|
+
expect(handler).toHaveBeenCalledTimes(5);
|
|
855
|
+
});
|
|
856
|
+
});
|
|
857
|
+
// ---------------------------------------------------------------------------
|
|
858
|
+
// Story 49-3: Auto-summarizer convergence integration
|
|
859
|
+
// ---------------------------------------------------------------------------
|
|
860
|
+
describe('auto-summarizer convergence integration (story 49-3)', () => {
|
|
861
|
+
beforeEach(() => {
|
|
862
|
+
vi.clearAllMocks();
|
|
863
|
+
mockSave.mockResolvedValue(undefined);
|
|
864
|
+
mockEvaluateGates.mockReturnValue({ satisfied: true, failingNodes: [] });
|
|
865
|
+
mockCheckGoalGates.mockReturnValue({ satisfied: true, failedGates: [] });
|
|
866
|
+
mockResolveRetryTarget.mockReturnValue(null);
|
|
867
|
+
});
|
|
868
|
+
it('recordIterationContext is called after each handler dispatch', async () => {
|
|
869
|
+
const handler = vi.fn().mockResolvedValue({ status: 'SUCCESS' });
|
|
870
|
+
const registry = makeRegistry(handler);
|
|
871
|
+
const graph = makeGraph([makeNode('start'), makeNode('mid'), makeNode('end')], [makeEdge('start', 'mid'), makeEdge('mid', 'end')], 'start', 'end');
|
|
872
|
+
const executor = createGraphExecutor();
|
|
873
|
+
const outcome = await executor.run(graph, makeConfig(registry));
|
|
874
|
+
expect(outcome.status).toBe('SUCCESS');
|
|
875
|
+
// recordIterationContext is called after each dispatched handler.
|
|
876
|
+
// The exit node completes the loop, so the count depends on how many
|
|
877
|
+
// non-exit nodes get dispatched (start, mid dispatched; end exits).
|
|
878
|
+
expect(mockRecordIterationContext).toHaveBeenCalled();
|
|
879
|
+
// Each call should include an index and content string
|
|
880
|
+
expect(mockRecordIterationContext).toHaveBeenCalledWith(expect.objectContaining({ index: expect.any(Number), content: expect.any(String) }));
|
|
881
|
+
});
|
|
882
|
+
it('prepareForIteration is called before retry dispatch in convergence loop', async () => {
|
|
883
|
+
// First call: goal gate unsatisfied → trigger convergence retry
|
|
884
|
+
// Second call: goal gate satisfied → exit successfully
|
|
885
|
+
mockCheckGoalGates
|
|
886
|
+
.mockReturnValueOnce({ satisfied: false, failedGates: ['end'] })
|
|
887
|
+
.mockReturnValueOnce({ satisfied: true, failedGates: [] });
|
|
888
|
+
mockResolveRetryTarget.mockReturnValue('start');
|
|
889
|
+
const handler = vi.fn().mockResolvedValue({ status: 'SUCCESS' });
|
|
890
|
+
const registry = makeRegistry(handler);
|
|
891
|
+
const graph = makeGraph([makeNode('start'), makeNode('end', { goalGate: true })], [makeEdge('start', 'end')], 'start', 'end');
|
|
892
|
+
const executor = createGraphExecutor();
|
|
893
|
+
const outcome = await executor.run(graph, makeConfig(registry));
|
|
894
|
+
expect(outcome.status).toBe('SUCCESS');
|
|
895
|
+
// prepareForIteration should be called at least once (before the retry)
|
|
896
|
+
expect(mockPrepareForIteration).toHaveBeenCalled();
|
|
897
|
+
// The convergence iteration index should be passed
|
|
898
|
+
expect(mockPrepareForIteration).toHaveBeenCalledWith(expect.any(Number));
|
|
899
|
+
});
|
|
900
|
+
});
|
|
901
|
+
//# sourceMappingURL=executor.test.js.map
|