@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
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
* Response processing utilities shared between respond() and respondStream() methods
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import type {
|
|
5
|
+
import type { EndedFlow,
|
|
6
6
|
AgentOptions,
|
|
7
7
|
Event,
|
|
8
8
|
SessionState,
|
|
9
9
|
Directive,
|
|
10
10
|
StructuredSchema,
|
|
11
|
-
} from "../types";
|
|
12
|
-
import type { SignalFiring } from "../types/signals";
|
|
11
|
+
} from "../types/index.js";
|
|
12
|
+
import type { SignalFiring } from "../types/signals.js";
|
|
13
13
|
import {
|
|
14
14
|
createSession,
|
|
15
15
|
enterStep,
|
|
@@ -18,16 +18,16 @@ import {
|
|
|
18
18
|
historyToEvents,
|
|
19
19
|
eventsToHistory,
|
|
20
20
|
getLastMessageFromHistory,
|
|
21
|
-
} from "../utils";
|
|
22
|
-
import { enterFlow } from "../utils/session";
|
|
23
|
-
import { createTemplateContext } from "../utils/template";
|
|
24
|
-
import { Flow } from "./Flow";
|
|
25
|
-
import { Step, FlowConfigurationError } from "../core/Step";
|
|
26
|
-
import { FlowRouter } from "./FlowRouter";
|
|
27
|
-
import { evaluateBranches, createAiConditionEvaluator } from "./BranchEvaluator";
|
|
28
|
-
import { DirectiveChainTracker } from "./DirectiveChainTracker";
|
|
29
|
-
import { ResponseGenerationError } from "./ResponseGenerationError";
|
|
30
|
-
import type { SignalCoordinator } from "./SignalCoordinator";
|
|
21
|
+
} from "../utils/index.js";
|
|
22
|
+
import { enterFlow } from "../utils/session.js";
|
|
23
|
+
import { createTemplateContext } from "../utils/template.js";
|
|
24
|
+
import { Flow } from "./Flow.js";
|
|
25
|
+
import { Step, FlowConfigurationError } from "../core/Step.js";
|
|
26
|
+
import { FlowRouter } from "./FlowRouter.js";
|
|
27
|
+
import { evaluateBranches, createAiConditionEvaluator } from "./BranchEvaluator.js";
|
|
28
|
+
import { DirectiveChainTracker } from "./DirectiveChainTracker.js";
|
|
29
|
+
import { ResponseGenerationError } from "./ResponseGenerationError.js";
|
|
30
|
+
import type { SignalCoordinator } from "./SignalCoordinator.js";
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* Position fields on a Directive that represent a navigation decision.
|
|
@@ -51,6 +51,27 @@ export function hasDirectivePositionField<TContext = unknown, TData = unknown>(
|
|
|
51
51
|
);
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Compute the per-key data writes the signal phase applied to a session.
|
|
56
|
+
* The signal phase and routing start from the same input session, so any
|
|
57
|
+
* key whose value differs between the input and the signal output was
|
|
58
|
+
* written by the signal phase alone (handler `updateData` calls).
|
|
59
|
+
*/
|
|
60
|
+
function diffSignalDataWrites<TData>(
|
|
61
|
+
before: Partial<TData> | undefined,
|
|
62
|
+
after: Partial<TData> | undefined,
|
|
63
|
+
): Partial<TData> {
|
|
64
|
+
const beforeData = (before ?? {}) as Record<string, unknown>;
|
|
65
|
+
const afterData = (after ?? {}) as Record<string, unknown>;
|
|
66
|
+
const writes: Record<string, unknown> = {};
|
|
67
|
+
for (const key of Object.keys(afterData)) {
|
|
68
|
+
if (afterData[key] !== beforeData[key]) {
|
|
69
|
+
writes[key] = afterData[key];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return writes as Partial<TData>;
|
|
73
|
+
}
|
|
74
|
+
|
|
54
75
|
export interface ResponsePreparationResult<TContext, TData = unknown> {
|
|
55
76
|
effectiveContext: TContext;
|
|
56
77
|
session: SessionState<TData>;
|
|
@@ -65,6 +86,8 @@ export interface RoutingResult<TContext, TData = unknown> {
|
|
|
65
86
|
session: SessionState<TData>;
|
|
66
87
|
isFlowComplete: boolean;
|
|
67
88
|
completedFlows?: Flow<TContext, TData>[];
|
|
89
|
+
/** Flows exited via pendingDirective redirects/resets this turn. */
|
|
90
|
+
endedFlows?: EndedFlow[];
|
|
68
91
|
}
|
|
69
92
|
|
|
70
93
|
/**
|
|
@@ -154,8 +177,10 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
154
177
|
history: Event[];
|
|
155
178
|
context: TContext;
|
|
156
179
|
signal?: AbortSignal;
|
|
180
|
+
/** Restrict ROUTING candidates; directive targets still use the full registry. */
|
|
181
|
+
allowedFlows?: string[];
|
|
157
182
|
}): Promise<RoutingResult<TContext, TData>> {
|
|
158
|
-
const { session, history, context, signal } = params;
|
|
183
|
+
const { session, history, context, signal, allowedFlows } = params;
|
|
159
184
|
|
|
160
185
|
// PHASE 2: ROUTING + STEP SELECTION - Determine which flow and step to use (combined)
|
|
161
186
|
let selectedFlow: Flow<TContext, TData> | undefined;
|
|
@@ -164,9 +189,23 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
164
189
|
let isFlowComplete = false;
|
|
165
190
|
let completedFlows: Flow<TContext, TData>[] = [];
|
|
166
191
|
let targetSession = session;
|
|
192
|
+
// Flows exited this turn via pendingDirective redirect/reset
|
|
193
|
+
const endedFlows: EndedFlow[] = [];
|
|
194
|
+
let exitPrevFlowId: string | undefined;
|
|
195
|
+
let exitPrevFlowTitle: string | undefined;
|
|
196
|
+
let exitReason: EndedFlow['reason'] | undefined;
|
|
167
197
|
|
|
168
198
|
// Get flows early since we need them for pending directives
|
|
169
199
|
const flows = this.getFlows();
|
|
200
|
+
// Routing candidates may be narrowed for this turn (entry pins); the
|
|
201
|
+
// pendingDirective applier below still resolves targets against the FULL
|
|
202
|
+
// registry so declared redirects always resolve.
|
|
203
|
+
const routingFlows =
|
|
204
|
+
allowedFlows && allowedFlows.length > 0
|
|
205
|
+
? flows.filter(
|
|
206
|
+
(f) => allowedFlows.includes(f.id) || allowedFlows.includes(f.title),
|
|
207
|
+
)
|
|
208
|
+
: flows;
|
|
170
209
|
|
|
171
210
|
// Check for pending directive from previous flow completion or external dispatch
|
|
172
211
|
if (targetSession.pendingDirective) {
|
|
@@ -195,8 +234,16 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
195
234
|
pendingDirective: nextDirective,
|
|
196
235
|
};
|
|
197
236
|
|
|
237
|
+
// Capture the flow we're leaving so directive-driven exits surface on
|
|
238
|
+
// the response (endedFlows).
|
|
239
|
+
exitPrevFlowId = targetSession.currentFlow?.id;
|
|
240
|
+
exitPrevFlowTitle = exitPrevFlowId
|
|
241
|
+
? flows.find((f) => f.id === exitPrevFlowId)?.title
|
|
242
|
+
: undefined;
|
|
243
|
+
|
|
198
244
|
// Apply the directive: resolve position field to a flow/step
|
|
199
245
|
if (directive.goTo) {
|
|
246
|
+
exitReason = 'goto';
|
|
200
247
|
const flowTarget = typeof directive.goTo === 'string'
|
|
201
248
|
? directive.goTo
|
|
202
249
|
: directive.goTo.flow;
|
|
@@ -283,6 +330,7 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
283
330
|
}
|
|
284
331
|
}
|
|
285
332
|
} else if (directive.reset) {
|
|
333
|
+
exitReason = 'reset';
|
|
286
334
|
// Reset current flow
|
|
287
335
|
if (targetSession.currentFlow) {
|
|
288
336
|
const currentFlow = flows.find(r => r.id === targetSession.currentFlow?.id);
|
|
@@ -316,10 +364,19 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
316
364
|
// Skip FlowRouter.decideFlowAndStep — the directive resolved the position
|
|
317
365
|
}
|
|
318
366
|
|
|
319
|
-
|
|
320
|
-
|
|
367
|
+
if (
|
|
368
|
+
exitReason &&
|
|
369
|
+
exitPrevFlowId &&
|
|
370
|
+
(!selectedFlow || selectedFlow.id !== exitPrevFlowId)
|
|
371
|
+
) {
|
|
372
|
+
endedFlows.push({ flowId: exitPrevFlowId, title: exitPrevFlowTitle, reason: exitReason });
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// If no pending transition or transition handled, do normal routing.
|
|
376
|
+
// Candidates honor allowedFlows; completion scoring runs over the same set.
|
|
377
|
+
if (routingFlows.length > 0 && !selectedFlow) {
|
|
321
378
|
const orchestration = await this.flowRouter.decideFlowAndStep({
|
|
322
|
-
flows:
|
|
379
|
+
flows: routingFlows,
|
|
323
380
|
session: targetSession,
|
|
324
381
|
history,
|
|
325
382
|
agentOptions: this.options,
|
|
@@ -350,9 +407,41 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
350
407
|
session: targetSession,
|
|
351
408
|
isFlowComplete,
|
|
352
409
|
completedFlows,
|
|
410
|
+
...(endedFlows.length > 0 ? { endedFlows } : {}),
|
|
353
411
|
};
|
|
354
412
|
}
|
|
355
413
|
|
|
414
|
+
/**
|
|
415
|
+
* Combine a routing-derived session with the signal phase's non-position
|
|
416
|
+
* mutations. The routing session is the base — it owns position state AND
|
|
417
|
+
* data merges such as flow initialData and directive-carried writes; the
|
|
418
|
+
* signal phase's mutations (trigger recording under `signals`, handler
|
|
419
|
+
* data writes) are re-applied on top. Both phases start from the same
|
|
420
|
+
* input session, so their mutations cannot silently collide.
|
|
421
|
+
*/
|
|
422
|
+
private combineRoutingAndSignalSessions(params: {
|
|
423
|
+
inputSession: SessionState<TData>;
|
|
424
|
+
signalSession: SessionState<TData>;
|
|
425
|
+
routingSession: SessionState<TData>;
|
|
426
|
+
}): SessionState<TData> {
|
|
427
|
+
const { inputSession, signalSession, routingSession } = params;
|
|
428
|
+
let combined = routingSession;
|
|
429
|
+
|
|
430
|
+
if (signalSession.signals !== inputSession.signals) {
|
|
431
|
+
combined = { ...combined, signals: signalSession.signals };
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
const signalWrites = diffSignalDataWrites(
|
|
435
|
+
inputSession.data,
|
|
436
|
+
signalSession.data,
|
|
437
|
+
);
|
|
438
|
+
if (Object.keys(signalWrites).length > 0) {
|
|
439
|
+
combined = mergeCollected(combined, signalWrites);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
return combined;
|
|
443
|
+
}
|
|
444
|
+
|
|
356
445
|
/**
|
|
357
446
|
* Determine next step and update session
|
|
358
447
|
*/
|
|
@@ -365,11 +454,23 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
365
454
|
context: TContext;
|
|
366
455
|
/** Merged directive from the directive bus (pre-LLM + post-LLM phases). */
|
|
367
456
|
busDirective?: Directive<TContext, TData>;
|
|
368
|
-
}): Promise<{
|
|
457
|
+
}): Promise<{
|
|
458
|
+
nextStep: Step<TContext, TData> | undefined;
|
|
459
|
+
session: SessionState<TData>;
|
|
460
|
+
flowChanged?: Flow<TContext, TData>;
|
|
461
|
+
/**
|
|
462
|
+
* The turn's authoritative completion verdict — callers must use this, not
|
|
463
|
+
* the `isFlowComplete` they passed in. The router derives its verdict from
|
|
464
|
+
* the LINEAR chain alone (the current step has no successor), before
|
|
465
|
+
* branches run, so what it returns is only a proposal. Branches win over
|
|
466
|
+
* flow completion (Algorithm 1, STEP 1) and this is where that resolves.
|
|
467
|
+
*/
|
|
468
|
+
isFlowComplete: boolean;
|
|
469
|
+
}> {
|
|
369
470
|
const { selectedFlow, selectedStep, session, isFlowComplete, context, busDirective } = params;
|
|
370
471
|
|
|
371
472
|
if (!selectedFlow) {
|
|
372
|
-
return { nextStep: undefined, session };
|
|
473
|
+
return { nextStep: undefined, session, isFlowComplete };
|
|
373
474
|
}
|
|
374
475
|
|
|
375
476
|
// ─── GUARD: directive bus winner with a position field preempts branches ───
|
|
@@ -381,7 +482,7 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
381
482
|
logger.debug(
|
|
382
483
|
`[ResponsePipeline] Directive bus winner has position field — skipping branch evaluation and linear/AI selection`,
|
|
383
484
|
);
|
|
384
|
-
return { nextStep: undefined, session };
|
|
485
|
+
return { nextStep: undefined, session, isFlowComplete };
|
|
385
486
|
}
|
|
386
487
|
|
|
387
488
|
// STEP 1 (Algorithm 1): branches win over linear chain AND flow completion.
|
|
@@ -397,14 +498,21 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
397
498
|
currentStep, selectedFlow, session, context
|
|
398
499
|
);
|
|
399
500
|
if (branchResult) {
|
|
400
|
-
|
|
501
|
+
// A branch that resolved a position overrides the router's completion
|
|
502
|
+
// proposal. Without this, a branch that parks on a step of its own
|
|
503
|
+
// flow (`then: '<stepId>'`, `then: { reset: true }`) keeps
|
|
504
|
+
// isFlowComplete=true, the caller drops the step it just resolved,
|
|
505
|
+
// and the turn ends as a silent completion — no LLM call, empty
|
|
506
|
+
// reply, flow marked completed for the rest of the session.
|
|
507
|
+
const resolvedPosition = Boolean(branchResult.nextStep || branchResult.flowChanged);
|
|
508
|
+
return { ...branchResult, isFlowComplete: resolvedPosition ? false : isFlowComplete };
|
|
401
509
|
}
|
|
402
510
|
// undefined → fall through to linear/AI selection or flow completion
|
|
403
511
|
}
|
|
404
512
|
}
|
|
405
513
|
|
|
406
514
|
if (isFlowComplete) {
|
|
407
|
-
return { nextStep: undefined, session };
|
|
515
|
+
return { nextStep: undefined, session, isFlowComplete: true };
|
|
408
516
|
}
|
|
409
517
|
|
|
410
518
|
let nextStep: Step<TContext, TData>;
|
|
@@ -457,7 +565,7 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
457
565
|
nextStep = currentStepInstance;
|
|
458
566
|
}
|
|
459
567
|
}
|
|
460
|
-
return { nextStep, session };
|
|
568
|
+
return { nextStep, session, isFlowComplete: false };
|
|
461
569
|
}
|
|
462
570
|
}
|
|
463
571
|
|
|
@@ -469,7 +577,7 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
469
577
|
);
|
|
470
578
|
logger.debug(`[ResponsePipeline] Entered step: ${nextStep.id}`);
|
|
471
579
|
|
|
472
|
-
return { nextStep, session: updatedSession };
|
|
580
|
+
return { nextStep, session: updatedSession, isFlowComplete: false };
|
|
473
581
|
}
|
|
474
582
|
|
|
475
583
|
/**
|
|
@@ -679,6 +787,8 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
679
787
|
history: Event[]; // Use Event[] for internal processing
|
|
680
788
|
context: TContext;
|
|
681
789
|
signal?: AbortSignal;
|
|
790
|
+
/** Restrict this turn's routing candidates (entry pins). */
|
|
791
|
+
allowedFlows?: string[];
|
|
682
792
|
}): Promise<{
|
|
683
793
|
selectedFlow?: Flow<TContext, TData>;
|
|
684
794
|
selectedStep?: Step<TContext, TData>;
|
|
@@ -693,16 +803,21 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
693
803
|
signalHalted?: boolean;
|
|
694
804
|
/** Reply text from the halt directive. */
|
|
695
805
|
signalHaltReply?: string;
|
|
806
|
+
/** Flows exited via pendingDirective redirects/resets this turn. */
|
|
807
|
+
endedFlows?: EndedFlow[];
|
|
696
808
|
}> {
|
|
697
809
|
try {
|
|
698
810
|
// Create a fresh chain tracker for this turn (Requirement 22.1)
|
|
699
811
|
this.createChainTracker();
|
|
700
812
|
|
|
701
813
|
// ROUTING SKIP OPTIMIZATION (Requirements 20.1, 20.2, 20.3):
|
|
702
|
-
// When the current step has collect fields AND pre-extraction
|
|
703
|
-
// one of those fields, skip FlowRouter.decideFlowAndStep
|
|
704
|
-
|
|
705
|
-
|
|
814
|
+
// When the current step has collect fields AND step-scoped pre-extraction
|
|
815
|
+
// populates at least one of those fields, skip FlowRouter.decideFlowAndStep
|
|
816
|
+
// for this turn. The check's extraction result is reused by the fallthrough
|
|
817
|
+
// paths below so a turn costs at most ONE extraction LLM call.
|
|
818
|
+
const routingSkipCheck = await this.attemptRoutingSkipForCollect(params);
|
|
819
|
+
if (routingSkipCheck.skipResult) {
|
|
820
|
+
const skipResult = routingSkipCheck.skipResult;
|
|
706
821
|
// Even when routing is skipped, run pre-signal phase if processor is present
|
|
707
822
|
if (this.signalCoordinator.enabled) {
|
|
708
823
|
const signalResult = await this.signalCoordinator.runPrePhase(
|
|
@@ -711,7 +826,7 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
711
826
|
// If signal halts, override the routing skip result
|
|
712
827
|
if (signalResult.mergedDirective?.halt) {
|
|
713
828
|
return {
|
|
714
|
-
...
|
|
829
|
+
...skipResult,
|
|
715
830
|
session: signalResult.updatedSession,
|
|
716
831
|
signalFirings: signalResult.firings,
|
|
717
832
|
signalHalted: true,
|
|
@@ -722,15 +837,20 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
722
837
|
if (hasDirectivePositionField(signalResult.mergedDirective)) {
|
|
723
838
|
return this.signalCoordinator.applyPositionDirective(signalResult);
|
|
724
839
|
}
|
|
725
|
-
// Non-position directive:
|
|
840
|
+
// Non-position directive: keep the skip result (extraction merges,
|
|
841
|
+
// step entry) and re-apply the signal phase's non-position mutations
|
|
726
842
|
return {
|
|
727
|
-
...
|
|
728
|
-
session:
|
|
843
|
+
...skipResult,
|
|
844
|
+
session: this.combineRoutingAndSignalSessions({
|
|
845
|
+
inputSession: params.session,
|
|
846
|
+
signalSession: signalResult.updatedSession,
|
|
847
|
+
routingSession: skipResult.session,
|
|
848
|
+
}),
|
|
729
849
|
signalFirings: signalResult.firings,
|
|
730
850
|
signalPreDirective: signalResult.mergedDirective || undefined,
|
|
731
851
|
};
|
|
732
852
|
}
|
|
733
|
-
return
|
|
853
|
+
return skipResult;
|
|
734
854
|
}
|
|
735
855
|
|
|
736
856
|
// ── PARALLEL PRE-SIGNAL PHASE + ROUTING (Algorithm 5) ────────────────
|
|
@@ -747,6 +867,7 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
747
867
|
history: params.history,
|
|
748
868
|
context: params.context,
|
|
749
869
|
signal: params.signal,
|
|
870
|
+
allowedFlows: params.allowedFlows,
|
|
750
871
|
}),
|
|
751
872
|
]);
|
|
752
873
|
|
|
@@ -770,44 +891,45 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
770
891
|
|
|
771
892
|
// ── Requirement 8.4: non-position directive → use routing, propagate augmentation ──
|
|
772
893
|
// ── Requirement 8.5: no directive → use routing as-is ─────────────
|
|
773
|
-
|
|
894
|
+
// Base = routed session (position state AND router data merges such as
|
|
895
|
+
// flow initialData survive); the signal phase's non-position mutations
|
|
896
|
+
// (trigger state, handler data writes) are re-applied on top.
|
|
897
|
+
let updatedSession = this.combineRoutingAndSignalSessions({
|
|
898
|
+
inputSession: params.session,
|
|
899
|
+
signalSession: signalResult.updatedSession,
|
|
900
|
+
routingSession: routingResult.session,
|
|
901
|
+
});
|
|
774
902
|
|
|
775
|
-
//
|
|
903
|
+
// Explicit dataUpdate from the signal's merged directive lands last
|
|
776
904
|
if (signalResult.mergedDirective?.dataUpdate) {
|
|
777
905
|
updatedSession = mergeCollected(updatedSession, signalResult.mergedDirective.dataUpdate);
|
|
778
906
|
}
|
|
779
907
|
|
|
780
|
-
// Use routing result for flow/step, but carry signal session state
|
|
781
|
-
// Merge routing session changes on top of signal session
|
|
782
|
-
const routingSession = routingResult.session;
|
|
783
|
-
updatedSession = {
|
|
784
|
-
...updatedSession,
|
|
785
|
-
currentFlow: routingSession.currentFlow,
|
|
786
|
-
currentStep: routingSession.currentStep,
|
|
787
|
-
flowHistory: routingSession.flowHistory,
|
|
788
|
-
pendingDirective: routingSession.pendingDirective,
|
|
789
|
-
};
|
|
790
|
-
|
|
791
908
|
const isFlowComplete = routingResult.isFlowComplete;
|
|
792
909
|
|
|
793
|
-
// PRE-EXTRACTION: same logic as below — extract data from user message
|
|
910
|
+
// PRE-EXTRACTION: same logic as below — extract data from user message.
|
|
911
|
+
// Reuses the routing-skip check's step-scoped extraction when it already
|
|
912
|
+
// ran this turn (at most ONE extraction LLM call per turn).
|
|
794
913
|
if (routingResult.selectedFlow && !isFlowComplete) {
|
|
795
|
-
|
|
914
|
+
let extractedData: Partial<TData> | undefined;
|
|
915
|
+
if (routingSkipCheck.extractionRan) {
|
|
916
|
+
extractedData = routingSkipCheck.extractedData;
|
|
917
|
+
} else if (this.shouldPreExtractData(routingResult.selectedFlow)) {
|
|
796
918
|
logger.debug(
|
|
797
919
|
`[ResponsePipeline] Pre-extracting data for flow: ${routingResult.selectedFlow.title}`
|
|
798
920
|
);
|
|
799
|
-
|
|
921
|
+
extractedData = await this.preExtractFlowData({
|
|
800
922
|
route: routingResult.selectedFlow,
|
|
801
923
|
history: params.history,
|
|
802
924
|
context: params.context,
|
|
803
925
|
session: updatedSession,
|
|
804
926
|
signal: params.signal,
|
|
805
927
|
});
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
928
|
+
}
|
|
929
|
+
if (extractedData && Object.keys(extractedData).length > 0) {
|
|
930
|
+
logger.debug(`[ResponsePipeline] Pre-extracted data:`, extractedData);
|
|
931
|
+
updatedSession = mergeCollected(updatedSession, extractedData);
|
|
932
|
+
await this.updateCollectedData(extractedData);
|
|
811
933
|
}
|
|
812
934
|
}
|
|
813
935
|
|
|
@@ -825,9 +947,10 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
825
947
|
selectedStep: stepResult.nextStep,
|
|
826
948
|
responseDirectives: routingResult.responseDirectives,
|
|
827
949
|
session: stepResult.session,
|
|
828
|
-
isFlowComplete: stepResult.
|
|
950
|
+
isFlowComplete: stepResult.isFlowComplete,
|
|
829
951
|
signalFirings: signalResult.firings,
|
|
830
952
|
signalPreDirective: signalResult.mergedDirective || undefined,
|
|
953
|
+
endedFlows: routingResult.endedFlows,
|
|
831
954
|
};
|
|
832
955
|
}
|
|
833
956
|
|
|
@@ -837,39 +960,45 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
837
960
|
history: params.history,
|
|
838
961
|
context: params.context,
|
|
839
962
|
signal: params.signal,
|
|
963
|
+
allowedFlows: params.allowedFlows,
|
|
840
964
|
});
|
|
841
965
|
|
|
842
966
|
let updatedSession = routingResult.session;
|
|
843
967
|
const isFlowComplete = routingResult.isFlowComplete;
|
|
844
968
|
|
|
845
969
|
// PRE-EXTRACTION: If entering a flow that collects data, extract data from user message first
|
|
846
|
-
// This allows us to skip steps whose data is already provided
|
|
970
|
+
// This allows us to skip steps whose data is already provided.
|
|
971
|
+
// Reuses the routing-skip check's step-scoped extraction when it already
|
|
972
|
+
// ran this turn — at most ONE extraction LLM call per turn.
|
|
847
973
|
if (routingResult.selectedFlow && !isFlowComplete) {
|
|
848
974
|
// Always pre-extract when flow collects data (not just on new flow entry)
|
|
849
975
|
// This ensures step selection has the most up-to-date data
|
|
850
|
-
|
|
976
|
+
let extractedData: Partial<TData> | undefined;
|
|
977
|
+
if (routingSkipCheck.extractionRan) {
|
|
978
|
+
extractedData = routingSkipCheck.extractedData;
|
|
979
|
+
} else if (this.shouldPreExtractData(routingResult.selectedFlow)) {
|
|
851
980
|
logger.debug(
|
|
852
981
|
`[ResponsePipeline] Pre-extracting data for flow: ${routingResult.selectedFlow.title}`
|
|
853
982
|
);
|
|
854
983
|
|
|
855
|
-
|
|
984
|
+
extractedData = await this.preExtractFlowData({
|
|
856
985
|
route: routingResult.selectedFlow,
|
|
857
986
|
history: params.history,
|
|
858
987
|
context: params.context,
|
|
859
988
|
session: updatedSession,
|
|
860
989
|
signal: params.signal,
|
|
861
990
|
});
|
|
991
|
+
}
|
|
862
992
|
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
}
|
|
993
|
+
if (extractedData && Object.keys(extractedData).length > 0) {
|
|
994
|
+
logger.debug(
|
|
995
|
+
`[ResponsePipeline] Pre-extracted data:`,
|
|
996
|
+
extractedData
|
|
997
|
+
);
|
|
998
|
+
// Merge pre-extracted data into session before step selection
|
|
999
|
+
updatedSession = mergeCollected(updatedSession, extractedData);
|
|
1000
|
+
// Also update agent's collected data
|
|
1001
|
+
await this.updateCollectedData(extractedData);
|
|
873
1002
|
}
|
|
874
1003
|
}
|
|
875
1004
|
|
|
@@ -887,8 +1016,10 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
887
1016
|
selectedStep: stepResult.nextStep, // Use the determined next step
|
|
888
1017
|
responseDirectives: routingResult.responseDirectives,
|
|
889
1018
|
session: stepResult.session,
|
|
890
|
-
//
|
|
891
|
-
|
|
1019
|
+
// determineNextStep owns the verdict: a branch that resolved a position
|
|
1020
|
+
// (new flow, or a step of this one) overrides the router's proposal.
|
|
1021
|
+
isFlowComplete: stepResult.isFlowComplete,
|
|
1022
|
+
endedFlows: routingResult.endedFlows,
|
|
892
1023
|
};
|
|
893
1024
|
} catch (error) {
|
|
894
1025
|
throw ResponseGenerationError.fromError(error, 'routing_optimization', params);
|
|
@@ -1003,12 +1134,19 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
1003
1134
|
}
|
|
1004
1135
|
|
|
1005
1136
|
/**
|
|
1006
|
-
* Routing skip
|
|
1007
|
-
* When the current step declares `collect` fields AND
|
|
1008
|
-
* at least one of those fields from the user's message,
|
|
1137
|
+
* Routing skip check (Requirements 20.1, 20.2, 20.3):
|
|
1138
|
+
* When the current step declares `collect` fields AND step-scoped extraction
|
|
1139
|
+
* populates at least one of those fields from the user's message, the caller
|
|
1140
|
+
* skips routing for this turn (`skipResult`).
|
|
1141
|
+
*
|
|
1142
|
+
* The extraction is scoped to EXACTLY this step's collect fields — incidental
|
|
1143
|
+
* mentions of other (e.g. other-flow) fields cannot pin the routing decision.
|
|
1144
|
+
* It is skipped entirely when every collect field is already populated.
|
|
1009
1145
|
*
|
|
1010
|
-
*
|
|
1011
|
-
*
|
|
1146
|
+
* Always returns what the check did so the caller can reuse the single
|
|
1147
|
+
* extraction result in its normal path instead of extracting twice:
|
|
1148
|
+
* - `extractionRan` — whether an extraction LLM call was made this turn.
|
|
1149
|
+
* - `extractedData` — that call's result (empty when nothing found / not run).
|
|
1012
1150
|
*/
|
|
1013
1151
|
private async attemptRoutingSkipForCollect(params: {
|
|
1014
1152
|
session: SessionState<TData>;
|
|
@@ -1016,22 +1154,27 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
1016
1154
|
context: TContext;
|
|
1017
1155
|
signal?: AbortSignal;
|
|
1018
1156
|
}): Promise<{
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1157
|
+
extractionRan: boolean;
|
|
1158
|
+
extractedData: Partial<TData>;
|
|
1159
|
+
skipResult?: {
|
|
1160
|
+
selectedFlow?: Flow<TContext, TData>;
|
|
1161
|
+
selectedStep?: Step<TContext, TData>;
|
|
1162
|
+
responseDirectives?: string[];
|
|
1163
|
+
session: SessionState<TData>;
|
|
1164
|
+
isFlowComplete: boolean;
|
|
1165
|
+
};
|
|
1166
|
+
}> {
|
|
1025
1167
|
const { session } = params;
|
|
1168
|
+
const notApplicable = { extractionRan: false, extractedData: {} as Partial<TData> };
|
|
1026
1169
|
|
|
1027
1170
|
// Only applies when we already have a current flow and step
|
|
1028
1171
|
if (!session.currentFlow || !session.currentStep) {
|
|
1029
|
-
return
|
|
1172
|
+
return notApplicable;
|
|
1030
1173
|
}
|
|
1031
1174
|
|
|
1032
1175
|
// Also skip this optimization if there's a pending directive (it takes priority)
|
|
1033
1176
|
if (session.pendingDirective) {
|
|
1034
|
-
return
|
|
1177
|
+
return notApplicable;
|
|
1035
1178
|
}
|
|
1036
1179
|
|
|
1037
1180
|
// Look up the actual Flow and Step objects to access `collect`
|
|
@@ -1039,40 +1182,54 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
1039
1182
|
(f) => f.id === session.currentFlow?.id
|
|
1040
1183
|
);
|
|
1041
1184
|
if (!currentFlow) {
|
|
1042
|
-
return
|
|
1185
|
+
return notApplicable;
|
|
1043
1186
|
}
|
|
1044
1187
|
|
|
1045
1188
|
const currentStep = currentFlow.getStep(session.currentStep.id);
|
|
1046
1189
|
if (!currentStep || !currentStep.collect || currentStep.collect.length === 0) {
|
|
1047
|
-
return
|
|
1190
|
+
return notApplicable;
|
|
1048
1191
|
}
|
|
1049
1192
|
|
|
1050
|
-
// We have a step with collect fields. Run pre-extraction to see if the
|
|
1051
|
-
// user's message populates any of them.
|
|
1052
1193
|
const collectFields = currentStep.collect;
|
|
1053
1194
|
|
|
1195
|
+
// Every relevant field already set — the skip cannot fire; don't spend
|
|
1196
|
+
// an extraction LLM call probing for it.
|
|
1197
|
+
const sessionRecord = (session.data ?? {}) as Record<string, unknown>;
|
|
1198
|
+
const allPopulated = collectFields.every((field) => {
|
|
1199
|
+
const value = sessionRecord[String(field)];
|
|
1200
|
+
return value !== undefined && value !== null;
|
|
1201
|
+
});
|
|
1202
|
+
if (allPopulated) {
|
|
1203
|
+
return notApplicable;
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1054
1206
|
// Snapshot current data for comparison
|
|
1055
|
-
const dataBefore = { ...
|
|
1207
|
+
const dataBefore = { ...sessionRecord } as Record<string, unknown>;
|
|
1056
1208
|
|
|
1057
|
-
//
|
|
1209
|
+
// Step-scoped pre-extraction: see if the user's message populates any of
|
|
1210
|
+
// THIS step's collect fields.
|
|
1058
1211
|
const extractedData = await this.preExtractFlowData({
|
|
1059
1212
|
route: currentFlow,
|
|
1060
1213
|
history: params.history,
|
|
1061
1214
|
context: params.context,
|
|
1062
1215
|
session,
|
|
1063
1216
|
signal: params.signal,
|
|
1217
|
+
restrictToFields: collectFields.map(String),
|
|
1064
1218
|
});
|
|
1065
1219
|
|
|
1066
1220
|
if (!extractedData || Object.keys(extractedData).length === 0) {
|
|
1067
|
-
return
|
|
1221
|
+
return { extractionRan: true, extractedData: {} };
|
|
1068
1222
|
}
|
|
1069
1223
|
|
|
1070
1224
|
// Determine which collect fields were newly populated by pre-extraction
|
|
1225
|
+
const extractedRecord = extractedData as Record<string, unknown>;
|
|
1071
1226
|
const populatedCollectFields: string[] = [];
|
|
1072
1227
|
for (const field of collectFields) {
|
|
1073
|
-
const key = field
|
|
1074
|
-
const hadValue =
|
|
1075
|
-
|
|
1228
|
+
const key = String(field);
|
|
1229
|
+
const hadValue =
|
|
1230
|
+
dataBefore[key] !== undefined && dataBefore[key] !== null;
|
|
1231
|
+
const hasNewValue =
|
|
1232
|
+
extractedRecord[key] !== undefined && extractedRecord[key] !== null;
|
|
1076
1233
|
if (hasNewValue && !hadValue) {
|
|
1077
1234
|
populatedCollectFields.push(key);
|
|
1078
1235
|
}
|
|
@@ -1080,7 +1237,7 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
1080
1237
|
|
|
1081
1238
|
if (populatedCollectFields.length === 0) {
|
|
1082
1239
|
// Pre-extraction didn't populate any declared collect field — no skip
|
|
1083
|
-
return
|
|
1240
|
+
return { extractionRan: true, extractedData };
|
|
1084
1241
|
}
|
|
1085
1242
|
|
|
1086
1243
|
// ROUTING SKIP: pre-extraction populated collect fields → retain current flow/step
|
|
@@ -1103,11 +1260,15 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
1103
1260
|
});
|
|
1104
1261
|
|
|
1105
1262
|
return {
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1263
|
+
extractionRan: true,
|
|
1264
|
+
extractedData,
|
|
1265
|
+
skipResult: {
|
|
1266
|
+
selectedFlow: stepResult.flowChanged || currentFlow,
|
|
1267
|
+
selectedStep: stepResult.nextStep,
|
|
1268
|
+
responseDirectives: undefined,
|
|
1269
|
+
session: stepResult.session,
|
|
1270
|
+
isFlowComplete: stepResult.isFlowComplete,
|
|
1271
|
+
},
|
|
1111
1272
|
};
|
|
1112
1273
|
}
|
|
1113
1274
|
|
|
@@ -1132,6 +1293,30 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
1132
1293
|
return hasDataCollectionSteps;
|
|
1133
1294
|
}
|
|
1134
1295
|
|
|
1296
|
+
/**
|
|
1297
|
+
* Build an extraction schema limited to the given subset of agent schema
|
|
1298
|
+
* fields. Used by the routing-skip probe so only the current step's collect
|
|
1299
|
+
* fields are visible to the extractor.
|
|
1300
|
+
*/
|
|
1301
|
+
private buildFieldRestrictedSchema(
|
|
1302
|
+
agentSchema: StructuredSchema,
|
|
1303
|
+
fields: string[],
|
|
1304
|
+
): StructuredSchema {
|
|
1305
|
+
const properties: Record<string, StructuredSchema> = {};
|
|
1306
|
+
for (const field of fields) {
|
|
1307
|
+
const prop = agentSchema.properties?.[field];
|
|
1308
|
+
if (prop) {
|
|
1309
|
+
properties[field] = prop;
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
return {
|
|
1313
|
+
type: "object",
|
|
1314
|
+
description: `Extraction restricted to these fields: ${fields.join(', ')}`,
|
|
1315
|
+
properties,
|
|
1316
|
+
additionalProperties: false,
|
|
1317
|
+
};
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1135
1320
|
/**
|
|
1136
1321
|
* Pre-extract data from user message when entering a flow
|
|
1137
1322
|
* This allows skipping steps whose data is already provided
|
|
@@ -1142,15 +1327,20 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
1142
1327
|
context: TContext;
|
|
1143
1328
|
session: SessionState<TData>;
|
|
1144
1329
|
signal?: AbortSignal;
|
|
1330
|
+
/** When set, extraction is restricted to exactly these schema fields (step-scoped routing-skip probe). */
|
|
1331
|
+
restrictToFields?: string[];
|
|
1145
1332
|
}): Promise<Partial<TData>> {
|
|
1146
|
-
const { route: flow, history, signal } = params;
|
|
1333
|
+
const { route: flow, history, signal, restrictToFields } = params;
|
|
1147
1334
|
|
|
1148
1335
|
// Build a schema for data extraction based on flow's fields
|
|
1149
|
-
const
|
|
1150
|
-
if (!
|
|
1336
|
+
const agentSchema = this.getSchema();
|
|
1337
|
+
if (!agentSchema) {
|
|
1151
1338
|
logger.warn(`[ResponsePipeline] No schema available for pre-extraction`);
|
|
1152
1339
|
return {};
|
|
1153
1340
|
}
|
|
1341
|
+
const extractionSchema = restrictToFields
|
|
1342
|
+
? this.buildFieldRestrictedSchema(agentSchema, restrictToFields)
|
|
1343
|
+
: agentSchema;
|
|
1154
1344
|
|
|
1155
1345
|
// Get last user message
|
|
1156
1346
|
const lastMessage = getLastMessageFromHistory(history);
|
|
@@ -1166,11 +1356,15 @@ export class ResponsePipeline<TContext = unknown, TData = unknown> {
|
|
|
1166
1356
|
];
|
|
1167
1357
|
|
|
1168
1358
|
// Add field descriptions
|
|
1169
|
-
if (
|
|
1170
|
-
extractionPrompt.push(`
|
|
1171
|
-
}
|
|
1172
|
-
|
|
1173
|
-
|
|
1359
|
+
if (restrictToFields) {
|
|
1360
|
+
extractionPrompt.push(`Only these fields: ${restrictToFields.join(', ')}`);
|
|
1361
|
+
} else {
|
|
1362
|
+
if (flow.requiredFields) {
|
|
1363
|
+
extractionPrompt.push(`Required fields: ${flow.requiredFields.join(', ')}`);
|
|
1364
|
+
}
|
|
1365
|
+
if (flow.optionalFields) {
|
|
1366
|
+
extractionPrompt.push(`Optional fields: ${flow.optionalFields.join(', ')}`);
|
|
1367
|
+
}
|
|
1174
1368
|
}
|
|
1175
1369
|
|
|
1176
1370
|
extractionPrompt.push(
|