@soleri/core 2.12.0 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/flows/build.flow.yaml +128 -0
- package/data/flows/deliver.flow.yaml +110 -0
- package/data/flows/design.flow.yaml +108 -0
- package/data/flows/enhance.flow.yaml +90 -0
- package/data/flows/explore.flow.yaml +84 -0
- package/data/flows/fix.flow.yaml +90 -0
- package/data/flows/plan.flow.yaml +87 -0
- package/data/flows/review.flow.yaml +90 -0
- package/dist/agency/agency-manager.d.ts +27 -1
- package/dist/agency/agency-manager.d.ts.map +1 -1
- package/dist/agency/agency-manager.js +180 -9
- package/dist/agency/agency-manager.js.map +1 -1
- package/dist/agency/default-rules.d.ts +7 -0
- package/dist/agency/default-rules.d.ts.map +1 -0
- package/dist/agency/default-rules.js +79 -0
- package/dist/agency/default-rules.js.map +1 -0
- package/dist/agency/types.d.ts +48 -0
- package/dist/agency/types.d.ts.map +1 -1
- package/dist/brain/brain.d.ts +17 -2
- package/dist/brain/brain.d.ts.map +1 -1
- package/dist/brain/brain.js +118 -8
- package/dist/brain/brain.js.map +1 -1
- package/dist/brain/intelligence.d.ts.map +1 -1
- package/dist/brain/intelligence.js +16 -2
- package/dist/brain/intelligence.js.map +1 -1
- package/dist/brain/knowledge-synthesizer.d.ts +37 -0
- package/dist/brain/knowledge-synthesizer.d.ts.map +1 -0
- package/dist/brain/knowledge-synthesizer.js +161 -0
- package/dist/brain/knowledge-synthesizer.js.map +1 -0
- package/dist/brain/learning-radar.d.ts +96 -0
- package/dist/brain/learning-radar.d.ts.map +1 -0
- package/dist/brain/learning-radar.js +202 -0
- package/dist/brain/learning-radar.js.map +1 -0
- package/dist/brain/types.d.ts +15 -0
- package/dist/brain/types.d.ts.map +1 -1
- package/dist/capabilities/chain-mapping.d.ts +21 -0
- package/dist/capabilities/chain-mapping.d.ts.map +1 -0
- package/dist/capabilities/chain-mapping.js +86 -0
- package/dist/capabilities/chain-mapping.js.map +1 -0
- package/dist/capabilities/index.d.ts +10 -0
- package/dist/capabilities/index.d.ts.map +1 -0
- package/dist/capabilities/index.js +8 -0
- package/dist/capabilities/index.js.map +1 -0
- package/dist/capabilities/registry.d.ts +95 -0
- package/dist/capabilities/registry.d.ts.map +1 -0
- package/dist/capabilities/registry.js +227 -0
- package/dist/capabilities/registry.js.map +1 -0
- package/dist/capabilities/types.d.ts +106 -0
- package/dist/capabilities/types.d.ts.map +1 -0
- package/dist/capabilities/types.js +12 -0
- package/dist/capabilities/types.js.map +1 -0
- package/dist/context/context-engine.d.ts.map +1 -1
- package/dist/context/context-engine.js +82 -17
- package/dist/context/context-engine.js.map +1 -1
- package/dist/context/types.d.ts +5 -0
- package/dist/context/types.d.ts.map +1 -1
- package/dist/control/intent-router.d.ts +12 -1
- package/dist/control/intent-router.d.ts.map +1 -1
- package/dist/control/intent-router.js +126 -2
- package/dist/control/intent-router.js.map +1 -1
- package/dist/control/types.d.ts +17 -0
- package/dist/control/types.d.ts.map +1 -1
- package/dist/curator/classifier.d.ts +18 -0
- package/dist/curator/classifier.d.ts.map +1 -0
- package/dist/curator/classifier.js +61 -0
- package/dist/curator/classifier.js.map +1 -0
- package/dist/curator/quality-gate.d.ts +29 -0
- package/dist/curator/quality-gate.d.ts.map +1 -0
- package/dist/curator/quality-gate.js +88 -0
- package/dist/curator/quality-gate.js.map +1 -0
- package/dist/domain-packs/index.d.ts +8 -0
- package/dist/domain-packs/index.d.ts.map +1 -0
- package/dist/domain-packs/index.js +8 -0
- package/dist/domain-packs/index.js.map +1 -0
- package/dist/domain-packs/inject-rules.d.ts +24 -0
- package/dist/domain-packs/inject-rules.d.ts.map +1 -0
- package/dist/domain-packs/inject-rules.js +65 -0
- package/dist/domain-packs/inject-rules.js.map +1 -0
- package/dist/domain-packs/knowledge-installer.d.ts +27 -0
- package/dist/domain-packs/knowledge-installer.d.ts.map +1 -0
- package/dist/domain-packs/knowledge-installer.js +89 -0
- package/dist/domain-packs/knowledge-installer.js.map +1 -0
- package/dist/domain-packs/loader.d.ts +28 -0
- package/dist/domain-packs/loader.d.ts.map +1 -0
- package/dist/domain-packs/loader.js +105 -0
- package/dist/domain-packs/loader.js.map +1 -0
- package/dist/domain-packs/pack-runtime.d.ts +80 -0
- package/dist/domain-packs/pack-runtime.d.ts.map +1 -0
- package/dist/domain-packs/pack-runtime.js +36 -0
- package/dist/domain-packs/pack-runtime.js.map +1 -0
- package/dist/domain-packs/skills-installer.d.ts +21 -0
- package/dist/domain-packs/skills-installer.d.ts.map +1 -0
- package/dist/domain-packs/skills-installer.js +38 -0
- package/dist/domain-packs/skills-installer.js.map +1 -0
- package/dist/domain-packs/token-resolver.d.ts +37 -0
- package/dist/domain-packs/token-resolver.d.ts.map +1 -0
- package/dist/domain-packs/token-resolver.js +109 -0
- package/dist/domain-packs/token-resolver.js.map +1 -0
- package/dist/domain-packs/types.d.ts +91 -0
- package/dist/domain-packs/types.d.ts.map +1 -0
- package/dist/domain-packs/types.js +122 -0
- package/dist/domain-packs/types.js.map +1 -0
- package/dist/engine/bin/soleri-engine.d.ts +12 -0
- package/dist/engine/bin/soleri-engine.d.ts.map +1 -0
- package/dist/engine/bin/soleri-engine.js +184 -0
- package/dist/engine/bin/soleri-engine.js.map +1 -0
- package/dist/engine/core-ops.d.ts +27 -0
- package/dist/engine/core-ops.d.ts.map +1 -0
- package/dist/engine/core-ops.js +159 -0
- package/dist/engine/core-ops.js.map +1 -0
- package/dist/engine/index.d.ts +19 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +17 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/register-engine.d.ts +54 -0
- package/dist/engine/register-engine.d.ts.map +1 -0
- package/dist/engine/register-engine.js +270 -0
- package/dist/engine/register-engine.js.map +1 -0
- package/dist/engine/test-helpers.d.ts +30 -0
- package/dist/engine/test-helpers.d.ts.map +1 -0
- package/dist/engine/test-helpers.js +59 -0
- package/dist/engine/test-helpers.js.map +1 -0
- package/dist/events/event-bus.d.ts +30 -0
- package/dist/events/event-bus.d.ts.map +1 -0
- package/dist/events/event-bus.js +51 -0
- package/dist/events/event-bus.js.map +1 -0
- package/dist/flows/chain-runner.d.ts +46 -0
- package/dist/flows/chain-runner.d.ts.map +1 -0
- package/dist/flows/chain-runner.js +271 -0
- package/dist/flows/chain-runner.js.map +1 -0
- package/dist/flows/chain-types.d.ts +103 -0
- package/dist/flows/chain-types.d.ts.map +1 -0
- package/dist/flows/chain-types.js +23 -0
- package/dist/flows/chain-types.js.map +1 -0
- package/dist/flows/context-router.d.ts +39 -0
- package/dist/flows/context-router.d.ts.map +1 -0
- package/dist/flows/context-router.js +206 -0
- package/dist/flows/context-router.js.map +1 -0
- package/dist/flows/dispatch-registry.d.ts +24 -0
- package/dist/flows/dispatch-registry.d.ts.map +1 -0
- package/dist/flows/dispatch-registry.js +70 -0
- package/dist/flows/dispatch-registry.js.map +1 -0
- package/dist/flows/epilogue.d.ts +24 -0
- package/dist/flows/epilogue.d.ts.map +1 -0
- package/dist/flows/epilogue.js +52 -0
- package/dist/flows/epilogue.js.map +1 -0
- package/dist/flows/executor.d.ts +25 -0
- package/dist/flows/executor.d.ts.map +1 -0
- package/dist/flows/executor.js +153 -0
- package/dist/flows/executor.js.map +1 -0
- package/dist/flows/gate-evaluator.d.ts +26 -0
- package/dist/flows/gate-evaluator.d.ts.map +1 -0
- package/dist/flows/gate-evaluator.js +162 -0
- package/dist/flows/gate-evaluator.js.map +1 -0
- package/dist/flows/index.d.ts +14 -0
- package/dist/flows/index.d.ts.map +1 -0
- package/dist/flows/index.js +20 -0
- package/dist/flows/index.js.map +1 -0
- package/dist/flows/loader.d.ts +17 -0
- package/dist/flows/loader.d.ts.map +1 -0
- package/dist/flows/loader.js +61 -0
- package/dist/flows/loader.js.map +1 -0
- package/dist/flows/plan-builder.d.ts +40 -0
- package/dist/flows/plan-builder.d.ts.map +1 -0
- package/dist/flows/plan-builder.js +213 -0
- package/dist/flows/plan-builder.js.map +1 -0
- package/dist/flows/probes.d.ts +11 -0
- package/dist/flows/probes.d.ts.map +1 -0
- package/dist/flows/probes.js +62 -0
- package/dist/flows/probes.js.map +1 -0
- package/dist/flows/types.d.ts +950 -0
- package/dist/flows/types.d.ts.map +1 -0
- package/dist/flows/types.js +105 -0
- package/dist/flows/types.js.map +1 -0
- package/dist/health/doctor-checks.d.ts +15 -0
- package/dist/health/doctor-checks.d.ts.map +1 -0
- package/dist/health/doctor-checks.js +98 -0
- package/dist/health/doctor-checks.js.map +1 -0
- package/dist/index.d.ts +11 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/intake/text-ingester.d.ts +52 -0
- package/dist/intake/text-ingester.d.ts.map +1 -0
- package/dist/intake/text-ingester.js +181 -0
- package/dist/intake/text-ingester.js.map +1 -0
- package/dist/intelligence/loader.d.ts +19 -0
- package/dist/intelligence/loader.d.ts.map +1 -1
- package/dist/intelligence/loader.js +35 -0
- package/dist/intelligence/loader.js.map +1 -1
- package/dist/intelligence/types.d.ts +1 -0
- package/dist/intelligence/types.d.ts.map +1 -1
- package/dist/llm/llm-client.d.ts.map +1 -1
- package/dist/llm/llm-client.js +37 -1
- package/dist/llm/llm-client.js.map +1 -1
- package/dist/llm/oauth-discovery.d.ts +26 -0
- package/dist/llm/oauth-discovery.d.ts.map +1 -0
- package/dist/llm/oauth-discovery.js +149 -0
- package/dist/llm/oauth-discovery.js.map +1 -0
- package/dist/packs/types.d.ts +58 -19
- package/dist/packs/types.d.ts.map +1 -1
- package/dist/packs/types.js +14 -0
- package/dist/packs/types.js.map +1 -1
- package/dist/planning/evidence-collector.d.ts +41 -0
- package/dist/planning/evidence-collector.d.ts.map +1 -0
- package/dist/planning/evidence-collector.js +194 -0
- package/dist/planning/evidence-collector.js.map +1 -0
- package/dist/planning/planner.d.ts +4 -0
- package/dist/planning/planner.d.ts.map +1 -1
- package/dist/planning/planner.js +11 -0
- package/dist/planning/planner.js.map +1 -1
- package/dist/playbooks/generic/onboarding.d.ts +9 -0
- package/dist/playbooks/generic/onboarding.d.ts.map +1 -0
- package/dist/playbooks/generic/onboarding.js +74 -0
- package/dist/playbooks/generic/onboarding.js.map +1 -0
- package/dist/playbooks/playbook-registry.d.ts.map +1 -1
- package/dist/playbooks/playbook-registry.js +2 -0
- package/dist/playbooks/playbook-registry.js.map +1 -1
- package/dist/queue/job-queue.d.ts +92 -0
- package/dist/queue/job-queue.d.ts.map +1 -0
- package/dist/queue/job-queue.js +180 -0
- package/dist/queue/job-queue.js.map +1 -0
- package/dist/queue/pipeline-runner.d.ts +62 -0
- package/dist/queue/pipeline-runner.d.ts.map +1 -0
- package/dist/queue/pipeline-runner.js +126 -0
- package/dist/queue/pipeline-runner.js.map +1 -0
- package/dist/runtime/admin-extra-ops.d.ts.map +1 -1
- package/dist/runtime/admin-extra-ops.js +15 -9
- package/dist/runtime/admin-extra-ops.js.map +1 -1
- package/dist/runtime/admin-ops.js +4 -4
- package/dist/runtime/admin-ops.js.map +1 -1
- package/dist/runtime/admin-setup-ops.d.ts +20 -0
- package/dist/runtime/admin-setup-ops.d.ts.map +1 -0
- package/dist/runtime/admin-setup-ops.js +583 -0
- package/dist/runtime/admin-setup-ops.js.map +1 -0
- package/dist/runtime/capture-ops.d.ts.map +1 -1
- package/dist/runtime/capture-ops.js +33 -1
- package/dist/runtime/capture-ops.js.map +1 -1
- package/dist/runtime/chain-ops.d.ts +9 -0
- package/dist/runtime/chain-ops.d.ts.map +1 -0
- package/dist/runtime/chain-ops.js +107 -0
- package/dist/runtime/chain-ops.js.map +1 -0
- package/dist/runtime/claude-md-helpers.d.ts +65 -0
- package/dist/runtime/claude-md-helpers.d.ts.map +1 -0
- package/dist/runtime/claude-md-helpers.js +173 -0
- package/dist/runtime/claude-md-helpers.js.map +1 -0
- package/dist/runtime/curator-extra-ops.d.ts +3 -2
- package/dist/runtime/curator-extra-ops.d.ts.map +1 -1
- package/dist/runtime/curator-extra-ops.js +81 -3
- package/dist/runtime/curator-extra-ops.js.map +1 -1
- package/dist/runtime/domain-ops.d.ts +21 -5
- package/dist/runtime/domain-ops.d.ts.map +1 -1
- package/dist/runtime/domain-ops.js +64 -6
- package/dist/runtime/domain-ops.js.map +1 -1
- package/dist/runtime/facades/admin-facade.d.ts.map +1 -1
- package/dist/runtime/facades/admin-facade.js +4 -0
- package/dist/runtime/facades/admin-facade.js.map +1 -1
- package/dist/runtime/facades/agency-facade.d.ts.map +1 -1
- package/dist/runtime/facades/agency-facade.js +64 -0
- package/dist/runtime/facades/agency-facade.js.map +1 -1
- package/dist/runtime/facades/brain-facade.d.ts.map +1 -1
- package/dist/runtime/facades/brain-facade.js +122 -1
- package/dist/runtime/facades/brain-facade.js.map +1 -1
- package/dist/runtime/facades/cognee-facade.d.ts.map +1 -1
- package/dist/runtime/facades/cognee-facade.js +3 -1
- package/dist/runtime/facades/cognee-facade.js.map +1 -1
- package/dist/runtime/facades/control-facade.d.ts.map +1 -1
- package/dist/runtime/facades/control-facade.js +42 -0
- package/dist/runtime/facades/control-facade.js.map +1 -1
- package/dist/runtime/facades/index.d.ts.map +1 -1
- package/dist/runtime/facades/index.js +10 -6
- package/dist/runtime/facades/index.js.map +1 -1
- package/dist/runtime/facades/memory-facade.d.ts.map +1 -1
- package/dist/runtime/facades/memory-facade.js +20 -2
- package/dist/runtime/facades/memory-facade.js.map +1 -1
- package/dist/runtime/facades/plan-facade.d.ts.map +1 -1
- package/dist/runtime/facades/plan-facade.js +2 -0
- package/dist/runtime/facades/plan-facade.js.map +1 -1
- package/dist/runtime/facades/vault-facade.d.ts.map +1 -1
- package/dist/runtime/facades/vault-facade.js +27 -5
- package/dist/runtime/facades/vault-facade.js.map +1 -1
- package/dist/runtime/intake-ops.d.ts +7 -5
- package/dist/runtime/intake-ops.d.ts.map +1 -1
- package/dist/runtime/intake-ops.js +98 -5
- package/dist/runtime/intake-ops.js.map +1 -1
- package/dist/runtime/memory-extra-ops.d.ts +6 -3
- package/dist/runtime/memory-extra-ops.d.ts.map +1 -1
- package/dist/runtime/memory-extra-ops.js +292 -4
- package/dist/runtime/memory-extra-ops.js.map +1 -1
- package/dist/runtime/orchestrate-ops.d.ts +8 -7
- package/dist/runtime/orchestrate-ops.d.ts.map +1 -1
- package/dist/runtime/orchestrate-ops.js +217 -61
- package/dist/runtime/orchestrate-ops.js.map +1 -1
- package/dist/runtime/planning-extra-ops.d.ts.map +1 -1
- package/dist/runtime/planning-extra-ops.js +85 -0
- package/dist/runtime/planning-extra-ops.js.map +1 -1
- package/dist/runtime/playbook-ops.js +1 -1
- package/dist/runtime/playbook-ops.js.map +1 -1
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +165 -18
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/session-briefing.d.ts +23 -0
- package/dist/runtime/session-briefing.d.ts.map +1 -0
- package/dist/runtime/session-briefing.js +140 -0
- package/dist/runtime/session-briefing.js.map +1 -0
- package/dist/runtime/types.d.ts +29 -2
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/vault-linking-ops.d.ts +13 -0
- package/dist/runtime/vault-linking-ops.d.ts.map +1 -0
- package/dist/runtime/vault-linking-ops.js +365 -0
- package/dist/runtime/vault-linking-ops.js.map +1 -0
- package/dist/vault/linking.d.ts +46 -0
- package/dist/vault/linking.d.ts.map +1 -0
- package/dist/vault/linking.js +275 -0
- package/dist/vault/linking.js.map +1 -0
- package/dist/vault/vault-types.d.ts +37 -0
- package/dist/vault/vault-types.d.ts.map +1 -1
- package/dist/vault/vault.d.ts +37 -0
- package/dist/vault/vault.d.ts.map +1 -1
- package/dist/vault/vault.js +152 -9
- package/dist/vault/vault.js.map +1 -1
- package/package.json +4 -1
- package/src/__tests__/admin-extra-ops.test.ts +1 -1
- package/src/__tests__/admin-ops.test.ts +2 -1
- package/src/__tests__/admin-setup-ops.test.ts +355 -0
- package/src/__tests__/async-infrastructure.test.ts +307 -0
- package/src/__tests__/cognee-client-gaps.test.ts +474 -0
- package/src/__tests__/cognee-hybrid-search.test.ts +492 -0
- package/src/__tests__/cognee-sync-manager-deep.test.ts +654 -0
- package/src/__tests__/cognee-sync-manager.test.ts +1 -0
- package/src/__tests__/core-ops.test.ts +9 -61
- package/src/__tests__/curator-extra-ops.test.ts +6 -2
- package/src/__tests__/curator-pipeline-e2e.test.ts +358 -0
- package/src/__tests__/domain-packs.test.ts +421 -0
- package/src/__tests__/flows.test.ts +604 -0
- package/src/__tests__/memory-extra-ops.test.ts +2 -2
- package/src/__tests__/planning-extra-ops.test.ts +2 -2
- package/src/__tests__/playbook-registry.test.ts +2 -2
- package/src/__tests__/playbook-seeder.test.ts +8 -8
- package/src/__tests__/playbook.test.ts +5 -5
- package/src/__tests__/second-brain-features.test.ts +583 -0
- package/src/__tests__/token-resolver.test.ts +79 -0
- package/src/agency/agency-manager.ts +217 -9
- package/src/agency/default-rules.ts +83 -0
- package/src/agency/types.ts +61 -0
- package/src/brain/brain.ts +110 -8
- package/src/brain/intelligence.ts +21 -2
- package/src/brain/knowledge-synthesizer.ts +218 -0
- package/src/brain/learning-radar.ts +340 -0
- package/src/brain/types.ts +16 -0
- package/src/capabilities/chain-mapping.ts +93 -0
- package/src/capabilities/index.ts +21 -0
- package/src/capabilities/registry.ts +290 -0
- package/src/capabilities/types.ts +143 -0
- package/src/context/context-engine.ts +114 -15
- package/src/context/types.ts +5 -0
- package/src/control/intent-router.ts +153 -2
- package/src/control/types.ts +10 -0
- package/src/curator/classifier.ts +88 -0
- package/src/curator/quality-gate.ts +129 -0
- package/src/domain-packs/index.ts +27 -0
- package/src/domain-packs/inject-rules.ts +74 -0
- package/src/domain-packs/knowledge-installer.ts +116 -0
- package/src/domain-packs/loader.ts +124 -0
- package/src/domain-packs/pack-runtime.ts +99 -0
- package/src/domain-packs/skills-installer.ts +56 -0
- package/src/domain-packs/token-resolver.ts +126 -0
- package/src/domain-packs/types.ts +229 -0
- package/src/engine/__tests__/register-engine.test.ts +104 -0
- package/src/engine/bin/soleri-engine.ts +218 -0
- package/src/engine/core-ops.ts +178 -0
- package/src/engine/index.ts +19 -0
- package/src/engine/register-engine.ts +385 -0
- package/src/engine/test-helpers.ts +83 -0
- package/src/events/event-bus.ts +58 -0
- package/src/flows/chain-runner.ts +369 -0
- package/src/flows/chain-types.ts +57 -0
- package/src/flows/context-router.ts +257 -0
- package/src/flows/dispatch-registry.ts +80 -0
- package/src/flows/epilogue.ts +65 -0
- package/src/flows/executor.ts +182 -0
- package/src/flows/gate-evaluator.ts +171 -0
- package/src/flows/index.ts +52 -0
- package/src/flows/loader.ts +63 -0
- package/src/flows/plan-builder.ts +250 -0
- package/src/flows/probes.ts +70 -0
- package/src/flows/types.ts +217 -0
- package/src/health/doctor-checks.ts +115 -0
- package/src/index.ts +68 -1
- package/src/intake/text-ingester.ts +234 -0
- package/src/intelligence/loader.ts +38 -0
- package/src/intelligence/types.ts +1 -0
- package/src/llm/llm-client.ts +38 -1
- package/src/llm/oauth-discovery.ts +169 -0
- package/src/packs/types.ts +19 -0
- package/src/planning/evidence-collector.ts +247 -0
- package/src/planning/planner.ts +11 -0
- package/src/playbooks/generic/onboarding.ts +79 -0
- package/src/playbooks/playbook-registry.ts +2 -0
- package/src/queue/job-queue.ts +281 -0
- package/src/queue/pipeline-runner.ts +149 -0
- package/src/runtime/admin-extra-ops.ts +14 -8
- package/src/runtime/admin-ops.ts +4 -4
- package/src/runtime/admin-setup-ops.ts +664 -0
- package/src/runtime/capture-ops.ts +40 -1
- package/src/runtime/chain-ops.ts +121 -0
- package/src/runtime/claude-md-helpers.ts +236 -0
- package/src/runtime/curator-extra-ops.ts +86 -3
- package/src/runtime/domain-ops.ts +71 -5
- package/src/runtime/facades/admin-facade.ts +4 -0
- package/src/runtime/facades/agency-facade.ts +68 -0
- package/src/runtime/facades/brain-facade.ts +142 -1
- package/src/runtime/facades/cognee-facade.ts +3 -1
- package/src/runtime/facades/control-facade.ts +45 -0
- package/src/runtime/facades/index.ts +12 -6
- package/src/runtime/facades/memory-facade.ts +20 -2
- package/src/runtime/facades/plan-facade.ts +2 -0
- package/src/runtime/facades/vault-facade.ts +30 -5
- package/src/runtime/intake-ops.ts +107 -5
- package/src/runtime/memory-extra-ops.ts +312 -4
- package/src/runtime/orchestrate-ops.ts +261 -65
- package/src/runtime/planning-extra-ops.ts +94 -0
- package/src/runtime/playbook-ops.ts +1 -1
- package/src/runtime/runtime.ts +164 -19
- package/src/runtime/session-briefing.ts +161 -0
- package/src/runtime/types.ts +29 -2
- package/src/runtime/vault-linking-ops.ts +452 -0
- package/src/vault/linking.ts +333 -0
- package/src/vault/vault-types.ts +46 -0
- package/src/vault/vault.ts +173 -11
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dispatch registry — maps tool names to real facade op handlers.
|
|
3
|
+
*
|
|
4
|
+
* Tool names follow the convention: `{agentId}_{facadeName}_{opName}`
|
|
5
|
+
* e.g. "myagent_vault_search" → facade "myagent_vault", op "search".
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { FacadeConfig } from '../facades/types.js';
|
|
9
|
+
|
|
10
|
+
type DispatchResult = { tool: string; status: string; data?: unknown; error?: string };
|
|
11
|
+
type DispatchFn = (toolName: string, params: Record<string, unknown>) => Promise<DispatchResult>;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Create a dispatcher function that routes tool calls to the correct facade op.
|
|
15
|
+
*
|
|
16
|
+
* @param agentId - Agent identifier prefix (e.g. "myagent")
|
|
17
|
+
* @param facades - Array of registered facade configs
|
|
18
|
+
* @returns A dispatch function that takes (toolName, params) and calls the matching handler
|
|
19
|
+
*/
|
|
20
|
+
export function createDispatcher(agentId: string, facades: FacadeConfig[]): DispatchFn {
|
|
21
|
+
// Build a lookup map: facadeName → { opName → handler }
|
|
22
|
+
const facadeMap = new Map<string, FacadeConfig>();
|
|
23
|
+
for (const facade of facades) {
|
|
24
|
+
facadeMap.set(facade.name, facade);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return async (toolName: string, params: Record<string, unknown>): Promise<DispatchResult> => {
|
|
28
|
+
const prefix = `${agentId}_`;
|
|
29
|
+
|
|
30
|
+
// Strip agent prefix if present
|
|
31
|
+
const unprefixed = toolName.startsWith(prefix) ? toolName.slice(prefix.length) : toolName;
|
|
32
|
+
|
|
33
|
+
// Try progressively longer facade name prefixes.
|
|
34
|
+
// E.g. for "vault_extra_search": try "vault_extra_search", "vault_extra", "vault"
|
|
35
|
+
const parts = unprefixed.split('_');
|
|
36
|
+
|
|
37
|
+
for (let splitAt = parts.length - 1; splitAt >= 1; splitAt--) {
|
|
38
|
+
const facadeSuffix = parts.slice(0, splitAt).join('_');
|
|
39
|
+
const opName = parts.slice(splitAt).join('_');
|
|
40
|
+
const facadeFullName = `${prefix}${facadeSuffix}`;
|
|
41
|
+
|
|
42
|
+
const facade = facadeMap.get(facadeFullName);
|
|
43
|
+
if (!facade) continue;
|
|
44
|
+
|
|
45
|
+
const op = facade.ops.find((o) => o.name === opName);
|
|
46
|
+
if (!op) continue;
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
const result = await op.handler(params);
|
|
50
|
+
return { tool: toolName, status: 'ok', data: result };
|
|
51
|
+
} catch (err) {
|
|
52
|
+
return {
|
|
53
|
+
tool: toolName,
|
|
54
|
+
status: 'error',
|
|
55
|
+
error: err instanceof Error ? err.message : String(err),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Also try matching the full unprefixed name as a facade with "op" from params
|
|
61
|
+
const facade = facadeMap.get(`${prefix}${unprefixed}`);
|
|
62
|
+
if (facade && params.op && typeof params.op === 'string') {
|
|
63
|
+
const op = facade.ops.find((o) => o.name === params.op);
|
|
64
|
+
if (op) {
|
|
65
|
+
try {
|
|
66
|
+
const result = await op.handler(params);
|
|
67
|
+
return { tool: toolName, status: 'ok', data: result };
|
|
68
|
+
} catch (err) {
|
|
69
|
+
return {
|
|
70
|
+
tool: toolName,
|
|
71
|
+
status: 'error',
|
|
72
|
+
error: err instanceof Error ? err.message : String(err),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return { tool: toolName, status: 'unregistered' };
|
|
79
|
+
};
|
|
80
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Epilogue — post-execution cleanup: capture knowledge and session summary.
|
|
3
|
+
* All operations are resilient (errors are caught, never propagated).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { ProbeResults } from './types.js';
|
|
7
|
+
|
|
8
|
+
type DispatchFn = (
|
|
9
|
+
toolName: string,
|
|
10
|
+
params: Record<string, unknown>,
|
|
11
|
+
) => Promise<{ tool: string; status: string; data?: unknown; error?: string }>;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Run post-execution epilogue steps.
|
|
15
|
+
* - Captures knowledge to vault (if available)
|
|
16
|
+
* - Captures session summary (if session store available)
|
|
17
|
+
*
|
|
18
|
+
* @returns Whether anything was captured and an optional session ID.
|
|
19
|
+
*/
|
|
20
|
+
export async function runEpilogue(
|
|
21
|
+
dispatch: DispatchFn,
|
|
22
|
+
probes: ProbeResults,
|
|
23
|
+
projectPath: string,
|
|
24
|
+
summary: string,
|
|
25
|
+
): Promise<{ captured: boolean; sessionId?: string }> {
|
|
26
|
+
let captured = false;
|
|
27
|
+
let sessionId: string | undefined;
|
|
28
|
+
|
|
29
|
+
// Capture knowledge to vault
|
|
30
|
+
if (probes.vault) {
|
|
31
|
+
try {
|
|
32
|
+
await dispatch('capture_knowledge', {
|
|
33
|
+
title: 'Flow execution summary',
|
|
34
|
+
content: summary,
|
|
35
|
+
type: 'workflow',
|
|
36
|
+
tags: ['flow-engine', 'auto-captured'],
|
|
37
|
+
projectPath,
|
|
38
|
+
});
|
|
39
|
+
captured = true;
|
|
40
|
+
} catch {
|
|
41
|
+
// Silently ignore — vault capture is best-effort
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Capture session
|
|
46
|
+
if (probes.sessionStore) {
|
|
47
|
+
try {
|
|
48
|
+
const result = await dispatch('session_capture', {
|
|
49
|
+
summary,
|
|
50
|
+
projectPath,
|
|
51
|
+
});
|
|
52
|
+
captured = true;
|
|
53
|
+
if (result.data && typeof result.data === 'object') {
|
|
54
|
+
const data = result.data as Record<string, unknown>;
|
|
55
|
+
if (typeof data.sessionId === 'string') {
|
|
56
|
+
sessionId = data.sessionId;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
} catch {
|
|
60
|
+
// Silently ignore — session capture is best-effort
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return { captured, sessionId };
|
|
65
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flow executor — runs an orchestration plan step-by-step,
|
|
3
|
+
* evaluating gates and handling branching.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { OrchestrationPlan, ExecutionResult, StepResult } from './types.js';
|
|
7
|
+
import { evaluateGate } from './gate-evaluator.js';
|
|
8
|
+
|
|
9
|
+
/** Maximum iterations for BRANCH loops to prevent infinite cycles. */
|
|
10
|
+
const MAX_BRANCH_ITERATIONS = 10;
|
|
11
|
+
|
|
12
|
+
type DispatchFn = (
|
|
13
|
+
toolName: string,
|
|
14
|
+
params: Record<string, unknown>,
|
|
15
|
+
) => Promise<{ tool: string; status: string; data?: unknown; error?: string }>;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Executes an orchestration plan sequentially (with parallel inner steps).
|
|
19
|
+
*/
|
|
20
|
+
export class FlowExecutor {
|
|
21
|
+
private dispatch: DispatchFn;
|
|
22
|
+
|
|
23
|
+
constructor(dispatch: DispatchFn) {
|
|
24
|
+
this.dispatch = dispatch;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Execute a full orchestration plan. Returns an ExecutionResult
|
|
29
|
+
* summarizing what happened.
|
|
30
|
+
*/
|
|
31
|
+
async execute(plan: OrchestrationPlan): Promise<ExecutionResult> {
|
|
32
|
+
const startTime = Date.now();
|
|
33
|
+
const stepResults: StepResult[] = [];
|
|
34
|
+
const toolsCalled: string[] = [];
|
|
35
|
+
let branchIterations = 0;
|
|
36
|
+
let currentIndex = 0;
|
|
37
|
+
|
|
38
|
+
while (currentIndex < plan.steps.length) {
|
|
39
|
+
const step = plan.steps[currentIndex];
|
|
40
|
+
const stepStart = Date.now();
|
|
41
|
+
step.status = 'running';
|
|
42
|
+
|
|
43
|
+
const toolResults: StepResult['toolResults'] = {};
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
if (step.parallel && step.tools.length > 1) {
|
|
47
|
+
// Execute tools in parallel
|
|
48
|
+
const results = await Promise.allSettled(
|
|
49
|
+
step.tools.map((tool) => this.dispatch(tool, { stepId: step.id, planId: plan.planId })),
|
|
50
|
+
);
|
|
51
|
+
for (let i = 0; i < step.tools.length; i++) {
|
|
52
|
+
const toolName = step.tools[i];
|
|
53
|
+
const result = results[i];
|
|
54
|
+
if (result.status === 'fulfilled') {
|
|
55
|
+
toolResults[toolName] = result.value;
|
|
56
|
+
} else {
|
|
57
|
+
toolResults[toolName] = {
|
|
58
|
+
tool: toolName,
|
|
59
|
+
status: 'error',
|
|
60
|
+
error:
|
|
61
|
+
result.reason instanceof Error ? result.reason.message : String(result.reason),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
toolsCalled.push(toolName);
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
// Execute tools sequentially
|
|
68
|
+
for (const toolName of step.tools) {
|
|
69
|
+
try {
|
|
70
|
+
toolResults[toolName] = await this.dispatch(toolName, {
|
|
71
|
+
stepId: step.id,
|
|
72
|
+
planId: plan.planId,
|
|
73
|
+
});
|
|
74
|
+
} catch (_err) {
|
|
75
|
+
toolResults[toolName] = {
|
|
76
|
+
tool: toolName,
|
|
77
|
+
status: 'error',
|
|
78
|
+
error: _err instanceof Error ? _err.message : String(_err),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
toolsCalled.push(toolName);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
} catch (_err) {
|
|
85
|
+
// Entire step failed
|
|
86
|
+
const stepResult: StepResult = {
|
|
87
|
+
stepId: step.id,
|
|
88
|
+
status: 'failed',
|
|
89
|
+
toolResults,
|
|
90
|
+
durationMs: Date.now() - stepStart,
|
|
91
|
+
};
|
|
92
|
+
stepResults.push(stepResult);
|
|
93
|
+
step.status = 'failed';
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Evaluate gate
|
|
98
|
+
const flatData: Record<string, unknown> = {};
|
|
99
|
+
for (const [key, val] of Object.entries(toolResults)) {
|
|
100
|
+
flatData[key] = val;
|
|
101
|
+
if (val.data && typeof val.data === 'object') {
|
|
102
|
+
Object.assign(flatData, val.data as Record<string, unknown>);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const verdict = evaluateGate(step.gate, flatData);
|
|
107
|
+
|
|
108
|
+
const stepResult: StepResult = {
|
|
109
|
+
stepId: step.id,
|
|
110
|
+
status: verdict.passed ? 'passed' : 'failed',
|
|
111
|
+
toolResults,
|
|
112
|
+
durationMs: Date.now() - stepStart,
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
if (!verdict.passed || verdict.action !== 'CONTINUE') {
|
|
116
|
+
stepResult.gateResult = {
|
|
117
|
+
action: verdict.action,
|
|
118
|
+
message: verdict.message,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
stepResults.push(stepResult);
|
|
123
|
+
|
|
124
|
+
// Handle gate action
|
|
125
|
+
switch (verdict.action) {
|
|
126
|
+
case 'STOP':
|
|
127
|
+
step.status = 'failed';
|
|
128
|
+
// Stop execution
|
|
129
|
+
return buildResult(plan, stepResults, toolsCalled, startTime, 'partial');
|
|
130
|
+
|
|
131
|
+
case 'BRANCH': {
|
|
132
|
+
step.status = verdict.passed ? 'passed' : 'gate-paused';
|
|
133
|
+
branchIterations++;
|
|
134
|
+
if (branchIterations >= MAX_BRANCH_ITERATIONS) {
|
|
135
|
+
return buildResult(plan, stepResults, toolsCalled, startTime, 'partial');
|
|
136
|
+
}
|
|
137
|
+
if (verdict.goto) {
|
|
138
|
+
const targetIdx = plan.steps.findIndex((s) => s.id === verdict.goto);
|
|
139
|
+
if (targetIdx >= 0) {
|
|
140
|
+
currentIndex = targetIdx;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// No valid goto — continue to next step
|
|
145
|
+
step.status = 'passed';
|
|
146
|
+
currentIndex++;
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
case 'CONTINUE':
|
|
151
|
+
default:
|
|
152
|
+
step.status = verdict.passed ? 'passed' : 'failed';
|
|
153
|
+
currentIndex++;
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const allPassed = stepResults.every((r) => r.status === 'passed');
|
|
159
|
+
const anyFailed = stepResults.some((r) => r.status === 'failed');
|
|
160
|
+
const status = allPassed ? 'completed' : anyFailed ? 'partial' : 'completed';
|
|
161
|
+
|
|
162
|
+
return buildResult(plan, stepResults, toolsCalled, startTime, status);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function buildResult(
|
|
167
|
+
plan: OrchestrationPlan,
|
|
168
|
+
stepResults: StepResult[],
|
|
169
|
+
toolsCalled: string[],
|
|
170
|
+
startTime: number,
|
|
171
|
+
status: ExecutionResult['status'],
|
|
172
|
+
): ExecutionResult {
|
|
173
|
+
return {
|
|
174
|
+
planId: plan.planId,
|
|
175
|
+
status,
|
|
176
|
+
stepsCompleted: stepResults.filter((r) => r.status === 'passed').length,
|
|
177
|
+
totalSteps: plan.steps.length,
|
|
178
|
+
toolsCalled: [...new Set(toolsCalled)],
|
|
179
|
+
durationMs: Date.now() - startTime,
|
|
180
|
+
stepResults,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gate evaluator — checks step gates against tool results to decide
|
|
3
|
+
* whether execution should CONTINUE, STOP, or BRANCH.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { PlanStep, GateVerdict } from './types.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Evaluate a plan step's gate against collected tool results.
|
|
10
|
+
* If no gate is defined, returns CONTINUE (passed).
|
|
11
|
+
*/
|
|
12
|
+
export function evaluateGate(
|
|
13
|
+
gate: PlanStep['gate'],
|
|
14
|
+
toolResults: Record<string, unknown>,
|
|
15
|
+
): GateVerdict {
|
|
16
|
+
if (!gate) {
|
|
17
|
+
return { passed: true, action: 'CONTINUE' };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
switch (gate.type) {
|
|
21
|
+
case 'GATE': {
|
|
22
|
+
const passed = gate.condition ? evaluateCondition(gate.condition, toolResults) : true;
|
|
23
|
+
if (passed) return { passed: true, action: 'CONTINUE' };
|
|
24
|
+
return {
|
|
25
|
+
passed: false,
|
|
26
|
+
action: (gate.onFail?.action as GateVerdict['action']) ?? 'STOP',
|
|
27
|
+
goto: gate.onFail?.goto,
|
|
28
|
+
message: gate.onFail?.message,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
case 'SCORE': {
|
|
33
|
+
const score = extractScore(toolResults);
|
|
34
|
+
const minScore = gate.min ?? 0;
|
|
35
|
+
const passed = score >= minScore;
|
|
36
|
+
if (passed) return { passed: true, action: 'CONTINUE', score };
|
|
37
|
+
return {
|
|
38
|
+
passed: false,
|
|
39
|
+
action: (gate.onFail?.action as GateVerdict['action']) ?? 'STOP',
|
|
40
|
+
goto: gate.onFail?.goto,
|
|
41
|
+
message: gate.onFail?.message ?? `Score ${score} below minimum ${minScore}`,
|
|
42
|
+
score,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
case 'CHECKPOINT': {
|
|
47
|
+
const passed = gate.condition ? evaluateCondition(gate.condition, toolResults) : true;
|
|
48
|
+
if (passed) return { passed: true, action: 'CONTINUE' };
|
|
49
|
+
return {
|
|
50
|
+
passed: false,
|
|
51
|
+
action: (gate.onFail?.action as GateVerdict['action']) ?? 'CONTINUE',
|
|
52
|
+
goto: gate.onFail?.goto,
|
|
53
|
+
message: gate.onFail?.message,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
case 'BRANCH': {
|
|
58
|
+
// BRANCH gates always trigger branching
|
|
59
|
+
return {
|
|
60
|
+
passed: true,
|
|
61
|
+
action: 'BRANCH',
|
|
62
|
+
goto: gate.onFail?.goto,
|
|
63
|
+
message: gate.onFail?.message,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
default:
|
|
68
|
+
return { passed: true, action: 'CONTINUE' };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Evaluate a simple condition string: "lhs op rhs".
|
|
74
|
+
* Supported operators: ==, !=, >=, <=, >, <
|
|
75
|
+
* lhs is resolved as a dotted path from data, rhs is a literal.
|
|
76
|
+
*/
|
|
77
|
+
export function evaluateCondition(condition: string, data: Record<string, unknown>): boolean {
|
|
78
|
+
const operators = ['>=', '<=', '!=', '==', '>', '<'] as const;
|
|
79
|
+
for (const op of operators) {
|
|
80
|
+
const idx = condition.indexOf(op);
|
|
81
|
+
if (idx === -1) continue;
|
|
82
|
+
|
|
83
|
+
const lhsPath = condition.slice(0, idx).trim();
|
|
84
|
+
const rhsRaw = condition.slice(idx + op.length).trim();
|
|
85
|
+
const lhsValue = resolvePath(data, lhsPath);
|
|
86
|
+
const rhsValue = parseConditionValue(rhsRaw);
|
|
87
|
+
|
|
88
|
+
const lNum = typeof lhsValue === 'number' ? lhsValue : Number(lhsValue);
|
|
89
|
+
const rNum = typeof rhsValue === 'number' ? rhsValue : Number(rhsValue);
|
|
90
|
+
const useNumeric = !Number.isNaN(lNum) && !Number.isNaN(rNum);
|
|
91
|
+
|
|
92
|
+
switch (op) {
|
|
93
|
+
case '==':
|
|
94
|
+
return useNumeric ? lNum === rNum : String(lhsValue) === String(rhsValue);
|
|
95
|
+
case '!=':
|
|
96
|
+
return useNumeric ? lNum !== rNum : String(lhsValue) !== String(rhsValue);
|
|
97
|
+
case '>=':
|
|
98
|
+
return useNumeric ? lNum >= rNum : false;
|
|
99
|
+
case '<=':
|
|
100
|
+
return useNumeric ? lNum <= rNum : false;
|
|
101
|
+
case '>':
|
|
102
|
+
return useNumeric ? lNum > rNum : false;
|
|
103
|
+
case '<':
|
|
104
|
+
return useNumeric ? lNum < rNum : false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// No operator found — check if value is truthy
|
|
109
|
+
const val = resolvePath(data, condition.trim());
|
|
110
|
+
return !!val;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Extract a numeric score from tool results.
|
|
115
|
+
* Looks for common score field names.
|
|
116
|
+
*/
|
|
117
|
+
export function extractScore(data: Record<string, unknown>): number {
|
|
118
|
+
// Direct score fields
|
|
119
|
+
for (const key of ['score', 'validationScore', 'total']) {
|
|
120
|
+
if (typeof data[key] === 'number') return data[key] as number;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Search within nested result objects
|
|
124
|
+
for (const val of Object.values(data)) {
|
|
125
|
+
if (val && typeof val === 'object' && !Array.isArray(val)) {
|
|
126
|
+
const nested = val as Record<string, unknown>;
|
|
127
|
+
for (const key of ['score', 'validationScore', 'total']) {
|
|
128
|
+
if (typeof nested[key] === 'number') return nested[key] as number;
|
|
129
|
+
}
|
|
130
|
+
// One more level: data property
|
|
131
|
+
if (nested.data && typeof nested.data === 'object') {
|
|
132
|
+
const deep = nested.data as Record<string, unknown>;
|
|
133
|
+
for (const key of ['score', 'validationScore', 'total']) {
|
|
134
|
+
if (typeof deep[key] === 'number') return deep[key] as number;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return 0;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Resolve a dotted path like "result.data.score" against an object.
|
|
145
|
+
*/
|
|
146
|
+
export function resolvePath(obj: Record<string, unknown>, path: string): unknown {
|
|
147
|
+
const parts = path.split('.');
|
|
148
|
+
let current: unknown = obj;
|
|
149
|
+
for (const part of parts) {
|
|
150
|
+
if (current === null || current === undefined || typeof current !== 'object') return undefined;
|
|
151
|
+
current = (current as Record<string, unknown>)[part];
|
|
152
|
+
}
|
|
153
|
+
return current;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// ---------------------------------------------------------------------------
|
|
157
|
+
// Internal
|
|
158
|
+
// ---------------------------------------------------------------------------
|
|
159
|
+
|
|
160
|
+
function parseConditionValue(raw: string): string | number | boolean {
|
|
161
|
+
if (raw === 'true') return true;
|
|
162
|
+
if (raw === 'false') return false;
|
|
163
|
+
if (raw === 'null') return 0;
|
|
164
|
+
// Strip quotes
|
|
165
|
+
if ((raw.startsWith('"') && raw.endsWith('"')) || (raw.startsWith("'") && raw.endsWith("'"))) {
|
|
166
|
+
return raw.slice(1, -1);
|
|
167
|
+
}
|
|
168
|
+
const num = Number(raw);
|
|
169
|
+
if (!Number.isNaN(num)) return num;
|
|
170
|
+
return raw;
|
|
171
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flow engine — YAML-driven workflow orchestration.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// Types
|
|
6
|
+
export type {
|
|
7
|
+
Flow,
|
|
8
|
+
FlowStep,
|
|
9
|
+
Gate,
|
|
10
|
+
GateAction,
|
|
11
|
+
ProbeName,
|
|
12
|
+
ProbeResults,
|
|
13
|
+
PlanStep,
|
|
14
|
+
SkippedStep,
|
|
15
|
+
OrchestrationPlan,
|
|
16
|
+
OrchestrationContext,
|
|
17
|
+
StepResult,
|
|
18
|
+
ExecutionResult,
|
|
19
|
+
GateVerdict,
|
|
20
|
+
} from './types.js';
|
|
21
|
+
|
|
22
|
+
// Loader
|
|
23
|
+
export { loadFlowById, loadAllFlows, parseSimpleYaml } from './loader.js';
|
|
24
|
+
|
|
25
|
+
// Probes
|
|
26
|
+
export { runProbes } from './probes.js';
|
|
27
|
+
|
|
28
|
+
// Plan builder
|
|
29
|
+
export {
|
|
30
|
+
INTENT_TO_FLOW,
|
|
31
|
+
chainToToolName,
|
|
32
|
+
chainToRequires,
|
|
33
|
+
flowStepsToPlanSteps,
|
|
34
|
+
pruneSteps,
|
|
35
|
+
buildPlan,
|
|
36
|
+
} from './plan-builder.js';
|
|
37
|
+
|
|
38
|
+
// Context router
|
|
39
|
+
export { detectContext, applyContextOverrides, getFlowOverrides } from './context-router.js';
|
|
40
|
+
export type { ContextOverride } from './context-router.js';
|
|
41
|
+
|
|
42
|
+
// Gate evaluator
|
|
43
|
+
export { evaluateGate, evaluateCondition, extractScore, resolvePath } from './gate-evaluator.js';
|
|
44
|
+
|
|
45
|
+
// Executor
|
|
46
|
+
export { FlowExecutor } from './executor.js';
|
|
47
|
+
|
|
48
|
+
// Dispatch registry
|
|
49
|
+
export { createDispatcher } from './dispatch-registry.js';
|
|
50
|
+
|
|
51
|
+
// Epilogue
|
|
52
|
+
export { runEpilogue } from './epilogue.js';
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flow loader — reads and validates YAML flow files from a directory.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { readdirSync, readFileSync, existsSync } from 'node:fs';
|
|
6
|
+
import { join, dirname } from 'node:path';
|
|
7
|
+
import { fileURLToPath } from 'node:url';
|
|
8
|
+
import { parse as parseYaml } from 'yaml';
|
|
9
|
+
import { flowSchema, type Flow } from './types.js';
|
|
10
|
+
|
|
11
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
const DEFAULT_FLOWS_DIR = join(__dirname, '..', '..', 'data', 'flows');
|
|
13
|
+
|
|
14
|
+
/** Re-export for backward compat (tests import this). */
|
|
15
|
+
export const parseSimpleYaml = parseYaml;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Load a single flow by its `id` field from *.flow.yaml files in a directory.
|
|
19
|
+
* Returns `null` if not found or validation fails.
|
|
20
|
+
*/
|
|
21
|
+
export function loadFlowById(flowId: string, flowsDir?: string): Flow | null {
|
|
22
|
+
const dir = flowsDir ?? DEFAULT_FLOWS_DIR;
|
|
23
|
+
if (!existsSync(dir)) return null;
|
|
24
|
+
|
|
25
|
+
const files = readdirSync(dir).filter((f) => f.endsWith('.flow.yaml'));
|
|
26
|
+
for (const file of files) {
|
|
27
|
+
try {
|
|
28
|
+
const content = readFileSync(join(dir, file), 'utf-8');
|
|
29
|
+
const raw = parseYaml(content);
|
|
30
|
+
const parsed = flowSchema.safeParse(raw);
|
|
31
|
+
if (parsed.success && parsed.data.id === flowId) {
|
|
32
|
+
return parsed.data;
|
|
33
|
+
}
|
|
34
|
+
} catch {
|
|
35
|
+
// skip invalid files
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Load all valid flows from *.flow.yaml files in a directory.
|
|
43
|
+
*/
|
|
44
|
+
export function loadAllFlows(flowsDir?: string): Flow[] {
|
|
45
|
+
const dir = flowsDir ?? DEFAULT_FLOWS_DIR;
|
|
46
|
+
if (!existsSync(dir)) return [];
|
|
47
|
+
|
|
48
|
+
const files = readdirSync(dir).filter((f) => f.endsWith('.flow.yaml'));
|
|
49
|
+
const flows: Flow[] = [];
|
|
50
|
+
for (const file of files) {
|
|
51
|
+
try {
|
|
52
|
+
const content = readFileSync(join(dir, file), 'utf-8');
|
|
53
|
+
const raw = parseYaml(content);
|
|
54
|
+
const parsed = flowSchema.safeParse(raw);
|
|
55
|
+
if (parsed.success) {
|
|
56
|
+
flows.push(parsed.data);
|
|
57
|
+
}
|
|
58
|
+
} catch {
|
|
59
|
+
// skip invalid files
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return flows;
|
|
63
|
+
}
|