@falai/agent 1.2.7 → 2.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/README.md +40 -886
- package/dist/adapters/MemoryAdapter.js +2 -2
- package/dist/adapters/MemoryAdapter.js.map +1 -1
- package/dist/adapters/MongoAdapter.js +2 -2
- package/dist/adapters/MongoAdapter.js.map +1 -1
- package/dist/adapters/OpenSearchAdapter.d.ts.map +1 -1
- package/dist/adapters/OpenSearchAdapter.js +9 -7
- package/dist/adapters/OpenSearchAdapter.js.map +1 -1
- package/dist/adapters/PostgreSQLAdapter.d.ts +14 -0
- package/dist/adapters/PostgreSQLAdapter.d.ts.map +1 -1
- package/dist/adapters/PostgreSQLAdapter.js +25 -9
- package/dist/adapters/PostgreSQLAdapter.js.map +1 -1
- package/dist/adapters/PrismaAdapter.js +5 -5
- package/dist/adapters/PrismaAdapter.js.map +1 -1
- package/dist/adapters/RedisAdapter.js +2 -2
- package/dist/adapters/RedisAdapter.js.map +1 -1
- package/dist/adapters/SQLiteAdapter.d.ts +17 -0
- package/dist/adapters/SQLiteAdapter.d.ts.map +1 -1
- package/dist/adapters/SQLiteAdapter.js +30 -11
- package/dist/adapters/SQLiteAdapter.js.map +1 -1
- package/dist/cjs/adapters/MemoryAdapter.js +2 -2
- package/dist/cjs/adapters/MemoryAdapter.js.map +1 -1
- package/dist/cjs/adapters/MongoAdapter.js +2 -2
- package/dist/cjs/adapters/MongoAdapter.js.map +1 -1
- package/dist/cjs/adapters/OpenSearchAdapter.d.ts.map +1 -1
- package/dist/cjs/adapters/OpenSearchAdapter.js +9 -7
- package/dist/cjs/adapters/OpenSearchAdapter.js.map +1 -1
- package/dist/cjs/adapters/PostgreSQLAdapter.d.ts +14 -0
- package/dist/cjs/adapters/PostgreSQLAdapter.d.ts.map +1 -1
- package/dist/cjs/adapters/PostgreSQLAdapter.js +25 -9
- package/dist/cjs/adapters/PostgreSQLAdapter.js.map +1 -1
- package/dist/cjs/adapters/PrismaAdapter.js +5 -5
- package/dist/cjs/adapters/PrismaAdapter.js.map +1 -1
- package/dist/cjs/adapters/RedisAdapter.js +2 -2
- package/dist/cjs/adapters/RedisAdapter.js.map +1 -1
- package/dist/cjs/adapters/SQLiteAdapter.d.ts +17 -0
- package/dist/cjs/adapters/SQLiteAdapter.d.ts.map +1 -1
- package/dist/cjs/adapters/SQLiteAdapter.js +30 -11
- package/dist/cjs/adapters/SQLiteAdapter.js.map +1 -1
- package/dist/cjs/constants/index.d.ts +0 -9
- package/dist/cjs/constants/index.d.ts.map +1 -1
- package/dist/cjs/constants/index.js +2 -11
- package/dist/cjs/constants/index.js.map +1 -1
- package/dist/cjs/core/Agent.d.ts +119 -153
- package/dist/cjs/core/Agent.d.ts.map +1 -1
- package/dist/cjs/core/Agent.js +471 -324
- package/dist/cjs/core/Agent.js.map +1 -1
- package/dist/cjs/core/AutoChainExecutor.d.ts +107 -0
- package/dist/cjs/core/AutoChainExecutor.d.ts.map +1 -0
- package/dist/cjs/core/AutoChainExecutor.js +297 -0
- package/dist/cjs/core/AutoChainExecutor.js.map +1 -0
- package/dist/cjs/core/BranchEvaluator.d.ts +54 -0
- package/dist/cjs/core/BranchEvaluator.d.ts.map +1 -0
- package/dist/cjs/core/BranchEvaluator.js +130 -0
- package/dist/cjs/core/BranchEvaluator.js.map +1 -0
- package/dist/cjs/core/DirectiveBus.d.ts +88 -0
- package/dist/cjs/core/DirectiveBus.d.ts.map +1 -0
- package/dist/cjs/core/DirectiveBus.js +196 -0
- package/dist/cjs/core/DirectiveBus.js.map +1 -0
- package/dist/cjs/core/DirectiveChainTracker.d.ts +49 -0
- package/dist/cjs/core/DirectiveChainTracker.d.ts.map +1 -0
- package/dist/cjs/core/DirectiveChainTracker.js +121 -0
- package/dist/cjs/core/DirectiveChainTracker.js.map +1 -0
- package/dist/cjs/core/Flow.d.ts +186 -0
- package/dist/cjs/core/Flow.d.ts.map +1 -0
- package/dist/cjs/core/Flow.js +550 -0
- package/dist/cjs/core/Flow.js.map +1 -0
- package/dist/cjs/core/FlowRouter.d.ts +182 -0
- package/dist/cjs/core/FlowRouter.d.ts.map +1 -0
- package/dist/cjs/core/{RoutingEngine.js → FlowRouter.js} +323 -306
- package/dist/cjs/core/FlowRouter.js.map +1 -0
- package/dist/cjs/core/PersistenceManager.d.ts +2 -2
- package/dist/cjs/core/PersistenceManager.d.ts.map +1 -1
- package/dist/cjs/core/PersistenceManager.js +7 -7
- package/dist/cjs/core/PersistenceManager.js.map +1 -1
- package/dist/cjs/core/PromptComposer.d.ts +21 -8
- package/dist/cjs/core/PromptComposer.d.ts.map +1 -1
- package/dist/cjs/core/PromptComposer.js +182 -105
- package/dist/cjs/core/PromptComposer.js.map +1 -1
- package/dist/cjs/core/PromptSectionCache.d.ts +1 -1
- package/dist/cjs/core/PromptSectionCache.js +1 -1
- package/dist/cjs/core/ResponseEngine.d.ts +18 -8
- package/dist/cjs/core/ResponseEngine.d.ts.map +1 -1
- package/dist/cjs/core/ResponseEngine.js +38 -36
- package/dist/cjs/core/ResponseEngine.js.map +1 -1
- package/dist/cjs/core/ResponseModal.d.ts +73 -56
- package/dist/cjs/core/ResponseModal.d.ts.map +1 -1
- package/dist/cjs/core/ResponseModal.js +1196 -1015
- package/dist/cjs/core/ResponseModal.js.map +1 -1
- package/dist/cjs/core/ResponsePipeline.d.ts +124 -26
- package/dist/cjs/core/ResponsePipeline.d.ts.map +1 -1
- package/dist/cjs/core/ResponsePipeline.js +524 -134
- package/dist/cjs/core/ResponsePipeline.js.map +1 -1
- package/dist/cjs/core/SignalEvaluator.d.ts +86 -0
- package/dist/cjs/core/SignalEvaluator.d.ts.map +1 -0
- package/dist/cjs/core/SignalEvaluator.js +333 -0
- package/dist/cjs/core/SignalEvaluator.js.map +1 -0
- package/dist/cjs/core/SignalProcessor.d.ts +152 -0
- package/dist/cjs/core/SignalProcessor.d.ts.map +1 -0
- package/dist/cjs/core/SignalProcessor.js +562 -0
- package/dist/cjs/core/SignalProcessor.js.map +1 -0
- package/dist/cjs/core/Step.d.ts +43 -32
- package/dist/cjs/core/Step.d.ts.map +1 -1
- package/dist/cjs/core/Step.js +221 -126
- package/dist/cjs/core/Step.js.map +1 -1
- package/dist/cjs/core/StreamingToolExecutor.d.ts +2 -2
- package/dist/cjs/core/StreamingToolExecutor.d.ts.map +1 -1
- package/dist/cjs/core/StreamingToolExecutor.js.map +1 -1
- package/dist/cjs/core/ToolManager.d.ts +44 -13
- package/dist/cjs/core/ToolManager.d.ts.map +1 -1
- package/dist/cjs/core/ToolManager.js +174 -91
- package/dist/cjs/core/ToolManager.js.map +1 -1
- package/dist/cjs/core/createAgent.d.ts +35 -0
- package/dist/cjs/core/createAgent.d.ts.map +1 -0
- package/dist/cjs/core/createAgent.js +39 -0
- package/dist/cjs/core/createAgent.js.map +1 -0
- package/dist/cjs/core/flow-namespace.d.ts +49 -0
- package/dist/cjs/core/flow-namespace.d.ts.map +1 -0
- package/dist/cjs/core/flow-namespace.js +171 -0
- package/dist/cjs/core/flow-namespace.js.map +1 -0
- package/dist/cjs/index.d.ts +11 -14
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +18 -22
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/providers/GeminiProvider.d.ts +3 -3
- package/dist/cjs/providers/GeminiProvider.d.ts.map +1 -1
- package/dist/cjs/providers/GeminiProvider.js +16 -14
- package/dist/cjs/providers/GeminiProvider.js.map +1 -1
- package/dist/cjs/types/agent.d.ts +183 -54
- package/dist/cjs/types/agent.d.ts.map +1 -1
- package/dist/cjs/types/agent.js +0 -6
- package/dist/cjs/types/agent.js.map +1 -1
- package/dist/cjs/types/ai.d.ts +3 -3
- package/dist/cjs/types/ai.d.ts.map +1 -1
- package/dist/cjs/types/errors.d.ts +15 -0
- package/dist/cjs/types/errors.d.ts.map +1 -0
- package/dist/cjs/types/errors.js +22 -0
- package/dist/cjs/types/errors.js.map +1 -0
- package/dist/cjs/types/flow.d.ts +513 -0
- package/dist/cjs/types/flow.d.ts.map +1 -0
- package/dist/cjs/types/{route.js → flow.js} +2 -2
- package/dist/cjs/types/flow.js.map +1 -0
- package/dist/cjs/types/index.d.ts +7 -6
- package/dist/cjs/types/index.d.ts.map +1 -1
- package/dist/cjs/types/index.js +6 -2
- package/dist/cjs/types/index.js.map +1 -1
- package/dist/cjs/types/persistence.d.ts +11 -7
- package/dist/cjs/types/persistence.d.ts.map +1 -1
- package/dist/cjs/types/routing.d.ts +1 -1
- package/dist/cjs/types/routing.d.ts.map +1 -1
- package/dist/cjs/types/session.d.ts +24 -23
- package/dist/cjs/types/session.d.ts.map +1 -1
- package/dist/cjs/types/signals.d.ts +248 -0
- package/dist/cjs/types/signals.d.ts.map +1 -0
- package/dist/cjs/types/signals.js +11 -0
- package/dist/cjs/types/signals.js.map +1 -0
- package/dist/cjs/types/template.d.ts +2 -8
- package/dist/cjs/types/template.d.ts.map +1 -1
- package/dist/cjs/types/tool.d.ts +36 -29
- package/dist/cjs/types/tool.d.ts.map +1 -1
- package/dist/cjs/types/tool.js +1 -1
- package/dist/cjs/types/tool.js.map +1 -1
- package/dist/cjs/utils/condition.d.ts +7 -1
- package/dist/cjs/utils/condition.d.ts.map +1 -1
- package/dist/cjs/utils/condition.js.map +1 -1
- package/dist/cjs/utils/id.d.ts +13 -5
- package/dist/cjs/utils/id.d.ts.map +1 -1
- package/dist/cjs/utils/id.js +24 -10
- package/dist/cjs/utils/id.js.map +1 -1
- package/dist/cjs/utils/index.d.ts +2 -2
- package/dist/cjs/utils/index.d.ts.map +1 -1
- package/dist/cjs/utils/index.js +7 -3
- package/dist/cjs/utils/index.js.map +1 -1
- package/dist/cjs/utils/session.d.ts +44 -5
- package/dist/cjs/utils/session.d.ts.map +1 -1
- package/dist/cjs/utils/session.js +197 -38
- package/dist/cjs/utils/session.js.map +1 -1
- package/dist/constants/index.d.ts +0 -9
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/constants/index.js +3 -9
- package/dist/constants/index.js.map +1 -1
- package/dist/core/Agent.d.ts +119 -153
- package/dist/core/Agent.d.ts.map +1 -1
- package/dist/core/Agent.js +472 -325
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/AutoChainExecutor.d.ts +107 -0
- package/dist/core/AutoChainExecutor.d.ts.map +1 -0
- package/dist/core/AutoChainExecutor.js +293 -0
- package/dist/core/AutoChainExecutor.js.map +1 -0
- package/dist/core/BranchEvaluator.d.ts +54 -0
- package/dist/core/BranchEvaluator.d.ts.map +1 -0
- package/dist/core/BranchEvaluator.js +126 -0
- package/dist/core/BranchEvaluator.js.map +1 -0
- package/dist/core/DirectiveBus.d.ts +88 -0
- package/dist/core/DirectiveBus.d.ts.map +1 -0
- package/dist/core/DirectiveBus.js +192 -0
- package/dist/core/DirectiveBus.js.map +1 -0
- package/dist/core/DirectiveChainTracker.d.ts +49 -0
- package/dist/core/DirectiveChainTracker.d.ts.map +1 -0
- package/dist/core/DirectiveChainTracker.js +117 -0
- package/dist/core/DirectiveChainTracker.js.map +1 -0
- package/dist/core/Flow.d.ts +186 -0
- package/dist/core/Flow.d.ts.map +1 -0
- package/dist/core/Flow.js +546 -0
- package/dist/core/Flow.js.map +1 -0
- package/dist/core/FlowRouter.d.ts +182 -0
- package/dist/core/FlowRouter.d.ts.map +1 -0
- package/dist/core/{RoutingEngine.js → FlowRouter.js} +322 -305
- package/dist/core/FlowRouter.js.map +1 -0
- package/dist/core/PersistenceManager.d.ts +2 -2
- package/dist/core/PersistenceManager.d.ts.map +1 -1
- package/dist/core/PersistenceManager.js +7 -7
- package/dist/core/PersistenceManager.js.map +1 -1
- package/dist/core/PromptComposer.d.ts +21 -8
- package/dist/core/PromptComposer.d.ts.map +1 -1
- package/dist/core/PromptComposer.js +183 -106
- package/dist/core/PromptComposer.js.map +1 -1
- package/dist/core/PromptSectionCache.d.ts +1 -1
- package/dist/core/PromptSectionCache.js +1 -1
- package/dist/core/ResponseEngine.d.ts +18 -8
- package/dist/core/ResponseEngine.d.ts.map +1 -1
- package/dist/core/ResponseEngine.js +38 -36
- package/dist/core/ResponseEngine.js.map +1 -1
- package/dist/core/ResponseModal.d.ts +73 -56
- package/dist/core/ResponseModal.d.ts.map +1 -1
- package/dist/core/ResponseModal.js +1198 -1017
- package/dist/core/ResponseModal.js.map +1 -1
- package/dist/core/ResponsePipeline.d.ts +124 -26
- package/dist/core/ResponsePipeline.d.ts.map +1 -1
- package/dist/core/ResponsePipeline.js +524 -135
- package/dist/core/ResponsePipeline.js.map +1 -1
- package/dist/core/SignalEvaluator.d.ts +86 -0
- package/dist/core/SignalEvaluator.d.ts.map +1 -0
- package/dist/core/SignalEvaluator.js +326 -0
- package/dist/core/SignalEvaluator.js.map +1 -0
- package/dist/core/SignalProcessor.d.ts +152 -0
- package/dist/core/SignalProcessor.d.ts.map +1 -0
- package/dist/core/SignalProcessor.js +555 -0
- package/dist/core/SignalProcessor.js.map +1 -0
- package/dist/core/Step.d.ts +43 -32
- package/dist/core/Step.d.ts.map +1 -1
- package/dist/core/Step.js +220 -126
- package/dist/core/Step.js.map +1 -1
- package/dist/core/StreamingToolExecutor.d.ts +2 -2
- package/dist/core/StreamingToolExecutor.d.ts.map +1 -1
- package/dist/core/StreamingToolExecutor.js.map +1 -1
- package/dist/core/ToolManager.d.ts +44 -13
- package/dist/core/ToolManager.d.ts.map +1 -1
- package/dist/core/ToolManager.js +174 -91
- package/dist/core/ToolManager.js.map +1 -1
- package/dist/core/createAgent.d.ts +35 -0
- package/dist/core/createAgent.d.ts.map +1 -0
- package/dist/core/createAgent.js +36 -0
- package/dist/core/createAgent.js.map +1 -0
- package/dist/core/flow-namespace.d.ts +49 -0
- package/dist/core/flow-namespace.d.ts.map +1 -0
- package/dist/core/flow-namespace.js +168 -0
- package/dist/core/flow-namespace.js.map +1 -0
- package/dist/index.d.ts +11 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -12
- package/dist/index.js.map +1 -1
- package/dist/providers/GeminiProvider.d.ts +3 -3
- package/dist/providers/GeminiProvider.d.ts.map +1 -1
- package/dist/providers/GeminiProvider.js +16 -14
- package/dist/providers/GeminiProvider.js.map +1 -1
- package/dist/types/agent.d.ts +183 -54
- package/dist/types/agent.d.ts.map +1 -1
- package/dist/types/agent.js +0 -6
- package/dist/types/agent.js.map +1 -1
- package/dist/types/ai.d.ts +3 -3
- package/dist/types/ai.d.ts.map +1 -1
- package/dist/types/errors.d.ts +15 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +18 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/flow.d.ts +513 -0
- package/dist/types/flow.d.ts.map +1 -0
- package/dist/types/flow.js +5 -0
- package/dist/types/flow.js.map +1 -0
- package/dist/types/index.d.ts +7 -6
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +4 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/persistence.d.ts +11 -7
- package/dist/types/persistence.d.ts.map +1 -1
- package/dist/types/routing.d.ts +1 -1
- package/dist/types/routing.d.ts.map +1 -1
- package/dist/types/session.d.ts +24 -23
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types/signals.d.ts +248 -0
- package/dist/types/signals.d.ts.map +1 -0
- package/dist/types/signals.js +10 -0
- package/dist/types/signals.js.map +1 -0
- package/dist/types/template.d.ts +2 -8
- package/dist/types/template.d.ts.map +1 -1
- package/dist/types/tool.d.ts +36 -29
- package/dist/types/tool.d.ts.map +1 -1
- package/dist/types/tool.js +1 -1
- package/dist/types/tool.js.map +1 -1
- package/dist/utils/condition.d.ts +7 -1
- package/dist/utils/condition.d.ts.map +1 -1
- package/dist/utils/condition.js.map +1 -1
- package/dist/utils/id.d.ts +13 -5
- package/dist/utils/id.d.ts.map +1 -1
- package/dist/utils/id.js +22 -9
- package/dist/utils/id.js.map +1 -1
- package/dist/utils/index.d.ts +2 -2
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2 -2
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/session.d.ts +44 -5
- package/dist/utils/session.d.ts.map +1 -1
- package/dist/utils/session.js +193 -37
- package/dist/utils/session.js.map +1 -1
- package/docs/README.md +15 -202
- package/docs/concepts/architecture.md +281 -0
- package/docs/concepts/directives.md +400 -0
- package/docs/concepts/pipeline.md +399 -0
- package/docs/guides/branching.md +263 -0
- package/docs/guides/compaction.md +163 -0
- package/docs/guides/conditions.md +167 -0
- package/docs/guides/error-handling.md +176 -0
- package/docs/guides/flow-control.md +409 -0
- package/docs/guides/instructions.md +210 -0
- package/docs/guides/persistence.md +182 -0
- package/docs/guides/streaming.md +137 -0
- package/docs/migration/README.md +15 -0
- package/docs/migration/route-to-flow.md +560 -0
- package/docs/migration/v1-to-v2.md +909 -0
- package/docs/reference/adapters.md +481 -0
- package/docs/reference/branches.md +241 -0
- package/docs/reference/create-agent.md +186 -0
- package/docs/reference/directive.md +243 -0
- package/docs/reference/errors.md +122 -0
- package/docs/reference/flow.md +238 -0
- package/docs/reference/instruction.md +177 -0
- package/docs/reference/pre-directive.md +131 -0
- package/docs/reference/providers.md +227 -0
- package/docs/reference/signals.md +356 -0
- package/docs/reference/step.md +339 -0
- package/docs/reference/tool.md +269 -0
- package/docs/start/01-install.md +81 -0
- package/docs/start/02-first-agent.md +196 -0
- package/docs/start/03-collect-data.md +222 -0
- package/docs/start/04-add-tools.md +276 -0
- package/docs/start/05-go-to-production.md +216 -0
- package/examples/01-quickstart.ts +20 -0
- package/examples/02-data-extraction.ts +90 -0
- package/examples/03-tools.ts +136 -0
- package/examples/04-instructions.ts +100 -0
- package/examples/05-branching.ts +140 -0
- package/examples/06-flow-control.ts +103 -0
- package/examples/07-streaming.ts +69 -0
- package/examples/08-persistence.ts +98 -0
- package/examples/09-signals.ts +144 -0
- package/examples/tsconfig.json +30 -0
- package/package.json +2 -1
- package/src/adapters/MemoryAdapter.ts +3 -3
- package/src/adapters/MongoAdapter.ts +3 -3
- package/src/adapters/OpenSearchAdapter.ts +10 -8
- package/src/adapters/PostgreSQLAdapter.ts +26 -10
- package/src/adapters/PrismaAdapter.ts +6 -6
- package/src/adapters/RedisAdapter.ts +3 -3
- package/src/adapters/SQLiteAdapter.ts +31 -12
- package/src/constants/index.ts +2 -10
- package/src/core/Agent.ts +585 -374
- package/src/core/AutoChainExecutor.ts +440 -0
- package/src/core/BranchEvaluator.ts +167 -0
- package/src/core/DirectiveBus.ts +248 -0
- package/src/core/DirectiveChainTracker.ts +144 -0
- package/src/core/Flow.ts +666 -0
- package/src/core/{RoutingEngine.ts → FlowRouter.ts} +385 -365
- package/src/core/PersistenceManager.ts +8 -8
- package/src/core/PromptComposer.ts +209 -140
- package/src/core/PromptSectionCache.ts +1 -1
- package/src/core/ResponseEngine.ts +61 -46
- package/src/core/ResponseModal.ts +1458 -1241
- package/src/core/ResponsePipeline.ts +675 -173
- package/src/core/SignalEvaluator.ts +420 -0
- package/src/core/SignalProcessor.ts +723 -0
- package/src/core/Step.ts +279 -176
- package/src/core/StreamingToolExecutor.ts +4 -4
- package/src/core/ToolManager.ts +200 -97
- package/src/core/createAgent.ts +40 -0
- package/src/core/flow-namespace.ts +219 -0
- package/src/index.ts +42 -36
- package/src/providers/GeminiProvider.ts +17 -15
- package/src/types/agent.ts +182 -53
- package/src/types/ai.ts +3 -3
- package/src/types/errors.ts +18 -0
- package/src/types/flow.ts +590 -0
- package/src/types/index.ts +43 -16
- package/src/types/persistence.ts +12 -8
- package/src/types/routing.ts +1 -1
- package/src/types/session.ts +26 -23
- package/src/types/signals.ts +321 -0
- package/src/types/template.ts +3 -11
- package/src/types/tool.ts +50 -42
- package/src/utils/condition.ts +13 -4
- package/src/utils/id.ts +27 -9
- package/src/utils/index.ts +6 -2
- package/src/utils/session.ts +238 -42
- package/dist/cjs/core/BatchExecutor.d.ts +0 -359
- package/dist/cjs/core/BatchExecutor.d.ts.map +0 -1
- package/dist/cjs/core/BatchExecutor.js +0 -861
- package/dist/cjs/core/BatchExecutor.js.map +0 -1
- package/dist/cjs/core/BatchPromptBuilder.d.ts +0 -89
- package/dist/cjs/core/BatchPromptBuilder.d.ts.map +0 -1
- package/dist/cjs/core/BatchPromptBuilder.js +0 -223
- package/dist/cjs/core/BatchPromptBuilder.js.map +0 -1
- package/dist/cjs/core/Route.d.ts +0 -180
- package/dist/cjs/core/Route.d.ts.map +0 -1
- package/dist/cjs/core/Route.js +0 -542
- package/dist/cjs/core/Route.js.map +0 -1
- package/dist/cjs/core/RoutingEngine.d.ts +0 -185
- package/dist/cjs/core/RoutingEngine.d.ts.map +0 -1
- package/dist/cjs/core/RoutingEngine.js.map +0 -1
- package/dist/cjs/types/route.d.ts +0 -336
- package/dist/cjs/types/route.d.ts.map +0 -1
- package/dist/cjs/types/route.js.map +0 -1
- package/dist/core/BatchExecutor.d.ts +0 -359
- package/dist/core/BatchExecutor.d.ts.map +0 -1
- package/dist/core/BatchExecutor.js +0 -856
- package/dist/core/BatchExecutor.js.map +0 -1
- package/dist/core/BatchPromptBuilder.d.ts +0 -89
- package/dist/core/BatchPromptBuilder.d.ts.map +0 -1
- package/dist/core/BatchPromptBuilder.js +0 -219
- package/dist/core/BatchPromptBuilder.js.map +0 -1
- package/dist/core/Route.d.ts +0 -180
- package/dist/core/Route.d.ts.map +0 -1
- package/dist/core/Route.js +0 -538
- package/dist/core/Route.js.map +0 -1
- package/dist/core/RoutingEngine.d.ts +0 -185
- package/dist/core/RoutingEngine.d.ts.map +0 -1
- package/dist/core/RoutingEngine.js.map +0 -1
- package/dist/types/route.d.ts +0 -336
- package/dist/types/route.d.ts.map +0 -1
- package/dist/types/route.js +0 -5
- package/dist/types/route.js.map +0 -1
- package/docs/CONTRIBUTING.md +0 -521
- package/docs/api/README.md +0 -3299
- package/docs/api/overview.md +0 -1410
- package/docs/architecture/data-extraction-flow.md +0 -360
- package/docs/architecture/multi-step-execution.md +0 -277
- package/docs/core/agent/README.md +0 -938
- package/docs/core/agent/context-management.md +0 -796
- package/docs/core/agent/rules-and-prohibitions.md +0 -113
- package/docs/core/agent/session-management.md +0 -693
- package/docs/core/ai-integration/prompt-composition.md +0 -355
- package/docs/core/ai-integration/providers.md +0 -515
- package/docs/core/ai-integration/response-processing.md +0 -433
- package/docs/core/conversation-flows/data-collection.md +0 -772
- package/docs/core/conversation-flows/route-dsl.md +0 -509
- package/docs/core/conversation-flows/routes.md +0 -249
- package/docs/core/conversation-flows/step-transitions.md +0 -731
- package/docs/core/conversation-flows/steps.md +0 -268
- package/docs/core/error-handling.md +0 -830
- package/docs/core/persistence/adapters.md +0 -255
- package/docs/core/persistence/session-storage.md +0 -656
- package/docs/core/routing/intelligent-routing.md +0 -470
- package/docs/core/tools/enhanced-tool.md +0 -186
- package/docs/core/tools/streaming-execution.md +0 -161
- package/docs/core/tools/tool-definition.md +0 -970
- package/docs/core/tools/tool-scoping.md +0 -819
- package/docs/guides/advanced-patterns/publishing.md +0 -186
- package/docs/guides/context-compaction.md +0 -96
- package/docs/guides/error-handling-patterns.md +0 -578
- package/docs/guides/getting-started/README.md +0 -795
- package/docs/guides/migration/README.md +0 -101
- package/docs/guides/migration/flexible-routing-conditions.md +0 -375
- package/docs/guides/migration/multi-step-execution.md +0 -393
- package/docs/guides/migration/response-modal-refactor.md +0 -518
- package/docs/guides/prompt-optimization.md +0 -164
- package/examples/advanced-patterns/context-compaction.ts +0 -223
- package/examples/advanced-patterns/knowledge-based-agent.ts +0 -735
- package/examples/advanced-patterns/persistent-onboarding.ts +0 -728
- package/examples/advanced-patterns/route-lifecycle-hooks.ts +0 -556
- package/examples/advanced-patterns/streaming-responses.ts +0 -656
- package/examples/ai-providers/anthropic-integration.ts +0 -388
- package/examples/ai-providers/openai-integration.ts +0 -228
- package/examples/condition-patterns/function-only-conditions.ts +0 -365
- package/examples/condition-patterns/mixed-array-conditions.ts +0 -477
- package/examples/condition-patterns/route-skipif-patterns.ts +0 -468
- package/examples/condition-patterns/step-skipif-patterns.ts +0 -0
- package/examples/condition-patterns/string-only-conditions.ts +0 -296
- package/examples/conversation-flows/completion-transitions.ts +0 -318
- package/examples/core-concepts/basic-agent.ts +0 -503
- package/examples/core-concepts/modern-streaming-api.ts +0 -309
- package/examples/core-concepts/schema-driven-extraction.ts +0 -332
- package/examples/core-concepts/session-management.ts +0 -494
- package/examples/integrations/database-integration.ts +0 -631
- package/examples/integrations/healthcare-integration.ts +0 -595
- package/examples/integrations/search-integration.ts +0 -530
- package/examples/integrations/server-session-management.ts +0 -307
- package/examples/persistence/custom-adapter.ts +0 -526
- package/examples/persistence/database-persistence.ts +0 -583
- package/examples/persistence/memory-sessions.ts +0 -495
- package/examples/persistence/prisma-schema.example.prisma +0 -74
- package/examples/persistence/redis-persistence.ts +0 -488
- package/examples/tools/basic-tools.ts +0 -765
- package/examples/tools/data-enrichment-tools.ts +0 -593
- package/examples/tools/enhanced-tool-metadata.ts +0 -268
- package/examples/tools/streaming-tool-execution.ts +0 -283
- package/src/core/BatchExecutor.ts +0 -1187
- package/src/core/BatchPromptBuilder.ts +0 -299
- package/src/core/Route.ts +0 -678
- package/src/types/route.ts +0 -392
|
@@ -4,22 +4,121 @@
|
|
|
4
4
|
*/
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.ResponsePipeline = void 0;
|
|
7
|
+
exports.hasDirectivePositionField = hasDirectivePositionField;
|
|
7
8
|
const utils_1 = require("../utils");
|
|
9
|
+
const session_1 = require("../utils/session");
|
|
8
10
|
const template_1 = require("../utils/template");
|
|
9
|
-
const
|
|
11
|
+
const Step_1 = require("../core/Step");
|
|
12
|
+
const BranchEvaluator_1 = require("./BranchEvaluator");
|
|
13
|
+
const DirectiveChainTracker_1 = require("./DirectiveChainTracker");
|
|
14
|
+
const DirectiveBus_1 = require("./DirectiveBus");
|
|
15
|
+
/**
|
|
16
|
+
* Position fields on a Directive that represent a navigation decision.
|
|
17
|
+
* When any of these is set, the directive "wins" the turn's position decision
|
|
18
|
+
* and downstream resolution (branches, linear, AI) must not run.
|
|
19
|
+
*/
|
|
20
|
+
const DIRECTIVE_POSITION_FIELDS = ['goTo', 'goToStep', 'complete', 'abort', 'reset'];
|
|
21
|
+
/**
|
|
22
|
+
* Returns `true` if the given directive has at least one position field set.
|
|
23
|
+
* Used as the guard at the directive-bus / branch-evaluation seam:
|
|
24
|
+
* if the bus produced a winner with a position field, `evaluateStepBranches`
|
|
25
|
+
* (and linear/AI selection) must not run.
|
|
26
|
+
*/
|
|
27
|
+
function hasDirectivePositionField(directive) {
|
|
28
|
+
if (!directive)
|
|
29
|
+
return false;
|
|
30
|
+
return DIRECTIVE_POSITION_FIELDS.some((field) => directive[field] !== undefined);
|
|
31
|
+
}
|
|
10
32
|
/**
|
|
11
33
|
* Shared response processing logic between respond() and respondStream() methods
|
|
12
34
|
*/
|
|
13
35
|
class ResponsePipeline {
|
|
14
|
-
constructor(options,
|
|
36
|
+
constructor(options, getFlows, tools, flowRouter, updateContext, updateData, updateCollectedData, toolManager, signalProcessor) {
|
|
15
37
|
this.options = options;
|
|
16
|
-
this.
|
|
38
|
+
this.getFlows = getFlows;
|
|
17
39
|
this.tools = tools;
|
|
18
|
-
this.
|
|
40
|
+
this.flowRouter = flowRouter;
|
|
19
41
|
this.updateContext = updateContext;
|
|
20
42
|
this.updateData = updateData;
|
|
21
43
|
this.updateCollectedData = updateCollectedData;
|
|
22
44
|
this.toolManager = toolManager;
|
|
45
|
+
this.signalProcessor = signalProcessor;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Create a fresh chain tracker for the current turn.
|
|
49
|
+
* Call at the start of each turn; the tracker is discarded at turn end.
|
|
50
|
+
*/
|
|
51
|
+
createChainTracker() {
|
|
52
|
+
const maxChain = this.options.maxDirectiveChain ?? 10;
|
|
53
|
+
this._chainTracker = new DirectiveChainTracker_1.DirectiveChainTracker(maxChain);
|
|
54
|
+
return this._chainTracker;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get the current turn's chain tracker (creates one if none exists).
|
|
58
|
+
*/
|
|
59
|
+
get chainTracker() {
|
|
60
|
+
if (!this._chainTracker) {
|
|
61
|
+
return this.createChainTracker();
|
|
62
|
+
}
|
|
63
|
+
return this._chainTracker;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Create a fresh DirectiveBus for a new turn.
|
|
67
|
+
* The bus collects directives from hooks, tools, and branches during the turn
|
|
68
|
+
* and merges them at phase boundaries via Algorithm 4.
|
|
69
|
+
*/
|
|
70
|
+
createDirectiveBus() {
|
|
71
|
+
return new DirectiveBus_1.DirectiveBus();
|
|
72
|
+
}
|
|
73
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
74
|
+
// Signal pipeline phases
|
|
75
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
76
|
+
/**
|
|
77
|
+
* PRE-SIGNAL PHASE — Evaluates pre/both signals in parallel with routing.
|
|
78
|
+
*
|
|
79
|
+
* Delegates to `signalProcessor.runPreSignalPhase(...)` when configured.
|
|
80
|
+
* When no signal processor is present (zero-cost path), returns a stable
|
|
81
|
+
* empty shape so callers don't need to branch.
|
|
82
|
+
*
|
|
83
|
+
* @requirements 2.1, 2.3, 8.6, 13.3
|
|
84
|
+
*/
|
|
85
|
+
async runPreSignalPhase(session, context, history) {
|
|
86
|
+
if (!this.signalProcessor) {
|
|
87
|
+
return { firings: [], updatedSession: session, mergedDirective: undefined };
|
|
88
|
+
}
|
|
89
|
+
const result = await this.signalProcessor.runPreSignalPhase({ session, history, context });
|
|
90
|
+
return {
|
|
91
|
+
firings: result.firings,
|
|
92
|
+
updatedSession: result.updatedSession,
|
|
93
|
+
mergedDirective: result.mergedDirective,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* POST-SIGNAL PHASE — Evaluates post/both signals after finalize/onComplete.
|
|
98
|
+
*
|
|
99
|
+
* Delegates to `signalProcessor.runPostSignalPhase(...)` when configured.
|
|
100
|
+
* When no signal processor is present, returns a stable empty shape.
|
|
101
|
+
*
|
|
102
|
+
* Post-phase signals see the complete turn result: assistant message in history,
|
|
103
|
+
* collected data, tool results. Position directives from this phase set
|
|
104
|
+
* `session.pendingDirective` (no mid-turn re-entry per D6 decision).
|
|
105
|
+
*
|
|
106
|
+
* Pre-LLM-only fields (`appendPrompt`, `injectTools`, `halt`) are already
|
|
107
|
+
* dropped inside `runPostSignalPhase` per Phase 4.5 — this seam does NOT
|
|
108
|
+
* re-introduce them.
|
|
109
|
+
*
|
|
110
|
+
* @requirements 9.1, 9.2, 9.3, 9.4
|
|
111
|
+
*/
|
|
112
|
+
async runPostSignalPhase(session, context, history) {
|
|
113
|
+
if (!this.signalProcessor) {
|
|
114
|
+
return { firings: [], updatedSession: session, mergedDirective: undefined };
|
|
115
|
+
}
|
|
116
|
+
const result = await this.signalProcessor.runPostSignalPhase({ session, history, context });
|
|
117
|
+
return {
|
|
118
|
+
firings: result.firings,
|
|
119
|
+
updatedSession: result.updatedSession,
|
|
120
|
+
mergedDirective: result.mergedDirective,
|
|
121
|
+
};
|
|
23
122
|
}
|
|
24
123
|
/**
|
|
25
124
|
* Prepare context and session for response generation
|
|
@@ -51,45 +150,136 @@ class ResponsePipeline {
|
|
|
51
150
|
*/
|
|
52
151
|
async handleRoutingAndStepSelection(params) {
|
|
53
152
|
const { session, history, context, signal } = params;
|
|
54
|
-
// PHASE 2: ROUTING + STEP SELECTION - Determine which
|
|
55
|
-
let
|
|
153
|
+
// PHASE 2: ROUTING + STEP SELECTION - Determine which flow and step to use (combined)
|
|
154
|
+
let selectedFlow;
|
|
56
155
|
let responseDirectives;
|
|
57
156
|
let selectedStep;
|
|
58
|
-
let
|
|
59
|
-
let
|
|
157
|
+
let isFlowComplete = false;
|
|
158
|
+
let completedFlows = [];
|
|
60
159
|
let targetSession = session;
|
|
61
|
-
// Get
|
|
62
|
-
const
|
|
63
|
-
// Check for pending
|
|
64
|
-
if (targetSession.
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
160
|
+
// Get flows early since we need them for pending directives
|
|
161
|
+
const flows = this.getFlows();
|
|
162
|
+
// Check for pending directive from previous flow completion or external dispatch
|
|
163
|
+
if (targetSession.pendingDirective) {
|
|
164
|
+
const directive = targetSession.pendingDirective;
|
|
165
|
+
utils_1.logger.debug(`[ResponseHandler] Applying pending directive at start of turn`);
|
|
166
|
+
// Track directive chain depth (Requirement 22.1)
|
|
167
|
+
const tracker = this.chainTracker;
|
|
168
|
+
tracker.record(directive, "pending");
|
|
169
|
+
// If abort (chain breaker), the tracker stops counting; apply normally below
|
|
170
|
+
// Clear pendingDirective before application (unless complete.next chains another)
|
|
171
|
+
let nextDirective = undefined;
|
|
172
|
+
if (directive.complete &&
|
|
173
|
+
typeof directive.complete === 'object' &&
|
|
174
|
+
directive.complete.next) {
|
|
175
|
+
nextDirective = directive.complete.next;
|
|
176
|
+
}
|
|
177
|
+
targetSession = {
|
|
178
|
+
...targetSession,
|
|
179
|
+
pendingDirective: nextDirective,
|
|
180
|
+
};
|
|
181
|
+
// Apply the directive: resolve position field to a flow/step
|
|
182
|
+
if (directive.goTo) {
|
|
183
|
+
const flowTarget = typeof directive.goTo === 'string'
|
|
184
|
+
? directive.goTo
|
|
185
|
+
: directive.goTo.flow;
|
|
186
|
+
if (flowTarget) {
|
|
187
|
+
const targetFlow = flows.find((r) => r.id === flowTarget || r.title === flowTarget);
|
|
188
|
+
if (targetFlow) {
|
|
189
|
+
utils_1.logger.debug(`[ResponseHandler] Pending directive goTo → flow: ${targetFlow.title}`);
|
|
190
|
+
targetSession = (0, session_1.enterFlow)(targetSession, targetFlow.id, targetFlow.title);
|
|
191
|
+
// Merge initial data if available
|
|
192
|
+
if (targetFlow.initialData) {
|
|
193
|
+
targetSession = (0, utils_1.mergeCollected)(targetSession, targetFlow.initialData);
|
|
194
|
+
}
|
|
195
|
+
// Merge directive-carried data if present
|
|
196
|
+
if (typeof directive.goTo === 'object' && directive.goTo.data) {
|
|
197
|
+
targetSession = (0, utils_1.mergeCollected)(targetSession, directive.goTo.data);
|
|
198
|
+
}
|
|
199
|
+
selectedFlow = targetFlow;
|
|
200
|
+
// If goTo specifies a step, enter it
|
|
201
|
+
if (typeof directive.goTo === 'object' && directive.goTo.step) {
|
|
202
|
+
const stepTarget = directive.goTo.step;
|
|
203
|
+
const targetStep = targetFlow.getStep(stepTarget);
|
|
204
|
+
if (targetStep) {
|
|
205
|
+
targetSession = (0, utils_1.enterStep)(targetSession, targetStep.id, targetStep.description);
|
|
206
|
+
selectedStep = targetStep;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
utils_1.logger.warn(`[FlowConfigurationError] Pending directive goTo target not found: flow "${flowTarget}" does not exist. Falling back to normal routing. Fix the goTo reference or remove the pending directive.`);
|
|
212
|
+
}
|
|
77
213
|
}
|
|
78
|
-
selectedRoute = targetRoute;
|
|
79
214
|
}
|
|
80
|
-
else {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
215
|
+
else if (directive.goToStep) {
|
|
216
|
+
const stepTarget = typeof directive.goToStep === 'string'
|
|
217
|
+
? directive.goToStep
|
|
218
|
+
: directive.goToStep.step;
|
|
219
|
+
const flowTarget = typeof directive.goToStep === 'object'
|
|
220
|
+
? directive.goToStep.flow
|
|
221
|
+
: undefined;
|
|
222
|
+
if (flowTarget) {
|
|
223
|
+
const targetFlow = flows.find((r) => r.id === flowTarget || r.title === flowTarget);
|
|
224
|
+
if (targetFlow) {
|
|
225
|
+
targetSession = (0, session_1.enterFlow)(targetSession, targetFlow.id, targetFlow.title);
|
|
226
|
+
selectedFlow = targetFlow;
|
|
227
|
+
const targetStep = targetFlow.getStep(stepTarget);
|
|
228
|
+
if (targetStep) {
|
|
229
|
+
targetSession = (0, utils_1.enterStep)(targetSession, targetStep.id, targetStep.description);
|
|
230
|
+
selectedStep = targetStep;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
else if (targetSession.currentFlow) {
|
|
235
|
+
// Step within current flow
|
|
236
|
+
const currentFlow = flows.find(r => r.id === targetSession.currentFlow?.id);
|
|
237
|
+
if (currentFlow) {
|
|
238
|
+
selectedFlow = currentFlow;
|
|
239
|
+
const targetStep = currentFlow.getStep(stepTarget);
|
|
240
|
+
if (targetStep) {
|
|
241
|
+
targetSession = (0, utils_1.enterStep)(targetSession, targetStep.id, targetStep.description);
|
|
242
|
+
selectedStep = targetStep;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
87
246
|
}
|
|
247
|
+
else if (directive.reset) {
|
|
248
|
+
// Reset current flow
|
|
249
|
+
if (targetSession.currentFlow) {
|
|
250
|
+
const currentFlow = flows.find(r => r.id === targetSession.currentFlow?.id);
|
|
251
|
+
if (currentFlow) {
|
|
252
|
+
const resetStep = typeof directive.reset === 'object' && directive.reset.step
|
|
253
|
+
? directive.reset.step
|
|
254
|
+
: undefined;
|
|
255
|
+
selectedFlow = currentFlow;
|
|
256
|
+
if (resetStep) {
|
|
257
|
+
const targetStep = currentFlow.getStep(resetStep);
|
|
258
|
+
if (targetStep) {
|
|
259
|
+
targetSession = (0, utils_1.enterStep)(targetSession, targetStep.id, targetStep.description);
|
|
260
|
+
selectedStep = targetStep;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
// Reset to initial step
|
|
265
|
+
const initialStep = currentFlow.initialStep;
|
|
266
|
+
targetSession = (0, utils_1.enterStep)(targetSession, initialStep.id, initialStep.description);
|
|
267
|
+
selectedStep = initialStep;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
// For complete/abort, selectedFlow stays undefined → handled downstream
|
|
273
|
+
// Apply state writes from the directive
|
|
274
|
+
if (directive.dataUpdate) {
|
|
275
|
+
targetSession = (0, utils_1.mergeCollected)(targetSession, directive.dataUpdate);
|
|
276
|
+
}
|
|
277
|
+
// Skip FlowRouter.decideFlowAndStep — the directive resolved the position
|
|
88
278
|
}
|
|
89
279
|
// If no pending transition or transition handled, do normal routing
|
|
90
|
-
if (
|
|
91
|
-
const orchestration = await this.
|
|
92
|
-
|
|
280
|
+
if (flows.length > 0 && !selectedFlow) {
|
|
281
|
+
const orchestration = await this.flowRouter.decideFlowAndStep({
|
|
282
|
+
flows: flows,
|
|
93
283
|
session: targetSession,
|
|
94
284
|
history,
|
|
95
285
|
agentOptions: this.options,
|
|
@@ -97,32 +287,60 @@ class ResponsePipeline {
|
|
|
97
287
|
context,
|
|
98
288
|
signal,
|
|
99
289
|
});
|
|
100
|
-
|
|
290
|
+
selectedFlow = orchestration.selectedFlow;
|
|
101
291
|
selectedStep = orchestration.selectedStep;
|
|
102
292
|
responseDirectives = orchestration.responseDirectives;
|
|
103
293
|
targetSession = orchestration.session;
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
// Log if
|
|
107
|
-
if (
|
|
108
|
-
utils_1.logger.debug(`[ResponseHandler]
|
|
294
|
+
isFlowComplete = orchestration.isFlowComplete || false;
|
|
295
|
+
completedFlows = orchestration.completedFlows || [];
|
|
296
|
+
// Log if flow is complete
|
|
297
|
+
if (isFlowComplete) {
|
|
298
|
+
utils_1.logger.debug(`[ResponseHandler] Flow complete: all required data collected or last step reached`);
|
|
109
299
|
}
|
|
110
300
|
}
|
|
111
301
|
return {
|
|
112
|
-
|
|
302
|
+
selectedFlow,
|
|
113
303
|
selectedStep,
|
|
114
304
|
responseDirectives,
|
|
115
305
|
session: targetSession,
|
|
116
|
-
|
|
117
|
-
|
|
306
|
+
isFlowComplete,
|
|
307
|
+
completedFlows,
|
|
118
308
|
};
|
|
119
309
|
}
|
|
120
310
|
/**
|
|
121
311
|
* Determine next step and update session
|
|
122
312
|
*/
|
|
123
313
|
async determineNextStep(params) {
|
|
124
|
-
const {
|
|
125
|
-
if (!
|
|
314
|
+
const { selectedFlow, selectedStep, session, isFlowComplete, busDirective } = params;
|
|
315
|
+
if (!selectedFlow) {
|
|
316
|
+
return { nextStep: undefined, session };
|
|
317
|
+
}
|
|
318
|
+
// ─── GUARD: directive bus winner with a position field preempts branches ───
|
|
319
|
+
// Resolution precedence (design.md): bus > branches > linear > AI.
|
|
320
|
+
// If the bus produced a directive with a position field (goTo, goToStep,
|
|
321
|
+
// complete, abort, reset), that decision wins the turn. Do NOT evaluate
|
|
322
|
+
// branches or linear/AI selection — the caller applies the bus directive.
|
|
323
|
+
if (hasDirectivePositionField(busDirective)) {
|
|
324
|
+
utils_1.logger.debug(`[ResponseHandler] Directive bus winner has position field — skipping branch evaluation and linear/AI selection`);
|
|
325
|
+
return { nextStep: undefined, session };
|
|
326
|
+
}
|
|
327
|
+
// STEP 1 (Algorithm 1): branches win over linear chain AND flow completion.
|
|
328
|
+
// Evaluate branches before checking isFlowComplete — a branch can redirect
|
|
329
|
+
// even from the "last" step (which getCandidateStepsWithConditions marks as complete).
|
|
330
|
+
if (!selectedStep) {
|
|
331
|
+
const currentStep = session.currentFlow?.id === selectedFlow.id && session.currentStep
|
|
332
|
+
? selectedFlow.getStep(session.currentStep.id)
|
|
333
|
+
: undefined;
|
|
334
|
+
if (currentStep?.branches && currentStep.branches.length > 0) {
|
|
335
|
+
const contextToUse = this.getStoredContext();
|
|
336
|
+
const branchResult = await this.evaluateStepBranches(currentStep, selectedFlow, session, contextToUse);
|
|
337
|
+
if (branchResult) {
|
|
338
|
+
return branchResult;
|
|
339
|
+
}
|
|
340
|
+
// undefined → fall through to linear/AI selection or flow completion
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
if (isFlowComplete) {
|
|
126
344
|
return { nextStep: undefined, session };
|
|
127
345
|
}
|
|
128
346
|
let nextStep;
|
|
@@ -131,22 +349,39 @@ class ResponsePipeline {
|
|
|
131
349
|
nextStep = selectedStep;
|
|
132
350
|
}
|
|
133
351
|
else {
|
|
134
|
-
// Determine current step from session if we're already in this
|
|
135
|
-
const currentStep = session.
|
|
136
|
-
?
|
|
352
|
+
// Determine current step from session if we're already in this flow
|
|
353
|
+
const currentStep = session.currentFlow?.id === selectedFlow.id && session.currentStep
|
|
354
|
+
? selectedFlow.getStep(session.currentStep.id)
|
|
137
355
|
: undefined;
|
|
138
356
|
const contextToUse = this.getStoredContext();
|
|
139
|
-
// Get candidate steps based on current position in the
|
|
140
|
-
const candidates = await this.
|
|
357
|
+
// Get candidate steps based on current position in the flow
|
|
358
|
+
const candidates = await this.flowRouter.getCandidateStepsWithConditions(selectedFlow, currentStep, // Pass current step instead of undefined to maintain progression
|
|
141
359
|
(0, template_1.createTemplateContext)({ data: session.data, session, context: contextToUse }));
|
|
142
360
|
if (candidates.length > 0) {
|
|
143
361
|
nextStep = candidates[0].step;
|
|
144
|
-
utils_1.logger.debug(`[ResponseHandler] Using first valid step: ${nextStep.id}${currentStep ? ' (progressing from ' + currentStep.id + ')' : ' for new
|
|
362
|
+
utils_1.logger.debug(`[ResponseHandler] Using first valid step: ${nextStep.id}${currentStep ? ' (progressing from ' + currentStep.id + ')' : ' for new flow'}`);
|
|
145
363
|
}
|
|
146
364
|
else {
|
|
147
365
|
// Fallback to initial step even if it should be skipped
|
|
148
|
-
nextStep =
|
|
149
|
-
utils_1.logger.warn(`[
|
|
366
|
+
nextStep = selectedFlow.initialStep;
|
|
367
|
+
utils_1.logger.warn(`[FlowConfigurationError] No valid steps found in flow "${selectedFlow.title}": all candidates were skipped. Falling back to initial step "${nextStep.id}". Review step skip conditions.`);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
// Before entering the step, check if requires fields are satisfied
|
|
371
|
+
if (nextStep.requires && nextStep.requires.length > 0) {
|
|
372
|
+
const sessionData = session.data || {};
|
|
373
|
+
const missingRequires = nextStep.requires.filter(field => sessionData[String(field)] === undefined);
|
|
374
|
+
if (missingRequires.length > 0) {
|
|
375
|
+
utils_1.logger.debug(`[ResponseHandler] Cannot enter step "${nextStep.id}": missing required fields [${missingRequires.join(', ')}]. Staying at current step.`);
|
|
376
|
+
// Stay at current step - don't enter the next one
|
|
377
|
+
const currentStepId = session.currentStep?.id;
|
|
378
|
+
if (currentStepId && selectedFlow) {
|
|
379
|
+
const currentStepInstance = selectedFlow.getStep(currentStepId);
|
|
380
|
+
if (currentStepInstance) {
|
|
381
|
+
nextStep = currentStepInstance;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
return { nextStep, session };
|
|
150
385
|
}
|
|
151
386
|
}
|
|
152
387
|
// Update session with next step
|
|
@@ -154,11 +389,158 @@ class ResponsePipeline {
|
|
|
154
389
|
utils_1.logger.debug(`[ResponseHandler] Entered step: ${nextStep.id}`);
|
|
155
390
|
return { nextStep, session: updatedSession };
|
|
156
391
|
}
|
|
392
|
+
/**
|
|
393
|
+
* Evaluate branches on a step and resolve the `then` value.
|
|
394
|
+
*
|
|
395
|
+
* Resolution rules (Algorithm 1, STEP 1 + then resolution):
|
|
396
|
+
* - String `then` → look up in current flow's step registry first (local step wins).
|
|
397
|
+
* - Not a local step → look up in agent's flow registry; if found, treat as goTo directive.
|
|
398
|
+
* - Neither → throw FlowConfigurationError.
|
|
399
|
+
* - Directive `then` → apply directly (bypass directive bus merge).
|
|
400
|
+
*
|
|
401
|
+
* Returns the resolved { nextStep, session, flowChanged? } or undefined if no branch matched.
|
|
402
|
+
*/
|
|
403
|
+
async evaluateStepBranches(currentStep, selectedFlow, session, context) {
|
|
404
|
+
const history = session.history ? (0, utils_1.historyToEvents)(session.history) : [];
|
|
405
|
+
// Build the BranchPredicateContext
|
|
406
|
+
const branchCtx = {
|
|
407
|
+
data: session.data,
|
|
408
|
+
context,
|
|
409
|
+
session,
|
|
410
|
+
history,
|
|
411
|
+
};
|
|
412
|
+
// Create the AI condition evaluator
|
|
413
|
+
const aiEvaluator = (0, BranchEvaluator_1.createAiConditionEvaluator)(this.options.provider, history, context);
|
|
414
|
+
const result = await (0, BranchEvaluator_1.evaluateBranches)(currentStep.branches, branchCtx, aiEvaluator);
|
|
415
|
+
if (result === undefined) {
|
|
416
|
+
return undefined; // No branch matched → fall through to linear/AI selection
|
|
417
|
+
}
|
|
418
|
+
// Task 4.3: Directive `then` value — apply directly
|
|
419
|
+
if (typeof result === 'object' && result !== null) {
|
|
420
|
+
const directive = result;
|
|
421
|
+
return this.applyBranchDirective(directive, selectedFlow, session);
|
|
422
|
+
}
|
|
423
|
+
// Task 4.2: String `then` resolution
|
|
424
|
+
// 1. Look up in current flow's step registry first (local step wins)
|
|
425
|
+
const localStep = selectedFlow.getStep(result);
|
|
426
|
+
if (localStep) {
|
|
427
|
+
const updatedSession = (0, utils_1.enterStep)(session, localStep.id, localStep.description);
|
|
428
|
+
utils_1.logger.debug(`[ResponseHandler] Branch resolved to local step: ${localStep.id}`);
|
|
429
|
+
return { nextStep: localStep, session: updatedSession };
|
|
430
|
+
}
|
|
431
|
+
// 2. Look up in agent's flow registry
|
|
432
|
+
const flows = this.getFlows();
|
|
433
|
+
const targetFlow = flows.find(f => f.id === result || f.title === result);
|
|
434
|
+
if (targetFlow) {
|
|
435
|
+
// Treat as applyDirective({ goTo: result }) — enter the target flow
|
|
436
|
+
utils_1.logger.debug(`[ResponseHandler] Branch resolved to flow: ${targetFlow.title}`);
|
|
437
|
+
const updatedSession = (0, session_1.enterFlow)(session, targetFlow.id, targetFlow.title);
|
|
438
|
+
return { nextStep: undefined, session: updatedSession, flowChanged: targetFlow };
|
|
439
|
+
}
|
|
440
|
+
// 3. Neither → throw FlowConfigurationError
|
|
441
|
+
throw new Step_1.FlowConfigurationError(`[FlowConfigurationError] Unresolved branch target: "${result}" does not match any step in flow "${selectedFlow.id}" or any flow in the agent. ` +
|
|
442
|
+
`Source: ${selectedFlow.id}.${currentStep.id}. Fix the branch "then" value to reference a valid step id or flow id/title.`);
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Apply a Directive returned by a branch entry's `then` value.
|
|
446
|
+
* Branches bypass the directive bus — the Directive is the position decision.
|
|
447
|
+
*/
|
|
448
|
+
applyBranchDirective(directive, selectedFlow, session) {
|
|
449
|
+
// Track directive chain depth (Requirement 22.1)
|
|
450
|
+
const tracker = this.chainTracker;
|
|
451
|
+
tracker.record(directive, `branch:${selectedFlow.id}`);
|
|
452
|
+
let updatedSession = session;
|
|
453
|
+
// Apply state writes first
|
|
454
|
+
if (directive.dataUpdate) {
|
|
455
|
+
updatedSession = (0, utils_1.mergeCollected)(updatedSession, directive.dataUpdate);
|
|
456
|
+
}
|
|
457
|
+
// Handle position fields
|
|
458
|
+
if (directive.goToStep) {
|
|
459
|
+
const stepTarget = typeof directive.goToStep === 'string'
|
|
460
|
+
? directive.goToStep
|
|
461
|
+
: directive.goToStep.step;
|
|
462
|
+
const flowTarget = typeof directive.goToStep === 'object'
|
|
463
|
+
? directive.goToStep.flow
|
|
464
|
+
: undefined;
|
|
465
|
+
if (flowTarget) {
|
|
466
|
+
// Cross-flow step reference — enter the target flow first
|
|
467
|
+
const flows = this.getFlows();
|
|
468
|
+
const targetFlow = flows.find(f => f.id === flowTarget || f.title === flowTarget);
|
|
469
|
+
if (targetFlow) {
|
|
470
|
+
updatedSession = (0, session_1.enterFlow)(updatedSession, targetFlow.id, targetFlow.title);
|
|
471
|
+
updatedSession = (0, utils_1.enterStep)(updatedSession, stepTarget);
|
|
472
|
+
// Try to resolve the target step instance for the caller
|
|
473
|
+
const targetStepInstance = targetFlow.getStep(stepTarget);
|
|
474
|
+
utils_1.logger.debug(`[ResponseHandler] Branch directive goToStep → ${flowTarget}.${stepTarget}`);
|
|
475
|
+
return { nextStep: targetStepInstance || undefined, session: updatedSession, flowChanged: targetFlow };
|
|
476
|
+
}
|
|
477
|
+
throw new Step_1.FlowConfigurationError(`[FlowConfigurationError] Branch directive goToStep targets unknown flow: "${flowTarget}" does not match any flow id or title. ` +
|
|
478
|
+
`Fix the goToStep.flow value or use goTo to target a known flow.`);
|
|
479
|
+
}
|
|
480
|
+
// Local step reference
|
|
481
|
+
const targetStep = selectedFlow.getStep(stepTarget);
|
|
482
|
+
if (targetStep) {
|
|
483
|
+
updatedSession = (0, utils_1.enterStep)(updatedSession, targetStep.id, targetStep.description);
|
|
484
|
+
utils_1.logger.debug(`[ResponseHandler] Branch directive goToStep → ${targetStep.id}`);
|
|
485
|
+
return { nextStep: targetStep, session: updatedSession };
|
|
486
|
+
}
|
|
487
|
+
throw new Step_1.FlowConfigurationError(`[FlowConfigurationError] Branch directive goToStep targets unknown step: "${stepTarget}" does not exist in flow "${selectedFlow.id}". ` +
|
|
488
|
+
`Fix the goToStep value to reference a valid step id in the current flow.`);
|
|
489
|
+
}
|
|
490
|
+
if (directive.goTo) {
|
|
491
|
+
const flowTarget = typeof directive.goTo === 'string'
|
|
492
|
+
? directive.goTo
|
|
493
|
+
: directive.goTo.flow ?? directive.goTo.step;
|
|
494
|
+
if (flowTarget) {
|
|
495
|
+
const flows = this.getFlows();
|
|
496
|
+
const targetFlow = flows.find(f => f.id === flowTarget || f.title === flowTarget);
|
|
497
|
+
if (targetFlow) {
|
|
498
|
+
updatedSession = (0, session_1.enterFlow)(updatedSession, targetFlow.id, targetFlow.title);
|
|
499
|
+
// If goTo is an object with a step field, enter that step too
|
|
500
|
+
if (typeof directive.goTo === 'object' && directive.goTo.step) {
|
|
501
|
+
updatedSession = (0, utils_1.enterStep)(updatedSession, directive.goTo.step);
|
|
502
|
+
}
|
|
503
|
+
utils_1.logger.debug(`[ResponseHandler] Branch directive goTo → ${targetFlow.title}`);
|
|
504
|
+
return { nextStep: undefined, session: updatedSession, flowChanged: targetFlow };
|
|
505
|
+
}
|
|
506
|
+
throw new Step_1.FlowConfigurationError(`[FlowConfigurationError] Branch directive goTo targets unknown flow: "${flowTarget}" does not match any flow id or title. ` +
|
|
507
|
+
`Fix the goTo value to reference a valid flow.`);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
if (directive.complete) {
|
|
511
|
+
utils_1.logger.debug(`[ResponseHandler] Branch directive complete`);
|
|
512
|
+
return { nextStep: undefined, session: updatedSession };
|
|
513
|
+
}
|
|
514
|
+
if (directive.abort) {
|
|
515
|
+
utils_1.logger.debug(`[ResponseHandler] Branch directive abort`);
|
|
516
|
+
return { nextStep: undefined, session: updatedSession };
|
|
517
|
+
}
|
|
518
|
+
if (directive.reset) {
|
|
519
|
+
const resetStep = typeof directive.reset === 'object' && directive.reset.step
|
|
520
|
+
? directive.reset.step
|
|
521
|
+
: undefined;
|
|
522
|
+
if (resetStep) {
|
|
523
|
+
const targetStep = selectedFlow.getStep(resetStep);
|
|
524
|
+
if (targetStep) {
|
|
525
|
+
updatedSession = (0, utils_1.enterStep)(updatedSession, targetStep.id, targetStep.description);
|
|
526
|
+
return { nextStep: targetStep, session: updatedSession };
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
// Reset to initial step
|
|
530
|
+
const initialStep = selectedFlow.initialStep;
|
|
531
|
+
updatedSession = (0, utils_1.enterStep)(updatedSession, initialStep.id, initialStep.description);
|
|
532
|
+
utils_1.logger.debug(`[ResponseHandler] Branch directive reset → ${initialStep.id}`);
|
|
533
|
+
return { nextStep: initialStep, session: updatedSession };
|
|
534
|
+
}
|
|
535
|
+
// Directive with only non-position fields (e.g., just dataUpdate/contextUpdate/reply)
|
|
536
|
+
// No position change — fall through to linear selection
|
|
537
|
+
return { nextStep: undefined, session: updatedSession };
|
|
538
|
+
}
|
|
157
539
|
/**
|
|
158
540
|
* Execute tool calls and handle results
|
|
159
541
|
*/
|
|
160
542
|
async executeToolCalls(params) {
|
|
161
|
-
const { toolCalls,
|
|
543
|
+
const { toolCalls, selectedFlow, context, session, history, isStreaming = false, } = params;
|
|
162
544
|
if (toolCalls.length === 0) {
|
|
163
545
|
return { session, toolCalls: undefined };
|
|
164
546
|
}
|
|
@@ -167,9 +549,9 @@ class ResponsePipeline {
|
|
|
167
549
|
const executedToolCalls = [];
|
|
168
550
|
const toolResults = new Map();
|
|
169
551
|
for (const toolCall of toolCalls) {
|
|
170
|
-
const tool = this.findAvailableTool(toolCall.toolName,
|
|
552
|
+
const tool = this.findAvailableTool(toolCall.toolName, selectedFlow);
|
|
171
553
|
if (!tool) {
|
|
172
|
-
utils_1.logger.warn(`[
|
|
554
|
+
utils_1.logger.warn(`[ToolExecutionError] Tool not found: "${toolCall.toolName}" is not registered in any scope (transient, step, flow, or agent). Skipping this tool call. Register the tool or check the tool name.`);
|
|
173
555
|
continue;
|
|
174
556
|
}
|
|
175
557
|
// Use ToolManager for unified tool execution
|
|
@@ -200,7 +582,7 @@ class ResponsePipeline {
|
|
|
200
582
|
updatedSession = await this.updateData(updatedSession, result.dataUpdate);
|
|
201
583
|
utils_1.logger.debug(`[ResponseHandler] ${isStreaming ? "Streaming " : ""}Tool updated collected data:`, result.dataUpdate);
|
|
202
584
|
}
|
|
203
|
-
utils_1.logger.debug(`[ResponseHandler] Executed ${isStreaming ? "streaming " : ""}tool: ${String(tool.id || tool.
|
|
585
|
+
utils_1.logger.debug(`[ResponseHandler] Executed ${isStreaming ? "streaming " : ""}tool: ${String(tool.id || tool.id || 'unknown')} (success: ${result.success})`);
|
|
204
586
|
}
|
|
205
587
|
return {
|
|
206
588
|
session: updatedSession,
|
|
@@ -212,7 +594,7 @@ class ResponsePipeline {
|
|
|
212
594
|
* Execute tool loop for follow-up tool calls
|
|
213
595
|
*/
|
|
214
596
|
async executeToolLoop(params) {
|
|
215
|
-
const { initialToolCalls,
|
|
597
|
+
const { initialToolCalls, selectedFlow, nextStep, responsePrompt, history, context, session, responseSchema, isStreaming = false, } = params;
|
|
216
598
|
const MAX_TOOL_LOOPS = 5;
|
|
217
599
|
let toolLoopCount = 0;
|
|
218
600
|
let currentToolCalls = initialToolCalls;
|
|
@@ -226,7 +608,7 @@ class ResponsePipeline {
|
|
|
226
608
|
// Add tool execution results to history so AI knows what happened
|
|
227
609
|
const toolResultItems = [];
|
|
228
610
|
for (const toolCall of currentToolCalls || []) {
|
|
229
|
-
const tool = this.findAvailableTool(toolCall.toolName,
|
|
611
|
+
const tool = this.findAvailableTool(toolCall.toolName, selectedFlow);
|
|
230
612
|
if (tool) {
|
|
231
613
|
toolResultItems.push({
|
|
232
614
|
role: "assistant",
|
|
@@ -252,7 +634,7 @@ class ResponsePipeline {
|
|
|
252
634
|
prompt: responsePrompt,
|
|
253
635
|
history: updatedHistory,
|
|
254
636
|
context,
|
|
255
|
-
tools: this.collectAvailableTools(
|
|
637
|
+
tools: this.collectAvailableTools(selectedFlow, nextStep),
|
|
256
638
|
parameters: {
|
|
257
639
|
jsonSchema: responseSchema,
|
|
258
640
|
schemaName: isStreaming ? "tool_followup_streaming" : "tool_followup",
|
|
@@ -266,7 +648,7 @@ class ResponsePipeline {
|
|
|
266
648
|
// Execute the follow-up tool calls
|
|
267
649
|
const toolResult = await this.executeToolCalls({
|
|
268
650
|
toolCalls: followUpToolCalls,
|
|
269
|
-
|
|
651
|
+
selectedFlow,
|
|
270
652
|
context,
|
|
271
653
|
session: currentSession,
|
|
272
654
|
history: (0, utils_1.historyToEvents)(updatedHistory),
|
|
@@ -284,7 +666,7 @@ class ResponsePipeline {
|
|
|
284
666
|
}
|
|
285
667
|
}
|
|
286
668
|
if (toolLoopCount >= MAX_TOOL_LOOPS) {
|
|
287
|
-
utils_1.logger.warn(`[
|
|
669
|
+
utils_1.logger.warn(`[ResponseGenerationError] ${isStreaming ? "Streaming t" : "T"}ool loop limit reached: ${toolLoopCount} iterations hit the cap (${MAX_TOOL_LOOPS}). Stopping tool execution. Increase MAX_TOOL_LOOPS or reduce recursive tool calls.`);
|
|
288
670
|
}
|
|
289
671
|
return {
|
|
290
672
|
session: currentSession,
|
|
@@ -335,77 +717,85 @@ class ResponsePipeline {
|
|
|
335
717
|
}
|
|
336
718
|
}
|
|
337
719
|
/**
|
|
338
|
-
* Handle
|
|
720
|
+
* Handle flow completion: pure state transition.
|
|
721
|
+
*
|
|
722
|
+
* Releases the session to idle (`currentFlow`/`currentStep` cleared),
|
|
723
|
+
* marks the active `flowHistory` entry completed, and (when `onComplete`
|
|
724
|
+
* is set) wires `pendingDirective` for the next turn. The framework
|
|
725
|
+
* emits no message of its own at the completion boundary; callers that
|
|
726
|
+
* need closing copy should add a final interactive step.
|
|
339
727
|
*/
|
|
340
|
-
async
|
|
341
|
-
const {
|
|
728
|
+
async handleFlowCompletion(params) {
|
|
729
|
+
const { selectedFlow, session, context } = params;
|
|
342
730
|
// Check for onComplete transition
|
|
343
|
-
const transitionConfig = await
|
|
731
|
+
const transitionConfig = await selectedFlow.evaluateOnComplete({ data: session.data }, context);
|
|
732
|
+
// Release to idle. When the flow is reentrant, scrub its owned
|
|
733
|
+
// fields so a future re-selection doesn't short-circuit on stale data.
|
|
734
|
+
const ownedFields = selectedFlow.reentrant
|
|
735
|
+
? [
|
|
736
|
+
...(selectedFlow.requiredFields ?? []),
|
|
737
|
+
...(selectedFlow.optionalFields ?? []),
|
|
738
|
+
]
|
|
739
|
+
: undefined;
|
|
740
|
+
let updatedSession = (0, utils_1.completeCurrentFlow)(session, {
|
|
741
|
+
clearOwnedFields: ownedFields,
|
|
742
|
+
});
|
|
344
743
|
if (transitionConfig) {
|
|
345
|
-
//
|
|
346
|
-
const
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
: "");
|
|
358
|
-
// Set pending transition in session
|
|
359
|
-
const updatedSession = {
|
|
360
|
-
...session,
|
|
361
|
-
pendingTransition: {
|
|
362
|
-
targetRouteId: targetRoute.id,
|
|
363
|
-
condition: renderedCondition,
|
|
364
|
-
reason: "route_complete",
|
|
744
|
+
// Extract target from directive's goTo field
|
|
745
|
+
const goToTarget = typeof transitionConfig.goTo === 'string'
|
|
746
|
+
? transitionConfig.goTo
|
|
747
|
+
: transitionConfig.goTo?.flow;
|
|
748
|
+
// Find target flow by ID or title
|
|
749
|
+
const targetFlow = goToTarget ? this.getFlows().find((r) => r.id === goToTarget ||
|
|
750
|
+
r.title === goToTarget) : undefined;
|
|
751
|
+
if (targetFlow) {
|
|
752
|
+
updatedSession = {
|
|
753
|
+
...updatedSession,
|
|
754
|
+
pendingDirective: {
|
|
755
|
+
goTo: targetFlow.id,
|
|
365
756
|
},
|
|
366
757
|
};
|
|
367
|
-
utils_1.logger.debug(`[ResponseHandler]
|
|
758
|
+
utils_1.logger.debug(`[ResponseHandler] Flow ${selectedFlow.title} completed with pending directive to: ${targetFlow.title}`);
|
|
368
759
|
return { session: updatedSession, hasTransition: true };
|
|
369
760
|
}
|
|
370
|
-
else {
|
|
371
|
-
utils_1.logger.warn(`[
|
|
761
|
+
else if (goToTarget) {
|
|
762
|
+
utils_1.logger.warn(`[FlowConfigurationError] onComplete target not found: flow "${selectedFlow.title}" completed but onComplete target "${goToTarget}" does not match any flow. ` +
|
|
763
|
+
`Fix the onComplete value to reference an existing flow id/title, or remove onComplete to release the session to idle.`);
|
|
372
764
|
}
|
|
373
765
|
}
|
|
374
|
-
|
|
375
|
-
const updatedSession = (0, utils_1.enterStep)(session, constants_1.END_ROUTE_ID, "Route completed");
|
|
376
|
-
utils_1.logger.debug(`[ResponseHandler] Route ${selectedRoute.title} completed. Entered END_ROUTE step.`);
|
|
766
|
+
utils_1.logger.debug(`[ResponseHandler] Flow ${selectedFlow.title} completed; session released to idle.`);
|
|
377
767
|
return { session: updatedSession, hasTransition: false };
|
|
378
768
|
}
|
|
379
769
|
/**
|
|
380
|
-
* Find an available tool by name for the given
|
|
770
|
+
* Find an available tool by name for the given flow using ToolManager
|
|
381
771
|
* Delegates to ToolManager for unified tool resolution
|
|
382
772
|
*/
|
|
383
|
-
findAvailableTool(toolName,
|
|
773
|
+
findAvailableTool(toolName, flow) {
|
|
384
774
|
// Use ToolManager for unified tool resolution if available
|
|
385
775
|
if (this.toolManager) {
|
|
386
|
-
return this.toolManager.find(toolName, undefined, undefined,
|
|
776
|
+
return this.toolManager.find(toolName, undefined, undefined, flow);
|
|
387
777
|
}
|
|
388
778
|
// Fallback to legacy resolution if ToolManager not available
|
|
389
779
|
utils_1.logger.warn(`[ResponsePipeline] ToolManager not available, using legacy tool resolution for: ${toolName}`);
|
|
390
|
-
// Check
|
|
391
|
-
if (
|
|
392
|
-
const
|
|
780
|
+
// Check flow-level tools first (if flow provided)
|
|
781
|
+
if (flow) {
|
|
782
|
+
const flowTool = flow
|
|
393
783
|
.getTools()
|
|
394
|
-
.find((tool) => tool.id === toolName || tool.
|
|
395
|
-
if (
|
|
396
|
-
return
|
|
784
|
+
.find((tool) => tool.id === toolName || tool.id === toolName);
|
|
785
|
+
if (flowTool)
|
|
786
|
+
return flowTool;
|
|
397
787
|
}
|
|
398
788
|
// Fall back to agent-level tools
|
|
399
|
-
return this.tools.find((tool) => tool.id === toolName || tool.
|
|
789
|
+
return this.tools.find((tool) => tool.id === toolName || tool.id === toolName);
|
|
400
790
|
}
|
|
401
791
|
/**
|
|
402
|
-
* Collect all available tools for the given
|
|
792
|
+
* Collect all available tools for the given flow and step context using ToolManager
|
|
403
793
|
* Delegates to ToolManager for unified tool resolution and deduplication
|
|
404
794
|
*/
|
|
405
|
-
collectAvailableTools(
|
|
795
|
+
collectAvailableTools(flow, step) {
|
|
406
796
|
// Use ToolManager for unified tool collection if available
|
|
407
797
|
if (this.toolManager) {
|
|
408
|
-
const availableTools = this.toolManager.getAvailable(undefined, step,
|
|
798
|
+
const availableTools = this.toolManager.getAvailable(undefined, step, flow);
|
|
409
799
|
return availableTools.map((tool) => ({
|
|
410
800
|
id: tool.id,
|
|
411
801
|
description: tool.description,
|
|
@@ -419,9 +809,9 @@ class ResponsePipeline {
|
|
|
419
809
|
this.tools.forEach((tool) => {
|
|
420
810
|
availableTools.set(tool.id, tool);
|
|
421
811
|
});
|
|
422
|
-
// Add
|
|
423
|
-
if (
|
|
424
|
-
|
|
812
|
+
// Add flow-level tools (these take precedence)
|
|
813
|
+
if (flow) {
|
|
814
|
+
flow.getTools().forEach((tool) => {
|
|
425
815
|
availableTools.set(tool.id, tool);
|
|
426
816
|
});
|
|
427
817
|
}
|
|
@@ -493,34 +883,34 @@ class ResponsePipeline {
|
|
|
493
883
|
return this.currentSession;
|
|
494
884
|
}
|
|
495
885
|
/**
|
|
496
|
-
* Handle cross-
|
|
497
|
-
* This method evaluates all
|
|
886
|
+
* Handle cross-flow completion evaluation and notifications
|
|
887
|
+
* This method evaluates all flows for completion and can trigger completion handlers
|
|
498
888
|
*/
|
|
499
|
-
async
|
|
500
|
-
const {
|
|
501
|
-
// Evaluate all
|
|
502
|
-
const
|
|
889
|
+
async handleCrossFlowCompletion(params) {
|
|
890
|
+
const { flows, session, context } = params;
|
|
891
|
+
// Evaluate all flows for completion
|
|
892
|
+
const completedFlows = [];
|
|
503
893
|
const pendingTransitions = [];
|
|
504
|
-
for (const
|
|
505
|
-
if (
|
|
506
|
-
|
|
894
|
+
for (const flow of flows) {
|
|
895
|
+
if (flow.isComplete(session.data || {})) {
|
|
896
|
+
completedFlows.push(flow);
|
|
507
897
|
// Check for onComplete transitions
|
|
508
|
-
const transitionConfig = await
|
|
898
|
+
const transitionConfig = await flow.evaluateOnComplete({ data: session.data }, context);
|
|
509
899
|
if (transitionConfig) {
|
|
510
|
-
pendingTransitions.push({
|
|
900
|
+
pendingTransitions.push({ flow, transitionConfig });
|
|
511
901
|
}
|
|
512
|
-
utils_1.logger.debug(`[ResponsePipeline]
|
|
513
|
-
`(${Math.round(
|
|
902
|
+
utils_1.logger.debug(`[ResponsePipeline] Flow completed: ${flow.title} ` +
|
|
903
|
+
`(${Math.round(flow.getCompletionProgress(session.data || {}) * 100)}%)`);
|
|
514
904
|
}
|
|
515
905
|
}
|
|
516
|
-
// Log completion status for all
|
|
517
|
-
if (
|
|
518
|
-
utils_1.logger.debug(`[ResponsePipeline] Cross-
|
|
519
|
-
`${
|
|
906
|
+
// Log completion status for all flows
|
|
907
|
+
if (completedFlows.length > 0) {
|
|
908
|
+
utils_1.logger.debug(`[ResponsePipeline] Cross-flow completion evaluation: ` +
|
|
909
|
+
`${completedFlows.length}/${flows.length} flows complete`);
|
|
520
910
|
}
|
|
521
911
|
return {
|
|
522
912
|
session,
|
|
523
|
-
|
|
913
|
+
completedFlows,
|
|
524
914
|
pendingTransitions,
|
|
525
915
|
};
|
|
526
916
|
}
|
|
@@ -529,23 +919,23 @@ class ResponsePipeline {
|
|
|
529
919
|
* This method ensures that data updates are properly validated and propagated
|
|
530
920
|
*/
|
|
531
921
|
async updateDataFlow(params) {
|
|
532
|
-
const { session, dataUpdate,
|
|
922
|
+
const { session, dataUpdate, flows } = params;
|
|
533
923
|
// Update session data
|
|
534
924
|
const updatedSession = await this.updateData(session, dataUpdate);
|
|
535
925
|
// Update agent-level data if handler is available
|
|
536
926
|
if (this.updateCollectedData) {
|
|
537
927
|
await this.updateCollectedData(dataUpdate);
|
|
538
928
|
}
|
|
539
|
-
// Evaluate
|
|
540
|
-
const completionResults = await this.
|
|
541
|
-
|
|
929
|
+
// Evaluate flow completions after data update
|
|
930
|
+
const completionResults = await this.handleCrossFlowCompletion({
|
|
931
|
+
flows,
|
|
542
932
|
session: updatedSession,
|
|
543
933
|
context: this.context,
|
|
544
934
|
history: [],
|
|
545
935
|
});
|
|
546
|
-
// Log any newly completed
|
|
547
|
-
if (completionResults.
|
|
548
|
-
utils_1.logger.debug(`[ResponsePipeline] Data update resulted in ${completionResults.
|
|
936
|
+
// Log any newly completed flows
|
|
937
|
+
if (completionResults.completedFlows.length > 0) {
|
|
938
|
+
utils_1.logger.debug(`[ResponsePipeline] Data update resulted in ${completionResults.completedFlows.length} completed flows`);
|
|
549
939
|
}
|
|
550
940
|
return completionResults.session;
|
|
551
941
|
}
|