@falai/agent 0.9.0 → 1.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 +304 -72
- package/dist/adapters/MemoryAdapter.d.ts.map +1 -0
- package/dist/adapters/MemoryAdapter.js.map +1 -0
- package/dist/adapters/MongoAdapter.d.ts.map +1 -0
- package/dist/adapters/MongoAdapter.js.map +1 -0
- package/dist/adapters/OpenSearchAdapter.d.ts.map +1 -0
- package/dist/adapters/OpenSearchAdapter.js.map +1 -0
- package/dist/adapters/PostgreSQLAdapter.d.ts.map +1 -0
- package/dist/adapters/PostgreSQLAdapter.js.map +1 -0
- package/dist/adapters/PrismaAdapter.d.ts.map +1 -0
- package/dist/{src/adapters → adapters}/PrismaAdapter.js +3 -2
- package/dist/adapters/PrismaAdapter.js.map +1 -0
- package/dist/adapters/RedisAdapter.d.ts.map +1 -0
- package/dist/{src/adapters → adapters}/RedisAdapter.js +3 -3
- package/dist/adapters/RedisAdapter.js.map +1 -0
- package/dist/adapters/SQLiteAdapter.d.ts.map +1 -0
- package/dist/adapters/SQLiteAdapter.js.map +1 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/cjs/adapters/MemoryAdapter.js.map +1 -0
- package/dist/cjs/adapters/MongoAdapter.js.map +1 -0
- package/dist/cjs/adapters/OpenSearchAdapter.js.map +1 -0
- package/dist/cjs/adapters/PostgreSQLAdapter.js.map +1 -0
- package/dist/{src → cjs}/adapters/PrismaAdapter.d.ts.map +1 -1
- package/dist/cjs/{src/adapters → adapters}/PrismaAdapter.js +3 -2
- package/dist/cjs/adapters/PrismaAdapter.js.map +1 -0
- package/dist/cjs/{src/adapters → adapters}/RedisAdapter.js +2 -2
- package/dist/cjs/adapters/RedisAdapter.js.map +1 -0
- package/dist/cjs/adapters/SQLiteAdapter.js.map +1 -0
- package/dist/cjs/adapters/index.js.map +1 -0
- package/dist/cjs/constants/index.js.map +1 -0
- package/dist/{src → cjs}/core/Agent.d.ts +25 -6
- package/dist/cjs/core/Agent.d.ts.map +1 -0
- package/dist/cjs/{src/core → core}/Agent.js +121 -37
- package/dist/cjs/core/Agent.js.map +1 -0
- package/dist/cjs/core/BatchExecutor.d.ts +353 -0
- package/dist/cjs/core/BatchExecutor.d.ts.map +1 -0
- package/dist/cjs/core/BatchExecutor.js +842 -0
- package/dist/cjs/core/BatchExecutor.js.map +1 -0
- package/dist/cjs/core/BatchPromptBuilder.d.ts +86 -0
- package/dist/cjs/core/BatchPromptBuilder.d.ts.map +1 -0
- package/dist/cjs/core/BatchPromptBuilder.js +201 -0
- package/dist/cjs/core/BatchPromptBuilder.js.map +1 -0
- package/dist/cjs/core/Events.js.map +1 -0
- package/dist/cjs/core/PersistenceManager.js.map +1 -0
- package/dist/{src → cjs}/core/PromptComposer.d.ts +1 -1
- package/dist/cjs/core/PromptComposer.d.ts.map +1 -0
- package/dist/cjs/{src/core → core}/PromptComposer.js +44 -7
- package/dist/cjs/core/PromptComposer.js.map +1 -0
- package/dist/{src → cjs}/core/ResponseEngine.d.ts.map +1 -1
- package/dist/cjs/core/ResponseEngine.js +202 -0
- package/dist/cjs/core/ResponseEngine.js.map +1 -0
- package/dist/{src → cjs}/core/ResponseModal.d.ts +54 -3
- package/dist/cjs/core/ResponseModal.d.ts.map +1 -0
- package/dist/cjs/{src/core → core}/ResponseModal.js +807 -121
- package/dist/cjs/core/ResponseModal.js.map +1 -0
- package/dist/{src → cjs}/core/ResponsePipeline.d.ts +10 -6
- package/dist/cjs/core/ResponsePipeline.d.ts.map +1 -0
- package/dist/cjs/{src/core → core}/ResponsePipeline.js +60 -25
- package/dist/cjs/core/ResponsePipeline.js.map +1 -0
- package/dist/{src → cjs}/core/Route.d.ts +46 -10
- package/dist/cjs/core/Route.d.ts.map +1 -0
- package/dist/cjs/core/Route.js +541 -0
- package/dist/cjs/core/Route.js.map +1 -0
- package/dist/cjs/{src/core → core}/RoutingEngine.d.ts +35 -5
- package/dist/cjs/core/RoutingEngine.d.ts.map +1 -0
- package/dist/cjs/{src/core → core}/RoutingEngine.js +360 -98
- package/dist/cjs/core/RoutingEngine.js.map +1 -0
- package/dist/{src → cjs}/core/SessionManager.d.ts +9 -1
- package/dist/cjs/core/SessionManager.d.ts.map +1 -0
- package/dist/cjs/{src/core → core}/SessionManager.js +27 -5
- package/dist/cjs/core/SessionManager.js.map +1 -0
- package/dist/cjs/core/Step.d.ts +170 -0
- package/dist/cjs/core/Step.d.ts.map +1 -0
- package/dist/cjs/core/Step.js +448 -0
- package/dist/cjs/core/Step.js.map +1 -0
- package/dist/cjs/core/ToolManager.d.ts +234 -0
- package/dist/cjs/core/ToolManager.d.ts.map +1 -0
- package/dist/cjs/core/ToolManager.js +1117 -0
- package/dist/cjs/core/ToolManager.js.map +1 -0
- package/dist/{src → cjs}/index.d.ts +5 -3
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/{src/index.js → index.js} +16 -3
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/{src/providers → providers}/AnthropicProvider.js +18 -18
- package/dist/cjs/providers/AnthropicProvider.js.map +1 -0
- package/dist/{src → cjs}/providers/GeminiProvider.d.ts.map +1 -1
- package/dist/cjs/{src/providers → providers}/GeminiProvider.js +123 -51
- package/dist/cjs/providers/GeminiProvider.js.map +1 -0
- package/dist/cjs/{src/providers → providers}/OpenAIProvider.js +19 -19
- package/dist/cjs/providers/OpenAIProvider.js.map +1 -0
- package/dist/cjs/{src/providers → providers}/OpenRouterProvider.js +19 -19
- package/dist/cjs/providers/OpenRouterProvider.js.map +1 -0
- package/dist/cjs/providers/index.js.map +1 -0
- package/dist/cjs/{src/types → types}/agent.d.ts +12 -4
- package/dist/cjs/types/agent.d.ts.map +1 -0
- package/dist/cjs/types/agent.js.map +1 -0
- package/dist/{src → cjs}/types/ai.js.map +1 -1
- package/dist/cjs/types/history.js.map +1 -0
- package/dist/cjs/{src/types → types}/index.d.ts +5 -3
- package/dist/{src → cjs}/types/index.d.ts.map +1 -1
- package/dist/cjs/{src/types → types}/index.js +8 -1
- package/dist/cjs/types/index.js.map +1 -0
- package/dist/cjs/types/persistence.js.map +1 -0
- package/dist/cjs/{src/types → types}/route.d.ts +116 -15
- package/dist/cjs/types/route.d.ts.map +1 -0
- package/dist/cjs/{src/types → types}/route.js.map +1 -1
- package/dist/cjs/types/session.js.map +1 -0
- package/dist/cjs/types/template.d.ts +88 -0
- package/dist/cjs/types/template.d.ts.map +1 -0
- package/dist/cjs/types/tool.d.ts +130 -0
- package/dist/cjs/types/tool.d.ts.map +1 -0
- package/dist/cjs/types/tool.js +19 -0
- package/dist/cjs/types/tool.js.map +1 -0
- package/dist/cjs/utils/clone.js.map +1 -0
- package/dist/cjs/utils/condition.d.ts +38 -0
- package/dist/cjs/utils/condition.d.ts.map +1 -0
- package/dist/cjs/utils/condition.js +168 -0
- package/dist/cjs/utils/condition.js.map +1 -0
- package/dist/cjs/utils/event.js.map +1 -0
- package/dist/cjs/utils/history.js.map +1 -0
- package/dist/cjs/utils/id.js.map +1 -0
- package/dist/cjs/{src/utils → utils}/index.d.ts +3 -1
- package/dist/cjs/utils/index.d.ts.map +1 -0
- package/dist/cjs/{src/utils → utils}/index.js +12 -1
- package/dist/cjs/utils/index.js.map +1 -0
- package/dist/cjs/utils/json.d.ts +16 -0
- package/dist/cjs/utils/json.d.ts.map +1 -0
- package/dist/cjs/utils/json.js +47 -0
- package/dist/cjs/utils/json.js.map +1 -0
- package/dist/cjs/utils/logger.js.map +1 -0
- package/dist/{src → cjs}/utils/retry.d.ts +0 -3
- package/dist/cjs/utils/retry.d.ts.map +1 -0
- package/dist/cjs/{src/utils → utils}/retry.js +8 -7
- package/dist/cjs/utils/retry.js.map +1 -0
- package/dist/cjs/utils/session.js.map +1 -0
- package/dist/{src → cjs}/utils/template.d.ts +48 -0
- package/dist/cjs/utils/template.d.ts.map +1 -0
- package/dist/cjs/{src/utils → utils}/template.js +100 -0
- package/dist/cjs/utils/template.js.map +1 -0
- package/dist/constants/index.d.ts.map +1 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/{cjs/src/core → core}/Agent.d.ts +25 -6
- package/dist/core/Agent.d.ts.map +1 -0
- package/dist/{src/core → core}/Agent.js +122 -38
- package/dist/core/Agent.js.map +1 -0
- package/dist/core/BatchExecutor.d.ts +353 -0
- package/dist/core/BatchExecutor.d.ts.map +1 -0
- package/dist/core/BatchExecutor.js +837 -0
- package/dist/core/BatchExecutor.js.map +1 -0
- package/dist/core/BatchPromptBuilder.d.ts +86 -0
- package/dist/core/BatchPromptBuilder.d.ts.map +1 -0
- package/dist/core/BatchPromptBuilder.js +197 -0
- package/dist/core/BatchPromptBuilder.js.map +1 -0
- package/dist/core/Events.d.ts.map +1 -0
- package/dist/core/Events.js.map +1 -0
- package/dist/core/PersistenceManager.d.ts.map +1 -0
- package/dist/core/PersistenceManager.js.map +1 -0
- package/dist/{cjs/src/core → core}/PromptComposer.d.ts +1 -1
- package/dist/core/PromptComposer.d.ts.map +1 -0
- package/dist/{src/core → core}/PromptComposer.js +45 -8
- package/dist/core/PromptComposer.js.map +1 -0
- package/dist/core/ResponseEngine.d.ts.map +1 -0
- package/dist/core/ResponseEngine.js +198 -0
- package/dist/core/ResponseEngine.js.map +1 -0
- package/dist/{cjs/src/core → core}/ResponseModal.d.ts +54 -3
- package/dist/core/ResponseModal.d.ts.map +1 -0
- package/dist/{src/core → core}/ResponseModal.js +807 -121
- package/dist/core/ResponseModal.js.map +1 -0
- package/dist/{cjs/src/core → core}/ResponsePipeline.d.ts +10 -6
- package/dist/core/ResponsePipeline.d.ts.map +1 -0
- package/dist/{src/core → core}/ResponsePipeline.js +60 -25
- package/dist/core/ResponsePipeline.js.map +1 -0
- package/dist/{cjs/src/core → core}/Route.d.ts +46 -10
- package/dist/core/Route.d.ts.map +1 -0
- package/dist/core/Route.js +537 -0
- package/dist/core/Route.js.map +1 -0
- package/dist/{src/core → core}/RoutingEngine.d.ts +35 -5
- package/dist/core/RoutingEngine.d.ts.map +1 -0
- package/dist/{src/core → core}/RoutingEngine.js +343 -81
- package/dist/core/RoutingEngine.js.map +1 -0
- package/dist/{cjs/src/core → core}/SessionManager.d.ts +9 -1
- package/dist/core/SessionManager.d.ts.map +1 -0
- package/dist/{src/core → core}/SessionManager.js +27 -5
- package/dist/core/SessionManager.js.map +1 -0
- package/dist/core/Step.d.ts +170 -0
- package/dist/core/Step.d.ts.map +1 -0
- package/dist/core/Step.js +444 -0
- package/dist/core/Step.js.map +1 -0
- package/dist/core/ToolManager.d.ts +234 -0
- package/dist/core/ToolManager.d.ts.map +1 -0
- package/dist/core/ToolManager.js +1111 -0
- package/dist/core/ToolManager.js.map +1 -0
- package/dist/{cjs/src/index.d.ts → index.d.ts} +5 -3
- package/dist/index.d.ts.map +1 -0
- package/dist/{src/index.js → index.js} +4 -1
- package/dist/index.js.map +1 -0
- package/dist/providers/AnthropicProvider.d.ts.map +1 -0
- package/dist/{src/providers → providers}/AnthropicProvider.js +17 -17
- package/dist/providers/AnthropicProvider.js.map +1 -0
- package/dist/providers/GeminiProvider.d.ts.map +1 -0
- package/dist/{src/providers → providers}/GeminiProvider.js +123 -51
- package/dist/providers/GeminiProvider.js.map +1 -0
- package/dist/providers/OpenAIProvider.d.ts.map +1 -0
- package/dist/{src/providers → providers}/OpenAIProvider.js +18 -18
- package/dist/providers/OpenAIProvider.js.map +1 -0
- package/dist/providers/OpenRouterProvider.d.ts.map +1 -0
- package/dist/{src/providers → providers}/OpenRouterProvider.js +18 -18
- package/dist/providers/OpenRouterProvider.js.map +1 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/{src/types → types}/agent.d.ts +12 -4
- package/dist/types/agent.d.ts.map +1 -0
- package/dist/types/agent.js.map +1 -0
- package/dist/types/ai.d.ts.map +1 -0
- package/dist/types/ai.js.map +1 -0
- package/dist/types/history.d.ts.map +1 -0
- package/dist/types/history.js.map +1 -0
- package/dist/{src/types → types}/index.d.ts +5 -3
- package/dist/types/index.d.ts.map +1 -0
- package/dist/{src/types → types}/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/persistence.d.ts.map +1 -0
- package/dist/types/persistence.js.map +1 -0
- package/dist/{src/types → types}/route.d.ts +116 -15
- package/dist/types/route.d.ts.map +1 -0
- package/dist/{src/types → types}/route.js.map +1 -1
- package/dist/types/routing.d.ts.map +1 -0
- package/dist/{cjs/src/types → types}/routing.js.map +1 -1
- package/dist/types/schema.d.ts.map +1 -0
- package/dist/{cjs/src/types → types}/schema.js.map +1 -1
- package/dist/types/session.d.ts.map +1 -0
- package/dist/{src/types → types}/session.js.map +1 -1
- package/dist/types/template.d.ts +88 -0
- package/dist/types/template.d.ts.map +1 -0
- package/dist/{cjs/src/types → types}/template.js.map +1 -1
- package/dist/types/tool.d.ts +130 -0
- package/dist/types/tool.d.ts.map +1 -0
- package/dist/types/tool.js +16 -0
- package/dist/types/tool.js.map +1 -0
- package/dist/utils/clone.d.ts.map +1 -0
- package/dist/utils/clone.js.map +1 -0
- package/dist/utils/condition.d.ts +38 -0
- package/dist/utils/condition.d.ts.map +1 -0
- package/dist/utils/condition.js +161 -0
- package/dist/utils/condition.js.map +1 -0
- package/dist/utils/event.d.ts.map +1 -0
- package/dist/utils/event.js.map +1 -0
- package/dist/utils/history.d.ts.map +1 -0
- package/dist/utils/history.js.map +1 -0
- package/dist/utils/id.d.ts.map +1 -0
- package/dist/utils/id.js.map +1 -0
- package/dist/{src/utils → utils}/index.d.ts +3 -1
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/{src/utils → utils}/index.js +5 -1
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/json.d.ts +16 -0
- package/dist/utils/json.d.ts.map +1 -0
- package/dist/utils/json.js +43 -0
- package/dist/utils/json.js.map +1 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/{cjs/src/utils → utils}/retry.d.ts +0 -3
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/{src/utils → utils}/retry.js +5 -4
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/session.d.ts.map +1 -0
- package/dist/utils/session.js.map +1 -0
- package/dist/{cjs/src/utils → utils}/template.d.ts +48 -0
- package/dist/utils/template.d.ts.map +1 -0
- package/dist/{src/utils → utils}/template.js +98 -0
- package/dist/utils/template.js.map +1 -0
- package/docs/CONTRIBUTING.md +40 -0
- package/docs/README.md +12 -5
- package/docs/api/README.md +295 -56
- package/docs/api/overview.md +272 -31
- package/docs/architecture/data-extraction-flow.md +363 -0
- package/docs/architecture/multi-step-execution.md +243 -0
- package/docs/core/agent/README.md +120 -5
- package/docs/core/agent/session-management.md +153 -6
- package/docs/core/ai-integration/prompt-composition.md +135 -0
- package/docs/core/ai-integration/response-processing.md +261 -4
- package/docs/core/conversation-flows/data-collection.md +143 -0
- package/docs/core/conversation-flows/routes.md +132 -2
- package/docs/core/conversation-flows/step-transitions.md +132 -0
- package/docs/core/conversation-flows/steps.md +112 -0
- package/docs/core/error-handling.md +831 -0
- package/docs/core/routing/intelligent-routing.md +118 -0
- package/docs/core/tools/tool-definition.md +684 -60
- package/docs/core/tools/tool-scoping.md +244 -53
- package/docs/guides/error-handling-patterns.md +578 -0
- package/docs/guides/getting-started/README.md +423 -31
- package/docs/guides/migration/README.md +23 -0
- package/docs/guides/migration/flexible-routing-conditions.md +375 -0
- package/docs/guides/migration/multi-step-execution.md +303 -0
- package/examples/advanced-patterns/knowledge-based-agent.ts +107 -30
- package/examples/advanced-patterns/persistent-onboarding.ts +70 -48
- package/examples/advanced-patterns/route-lifecycle-hooks.ts +82 -12
- package/examples/advanced-patterns/streaming-responses.ts +2 -2
- package/examples/ai-providers/anthropic-integration.ts +13 -9
- package/examples/ai-providers/openai-integration.ts +12 -8
- package/examples/condition-patterns/function-only-conditions.ts +365 -0
- package/examples/condition-patterns/mixed-array-conditions.ts +477 -0
- package/examples/condition-patterns/route-skipif-patterns.ts +468 -0
- package/examples/condition-patterns/step-skipif-patterns.ts +0 -0
- package/examples/condition-patterns/string-only-conditions.ts +296 -0
- package/examples/conversation-flows/completion-transitions.ts +48 -7
- package/examples/core-concepts/basic-agent.ts +158 -98
- package/examples/core-concepts/schema-driven-extraction.ts +43 -16
- package/examples/core-concepts/session-management.ts +117 -29
- package/examples/integrations/database-integration.ts +6 -6
- package/examples/integrations/healthcare-integration.ts +25 -39
- package/examples/integrations/search-integration.ts +8 -8
- package/examples/integrations/server-session-management.ts +11 -11
- package/examples/persistence/database-persistence.ts +15 -15
- package/examples/persistence/memory-sessions.ts +6 -6
- package/examples/persistence/redis-persistence.ts +7 -9
- package/examples/tools/basic-tools.ts +293 -89
- package/examples/tools/data-enrichment-tools.ts +189 -79
- package/package.json +6 -4
- package/src/adapters/PrismaAdapter.ts +3 -2
- package/src/adapters/RedisAdapter.ts +3 -3
- package/src/core/Agent.ts +152 -46
- package/src/core/BatchExecutor.ts +1156 -0
- package/src/core/BatchPromptBuilder.ts +275 -0
- package/src/core/PromptComposer.ts +53 -16
- package/src/core/ResponseEngine.ts +143 -4
- package/src/core/ResponseModal.ts +1035 -137
- package/src/core/ResponsePipeline.ts +99 -65
- package/src/core/Route.ts +262 -34
- package/src/core/RoutingEngine.ts +467 -120
- package/src/core/SessionManager.ts +39 -7
- package/src/core/Step.ts +338 -32
- package/src/core/ToolManager.ts +1394 -0
- package/src/index.ts +27 -3
- package/src/providers/AnthropicProvider.ts +17 -17
- package/src/providers/GeminiProvider.ts +129 -60
- package/src/providers/OpenAIProvider.ts +18 -18
- package/src/providers/OpenRouterProvider.ts +18 -18
- package/src/types/agent.ts +12 -4
- package/src/types/index.ts +25 -3
- package/src/types/route.ts +136 -15
- package/src/types/template.ts +70 -2
- package/src/types/tool.ts +116 -25
- package/src/utils/condition.ts +190 -0
- package/src/utils/index.ts +12 -0
- package/src/utils/json.ts +46 -0
- package/src/utils/retry.ts +5 -4
- package/src/utils/template.ts +109 -0
- package/dist/cjs/src/adapters/MemoryAdapter.d.ts.map +0 -1
- package/dist/cjs/src/adapters/MemoryAdapter.js.map +0 -1
- package/dist/cjs/src/adapters/MongoAdapter.d.ts.map +0 -1
- package/dist/cjs/src/adapters/MongoAdapter.js.map +0 -1
- package/dist/cjs/src/adapters/OpenSearchAdapter.d.ts.map +0 -1
- package/dist/cjs/src/adapters/OpenSearchAdapter.js.map +0 -1
- package/dist/cjs/src/adapters/PostgreSQLAdapter.d.ts.map +0 -1
- package/dist/cjs/src/adapters/PostgreSQLAdapter.js.map +0 -1
- package/dist/cjs/src/adapters/PrismaAdapter.d.ts.map +0 -1
- package/dist/cjs/src/adapters/PrismaAdapter.js.map +0 -1
- package/dist/cjs/src/adapters/RedisAdapter.d.ts.map +0 -1
- package/dist/cjs/src/adapters/RedisAdapter.js.map +0 -1
- package/dist/cjs/src/adapters/SQLiteAdapter.d.ts.map +0 -1
- package/dist/cjs/src/adapters/SQLiteAdapter.js.map +0 -1
- package/dist/cjs/src/adapters/index.d.ts.map +0 -1
- package/dist/cjs/src/adapters/index.js.map +0 -1
- package/dist/cjs/src/constants/index.d.ts.map +0 -1
- package/dist/cjs/src/constants/index.js.map +0 -1
- package/dist/cjs/src/core/Agent.d.ts.map +0 -1
- package/dist/cjs/src/core/Agent.js.map +0 -1
- package/dist/cjs/src/core/Events.d.ts.map +0 -1
- package/dist/cjs/src/core/Events.js.map +0 -1
- package/dist/cjs/src/core/PersistenceManager.d.ts.map +0 -1
- package/dist/cjs/src/core/PersistenceManager.js.map +0 -1
- package/dist/cjs/src/core/PromptComposer.d.ts.map +0 -1
- package/dist/cjs/src/core/PromptComposer.js.map +0 -1
- package/dist/cjs/src/core/ResponseEngine.d.ts.map +0 -1
- package/dist/cjs/src/core/ResponseEngine.js +0 -84
- package/dist/cjs/src/core/ResponseEngine.js.map +0 -1
- package/dist/cjs/src/core/ResponseModal.d.ts.map +0 -1
- package/dist/cjs/src/core/ResponseModal.js.map +0 -1
- package/dist/cjs/src/core/ResponsePipeline.d.ts.map +0 -1
- package/dist/cjs/src/core/ResponsePipeline.js.map +0 -1
- package/dist/cjs/src/core/Route.d.ts.map +0 -1
- package/dist/cjs/src/core/Route.js +0 -343
- package/dist/cjs/src/core/Route.js.map +0 -1
- package/dist/cjs/src/core/RoutingEngine.d.ts.map +0 -1
- package/dist/cjs/src/core/RoutingEngine.js.map +0 -1
- package/dist/cjs/src/core/SessionManager.d.ts.map +0 -1
- package/dist/cjs/src/core/SessionManager.js.map +0 -1
- package/dist/cjs/src/core/Step.d.ts +0 -96
- package/dist/cjs/src/core/Step.d.ts.map +0 -1
- package/dist/cjs/src/core/Step.js +0 -206
- package/dist/cjs/src/core/Step.js.map +0 -1
- package/dist/cjs/src/core/ToolExecutor.d.ts +0 -45
- package/dist/cjs/src/core/ToolExecutor.d.ts.map +0 -1
- package/dist/cjs/src/core/ToolExecutor.js +0 -84
- package/dist/cjs/src/core/ToolExecutor.js.map +0 -1
- package/dist/cjs/src/index.d.ts.map +0 -1
- package/dist/cjs/src/index.js.map +0 -1
- package/dist/cjs/src/providers/AnthropicProvider.d.ts.map +0 -1
- package/dist/cjs/src/providers/AnthropicProvider.js.map +0 -1
- package/dist/cjs/src/providers/GeminiProvider.d.ts.map +0 -1
- package/dist/cjs/src/providers/GeminiProvider.js.map +0 -1
- package/dist/cjs/src/providers/OpenAIProvider.d.ts.map +0 -1
- package/dist/cjs/src/providers/OpenAIProvider.js.map +0 -1
- package/dist/cjs/src/providers/OpenRouterProvider.d.ts.map +0 -1
- package/dist/cjs/src/providers/OpenRouterProvider.js.map +0 -1
- package/dist/cjs/src/providers/index.d.ts.map +0 -1
- package/dist/cjs/src/providers/index.js.map +0 -1
- package/dist/cjs/src/types/agent.d.ts.map +0 -1
- package/dist/cjs/src/types/agent.js.map +0 -1
- package/dist/cjs/src/types/ai.d.ts.map +0 -1
- package/dist/cjs/src/types/ai.js.map +0 -1
- package/dist/cjs/src/types/history.d.ts.map +0 -1
- package/dist/cjs/src/types/history.js.map +0 -1
- package/dist/cjs/src/types/index.d.ts.map +0 -1
- package/dist/cjs/src/types/index.js.map +0 -1
- package/dist/cjs/src/types/persistence.d.ts.map +0 -1
- package/dist/cjs/src/types/persistence.js.map +0 -1
- package/dist/cjs/src/types/route.d.ts.map +0 -1
- package/dist/cjs/src/types/routing.d.ts.map +0 -1
- package/dist/cjs/src/types/schema.d.ts.map +0 -1
- package/dist/cjs/src/types/session.d.ts.map +0 -1
- package/dist/cjs/src/types/session.js.map +0 -1
- package/dist/cjs/src/types/template.d.ts +0 -30
- package/dist/cjs/src/types/template.d.ts.map +0 -1
- package/dist/cjs/src/types/tool.d.ts +0 -60
- package/dist/cjs/src/types/tool.d.ts.map +0 -1
- package/dist/cjs/src/types/tool.js +0 -6
- package/dist/cjs/src/types/tool.js.map +0 -1
- package/dist/cjs/src/utils/clone.d.ts.map +0 -1
- package/dist/cjs/src/utils/clone.js.map +0 -1
- package/dist/cjs/src/utils/event.d.ts.map +0 -1
- package/dist/cjs/src/utils/event.js.map +0 -1
- package/dist/cjs/src/utils/history.d.ts.map +0 -1
- package/dist/cjs/src/utils/history.js.map +0 -1
- package/dist/cjs/src/utils/id.d.ts.map +0 -1
- package/dist/cjs/src/utils/id.js.map +0 -1
- package/dist/cjs/src/utils/index.d.ts.map +0 -1
- package/dist/cjs/src/utils/index.js.map +0 -1
- package/dist/cjs/src/utils/logger.d.ts.map +0 -1
- package/dist/cjs/src/utils/logger.js.map +0 -1
- package/dist/cjs/src/utils/retry.d.ts.map +0 -1
- package/dist/cjs/src/utils/retry.js.map +0 -1
- package/dist/cjs/src/utils/session.d.ts.map +0 -1
- package/dist/cjs/src/utils/session.js.map +0 -1
- package/dist/cjs/src/utils/template.d.ts.map +0 -1
- package/dist/cjs/src/utils/template.js.map +0 -1
- package/dist/src/adapters/MemoryAdapter.js.map +0 -1
- package/dist/src/adapters/MongoAdapter.js.map +0 -1
- package/dist/src/adapters/OpenSearchAdapter.js.map +0 -1
- package/dist/src/adapters/PostgreSQLAdapter.js.map +0 -1
- package/dist/src/adapters/PrismaAdapter.js.map +0 -1
- package/dist/src/adapters/RedisAdapter.js.map +0 -1
- package/dist/src/adapters/SQLiteAdapter.js.map +0 -1
- package/dist/src/adapters/index.js.map +0 -1
- package/dist/src/constants/index.js.map +0 -1
- package/dist/src/core/Agent.d.ts.map +0 -1
- package/dist/src/core/Agent.js.map +0 -1
- package/dist/src/core/Events.js.map +0 -1
- package/dist/src/core/PersistenceManager.js.map +0 -1
- package/dist/src/core/PromptComposer.d.ts.map +0 -1
- package/dist/src/core/PromptComposer.js.map +0 -1
- package/dist/src/core/ResponseEngine.js +0 -80
- package/dist/src/core/ResponseEngine.js.map +0 -1
- package/dist/src/core/ResponseModal.d.ts.map +0 -1
- package/dist/src/core/ResponseModal.js.map +0 -1
- package/dist/src/core/ResponsePipeline.d.ts.map +0 -1
- package/dist/src/core/ResponsePipeline.js.map +0 -1
- package/dist/src/core/Route.d.ts.map +0 -1
- package/dist/src/core/Route.js +0 -339
- package/dist/src/core/Route.js.map +0 -1
- package/dist/src/core/RoutingEngine.d.ts.map +0 -1
- package/dist/src/core/RoutingEngine.js.map +0 -1
- package/dist/src/core/SessionManager.d.ts.map +0 -1
- package/dist/src/core/SessionManager.js.map +0 -1
- package/dist/src/core/Step.d.ts +0 -96
- package/dist/src/core/Step.d.ts.map +0 -1
- package/dist/src/core/Step.js +0 -202
- package/dist/src/core/Step.js.map +0 -1
- package/dist/src/core/ToolExecutor.d.ts +0 -45
- package/dist/src/core/ToolExecutor.d.ts.map +0 -1
- package/dist/src/core/ToolExecutor.js +0 -80
- package/dist/src/core/ToolExecutor.js.map +0 -1
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/index.js.map +0 -1
- package/dist/src/providers/AnthropicProvider.js.map +0 -1
- package/dist/src/providers/GeminiProvider.js.map +0 -1
- package/dist/src/providers/OpenAIProvider.js.map +0 -1
- package/dist/src/providers/OpenRouterProvider.js.map +0 -1
- package/dist/src/providers/index.js.map +0 -1
- package/dist/src/types/agent.d.ts.map +0 -1
- package/dist/src/types/agent.js.map +0 -1
- package/dist/src/types/history.js.map +0 -1
- package/dist/src/types/index.js.map +0 -1
- package/dist/src/types/persistence.js.map +0 -1
- package/dist/src/types/route.d.ts.map +0 -1
- package/dist/src/types/template.d.ts +0 -30
- package/dist/src/types/template.d.ts.map +0 -1
- package/dist/src/types/tool.d.ts +0 -60
- package/dist/src/types/tool.d.ts.map +0 -1
- package/dist/src/types/tool.js +0 -5
- package/dist/src/types/tool.js.map +0 -1
- package/dist/src/utils/clone.js.map +0 -1
- package/dist/src/utils/event.js.map +0 -1
- package/dist/src/utils/history.js.map +0 -1
- package/dist/src/utils/id.js.map +0 -1
- package/dist/src/utils/index.d.ts.map +0 -1
- package/dist/src/utils/index.js.map +0 -1
- package/dist/src/utils/logger.js.map +0 -1
- package/dist/src/utils/retry.d.ts.map +0 -1
- package/dist/src/utils/retry.js.map +0 -1
- package/dist/src/utils/session.js.map +0 -1
- package/dist/src/utils/template.d.ts.map +0 -1
- package/dist/src/utils/template.js.map +0 -1
- package/docs/core/tools/tool-execution.md +0 -815
- package/src/core/ToolExecutor.ts +0 -126
- /package/dist/{cjs/src/adapters → adapters}/MemoryAdapter.d.ts +0 -0
- /package/dist/{src/adapters → adapters}/MemoryAdapter.js +0 -0
- /package/dist/{cjs/src/adapters → adapters}/MongoAdapter.d.ts +0 -0
- /package/dist/{src/adapters → adapters}/MongoAdapter.js +0 -0
- /package/dist/{cjs/src/adapters → adapters}/OpenSearchAdapter.d.ts +0 -0
- /package/dist/{src/adapters → adapters}/OpenSearchAdapter.js +0 -0
- /package/dist/{cjs/src/adapters → adapters}/PostgreSQLAdapter.d.ts +0 -0
- /package/dist/{src/adapters → adapters}/PostgreSQLAdapter.js +0 -0
- /package/dist/{cjs/src/adapters → adapters}/PrismaAdapter.d.ts +0 -0
- /package/dist/{cjs/src/adapters → adapters}/RedisAdapter.d.ts +0 -0
- /package/dist/{cjs/src/adapters → adapters}/SQLiteAdapter.d.ts +0 -0
- /package/dist/{src/adapters → adapters}/SQLiteAdapter.js +0 -0
- /package/dist/{cjs/src/adapters → adapters}/index.d.ts +0 -0
- /package/dist/{src/adapters → adapters}/index.js +0 -0
- /package/dist/{src → cjs}/adapters/MemoryAdapter.d.ts +0 -0
- /package/dist/{src → cjs}/adapters/MemoryAdapter.d.ts.map +0 -0
- /package/dist/cjs/{src/adapters → adapters}/MemoryAdapter.js +0 -0
- /package/dist/{src → cjs}/adapters/MongoAdapter.d.ts +0 -0
- /package/dist/{src → cjs}/adapters/MongoAdapter.d.ts.map +0 -0
- /package/dist/cjs/{src/adapters → adapters}/MongoAdapter.js +0 -0
- /package/dist/{src → cjs}/adapters/OpenSearchAdapter.d.ts +0 -0
- /package/dist/{src → cjs}/adapters/OpenSearchAdapter.d.ts.map +0 -0
- /package/dist/cjs/{src/adapters → adapters}/OpenSearchAdapter.js +0 -0
- /package/dist/{src → cjs}/adapters/PostgreSQLAdapter.d.ts +0 -0
- /package/dist/{src → cjs}/adapters/PostgreSQLAdapter.d.ts.map +0 -0
- /package/dist/cjs/{src/adapters → adapters}/PostgreSQLAdapter.js +0 -0
- /package/dist/{src → cjs}/adapters/PrismaAdapter.d.ts +0 -0
- /package/dist/{src → cjs}/adapters/RedisAdapter.d.ts +0 -0
- /package/dist/{src → cjs}/adapters/RedisAdapter.d.ts.map +0 -0
- /package/dist/{src → cjs}/adapters/SQLiteAdapter.d.ts +0 -0
- /package/dist/{src → cjs}/adapters/SQLiteAdapter.d.ts.map +0 -0
- /package/dist/cjs/{src/adapters → adapters}/SQLiteAdapter.js +0 -0
- /package/dist/{src → cjs}/adapters/index.d.ts +0 -0
- /package/dist/{src → cjs}/adapters/index.d.ts.map +0 -0
- /package/dist/cjs/{src/adapters → adapters}/index.js +0 -0
- /package/dist/cjs/{src/constants → constants}/index.d.ts +0 -0
- /package/dist/{src → cjs}/constants/index.d.ts.map +0 -0
- /package/dist/cjs/{src/constants → constants}/index.js +0 -0
- /package/dist/cjs/{src/core → core}/Events.d.ts +0 -0
- /package/dist/{src → cjs}/core/Events.d.ts.map +0 -0
- /package/dist/cjs/{src/core → core}/Events.js +0 -0
- /package/dist/cjs/{src/core → core}/PersistenceManager.d.ts +0 -0
- /package/dist/{src → cjs}/core/PersistenceManager.d.ts.map +0 -0
- /package/dist/cjs/{src/core → core}/PersistenceManager.js +0 -0
- /package/dist/cjs/{src/core → core}/ResponseEngine.d.ts +0 -0
- /package/dist/cjs/{src/providers → providers}/AnthropicProvider.d.ts +0 -0
- /package/dist/{src → cjs}/providers/AnthropicProvider.d.ts.map +0 -0
- /package/dist/cjs/{src/providers → providers}/GeminiProvider.d.ts +0 -0
- /package/dist/cjs/{src/providers → providers}/OpenAIProvider.d.ts +0 -0
- /package/dist/{src → cjs}/providers/OpenAIProvider.d.ts.map +0 -0
- /package/dist/cjs/{src/providers → providers}/OpenRouterProvider.d.ts +0 -0
- /package/dist/{src → cjs}/providers/OpenRouterProvider.d.ts.map +0 -0
- /package/dist/cjs/{src/providers → providers}/index.d.ts +0 -0
- /package/dist/{src → cjs}/providers/index.d.ts.map +0 -0
- /package/dist/cjs/{src/providers → providers}/index.js +0 -0
- /package/dist/cjs/{src/types → types}/agent.js +0 -0
- /package/dist/cjs/{src/types → types}/ai.d.ts +0 -0
- /package/dist/{src → cjs}/types/ai.d.ts.map +0 -0
- /package/dist/cjs/{src/types → types}/ai.js +0 -0
- /package/dist/cjs/{src/types → types}/history.d.ts +0 -0
- /package/dist/{src → cjs}/types/history.d.ts.map +0 -0
- /package/dist/cjs/{src/types → types}/history.js +0 -0
- /package/dist/cjs/{src/types → types}/persistence.d.ts +0 -0
- /package/dist/{src → cjs}/types/persistence.d.ts.map +0 -0
- /package/dist/cjs/{src/types → types}/persistence.js +0 -0
- /package/dist/cjs/{src/types → types}/route.js +0 -0
- /package/dist/cjs/{src/types → types}/routing.d.ts +0 -0
- /package/dist/{src → cjs}/types/routing.d.ts.map +0 -0
- /package/dist/cjs/{src/types → types}/routing.js +0 -0
- /package/dist/{src → cjs}/types/routing.js.map +0 -0
- /package/dist/cjs/{src/types → types}/schema.d.ts +0 -0
- /package/dist/{src → cjs}/types/schema.d.ts.map +0 -0
- /package/dist/cjs/{src/types → types}/schema.js +0 -0
- /package/dist/{src → cjs}/types/schema.js.map +0 -0
- /package/dist/cjs/{src/types → types}/session.d.ts +0 -0
- /package/dist/{src → cjs}/types/session.d.ts.map +0 -0
- /package/dist/cjs/{src/types → types}/session.js +0 -0
- /package/dist/cjs/{src/types → types}/template.js +0 -0
- /package/dist/{src → cjs}/types/template.js.map +0 -0
- /package/dist/cjs/{src/utils → utils}/clone.d.ts +0 -0
- /package/dist/{src → cjs}/utils/clone.d.ts.map +0 -0
- /package/dist/cjs/{src/utils → utils}/clone.js +0 -0
- /package/dist/cjs/{src/utils → utils}/event.d.ts +0 -0
- /package/dist/{src → cjs}/utils/event.d.ts.map +0 -0
- /package/dist/cjs/{src/utils → utils}/event.js +0 -0
- /package/dist/cjs/{src/utils → utils}/history.d.ts +0 -0
- /package/dist/{src → cjs}/utils/history.d.ts.map +0 -0
- /package/dist/cjs/{src/utils → utils}/history.js +0 -0
- /package/dist/cjs/{src/utils → utils}/id.d.ts +0 -0
- /package/dist/{src → cjs}/utils/id.d.ts.map +0 -0
- /package/dist/cjs/{src/utils → utils}/id.js +0 -0
- /package/dist/cjs/{src/utils → utils}/logger.d.ts +0 -0
- /package/dist/{src → cjs}/utils/logger.d.ts.map +0 -0
- /package/dist/cjs/{src/utils → utils}/logger.js +0 -0
- /package/dist/cjs/{src/utils → utils}/session.d.ts +0 -0
- /package/dist/{src → cjs}/utils/session.d.ts.map +0 -0
- /package/dist/cjs/{src/utils → utils}/session.js +0 -0
- /package/dist/{src/constants → constants}/index.d.ts +0 -0
- /package/dist/{src/constants → constants}/index.js +0 -0
- /package/dist/{src/core → core}/Events.d.ts +0 -0
- /package/dist/{src/core → core}/Events.js +0 -0
- /package/dist/{src/core → core}/PersistenceManager.d.ts +0 -0
- /package/dist/{src/core → core}/PersistenceManager.js +0 -0
- /package/dist/{src/core → core}/ResponseEngine.d.ts +0 -0
- /package/dist/{src/providers → providers}/AnthropicProvider.d.ts +0 -0
- /package/dist/{src/providers → providers}/GeminiProvider.d.ts +0 -0
- /package/dist/{src/providers → providers}/OpenAIProvider.d.ts +0 -0
- /package/dist/{src/providers → providers}/OpenRouterProvider.d.ts +0 -0
- /package/dist/{src/providers → providers}/index.d.ts +0 -0
- /package/dist/{src/providers → providers}/index.js +0 -0
- /package/dist/{src/types → types}/agent.js +0 -0
- /package/dist/{src/types → types}/ai.d.ts +0 -0
- /package/dist/{src/types → types}/ai.js +0 -0
- /package/dist/{src/types → types}/history.d.ts +0 -0
- /package/dist/{src/types → types}/history.js +0 -0
- /package/dist/{src/types → types}/persistence.d.ts +0 -0
- /package/dist/{src/types → types}/persistence.js +0 -0
- /package/dist/{src/types → types}/route.js +0 -0
- /package/dist/{src/types → types}/routing.d.ts +0 -0
- /package/dist/{src/types → types}/routing.js +0 -0
- /package/dist/{src/types → types}/schema.d.ts +0 -0
- /package/dist/{src/types → types}/schema.js +0 -0
- /package/dist/{src/types → types}/session.d.ts +0 -0
- /package/dist/{src/types → types}/session.js +0 -0
- /package/dist/{src/types → types}/template.js +0 -0
- /package/dist/{src/utils → utils}/clone.d.ts +0 -0
- /package/dist/{src/utils → utils}/clone.js +0 -0
- /package/dist/{src/utils → utils}/event.d.ts +0 -0
- /package/dist/{src/utils → utils}/event.js +0 -0
- /package/dist/{src/utils → utils}/history.d.ts +0 -0
- /package/dist/{src/utils → utils}/history.js +0 -0
- /package/dist/{src/utils → utils}/id.d.ts +0 -0
- /package/dist/{src/utils → utils}/id.js +0 -0
- /package/dist/{src/utils → utils}/logger.d.ts +0 -0
- /package/dist/{src/utils → utils}/logger.js +0 -0
- /package/dist/{src/utils → utils}/session.d.ts +0 -0
- /package/dist/{src/utils → utils}/session.js +0 -0
|
@@ -1,47 +1,59 @@
|
|
|
1
1
|
import { enterRoute, mergeCollected } from "../utils";
|
|
2
2
|
import { PromptComposer } from "./PromptComposer";
|
|
3
|
-
import { getLastMessageFromHistory } from "../utils/event";
|
|
4
|
-
import { logger } from "../utils/logger";
|
|
5
|
-
import { render } from "../utils/template";
|
|
6
3
|
import { END_ROUTE_ID } from "../constants";
|
|
4
|
+
import { createTemplateContext, getLastMessageFromHistory, logger } from "../utils";
|
|
7
5
|
export class RoutingEngine {
|
|
8
6
|
constructor(options) {
|
|
9
7
|
this.options = options;
|
|
10
8
|
}
|
|
11
9
|
/**
|
|
12
|
-
*
|
|
13
|
-
* Skips route scoring and only does step selection
|
|
10
|
+
* Enter a route if not already in it, merging initial data
|
|
14
11
|
* @private
|
|
15
12
|
*/
|
|
16
|
-
|
|
17
|
-
const { route, session, history, agentOptions, provider, context, signal } = params;
|
|
18
|
-
let updatedSession = session;
|
|
19
|
-
const selectedRoute = route;
|
|
20
|
-
// Check if this single route is complete
|
|
21
|
-
const completedRoutes = route.isComplete(session.data || {}) ? [route] : [];
|
|
22
|
-
// Enter route if not already in it
|
|
13
|
+
enterRouteIfNeeded(session, route) {
|
|
23
14
|
if (!session.currentRoute || session.currentRoute.id !== route.id) {
|
|
24
|
-
updatedSession = enterRoute(session, route.id, route.title);
|
|
15
|
+
let updatedSession = enterRoute(session, route.id, route.title);
|
|
25
16
|
if (route.initialData) {
|
|
26
17
|
updatedSession = mergeCollected(updatedSession, route.initialData);
|
|
27
|
-
logger.debug(`[RoutingEngine]
|
|
18
|
+
logger.debug(`[RoutingEngine] Merged initial data for route ${route.title}:`, route.initialData);
|
|
28
19
|
}
|
|
29
|
-
logger.debug(`[RoutingEngine]
|
|
20
|
+
logger.debug(`[RoutingEngine] Entered route: ${route.title}`);
|
|
21
|
+
return updatedSession;
|
|
30
22
|
}
|
|
31
|
-
|
|
23
|
+
return session;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Optimized decision for single-route scenarios
|
|
27
|
+
* Skips route scoring and only does step selection
|
|
28
|
+
* @private
|
|
29
|
+
*/
|
|
30
|
+
async decideSingleRouteStep(params) {
|
|
31
|
+
const { route, session, history, agentOptions, provider, context, signal } = params;
|
|
32
|
+
const selectedRoute = route;
|
|
33
|
+
// Enter route if not already in it (this may merge initial data)
|
|
34
|
+
const updatedSession = this.enterRouteIfNeeded(session, route);
|
|
35
|
+
// Check if this single route is complete (use updated session data)
|
|
36
|
+
const completedRoutes = route.isComplete(updatedSession.data || {}) ? [route] : [];
|
|
37
|
+
// Get candidate steps using new condition evaluation
|
|
38
|
+
const templateContext = createTemplateContext({
|
|
39
|
+
context,
|
|
40
|
+
session: updatedSession,
|
|
41
|
+
history,
|
|
42
|
+
data: updatedSession.data
|
|
43
|
+
});
|
|
32
44
|
const currentStep = updatedSession.currentStep
|
|
33
45
|
? route.getStep(updatedSession.currentStep.id)
|
|
34
46
|
: undefined;
|
|
35
|
-
const candidates = this.
|
|
47
|
+
const candidates = await this.getCandidateStepsWithConditions(route, currentStep, templateContext);
|
|
36
48
|
if (candidates.length === 0) {
|
|
37
49
|
logger.warn(`[RoutingEngine] Single-route: No valid steps found`);
|
|
38
50
|
return { selectedRoute, session: updatedSession };
|
|
39
51
|
}
|
|
40
|
-
// If only one candidate, check if
|
|
52
|
+
// If only one candidate, check if it's a completion marker
|
|
41
53
|
if (candidates.length === 1) {
|
|
42
|
-
const
|
|
43
|
-
if (isRouteComplete) {
|
|
44
|
-
logger.debug(`[RoutingEngine] Single-route: Route complete - all
|
|
54
|
+
const candidate = candidates[0];
|
|
55
|
+
if (candidate.isRouteComplete) {
|
|
56
|
+
logger.debug(`[RoutingEngine] Single-route: Route complete - all required fields collected or END_ROUTE reached`);
|
|
45
57
|
// Don't return a selectedStep when route is complete - there's no step to enter
|
|
46
58
|
return {
|
|
47
59
|
selectedRoute,
|
|
@@ -52,18 +64,39 @@ export class RoutingEngine {
|
|
|
52
64
|
};
|
|
53
65
|
}
|
|
54
66
|
else {
|
|
55
|
-
logger.debug(`[RoutingEngine] Single-route: Only one valid step: ${
|
|
67
|
+
logger.debug(`[RoutingEngine] Single-route: Only one valid step: ${candidate.step.id}`);
|
|
56
68
|
return {
|
|
57
69
|
selectedRoute,
|
|
58
|
-
selectedStep:
|
|
70
|
+
selectedStep: candidate.step,
|
|
59
71
|
session: updatedSession,
|
|
60
72
|
isRouteComplete: false,
|
|
61
73
|
completedRoutes,
|
|
62
74
|
};
|
|
63
75
|
}
|
|
64
76
|
}
|
|
77
|
+
// No candidates means route is likely complete or has no valid next steps
|
|
78
|
+
if (candidates.length === 0) {
|
|
79
|
+
const dataComplete = route.isComplete(updatedSession.data || {});
|
|
80
|
+
logger.debug(`[RoutingEngine] Single-route: No valid steps found - ` +
|
|
81
|
+
`(data: ${dataComplete ? 'complete' : 'incomplete'}, marking as ${dataComplete ? 'complete' : 'incomplete'})`);
|
|
82
|
+
return {
|
|
83
|
+
selectedRoute,
|
|
84
|
+
selectedStep: undefined,
|
|
85
|
+
session: updatedSession,
|
|
86
|
+
isRouteComplete: dataComplete,
|
|
87
|
+
completedRoutes,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
65
90
|
// Multiple candidates - use AI to select best step
|
|
66
91
|
const lastUserMessage = getLastMessageFromHistory(history);
|
|
92
|
+
// Collect AI context strings from step conditions
|
|
93
|
+
const stepConditionContext = [];
|
|
94
|
+
for (const candidate of candidates) {
|
|
95
|
+
const whenResult = await candidate.step.evaluateWhen(templateContext);
|
|
96
|
+
stepConditionContext.push(...whenResult.aiContextStrings);
|
|
97
|
+
}
|
|
98
|
+
// Check if any candidate is a completion marker (isRouteComplete = true)
|
|
99
|
+
const hasCompletionOption = candidates.some(c => c.isRouteComplete);
|
|
67
100
|
const stepPrompt = await this.buildStepSelectionPrompt({
|
|
68
101
|
route,
|
|
69
102
|
currentStep,
|
|
@@ -74,8 +107,10 @@ export class RoutingEngine {
|
|
|
74
107
|
agentOptions,
|
|
75
108
|
context,
|
|
76
109
|
session: updatedSession,
|
|
110
|
+
stepConditionContext,
|
|
111
|
+
includeEndRoute: hasCompletionOption,
|
|
77
112
|
});
|
|
78
|
-
const stepSchema = this.buildStepSelectionSchema(candidates.map((c) => c.step));
|
|
113
|
+
const stepSchema = this.buildStepSelectionSchema(candidates.filter(c => !c.isRouteComplete).map((c) => c.step), hasCompletionOption);
|
|
79
114
|
const stepResult = await provider.generateMessage({
|
|
80
115
|
prompt: stepPrompt,
|
|
81
116
|
history,
|
|
@@ -87,6 +122,19 @@ export class RoutingEngine {
|
|
|
87
122
|
},
|
|
88
123
|
});
|
|
89
124
|
const selectedStepId = stepResult.structured?.selectedStepId;
|
|
125
|
+
// Check if AI selected END_ROUTE
|
|
126
|
+
if (selectedStepId === END_ROUTE_ID) {
|
|
127
|
+
logger.debug(`[RoutingEngine] Single-route: AI selected END_ROUTE - completing route`);
|
|
128
|
+
logger.debug(`[RoutingEngine] Single-route: Reasoning: ${stepResult.structured?.reasoning}`);
|
|
129
|
+
return {
|
|
130
|
+
selectedRoute,
|
|
131
|
+
selectedStep: undefined,
|
|
132
|
+
responseDirectives: stepResult.structured?.responseDirectives,
|
|
133
|
+
session: updatedSession,
|
|
134
|
+
isRouteComplete: true,
|
|
135
|
+
completedRoutes,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
90
138
|
const selectedStep = candidates.find((c) => c.step.id === selectedStepId);
|
|
91
139
|
if (selectedStep) {
|
|
92
140
|
logger.debug(`[RoutingEngine] Single-route: AI selected step: ${selectedStep.step.id}`);
|
|
@@ -104,16 +152,17 @@ export class RoutingEngine {
|
|
|
104
152
|
};
|
|
105
153
|
}
|
|
106
154
|
/**
|
|
107
|
-
* Recursively traverse step chain to find first non-skipped step or END_ROUTE
|
|
155
|
+
* Recursively traverse step chain to find first non-skipped step or END_ROUTE using new condition evaluation
|
|
108
156
|
* @private
|
|
109
157
|
*/
|
|
110
|
-
|
|
158
|
+
async findFirstValidStepRecursiveWithConditions(currentStep, templateContext, visited) {
|
|
111
159
|
// Prevent infinite loops
|
|
112
160
|
if (visited.has(currentStep.id)) {
|
|
113
|
-
return {};
|
|
161
|
+
return { aiContextStrings: [] };
|
|
114
162
|
}
|
|
115
163
|
visited.add(currentStep.id);
|
|
116
164
|
const transitions = currentStep.getTransitions();
|
|
165
|
+
const allAiContextStrings = [];
|
|
117
166
|
for (const transition of transitions) {
|
|
118
167
|
const target = transition;
|
|
119
168
|
// Check for END_ROUTE transition
|
|
@@ -121,40 +170,69 @@ export class RoutingEngine {
|
|
|
121
170
|
// Found END_ROUTE - route is complete
|
|
122
171
|
return {
|
|
123
172
|
isRouteComplete: true,
|
|
173
|
+
aiContextStrings: allAiContextStrings,
|
|
124
174
|
};
|
|
125
175
|
}
|
|
126
176
|
if (!target)
|
|
127
177
|
continue;
|
|
178
|
+
// Evaluate skipIf condition using new system
|
|
179
|
+
const skipResult = await target.evaluateSkipIf(templateContext);
|
|
180
|
+
allAiContextStrings.push(...skipResult.aiContextStrings);
|
|
128
181
|
// If target should NOT be skipped, we found our step
|
|
129
|
-
if (!
|
|
182
|
+
if (!skipResult.shouldSkip) {
|
|
130
183
|
logger.debug(`[RoutingEngine] Found valid step after skipping: ${target.id}`);
|
|
131
184
|
return {
|
|
132
185
|
step: target,
|
|
133
186
|
isRouteComplete: false,
|
|
187
|
+
aiContextStrings: allAiContextStrings,
|
|
134
188
|
};
|
|
135
189
|
}
|
|
136
190
|
// Target should be skipped too - recurse deeper
|
|
137
191
|
logger.debug(`[RoutingEngine] Skipping step ${target.id} (skipIf condition met), continuing traversal...`);
|
|
138
|
-
const result = this.
|
|
192
|
+
const result = await this.findFirstValidStepRecursiveWithConditions(target, templateContext, visited);
|
|
193
|
+
// Collect AI context from recursive call
|
|
194
|
+
if (result.aiContextStrings) {
|
|
195
|
+
allAiContextStrings.push(...result.aiContextStrings);
|
|
196
|
+
}
|
|
139
197
|
// If we found something (a valid step or END_ROUTE), return it
|
|
140
198
|
if (result.step || result.isRouteComplete) {
|
|
141
|
-
return
|
|
199
|
+
return {
|
|
200
|
+
...result,
|
|
201
|
+
aiContextStrings: allAiContextStrings,
|
|
202
|
+
};
|
|
142
203
|
}
|
|
143
204
|
}
|
|
144
205
|
// No valid steps or END_ROUTE found in this branch
|
|
145
|
-
return {};
|
|
206
|
+
return { aiContextStrings: allAiContextStrings };
|
|
146
207
|
}
|
|
147
208
|
/**
|
|
148
|
-
* Identify valid next candidate steps
|
|
209
|
+
* Identify valid next candidate steps using new condition evaluation system
|
|
149
210
|
* Returns step with isRouteComplete flag if route is complete (all steps skipped + has END_ROUTE transition)
|
|
211
|
+
*
|
|
212
|
+
* NEW: Automatically completes route when all required fields are collected
|
|
150
213
|
*/
|
|
151
|
-
|
|
214
|
+
async getCandidateStepsWithConditions(route, currentStep, templateContext) {
|
|
152
215
|
const candidates = [];
|
|
216
|
+
const data = templateContext.data || {};
|
|
217
|
+
// Check if all required fields are collected
|
|
218
|
+
const allRequiredFieldsCollected = route.isComplete(data);
|
|
153
219
|
if (!currentStep) {
|
|
220
|
+
// Entering route for the first time
|
|
221
|
+
// If all required fields already collected, route is immediately complete
|
|
222
|
+
if (allRequiredFieldsCollected) {
|
|
223
|
+
logger.debug(`[RoutingEngine] Route ${route.title} complete on entry: all required fields already collected`);
|
|
224
|
+
// Return a completion marker - use initial step with completion flag
|
|
225
|
+
candidates.push({
|
|
226
|
+
step: route.initialStep,
|
|
227
|
+
isRouteComplete: true,
|
|
228
|
+
});
|
|
229
|
+
return candidates;
|
|
230
|
+
}
|
|
154
231
|
const initialStep = route.initialStep;
|
|
155
|
-
|
|
232
|
+
const skipResult = await initialStep.evaluateSkipIf(templateContext);
|
|
233
|
+
if (skipResult.shouldSkip) {
|
|
156
234
|
// Initial step should be skipped - recursively traverse to find first non-skipped step or END_ROUTE
|
|
157
|
-
const result = this.
|
|
235
|
+
const result = await this.findFirstValidStepRecursiveWithConditions(initialStep, templateContext, new Set());
|
|
158
236
|
if (result.isRouteComplete) {
|
|
159
237
|
// All steps are skipped and we reached END_ROUTE
|
|
160
238
|
logger.debug(`[RoutingEngine] Route complete on entry: all steps skipped, END_ROUTE reached`);
|
|
@@ -180,6 +258,55 @@ export class RoutingEngine {
|
|
|
180
258
|
}
|
|
181
259
|
return candidates;
|
|
182
260
|
}
|
|
261
|
+
// Check if all required fields are now collected (may have been collected during this step)
|
|
262
|
+
if (allRequiredFieldsCollected) {
|
|
263
|
+
// Required fields are complete - check if we should continue for optional fields
|
|
264
|
+
const transitions = currentStep.getTransitions();
|
|
265
|
+
const optionalFieldCandidates = [];
|
|
266
|
+
for (const transition of transitions) {
|
|
267
|
+
const target = transition;
|
|
268
|
+
// Check for END_ROUTE transition
|
|
269
|
+
if (target && target.id === END_ROUTE_ID) {
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
if (!target)
|
|
273
|
+
continue;
|
|
274
|
+
// Check if this step collects only optional fields
|
|
275
|
+
const collectsOnlyOptional = target.collect && target.collect.length > 0 &&
|
|
276
|
+
target.collect.every(field => route.optionalFields?.includes(field));
|
|
277
|
+
if (collectsOnlyOptional) {
|
|
278
|
+
// This step collects optional fields - it's a candidate
|
|
279
|
+
const skipResult = await target.evaluateSkipIf(templateContext);
|
|
280
|
+
if (!skipResult.shouldSkip) {
|
|
281
|
+
optionalFieldCandidates.push({
|
|
282
|
+
step: target,
|
|
283
|
+
isRouteComplete: false,
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
// If we have optional field candidates, include them along with END_ROUTE option
|
|
289
|
+
if (optionalFieldCandidates.length > 0) {
|
|
290
|
+
logger.debug(`[RoutingEngine] Required fields complete, but ${optionalFieldCandidates.length} optional field steps available`);
|
|
291
|
+
// Add optional field steps as candidates
|
|
292
|
+
candidates.push(...optionalFieldCandidates);
|
|
293
|
+
// Also add END_ROUTE as a candidate (AI can choose to skip optional fields)
|
|
294
|
+
candidates.push({
|
|
295
|
+
step: currentStep,
|
|
296
|
+
isRouteComplete: true,
|
|
297
|
+
});
|
|
298
|
+
return candidates;
|
|
299
|
+
}
|
|
300
|
+
// No optional fields to collect - route is complete
|
|
301
|
+
logger.debug(`[RoutingEngine] Route ${route.title} complete: all required fields collected, no optional fields remain`);
|
|
302
|
+
return [
|
|
303
|
+
{
|
|
304
|
+
step: currentStep,
|
|
305
|
+
isRouteComplete: true,
|
|
306
|
+
},
|
|
307
|
+
];
|
|
308
|
+
}
|
|
309
|
+
// Required fields not yet complete - continue normal step progression
|
|
183
310
|
const transitions = currentStep.getTransitions();
|
|
184
311
|
let hasEndRoute = false;
|
|
185
312
|
for (const transition of transitions) {
|
|
@@ -191,10 +318,11 @@ export class RoutingEngine {
|
|
|
191
318
|
}
|
|
192
319
|
if (!target)
|
|
193
320
|
continue;
|
|
194
|
-
|
|
321
|
+
const skipResult = await target.evaluateSkipIf(templateContext);
|
|
322
|
+
if (skipResult.shouldSkip) {
|
|
195
323
|
logger.debug(`[RoutingEngine] Skipping step ${target.id} (skipIf condition met)`);
|
|
196
324
|
// Recursively traverse to find next valid step or END_ROUTE
|
|
197
|
-
const result = this.
|
|
325
|
+
const result = await this.findFirstValidStepRecursiveWithConditions(target, templateContext, new Set([currentStep.id]) // Already visited current step
|
|
198
326
|
);
|
|
199
327
|
if (result.isRouteComplete) {
|
|
200
328
|
hasEndRoute = true;
|
|
@@ -227,7 +355,8 @@ export class RoutingEngine {
|
|
|
227
355
|
];
|
|
228
356
|
}
|
|
229
357
|
// Otherwise, stay in current step if it's still valid
|
|
230
|
-
|
|
358
|
+
const currentSkipResult = await currentStep.evaluateSkipIf(templateContext);
|
|
359
|
+
if (!currentSkipResult.shouldSkip) {
|
|
231
360
|
candidates.push({
|
|
232
361
|
step: currentStep,
|
|
233
362
|
isRouteComplete: hasEndRoute || false,
|
|
@@ -271,38 +400,69 @@ export class RoutingEngine {
|
|
|
271
400
|
};
|
|
272
401
|
}
|
|
273
402
|
const lastUserMessage = getLastMessageFromHistory(history);
|
|
403
|
+
const templateContext = createTemplateContext({
|
|
404
|
+
context,
|
|
405
|
+
session,
|
|
406
|
+
history,
|
|
407
|
+
data: session.data
|
|
408
|
+
});
|
|
409
|
+
// Apply route filtering with new condition evaluation system
|
|
410
|
+
const skipIfResult = await this.filterRoutesBySkipIf(routes, templateContext);
|
|
411
|
+
const whenResult = await this.filterRoutesByWhen(skipIfResult.eligibleRoutes, templateContext);
|
|
412
|
+
// Collect all AI context strings from route conditions
|
|
413
|
+
const routeConditionContext = [...skipIfResult.aiContextStrings, ...whenResult.aiContextStrings];
|
|
414
|
+
// Use filtered routes for further processing
|
|
415
|
+
const eligibleRoutes = whenResult.eligibleRoutes;
|
|
416
|
+
logger.debug(`[RoutingEngine] Route filtering: ${routes.length} total → ${skipIfResult.eligibleRoutes.length} after skipIf → ${eligibleRoutes.length} after when`);
|
|
274
417
|
let activeRouteSteps;
|
|
275
418
|
let activeRoute;
|
|
276
419
|
let isRouteComplete = false;
|
|
420
|
+
let updatedSession = session;
|
|
277
421
|
if (session.currentRoute) {
|
|
278
|
-
activeRoute =
|
|
422
|
+
activeRoute = eligibleRoutes.find((r) => r.id === session.currentRoute?.id);
|
|
279
423
|
if (activeRoute) {
|
|
280
424
|
const currentStep = session.currentStep
|
|
281
425
|
? activeRoute.getStep(session.currentStep.id)
|
|
282
426
|
: undefined;
|
|
283
|
-
const
|
|
427
|
+
const activeTemplateContext = createTemplateContext({
|
|
428
|
+
...templateContext,
|
|
429
|
+
session: updatedSession,
|
|
430
|
+
data: updatedSession.data
|
|
431
|
+
});
|
|
432
|
+
const candidates = await this.getCandidateStepsWithConditions(activeRoute, currentStep, activeTemplateContext);
|
|
284
433
|
// Check if route is complete
|
|
434
|
+
// getCandidateStepsWithConditions now automatically handles completion when required fields are collected
|
|
285
435
|
if (candidates.length === 1 && candidates[0].isRouteComplete) {
|
|
286
436
|
isRouteComplete = true;
|
|
287
|
-
logger.debug(`[RoutingEngine] Route ${activeRoute.title} is complete - all
|
|
437
|
+
logger.debug(`[RoutingEngine] Route ${activeRoute.title} is complete - all required fields collected or END_ROUTE reached`);
|
|
288
438
|
// Don't include steps in routing if route is complete
|
|
289
439
|
activeRouteSteps = undefined;
|
|
290
440
|
}
|
|
441
|
+
else if (candidates.length === 0) {
|
|
442
|
+
// No candidates - check if data is complete
|
|
443
|
+
const dataComplete = activeRoute.isComplete(updatedSession.data || {});
|
|
444
|
+
isRouteComplete = dataComplete;
|
|
445
|
+
logger.debug(`[RoutingEngine] Route ${activeRoute.title} has no valid steps - ` +
|
|
446
|
+
`marking as ${isRouteComplete ? 'complete' : 'incomplete'}`);
|
|
447
|
+
activeRouteSteps = undefined;
|
|
448
|
+
}
|
|
291
449
|
else {
|
|
450
|
+
// Multiple candidates or single non-complete candidate
|
|
292
451
|
activeRouteSteps = candidates.map((c) => c.step);
|
|
293
452
|
logger.debug(`[RoutingEngine] Found ${activeRouteSteps.length} candidate steps for active route`);
|
|
294
453
|
}
|
|
295
454
|
}
|
|
296
455
|
}
|
|
297
|
-
const routingSchema = this.buildDynamicRoutingSchema(
|
|
456
|
+
const routingSchema = this.buildDynamicRoutingSchema(eligibleRoutes, undefined, activeRouteSteps);
|
|
298
457
|
const routingPrompt = await this.buildRoutingPrompt({
|
|
299
458
|
history,
|
|
300
|
-
routes,
|
|
459
|
+
routes: eligibleRoutes,
|
|
301
460
|
lastMessage: lastUserMessage,
|
|
302
461
|
agentOptions,
|
|
303
462
|
session,
|
|
304
463
|
activeRouteSteps,
|
|
305
464
|
context,
|
|
465
|
+
routeConditionContext, // Pass AI context strings from route conditions
|
|
306
466
|
});
|
|
307
467
|
const routingResult = await provider.generateMessage({
|
|
308
468
|
prompt: routingPrompt,
|
|
@@ -317,19 +477,26 @@ export class RoutingEngine {
|
|
|
317
477
|
let selectedRoute;
|
|
318
478
|
let selectedStep;
|
|
319
479
|
let responseDirectives;
|
|
320
|
-
let updatedSession = session;
|
|
321
480
|
if (routingResult.structured?.routes) {
|
|
322
481
|
// Use cross-route completion evaluation to select optimal route
|
|
323
|
-
const optimalRoute = this.selectOptimalRoute(
|
|
324
|
-
//
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
routes
|
|
329
|
-
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
|
|
482
|
+
const optimalRoute = this.selectOptimalRoute(eligibleRoutes, updatedSession.data || {}, routingResult.structured.routes);
|
|
483
|
+
// If no optimal route found, check why
|
|
484
|
+
if (!optimalRoute) {
|
|
485
|
+
if (eligibleRoutes.length === 0) {
|
|
486
|
+
// No routes passed filtering
|
|
487
|
+
logger.debug(`[RoutingEngine] No eligible routes available - all routes filtered out`);
|
|
488
|
+
selectedRoute = undefined;
|
|
489
|
+
}
|
|
490
|
+
else {
|
|
491
|
+
// Routes exist but selectOptimalRoute returned undefined
|
|
492
|
+
// This means all routes are 100% complete
|
|
493
|
+
logger.debug(`[RoutingEngine] No optimal route found - all ${eligibleRoutes.length} eligible routes are complete`);
|
|
494
|
+
selectedRoute = undefined;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
else {
|
|
498
|
+
selectedRoute = optimalRoute;
|
|
499
|
+
}
|
|
333
500
|
responseDirectives = routingResult.structured.responseDirectives;
|
|
334
501
|
if (selectedRoute === activeRoute &&
|
|
335
502
|
routingResult.structured.selectedStepId &&
|
|
@@ -342,15 +509,7 @@ export class RoutingEngine {
|
|
|
342
509
|
}
|
|
343
510
|
if (selectedRoute) {
|
|
344
511
|
logger.debug(`[RoutingEngine] Selected route: ${selectedRoute.title}`);
|
|
345
|
-
|
|
346
|
-
session.currentRoute.id !== selectedRoute.id) {
|
|
347
|
-
updatedSession = enterRoute(session, selectedRoute.id, selectedRoute.title);
|
|
348
|
-
if (selectedRoute.initialData) {
|
|
349
|
-
updatedSession = mergeCollected(updatedSession, selectedRoute.initialData);
|
|
350
|
-
logger.debug(`[RoutingEngine] Merged initial data:`, selectedRoute.initialData);
|
|
351
|
-
}
|
|
352
|
-
logger.debug(`[RoutingEngine] Entered route: ${selectedRoute.title}`);
|
|
353
|
-
}
|
|
512
|
+
updatedSession = this.enterRouteIfNeeded(updatedSession, selectedRoute);
|
|
354
513
|
}
|
|
355
514
|
}
|
|
356
515
|
return {
|
|
@@ -362,6 +521,52 @@ export class RoutingEngine {
|
|
|
362
521
|
completedRoutes,
|
|
363
522
|
};
|
|
364
523
|
}
|
|
524
|
+
/**
|
|
525
|
+
* Filter routes based on skipIf conditions
|
|
526
|
+
* @param routes - All available routes
|
|
527
|
+
* @param templateContext - Context for condition evaluation
|
|
528
|
+
* @returns Object with eligible routes and collected AI context strings
|
|
529
|
+
*/
|
|
530
|
+
async filterRoutesBySkipIf(routes, templateContext) {
|
|
531
|
+
const eligibleRoutes = [];
|
|
532
|
+
const aiContextStrings = [];
|
|
533
|
+
for (const route of routes) {
|
|
534
|
+
const skipResult = await route.evaluateSkipIf(templateContext);
|
|
535
|
+
// Collect AI context strings from skipIf conditions
|
|
536
|
+
aiContextStrings.push(...skipResult.aiContextStrings);
|
|
537
|
+
// If route should not be skipped, it's eligible
|
|
538
|
+
if (!skipResult.programmaticResult) {
|
|
539
|
+
eligibleRoutes.push(route);
|
|
540
|
+
}
|
|
541
|
+
else {
|
|
542
|
+
logger.debug(`[RoutingEngine] Skipping route ${route.title} (skipIf condition met)`);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
return { eligibleRoutes, aiContextStrings };
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* Filter routes based on when conditions
|
|
549
|
+
* @param routes - Routes that passed skipIf filtering
|
|
550
|
+
* @param templateContext - Context for condition evaluation
|
|
551
|
+
* @returns Object with eligible routes and collected AI context strings
|
|
552
|
+
*/
|
|
553
|
+
async filterRoutesByWhen(routes, templateContext) {
|
|
554
|
+
const eligibleRoutes = [];
|
|
555
|
+
const aiContextStrings = [];
|
|
556
|
+
for (const route of routes) {
|
|
557
|
+
const whenResult = await route.evaluateWhen(templateContext);
|
|
558
|
+
// Collect AI context strings from when conditions
|
|
559
|
+
aiContextStrings.push(...whenResult.aiContextStrings);
|
|
560
|
+
// If route has no programmatic conditions or they evaluate to true, it's eligible
|
|
561
|
+
if (!whenResult.hasProgrammaticConditions || whenResult.programmaticResult) {
|
|
562
|
+
eligibleRoutes.push(route);
|
|
563
|
+
}
|
|
564
|
+
else {
|
|
565
|
+
logger.debug(`[RoutingEngine] Route ${route.title} not eligible (when condition not met)`);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
return { eligibleRoutes, aiContextStrings };
|
|
569
|
+
}
|
|
365
570
|
/**
|
|
366
571
|
* Evaluate all routes for completion based on collected data
|
|
367
572
|
* @param routes - All available routes
|
|
@@ -388,6 +593,7 @@ export class RoutingEngine {
|
|
|
388
593
|
/**
|
|
389
594
|
* Find the best route to continue based on completion status and user intent
|
|
390
595
|
* Prioritizes routes that are partially complete but not finished
|
|
596
|
+
* IMPORTANT: Completed routes are excluded to prevent re-entering finished tasks
|
|
391
597
|
* @param routes - All available routes
|
|
392
598
|
* @param data - Currently collected agent-level data
|
|
393
599
|
* @param routeScores - AI-generated route scores from routing decision
|
|
@@ -400,8 +606,10 @@ export class RoutingEngine {
|
|
|
400
606
|
for (const route of routes) {
|
|
401
607
|
const aiScore = routeScores[route.id] || 0;
|
|
402
608
|
const completionProgress = completionStatus.get(route.id) || 0;
|
|
403
|
-
//
|
|
404
|
-
|
|
609
|
+
// ALWAYS skip fully completed routes to prevent re-entering finished tasks
|
|
610
|
+
// Users should not be forced back into completed routes
|
|
611
|
+
if (completionProgress >= 1.0) {
|
|
612
|
+
logger.debug(`[RoutingEngine] Excluding completed route: ${route.title} (100% complete)`);
|
|
405
613
|
continue;
|
|
406
614
|
}
|
|
407
615
|
// Boost partially complete routes that match user intent
|
|
@@ -428,8 +636,8 @@ export class RoutingEngine {
|
|
|
428
636
|
* @private
|
|
429
637
|
*/
|
|
430
638
|
async buildStepSelectionPrompt(params) {
|
|
431
|
-
const { route, currentStep, candidates, data, history, lastMessage, agentOptions, context, session, } = params;
|
|
432
|
-
const templateContext = { context, session, history };
|
|
639
|
+
const { route, currentStep, candidates, data, history, lastMessage, agentOptions, context, session, stepConditionContext, includeEndRoute = false, } = params;
|
|
640
|
+
const templateContext = createTemplateContext({ context, session, history });
|
|
433
641
|
const pc = new PromptComposer(templateContext);
|
|
434
642
|
// Add agent metadata
|
|
435
643
|
if (agentOptions) {
|
|
@@ -454,7 +662,7 @@ export class RoutingEngine {
|
|
|
454
662
|
// Add conversation history
|
|
455
663
|
await pc.addInteractionHistory(history);
|
|
456
664
|
await pc.addLastMessage(lastMessage);
|
|
457
|
-
// Add candidate steps
|
|
665
|
+
// Add candidate steps with condition context
|
|
458
666
|
const stepDescriptions = [];
|
|
459
667
|
for (const candidate of candidates) {
|
|
460
668
|
const idx = candidates.indexOf(candidate);
|
|
@@ -462,9 +670,15 @@ export class RoutingEngine {
|
|
|
462
670
|
`${idx + 1}. Step ID: ${candidate.step.id}`,
|
|
463
671
|
` Description: ${candidate.step.description || "N/A"}`,
|
|
464
672
|
];
|
|
673
|
+
// Add when condition context
|
|
465
674
|
if (candidate.step.when) {
|
|
466
|
-
const
|
|
467
|
-
|
|
675
|
+
const whenResult = await candidate.step.evaluateWhen(templateContext);
|
|
676
|
+
if (whenResult.aiContextStrings.length > 0) {
|
|
677
|
+
parts.push(` When conditions: ${whenResult.aiContextStrings.join(", ")}`);
|
|
678
|
+
}
|
|
679
|
+
else if (typeof candidate.step.when === 'string') {
|
|
680
|
+
parts.push(` When this step should be completed: ${candidate.step.when}`);
|
|
681
|
+
}
|
|
468
682
|
}
|
|
469
683
|
if (candidate.step.requires && candidate.step.requires.length > 0) {
|
|
470
684
|
parts.push(` Required Data: ${candidate.step.requires.join(", ")}`);
|
|
@@ -475,8 +689,18 @@ export class RoutingEngine {
|
|
|
475
689
|
stepDescriptions.push(parts.join("\n"));
|
|
476
690
|
}
|
|
477
691
|
await pc.addInstruction(`Available Steps to Transition To:\n${stepDescriptions.join("\n\n")}`);
|
|
692
|
+
// Add step condition context if available
|
|
693
|
+
if (stepConditionContext && stepConditionContext.length > 0) {
|
|
694
|
+
await pc.addInstruction([
|
|
695
|
+
"",
|
|
696
|
+
"Additional step context from conditions:",
|
|
697
|
+
...stepConditionContext.map(ctx => `- ${ctx}`),
|
|
698
|
+
"",
|
|
699
|
+
"Consider this context when selecting the most appropriate step.",
|
|
700
|
+
].join("\n"));
|
|
701
|
+
}
|
|
478
702
|
// Add decision prompt
|
|
479
|
-
|
|
703
|
+
const decisionRules = [
|
|
480
704
|
"Task: Decide which step to transition to based on:",
|
|
481
705
|
"1. The user's current message and intent",
|
|
482
706
|
"2. The conversation history and context",
|
|
@@ -489,16 +713,24 @@ export class RoutingEngine {
|
|
|
489
713
|
"- If a step requires data we don't have, consider if we should collect it now",
|
|
490
714
|
"- Choose the step that makes the most sense for moving the conversation forward",
|
|
491
715
|
"- Steps with skipIf conditions that are met have already been filtered out",
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
716
|
+
];
|
|
717
|
+
if (includeEndRoute) {
|
|
718
|
+
decisionRules.push("", `- You can select '${END_ROUTE_ID}' to complete this route if:`, " * All required data has been collected", " * The user's intent suggests they're done with this task", " * No further steps are needed to fulfill the user's request");
|
|
719
|
+
}
|
|
720
|
+
decisionRules.push("", "Return ONLY JSON matching the provided schema.");
|
|
721
|
+
await pc.addInstruction(decisionRules.join("\n"));
|
|
495
722
|
return pc.build();
|
|
496
723
|
}
|
|
497
724
|
/**
|
|
498
725
|
* Build schema for step selection
|
|
499
726
|
* @private
|
|
500
727
|
*/
|
|
501
|
-
buildStepSelectionSchema(validSteps) {
|
|
728
|
+
buildStepSelectionSchema(validSteps, includeEndRoute = false) {
|
|
729
|
+
const stepIds = validSteps.map((s) => s.id);
|
|
730
|
+
// Add END_ROUTE as an option if requested (when required fields are complete)
|
|
731
|
+
if (includeEndRoute) {
|
|
732
|
+
stepIds.push(END_ROUTE_ID);
|
|
733
|
+
}
|
|
502
734
|
return {
|
|
503
735
|
description: "Step transition decision based on conversation context and collected data",
|
|
504
736
|
type: "object",
|
|
@@ -511,8 +743,10 @@ export class RoutingEngine {
|
|
|
511
743
|
selectedStepId: {
|
|
512
744
|
type: "string",
|
|
513
745
|
nullable: false,
|
|
514
|
-
description:
|
|
515
|
-
|
|
746
|
+
description: includeEndRoute
|
|
747
|
+
? `The ID of the selected step to transition to, or '${END_ROUTE_ID}' to complete the route`
|
|
748
|
+
: "The ID of the selected step to transition to",
|
|
749
|
+
enum: stepIds,
|
|
516
750
|
},
|
|
517
751
|
responseDirectives: {
|
|
518
752
|
type: "array",
|
|
@@ -588,8 +822,8 @@ export class RoutingEngine {
|
|
|
588
822
|
return base;
|
|
589
823
|
}
|
|
590
824
|
async buildRoutingPrompt(params) {
|
|
591
|
-
const { history, routes, lastMessage, agentOptions, session, activeRouteSteps, context, } = params;
|
|
592
|
-
const templateContext = { context, session, history };
|
|
825
|
+
const { history, routes, lastMessage, agentOptions, session, activeRouteSteps, context, routeConditionContext, } = params;
|
|
826
|
+
const templateContext = createTemplateContext({ context, session, history });
|
|
593
827
|
const pc = new PromptComposer(templateContext);
|
|
594
828
|
if (agentOptions) {
|
|
595
829
|
await pc.addAgentMeta(agentOptions);
|
|
@@ -641,15 +875,23 @@ export class RoutingEngine {
|
|
|
641
875
|
"",
|
|
642
876
|
"Available steps in active route (choose one to transition to):",
|
|
643
877
|
];
|
|
878
|
+
const activeStepConditionContext = [];
|
|
644
879
|
for (const step of activeRouteSteps) {
|
|
645
880
|
const idx = activeRouteSteps.indexOf(step);
|
|
646
881
|
stepInfo.push(`${idx + 1}. Step: ${step.id}`);
|
|
647
882
|
if (step.description) {
|
|
648
883
|
stepInfo.push(` Description: ${step.description}`);
|
|
649
884
|
}
|
|
650
|
-
|
|
885
|
+
// Collect AI context from step conditions
|
|
651
886
|
if (step.when) {
|
|
652
|
-
|
|
887
|
+
const whenResult = await step.evaluateWhen(templateContext);
|
|
888
|
+
if (whenResult.aiContextStrings.length > 0) {
|
|
889
|
+
stepInfo.push(` When conditions: ${whenResult.aiContextStrings.join(", ")}`);
|
|
890
|
+
activeStepConditionContext.push(...whenResult.aiContextStrings);
|
|
891
|
+
}
|
|
892
|
+
else if (typeof step.when === 'string') {
|
|
893
|
+
stepInfo.push(` When this step should be completed: ${step.when}`);
|
|
894
|
+
}
|
|
653
895
|
}
|
|
654
896
|
if (step.requires && step.requires.length > 0) {
|
|
655
897
|
stepInfo.push(` Required data: ${step.requires.join(", ")}`);
|
|
@@ -665,11 +907,31 @@ export class RoutingEngine {
|
|
|
665
907
|
stepInfo.push("- The logical next step in the conversation");
|
|
666
908
|
stepInfo.push("- Whether conditions for steps are met");
|
|
667
909
|
await pc.addInstruction(stepInfo.join("\n"));
|
|
910
|
+
// Add active step condition context if available
|
|
911
|
+
if (activeStepConditionContext.length > 0) {
|
|
912
|
+
await pc.addInstruction([
|
|
913
|
+
"",
|
|
914
|
+
"Additional context from step conditions:",
|
|
915
|
+
...activeStepConditionContext.map(ctx => `- ${ctx}`),
|
|
916
|
+
"",
|
|
917
|
+
"Use this context to inform your step selection decision.",
|
|
918
|
+
].join("\n"));
|
|
919
|
+
}
|
|
668
920
|
}
|
|
669
921
|
}
|
|
670
922
|
await pc.addInteractionHistory(history);
|
|
671
923
|
await pc.addLastMessage(lastMessage);
|
|
672
924
|
await pc.addRoutingOverview(routes);
|
|
925
|
+
// Add route condition context if available
|
|
926
|
+
if (routeConditionContext && routeConditionContext.length > 0) {
|
|
927
|
+
await pc.addInstruction([
|
|
928
|
+
"",
|
|
929
|
+
"Additional routing context from route conditions:",
|
|
930
|
+
...routeConditionContext.map(ctx => `- ${ctx}`),
|
|
931
|
+
"",
|
|
932
|
+
"Consider this context when scoring routes for relevance.",
|
|
933
|
+
].join("\n"));
|
|
934
|
+
}
|
|
673
935
|
await pc.addInstruction([
|
|
674
936
|
"Scoring rules:",
|
|
675
937
|
"- 90-100: explicit keywords + clear intent",
|