@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
|
@@ -9,8 +9,10 @@ const types_1 = require("../types");
|
|
|
9
9
|
const Step_1 = require("./Step");
|
|
10
10
|
const ResponseEngine_1 = require("./ResponseEngine");
|
|
11
11
|
const ResponsePipeline_1 = require("./ResponsePipeline");
|
|
12
|
+
const BatchExecutor_1 = require("./BatchExecutor");
|
|
13
|
+
const BatchPromptBuilder_1 = require("./BatchPromptBuilder");
|
|
12
14
|
const utils_1 = require("../utils");
|
|
13
|
-
const
|
|
15
|
+
const template_1 = require("../utils/template");
|
|
14
16
|
const constants_1 = require("../constants");
|
|
15
17
|
/**
|
|
16
18
|
* Error class for response generation failures
|
|
@@ -51,7 +53,12 @@ class ResponseModal {
|
|
|
51
53
|
// Initialize response engine
|
|
52
54
|
this.responseEngine = new ResponseEngine_1.ResponseEngine();
|
|
53
55
|
// Initialize response pipeline with agent dependencies
|
|
54
|
-
this.responsePipeline = new ResponsePipeline_1.ResponsePipeline(this.agent.getAgentOptions(),
|
|
56
|
+
this.responsePipeline = new ResponsePipeline_1.ResponsePipeline(this.agent.getAgentOptions(), () => this.agent.getRoutes(), // Pass a function to get routes dynamically
|
|
57
|
+
this.agent.getTools(), this.agent.getRoutingEngine(), this.agent.updateContext.bind(this.agent), this.agent.getUpdateDataMethod(), this.agent.updateCollectedData.bind(this.agent), this.getToolManager());
|
|
58
|
+
// Initialize batch executor for multi-step execution
|
|
59
|
+
this.batchExecutor = new BatchExecutor_1.BatchExecutor();
|
|
60
|
+
// Initialize batch prompt builder for combined prompts
|
|
61
|
+
this.batchPromptBuilder = new BatchPromptBuilder_1.BatchPromptBuilder();
|
|
55
62
|
}
|
|
56
63
|
/**
|
|
57
64
|
* Generate a non-streaming response using unified logic
|
|
@@ -195,6 +202,19 @@ class ResponseModal {
|
|
|
195
202
|
getResponsePipeline() {
|
|
196
203
|
return this.responsePipeline;
|
|
197
204
|
}
|
|
205
|
+
/**
|
|
206
|
+
* Get the ToolManager instance from the agent
|
|
207
|
+
* @private
|
|
208
|
+
*/
|
|
209
|
+
getToolManager() {
|
|
210
|
+
// Check if agent has a tool property (ToolManager)
|
|
211
|
+
if (this.agent && 'tool' in this.agent && this.agent.tool) {
|
|
212
|
+
return this.agent.tool;
|
|
213
|
+
}
|
|
214
|
+
// Log warning if ToolManager is not available
|
|
215
|
+
utils_1.logger.warn(`[ResponseModal] ToolManager not available on agent - tool execution will use fallback methods`);
|
|
216
|
+
return undefined;
|
|
217
|
+
}
|
|
198
218
|
// UNIFIED RESPONSE LOGIC - Consolidates common logic between streaming and non-streaming
|
|
199
219
|
// ============================================================================
|
|
200
220
|
/**
|
|
@@ -259,6 +279,7 @@ class ResponseModal {
|
|
|
259
279
|
throw ResponseGenerationError.fromError(error, 'step_preparation', params, { session, effectiveContext });
|
|
260
280
|
}
|
|
261
281
|
// PHASE 2: ROUTING + STEP SELECTION - Determine which route and step to use
|
|
282
|
+
// Also performs pre-extraction and batch determination
|
|
262
283
|
let routingResult;
|
|
263
284
|
try {
|
|
264
285
|
routingResult = await this.handleUnifiedRoutingAndStepSelection({
|
|
@@ -279,6 +300,9 @@ class ResponseModal {
|
|
|
279
300
|
selectedStep: routingResult.selectedStep,
|
|
280
301
|
responseDirectives: routingResult.responseDirectives,
|
|
281
302
|
isRouteComplete: routingResult.isRouteComplete,
|
|
303
|
+
batchSteps: routingResult.batchSteps,
|
|
304
|
+
batchStoppedReason: routingResult.batchStoppedReason,
|
|
305
|
+
batchStoppedAtStep: routingResult.batchStoppedAtStep,
|
|
282
306
|
};
|
|
283
307
|
}
|
|
284
308
|
catch (error) {
|
|
@@ -304,31 +328,156 @@ class ResponseModal {
|
|
|
304
328
|
context: params.context,
|
|
305
329
|
signal: params.signal,
|
|
306
330
|
});
|
|
331
|
+
let updatedSession = routingResult.session;
|
|
332
|
+
let isRouteComplete = routingResult.isRouteComplete;
|
|
333
|
+
// PRE-EXTRACTION: If entering a route that collects data, extract data from user message first
|
|
334
|
+
// This allows us to skip steps whose data is already provided
|
|
335
|
+
// Requirement 3.1: Perform Pre_Extraction before determining the Batch
|
|
336
|
+
if (routingResult.selectedRoute && !isRouteComplete) {
|
|
337
|
+
// Always pre-extract when route collects data (not just on new route entry)
|
|
338
|
+
// This ensures batch determination has the most up-to-date data
|
|
339
|
+
if (this.shouldPreExtractData(routingResult.selectedRoute)) {
|
|
340
|
+
utils_1.logger.debug(`[ResponseModal] Pre-extracting data for route: ${routingResult.selectedRoute.title}`);
|
|
341
|
+
const extractedData = await this.preExtractRouteData({
|
|
342
|
+
route: routingResult.selectedRoute,
|
|
343
|
+
history: params.history,
|
|
344
|
+
context: params.context,
|
|
345
|
+
session: updatedSession,
|
|
346
|
+
signal: params.signal,
|
|
347
|
+
});
|
|
348
|
+
if (extractedData && Object.keys(extractedData).length > 0) {
|
|
349
|
+
utils_1.logger.debug(`[ResponseModal] Pre-extracted data:`, extractedData);
|
|
350
|
+
// Requirement 3.3: Merge pre-extracted data into session before batch determination
|
|
351
|
+
updatedSession = (0, utils_1.mergeCollected)(updatedSession, extractedData);
|
|
352
|
+
// Also update agent's collected data
|
|
353
|
+
await this.agent.updateCollectedData(extractedData);
|
|
354
|
+
// Re-check route completion after pre-extraction
|
|
355
|
+
const allRequiredFieldsCollected = routingResult.selectedRoute.isComplete(updatedSession.data || {});
|
|
356
|
+
if (allRequiredFieldsCollected) {
|
|
357
|
+
utils_1.logger.debug(`[ResponseModal] Route ${routingResult.selectedRoute.title} completed after pre-extraction`);
|
|
358
|
+
isRouteComplete = true;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
// BATCH DETERMINATION: Use BatchExecutor to determine which steps can execute together
|
|
364
|
+
// Requirement 3.4: Pre-extraction results affect batch determination
|
|
365
|
+
let batchSteps;
|
|
366
|
+
let batchStoppedReason;
|
|
367
|
+
let batchStoppedAtStep;
|
|
368
|
+
if (routingResult.selectedRoute && !isRouteComplete) {
|
|
369
|
+
// Determine current step position for batch determination
|
|
370
|
+
const currentStep = routingResult.selectedStep ||
|
|
371
|
+
(updatedSession.currentStep ? routingResult.selectedRoute.getStep(updatedSession.currentStep.id) : undefined);
|
|
372
|
+
utils_1.logger.debug(`[ResponseModal] Determining batch starting from step: ${currentStep?.id || 'initial'}`);
|
|
373
|
+
const batchResult = await this.batchExecutor.determineBatch({
|
|
374
|
+
route: routingResult.selectedRoute,
|
|
375
|
+
currentStep,
|
|
376
|
+
sessionData: updatedSession.data || {},
|
|
377
|
+
context: params.context,
|
|
378
|
+
});
|
|
379
|
+
batchSteps = batchResult.steps;
|
|
380
|
+
batchStoppedReason = batchResult.stoppedReason;
|
|
381
|
+
batchStoppedAtStep = batchResult.stoppedAtStep;
|
|
382
|
+
utils_1.logger.debug(`[ResponseModal] Batch determined: ${batchSteps.length} steps, stopped reason: ${batchStoppedReason}`);
|
|
383
|
+
}
|
|
307
384
|
// Determine next step using pipeline method for consistency
|
|
308
|
-
const stepResult = this.responsePipeline.determineNextStep({
|
|
385
|
+
const stepResult = await this.responsePipeline.determineNextStep({
|
|
309
386
|
selectedRoute: routingResult.selectedRoute,
|
|
310
387
|
selectedStep: routingResult.selectedStep,
|
|
311
|
-
session:
|
|
312
|
-
isRouteComplete
|
|
388
|
+
session: updatedSession, // Use updated session with pre-extracted data
|
|
389
|
+
isRouteComplete, // Use updated completion status
|
|
313
390
|
});
|
|
314
391
|
return {
|
|
315
392
|
selectedRoute: routingResult.selectedRoute,
|
|
316
393
|
selectedStep: stepResult.nextStep, // Use the determined next step
|
|
317
394
|
responseDirectives: routingResult.responseDirectives,
|
|
318
395
|
session: stepResult.session,
|
|
319
|
-
isRouteComplete
|
|
396
|
+
isRouteComplete, // Use updated completion status
|
|
397
|
+
batchSteps,
|
|
398
|
+
batchStoppedReason,
|
|
399
|
+
batchStoppedAtStep,
|
|
320
400
|
};
|
|
321
401
|
}
|
|
322
402
|
catch (error) {
|
|
323
403
|
throw ResponseGenerationError.fromError(error, 'routing_optimization', params);
|
|
324
404
|
}
|
|
325
405
|
}
|
|
406
|
+
/**
|
|
407
|
+
* Check if a route should pre-extract data before determining the initial step
|
|
408
|
+
* @private
|
|
409
|
+
*/
|
|
410
|
+
shouldPreExtractData(route) {
|
|
411
|
+
// Pre-extract if route has declared required or optional fields
|
|
412
|
+
if (route.requiredFields && route.requiredFields.length > 0) {
|
|
413
|
+
return true;
|
|
414
|
+
}
|
|
415
|
+
if (route.optionalFields && route.optionalFields.length > 0) {
|
|
416
|
+
return true;
|
|
417
|
+
}
|
|
418
|
+
// Pre-extract if any step in the route collects data
|
|
419
|
+
const steps = route.getAllSteps();
|
|
420
|
+
const hasDataCollectionSteps = steps.some(step => step.collect && step.collect.length > 0);
|
|
421
|
+
return hasDataCollectionSteps;
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Pre-extract data from user message when entering a route
|
|
425
|
+
* This allows skipping steps whose data is already provided
|
|
426
|
+
* @private
|
|
427
|
+
*/
|
|
428
|
+
async preExtractRouteData(params) {
|
|
429
|
+
const { route, history, context, signal } = params;
|
|
430
|
+
// Build a schema for data extraction based on route's fields
|
|
431
|
+
const extractionSchema = this.agent.getSchema();
|
|
432
|
+
if (!extractionSchema) {
|
|
433
|
+
utils_1.logger.warn(`[ResponseModal] No schema available for pre-extraction`);
|
|
434
|
+
return {};
|
|
435
|
+
}
|
|
436
|
+
// Get last user message
|
|
437
|
+
const lastMessage = (0, utils_1.getLastMessageFromHistory)(history);
|
|
438
|
+
// Build extraction prompt
|
|
439
|
+
const extractionPrompt = [
|
|
440
|
+
`Extract any relevant information from the user's message that matches the following data fields.`,
|
|
441
|
+
`Only extract information that is explicitly stated or clearly implied.`,
|
|
442
|
+
``,
|
|
443
|
+
`User's message: "${lastMessage}"`,
|
|
444
|
+
``,
|
|
445
|
+
`Extract data for these fields if present:`,
|
|
446
|
+
];
|
|
447
|
+
// Add field descriptions
|
|
448
|
+
if (route.requiredFields) {
|
|
449
|
+
extractionPrompt.push(`Required fields: ${route.requiredFields.join(', ')}`);
|
|
450
|
+
}
|
|
451
|
+
if (route.optionalFields) {
|
|
452
|
+
extractionPrompt.push(`Optional fields: ${route.optionalFields.join(', ')}`);
|
|
453
|
+
}
|
|
454
|
+
extractionPrompt.push(``, `Return ONLY the extracted data as JSON. If no data can be extracted, return an empty object {}.`);
|
|
455
|
+
// Call AI to extract data
|
|
456
|
+
const agentOptions = this.agent.getAgentOptions();
|
|
457
|
+
try {
|
|
458
|
+
const result = await agentOptions.provider.generateMessage({
|
|
459
|
+
prompt: extractionPrompt.join('\n'),
|
|
460
|
+
history,
|
|
461
|
+
context,
|
|
462
|
+
signal,
|
|
463
|
+
parameters: {
|
|
464
|
+
jsonSchema: extractionSchema,
|
|
465
|
+
schemaName: 'data_extraction',
|
|
466
|
+
},
|
|
467
|
+
});
|
|
468
|
+
return result.structured || {};
|
|
469
|
+
}
|
|
470
|
+
catch (error) {
|
|
471
|
+
utils_1.logger.error(`[ResponseModal] Pre-extraction failed:`, error);
|
|
472
|
+
return {};
|
|
473
|
+
}
|
|
474
|
+
}
|
|
326
475
|
/**
|
|
327
476
|
* Unified response generation for non-streaming responses
|
|
328
477
|
* @private
|
|
329
478
|
*/
|
|
330
479
|
async generateUnifiedResponse(responseContext) {
|
|
331
|
-
const { effectiveContext, session: initialSession, history, selectedRoute, selectedStep, responseDirectives, isRouteComplete } = responseContext;
|
|
480
|
+
const { effectiveContext, session: initialSession, history, selectedRoute, selectedStep, responseDirectives, isRouteComplete, batchSteps, batchStoppedReason, } = responseContext;
|
|
332
481
|
let session = initialSession;
|
|
333
482
|
// Get last user message (needed for both route and completion handling)
|
|
334
483
|
// Convert HistoryItem[] to Event[] for internal processing
|
|
@@ -336,35 +485,79 @@ class ResponseModal {
|
|
|
336
485
|
const lastMessageText = (0, utils_1.getLastMessageFromHistory)(historyEvents);
|
|
337
486
|
let message;
|
|
338
487
|
let toolCalls = undefined;
|
|
488
|
+
let executedSteps;
|
|
489
|
+
let stoppedReason;
|
|
339
490
|
if (selectedRoute && !isRouteComplete) {
|
|
340
|
-
//
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
491
|
+
// Check if we have batch steps to execute
|
|
492
|
+
if (batchSteps && batchSteps.length > 0) {
|
|
493
|
+
// BATCH EXECUTION: Execute multiple steps in a single LLM call
|
|
494
|
+
utils_1.logger.debug(`[ResponseModal] Executing batch of ${batchSteps.length} steps`);
|
|
495
|
+
const batchResult = await this.executeBatchResponse({
|
|
496
|
+
selectedRoute,
|
|
497
|
+
batchSteps,
|
|
498
|
+
responseDirectives,
|
|
499
|
+
session,
|
|
500
|
+
history,
|
|
501
|
+
context: effectiveContext,
|
|
502
|
+
historyEvents,
|
|
503
|
+
});
|
|
504
|
+
message = batchResult.message;
|
|
505
|
+
toolCalls = batchResult.toolCalls;
|
|
506
|
+
session = batchResult.session;
|
|
507
|
+
executedSteps = batchResult.executedSteps;
|
|
508
|
+
stoppedReason = batchStoppedReason;
|
|
509
|
+
}
|
|
510
|
+
else {
|
|
511
|
+
// SINGLE STEP EXECUTION: Fall back to single-step processing
|
|
512
|
+
// This happens when batch determination returns empty (first step needs input)
|
|
513
|
+
const result = await this.processRouteResponse({
|
|
514
|
+
selectedRoute,
|
|
515
|
+
selectedStep,
|
|
516
|
+
responseDirectives,
|
|
517
|
+
session,
|
|
518
|
+
history,
|
|
519
|
+
context: effectiveContext,
|
|
520
|
+
lastMessageText,
|
|
521
|
+
historyEvents,
|
|
522
|
+
signal: undefined,
|
|
523
|
+
});
|
|
524
|
+
message = result.message;
|
|
525
|
+
toolCalls = result.toolCalls;
|
|
526
|
+
session = result.session;
|
|
527
|
+
// Track executed step for single-step execution
|
|
528
|
+
if (selectedStep) {
|
|
529
|
+
executedSteps = [{
|
|
530
|
+
id: selectedStep.id,
|
|
531
|
+
routeId: selectedRoute.id,
|
|
532
|
+
}];
|
|
533
|
+
}
|
|
534
|
+
stoppedReason = batchStoppedReason || 'needs_input';
|
|
535
|
+
}
|
|
355
536
|
}
|
|
356
537
|
else if (isRouteComplete && selectedRoute) {
|
|
357
538
|
// Handle route completion
|
|
358
|
-
message
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
539
|
+
utils_1.logger.debug(`[ResponseModal] Generating completion message for route: ${selectedRoute.title}`);
|
|
540
|
+
try {
|
|
541
|
+
message = await this.handleRouteCompletion({
|
|
542
|
+
selectedRoute,
|
|
543
|
+
session,
|
|
544
|
+
context: effectiveContext,
|
|
545
|
+
lastMessageText,
|
|
546
|
+
historyEvents,
|
|
547
|
+
signal: undefined,
|
|
548
|
+
});
|
|
549
|
+
// Set step to END_ROUTE marker
|
|
550
|
+
session = (0, utils_1.enterStep)(session, constants_1.END_ROUTE_ID, "Route completed");
|
|
551
|
+
stoppedReason = 'route_complete';
|
|
552
|
+
utils_1.logger.debug(`[ResponseModal] Route ${selectedRoute.title} completed. Entered END_ROUTE step.`);
|
|
553
|
+
}
|
|
554
|
+
catch (error) {
|
|
555
|
+
utils_1.logger.error(`[ResponseModal] Error generating completion message:`, error);
|
|
556
|
+
// Fallback to simple completion message
|
|
557
|
+
message = `Thank you! I've recorded all the information for your ${selectedRoute.title.toLowerCase()}.`;
|
|
558
|
+
session = (0, utils_1.enterStep)(session, constants_1.END_ROUTE_ID, "Route completed");
|
|
559
|
+
stoppedReason = 'route_complete';
|
|
560
|
+
}
|
|
368
561
|
}
|
|
369
562
|
else {
|
|
370
563
|
// Fallback: No routes defined, generate a simple response
|
|
@@ -373,37 +566,268 @@ class ResponseModal {
|
|
|
373
566
|
context: effectiveContext,
|
|
374
567
|
session,
|
|
375
568
|
});
|
|
569
|
+
// For fallback responses, set empty executedSteps and no stoppedReason
|
|
570
|
+
// since there's no route/step execution happening
|
|
571
|
+
executedSteps = [];
|
|
572
|
+
stoppedReason = undefined;
|
|
376
573
|
}
|
|
574
|
+
// Ensure response structure completeness (Requirement 8.1, 8.2, 8.3)
|
|
575
|
+
// - executedSteps: array of steps executed (empty array if none)
|
|
576
|
+
// - stoppedReason: why execution stopped (undefined for fallback)
|
|
577
|
+
// - session.currentStep: reflects final step position
|
|
377
578
|
return {
|
|
378
579
|
message,
|
|
379
580
|
session,
|
|
380
581
|
toolCalls,
|
|
381
582
|
isRouteComplete,
|
|
583
|
+
executedSteps: executedSteps || [],
|
|
584
|
+
stoppedReason,
|
|
585
|
+
};
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* Execute a batch of steps with a single LLM call
|
|
589
|
+
*
|
|
590
|
+
* This method:
|
|
591
|
+
* 1. Executes all prepare hooks for steps in the batch (in order)
|
|
592
|
+
* 2. Builds a combined prompt using BatchPromptBuilder
|
|
593
|
+
* 3. Makes a single LLM call
|
|
594
|
+
* 4. Collects data from the response for all steps
|
|
595
|
+
* 5. Executes all finalize hooks for steps in the batch (in order)
|
|
596
|
+
*
|
|
597
|
+
* @private
|
|
598
|
+
* **Validates: Requirements 1.1, 4.4, 5.1, 5.2**
|
|
599
|
+
*/
|
|
600
|
+
async executeBatchResponse(params) {
|
|
601
|
+
const { selectedRoute, batchSteps, history, context, historyEvents, signal } = params;
|
|
602
|
+
let session = params.session;
|
|
603
|
+
utils_1.logger.debug(`[ResponseModal] Starting batch execution for ${batchSteps.length} steps`);
|
|
604
|
+
// Create hook executor function
|
|
605
|
+
const executeHook = async (hook, hookContext, data, step) => {
|
|
606
|
+
// Find the route for this step
|
|
607
|
+
const route = selectedRoute;
|
|
608
|
+
// Convert StepOptions to Step if needed for executePrepareFinalize
|
|
609
|
+
const stepInstance = step?.id ? route.getStep(step.id) : undefined;
|
|
610
|
+
await this.executePrepareFinalize(hook, hookContext, data, route, stepInstance);
|
|
611
|
+
};
|
|
612
|
+
// PHASE 1: Execute all prepare hooks (Requirement 5.1)
|
|
613
|
+
utils_1.logger.debug(`[ResponseModal] Executing prepare hooks for batch`);
|
|
614
|
+
const prepareResult = await this.batchExecutor.executePrepareHooks({
|
|
615
|
+
steps: batchSteps,
|
|
616
|
+
context,
|
|
617
|
+
data: session.data,
|
|
618
|
+
executeHook,
|
|
619
|
+
});
|
|
620
|
+
if (!prepareResult.success) {
|
|
621
|
+
// Prepare hook failed - return error response
|
|
622
|
+
utils_1.logger.error(`[ResponseModal] Prepare hook failed:`, prepareResult.error);
|
|
623
|
+
throw new ResponseGenerationError(`Prepare hook failed: ${prepareResult.error?.message}`, {
|
|
624
|
+
phase: 'prepare_hooks',
|
|
625
|
+
context: {
|
|
626
|
+
stepId: prepareResult.error?.stepId,
|
|
627
|
+
executedSteps: prepareResult.executedSteps,
|
|
628
|
+
}
|
|
629
|
+
});
|
|
630
|
+
}
|
|
631
|
+
// PHASE 2: Build combined prompt using BatchPromptBuilder (Requirement 4.4)
|
|
632
|
+
utils_1.logger.debug(`[ResponseModal] Building batch prompt`);
|
|
633
|
+
const batchPromptResult = await this.batchPromptBuilder.buildBatchPrompt({
|
|
634
|
+
steps: batchSteps,
|
|
635
|
+
route: selectedRoute,
|
|
636
|
+
history: historyEvents,
|
|
637
|
+
context,
|
|
638
|
+
session,
|
|
639
|
+
agentOptions: this.agent.getAgentOptions(),
|
|
640
|
+
});
|
|
641
|
+
utils_1.logger.debug(`[ResponseModal] Batch prompt built with ${batchPromptResult.stepCount} steps, collecting: ${batchPromptResult.collectFields.join(', ')}`);
|
|
642
|
+
// Build response schema for batch (includes all collect fields)
|
|
643
|
+
const responseSchema = this.buildBatchResponseSchema(batchPromptResult.collectFields);
|
|
644
|
+
// Collect available tools for AI (from all steps in batch)
|
|
645
|
+
const availableTools = this.collectBatchAvailableTools(selectedRoute, batchSteps);
|
|
646
|
+
// PHASE 3: Make single LLM call (Requirement 4.4)
|
|
647
|
+
utils_1.logger.debug(`[ResponseModal] Making LLM call for batch`);
|
|
648
|
+
const agentOptions = this.agent.getAgentOptions();
|
|
649
|
+
const result = await agentOptions.provider.generateMessage({
|
|
650
|
+
prompt: batchPromptResult.prompt,
|
|
651
|
+
history: historyEvents,
|
|
652
|
+
context,
|
|
653
|
+
tools: availableTools,
|
|
654
|
+
signal,
|
|
655
|
+
parameters: responseSchema ? { jsonSchema: responseSchema, schemaName: "batch_response" } : undefined,
|
|
656
|
+
});
|
|
657
|
+
let message = result.structured?.message || result.message;
|
|
658
|
+
let toolCalls = result.structured?.toolCalls;
|
|
659
|
+
utils_1.logger.debug(`[ResponseModal] LLM response received for batch`);
|
|
660
|
+
// Execute tools if any
|
|
661
|
+
if (toolCalls && toolCalls.length > 0) {
|
|
662
|
+
const toolResult = await this.executeUnifiedToolLoop({
|
|
663
|
+
toolCalls,
|
|
664
|
+
context,
|
|
665
|
+
session,
|
|
666
|
+
history,
|
|
667
|
+
selectedRoute,
|
|
668
|
+
responsePrompt: batchPromptResult.prompt,
|
|
669
|
+
availableTools,
|
|
670
|
+
responseSchema,
|
|
671
|
+
signal,
|
|
672
|
+
});
|
|
673
|
+
session = toolResult.session;
|
|
674
|
+
toolCalls = toolResult.finalToolCalls;
|
|
675
|
+
if (toolResult.finalMessage) {
|
|
676
|
+
message = toolResult.finalMessage;
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
// PHASE 4: Collect data from response for all steps (Requirement 6.1, 6.2, 6.3)
|
|
680
|
+
utils_1.logger.debug(`[ResponseModal] Collecting batch data`);
|
|
681
|
+
const collectResult = this.batchExecutor.collectBatchData({
|
|
682
|
+
steps: batchSteps,
|
|
683
|
+
llmResponse: result.structured || {},
|
|
684
|
+
session,
|
|
685
|
+
schema: this.agent.getSchema(),
|
|
686
|
+
});
|
|
687
|
+
session = collectResult.session;
|
|
688
|
+
if (collectResult.collectedData && Object.keys(collectResult.collectedData).length > 0) {
|
|
689
|
+
// Update agent's collected data
|
|
690
|
+
await this.agent.updateCollectedData(collectResult.collectedData);
|
|
691
|
+
utils_1.logger.debug(`[ResponseModal] Batch collected data:`, collectResult.collectedData);
|
|
692
|
+
}
|
|
693
|
+
if (collectResult.validationErrors && collectResult.validationErrors.length > 0) {
|
|
694
|
+
utils_1.logger.warn(`[ResponseModal] Batch data validation errors:`, collectResult.validationErrors);
|
|
695
|
+
}
|
|
696
|
+
// Update session to final step position
|
|
697
|
+
const lastStep = batchSteps[batchSteps.length - 1];
|
|
698
|
+
if (lastStep?.id) {
|
|
699
|
+
session = (0, utils_1.enterStep)(session, lastStep.id, lastStep.description);
|
|
700
|
+
utils_1.logger.debug(`[ResponseModal] Updated session to final batch step: ${lastStep.id}`);
|
|
701
|
+
}
|
|
702
|
+
// PHASE 5: Execute all finalize hooks (Requirement 5.2)
|
|
703
|
+
utils_1.logger.debug(`[ResponseModal] Executing finalize hooks for batch`);
|
|
704
|
+
const finalizeResult = await this.batchExecutor.executeFinalizeHooks({
|
|
705
|
+
steps: batchSteps,
|
|
706
|
+
context,
|
|
707
|
+
data: session.data,
|
|
708
|
+
executeHook,
|
|
709
|
+
});
|
|
710
|
+
if (finalizeResult.errors && finalizeResult.errors.length > 0) {
|
|
711
|
+
// Log finalize errors but don't fail (Requirement 5.5)
|
|
712
|
+
utils_1.logger.warn(`[ResponseModal] Some finalize hooks failed:`, finalizeResult.errors);
|
|
713
|
+
}
|
|
714
|
+
// Build executed steps list
|
|
715
|
+
const executedSteps = batchSteps
|
|
716
|
+
.filter(step => step.id)
|
|
717
|
+
.map(step => ({
|
|
718
|
+
id: step.id,
|
|
719
|
+
routeId: selectedRoute.id,
|
|
720
|
+
}));
|
|
721
|
+
utils_1.logger.debug(`[ResponseModal] Batch execution complete. Executed ${executedSteps.length} steps`);
|
|
722
|
+
return {
|
|
723
|
+
message,
|
|
724
|
+
toolCalls,
|
|
725
|
+
session,
|
|
726
|
+
executedSteps,
|
|
727
|
+
};
|
|
728
|
+
}
|
|
729
|
+
/**
|
|
730
|
+
* Build response schema for batch execution
|
|
731
|
+
* @private
|
|
732
|
+
*/
|
|
733
|
+
buildBatchResponseSchema(collectFields) {
|
|
734
|
+
const properties = {
|
|
735
|
+
message: {
|
|
736
|
+
type: "string",
|
|
737
|
+
description: "Your response to the user",
|
|
738
|
+
},
|
|
739
|
+
};
|
|
740
|
+
// Add collect fields to schema
|
|
741
|
+
for (const field of collectFields) {
|
|
742
|
+
properties[field] = {
|
|
743
|
+
type: "string",
|
|
744
|
+
description: `Collected value for ${field}`,
|
|
745
|
+
};
|
|
746
|
+
}
|
|
747
|
+
return {
|
|
748
|
+
type: "object",
|
|
749
|
+
properties,
|
|
750
|
+
required: ["message"],
|
|
751
|
+
additionalProperties: true,
|
|
382
752
|
};
|
|
383
753
|
}
|
|
754
|
+
/**
|
|
755
|
+
* Collect available tools from all steps in the batch
|
|
756
|
+
* @private
|
|
757
|
+
*/
|
|
758
|
+
collectBatchAvailableTools(route, batchSteps) {
|
|
759
|
+
const availableTools = new Map();
|
|
760
|
+
// Add agent-level tools
|
|
761
|
+
this.agent.getTools().forEach((tool) => {
|
|
762
|
+
availableTools.set(tool.id, tool);
|
|
763
|
+
});
|
|
764
|
+
// Add route-level tools
|
|
765
|
+
route.getTools().forEach((tool) => {
|
|
766
|
+
availableTools.set(tool.id, tool);
|
|
767
|
+
});
|
|
768
|
+
// Add step-level tools from all batch steps
|
|
769
|
+
for (const step of batchSteps) {
|
|
770
|
+
if (step.tools) {
|
|
771
|
+
for (const toolRef of step.tools) {
|
|
772
|
+
if (typeof toolRef === "string") {
|
|
773
|
+
// Reference to registered tool - already in availableTools
|
|
774
|
+
}
|
|
775
|
+
else if (typeof toolRef === 'object' && 'id' in toolRef && toolRef.id) {
|
|
776
|
+
// Inline tool definition
|
|
777
|
+
availableTools.set(toolRef.id, toolRef);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
// Convert to the format expected by AI providers
|
|
783
|
+
return Array.from(availableTools.values()).map((tool) => ({
|
|
784
|
+
id: tool.id,
|
|
785
|
+
name: tool.name || tool.id,
|
|
786
|
+
description: tool.description,
|
|
787
|
+
parameters: tool.parameters,
|
|
788
|
+
}));
|
|
789
|
+
}
|
|
384
790
|
/**
|
|
385
791
|
* Unified streaming response generation
|
|
386
792
|
* @private
|
|
387
793
|
*/
|
|
388
794
|
async *generateUnifiedStreamingResponse(responseContext) {
|
|
389
|
-
const { effectiveContext, session: initialSession, history, selectedRoute, selectedStep, responseDirectives, isRouteComplete } = responseContext;
|
|
795
|
+
const { effectiveContext, session: initialSession, history, selectedRoute, selectedStep, responseDirectives, isRouteComplete, batchSteps, batchStoppedReason, } = responseContext;
|
|
390
796
|
const session = initialSession;
|
|
391
797
|
// Get last user message (needed for both route and completion handling)
|
|
392
798
|
// Convert HistoryItem[] to Event[] for internal processing
|
|
393
799
|
const historyEvents = (0, utils_1.historyToEvents)(history);
|
|
394
800
|
const lastMessageText = (0, utils_1.getLastMessageFromHistory)(historyEvents);
|
|
395
801
|
if (selectedRoute && !isRouteComplete) {
|
|
396
|
-
//
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
802
|
+
// Check if we have batch steps to execute
|
|
803
|
+
if (batchSteps && batchSteps.length > 0) {
|
|
804
|
+
// BATCH EXECUTION: Execute multiple steps with streaming
|
|
805
|
+
// Note: For streaming, we still use batch execution but stream the response
|
|
806
|
+
utils_1.logger.debug(`[ResponseModal] Streaming batch execution for ${batchSteps.length} steps`);
|
|
807
|
+
yield* this.streamBatchResponse({
|
|
808
|
+
selectedRoute,
|
|
809
|
+
batchSteps,
|
|
810
|
+
responseDirectives,
|
|
811
|
+
session,
|
|
812
|
+
history,
|
|
813
|
+
context: effectiveContext,
|
|
814
|
+
historyEvents,
|
|
815
|
+
batchStoppedReason,
|
|
816
|
+
});
|
|
817
|
+
}
|
|
818
|
+
else {
|
|
819
|
+
// SINGLE STEP EXECUTION: Fall back to single-step streaming
|
|
820
|
+
yield* this.processRouteStreamingResponse({
|
|
821
|
+
selectedRoute,
|
|
822
|
+
selectedStep,
|
|
823
|
+
responseDirectives,
|
|
824
|
+
session,
|
|
825
|
+
history,
|
|
826
|
+
context: effectiveContext,
|
|
827
|
+
lastMessageText,
|
|
828
|
+
historyEvents,
|
|
829
|
+
});
|
|
830
|
+
}
|
|
407
831
|
}
|
|
408
832
|
else if (isRouteComplete && selectedRoute) {
|
|
409
833
|
// Handle route completion streaming
|
|
@@ -424,6 +848,114 @@ class ResponseModal {
|
|
|
424
848
|
});
|
|
425
849
|
}
|
|
426
850
|
}
|
|
851
|
+
/**
|
|
852
|
+
* Stream a batch response with multiple steps
|
|
853
|
+
*
|
|
854
|
+
* Similar to executeBatchResponse but streams the LLM response.
|
|
855
|
+
*
|
|
856
|
+
* @private
|
|
857
|
+
*/
|
|
858
|
+
async *streamBatchResponse(params) {
|
|
859
|
+
const { selectedRoute, batchSteps, context, historyEvents, batchStoppedReason, signal } = params;
|
|
860
|
+
let session = params.session;
|
|
861
|
+
// Create hook executor function
|
|
862
|
+
const executeHook = async (hook, hookContext, data, step) => {
|
|
863
|
+
const route = selectedRoute;
|
|
864
|
+
const stepInstance = step?.id ? route.getStep(step.id) : undefined;
|
|
865
|
+
await this.executePrepareFinalize(hook, hookContext, data, route, stepInstance);
|
|
866
|
+
};
|
|
867
|
+
// PHASE 1: Execute all prepare hooks
|
|
868
|
+
const prepareResult = await this.batchExecutor.executePrepareHooks({
|
|
869
|
+
steps: batchSteps,
|
|
870
|
+
context,
|
|
871
|
+
data: session.data,
|
|
872
|
+
executeHook,
|
|
873
|
+
});
|
|
874
|
+
if (!prepareResult.success) {
|
|
875
|
+
// Yield error chunk
|
|
876
|
+
yield {
|
|
877
|
+
delta: "",
|
|
878
|
+
accumulated: "",
|
|
879
|
+
done: true,
|
|
880
|
+
session,
|
|
881
|
+
error: new ResponseGenerationError(`Prepare hook failed: ${prepareResult.error?.message}`, { phase: 'prepare_hooks' }),
|
|
882
|
+
};
|
|
883
|
+
return;
|
|
884
|
+
}
|
|
885
|
+
// PHASE 2: Build combined prompt
|
|
886
|
+
const batchPromptResult = await this.batchPromptBuilder.buildBatchPrompt({
|
|
887
|
+
steps: batchSteps,
|
|
888
|
+
route: selectedRoute,
|
|
889
|
+
history: historyEvents,
|
|
890
|
+
context,
|
|
891
|
+
session,
|
|
892
|
+
agentOptions: this.agent.getAgentOptions(),
|
|
893
|
+
});
|
|
894
|
+
const responseSchema = this.buildBatchResponseSchema(batchPromptResult.collectFields);
|
|
895
|
+
const availableTools = this.collectBatchAvailableTools(selectedRoute, batchSteps);
|
|
896
|
+
// PHASE 3: Stream LLM response
|
|
897
|
+
const agentOptions = this.agent.getAgentOptions();
|
|
898
|
+
const stream = agentOptions.provider.generateMessageStream({
|
|
899
|
+
prompt: batchPromptResult.prompt,
|
|
900
|
+
history: historyEvents,
|
|
901
|
+
context,
|
|
902
|
+
tools: availableTools,
|
|
903
|
+
signal,
|
|
904
|
+
parameters: responseSchema ? { jsonSchema: responseSchema, schemaName: "batch_stream_response" } : undefined,
|
|
905
|
+
});
|
|
906
|
+
// Build executed steps list
|
|
907
|
+
const executedSteps = batchSteps
|
|
908
|
+
.filter(step => step.id)
|
|
909
|
+
.map(step => ({
|
|
910
|
+
id: step.id,
|
|
911
|
+
routeId: selectedRoute.id,
|
|
912
|
+
}));
|
|
913
|
+
// Stream chunks
|
|
914
|
+
for await (const chunk of stream) {
|
|
915
|
+
// On final chunk, collect data and execute finalize hooks
|
|
916
|
+
if (chunk.done) {
|
|
917
|
+
// Collect data from response
|
|
918
|
+
if (chunk.structured) {
|
|
919
|
+
const collectResult = this.batchExecutor.collectBatchData({
|
|
920
|
+
steps: batchSteps,
|
|
921
|
+
llmResponse: chunk.structured,
|
|
922
|
+
session,
|
|
923
|
+
schema: this.agent.getSchema(),
|
|
924
|
+
});
|
|
925
|
+
session = collectResult.session;
|
|
926
|
+
if (collectResult.collectedData && Object.keys(collectResult.collectedData).length > 0) {
|
|
927
|
+
await this.agent.updateCollectedData(collectResult.collectedData);
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
// Update session to final step position
|
|
931
|
+
const lastStep = batchSteps[batchSteps.length - 1];
|
|
932
|
+
if (lastStep?.id) {
|
|
933
|
+
session = (0, utils_1.enterStep)(session, lastStep.id, lastStep.description);
|
|
934
|
+
}
|
|
935
|
+
// Execute finalize hooks
|
|
936
|
+
await this.batchExecutor.executeFinalizeHooks({
|
|
937
|
+
steps: batchSteps,
|
|
938
|
+
context,
|
|
939
|
+
data: session.data,
|
|
940
|
+
executeHook,
|
|
941
|
+
});
|
|
942
|
+
// Finalize session
|
|
943
|
+
await this.finalizeSession(session, context);
|
|
944
|
+
}
|
|
945
|
+
yield {
|
|
946
|
+
delta: chunk.delta,
|
|
947
|
+
accumulated: chunk.accumulated,
|
|
948
|
+
done: chunk.done,
|
|
949
|
+
session,
|
|
950
|
+
toolCalls: chunk.structured?.toolCalls,
|
|
951
|
+
isRouteComplete: false,
|
|
952
|
+
executedSteps: chunk.done ? executedSteps : undefined,
|
|
953
|
+
stoppedReason: chunk.done ? batchStoppedReason : undefined,
|
|
954
|
+
metadata: chunk.metadata,
|
|
955
|
+
structured: chunk.structured,
|
|
956
|
+
};
|
|
957
|
+
}
|
|
958
|
+
}
|
|
427
959
|
/**
|
|
428
960
|
* Execute prepare function for current step if available
|
|
429
961
|
* @private
|
|
@@ -469,12 +1001,20 @@ class ResponseModal {
|
|
|
469
1001
|
nextStep = selectedStep;
|
|
470
1002
|
}
|
|
471
1003
|
else {
|
|
472
|
-
//
|
|
1004
|
+
// Determine current step from session if we're already in this route
|
|
1005
|
+
const isInSameRoute = session.currentRoute?.id === selectedRoute.id;
|
|
1006
|
+
const currentStep = isInSameRoute && session.currentStep
|
|
1007
|
+
? selectedRoute.getStep(session.currentStep.id)
|
|
1008
|
+
: undefined;
|
|
1009
|
+
utils_1.logger.debug(`[ResponseModal] Step determination: route match=${isInSameRoute}, currentRoute=${session.currentRoute?.id}, selectedRoute=${selectedRoute.id}, currentStep=${currentStep?.id || 'none'}`);
|
|
1010
|
+
// Get candidate steps based on current position in the route
|
|
473
1011
|
const routingEngine = this.agent.getRoutingEngine();
|
|
474
|
-
const candidates = routingEngine.
|
|
1012
|
+
const candidates = await routingEngine.getCandidateStepsWithConditions(selectedRoute, currentStep, // Pass current step instead of undefined to maintain progression
|
|
1013
|
+
(0, template_1.createTemplateContext)({ data: session.data, session, context }));
|
|
1014
|
+
utils_1.logger.debug(`[ResponseModal] Found ${candidates.length} candidate steps${currentStep ? ' from current step ' + currentStep.id : ' (new route entry)'}`);
|
|
475
1015
|
if (candidates.length > 0) {
|
|
476
1016
|
nextStep = candidates[0].step;
|
|
477
|
-
utils_1.logger.debug(`[ResponseModal] Using first valid step: ${nextStep.id} for new route`);
|
|
1017
|
+
utils_1.logger.debug(`[ResponseModal] Using first valid step: ${nextStep.id}${currentStep ? ' (progressing from ' + currentStep.id + ')' : ' for new route'}`);
|
|
478
1018
|
}
|
|
479
1019
|
else {
|
|
480
1020
|
// Fallback to initial step even if it should be skipped
|
|
@@ -517,6 +1057,14 @@ class ResponseModal {
|
|
|
517
1057
|
});
|
|
518
1058
|
let message = result.structured?.message || result.message;
|
|
519
1059
|
let toolCalls = result.structured?.toolCalls;
|
|
1060
|
+
// Debug: Log initial AI response
|
|
1061
|
+
utils_1.logger.debug(`[ResponseModal] Initial AI response:`, {
|
|
1062
|
+
hasMessage: !!message,
|
|
1063
|
+
messageLength: message?.length || 0,
|
|
1064
|
+
hasToolCalls: !!toolCalls,
|
|
1065
|
+
toolCallsCount: toolCalls?.length || 0,
|
|
1066
|
+
toolNames: toolCalls?.map(tc => tc.toolName) || [],
|
|
1067
|
+
});
|
|
520
1068
|
// Execute tools with unified loop handling
|
|
521
1069
|
const toolResult = await this.executeUnifiedToolLoop({
|
|
522
1070
|
toolCalls,
|
|
@@ -551,11 +1099,17 @@ class ResponseModal {
|
|
|
551
1099
|
nextStep = selectedStep;
|
|
552
1100
|
}
|
|
553
1101
|
else {
|
|
1102
|
+
// Determine current step from session if we're already in this route
|
|
1103
|
+
const currentStep = session.currentRoute?.id === selectedRoute.id && session.currentStep
|
|
1104
|
+
? selectedRoute.getStep(session.currentStep.id)
|
|
1105
|
+
: undefined;
|
|
1106
|
+
// Get candidate steps based on current position in the route
|
|
554
1107
|
const routingEngine = this.agent.getRoutingEngine();
|
|
555
|
-
const candidates = routingEngine.
|
|
1108
|
+
const candidates = await routingEngine.getCandidateStepsWithConditions(selectedRoute, currentStep, // Pass current step instead of undefined to maintain progression
|
|
1109
|
+
(0, template_1.createTemplateContext)({ data: session.data, session, context }));
|
|
556
1110
|
if (candidates.length > 0) {
|
|
557
1111
|
nextStep = candidates[0].step;
|
|
558
|
-
utils_1.logger.debug(`[ResponseModal] Using first valid step: ${nextStep.id} for new route`);
|
|
1112
|
+
utils_1.logger.debug(`[ResponseModal] Using first valid step: ${nextStep.id}${currentStep ? ' (progressing from ' + currentStep.id + ')' : ' for new route'}`);
|
|
559
1113
|
}
|
|
560
1114
|
else {
|
|
561
1115
|
nextStep = selectedRoute.initialStep;
|
|
@@ -628,6 +1182,10 @@ class ResponseModal {
|
|
|
628
1182
|
if (chunk.done) {
|
|
629
1183
|
await this.finalizeSession(session, context);
|
|
630
1184
|
}
|
|
1185
|
+
// Response structure completeness (Requirement 8.1, 8.2, 8.3)
|
|
1186
|
+
// - executedSteps: single step executed in this response
|
|
1187
|
+
// - stoppedReason: 'needs_input' for single-step execution (waiting for user input)
|
|
1188
|
+
// - session.currentStep: reflects the executed step
|
|
631
1189
|
yield {
|
|
632
1190
|
delta: chunk.delta,
|
|
633
1191
|
accumulated: chunk.accumulated,
|
|
@@ -635,6 +1193,8 @@ class ResponseModal {
|
|
|
635
1193
|
session,
|
|
636
1194
|
toolCalls,
|
|
637
1195
|
isRouteComplete: false,
|
|
1196
|
+
executedSteps: chunk.done ? [{ id: nextStep.id, routeId: selectedRoute.id }] : undefined,
|
|
1197
|
+
stoppedReason: chunk.done ? 'needs_input' : undefined,
|
|
638
1198
|
metadata: chunk.metadata,
|
|
639
1199
|
structured: chunk.structured,
|
|
640
1200
|
};
|
|
@@ -653,7 +1213,7 @@ class ResponseModal {
|
|
|
653
1213
|
const historyEvents = (0, utils_1.historyToEvents)(history);
|
|
654
1214
|
// Execute initial dynamic tool calls
|
|
655
1215
|
if (toolCalls && toolCalls.length > 0) {
|
|
656
|
-
utils_1.logger.debug(`[ResponseModal] Executing ${toolCalls.length} dynamic tool calls
|
|
1216
|
+
utils_1.logger.debug(`[ResponseModal] Executing ${toolCalls.length} dynamic tool calls:`, toolCalls.map(tc => tc.toolName));
|
|
657
1217
|
for (const toolCall of toolCalls) {
|
|
658
1218
|
const tool = this.findAvailableTool(toolCall.toolName, selectedRoute);
|
|
659
1219
|
if (!tool) {
|
|
@@ -661,16 +1221,24 @@ class ResponseModal {
|
|
|
661
1221
|
continue;
|
|
662
1222
|
}
|
|
663
1223
|
try {
|
|
664
|
-
|
|
665
|
-
const
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
1224
|
+
// Use ToolManager for unified tool execution
|
|
1225
|
+
const toolManager = this.getToolManager();
|
|
1226
|
+
let toolResult;
|
|
1227
|
+
if (toolManager) {
|
|
1228
|
+
toolResult = await toolManager.executeTool({
|
|
1229
|
+
tool: tool,
|
|
1230
|
+
context,
|
|
1231
|
+
updateContext: this.agent.updateContext.bind(this.agent),
|
|
1232
|
+
updateData: this.agent.updateCollectedData.bind(this.agent),
|
|
1233
|
+
history: historyEvents, // Use Event[] for tool execution
|
|
1234
|
+
data: session.data,
|
|
1235
|
+
toolArguments: toolCall.arguments,
|
|
1236
|
+
});
|
|
1237
|
+
}
|
|
1238
|
+
else {
|
|
1239
|
+
// Fallback: execute tool directly if ToolManager not available
|
|
1240
|
+
throw new Error(`ToolManager not available for tool execution: ${toolCall.toolName}`);
|
|
1241
|
+
}
|
|
674
1242
|
// Check if tool execution was successful
|
|
675
1243
|
if (!toolResult.success) {
|
|
676
1244
|
utils_1.logger.error(`[ResponseModal] Tool execution failed: ${toolCall.toolName} - ${toolResult.error}`);
|
|
@@ -699,7 +1267,7 @@ class ResponseModal {
|
|
|
699
1267
|
// Continue execution but log the error
|
|
700
1268
|
}
|
|
701
1269
|
}
|
|
702
|
-
utils_1.logger.debug(`[ResponseModal] Executed dynamic tool: ${
|
|
1270
|
+
utils_1.logger.debug(`[ResponseModal] Executed dynamic tool: ${toolCall.toolName} (success: ${toolResult.success})`);
|
|
703
1271
|
}
|
|
704
1272
|
catch (error) {
|
|
705
1273
|
utils_1.logger.error(`[ResponseModal] Tool execution error for ${toolCall.toolName}:`, error);
|
|
@@ -715,7 +1283,7 @@ class ResponseModal {
|
|
|
715
1283
|
let finalMessage;
|
|
716
1284
|
while (hasToolCalls && toolLoopCount < MAX_TOOL_LOOPS) {
|
|
717
1285
|
toolLoopCount++;
|
|
718
|
-
utils_1.logger.debug(`[ResponseModal] Starting tool loop ${toolLoopCount}/${MAX_TOOL_LOOPS}`);
|
|
1286
|
+
utils_1.logger.debug(`[ResponseModal] Starting tool loop ${toolLoopCount}/${MAX_TOOL_LOOPS} with ${toolCalls?.length || 0} tool calls`);
|
|
719
1287
|
// Create tool result events with proper Event format structure
|
|
720
1288
|
const toolResultEvents = [];
|
|
721
1289
|
for (const toolCall of toolCalls || []) {
|
|
@@ -744,12 +1312,19 @@ class ResponseModal {
|
|
|
744
1312
|
// Create updated history with tool results (combine Event arrays)
|
|
745
1313
|
const updatedHistoryEvents = [...historyEvents, ...toolResultEvents];
|
|
746
1314
|
// Make follow-up AI call to see if more tools are needed
|
|
1315
|
+
// After first iteration, don't provide tools to force a text response
|
|
747
1316
|
const agentOptions = this.agent.getAgentOptions();
|
|
1317
|
+
const shouldProvideTools = toolLoopCount === 1;
|
|
1318
|
+
utils_1.logger.debug(`[ResponseModal] Making follow-up AI call (loop ${toolLoopCount}):`, {
|
|
1319
|
+
providingTools: shouldProvideTools,
|
|
1320
|
+
toolsCount: shouldProvideTools ? availableTools.length : 0,
|
|
1321
|
+
addingTextInstruction: toolLoopCount > 1,
|
|
1322
|
+
});
|
|
748
1323
|
const followUpResult = await agentOptions.provider.generateMessage({
|
|
749
|
-
prompt: responsePrompt,
|
|
1324
|
+
prompt: responsePrompt + (toolLoopCount > 1 ? "\n\nProvide a text response to the user based on the tool results." : ""),
|
|
750
1325
|
history: updatedHistoryEvents, // Use Event[] for AI provider
|
|
751
1326
|
context,
|
|
752
|
-
tools: availableTools,
|
|
1327
|
+
tools: shouldProvideTools ? availableTools : [], // Only provide tools on first iteration
|
|
753
1328
|
parameters: responseSchema ? {
|
|
754
1329
|
jsonSchema: responseSchema,
|
|
755
1330
|
schemaName: "tool_followup",
|
|
@@ -759,6 +1334,13 @@ class ResponseModal {
|
|
|
759
1334
|
// Check if follow-up call has more tool calls
|
|
760
1335
|
const followUpToolCalls = followUpResult.structured?.toolCalls;
|
|
761
1336
|
hasToolCalls = followUpToolCalls && followUpToolCalls.length > 0;
|
|
1337
|
+
utils_1.logger.debug(`[ResponseModal] Follow-up AI response (loop ${toolLoopCount}):`, {
|
|
1338
|
+
hasMessage: !!followUpResult.message,
|
|
1339
|
+
messageLength: followUpResult.message?.length || 0,
|
|
1340
|
+
hasToolCalls,
|
|
1341
|
+
toolCallsCount: followUpToolCalls?.length || 0,
|
|
1342
|
+
toolNames: followUpToolCalls?.map(tc => tc.toolName) || [],
|
|
1343
|
+
});
|
|
762
1344
|
if (hasToolCalls) {
|
|
763
1345
|
utils_1.logger.debug(`[ResponseModal] Follow-up call produced ${followUpToolCalls.length} additional tool calls`);
|
|
764
1346
|
// Execute the follow-up tool calls
|
|
@@ -769,16 +1351,24 @@ class ResponseModal {
|
|
|
769
1351
|
continue;
|
|
770
1352
|
}
|
|
771
1353
|
try {
|
|
772
|
-
|
|
773
|
-
const
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
1354
|
+
// Use ToolManager for unified tool execution
|
|
1355
|
+
const toolManager = this.getToolManager();
|
|
1356
|
+
let toolResult;
|
|
1357
|
+
if (toolManager) {
|
|
1358
|
+
toolResult = await toolManager.executeTool({
|
|
1359
|
+
tool: tool,
|
|
1360
|
+
context,
|
|
1361
|
+
updateContext: this.agent.updateContext.bind(this.agent),
|
|
1362
|
+
updateData: this.agent.updateCollectedData.bind(this.agent),
|
|
1363
|
+
history: updatedHistoryEvents, // Use Event[] for tool execution
|
|
1364
|
+
data: session.data,
|
|
1365
|
+
toolArguments: toolCall.arguments,
|
|
1366
|
+
});
|
|
1367
|
+
}
|
|
1368
|
+
else {
|
|
1369
|
+
// Fallback: execute tool directly if ToolManager not available
|
|
1370
|
+
throw new Error(`ToolManager not available for follow-up tool execution: ${toolCall.toolName}`);
|
|
1371
|
+
}
|
|
782
1372
|
// Check if tool execution was successful
|
|
783
1373
|
if (!toolResult.success) {
|
|
784
1374
|
utils_1.logger.error(`[ResponseModal] Follow-up tool execution failed: ${toolCall.toolName} - ${toolResult.error}`);
|
|
@@ -803,7 +1393,7 @@ class ResponseModal {
|
|
|
803
1393
|
utils_1.logger.error(`[ResponseModal] Failed to update data from follow-up tool ${toolCall.toolName}:`, error);
|
|
804
1394
|
}
|
|
805
1395
|
}
|
|
806
|
-
utils_1.logger.debug(`[ResponseModal] Executed follow-up tool: ${
|
|
1396
|
+
utils_1.logger.debug(`[ResponseModal] Executed follow-up tool: ${toolCall.toolName} (success: ${toolResult.success})`);
|
|
807
1397
|
}
|
|
808
1398
|
catch (error) {
|
|
809
1399
|
utils_1.logger.error(`[ResponseModal] Follow-up tool execution error for ${toolCall.toolName}:`, error);
|
|
@@ -824,6 +1414,12 @@ class ResponseModal {
|
|
|
824
1414
|
if (toolLoopCount >= MAX_TOOL_LOOPS) {
|
|
825
1415
|
utils_1.logger.warn(`[ResponseModal] Tool loop limit reached (${MAX_TOOL_LOOPS}), stopping`);
|
|
826
1416
|
}
|
|
1417
|
+
utils_1.logger.debug(`[ResponseModal] Tool loop completed:`, {
|
|
1418
|
+
totalIterations: toolLoopCount,
|
|
1419
|
+
hasFinalMessage: !!finalMessage,
|
|
1420
|
+
finalMessageLength: finalMessage?.length || 0,
|
|
1421
|
+
finalToolCallsCount: toolCalls?.length || 0,
|
|
1422
|
+
});
|
|
827
1423
|
return {
|
|
828
1424
|
session,
|
|
829
1425
|
finalToolCalls: toolCalls,
|
|
@@ -845,14 +1441,29 @@ class ResponseModal {
|
|
|
845
1441
|
const { result, selectedRoute, nextStep, session } = params;
|
|
846
1442
|
let updatedSession = session;
|
|
847
1443
|
// Extract collected data from final response (only for route-based interactions)
|
|
848
|
-
if (selectedRoute && result.structured
|
|
1444
|
+
if (selectedRoute && result.structured) {
|
|
849
1445
|
try {
|
|
850
1446
|
const collectedData = {};
|
|
851
1447
|
// AgentStructuredResponse extends Record<string, unknown>, so we can safely access properties
|
|
852
1448
|
const structuredData = result.structured;
|
|
853
|
-
|
|
1449
|
+
// Collect ALL route fields (required + optional) from structured response
|
|
1450
|
+
const allRouteFields = new Set();
|
|
1451
|
+
// Add route required fields
|
|
1452
|
+
if (selectedRoute.requiredFields) {
|
|
1453
|
+
selectedRoute.requiredFields.forEach(field => allRouteFields.add(String(field)));
|
|
1454
|
+
}
|
|
1455
|
+
// Add route optional fields
|
|
1456
|
+
if (selectedRoute.optionalFields) {
|
|
1457
|
+
selectedRoute.optionalFields.forEach(field => allRouteFields.add(String(field)));
|
|
1458
|
+
}
|
|
1459
|
+
// Also include current step's collect fields (in case they're not in route fields)
|
|
1460
|
+
if (nextStep?.collect) {
|
|
1461
|
+
nextStep.collect.forEach(field => allRouteFields.add(String(field)));
|
|
1462
|
+
}
|
|
1463
|
+
// Extract all available fields from structured response
|
|
1464
|
+
for (const field of allRouteFields) {
|
|
854
1465
|
const fieldKey = String(field);
|
|
855
|
-
if (fieldKey in structuredData) {
|
|
1466
|
+
if (fieldKey in structuredData && structuredData[fieldKey] !== undefined && structuredData[fieldKey] !== null) {
|
|
856
1467
|
collectedData[fieldKey] = structuredData[fieldKey];
|
|
857
1468
|
}
|
|
858
1469
|
}
|
|
@@ -915,34 +1526,60 @@ class ResponseModal {
|
|
|
915
1526
|
requires: endStepSpec.requires,
|
|
916
1527
|
prompt: endStepSpec.prompt || "Summarize what was accomplished and confirm completion based on the conversation history and collected data",
|
|
917
1528
|
});
|
|
918
|
-
// Build response schema for completion
|
|
919
|
-
const
|
|
920
|
-
|
|
921
|
-
|
|
1529
|
+
// Build response schema for completion (message only, no data collection)
|
|
1530
|
+
const completionSchema = {
|
|
1531
|
+
type: "object",
|
|
1532
|
+
properties: {
|
|
1533
|
+
message: {
|
|
1534
|
+
type: "string",
|
|
1535
|
+
description: "Completion message confirming what was accomplished",
|
|
1536
|
+
},
|
|
1537
|
+
},
|
|
1538
|
+
required: ["message"],
|
|
1539
|
+
additionalProperties: false,
|
|
1540
|
+
};
|
|
1541
|
+
const templateContext = (0, template_1.createTemplateContext)({ context, session, history: historyEvents });
|
|
1542
|
+
// Build completion response prompt using ResponseEngine
|
|
1543
|
+
// Filter out conditional guidelines - only include always-active ones
|
|
1544
|
+
const alwaysActiveGuidelines = [
|
|
1545
|
+
...this.agent.getGuidelines().filter(g => !g.condition),
|
|
1546
|
+
...selectedRoute.getGuidelines().filter(g => !g.condition),
|
|
1547
|
+
];
|
|
1548
|
+
let completitionPrompt = "Summarize what was accomplished and confirm completion";
|
|
1549
|
+
if (endStepSpec.prompt) {
|
|
1550
|
+
completitionPrompt = await (0, utils_1.render)(endStepSpec.prompt, templateContext);
|
|
1551
|
+
}
|
|
922
1552
|
const completionPrompt = await this.responseEngine.buildResponsePrompt({
|
|
923
1553
|
route: selectedRoute,
|
|
924
1554
|
currentStep: completionStep,
|
|
925
1555
|
rules: selectedRoute.getRules(),
|
|
926
1556
|
prohibitions: selectedRoute.getProhibitions(),
|
|
927
|
-
directives:
|
|
928
|
-
|
|
929
|
-
|
|
1557
|
+
directives: [
|
|
1558
|
+
`Task completed: ${selectedRoute.title}`,
|
|
1559
|
+
`Collected data: ${JSON.stringify(session.data, null, 2)}`,
|
|
1560
|
+
"Do NOT ask for more information - the task is complete",
|
|
1561
|
+
completitionPrompt,
|
|
1562
|
+
],
|
|
1563
|
+
history: historyEvents,
|
|
1564
|
+
lastMessage: lastMessageText,
|
|
930
1565
|
agentOptions: this.agent.getAgentOptions(),
|
|
931
|
-
combinedGuidelines:
|
|
1566
|
+
combinedGuidelines: alwaysActiveGuidelines, // Only non-conditional guidelines
|
|
932
1567
|
combinedTerms: this.mergeTerms(this.agent.getTerms(), selectedRoute.getTerms()),
|
|
933
1568
|
context,
|
|
934
1569
|
session,
|
|
935
|
-
agentSchema:
|
|
1570
|
+
agentSchema: undefined, // No data collection schema for completion
|
|
936
1571
|
});
|
|
937
1572
|
// Generate completion message using AI provider
|
|
938
1573
|
const agentOptions = this.agent.getAgentOptions();
|
|
1574
|
+
utils_1.logger.debug(`[ResponseModal] Calling AI provider for completion message...`);
|
|
939
1575
|
const completionResult = await agentOptions.provider.generateMessage({
|
|
940
1576
|
prompt: completionPrompt,
|
|
941
|
-
history: historyEvents,
|
|
1577
|
+
history: historyEvents,
|
|
942
1578
|
context,
|
|
943
1579
|
signal,
|
|
944
|
-
parameters: { jsonSchema:
|
|
1580
|
+
parameters: { jsonSchema: completionSchema, schemaName: "completion_message" },
|
|
945
1581
|
});
|
|
1582
|
+
utils_1.logger.debug(`[ResponseModal] AI provider returned completion result`);
|
|
946
1583
|
const message = completionResult.structured?.message || completionResult.message;
|
|
947
1584
|
utils_1.logger.debug(`[ResponseModal] Generated completion message for route: ${selectedRoute.title}`);
|
|
948
1585
|
// Check for onComplete transition
|
|
@@ -985,7 +1622,7 @@ class ResponseModal {
|
|
|
985
1622
|
});
|
|
986
1623
|
// Build response schema for completion
|
|
987
1624
|
const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute, completionStep, this.agent.getSchema());
|
|
988
|
-
const templateContext = { context, session, history: historyEvents }; // Use Event[] for template context
|
|
1625
|
+
const templateContext = (0, template_1.createTemplateContext)({ context, session, history: historyEvents }); // Use Event[] for template context
|
|
989
1626
|
// Build completion response prompt
|
|
990
1627
|
const completionPrompt = await this.responseEngine.buildResponsePrompt({
|
|
991
1628
|
route: selectedRoute,
|
|
@@ -1043,6 +1680,10 @@ class ResponseModal {
|
|
|
1043
1680
|
if (chunk.done) {
|
|
1044
1681
|
await this.finalizeSession(session, context);
|
|
1045
1682
|
}
|
|
1683
|
+
// Response structure completeness (Requirement 8.1, 8.2, 8.3)
|
|
1684
|
+
// - executedSteps: empty for route completion (no new steps executed)
|
|
1685
|
+
// - stoppedReason: 'route_complete' for completed routes
|
|
1686
|
+
// - session.currentStep: set to END_ROUTE
|
|
1046
1687
|
yield {
|
|
1047
1688
|
delta: chunk.delta,
|
|
1048
1689
|
accumulated: chunk.accumulated,
|
|
@@ -1050,6 +1691,8 @@ class ResponseModal {
|
|
|
1050
1691
|
session,
|
|
1051
1692
|
toolCalls: undefined,
|
|
1052
1693
|
isRouteComplete: true,
|
|
1694
|
+
executedSteps: chunk.done ? [] : undefined,
|
|
1695
|
+
stoppedReason: chunk.done ? 'route_complete' : undefined,
|
|
1053
1696
|
metadata: chunk.metadata,
|
|
1054
1697
|
structured: chunk.structured,
|
|
1055
1698
|
};
|
|
@@ -1124,6 +1767,10 @@ class ResponseModal {
|
|
|
1124
1767
|
if (chunk.done) {
|
|
1125
1768
|
await this.finalizeSession(session, context);
|
|
1126
1769
|
}
|
|
1770
|
+
// Response structure completeness (Requirement 8.1, 8.2, 8.3)
|
|
1771
|
+
// - executedSteps: empty for fallback (no route/step execution)
|
|
1772
|
+
// - stoppedReason: undefined for fallback (no route context)
|
|
1773
|
+
// - session.currentStep: unchanged (no step progression)
|
|
1127
1774
|
yield {
|
|
1128
1775
|
delta: chunk.delta,
|
|
1129
1776
|
accumulated: chunk.accumulated,
|
|
@@ -1131,6 +1778,8 @@ class ResponseModal {
|
|
|
1131
1778
|
session,
|
|
1132
1779
|
toolCalls: undefined,
|
|
1133
1780
|
isRouteComplete: false,
|
|
1781
|
+
executedSteps: chunk.done ? [] : undefined,
|
|
1782
|
+
stoppedReason: undefined,
|
|
1134
1783
|
metadata: chunk.metadata,
|
|
1135
1784
|
structured: chunk.structured,
|
|
1136
1785
|
};
|
|
@@ -1162,11 +1811,18 @@ class ResponseModal {
|
|
|
1162
1811
|
// UTILITY METHODS - Helper methods for tool management and other utilities
|
|
1163
1812
|
// ============================================================================
|
|
1164
1813
|
/**
|
|
1165
|
-
* Find an available tool by name for the given route
|
|
1166
|
-
*
|
|
1814
|
+
* Find an available tool by name for the given route using ToolManager
|
|
1815
|
+
* Delegates to ToolManager for unified tool resolution
|
|
1167
1816
|
* @private
|
|
1168
1817
|
*/
|
|
1169
1818
|
findAvailableTool(toolName, route) {
|
|
1819
|
+
// Use ToolManager for unified tool resolution
|
|
1820
|
+
const toolManager = this.getToolManager();
|
|
1821
|
+
if (toolManager) {
|
|
1822
|
+
return toolManager.find(toolName, undefined, undefined, route);
|
|
1823
|
+
}
|
|
1824
|
+
// Fallback to legacy resolution if ToolManager not available
|
|
1825
|
+
utils_1.logger.warn(`[ResponseModal] ToolManager not available, using legacy tool resolution for: ${toolName}`);
|
|
1170
1826
|
// Check route-level tools first (if route provided)
|
|
1171
1827
|
if (route) {
|
|
1172
1828
|
const routeTool = route
|
|
@@ -1180,10 +1836,24 @@ class ResponseModal {
|
|
|
1180
1836
|
return agentTools.find((tool) => tool.id === toolName || tool.name === toolName);
|
|
1181
1837
|
}
|
|
1182
1838
|
/**
|
|
1183
|
-
* Collect all available tools for the given route and step context
|
|
1839
|
+
* Collect all available tools for the given route and step context using ToolManager
|
|
1840
|
+
* Delegates to ToolManager for unified tool resolution and deduplication
|
|
1184
1841
|
* @private
|
|
1185
1842
|
*/
|
|
1186
1843
|
collectAvailableTools(route, step) {
|
|
1844
|
+
// Use ToolManager for unified tool collection if available
|
|
1845
|
+
const toolManager = this.getToolManager();
|
|
1846
|
+
if (toolManager) {
|
|
1847
|
+
const availableTools = toolManager.getAvailable(undefined, step, route);
|
|
1848
|
+
return availableTools.map((tool) => ({
|
|
1849
|
+
id: tool.id,
|
|
1850
|
+
name: tool.name || tool.id,
|
|
1851
|
+
description: tool.description,
|
|
1852
|
+
parameters: tool.parameters,
|
|
1853
|
+
}));
|
|
1854
|
+
}
|
|
1855
|
+
// Fallback to legacy collection logic if ToolManager not available
|
|
1856
|
+
utils_1.logger.warn(`[ResponseModal] ToolManager not available, using legacy tool collection`);
|
|
1187
1857
|
const availableTools = new Map();
|
|
1188
1858
|
// Add agent-level tools
|
|
1189
1859
|
this.agent.getTools().forEach((tool) => {
|
|
@@ -1254,45 +1924,61 @@ class ResponseModal {
|
|
|
1254
1924
|
// It's a tool reference - find and execute the tool
|
|
1255
1925
|
let tool;
|
|
1256
1926
|
if (typeof prepareOrFinalize === "string") {
|
|
1257
|
-
// Tool ID -
|
|
1258
|
-
const
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1927
|
+
// Tool ID - use ToolManager for unified resolution
|
|
1928
|
+
const toolManager = this.getToolManager();
|
|
1929
|
+
if (toolManager) {
|
|
1930
|
+
tool = toolManager.find(prepareOrFinalize, undefined, step, route);
|
|
1931
|
+
}
|
|
1932
|
+
else {
|
|
1933
|
+
// Fallback to legacy resolution if ToolManager not available
|
|
1934
|
+
utils_1.logger.warn(`[ResponseModal] ToolManager not available, using legacy tool resolution for prepare/finalize: ${prepareOrFinalize}`);
|
|
1935
|
+
const availableTools = new Map();
|
|
1936
|
+
// Add agent-level tools
|
|
1937
|
+
this.agent.getTools().forEach((t) => {
|
|
1266
1938
|
availableTools.set(t.id, t);
|
|
1267
1939
|
});
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1940
|
+
// Add route-level tools
|
|
1941
|
+
if (route) {
|
|
1942
|
+
route.getTools().forEach((t) => {
|
|
1943
|
+
availableTools.set(t.id, t);
|
|
1944
|
+
});
|
|
1945
|
+
}
|
|
1946
|
+
// Add step-level tools
|
|
1947
|
+
if (step?.tools) {
|
|
1948
|
+
for (const toolRef of step.tools) {
|
|
1949
|
+
if (typeof toolRef === "string") {
|
|
1950
|
+
// Keep as is
|
|
1951
|
+
}
|
|
1952
|
+
else if (typeof toolRef === 'object' && 'id' in toolRef && toolRef.id) {
|
|
1953
|
+
availableTools.set(toolRef.id, toolRef);
|
|
1954
|
+
}
|
|
1277
1955
|
}
|
|
1278
1956
|
}
|
|
1957
|
+
tool = availableTools.get(prepareOrFinalize);
|
|
1279
1958
|
}
|
|
1280
|
-
tool = availableTools.get(prepareOrFinalize);
|
|
1281
1959
|
}
|
|
1282
1960
|
else {
|
|
1283
1961
|
// Tool object - use directly
|
|
1284
1962
|
tool = prepareOrFinalize;
|
|
1285
1963
|
}
|
|
1286
1964
|
if (tool) {
|
|
1287
|
-
|
|
1288
|
-
const
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1965
|
+
// Use ToolManager for unified tool execution
|
|
1966
|
+
const toolManager = this.getToolManager();
|
|
1967
|
+
let result;
|
|
1968
|
+
if (toolManager) {
|
|
1969
|
+
result = await toolManager.executeTool({
|
|
1970
|
+
tool,
|
|
1971
|
+
context,
|
|
1972
|
+
updateContext: this.agent.updateContext.bind(this.agent),
|
|
1973
|
+
updateData: this.agent.updateCollectedData.bind(this.agent),
|
|
1974
|
+
history: [], // Empty history for prepare/finalize
|
|
1975
|
+
data,
|
|
1976
|
+
});
|
|
1977
|
+
}
|
|
1978
|
+
else {
|
|
1979
|
+
// Fallback: execute tool directly if ToolManager not available
|
|
1980
|
+
throw new Error(`ToolManager not available for prepare/finalize tool execution: ${typeof prepareOrFinalize === "string" ? prepareOrFinalize : "inline tool"}`);
|
|
1981
|
+
}
|
|
1296
1982
|
if (!result.success) {
|
|
1297
1983
|
utils_1.logger.error(`[ResponseModal] Tool execution failed in prepare/finalize: ${result.error}`);
|
|
1298
1984
|
throw new Error(`Tool execution failed: ${result.error}`);
|