@falai/agent 2.6.1 → 3.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 +2 -2
- package/dist/adapters/MemoryAdapter.d.ts +1 -1
- package/dist/adapters/MemoryAdapter.d.ts.map +1 -1
- package/dist/adapters/MemoryAdapter.js +32 -36
- package/dist/adapters/MemoryAdapter.js.map +1 -1
- package/dist/adapters/MongoAdapter.d.ts +1 -1
- package/dist/adapters/MongoAdapter.d.ts.map +1 -1
- package/dist/adapters/MongoAdapter.js +2 -2
- package/dist/adapters/MongoAdapter.js.map +1 -1
- package/dist/adapters/OpenSearchAdapter.d.ts +1 -1
- package/dist/adapters/OpenSearchAdapter.d.ts.map +1 -1
- package/dist/adapters/OpenSearchAdapter.js +3 -3
- package/dist/adapters/OpenSearchAdapter.js.map +1 -1
- package/dist/adapters/PostgreSQLAdapter.d.ts +1 -1
- package/dist/adapters/PostgreSQLAdapter.d.ts.map +1 -1
- package/dist/adapters/PostgreSQLAdapter.js +18 -13
- package/dist/adapters/PostgreSQLAdapter.js.map +1 -1
- package/dist/adapters/PrismaAdapter.d.ts +1 -1
- package/dist/adapters/PrismaAdapter.d.ts.map +1 -1
- package/dist/adapters/PrismaAdapter.js +3 -3
- package/dist/adapters/PrismaAdapter.js.map +1 -1
- package/dist/adapters/RedisAdapter.d.ts +2 -1
- package/dist/adapters/RedisAdapter.d.ts.map +1 -1
- package/dist/adapters/RedisAdapter.js +77 -27
- package/dist/adapters/RedisAdapter.js.map +1 -1
- package/dist/adapters/SQLiteAdapter.d.ts +1 -1
- package/dist/adapters/SQLiteAdapter.d.ts.map +1 -1
- package/dist/adapters/SQLiteAdapter.js +9 -31
- package/dist/adapters/SQLiteAdapter.js.map +1 -1
- package/dist/adapters/index.d.ts +13 -13
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +7 -7
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/sessionRow.d.ts +22 -0
- package/dist/adapters/sessionRow.d.ts.map +1 -0
- package/dist/adapters/sessionRow.js +48 -0
- package/dist/adapters/sessionRow.js.map +1 -0
- package/dist/cjs/adapters/MemoryAdapter.d.ts +1 -1
- package/dist/cjs/adapters/MemoryAdapter.d.ts.map +1 -1
- package/dist/cjs/adapters/MemoryAdapter.js +39 -43
- package/dist/cjs/adapters/MemoryAdapter.js.map +1 -1
- package/dist/cjs/adapters/MongoAdapter.d.ts +1 -1
- package/dist/cjs/adapters/MongoAdapter.d.ts.map +1 -1
- package/dist/cjs/adapters/MongoAdapter.js +4 -4
- package/dist/cjs/adapters/MongoAdapter.js.map +1 -1
- package/dist/cjs/adapters/OpenSearchAdapter.d.ts +1 -1
- package/dist/cjs/adapters/OpenSearchAdapter.d.ts.map +1 -1
- package/dist/cjs/adapters/OpenSearchAdapter.js +6 -6
- package/dist/cjs/adapters/OpenSearchAdapter.js.map +1 -1
- package/dist/cjs/adapters/PostgreSQLAdapter.d.ts +1 -1
- package/dist/cjs/adapters/PostgreSQLAdapter.d.ts.map +1 -1
- package/dist/cjs/adapters/PostgreSQLAdapter.js +20 -15
- package/dist/cjs/adapters/PostgreSQLAdapter.js.map +1 -1
- package/dist/cjs/adapters/PrismaAdapter.d.ts +1 -1
- package/dist/cjs/adapters/PrismaAdapter.d.ts.map +1 -1
- package/dist/cjs/adapters/PrismaAdapter.js +7 -7
- package/dist/cjs/adapters/PrismaAdapter.js.map +1 -1
- package/dist/cjs/adapters/RedisAdapter.d.ts +2 -1
- package/dist/cjs/adapters/RedisAdapter.d.ts.map +1 -1
- package/dist/cjs/adapters/RedisAdapter.js +81 -31
- package/dist/cjs/adapters/RedisAdapter.js.map +1 -1
- package/dist/cjs/adapters/SQLiteAdapter.d.ts +1 -1
- package/dist/cjs/adapters/SQLiteAdapter.d.ts.map +1 -1
- package/dist/cjs/adapters/SQLiteAdapter.js +11 -33
- package/dist/cjs/adapters/SQLiteAdapter.js.map +1 -1
- package/dist/cjs/adapters/index.d.ts +13 -13
- package/dist/cjs/adapters/index.d.ts.map +1 -1
- package/dist/cjs/adapters/index.js +14 -14
- package/dist/cjs/adapters/index.js.map +1 -1
- package/dist/cjs/adapters/sessionRow.d.ts +22 -0
- package/dist/cjs/adapters/sessionRow.d.ts.map +1 -0
- package/dist/cjs/adapters/sessionRow.js +52 -0
- package/dist/cjs/adapters/sessionRow.js.map +1 -0
- package/dist/cjs/core/Agent.d.ts +19 -11
- package/dist/cjs/core/Agent.d.ts.map +1 -1
- package/dist/cjs/core/Agent.js +102 -64
- package/dist/cjs/core/Agent.js.map +1 -1
- package/dist/cjs/core/AutoChainExecutor.d.ts +12 -22
- package/dist/cjs/core/AutoChainExecutor.d.ts.map +1 -1
- package/dist/cjs/core/AutoChainExecutor.js +46 -49
- package/dist/cjs/core/AutoChainExecutor.js.map +1 -1
- package/dist/cjs/core/BranchEvaluator.d.ts +4 -4
- package/dist/cjs/core/BranchEvaluator.d.ts.map +1 -1
- package/dist/cjs/core/BranchEvaluator.js +6 -6
- package/dist/cjs/core/BranchEvaluator.js.map +1 -1
- package/dist/cjs/core/CompactionEngine.d.ts +16 -3
- package/dist/cjs/core/CompactionEngine.d.ts.map +1 -1
- package/dist/cjs/core/CompactionEngine.js +30 -6
- package/dist/cjs/core/CompactionEngine.js.map +1 -1
- package/dist/cjs/core/DirectiveChainTracker.d.ts +1 -1
- package/dist/cjs/core/DirectiveChainTracker.d.ts.map +1 -1
- package/dist/cjs/core/DirectiveChainTracker.js +5 -5
- package/dist/cjs/core/DirectiveChainTracker.js.map +1 -1
- package/dist/cjs/core/Events.d.ts +1 -1
- package/dist/cjs/core/Events.d.ts.map +1 -1
- package/dist/cjs/core/Events.js +15 -15
- package/dist/cjs/core/Events.js.map +1 -1
- package/dist/cjs/core/Flow.d.ts +4 -4
- package/dist/cjs/core/Flow.d.ts.map +1 -1
- package/dist/cjs/core/Flow.js +15 -15
- package/dist/cjs/core/Flow.js.map +1 -1
- package/dist/cjs/core/FlowRouter.d.ts +4 -4
- package/dist/cjs/core/FlowRouter.d.ts.map +1 -1
- package/dist/cjs/core/FlowRouter.js +92 -70
- package/dist/cjs/core/FlowRouter.js.map +1 -1
- package/dist/cjs/core/PersistenceManager.d.ts +1 -1
- package/dist/cjs/core/PersistenceManager.d.ts.map +1 -1
- package/dist/cjs/core/PersistenceManager.js +10 -10
- package/dist/cjs/core/PersistenceManager.js.map +1 -1
- package/dist/cjs/core/PromptComposer.d.ts +4 -4
- package/dist/cjs/core/PromptComposer.d.ts.map +1 -1
- package/dist/cjs/core/PromptComposer.js +13 -13
- package/dist/cjs/core/PromptComposer.js.map +1 -1
- package/dist/cjs/core/PromptSectionCache.d.ts +2 -2
- package/dist/cjs/core/PromptSectionCache.d.ts.map +1 -1
- package/dist/cjs/core/ResponseEngine.d.ts +4 -4
- package/dist/cjs/core/ResponseEngine.d.ts.map +1 -1
- package/dist/cjs/core/ResponseEngine.js +7 -7
- package/dist/cjs/core/ResponseEngine.js.map +1 -1
- package/dist/cjs/core/ResponseGenerationError.d.ts.map +1 -1
- package/dist/cjs/core/ResponseGenerationError.js +3 -5
- package/dist/cjs/core/ResponseGenerationError.js.map +1 -1
- package/dist/cjs/core/ResponseModal.d.ts +39 -10
- package/dist/cjs/core/ResponseModal.d.ts.map +1 -1
- package/dist/cjs/core/ResponseModal.js +195 -72
- package/dist/cjs/core/ResponseModal.js.map +1 -1
- package/dist/cjs/core/ResponsePipeline.d.ts +50 -12
- package/dist/cjs/core/ResponsePipeline.d.ts.map +1 -1
- package/dist/cjs/core/ResponsePipeline.js +301 -158
- package/dist/cjs/core/ResponsePipeline.js.map +1 -1
- package/dist/cjs/core/SessionFinalizer.d.ts +4 -4
- package/dist/cjs/core/SessionFinalizer.d.ts.map +1 -1
- package/dist/cjs/core/SessionFinalizer.js +36 -9
- package/dist/cjs/core/SessionFinalizer.js.map +1 -1
- package/dist/cjs/core/SessionManager.d.ts +15 -6
- package/dist/cjs/core/SessionManager.d.ts.map +1 -1
- package/dist/cjs/core/SessionManager.js +49 -22
- package/dist/cjs/core/SessionManager.js.map +1 -1
- package/dist/cjs/core/SignalCoordinator.d.ts +5 -5
- package/dist/cjs/core/SignalCoordinator.d.ts.map +1 -1
- package/dist/cjs/core/SignalCoordinator.js +12 -12
- package/dist/cjs/core/SignalCoordinator.js.map +1 -1
- package/dist/cjs/core/SignalEvaluator.d.ts +4 -4
- package/dist/cjs/core/SignalEvaluator.d.ts.map +1 -1
- package/dist/cjs/core/SignalEvaluator.js +6 -6
- package/dist/cjs/core/SignalEvaluator.js.map +1 -1
- package/dist/cjs/core/SignalProcessor.d.ts +6 -6
- package/dist/cjs/core/SignalProcessor.d.ts.map +1 -1
- package/dist/cjs/core/SignalProcessor.js +17 -89
- package/dist/cjs/core/SignalProcessor.js.map +1 -1
- package/dist/cjs/core/Step.d.ts +5 -5
- package/dist/cjs/core/Step.d.ts.map +1 -1
- package/dist/cjs/core/Step.js +65 -17
- package/dist/cjs/core/Step.js.map +1 -1
- package/dist/cjs/core/StepLifecycle.d.ts +18 -8
- package/dist/cjs/core/StepLifecycle.d.ts.map +1 -1
- package/dist/cjs/core/StepLifecycle.js +103 -20
- package/dist/cjs/core/StepLifecycle.js.map +1 -1
- package/dist/cjs/core/StreamingToolExecutor.d.ts +1 -1
- package/dist/cjs/core/StreamingToolExecutor.d.ts.map +1 -1
- package/dist/cjs/core/StreamingToolExecutor.js +30 -6
- package/dist/cjs/core/StreamingToolExecutor.js.map +1 -1
- package/dist/cjs/core/ToolLoopExecutor.d.ts +8 -4
- package/dist/cjs/core/ToolLoopExecutor.d.ts.map +1 -1
- package/dist/cjs/core/ToolLoopExecutor.js +189 -97
- package/dist/cjs/core/ToolLoopExecutor.js.map +1 -1
- package/dist/cjs/core/ToolManager.d.ts +6 -6
- package/dist/cjs/core/ToolManager.d.ts.map +1 -1
- package/dist/cjs/core/ToolManager.js +102 -79
- package/dist/cjs/core/ToolManager.js.map +1 -1
- package/dist/cjs/core/createAgent.d.ts +2 -2
- package/dist/cjs/core/createAgent.d.ts.map +1 -1
- package/dist/cjs/core/createAgent.js +2 -2
- package/dist/cjs/core/createAgent.js.map +1 -1
- package/dist/cjs/core/flow-namespace.d.ts +16 -1
- package/dist/cjs/core/flow-namespace.d.ts.map +1 -1
- package/dist/cjs/core/flow-namespace.js +26 -4
- package/dist/cjs/core/flow-namespace.js.map +1 -1
- package/dist/cjs/core/toolGates.d.ts +1 -1
- package/dist/cjs/core/toolGates.d.ts.map +1 -1
- package/dist/cjs/core/toolGates.js +3 -3
- package/dist/cjs/core/toolGates.js.map +1 -1
- package/dist/cjs/index.d.ts +50 -45
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +96 -88
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/providers/AnthropicProvider.d.ts +25 -35
- package/dist/cjs/providers/AnthropicProvider.d.ts.map +1 -1
- package/dist/cjs/providers/AnthropicProvider.js +30 -426
- package/dist/cjs/providers/AnthropicProvider.js.map +1 -1
- package/dist/cjs/providers/DeepSeekProvider.d.ts +13 -34
- package/dist/cjs/providers/DeepSeekProvider.d.ts.map +1 -1
- package/dist/cjs/providers/DeepSeekProvider.js +17 -51
- package/dist/cjs/providers/DeepSeekProvider.js.map +1 -1
- package/dist/cjs/providers/GeminiProvider.d.ts +22 -75
- package/dist/cjs/providers/GeminiProvider.d.ts.map +1 -1
- package/dist/cjs/providers/GeminiProvider.js +32 -558
- package/dist/cjs/providers/GeminiProvider.js.map +1 -1
- package/dist/cjs/providers/GenericOpenAICompatibleProvider.d.ts +9 -10
- package/dist/cjs/providers/GenericOpenAICompatibleProvider.d.ts.map +1 -1
- package/dist/cjs/providers/GenericOpenAICompatibleProvider.js +14 -20
- package/dist/cjs/providers/GenericOpenAICompatibleProvider.js.map +1 -1
- package/dist/cjs/providers/OpenAICompatibleProvider.d.ts +26 -135
- package/dist/cjs/providers/OpenAICompatibleProvider.d.ts.map +1 -1
- package/dist/cjs/providers/OpenAICompatibleProvider.js +40 -496
- package/dist/cjs/providers/OpenAICompatibleProvider.js.map +1 -1
- package/dist/cjs/providers/OpenAIProvider.d.ts +14 -20
- package/dist/cjs/providers/OpenAIProvider.d.ts.map +1 -1
- package/dist/cjs/providers/OpenAIProvider.js +21 -28
- package/dist/cjs/providers/OpenAIProvider.js.map +1 -1
- package/dist/cjs/providers/OpenRouterProvider.d.ts +20 -24
- package/dist/cjs/providers/OpenRouterProvider.d.ts.map +1 -1
- package/dist/cjs/providers/OpenRouterProvider.js +22 -38
- package/dist/cjs/providers/OpenRouterProvider.js.map +1 -1
- package/dist/cjs/providers/ProviderAdapter.d.ts +94 -0
- package/dist/cjs/providers/ProviderAdapter.d.ts.map +1 -0
- package/dist/cjs/providers/ProviderAdapter.js +257 -0
- package/dist/cjs/providers/ProviderAdapter.js.map +1 -0
- package/dist/cjs/providers/index.d.ts +21 -18
- package/dist/cjs/providers/index.d.ts.map +1 -1
- package/dist/cjs/providers/index.js +23 -21
- package/dist/cjs/providers/index.js.map +1 -1
- package/dist/cjs/types/agent.d.ts +37 -11
- package/dist/cjs/types/agent.d.ts.map +1 -1
- package/dist/cjs/types/ai.d.ts +11 -21
- package/dist/cjs/types/ai.d.ts.map +1 -1
- package/dist/cjs/types/compaction.d.ts +2 -2
- package/dist/cjs/types/compaction.d.ts.map +1 -1
- package/dist/cjs/types/errors.d.ts +16 -20
- package/dist/cjs/types/errors.d.ts.map +1 -1
- package/dist/cjs/types/errors.js +17 -18
- package/dist/cjs/types/errors.js.map +1 -1
- package/dist/cjs/types/flow.d.ts +56 -39
- package/dist/cjs/types/flow.d.ts.map +1 -1
- package/dist/cjs/types/history.d.ts +1 -1
- package/dist/cjs/types/history.d.ts.map +1 -1
- package/dist/cjs/types/index.d.ts +17 -17
- package/dist/cjs/types/index.d.ts.map +1 -1
- package/dist/cjs/types/index.js +14 -14
- package/dist/cjs/types/index.js.map +1 -1
- package/dist/cjs/types/persistence.d.ts +2 -2
- package/dist/cjs/types/persistence.d.ts.map +1 -1
- package/dist/cjs/types/session.d.ts +4 -4
- package/dist/cjs/types/session.d.ts.map +1 -1
- package/dist/cjs/types/signals.d.ts +3 -3
- package/dist/cjs/types/signals.d.ts.map +1 -1
- package/dist/cjs/types/template.d.ts +2 -2
- package/dist/cjs/types/template.d.ts.map +1 -1
- package/dist/cjs/types/tool.d.ts +4 -2
- package/dist/cjs/types/tool.d.ts.map +1 -1
- package/dist/cjs/types/tool.js.map +1 -1
- package/dist/cjs/utils/condition.d.ts +1 -1
- package/dist/cjs/utils/condition.d.ts.map +1 -1
- package/dist/cjs/utils/condition.js +6 -6
- package/dist/cjs/utils/condition.js.map +1 -1
- package/dist/cjs/utils/event.d.ts +1 -1
- package/dist/cjs/utils/event.d.ts.map +1 -1
- package/dist/cjs/utils/event.js +2 -2
- package/dist/cjs/utils/event.js.map +1 -1
- package/dist/cjs/utils/history.d.ts +2 -2
- package/dist/cjs/utils/history.d.ts.map +1 -1
- package/dist/cjs/utils/history.js +15 -15
- package/dist/cjs/utils/history.js.map +1 -1
- package/dist/cjs/utils/index.d.ts +11 -13
- package/dist/cjs/utils/index.d.ts.map +1 -1
- package/dist/cjs/utils/index.js +57 -58
- package/dist/cjs/utils/index.js.map +1 -1
- package/dist/cjs/utils/serialize.d.ts +17 -0
- package/dist/cjs/utils/serialize.d.ts.map +1 -1
- package/dist/cjs/utils/serialize.js +33 -0
- package/dist/cjs/utils/serialize.js.map +1 -1
- package/dist/cjs/utils/session.d.ts +23 -3
- package/dist/cjs/utils/session.d.ts.map +1 -1
- package/dist/cjs/utils/session.js +40 -8
- package/dist/cjs/utils/session.js.map +1 -1
- package/dist/cjs/utils/template.d.ts +3 -3
- package/dist/cjs/utils/template.d.ts.map +1 -1
- package/dist/cjs/utils/template.js +5 -5
- package/dist/cjs/utils/template.js.map +1 -1
- package/dist/constants/index.d.ts +1 -0
- package/dist/constants/index.js +1 -1
- package/dist/core/Agent.d.ts +19 -11
- package/dist/core/Agent.d.ts.map +1 -1
- package/dist/core/Agent.js +53 -15
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/AutoChainExecutor.d.ts +12 -22
- package/dist/core/AutoChainExecutor.d.ts.map +1 -1
- package/dist/core/AutoChainExecutor.js +27 -30
- package/dist/core/AutoChainExecutor.js.map +1 -1
- package/dist/core/BranchEvaluator.d.ts +4 -4
- package/dist/core/BranchEvaluator.d.ts.map +1 -1
- package/dist/core/BranchEvaluator.js +2 -2
- package/dist/core/BranchEvaluator.js.map +1 -1
- package/dist/core/CompactionEngine.d.ts +16 -3
- package/dist/core/CompactionEngine.d.ts.map +1 -1
- package/dist/core/CompactionEngine.js +30 -6
- package/dist/core/CompactionEngine.js.map +1 -1
- package/dist/core/DirectiveChainTracker.d.ts +1 -1
- package/dist/core/DirectiveChainTracker.d.ts.map +1 -1
- package/dist/core/DirectiveChainTracker.js +2 -2
- package/dist/core/DirectiveChainTracker.js.map +1 -1
- package/dist/core/Events.d.ts +1 -1
- package/dist/core/Events.d.ts.map +1 -1
- package/dist/core/Events.js +1 -1
- package/dist/core/Events.js.map +1 -1
- package/dist/core/Flow.d.ts +4 -4
- package/dist/core/Flow.d.ts.map +1 -1
- package/dist/core/Flow.js +3 -3
- package/dist/core/Flow.js.map +1 -1
- package/dist/core/FlowRouter.d.ts +4 -4
- package/dist/core/FlowRouter.d.ts.map +1 -1
- package/dist/core/FlowRouter.js +36 -14
- package/dist/core/FlowRouter.js.map +1 -1
- package/dist/core/PersistenceManager.d.ts +1 -1
- package/dist/core/PersistenceManager.d.ts.map +1 -1
- package/dist/core/PersistenceManager.js +3 -3
- package/dist/core/PersistenceManager.js.map +1 -1
- package/dist/core/PromptComposer.d.ts +4 -4
- package/dist/core/PromptComposer.d.ts.map +1 -1
- package/dist/core/PromptComposer.js +3 -3
- package/dist/core/PromptComposer.js.map +1 -1
- package/dist/core/PromptSectionCache.d.ts +2 -2
- package/dist/core/PromptSectionCache.d.ts.map +1 -1
- package/dist/core/ResponseEngine.d.ts +4 -4
- package/dist/core/ResponseEngine.d.ts.map +1 -1
- package/dist/core/ResponseEngine.js +2 -2
- package/dist/core/ResponseEngine.js.map +1 -1
- package/dist/core/ResponseGenerationError.d.ts.map +1 -1
- package/dist/core/ResponseGenerationError.js +3 -5
- package/dist/core/ResponseGenerationError.js.map +1 -1
- package/dist/core/ResponseModal.d.ts +39 -10
- package/dist/core/ResponseModal.d.ts.map +1 -1
- package/dist/core/ResponseModal.js +152 -29
- package/dist/core/ResponseModal.js.map +1 -1
- package/dist/core/ResponsePipeline.d.ts +50 -12
- package/dist/core/ResponsePipeline.d.ts.map +1 -1
- package/dist/core/ResponsePipeline.js +232 -89
- package/dist/core/ResponsePipeline.js.map +1 -1
- package/dist/core/SessionFinalizer.d.ts +4 -4
- package/dist/core/SessionFinalizer.d.ts.map +1 -1
- package/dist/core/SessionFinalizer.js +32 -5
- package/dist/core/SessionFinalizer.js.map +1 -1
- package/dist/core/SessionManager.d.ts +15 -6
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js +46 -19
- package/dist/core/SessionManager.js.map +1 -1
- package/dist/core/SignalCoordinator.d.ts +5 -5
- package/dist/core/SignalCoordinator.d.ts.map +1 -1
- package/dist/core/SignalCoordinator.js +2 -2
- package/dist/core/SignalCoordinator.js.map +1 -1
- package/dist/core/SignalEvaluator.d.ts +4 -4
- package/dist/core/SignalEvaluator.d.ts.map +1 -1
- package/dist/core/SignalEvaluator.js +2 -2
- package/dist/core/SignalEvaluator.js.map +1 -1
- package/dist/core/SignalProcessor.d.ts +6 -6
- package/dist/core/SignalProcessor.d.ts.map +1 -1
- package/dist/core/SignalProcessor.js +7 -79
- package/dist/core/SignalProcessor.js.map +1 -1
- package/dist/core/Step.d.ts +5 -5
- package/dist/core/Step.d.ts.map +1 -1
- package/dist/core/Step.js +53 -5
- package/dist/core/Step.js.map +1 -1
- package/dist/core/StepLifecycle.d.ts +18 -8
- package/dist/core/StepLifecycle.d.ts.map +1 -1
- package/dist/core/StepLifecycle.js +98 -15
- package/dist/core/StepLifecycle.js.map +1 -1
- package/dist/core/StreamingToolExecutor.d.ts +1 -1
- package/dist/core/StreamingToolExecutor.d.ts.map +1 -1
- package/dist/core/StreamingToolExecutor.js +29 -5
- package/dist/core/StreamingToolExecutor.js.map +1 -1
- package/dist/core/ToolLoopExecutor.d.ts +8 -4
- package/dist/core/ToolLoopExecutor.d.ts.map +1 -1
- package/dist/core/ToolLoopExecutor.js +157 -65
- package/dist/core/ToolLoopExecutor.js.map +1 -1
- package/dist/core/ToolManager.d.ts +6 -6
- package/dist/core/ToolManager.d.ts.map +1 -1
- package/dist/core/ToolManager.js +44 -21
- package/dist/core/ToolManager.js.map +1 -1
- package/dist/core/createAgent.d.ts +2 -2
- package/dist/core/createAgent.d.ts.map +1 -1
- package/dist/core/createAgent.js +1 -1
- package/dist/core/createAgent.js.map +1 -1
- package/dist/core/flow-namespace.d.ts +16 -1
- package/dist/core/flow-namespace.d.ts.map +1 -1
- package/dist/core/flow-namespace.js +23 -1
- package/dist/core/flow-namespace.js.map +1 -1
- package/dist/core/toolGates.d.ts +1 -1
- package/dist/core/toolGates.d.ts.map +1 -1
- package/dist/core/toolGates.js +1 -1
- package/dist/core/toolGates.js.map +1 -1
- package/dist/index.d.ts +50 -45
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -30
- package/dist/index.js.map +1 -1
- package/dist/providers/AnthropicProvider.d.ts +25 -35
- package/dist/providers/AnthropicProvider.d.ts.map +1 -1
- package/dist/providers/AnthropicProvider.js +30 -423
- package/dist/providers/AnthropicProvider.js.map +1 -1
- package/dist/providers/DeepSeekProvider.d.ts +13 -34
- package/dist/providers/DeepSeekProvider.d.ts.map +1 -1
- package/dist/providers/DeepSeekProvider.js +16 -47
- package/dist/providers/DeepSeekProvider.js.map +1 -1
- package/dist/providers/GeminiProvider.d.ts +22 -75
- package/dist/providers/GeminiProvider.d.ts.map +1 -1
- package/dist/providers/GeminiProvider.js +32 -558
- package/dist/providers/GeminiProvider.js.map +1 -1
- package/dist/providers/GenericOpenAICompatibleProvider.d.ts +9 -10
- package/dist/providers/GenericOpenAICompatibleProvider.d.ts.map +1 -1
- package/dist/providers/GenericOpenAICompatibleProvider.js +13 -16
- package/dist/providers/GenericOpenAICompatibleProvider.js.map +1 -1
- package/dist/providers/OpenAICompatibleProvider.d.ts +26 -135
- package/dist/providers/OpenAICompatibleProvider.d.ts.map +1 -1
- package/dist/providers/OpenAICompatibleProvider.js +39 -495
- package/dist/providers/OpenAICompatibleProvider.js.map +1 -1
- package/dist/providers/OpenAIProvider.d.ts +14 -20
- package/dist/providers/OpenAIProvider.d.ts.map +1 -1
- package/dist/providers/OpenAIProvider.js +20 -24
- package/dist/providers/OpenAIProvider.js.map +1 -1
- package/dist/providers/OpenRouterProvider.d.ts +20 -24
- package/dist/providers/OpenRouterProvider.d.ts.map +1 -1
- package/dist/providers/OpenRouterProvider.js +21 -34
- package/dist/providers/OpenRouterProvider.js.map +1 -1
- package/dist/providers/ProviderAdapter.d.ts +94 -0
- package/dist/providers/ProviderAdapter.d.ts.map +1 -0
- package/dist/providers/ProviderAdapter.js +251 -0
- package/dist/providers/ProviderAdapter.js.map +1 -0
- package/dist/providers/index.d.ts +21 -18
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +13 -10
- package/dist/providers/index.js.map +1 -1
- package/dist/types/agent.d.ts +37 -11
- package/dist/types/agent.d.ts.map +1 -1
- package/dist/types/ai.d.ts +11 -21
- package/dist/types/ai.d.ts.map +1 -1
- package/dist/types/compaction.d.ts +2 -2
- package/dist/types/compaction.d.ts.map +1 -1
- package/dist/types/errors.d.ts +16 -20
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/errors.js +15 -16
- package/dist/types/errors.js.map +1 -1
- package/dist/types/flow.d.ts +56 -39
- package/dist/types/flow.d.ts.map +1 -1
- package/dist/types/history.d.ts +1 -1
- package/dist/types/history.d.ts.map +1 -1
- package/dist/types/index.d.ts +17 -17
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +4 -4
- package/dist/types/index.js.map +1 -1
- package/dist/types/persistence.d.ts +2 -2
- package/dist/types/persistence.d.ts.map +1 -1
- package/dist/types/session.d.ts +4 -4
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types/signals.d.ts +3 -3
- package/dist/types/signals.d.ts.map +1 -1
- package/dist/types/template.d.ts +2 -2
- package/dist/types/template.d.ts.map +1 -1
- package/dist/types/tool.d.ts +4 -2
- package/dist/types/tool.d.ts.map +1 -1
- package/dist/types/tool.js.map +1 -1
- package/dist/utils/condition.d.ts +1 -1
- package/dist/utils/condition.d.ts.map +1 -1
- package/dist/utils/condition.js +2 -2
- package/dist/utils/condition.js.map +1 -1
- package/dist/utils/event.d.ts +1 -1
- package/dist/utils/event.d.ts.map +1 -1
- package/dist/utils/event.js +1 -1
- package/dist/utils/event.js.map +1 -1
- package/dist/utils/history.d.ts +2 -2
- package/dist/utils/history.d.ts.map +1 -1
- package/dist/utils/history.js +1 -1
- package/dist/utils/history.js.map +1 -1
- package/dist/utils/index.d.ts +11 -13
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +11 -12
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/serialize.d.ts +17 -0
- package/dist/utils/serialize.d.ts.map +1 -1
- package/dist/utils/serialize.js +31 -0
- package/dist/utils/serialize.js.map +1 -1
- package/dist/utils/session.d.ts +23 -3
- package/dist/utils/session.d.ts.map +1 -1
- package/dist/utils/session.js +35 -6
- package/dist/utils/session.js.map +1 -1
- package/dist/utils/template.d.ts +3 -3
- package/dist/utils/template.d.ts.map +1 -1
- package/dist/utils/template.js +1 -1
- package/dist/utils/template.js.map +1 -1
- package/docs/concepts/architecture.md +3 -3
- package/docs/concepts/directives.md +1 -1
- package/docs/guides/error-handling.md +46 -45
- package/docs/guides/flow-control.md +8 -1
- package/docs/guides/instructions.md +15 -6
- package/docs/guides/persistence.md +12 -5
- package/docs/guides/streaming.md +10 -0
- package/docs/migration/README.md +4 -0
- package/docs/migration/v2-3-to-v2-4.md +4 -0
- package/docs/migration/v2-6-to-v2-7.md +246 -0
- package/docs/reference/adapters.md +15 -1
- package/docs/reference/branches.md +2 -0
- package/docs/reference/create-agent.md +28 -0
- package/docs/reference/directive.md +1 -1
- package/docs/reference/errors.md +30 -32
- package/docs/reference/providers.md +63 -60
- package/docs/reference/step.md +28 -21
- package/docs/reference/tool.md +14 -5
- package/docs/start/02-first-agent.md +8 -4
- package/docs/start/03-collect-data.md +19 -10
- package/examples/01-quickstart.ts +2 -2
- package/examples/02-data-extraction.ts +1 -1
- package/examples/03-tools.ts +1 -1
- package/examples/04-instructions.ts +2 -2
- package/examples/05-branching.ts +3 -3
- package/examples/06-flow-control.ts +3 -3
- package/examples/07-streaming.ts +1 -1
- package/examples/08-persistence.ts +2 -2
- package/examples/09-signals.ts +1 -1
- package/examples/tsconfig.json +6 -3
- package/package.json +9 -7
- package/src/adapters/MemoryAdapter.ts +33 -37
- package/src/adapters/MongoAdapter.ts +3 -3
- package/src/adapters/OpenSearchAdapter.ts +4 -4
- package/src/adapters/PostgreSQLAdapter.ts +26 -21
- package/src/adapters/PrismaAdapter.ts +4 -4
- package/src/adapters/RedisAdapter.ts +84 -37
- package/src/adapters/SQLiteAdapter.ts +13 -34
- package/src/adapters/index.ts +13 -13
- package/src/adapters/sessionRow.ts +57 -0
- package/src/core/Agent.ts +64 -18
- package/src/core/AutoChainExecutor.ts +44 -57
- package/src/core/BranchEvaluator.ts +5 -5
- package/src/core/CompactionEngine.ts +42 -8
- package/src/core/DirectiveChainTracker.ts +3 -3
- package/src/core/Events.ts +2 -2
- package/src/core/Flow.ts +9 -9
- package/src/core/FlowRouter.ts +46 -20
- package/src/core/PersistenceManager.ts +4 -4
- package/src/core/PromptComposer.ts +8 -8
- package/src/core/PromptSectionCache.ts +2 -2
- package/src/core/ResponseEngine.ts +6 -6
- package/src/core/ResponseGenerationError.ts +3 -6
- package/src/core/ResponseModal.ts +205 -39
- package/src/core/ResponsePipeline.ts +301 -107
- package/src/core/SessionFinalizer.ts +40 -10
- package/src/core/SessionManager.ts +61 -27
- package/src/core/SignalCoordinator.ts +7 -7
- package/src/core/SignalEvaluator.ts +6 -6
- package/src/core/SignalProcessor.ts +13 -93
- package/src/core/Step.ts +87 -10
- package/src/core/StepLifecycle.ts +129 -26
- package/src/core/StreamingToolExecutor.ts +33 -8
- package/src/core/ToolLoopExecutor.ts +206 -80
- package/src/core/ToolManager.ts +53 -26
- package/src/core/createAgent.ts +2 -2
- package/src/core/flow-namespace.ts +31 -2
- package/src/core/toolGates.ts +2 -2
- package/src/index.ts +59 -45
- package/src/providers/AnthropicProvider.ts +44 -595
- package/src/providers/DeepSeekProvider.ts +27 -92
- package/src/providers/GeminiProvider.ts +41 -752
- package/src/providers/GenericOpenAICompatibleProvider.ts +19 -27
- package/src/providers/OpenAICompatibleProvider.ts +58 -764
- package/src/providers/OpenAIProvider.ts +31 -55
- package/src/providers/OpenRouterProvider.ts +40 -70
- package/src/providers/ProviderAdapter.ts +368 -0
- package/src/providers/index.ts +21 -23
- package/src/types/agent.ts +36 -11
- package/src/types/ai.ts +11 -21
- package/src/types/compaction.ts +2 -2
- package/src/types/errors.ts +17 -35
- package/src/types/flow.ts +44 -46
- package/src/types/history.ts +1 -1
- package/src/types/index.ts +18 -17
- package/src/types/persistence.ts +2 -2
- package/src/types/session.ts +4 -4
- package/src/types/signals.ts +3 -3
- package/src/types/template.ts +2 -2
- package/src/types/tool.ts +4 -2
- package/src/utils/condition.ts +3 -3
- package/src/utils/event.ts +1 -1
- package/src/utils/history.ts +3 -3
- package/src/utils/index.ts +14 -15
- package/src/utils/serialize.ts +38 -0
- package/src/utils/session.ts +46 -9
- package/src/utils/template.ts +3 -3
- package/dist/cjs/core/DirectiveBus.d.ts +0 -88
- package/dist/cjs/core/DirectiveBus.d.ts.map +0 -1
- package/dist/cjs/core/DirectiveBus.js +0 -196
- package/dist/cjs/core/DirectiveBus.js.map +0 -1
- package/dist/cjs/providers/errorClassification.d.ts +0 -61
- package/dist/cjs/providers/errorClassification.d.ts.map +0 -1
- package/dist/cjs/providers/errorClassification.js +0 -123
- package/dist/cjs/providers/errorClassification.js.map +0 -1
- package/dist/cjs/utils/retry.d.ts +0 -67
- package/dist/cjs/utils/retry.d.ts.map +0 -1
- package/dist/cjs/utils/retry.js +0 -201
- package/dist/cjs/utils/retry.js.map +0 -1
- package/dist/core/DirectiveBus.d.ts +0 -88
- package/dist/core/DirectiveBus.d.ts.map +0 -1
- package/dist/core/DirectiveBus.js +0 -192
- package/dist/core/DirectiveBus.js.map +0 -1
- package/dist/providers/errorClassification.d.ts +0 -61
- package/dist/providers/errorClassification.d.ts.map +0 -1
- package/dist/providers/errorClassification.js +0 -116
- package/dist/providers/errorClassification.js.map +0 -1
- package/dist/utils/retry.d.ts +0 -67
- package/dist/utils/retry.d.ts.map +0 -1
- package/dist/utils/retry.js +0 -193
- package/dist/utils/retry.js.map +0 -1
- package/src/core/DirectiveBus.ts +0 -248
- package/src/providers/errorClassification.ts +0 -172
- package/src/utils/retry.ts +0 -274
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.ResponsePipeline = void 0;
|
|
7
7
|
exports.hasDirectivePositionField = hasDirectivePositionField;
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
8
|
+
const index_js_1 = require("../utils/index.js");
|
|
9
|
+
const session_js_1 = require("../utils/session.js");
|
|
10
|
+
const template_js_1 = require("../utils/template.js");
|
|
11
|
+
const Step_js_1 = require("../core/Step.js");
|
|
12
|
+
const BranchEvaluator_js_1 = require("./BranchEvaluator.js");
|
|
13
|
+
const DirectiveChainTracker_js_1 = require("./DirectiveChainTracker.js");
|
|
14
|
+
const ResponseGenerationError_js_1 = require("./ResponseGenerationError.js");
|
|
15
15
|
/**
|
|
16
16
|
* Position fields on a Directive that represent a navigation decision.
|
|
17
17
|
* When any of these is set, the directive "wins" the turn's position decision
|
|
@@ -29,6 +29,23 @@ function hasDirectivePositionField(directive) {
|
|
|
29
29
|
return false;
|
|
30
30
|
return DIRECTIVE_POSITION_FIELDS.some((field) => directive[field] !== undefined);
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Compute the per-key data writes the signal phase applied to a session.
|
|
34
|
+
* The signal phase and routing start from the same input session, so any
|
|
35
|
+
* key whose value differs between the input and the signal output was
|
|
36
|
+
* written by the signal phase alone (handler `updateData` calls).
|
|
37
|
+
*/
|
|
38
|
+
function diffSignalDataWrites(before, after) {
|
|
39
|
+
const beforeData = (before ?? {});
|
|
40
|
+
const afterData = (after ?? {});
|
|
41
|
+
const writes = {};
|
|
42
|
+
for (const key of Object.keys(afterData)) {
|
|
43
|
+
if (afterData[key] !== beforeData[key]) {
|
|
44
|
+
writes[key] = afterData[key];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return writes;
|
|
48
|
+
}
|
|
32
49
|
/**
|
|
33
50
|
* Shared response processing logic between respond() and respondStream() methods
|
|
34
51
|
*/
|
|
@@ -47,7 +64,7 @@ class ResponsePipeline {
|
|
|
47
64
|
*/
|
|
48
65
|
createChainTracker() {
|
|
49
66
|
const maxChain = this.options.maxDirectiveChain ?? 10;
|
|
50
|
-
this._chainTracker = new
|
|
67
|
+
this._chainTracker = new DirectiveChainTracker_js_1.DirectiveChainTracker(maxChain);
|
|
51
68
|
return this._chainTracker;
|
|
52
69
|
}
|
|
53
70
|
/**
|
|
@@ -78,7 +95,7 @@ class ResponsePipeline {
|
|
|
78
95
|
...contextOverride,
|
|
79
96
|
};
|
|
80
97
|
// Initialize or get session (use the live session if available)
|
|
81
|
-
const targetSession = session || params.currentSession || (0,
|
|
98
|
+
const targetSession = session || params.currentSession || (0, index_js_1.createSession)();
|
|
82
99
|
return {
|
|
83
100
|
effectiveContext,
|
|
84
101
|
session: targetSession,
|
|
@@ -89,7 +106,7 @@ class ResponsePipeline {
|
|
|
89
106
|
* Handle routing and step selection logic
|
|
90
107
|
*/
|
|
91
108
|
async handleRoutingAndStepSelection(params) {
|
|
92
|
-
const { session, history, context, signal } = params;
|
|
109
|
+
const { session, history, context, signal, allowedFlows } = params;
|
|
93
110
|
// PHASE 2: ROUTING + STEP SELECTION - Determine which flow and step to use (combined)
|
|
94
111
|
let selectedFlow;
|
|
95
112
|
let responseDirectives;
|
|
@@ -97,12 +114,23 @@ class ResponsePipeline {
|
|
|
97
114
|
let isFlowComplete = false;
|
|
98
115
|
let completedFlows = [];
|
|
99
116
|
let targetSession = session;
|
|
117
|
+
// Flows exited this turn via pendingDirective redirect/reset
|
|
118
|
+
const endedFlows = [];
|
|
119
|
+
let exitPrevFlowId;
|
|
120
|
+
let exitPrevFlowTitle;
|
|
121
|
+
let exitReason;
|
|
100
122
|
// Get flows early since we need them for pending directives
|
|
101
123
|
const flows = this.getFlows();
|
|
124
|
+
// Routing candidates may be narrowed for this turn (entry pins); the
|
|
125
|
+
// pendingDirective applier below still resolves targets against the FULL
|
|
126
|
+
// registry so declared redirects always resolve.
|
|
127
|
+
const routingFlows = allowedFlows && allowedFlows.length > 0
|
|
128
|
+
? flows.filter((f) => allowedFlows.includes(f.id) || allowedFlows.includes(f.title))
|
|
129
|
+
: flows;
|
|
102
130
|
// Check for pending directive from previous flow completion or external dispatch
|
|
103
131
|
if (targetSession.pendingDirective) {
|
|
104
132
|
const directive = targetSession.pendingDirective;
|
|
105
|
-
|
|
133
|
+
index_js_1.logger.debug(`[ResponsePipeline] Applying pending directive at start of turn`);
|
|
106
134
|
// Track directive chain depth (Requirement 22.1)
|
|
107
135
|
const tracker = this.chainTracker;
|
|
108
136
|
tracker.record(directive, "pending");
|
|
@@ -118,23 +146,30 @@ class ResponsePipeline {
|
|
|
118
146
|
...targetSession,
|
|
119
147
|
pendingDirective: nextDirective,
|
|
120
148
|
};
|
|
149
|
+
// Capture the flow we're leaving so directive-driven exits surface on
|
|
150
|
+
// the response (endedFlows).
|
|
151
|
+
exitPrevFlowId = targetSession.currentFlow?.id;
|
|
152
|
+
exitPrevFlowTitle = exitPrevFlowId
|
|
153
|
+
? flows.find((f) => f.id === exitPrevFlowId)?.title
|
|
154
|
+
: undefined;
|
|
121
155
|
// Apply the directive: resolve position field to a flow/step
|
|
122
156
|
if (directive.goTo) {
|
|
157
|
+
exitReason = 'goto';
|
|
123
158
|
const flowTarget = typeof directive.goTo === 'string'
|
|
124
159
|
? directive.goTo
|
|
125
160
|
: directive.goTo.flow;
|
|
126
161
|
if (flowTarget) {
|
|
127
162
|
const targetFlow = flows.find((r) => r.id === flowTarget || r.title === flowTarget);
|
|
128
163
|
if (targetFlow) {
|
|
129
|
-
|
|
130
|
-
targetSession = (0,
|
|
164
|
+
index_js_1.logger.debug(`[ResponsePipeline] Pending directive goTo → flow: ${targetFlow.title}`);
|
|
165
|
+
targetSession = (0, session_js_1.enterFlow)(targetSession, targetFlow.id, targetFlow.title);
|
|
131
166
|
// Merge initial data if available
|
|
132
167
|
if (targetFlow.initialData) {
|
|
133
|
-
targetSession = (0,
|
|
168
|
+
targetSession = (0, index_js_1.mergeCollected)(targetSession, targetFlow.initialData);
|
|
134
169
|
}
|
|
135
170
|
// Merge directive-carried data if present
|
|
136
171
|
if (typeof directive.goTo === 'object' && directive.goTo.data) {
|
|
137
|
-
targetSession = (0,
|
|
172
|
+
targetSession = (0, index_js_1.mergeCollected)(targetSession, directive.goTo.data);
|
|
138
173
|
}
|
|
139
174
|
selectedFlow = targetFlow;
|
|
140
175
|
// If goTo specifies a step, enter it
|
|
@@ -142,13 +177,13 @@ class ResponsePipeline {
|
|
|
142
177
|
const stepTarget = directive.goTo.step;
|
|
143
178
|
const targetStep = targetFlow.getStep(stepTarget);
|
|
144
179
|
if (targetStep) {
|
|
145
|
-
targetSession = (0,
|
|
180
|
+
targetSession = (0, index_js_1.enterStep)(targetSession, targetStep.id, targetStep.description);
|
|
146
181
|
selectedStep = targetStep;
|
|
147
182
|
}
|
|
148
183
|
}
|
|
149
184
|
}
|
|
150
185
|
else {
|
|
151
|
-
|
|
186
|
+
index_js_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.`);
|
|
152
187
|
}
|
|
153
188
|
}
|
|
154
189
|
}
|
|
@@ -162,11 +197,11 @@ class ResponsePipeline {
|
|
|
162
197
|
if (flowTarget) {
|
|
163
198
|
const targetFlow = flows.find((r) => r.id === flowTarget || r.title === flowTarget);
|
|
164
199
|
if (targetFlow) {
|
|
165
|
-
targetSession = (0,
|
|
200
|
+
targetSession = (0, session_js_1.enterFlow)(targetSession, targetFlow.id, targetFlow.title);
|
|
166
201
|
selectedFlow = targetFlow;
|
|
167
202
|
const targetStep = targetFlow.getStep(stepTarget);
|
|
168
203
|
if (targetStep) {
|
|
169
|
-
targetSession = (0,
|
|
204
|
+
targetSession = (0, index_js_1.enterStep)(targetSession, targetStep.id, targetStep.description);
|
|
170
205
|
selectedStep = targetStep;
|
|
171
206
|
}
|
|
172
207
|
}
|
|
@@ -178,13 +213,14 @@ class ResponsePipeline {
|
|
|
178
213
|
selectedFlow = currentFlow;
|
|
179
214
|
const targetStep = currentFlow.getStep(stepTarget);
|
|
180
215
|
if (targetStep) {
|
|
181
|
-
targetSession = (0,
|
|
216
|
+
targetSession = (0, index_js_1.enterStep)(targetSession, targetStep.id, targetStep.description);
|
|
182
217
|
selectedStep = targetStep;
|
|
183
218
|
}
|
|
184
219
|
}
|
|
185
220
|
}
|
|
186
221
|
}
|
|
187
222
|
else if (directive.reset) {
|
|
223
|
+
exitReason = 'reset';
|
|
188
224
|
// Reset current flow
|
|
189
225
|
if (targetSession.currentFlow) {
|
|
190
226
|
const currentFlow = flows.find(r => r.id === targetSession.currentFlow?.id);
|
|
@@ -196,14 +232,14 @@ class ResponsePipeline {
|
|
|
196
232
|
if (resetStep) {
|
|
197
233
|
const targetStep = currentFlow.getStep(resetStep);
|
|
198
234
|
if (targetStep) {
|
|
199
|
-
targetSession = (0,
|
|
235
|
+
targetSession = (0, index_js_1.enterStep)(targetSession, targetStep.id, targetStep.description);
|
|
200
236
|
selectedStep = targetStep;
|
|
201
237
|
}
|
|
202
238
|
}
|
|
203
239
|
else {
|
|
204
240
|
// Reset to initial step
|
|
205
241
|
const initialStep = currentFlow.initialStep;
|
|
206
|
-
targetSession = (0,
|
|
242
|
+
targetSession = (0, index_js_1.enterStep)(targetSession, initialStep.id, initialStep.description);
|
|
207
243
|
selectedStep = initialStep;
|
|
208
244
|
}
|
|
209
245
|
}
|
|
@@ -212,14 +248,20 @@ class ResponsePipeline {
|
|
|
212
248
|
// For complete/abort, selectedFlow stays undefined → handled downstream
|
|
213
249
|
// Apply state writes from the directive
|
|
214
250
|
if (directive.dataUpdate) {
|
|
215
|
-
targetSession = (0,
|
|
251
|
+
targetSession = (0, index_js_1.mergeCollected)(targetSession, directive.dataUpdate);
|
|
216
252
|
}
|
|
217
253
|
// Skip FlowRouter.decideFlowAndStep — the directive resolved the position
|
|
218
254
|
}
|
|
219
|
-
|
|
220
|
-
|
|
255
|
+
if (exitReason &&
|
|
256
|
+
exitPrevFlowId &&
|
|
257
|
+
(!selectedFlow || selectedFlow.id !== exitPrevFlowId)) {
|
|
258
|
+
endedFlows.push({ flowId: exitPrevFlowId, title: exitPrevFlowTitle, reason: exitReason });
|
|
259
|
+
}
|
|
260
|
+
// If no pending transition or transition handled, do normal routing.
|
|
261
|
+
// Candidates honor allowedFlows; completion scoring runs over the same set.
|
|
262
|
+
if (routingFlows.length > 0 && !selectedFlow) {
|
|
221
263
|
const orchestration = await this.flowRouter.decideFlowAndStep({
|
|
222
|
-
flows:
|
|
264
|
+
flows: routingFlows,
|
|
223
265
|
session: targetSession,
|
|
224
266
|
history,
|
|
225
267
|
agentOptions: this.options,
|
|
@@ -235,7 +277,7 @@ class ResponsePipeline {
|
|
|
235
277
|
completedFlows = orchestration.completedFlows || [];
|
|
236
278
|
// Log if flow is complete
|
|
237
279
|
if (isFlowComplete) {
|
|
238
|
-
|
|
280
|
+
index_js_1.logger.debug(`[ResponsePipeline] Flow complete: all required data collected or last step reached`);
|
|
239
281
|
}
|
|
240
282
|
}
|
|
241
283
|
return {
|
|
@@ -245,15 +287,36 @@ class ResponsePipeline {
|
|
|
245
287
|
session: targetSession,
|
|
246
288
|
isFlowComplete,
|
|
247
289
|
completedFlows,
|
|
290
|
+
...(endedFlows.length > 0 ? { endedFlows } : {}),
|
|
248
291
|
};
|
|
249
292
|
}
|
|
293
|
+
/**
|
|
294
|
+
* Combine a routing-derived session with the signal phase's non-position
|
|
295
|
+
* mutations. The routing session is the base — it owns position state AND
|
|
296
|
+
* data merges such as flow initialData and directive-carried writes; the
|
|
297
|
+
* signal phase's mutations (trigger recording under `signals`, handler
|
|
298
|
+
* data writes) are re-applied on top. Both phases start from the same
|
|
299
|
+
* input session, so their mutations cannot silently collide.
|
|
300
|
+
*/
|
|
301
|
+
combineRoutingAndSignalSessions(params) {
|
|
302
|
+
const { inputSession, signalSession, routingSession } = params;
|
|
303
|
+
let combined = routingSession;
|
|
304
|
+
if (signalSession.signals !== inputSession.signals) {
|
|
305
|
+
combined = { ...combined, signals: signalSession.signals };
|
|
306
|
+
}
|
|
307
|
+
const signalWrites = diffSignalDataWrites(inputSession.data, signalSession.data);
|
|
308
|
+
if (Object.keys(signalWrites).length > 0) {
|
|
309
|
+
combined = (0, index_js_1.mergeCollected)(combined, signalWrites);
|
|
310
|
+
}
|
|
311
|
+
return combined;
|
|
312
|
+
}
|
|
250
313
|
/**
|
|
251
314
|
* Determine next step and update session
|
|
252
315
|
*/
|
|
253
316
|
async determineNextStep(params) {
|
|
254
317
|
const { selectedFlow, selectedStep, session, isFlowComplete, context, busDirective } = params;
|
|
255
318
|
if (!selectedFlow) {
|
|
256
|
-
return { nextStep: undefined, session };
|
|
319
|
+
return { nextStep: undefined, session, isFlowComplete };
|
|
257
320
|
}
|
|
258
321
|
// ─── GUARD: directive bus winner with a position field preempts branches ───
|
|
259
322
|
// Resolution precedence (design.md): bus > branches > linear > AI.
|
|
@@ -261,8 +324,8 @@ class ResponsePipeline {
|
|
|
261
324
|
// complete, abort, reset), that decision wins the turn. Do NOT evaluate
|
|
262
325
|
// branches or linear/AI selection — the caller applies the bus directive.
|
|
263
326
|
if (hasDirectivePositionField(busDirective)) {
|
|
264
|
-
|
|
265
|
-
return { nextStep: undefined, session };
|
|
327
|
+
index_js_1.logger.debug(`[ResponsePipeline] Directive bus winner has position field — skipping branch evaluation and linear/AI selection`);
|
|
328
|
+
return { nextStep: undefined, session, isFlowComplete };
|
|
266
329
|
}
|
|
267
330
|
// STEP 1 (Algorithm 1): branches win over linear chain AND flow completion.
|
|
268
331
|
// Evaluate branches before checking isFlowComplete — a branch can redirect
|
|
@@ -274,13 +337,20 @@ class ResponsePipeline {
|
|
|
274
337
|
if (currentStep?.branches && currentStep.branches.length > 0) {
|
|
275
338
|
const branchResult = await this.evaluateStepBranches(currentStep, selectedFlow, session, context);
|
|
276
339
|
if (branchResult) {
|
|
277
|
-
|
|
340
|
+
// A branch that resolved a position overrides the router's completion
|
|
341
|
+
// proposal. Without this, a branch that parks on a step of its own
|
|
342
|
+
// flow (`then: '<stepId>'`, `then: { reset: true }`) keeps
|
|
343
|
+
// isFlowComplete=true, the caller drops the step it just resolved,
|
|
344
|
+
// and the turn ends as a silent completion — no LLM call, empty
|
|
345
|
+
// reply, flow marked completed for the rest of the session.
|
|
346
|
+
const resolvedPosition = Boolean(branchResult.nextStep || branchResult.flowChanged);
|
|
347
|
+
return { ...branchResult, isFlowComplete: resolvedPosition ? false : isFlowComplete };
|
|
278
348
|
}
|
|
279
349
|
// undefined → fall through to linear/AI selection or flow completion
|
|
280
350
|
}
|
|
281
351
|
}
|
|
282
352
|
if (isFlowComplete) {
|
|
283
|
-
return { nextStep: undefined, session };
|
|
353
|
+
return { nextStep: undefined, session, isFlowComplete: true };
|
|
284
354
|
}
|
|
285
355
|
let nextStep;
|
|
286
356
|
// If we have a selected step from the combined routing decision, use it
|
|
@@ -294,15 +364,15 @@ class ResponsePipeline {
|
|
|
294
364
|
: undefined;
|
|
295
365
|
// Get candidate steps based on current position in the flow
|
|
296
366
|
const candidates = await this.flowRouter.getCandidateStepsWithConditions(selectedFlow, currentStep, // Pass current step instead of undefined to maintain progression
|
|
297
|
-
(0,
|
|
367
|
+
(0, template_js_1.createTemplateContext)({ data: session.data, session, context }));
|
|
298
368
|
if (candidates.length > 0) {
|
|
299
369
|
nextStep = candidates[0].step;
|
|
300
|
-
|
|
370
|
+
index_js_1.logger.debug(`[ResponsePipeline] Using first valid step: ${nextStep.id}${currentStep ? ' (progressing from ' + currentStep.id + ')' : ' for new flow'}`);
|
|
301
371
|
}
|
|
302
372
|
else {
|
|
303
373
|
// Fallback to initial step even if it should be skipped
|
|
304
374
|
nextStep = selectedFlow.initialStep;
|
|
305
|
-
|
|
375
|
+
index_js_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.`);
|
|
306
376
|
}
|
|
307
377
|
}
|
|
308
378
|
// Before entering the step, check if requires fields are satisfied
|
|
@@ -310,7 +380,7 @@ class ResponsePipeline {
|
|
|
310
380
|
const sessionData = session.data || {};
|
|
311
381
|
const missingRequires = nextStep.requires.filter(field => sessionData[String(field)] === undefined);
|
|
312
382
|
if (missingRequires.length > 0) {
|
|
313
|
-
|
|
383
|
+
index_js_1.logger.debug(`[ResponsePipeline] Cannot enter step "${nextStep.id}": missing required fields [${missingRequires.join(', ')}]. Staying at current step.`);
|
|
314
384
|
// Stay at current step - don't enter the next one
|
|
315
385
|
const currentStepId = session.currentStep?.id;
|
|
316
386
|
if (currentStepId && selectedFlow) {
|
|
@@ -319,13 +389,13 @@ class ResponsePipeline {
|
|
|
319
389
|
nextStep = currentStepInstance;
|
|
320
390
|
}
|
|
321
391
|
}
|
|
322
|
-
return { nextStep, session };
|
|
392
|
+
return { nextStep, session, isFlowComplete: false };
|
|
323
393
|
}
|
|
324
394
|
}
|
|
325
395
|
// Update session with next step
|
|
326
|
-
const updatedSession = (0,
|
|
327
|
-
|
|
328
|
-
return { nextStep, session: updatedSession };
|
|
396
|
+
const updatedSession = (0, index_js_1.enterStep)(session, nextStep.id, nextStep.description);
|
|
397
|
+
index_js_1.logger.debug(`[ResponsePipeline] Entered step: ${nextStep.id}`);
|
|
398
|
+
return { nextStep, session: updatedSession, isFlowComplete: false };
|
|
329
399
|
}
|
|
330
400
|
/**
|
|
331
401
|
* Evaluate branches on a step and resolve the `then` value.
|
|
@@ -339,7 +409,7 @@ class ResponsePipeline {
|
|
|
339
409
|
* Returns the resolved { nextStep, session, flowChanged? } or undefined if no branch matched.
|
|
340
410
|
*/
|
|
341
411
|
async evaluateStepBranches(currentStep, selectedFlow, session, context) {
|
|
342
|
-
const history = session.history ? (0,
|
|
412
|
+
const history = session.history ? (0, index_js_1.historyToEvents)(session.history) : [];
|
|
343
413
|
// Build the BranchPredicateContext
|
|
344
414
|
const branchCtx = {
|
|
345
415
|
data: session.data,
|
|
@@ -348,8 +418,8 @@ class ResponsePipeline {
|
|
|
348
418
|
history,
|
|
349
419
|
};
|
|
350
420
|
// Create the AI condition evaluator
|
|
351
|
-
const aiEvaluator = (0,
|
|
352
|
-
const result = await (0,
|
|
421
|
+
const aiEvaluator = (0, BranchEvaluator_js_1.createAiConditionEvaluator)(this.options.provider, history, context);
|
|
422
|
+
const result = await (0, BranchEvaluator_js_1.evaluateBranches)(currentStep.branches, branchCtx, aiEvaluator);
|
|
353
423
|
if (result === undefined) {
|
|
354
424
|
return undefined; // No branch matched → fall through to linear/AI selection
|
|
355
425
|
}
|
|
@@ -362,8 +432,8 @@ class ResponsePipeline {
|
|
|
362
432
|
// 1. Look up in current flow's step registry first (local step wins)
|
|
363
433
|
const localStep = selectedFlow.getStep(result);
|
|
364
434
|
if (localStep) {
|
|
365
|
-
const updatedSession = (0,
|
|
366
|
-
|
|
435
|
+
const updatedSession = (0, index_js_1.enterStep)(session, localStep.id, localStep.description);
|
|
436
|
+
index_js_1.logger.debug(`[ResponsePipeline] Branch resolved to local step: ${localStep.id}`);
|
|
367
437
|
return { nextStep: localStep, session: updatedSession };
|
|
368
438
|
}
|
|
369
439
|
// 2. Look up in agent's flow registry
|
|
@@ -371,12 +441,12 @@ class ResponsePipeline {
|
|
|
371
441
|
const targetFlow = flows.find(f => f.id === result || f.title === result);
|
|
372
442
|
if (targetFlow) {
|
|
373
443
|
// Treat as applyDirective({ goTo: result }) — enter the target flow
|
|
374
|
-
|
|
375
|
-
const updatedSession = (0,
|
|
444
|
+
index_js_1.logger.debug(`[ResponsePipeline] Branch resolved to flow: ${targetFlow.title}`);
|
|
445
|
+
const updatedSession = (0, session_js_1.enterFlow)(session, targetFlow.id, targetFlow.title);
|
|
376
446
|
return { nextStep: undefined, session: updatedSession, flowChanged: targetFlow };
|
|
377
447
|
}
|
|
378
448
|
// 3. Neither → throw FlowConfigurationError
|
|
379
|
-
throw new
|
|
449
|
+
throw new Step_js_1.FlowConfigurationError(`[FlowConfigurationError] Unresolved branch target: "${result}" does not match any step in flow "${selectedFlow.id}" or any flow in the agent. ` +
|
|
380
450
|
`Source: ${selectedFlow.id}.${currentStep.id}. Fix the branch "then" value to reference a valid step id or flow id/title.`);
|
|
381
451
|
}
|
|
382
452
|
/**
|
|
@@ -390,7 +460,7 @@ class ResponsePipeline {
|
|
|
390
460
|
let updatedSession = session;
|
|
391
461
|
// Apply state writes first
|
|
392
462
|
if (directive.dataUpdate) {
|
|
393
|
-
updatedSession = (0,
|
|
463
|
+
updatedSession = (0, index_js_1.mergeCollected)(updatedSession, directive.dataUpdate);
|
|
394
464
|
}
|
|
395
465
|
// Handle position fields
|
|
396
466
|
if (directive.goToStep) {
|
|
@@ -405,24 +475,24 @@ class ResponsePipeline {
|
|
|
405
475
|
const flows = this.getFlows();
|
|
406
476
|
const targetFlow = flows.find(f => f.id === flowTarget || f.title === flowTarget);
|
|
407
477
|
if (targetFlow) {
|
|
408
|
-
updatedSession = (0,
|
|
409
|
-
updatedSession = (0,
|
|
478
|
+
updatedSession = (0, session_js_1.enterFlow)(updatedSession, targetFlow.id, targetFlow.title);
|
|
479
|
+
updatedSession = (0, index_js_1.enterStep)(updatedSession, stepTarget);
|
|
410
480
|
// Try to resolve the target step instance for the caller
|
|
411
481
|
const targetStepInstance = targetFlow.getStep(stepTarget);
|
|
412
|
-
|
|
482
|
+
index_js_1.logger.debug(`[ResponsePipeline] Branch directive goToStep → ${flowTarget}.${stepTarget}`);
|
|
413
483
|
return { nextStep: targetStepInstance || undefined, session: updatedSession, flowChanged: targetFlow };
|
|
414
484
|
}
|
|
415
|
-
throw new
|
|
485
|
+
throw new Step_js_1.FlowConfigurationError(`[FlowConfigurationError] Branch directive goToStep targets unknown flow: "${flowTarget}" does not match any flow id or title. ` +
|
|
416
486
|
`Fix the goToStep.flow value or use goTo to target a known flow.`);
|
|
417
487
|
}
|
|
418
488
|
// Local step reference
|
|
419
489
|
const targetStep = selectedFlow.getStep(stepTarget);
|
|
420
490
|
if (targetStep) {
|
|
421
|
-
updatedSession = (0,
|
|
422
|
-
|
|
491
|
+
updatedSession = (0, index_js_1.enterStep)(updatedSession, targetStep.id, targetStep.description);
|
|
492
|
+
index_js_1.logger.debug(`[ResponsePipeline] Branch directive goToStep → ${targetStep.id}`);
|
|
423
493
|
return { nextStep: targetStep, session: updatedSession };
|
|
424
494
|
}
|
|
425
|
-
throw new
|
|
495
|
+
throw new Step_js_1.FlowConfigurationError(`[FlowConfigurationError] Branch directive goToStep targets unknown step: "${stepTarget}" does not exist in flow "${selectedFlow.id}". ` +
|
|
426
496
|
`Fix the goToStep value to reference a valid step id in the current flow.`);
|
|
427
497
|
}
|
|
428
498
|
if (directive.goTo) {
|
|
@@ -433,24 +503,24 @@ class ResponsePipeline {
|
|
|
433
503
|
const flows = this.getFlows();
|
|
434
504
|
const targetFlow = flows.find(f => f.id === flowTarget || f.title === flowTarget);
|
|
435
505
|
if (targetFlow) {
|
|
436
|
-
updatedSession = (0,
|
|
506
|
+
updatedSession = (0, session_js_1.enterFlow)(updatedSession, targetFlow.id, targetFlow.title);
|
|
437
507
|
// If goTo is an object with a step field, enter that step too
|
|
438
508
|
if (typeof directive.goTo === 'object' && directive.goTo.step) {
|
|
439
|
-
updatedSession = (0,
|
|
509
|
+
updatedSession = (0, index_js_1.enterStep)(updatedSession, directive.goTo.step);
|
|
440
510
|
}
|
|
441
|
-
|
|
511
|
+
index_js_1.logger.debug(`[ResponsePipeline] Branch directive goTo → ${targetFlow.title}`);
|
|
442
512
|
return { nextStep: undefined, session: updatedSession, flowChanged: targetFlow };
|
|
443
513
|
}
|
|
444
|
-
throw new
|
|
514
|
+
throw new Step_js_1.FlowConfigurationError(`[FlowConfigurationError] Branch directive goTo targets unknown flow: "${flowTarget}" does not match any flow id or title. ` +
|
|
445
515
|
`Fix the goTo value to reference a valid flow.`);
|
|
446
516
|
}
|
|
447
517
|
}
|
|
448
518
|
if (directive.complete) {
|
|
449
|
-
|
|
519
|
+
index_js_1.logger.debug(`[ResponsePipeline] Branch directive complete`);
|
|
450
520
|
return { nextStep: undefined, session: updatedSession };
|
|
451
521
|
}
|
|
452
522
|
if (directive.abort) {
|
|
453
|
-
|
|
523
|
+
index_js_1.logger.debug(`[ResponsePipeline] Branch directive abort`);
|
|
454
524
|
return { nextStep: undefined, session: updatedSession };
|
|
455
525
|
}
|
|
456
526
|
if (directive.reset) {
|
|
@@ -460,14 +530,14 @@ class ResponsePipeline {
|
|
|
460
530
|
if (resetStep) {
|
|
461
531
|
const targetStep = selectedFlow.getStep(resetStep);
|
|
462
532
|
if (targetStep) {
|
|
463
|
-
updatedSession = (0,
|
|
533
|
+
updatedSession = (0, index_js_1.enterStep)(updatedSession, targetStep.id, targetStep.description);
|
|
464
534
|
return { nextStep: targetStep, session: updatedSession };
|
|
465
535
|
}
|
|
466
536
|
}
|
|
467
537
|
// Reset to initial step
|
|
468
538
|
const initialStep = selectedFlow.initialStep;
|
|
469
|
-
updatedSession = (0,
|
|
470
|
-
|
|
539
|
+
updatedSession = (0, index_js_1.enterStep)(updatedSession, initialStep.id, initialStep.description);
|
|
540
|
+
index_js_1.logger.debug(`[ResponsePipeline] Branch directive reset → ${initialStep.id}`);
|
|
471
541
|
return { nextStep: initialStep, session: updatedSession };
|
|
472
542
|
}
|
|
473
543
|
// Directive with only non-position fields (e.g., just dataUpdate/contextUpdate/reply)
|
|
@@ -485,17 +555,20 @@ class ResponsePipeline {
|
|
|
485
555
|
// Create a fresh chain tracker for this turn (Requirement 22.1)
|
|
486
556
|
this.createChainTracker();
|
|
487
557
|
// ROUTING SKIP OPTIMIZATION (Requirements 20.1, 20.2, 20.3):
|
|
488
|
-
// When the current step has collect fields AND pre-extraction
|
|
489
|
-
// one of those fields, skip FlowRouter.decideFlowAndStep
|
|
490
|
-
|
|
491
|
-
|
|
558
|
+
// When the current step has collect fields AND step-scoped pre-extraction
|
|
559
|
+
// populates at least one of those fields, skip FlowRouter.decideFlowAndStep
|
|
560
|
+
// for this turn. The check's extraction result is reused by the fallthrough
|
|
561
|
+
// paths below so a turn costs at most ONE extraction LLM call.
|
|
562
|
+
const routingSkipCheck = await this.attemptRoutingSkipForCollect(params);
|
|
563
|
+
if (routingSkipCheck.skipResult) {
|
|
564
|
+
const skipResult = routingSkipCheck.skipResult;
|
|
492
565
|
// Even when routing is skipped, run pre-signal phase if processor is present
|
|
493
566
|
if (this.signalCoordinator.enabled) {
|
|
494
567
|
const signalResult = await this.signalCoordinator.runPrePhase(params.session, params.context, params.history);
|
|
495
568
|
// If signal halts, override the routing skip result
|
|
496
569
|
if (signalResult.mergedDirective?.halt) {
|
|
497
570
|
return {
|
|
498
|
-
...
|
|
571
|
+
...skipResult,
|
|
499
572
|
session: signalResult.updatedSession,
|
|
500
573
|
signalFirings: signalResult.firings,
|
|
501
574
|
signalHalted: true,
|
|
@@ -506,15 +579,20 @@ class ResponsePipeline {
|
|
|
506
579
|
if (hasDirectivePositionField(signalResult.mergedDirective)) {
|
|
507
580
|
return this.signalCoordinator.applyPositionDirective(signalResult);
|
|
508
581
|
}
|
|
509
|
-
// Non-position directive:
|
|
582
|
+
// Non-position directive: keep the skip result (extraction merges,
|
|
583
|
+
// step entry) and re-apply the signal phase's non-position mutations
|
|
510
584
|
return {
|
|
511
|
-
...
|
|
512
|
-
session:
|
|
585
|
+
...skipResult,
|
|
586
|
+
session: this.combineRoutingAndSignalSessions({
|
|
587
|
+
inputSession: params.session,
|
|
588
|
+
signalSession: signalResult.updatedSession,
|
|
589
|
+
routingSession: skipResult.session,
|
|
590
|
+
}),
|
|
513
591
|
signalFirings: signalResult.firings,
|
|
514
592
|
signalPreDirective: signalResult.mergedDirective || undefined,
|
|
515
593
|
};
|
|
516
594
|
}
|
|
517
|
-
return
|
|
595
|
+
return skipResult;
|
|
518
596
|
}
|
|
519
597
|
// ── PARALLEL PRE-SIGNAL PHASE + ROUTING (Algorithm 5) ────────────────
|
|
520
598
|
// When signalProcessor is present, run pre-signals in parallel with routing.
|
|
@@ -528,6 +606,7 @@ class ResponsePipeline {
|
|
|
528
606
|
history: params.history,
|
|
529
607
|
context: params.context,
|
|
530
608
|
signal: params.signal,
|
|
609
|
+
allowedFlows: params.allowedFlows,
|
|
531
610
|
}),
|
|
532
611
|
]);
|
|
533
612
|
// ── Requirement 8.2: halt → discard routing, skip LLM ────────────
|
|
@@ -548,38 +627,41 @@ class ResponsePipeline {
|
|
|
548
627
|
}
|
|
549
628
|
// ── Requirement 8.4: non-position directive → use routing, propagate augmentation ──
|
|
550
629
|
// ── Requirement 8.5: no directive → use routing as-is ─────────────
|
|
551
|
-
|
|
552
|
-
//
|
|
630
|
+
// Base = routed session (position state AND router data merges such as
|
|
631
|
+
// flow initialData survive); the signal phase's non-position mutations
|
|
632
|
+
// (trigger state, handler data writes) are re-applied on top.
|
|
633
|
+
let updatedSession = this.combineRoutingAndSignalSessions({
|
|
634
|
+
inputSession: params.session,
|
|
635
|
+
signalSession: signalResult.updatedSession,
|
|
636
|
+
routingSession: routingResult.session,
|
|
637
|
+
});
|
|
638
|
+
// Explicit dataUpdate from the signal's merged directive lands last
|
|
553
639
|
if (signalResult.mergedDirective?.dataUpdate) {
|
|
554
|
-
updatedSession = (0,
|
|
640
|
+
updatedSession = (0, index_js_1.mergeCollected)(updatedSession, signalResult.mergedDirective.dataUpdate);
|
|
555
641
|
}
|
|
556
|
-
// Use routing result for flow/step, but carry signal session state
|
|
557
|
-
// Merge routing session changes on top of signal session
|
|
558
|
-
const routingSession = routingResult.session;
|
|
559
|
-
updatedSession = {
|
|
560
|
-
...updatedSession,
|
|
561
|
-
currentFlow: routingSession.currentFlow,
|
|
562
|
-
currentStep: routingSession.currentStep,
|
|
563
|
-
flowHistory: routingSession.flowHistory,
|
|
564
|
-
pendingDirective: routingSession.pendingDirective,
|
|
565
|
-
};
|
|
566
642
|
const isFlowComplete = routingResult.isFlowComplete;
|
|
567
|
-
// PRE-EXTRACTION: same logic as below — extract data from user message
|
|
643
|
+
// PRE-EXTRACTION: same logic as below — extract data from user message.
|
|
644
|
+
// Reuses the routing-skip check's step-scoped extraction when it already
|
|
645
|
+
// ran this turn (at most ONE extraction LLM call per turn).
|
|
568
646
|
if (routingResult.selectedFlow && !isFlowComplete) {
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
647
|
+
let extractedData;
|
|
648
|
+
if (routingSkipCheck.extractionRan) {
|
|
649
|
+
extractedData = routingSkipCheck.extractedData;
|
|
650
|
+
}
|
|
651
|
+
else if (this.shouldPreExtractData(routingResult.selectedFlow)) {
|
|
652
|
+
index_js_1.logger.debug(`[ResponsePipeline] Pre-extracting data for flow: ${routingResult.selectedFlow.title}`);
|
|
653
|
+
extractedData = await this.preExtractFlowData({
|
|
572
654
|
route: routingResult.selectedFlow,
|
|
573
655
|
history: params.history,
|
|
574
656
|
context: params.context,
|
|
575
657
|
session: updatedSession,
|
|
576
658
|
signal: params.signal,
|
|
577
659
|
});
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
660
|
+
}
|
|
661
|
+
if (extractedData && Object.keys(extractedData).length > 0) {
|
|
662
|
+
index_js_1.logger.debug(`[ResponsePipeline] Pre-extracted data:`, extractedData);
|
|
663
|
+
updatedSession = (0, index_js_1.mergeCollected)(updatedSession, extractedData);
|
|
664
|
+
await this.updateCollectedData(extractedData);
|
|
583
665
|
}
|
|
584
666
|
}
|
|
585
667
|
// Determine next step
|
|
@@ -595,9 +677,10 @@ class ResponsePipeline {
|
|
|
595
677
|
selectedStep: stepResult.nextStep,
|
|
596
678
|
responseDirectives: routingResult.responseDirectives,
|
|
597
679
|
session: stepResult.session,
|
|
598
|
-
isFlowComplete: stepResult.
|
|
680
|
+
isFlowComplete: stepResult.isFlowComplete,
|
|
599
681
|
signalFirings: signalResult.firings,
|
|
600
682
|
signalPreDirective: signalResult.mergedDirective || undefined,
|
|
683
|
+
endedFlows: routingResult.endedFlows,
|
|
601
684
|
};
|
|
602
685
|
}
|
|
603
686
|
// ── No signal processor: existing behavior (zero overhead) ────────────
|
|
@@ -606,30 +689,37 @@ class ResponsePipeline {
|
|
|
606
689
|
history: params.history,
|
|
607
690
|
context: params.context,
|
|
608
691
|
signal: params.signal,
|
|
692
|
+
allowedFlows: params.allowedFlows,
|
|
609
693
|
});
|
|
610
694
|
let updatedSession = routingResult.session;
|
|
611
695
|
const isFlowComplete = routingResult.isFlowComplete;
|
|
612
696
|
// PRE-EXTRACTION: If entering a flow that collects data, extract data from user message first
|
|
613
|
-
// This allows us to skip steps whose data is already provided
|
|
697
|
+
// This allows us to skip steps whose data is already provided.
|
|
698
|
+
// Reuses the routing-skip check's step-scoped extraction when it already
|
|
699
|
+
// ran this turn — at most ONE extraction LLM call per turn.
|
|
614
700
|
if (routingResult.selectedFlow && !isFlowComplete) {
|
|
615
701
|
// Always pre-extract when flow collects data (not just on new flow entry)
|
|
616
702
|
// This ensures step selection has the most up-to-date data
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
703
|
+
let extractedData;
|
|
704
|
+
if (routingSkipCheck.extractionRan) {
|
|
705
|
+
extractedData = routingSkipCheck.extractedData;
|
|
706
|
+
}
|
|
707
|
+
else if (this.shouldPreExtractData(routingResult.selectedFlow)) {
|
|
708
|
+
index_js_1.logger.debug(`[ResponsePipeline] Pre-extracting data for flow: ${routingResult.selectedFlow.title}`);
|
|
709
|
+
extractedData = await this.preExtractFlowData({
|
|
620
710
|
route: routingResult.selectedFlow,
|
|
621
711
|
history: params.history,
|
|
622
712
|
context: params.context,
|
|
623
713
|
session: updatedSession,
|
|
624
714
|
signal: params.signal,
|
|
625
715
|
});
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
716
|
+
}
|
|
717
|
+
if (extractedData && Object.keys(extractedData).length > 0) {
|
|
718
|
+
index_js_1.logger.debug(`[ResponsePipeline] Pre-extracted data:`, extractedData);
|
|
719
|
+
// Merge pre-extracted data into session before step selection
|
|
720
|
+
updatedSession = (0, index_js_1.mergeCollected)(updatedSession, extractedData);
|
|
721
|
+
// Also update agent's collected data
|
|
722
|
+
await this.updateCollectedData(extractedData);
|
|
633
723
|
}
|
|
634
724
|
}
|
|
635
725
|
// Determine next step using pipeline method for consistency
|
|
@@ -645,12 +735,14 @@ class ResponsePipeline {
|
|
|
645
735
|
selectedStep: stepResult.nextStep, // Use the determined next step
|
|
646
736
|
responseDirectives: routingResult.responseDirectives,
|
|
647
737
|
session: stepResult.session,
|
|
648
|
-
//
|
|
649
|
-
|
|
738
|
+
// determineNextStep owns the verdict: a branch that resolved a position
|
|
739
|
+
// (new flow, or a step of this one) overrides the router's proposal.
|
|
740
|
+
isFlowComplete: stepResult.isFlowComplete,
|
|
741
|
+
endedFlows: routingResult.endedFlows,
|
|
650
742
|
};
|
|
651
743
|
}
|
|
652
744
|
catch (error) {
|
|
653
|
-
throw
|
|
745
|
+
throw ResponseGenerationError_js_1.ResponseGenerationError.fromError(error, 'routing_optimization', params);
|
|
654
746
|
}
|
|
655
747
|
}
|
|
656
748
|
/**
|
|
@@ -678,7 +770,7 @@ class ResponsePipeline {
|
|
|
678
770
|
const currentStep = isInSameFlow && session.currentStep
|
|
679
771
|
? selectedFlow.getStep(session.currentStep.id)
|
|
680
772
|
: undefined;
|
|
681
|
-
|
|
773
|
+
index_js_1.logger.debug(`[ResponsePipeline] Step determination: flow match=${isInSameFlow}, currentFlow=${session.currentFlow?.id}, selectedFlow=${selectedFlow.id}, currentStep=${currentStep?.id || 'none'}`);
|
|
682
774
|
// STEP 1 (Algorithm 1): branches win over linear chain
|
|
683
775
|
if (currentStep?.branches && currentStep.branches.length > 0) {
|
|
684
776
|
const branchResult = await this.evaluateStepBranches(currentStep, selectedFlow, session, context);
|
|
@@ -696,16 +788,16 @@ class ResponsePipeline {
|
|
|
696
788
|
if (!nextStep) {
|
|
697
789
|
// Get candidate steps based on current position in the flow
|
|
698
790
|
const candidates = await this.flowRouter.getCandidateStepsWithConditions(selectedFlow, currentStep, // Pass current step instead of undefined to maintain progression
|
|
699
|
-
(0,
|
|
700
|
-
|
|
791
|
+
(0, template_js_1.createTemplateContext)({ data: session.data, session, context }));
|
|
792
|
+
index_js_1.logger.debug(`[ResponsePipeline] Found ${candidates.length} candidate steps${currentStep ? ' from current step ' + currentStep.id : ' (new flow entry)'}`);
|
|
701
793
|
if (candidates.length > 0) {
|
|
702
794
|
nextStep = candidates[0].step;
|
|
703
|
-
|
|
795
|
+
index_js_1.logger.debug(`[ResponsePipeline] Using first valid step: ${nextStep.id}${currentStep ? ' (progressing from ' + currentStep.id + ')' : ' for new flow'}`);
|
|
704
796
|
}
|
|
705
797
|
else {
|
|
706
798
|
// Fallback to initial step even if it should be skipped
|
|
707
799
|
nextStep = selectedFlow.initialStep;
|
|
708
|
-
|
|
800
|
+
index_js_1.logger.warn(`[FlowConfigurationError] No valid steps found: all candidates were skipped in flow. Falling back to initial step "${nextStep.id}". Review step skip conditions.`);
|
|
709
801
|
}
|
|
710
802
|
}
|
|
711
803
|
}
|
|
@@ -717,7 +809,7 @@ class ResponsePipeline {
|
|
|
717
809
|
if (missingRequires.length > 0) {
|
|
718
810
|
const warning = `[FlowConfigurationError] Cannot advance to step "${nextStep.description || nextStep.id}": ` +
|
|
719
811
|
`missing required fields [${missingRequires.join(', ')}]. Staying at current step. Ensure preceding steps collect these fields.`;
|
|
720
|
-
|
|
812
|
+
index_js_1.logger.warn(warning);
|
|
721
813
|
console.warn(warning);
|
|
722
814
|
// Stay at the current step - don't enter the next one
|
|
723
815
|
const currentStepId = session.currentStep?.id;
|
|
@@ -725,82 +817,101 @@ class ResponsePipeline {
|
|
|
725
817
|
const currentStepInstance = selectedFlow.getStep(currentStepId);
|
|
726
818
|
if (currentStepInstance) {
|
|
727
819
|
nextStep = currentStepInstance;
|
|
728
|
-
|
|
820
|
+
index_js_1.logger.debug(`[ResponsePipeline] Staying at current step: ${nextStep.id} due to missing requires`);
|
|
729
821
|
}
|
|
730
822
|
}
|
|
731
823
|
}
|
|
732
824
|
else {
|
|
733
|
-
session = (0,
|
|
734
|
-
|
|
825
|
+
session = (0, index_js_1.enterStep)(session, nextStep.id, nextStep.description);
|
|
826
|
+
index_js_1.logger.debug(`[ResponsePipeline] Entered step: ${nextStep.id}`);
|
|
735
827
|
}
|
|
736
828
|
}
|
|
737
829
|
else {
|
|
738
|
-
session = (0,
|
|
739
|
-
|
|
830
|
+
session = (0, index_js_1.enterStep)(session, nextStep.id, nextStep.description);
|
|
831
|
+
index_js_1.logger.debug(`[ResponsePipeline] Entered step: ${nextStep.id}`);
|
|
740
832
|
}
|
|
741
833
|
return { nextStep, session, flowTransition: false };
|
|
742
834
|
}
|
|
743
835
|
/**
|
|
744
|
-
* Routing skip
|
|
745
|
-
* When the current step declares `collect` fields AND
|
|
746
|
-
* at least one of those fields from the user's message,
|
|
836
|
+
* Routing skip check (Requirements 20.1, 20.2, 20.3):
|
|
837
|
+
* When the current step declares `collect` fields AND step-scoped extraction
|
|
838
|
+
* populates at least one of those fields from the user's message, the caller
|
|
839
|
+
* skips routing for this turn (`skipResult`).
|
|
747
840
|
*
|
|
748
|
-
*
|
|
749
|
-
*
|
|
841
|
+
* The extraction is scoped to EXACTLY this step's collect fields — incidental
|
|
842
|
+
* mentions of other (e.g. other-flow) fields cannot pin the routing decision.
|
|
843
|
+
* It is skipped entirely when every collect field is already populated.
|
|
844
|
+
*
|
|
845
|
+
* Always returns what the check did so the caller can reuse the single
|
|
846
|
+
* extraction result in its normal path instead of extracting twice:
|
|
847
|
+
* - `extractionRan` — whether an extraction LLM call was made this turn.
|
|
848
|
+
* - `extractedData` — that call's result (empty when nothing found / not run).
|
|
750
849
|
*/
|
|
751
850
|
async attemptRoutingSkipForCollect(params) {
|
|
752
851
|
const { session } = params;
|
|
852
|
+
const notApplicable = { extractionRan: false, extractedData: {} };
|
|
753
853
|
// Only applies when we already have a current flow and step
|
|
754
854
|
if (!session.currentFlow || !session.currentStep) {
|
|
755
|
-
return
|
|
855
|
+
return notApplicable;
|
|
756
856
|
}
|
|
757
857
|
// Also skip this optimization if there's a pending directive (it takes priority)
|
|
758
858
|
if (session.pendingDirective) {
|
|
759
|
-
return
|
|
859
|
+
return notApplicable;
|
|
760
860
|
}
|
|
761
861
|
// Look up the actual Flow and Step objects to access `collect`
|
|
762
862
|
const currentFlow = this.getFlows().find((f) => f.id === session.currentFlow?.id);
|
|
763
863
|
if (!currentFlow) {
|
|
764
|
-
return
|
|
864
|
+
return notApplicable;
|
|
765
865
|
}
|
|
766
866
|
const currentStep = currentFlow.getStep(session.currentStep.id);
|
|
767
867
|
if (!currentStep || !currentStep.collect || currentStep.collect.length === 0) {
|
|
768
|
-
return
|
|
868
|
+
return notApplicable;
|
|
769
869
|
}
|
|
770
|
-
// We have a step with collect fields. Run pre-extraction to see if the
|
|
771
|
-
// user's message populates any of them.
|
|
772
870
|
const collectFields = currentStep.collect;
|
|
871
|
+
// Every relevant field already set — the skip cannot fire; don't spend
|
|
872
|
+
// an extraction LLM call probing for it.
|
|
873
|
+
const sessionRecord = (session.data ?? {});
|
|
874
|
+
const allPopulated = collectFields.every((field) => {
|
|
875
|
+
const value = sessionRecord[String(field)];
|
|
876
|
+
return value !== undefined && value !== null;
|
|
877
|
+
});
|
|
878
|
+
if (allPopulated) {
|
|
879
|
+
return notApplicable;
|
|
880
|
+
}
|
|
773
881
|
// Snapshot current data for comparison
|
|
774
|
-
const dataBefore = { ...
|
|
775
|
-
//
|
|
882
|
+
const dataBefore = { ...sessionRecord };
|
|
883
|
+
// Step-scoped pre-extraction: see if the user's message populates any of
|
|
884
|
+
// THIS step's collect fields.
|
|
776
885
|
const extractedData = await this.preExtractFlowData({
|
|
777
886
|
route: currentFlow,
|
|
778
887
|
history: params.history,
|
|
779
888
|
context: params.context,
|
|
780
889
|
session,
|
|
781
890
|
signal: params.signal,
|
|
891
|
+
restrictToFields: collectFields.map(String),
|
|
782
892
|
});
|
|
783
893
|
if (!extractedData || Object.keys(extractedData).length === 0) {
|
|
784
|
-
return
|
|
894
|
+
return { extractionRan: true, extractedData: {} };
|
|
785
895
|
}
|
|
786
896
|
// Determine which collect fields were newly populated by pre-extraction
|
|
897
|
+
const extractedRecord = extractedData;
|
|
787
898
|
const populatedCollectFields = [];
|
|
788
899
|
for (const field of collectFields) {
|
|
789
|
-
const key = field;
|
|
790
|
-
const hadValue = dataBefore[
|
|
791
|
-
const hasNewValue =
|
|
900
|
+
const key = String(field);
|
|
901
|
+
const hadValue = dataBefore[key] !== undefined && dataBefore[key] !== null;
|
|
902
|
+
const hasNewValue = extractedRecord[key] !== undefined && extractedRecord[key] !== null;
|
|
792
903
|
if (hasNewValue && !hadValue) {
|
|
793
904
|
populatedCollectFields.push(key);
|
|
794
905
|
}
|
|
795
906
|
}
|
|
796
907
|
if (populatedCollectFields.length === 0) {
|
|
797
908
|
// Pre-extraction didn't populate any declared collect field — no skip
|
|
798
|
-
return
|
|
909
|
+
return { extractionRan: true, extractedData };
|
|
799
910
|
}
|
|
800
911
|
// ROUTING SKIP: pre-extraction populated collect fields → retain current flow/step
|
|
801
|
-
|
|
912
|
+
index_js_1.logger.debug(`[ResponsePipeline] Routing skip: pre-extraction populated collect fields [${populatedCollectFields.join(', ')}] for step "${currentStep.id}" — skipping FlowRouter`);
|
|
802
913
|
// Merge extracted data into session
|
|
803
|
-
const updatedSession = (0,
|
|
914
|
+
const updatedSession = (0, index_js_1.mergeCollected)(session, extractedData);
|
|
804
915
|
await this.updateCollectedData(extractedData);
|
|
805
916
|
// Determine next step using pipeline method for consistency
|
|
806
917
|
// Pass the current flow/step as the routing result (retained)
|
|
@@ -812,11 +923,15 @@ class ResponsePipeline {
|
|
|
812
923
|
context: params.context,
|
|
813
924
|
});
|
|
814
925
|
return {
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
926
|
+
extractionRan: true,
|
|
927
|
+
extractedData,
|
|
928
|
+
skipResult: {
|
|
929
|
+
selectedFlow: stepResult.flowChanged || currentFlow,
|
|
930
|
+
selectedStep: stepResult.nextStep,
|
|
931
|
+
responseDirectives: undefined,
|
|
932
|
+
session: stepResult.session,
|
|
933
|
+
isFlowComplete: stepResult.isFlowComplete,
|
|
934
|
+
},
|
|
820
935
|
};
|
|
821
936
|
}
|
|
822
937
|
/**
|
|
@@ -835,20 +950,43 @@ class ResponsePipeline {
|
|
|
835
950
|
const hasDataCollectionSteps = steps.some(step => step.collect && step.collect.length > 0);
|
|
836
951
|
return hasDataCollectionSteps;
|
|
837
952
|
}
|
|
953
|
+
/**
|
|
954
|
+
* Build an extraction schema limited to the given subset of agent schema
|
|
955
|
+
* fields. Used by the routing-skip probe so only the current step's collect
|
|
956
|
+
* fields are visible to the extractor.
|
|
957
|
+
*/
|
|
958
|
+
buildFieldRestrictedSchema(agentSchema, fields) {
|
|
959
|
+
const properties = {};
|
|
960
|
+
for (const field of fields) {
|
|
961
|
+
const prop = agentSchema.properties?.[field];
|
|
962
|
+
if (prop) {
|
|
963
|
+
properties[field] = prop;
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
return {
|
|
967
|
+
type: "object",
|
|
968
|
+
description: `Extraction restricted to these fields: ${fields.join(', ')}`,
|
|
969
|
+
properties,
|
|
970
|
+
additionalProperties: false,
|
|
971
|
+
};
|
|
972
|
+
}
|
|
838
973
|
/**
|
|
839
974
|
* Pre-extract data from user message when entering a flow
|
|
840
975
|
* This allows skipping steps whose data is already provided
|
|
841
976
|
*/
|
|
842
977
|
async preExtractFlowData(params) {
|
|
843
|
-
const { route: flow, history, signal } = params;
|
|
978
|
+
const { route: flow, history, signal, restrictToFields } = params;
|
|
844
979
|
// Build a schema for data extraction based on flow's fields
|
|
845
|
-
const
|
|
846
|
-
if (!
|
|
847
|
-
|
|
980
|
+
const agentSchema = this.getSchema();
|
|
981
|
+
if (!agentSchema) {
|
|
982
|
+
index_js_1.logger.warn(`[ResponsePipeline] No schema available for pre-extraction`);
|
|
848
983
|
return {};
|
|
849
984
|
}
|
|
985
|
+
const extractionSchema = restrictToFields
|
|
986
|
+
? this.buildFieldRestrictedSchema(agentSchema, restrictToFields)
|
|
987
|
+
: agentSchema;
|
|
850
988
|
// Get last user message
|
|
851
|
-
const lastMessage = (0,
|
|
989
|
+
const lastMessage = (0, index_js_1.getLastMessageFromHistory)(history);
|
|
852
990
|
// Build extraction prompt
|
|
853
991
|
const extractionPrompt = [
|
|
854
992
|
`Extract any relevant information from the user's message that matches the following data fields.`,
|
|
@@ -859,15 +997,20 @@ class ResponsePipeline {
|
|
|
859
997
|
`Extract data for these fields if present:`,
|
|
860
998
|
];
|
|
861
999
|
// Add field descriptions
|
|
862
|
-
if (
|
|
863
|
-
extractionPrompt.push(`
|
|
1000
|
+
if (restrictToFields) {
|
|
1001
|
+
extractionPrompt.push(`Only these fields: ${restrictToFields.join(', ')}`);
|
|
864
1002
|
}
|
|
865
|
-
|
|
866
|
-
|
|
1003
|
+
else {
|
|
1004
|
+
if (flow.requiredFields) {
|
|
1005
|
+
extractionPrompt.push(`Required fields: ${flow.requiredFields.join(', ')}`);
|
|
1006
|
+
}
|
|
1007
|
+
if (flow.optionalFields) {
|
|
1008
|
+
extractionPrompt.push(`Optional fields: ${flow.optionalFields.join(', ')}`);
|
|
1009
|
+
}
|
|
867
1010
|
}
|
|
868
1011
|
extractionPrompt.push(``, `Return ONLY the extracted data as JSON. If no data can be extracted, return an empty object {}.`);
|
|
869
1012
|
// Convert Event[] to HistoryItem[] for provider call
|
|
870
|
-
const historyItems = (0,
|
|
1013
|
+
const historyItems = (0, index_js_1.eventsToHistory)(history);
|
|
871
1014
|
// Call AI to extract data
|
|
872
1015
|
try {
|
|
873
1016
|
const result = await this.options.provider.generateMessage({
|
|
@@ -886,7 +1029,7 @@ class ResponsePipeline {
|
|
|
886
1029
|
return result.structured || {};
|
|
887
1030
|
}
|
|
888
1031
|
catch (error) {
|
|
889
|
-
|
|
1032
|
+
index_js_1.logger.error(`[ResponsePipeline] Pre-extraction failed:`, error);
|
|
890
1033
|
return {};
|
|
891
1034
|
}
|
|
892
1035
|
}
|