@falai/agent 0.9.2 → 1.0.1
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 +281 -42
- 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/cjs/{src/core → core}/Agent.d.ts +16 -1
- package/dist/cjs/core/Agent.d.ts.map +1 -0
- package/dist/cjs/{src/core → core}/Agent.js +63 -2
- 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 +850 -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 +217 -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 +211 -0
- package/dist/cjs/core/ResponseEngine.js.map +1 -0
- package/dist/{src → cjs}/core/ResponseModal.d.ts +45 -0
- package/dist/cjs/core/ResponseModal.d.ts.map +1 -0
- package/dist/cjs/{src/core → core}/ResponseModal.js +752 -74
- package/dist/cjs/core/ResponseModal.js.map +1 -0
- package/dist/{src → cjs}/core/ResponsePipeline.d.ts +2 -2
- package/dist/cjs/core/ResponsePipeline.d.ts.map +1 -0
- package/dist/cjs/{src/core → core}/ResponsePipeline.js +13 -6
- package/dist/cjs/core/ResponsePipeline.js.map +1 -0
- package/dist/{src → cjs}/core/Route.d.ts +34 -5
- package/dist/cjs/core/Route.d.ts.map +1 -0
- package/dist/cjs/{src/core → core}/Route.js +196 -19
- package/dist/cjs/core/Route.js.map +1 -0
- package/dist/cjs/{src/core → core}/RoutingEngine.d.ts +30 -5
- package/dist/cjs/core/RoutingEngine.d.ts.map +1 -0
- package/dist/cjs/{src/core → core}/RoutingEngine.js +330 -80
- package/dist/cjs/core/RoutingEngine.js.map +1 -0
- package/dist/cjs/core/SessionManager.js.map +1 -0
- package/dist/{src → cjs}/core/Step.d.ts +31 -10
- package/dist/cjs/core/Step.d.ts.map +1 -0
- package/dist/cjs/{src/core → core}/Step.js +105 -10
- package/dist/cjs/core/Step.js.map +1 -0
- package/dist/cjs/core/ToolManager.js.map +1 -0
- package/dist/{src → cjs}/index.d.ts +4 -1
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/{src/index.js → index.js} +12 -1
- 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 +15 -3
- 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 +2 -1
- package/dist/{src → cjs}/types/index.d.ts.map +1 -1
- package/dist/cjs/{src/types → types}/index.js +6 -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 +111 -12
- 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.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/{src/core → core}/Agent.d.ts +16 -1
- package/dist/core/Agent.d.ts.map +1 -0
- package/dist/{src/core → core}/Agent.js +64 -3
- 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 +845 -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 +213 -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 +207 -0
- package/dist/core/ResponseEngine.js.map +1 -0
- package/dist/{cjs/src/core → core}/ResponseModal.d.ts +45 -0
- package/dist/core/ResponseModal.d.ts.map +1 -0
- package/dist/{src/core → core}/ResponseModal.js +752 -74
- package/dist/core/ResponseModal.js.map +1 -0
- package/dist/{cjs/src/core → core}/ResponsePipeline.d.ts +2 -2
- package/dist/core/ResponsePipeline.d.ts.map +1 -0
- package/dist/{src/core → core}/ResponsePipeline.js +13 -6
- package/dist/core/ResponsePipeline.js.map +1 -0
- package/dist/{cjs/src/core → core}/Route.d.ts +34 -5
- package/dist/core/Route.d.ts.map +1 -0
- package/dist/{src/core → core}/Route.js +195 -18
- package/dist/core/Route.js.map +1 -0
- package/dist/{src/core → core}/RoutingEngine.d.ts +30 -5
- package/dist/core/RoutingEngine.d.ts.map +1 -0
- package/dist/{src/core → core}/RoutingEngine.js +310 -60
- package/dist/core/RoutingEngine.js.map +1 -0
- package/dist/core/SessionManager.d.ts.map +1 -0
- package/dist/core/SessionManager.js.map +1 -0
- package/dist/{cjs/src/core → core}/Step.d.ts +31 -10
- package/dist/core/Step.d.ts.map +1 -0
- package/dist/{src/core → core}/Step.js +104 -9
- package/dist/core/Step.js.map +1 -0
- package/dist/core/ToolManager.d.ts.map +1 -0
- package/dist/core/ToolManager.js.map +1 -0
- package/dist/{cjs/src/index.d.ts → index.d.ts} +4 -1
- package/dist/index.d.ts.map +1 -0
- package/dist/{src/index.js → index.js} +3 -0
- 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 +15 -3
- 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 +2 -1
- package/dist/types/index.d.ts.map +1 -0
- package/dist/{src/types → types}/index.js +1 -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 +111 -12
- 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.map +1 -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/README.md +1 -0
- package/docs/api/README.md +237 -12
- package/docs/api/overview.md +206 -3
- package/docs/architecture/data-extraction-flow.md +363 -0
- package/docs/architecture/multi-step-execution.md +243 -0
- package/docs/core/agent/README.md +156 -5
- package/docs/core/agent/rules-and-prohibitions.md +113 -0
- package/docs/core/agent/session-management.md +1 -1
- package/docs/core/ai-integration/prompt-composition.md +135 -0
- package/docs/core/ai-integration/response-processing.md +146 -0
- package/docs/core/conversation-flows/data-collection.md +143 -0
- package/docs/core/conversation-flows/routes.md +2 -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 +193 -0
- package/docs/core/routing/intelligent-routing.md +118 -0
- package/docs/guides/getting-started/README.md +284 -3
- package/docs/guides/migration/README.md +27 -0
- package/docs/guides/migration/flexible-routing-conditions.md +375 -0
- package/docs/guides/migration/multi-step-execution.md +373 -0
- package/examples/advanced-patterns/knowledge-based-agent.ts +101 -24
- package/examples/advanced-patterns/persistent-onboarding.ts +40 -5
- 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 +4 -4
- package/examples/ai-providers/openai-integration.ts +1 -1
- 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 +54 -33
- package/examples/core-concepts/schema-driven-extraction.ts +33 -9
- package/examples/core-concepts/session-management.ts +51 -16
- package/examples/integrations/database-integration.ts +6 -6
- package/examples/integrations/healthcare-integration.ts +10 -10
- package/examples/integrations/search-integration.ts +8 -8
- package/examples/integrations/server-session-management.ts +8 -8
- package/examples/persistence/database-persistence.ts +15 -15
- package/examples/persistence/memory-sessions.ts +3 -3
- package/examples/persistence/redis-persistence.ts +7 -9
- package/examples/tools/data-enrichment-tools.ts +4 -4
- package/package.json +6 -4
- package/src/adapters/PrismaAdapter.ts +3 -2
- package/src/adapters/RedisAdapter.ts +3 -3
- package/src/core/Agent.ts +78 -2
- package/src/core/BatchExecutor.ts +1166 -0
- package/src/core/BatchPromptBuilder.ts +293 -0
- package/src/core/PromptComposer.ts +53 -16
- package/src/core/ResponseEngine.ts +168 -29
- package/src/core/ResponseModal.ts +954 -74
- package/src/core/ResponsePipeline.ts +17 -9
- package/src/core/Route.ts +223 -22
- package/src/core/RoutingEngine.ts +426 -83
- package/src/core/Step.ts +144 -16
- package/src/index.ts +19 -0
- 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 +15 -3
- package/src/types/index.ts +12 -1
- package/src/types/route.ts +131 -12
- package/src/types/template.ts +70 -2
- 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.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.map +0 -1
- package/dist/cjs/src/core/Step.js.map +0 -1
- package/dist/cjs/src/core/ToolManager.d.ts.map +0 -1
- package/dist/cjs/src/core/ToolManager.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.map +0 -1
- 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.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.js.map +0 -1
- package/dist/src/core/Step.d.ts.map +0 -1
- package/dist/src/core/Step.js.map +0 -1
- package/dist/src/core/ToolManager.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.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/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/core → core}/SessionManager.d.ts +0 -0
- /package/dist/{src → cjs}/core/SessionManager.d.ts.map +0 -0
- /package/dist/cjs/{src/core → core}/SessionManager.js +0 -0
- /package/dist/cjs/{src/core → core}/ToolManager.d.ts +0 -0
- /package/dist/{src → cjs}/core/ToolManager.d.ts.map +0 -0
- /package/dist/cjs/{src/core → core}/ToolManager.js +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/types → types}/tool.d.ts +0 -0
- /package/dist/{src → cjs}/types/tool.d.ts.map +0 -0
- /package/dist/cjs/{src/types → types}/tool.js +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/core → core}/SessionManager.d.ts +0 -0
- /package/dist/{src/core → core}/SessionManager.js +0 -0
- /package/dist/{src/core → core}/ToolManager.d.ts +0 -0
- /package/dist/{src/core → core}/ToolManager.js +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/types → types}/tool.d.ts +0 -0
- /package/dist/{src/types → types}/tool.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,7 +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");
|
|
15
|
+
const template_1 = require("../utils/template");
|
|
13
16
|
const constants_1 = require("../constants");
|
|
14
17
|
/**
|
|
15
18
|
* Error class for response generation failures
|
|
@@ -52,6 +55,10 @@ class ResponseModal {
|
|
|
52
55
|
// Initialize response pipeline with agent dependencies
|
|
53
56
|
this.responsePipeline = new ResponsePipeline_1.ResponsePipeline(this.agent.getAgentOptions(), () => this.agent.getRoutes(), // Pass a function to get routes dynamically
|
|
54
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
|
|
@@ -272,6 +279,7 @@ class ResponseModal {
|
|
|
272
279
|
throw ResponseGenerationError.fromError(error, 'step_preparation', params, { session, effectiveContext });
|
|
273
280
|
}
|
|
274
281
|
// PHASE 2: ROUTING + STEP SELECTION - Determine which route and step to use
|
|
282
|
+
// Also performs pre-extraction and batch determination
|
|
275
283
|
let routingResult;
|
|
276
284
|
try {
|
|
277
285
|
routingResult = await this.handleUnifiedRoutingAndStepSelection({
|
|
@@ -292,6 +300,9 @@ class ResponseModal {
|
|
|
292
300
|
selectedStep: routingResult.selectedStep,
|
|
293
301
|
responseDirectives: routingResult.responseDirectives,
|
|
294
302
|
isRouteComplete: routingResult.isRouteComplete,
|
|
303
|
+
batchSteps: routingResult.batchSteps,
|
|
304
|
+
batchStoppedReason: routingResult.batchStoppedReason,
|
|
305
|
+
batchStoppedAtStep: routingResult.batchStoppedAtStep,
|
|
295
306
|
};
|
|
296
307
|
}
|
|
297
308
|
catch (error) {
|
|
@@ -317,31 +328,156 @@ class ResponseModal {
|
|
|
317
328
|
context: params.context,
|
|
318
329
|
signal: params.signal,
|
|
319
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
|
+
}
|
|
320
384
|
// Determine next step using pipeline method for consistency
|
|
321
|
-
const stepResult = this.responsePipeline.determineNextStep({
|
|
385
|
+
const stepResult = await this.responsePipeline.determineNextStep({
|
|
322
386
|
selectedRoute: routingResult.selectedRoute,
|
|
323
387
|
selectedStep: routingResult.selectedStep,
|
|
324
|
-
session:
|
|
325
|
-
isRouteComplete
|
|
388
|
+
session: updatedSession, // Use updated session with pre-extracted data
|
|
389
|
+
isRouteComplete, // Use updated completion status
|
|
326
390
|
});
|
|
327
391
|
return {
|
|
328
392
|
selectedRoute: routingResult.selectedRoute,
|
|
329
393
|
selectedStep: stepResult.nextStep, // Use the determined next step
|
|
330
394
|
responseDirectives: routingResult.responseDirectives,
|
|
331
395
|
session: stepResult.session,
|
|
332
|
-
isRouteComplete
|
|
396
|
+
isRouteComplete, // Use updated completion status
|
|
397
|
+
batchSteps,
|
|
398
|
+
batchStoppedReason,
|
|
399
|
+
batchStoppedAtStep,
|
|
333
400
|
};
|
|
334
401
|
}
|
|
335
402
|
catch (error) {
|
|
336
403
|
throw ResponseGenerationError.fromError(error, 'routing_optimization', params);
|
|
337
404
|
}
|
|
338
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
|
+
}
|
|
339
475
|
/**
|
|
340
476
|
* Unified response generation for non-streaming responses
|
|
341
477
|
* @private
|
|
342
478
|
*/
|
|
343
479
|
async generateUnifiedResponse(responseContext) {
|
|
344
|
-
const { effectiveContext, session: initialSession, history, selectedRoute, selectedStep, responseDirectives, isRouteComplete } = responseContext;
|
|
480
|
+
const { effectiveContext, session: initialSession, history, selectedRoute, selectedStep, responseDirectives, isRouteComplete, batchSteps, batchStoppedReason, } = responseContext;
|
|
345
481
|
let session = initialSession;
|
|
346
482
|
// Get last user message (needed for both route and completion handling)
|
|
347
483
|
// Convert HistoryItem[] to Event[] for internal processing
|
|
@@ -349,35 +485,79 @@ class ResponseModal {
|
|
|
349
485
|
const lastMessageText = (0, utils_1.getLastMessageFromHistory)(historyEvents);
|
|
350
486
|
let message;
|
|
351
487
|
let toolCalls = undefined;
|
|
488
|
+
let executedSteps;
|
|
489
|
+
let stoppedReason;
|
|
352
490
|
if (selectedRoute && !isRouteComplete) {
|
|
353
|
-
//
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
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
|
+
}
|
|
368
536
|
}
|
|
369
537
|
else if (isRouteComplete && selectedRoute) {
|
|
370
538
|
// Handle route completion
|
|
371
|
-
message
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
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
|
+
}
|
|
381
561
|
}
|
|
382
562
|
else {
|
|
383
563
|
// Fallback: No routes defined, generate a simple response
|
|
@@ -386,37 +566,275 @@ class ResponseModal {
|
|
|
386
566
|
context: effectiveContext,
|
|
387
567
|
session,
|
|
388
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;
|
|
389
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
|
|
390
578
|
return {
|
|
391
579
|
message,
|
|
392
580
|
session,
|
|
393
581
|
toolCalls,
|
|
394
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
|
+
const agentSchema = this.agent.getSchema();
|
|
741
|
+
// Add collect fields to schema, using agent schema definitions when available
|
|
742
|
+
for (const field of collectFields) {
|
|
743
|
+
if (agentSchema?.properties && agentSchema.properties[field]) {
|
|
744
|
+
properties[field] = agentSchema.properties[field];
|
|
745
|
+
}
|
|
746
|
+
else {
|
|
747
|
+
// Dynamic fallback when no agent schema is defined
|
|
748
|
+
properties[field] = {
|
|
749
|
+
type: "string",
|
|
750
|
+
description: `Collected value for ${field}`,
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
return {
|
|
755
|
+
type: "object",
|
|
756
|
+
properties,
|
|
757
|
+
required: ["message"],
|
|
758
|
+
additionalProperties: true,
|
|
395
759
|
};
|
|
396
760
|
}
|
|
761
|
+
/**
|
|
762
|
+
* Collect available tools from all steps in the batch
|
|
763
|
+
* @private
|
|
764
|
+
*/
|
|
765
|
+
collectBatchAvailableTools(route, batchSteps) {
|
|
766
|
+
const availableTools = new Map();
|
|
767
|
+
// Add agent-level tools
|
|
768
|
+
this.agent.getTools().forEach((tool) => {
|
|
769
|
+
availableTools.set(tool.id, tool);
|
|
770
|
+
});
|
|
771
|
+
// Add route-level tools
|
|
772
|
+
route.getTools().forEach((tool) => {
|
|
773
|
+
availableTools.set(tool.id, tool);
|
|
774
|
+
});
|
|
775
|
+
// Add step-level tools from all batch steps
|
|
776
|
+
for (const step of batchSteps) {
|
|
777
|
+
if (step.tools) {
|
|
778
|
+
for (const toolRef of step.tools) {
|
|
779
|
+
if (typeof toolRef === "string") {
|
|
780
|
+
// Reference to registered tool - already in availableTools
|
|
781
|
+
}
|
|
782
|
+
else if (typeof toolRef === 'object' && 'id' in toolRef && toolRef.id) {
|
|
783
|
+
// Inline tool definition
|
|
784
|
+
availableTools.set(toolRef.id, toolRef);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
// Convert to the format expected by AI providers
|
|
790
|
+
return Array.from(availableTools.values()).map((tool) => ({
|
|
791
|
+
id: tool.id,
|
|
792
|
+
name: tool.name || tool.id,
|
|
793
|
+
description: tool.description,
|
|
794
|
+
parameters: tool.parameters,
|
|
795
|
+
}));
|
|
796
|
+
}
|
|
397
797
|
/**
|
|
398
798
|
* Unified streaming response generation
|
|
399
799
|
* @private
|
|
400
800
|
*/
|
|
401
801
|
async *generateUnifiedStreamingResponse(responseContext) {
|
|
402
|
-
const { effectiveContext, session: initialSession, history, selectedRoute, selectedStep, responseDirectives, isRouteComplete } = responseContext;
|
|
802
|
+
const { effectiveContext, session: initialSession, history, selectedRoute, selectedStep, responseDirectives, isRouteComplete, batchSteps, batchStoppedReason, } = responseContext;
|
|
403
803
|
const session = initialSession;
|
|
404
804
|
// Get last user message (needed for both route and completion handling)
|
|
405
805
|
// Convert HistoryItem[] to Event[] for internal processing
|
|
406
806
|
const historyEvents = (0, utils_1.historyToEvents)(history);
|
|
407
807
|
const lastMessageText = (0, utils_1.getLastMessageFromHistory)(historyEvents);
|
|
408
808
|
if (selectedRoute && !isRouteComplete) {
|
|
409
|
-
//
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
809
|
+
// Check if we have batch steps to execute
|
|
810
|
+
if (batchSteps && batchSteps.length > 0) {
|
|
811
|
+
// BATCH EXECUTION: Execute multiple steps with streaming
|
|
812
|
+
// Note: For streaming, we still use batch execution but stream the response
|
|
813
|
+
utils_1.logger.debug(`[ResponseModal] Streaming batch execution for ${batchSteps.length} steps`);
|
|
814
|
+
yield* this.streamBatchResponse({
|
|
815
|
+
selectedRoute,
|
|
816
|
+
batchSteps,
|
|
817
|
+
responseDirectives,
|
|
818
|
+
session,
|
|
819
|
+
history,
|
|
820
|
+
context: effectiveContext,
|
|
821
|
+
historyEvents,
|
|
822
|
+
batchStoppedReason,
|
|
823
|
+
});
|
|
824
|
+
}
|
|
825
|
+
else {
|
|
826
|
+
// SINGLE STEP EXECUTION: Fall back to single-step streaming
|
|
827
|
+
yield* this.processRouteStreamingResponse({
|
|
828
|
+
selectedRoute,
|
|
829
|
+
selectedStep,
|
|
830
|
+
responseDirectives,
|
|
831
|
+
session,
|
|
832
|
+
history,
|
|
833
|
+
context: effectiveContext,
|
|
834
|
+
lastMessageText,
|
|
835
|
+
historyEvents,
|
|
836
|
+
});
|
|
837
|
+
}
|
|
420
838
|
}
|
|
421
839
|
else if (isRouteComplete && selectedRoute) {
|
|
422
840
|
// Handle route completion streaming
|
|
@@ -437,6 +855,114 @@ class ResponseModal {
|
|
|
437
855
|
});
|
|
438
856
|
}
|
|
439
857
|
}
|
|
858
|
+
/**
|
|
859
|
+
* Stream a batch response with multiple steps
|
|
860
|
+
*
|
|
861
|
+
* Similar to executeBatchResponse but streams the LLM response.
|
|
862
|
+
*
|
|
863
|
+
* @private
|
|
864
|
+
*/
|
|
865
|
+
async *streamBatchResponse(params) {
|
|
866
|
+
const { selectedRoute, batchSteps, context, historyEvents, batchStoppedReason, signal } = params;
|
|
867
|
+
let session = params.session;
|
|
868
|
+
// Create hook executor function
|
|
869
|
+
const executeHook = async (hook, hookContext, data, step) => {
|
|
870
|
+
const route = selectedRoute;
|
|
871
|
+
const stepInstance = step?.id ? route.getStep(step.id) : undefined;
|
|
872
|
+
await this.executePrepareFinalize(hook, hookContext, data, route, stepInstance);
|
|
873
|
+
};
|
|
874
|
+
// PHASE 1: Execute all prepare hooks
|
|
875
|
+
const prepareResult = await this.batchExecutor.executePrepareHooks({
|
|
876
|
+
steps: batchSteps,
|
|
877
|
+
context,
|
|
878
|
+
data: session.data,
|
|
879
|
+
executeHook,
|
|
880
|
+
});
|
|
881
|
+
if (!prepareResult.success) {
|
|
882
|
+
// Yield error chunk
|
|
883
|
+
yield {
|
|
884
|
+
delta: "",
|
|
885
|
+
accumulated: "",
|
|
886
|
+
done: true,
|
|
887
|
+
session,
|
|
888
|
+
error: new ResponseGenerationError(`Prepare hook failed: ${prepareResult.error?.message}`, { phase: 'prepare_hooks' }),
|
|
889
|
+
};
|
|
890
|
+
return;
|
|
891
|
+
}
|
|
892
|
+
// PHASE 2: Build combined prompt
|
|
893
|
+
const batchPromptResult = await this.batchPromptBuilder.buildBatchPrompt({
|
|
894
|
+
steps: batchSteps,
|
|
895
|
+
route: selectedRoute,
|
|
896
|
+
history: historyEvents,
|
|
897
|
+
context,
|
|
898
|
+
session,
|
|
899
|
+
agentOptions: this.agent.getAgentOptions(),
|
|
900
|
+
});
|
|
901
|
+
const responseSchema = this.buildBatchResponseSchema(batchPromptResult.collectFields);
|
|
902
|
+
const availableTools = this.collectBatchAvailableTools(selectedRoute, batchSteps);
|
|
903
|
+
// PHASE 3: Stream LLM response
|
|
904
|
+
const agentOptions = this.agent.getAgentOptions();
|
|
905
|
+
const stream = agentOptions.provider.generateMessageStream({
|
|
906
|
+
prompt: batchPromptResult.prompt,
|
|
907
|
+
history: historyEvents,
|
|
908
|
+
context,
|
|
909
|
+
tools: availableTools,
|
|
910
|
+
signal,
|
|
911
|
+
parameters: responseSchema ? { jsonSchema: responseSchema, schemaName: "batch_stream_response" } : undefined,
|
|
912
|
+
});
|
|
913
|
+
// Build executed steps list
|
|
914
|
+
const executedSteps = batchSteps
|
|
915
|
+
.filter(step => step.id)
|
|
916
|
+
.map(step => ({
|
|
917
|
+
id: step.id,
|
|
918
|
+
routeId: selectedRoute.id,
|
|
919
|
+
}));
|
|
920
|
+
// Stream chunks
|
|
921
|
+
for await (const chunk of stream) {
|
|
922
|
+
// On final chunk, collect data and execute finalize hooks
|
|
923
|
+
if (chunk.done) {
|
|
924
|
+
// Collect data from response
|
|
925
|
+
if (chunk.structured) {
|
|
926
|
+
const collectResult = this.batchExecutor.collectBatchData({
|
|
927
|
+
steps: batchSteps,
|
|
928
|
+
llmResponse: chunk.structured,
|
|
929
|
+
session,
|
|
930
|
+
schema: this.agent.getSchema(),
|
|
931
|
+
});
|
|
932
|
+
session = collectResult.session;
|
|
933
|
+
if (collectResult.collectedData && Object.keys(collectResult.collectedData).length > 0) {
|
|
934
|
+
await this.agent.updateCollectedData(collectResult.collectedData);
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
// Update session to final step position
|
|
938
|
+
const lastStep = batchSteps[batchSteps.length - 1];
|
|
939
|
+
if (lastStep?.id) {
|
|
940
|
+
session = (0, utils_1.enterStep)(session, lastStep.id, lastStep.description);
|
|
941
|
+
}
|
|
942
|
+
// Execute finalize hooks
|
|
943
|
+
await this.batchExecutor.executeFinalizeHooks({
|
|
944
|
+
steps: batchSteps,
|
|
945
|
+
context,
|
|
946
|
+
data: session.data,
|
|
947
|
+
executeHook,
|
|
948
|
+
});
|
|
949
|
+
// Finalize session
|
|
950
|
+
await this.finalizeSession(session, context);
|
|
951
|
+
}
|
|
952
|
+
yield {
|
|
953
|
+
delta: chunk.delta,
|
|
954
|
+
accumulated: chunk.accumulated,
|
|
955
|
+
done: chunk.done,
|
|
956
|
+
session,
|
|
957
|
+
toolCalls: chunk.structured?.toolCalls,
|
|
958
|
+
isRouteComplete: false,
|
|
959
|
+
executedSteps: chunk.done ? executedSteps : undefined,
|
|
960
|
+
stoppedReason: chunk.done ? batchStoppedReason : undefined,
|
|
961
|
+
metadata: chunk.metadata,
|
|
962
|
+
structured: chunk.structured,
|
|
963
|
+
};
|
|
964
|
+
}
|
|
965
|
+
}
|
|
440
966
|
/**
|
|
441
967
|
* Execute prepare function for current step if available
|
|
442
968
|
* @private
|
|
@@ -482,12 +1008,20 @@ class ResponseModal {
|
|
|
482
1008
|
nextStep = selectedStep;
|
|
483
1009
|
}
|
|
484
1010
|
else {
|
|
485
|
-
//
|
|
1011
|
+
// Determine current step from session if we're already in this route
|
|
1012
|
+
const isInSameRoute = session.currentRoute?.id === selectedRoute.id;
|
|
1013
|
+
const currentStep = isInSameRoute && session.currentStep
|
|
1014
|
+
? selectedRoute.getStep(session.currentStep.id)
|
|
1015
|
+
: undefined;
|
|
1016
|
+
utils_1.logger.debug(`[ResponseModal] Step determination: route match=${isInSameRoute}, currentRoute=${session.currentRoute?.id}, selectedRoute=${selectedRoute.id}, currentStep=${currentStep?.id || 'none'}`);
|
|
1017
|
+
// Get candidate steps based on current position in the route
|
|
486
1018
|
const routingEngine = this.agent.getRoutingEngine();
|
|
487
|
-
const candidates = routingEngine.
|
|
1019
|
+
const candidates = await routingEngine.getCandidateStepsWithConditions(selectedRoute, currentStep, // Pass current step instead of undefined to maintain progression
|
|
1020
|
+
(0, template_1.createTemplateContext)({ data: session.data, session, context }));
|
|
1021
|
+
utils_1.logger.debug(`[ResponseModal] Found ${candidates.length} candidate steps${currentStep ? ' from current step ' + currentStep.id : ' (new route entry)'}`);
|
|
488
1022
|
if (candidates.length > 0) {
|
|
489
1023
|
nextStep = candidates[0].step;
|
|
490
|
-
utils_1.logger.debug(`[ResponseModal] Using first valid step: ${nextStep.id} for new route`);
|
|
1024
|
+
utils_1.logger.debug(`[ResponseModal] Using first valid step: ${nextStep.id}${currentStep ? ' (progressing from ' + currentStep.id + ')' : ' for new route'}`);
|
|
491
1025
|
}
|
|
492
1026
|
else {
|
|
493
1027
|
// Fallback to initial step even if it should be skipped
|
|
@@ -496,16 +1030,42 @@ class ResponseModal {
|
|
|
496
1030
|
}
|
|
497
1031
|
}
|
|
498
1032
|
// Update session with next step
|
|
499
|
-
|
|
500
|
-
|
|
1033
|
+
// If the next step has requires fields that are missing, stay at the previous step
|
|
1034
|
+
if (nextStep.requires && nextStep.requires.length > 0) {
|
|
1035
|
+
const sessionData = session.data || {};
|
|
1036
|
+
const missingRequires = nextStep.requires.filter(field => sessionData[String(field)] === undefined);
|
|
1037
|
+
if (missingRequires.length > 0) {
|
|
1038
|
+
const warning = `[Agent] Cannot advance to step "${nextStep.description || nextStep.id}": ` +
|
|
1039
|
+
`missing required fields [${missingRequires.join(', ')}]. Staying at current step.`;
|
|
1040
|
+
utils_1.logger.warn(warning);
|
|
1041
|
+
console.warn(warning);
|
|
1042
|
+
// Stay at the current step - don't enter the next one
|
|
1043
|
+
const currentStepId = session.currentStep?.id;
|
|
1044
|
+
if (currentStepId) {
|
|
1045
|
+
const currentStepInstance = selectedRoute.getStep(currentStepId);
|
|
1046
|
+
if (currentStepInstance) {
|
|
1047
|
+
nextStep = currentStepInstance;
|
|
1048
|
+
utils_1.logger.debug(`[ResponseModal] Staying at current step: ${nextStep.id} due to missing requires`);
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
else {
|
|
1053
|
+
session = (0, utils_1.enterStep)(session, nextStep.id, nextStep.description);
|
|
1054
|
+
utils_1.logger.debug(`[ResponseModal] Entered step: ${nextStep.id}`);
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
else {
|
|
1058
|
+
session = (0, utils_1.enterStep)(session, nextStep.id, nextStep.description);
|
|
1059
|
+
utils_1.logger.debug(`[ResponseModal] Entered step: ${nextStep.id}`);
|
|
1060
|
+
}
|
|
501
1061
|
// Build response schema for this route (with collect fields from step)
|
|
502
1062
|
const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute, nextStep, this.agent.getSchema());
|
|
503
1063
|
// Build response prompt
|
|
504
1064
|
const responsePrompt = await this.responseEngine.buildResponsePrompt({
|
|
505
1065
|
route: selectedRoute,
|
|
506
1066
|
currentStep: nextStep,
|
|
507
|
-
rules: selectedRoute.getRules(),
|
|
508
|
-
prohibitions: selectedRoute.getProhibitions(),
|
|
1067
|
+
rules: [...this.agent.getRules(), ...selectedRoute.getRules()],
|
|
1068
|
+
prohibitions: [...this.agent.getProhibitions(), ...selectedRoute.getProhibitions()],
|
|
509
1069
|
directives: responseDirectives,
|
|
510
1070
|
history: historyEvents, // Use Event[] for buildResponsePrompt
|
|
511
1071
|
lastMessage: lastMessageText, // Use string for buildResponsePrompt
|
|
@@ -530,6 +1090,14 @@ class ResponseModal {
|
|
|
530
1090
|
});
|
|
531
1091
|
let message = result.structured?.message || result.message;
|
|
532
1092
|
let toolCalls = result.structured?.toolCalls;
|
|
1093
|
+
// Debug: Log initial AI response
|
|
1094
|
+
utils_1.logger.debug(`[ResponseModal] Initial AI response:`, {
|
|
1095
|
+
hasMessage: !!message,
|
|
1096
|
+
messageLength: message?.length || 0,
|
|
1097
|
+
hasToolCalls: !!toolCalls,
|
|
1098
|
+
toolCallsCount: toolCalls?.length || 0,
|
|
1099
|
+
toolNames: toolCalls?.map(tc => tc.toolName) || [],
|
|
1100
|
+
});
|
|
533
1101
|
// Execute tools with unified loop handling
|
|
534
1102
|
const toolResult = await this.executeUnifiedToolLoop({
|
|
535
1103
|
toolCalls,
|
|
@@ -564,11 +1132,17 @@ class ResponseModal {
|
|
|
564
1132
|
nextStep = selectedStep;
|
|
565
1133
|
}
|
|
566
1134
|
else {
|
|
1135
|
+
// Determine current step from session if we're already in this route
|
|
1136
|
+
const currentStep = session.currentRoute?.id === selectedRoute.id && session.currentStep
|
|
1137
|
+
? selectedRoute.getStep(session.currentStep.id)
|
|
1138
|
+
: undefined;
|
|
1139
|
+
// Get candidate steps based on current position in the route
|
|
567
1140
|
const routingEngine = this.agent.getRoutingEngine();
|
|
568
|
-
const candidates = routingEngine.
|
|
1141
|
+
const candidates = await routingEngine.getCandidateStepsWithConditions(selectedRoute, currentStep, // Pass current step instead of undefined to maintain progression
|
|
1142
|
+
(0, template_1.createTemplateContext)({ data: session.data, session, context }));
|
|
569
1143
|
if (candidates.length > 0) {
|
|
570
1144
|
nextStep = candidates[0].step;
|
|
571
|
-
utils_1.logger.debug(`[ResponseModal] Using first valid step: ${nextStep.id} for new route`);
|
|
1145
|
+
utils_1.logger.debug(`[ResponseModal] Using first valid step: ${nextStep.id}${currentStep ? ' (progressing from ' + currentStep.id + ')' : ' for new route'}`);
|
|
572
1146
|
}
|
|
573
1147
|
else {
|
|
574
1148
|
nextStep = selectedRoute.initialStep;
|
|
@@ -576,15 +1150,40 @@ class ResponseModal {
|
|
|
576
1150
|
}
|
|
577
1151
|
}
|
|
578
1152
|
// Update session with next step
|
|
579
|
-
|
|
580
|
-
|
|
1153
|
+
// If the next step has requires fields that are missing, stay at the previous step
|
|
1154
|
+
if (nextStep.requires && nextStep.requires.length > 0) {
|
|
1155
|
+
const sessionData = session.data || {};
|
|
1156
|
+
const missingRequires = nextStep.requires.filter(field => sessionData[String(field)] === undefined);
|
|
1157
|
+
if (missingRequires.length > 0) {
|
|
1158
|
+
const warning = `[Agent] Cannot advance to step "${nextStep.description || nextStep.id}": ` +
|
|
1159
|
+
`missing required fields [${missingRequires.join(', ')}]. Staying at current step.`;
|
|
1160
|
+
utils_1.logger.warn(warning);
|
|
1161
|
+
console.warn(warning);
|
|
1162
|
+
const currentStepId = session.currentStep?.id;
|
|
1163
|
+
if (currentStepId) {
|
|
1164
|
+
const currentStepInstance = selectedRoute.getStep(currentStepId);
|
|
1165
|
+
if (currentStepInstance) {
|
|
1166
|
+
nextStep = currentStepInstance;
|
|
1167
|
+
utils_1.logger.debug(`[ResponseModal] Staying at current step: ${nextStep.id} due to missing requires`);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
else {
|
|
1172
|
+
session = (0, utils_1.enterStep)(session, nextStep.id, nextStep.description);
|
|
1173
|
+
utils_1.logger.debug(`[ResponseModal] Entered step: ${nextStep.id}`);
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
else {
|
|
1177
|
+
session = (0, utils_1.enterStep)(session, nextStep.id, nextStep.description);
|
|
1178
|
+
utils_1.logger.debug(`[ResponseModal] Entered step: ${nextStep.id}`);
|
|
1179
|
+
}
|
|
581
1180
|
// Build response schema and prompt (same as non-streaming)
|
|
582
1181
|
const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute, nextStep, this.agent.getSchema());
|
|
583
1182
|
const responsePrompt = await this.responseEngine.buildResponsePrompt({
|
|
584
1183
|
route: selectedRoute,
|
|
585
1184
|
currentStep: nextStep,
|
|
586
|
-
rules: selectedRoute.getRules(),
|
|
587
|
-
prohibitions: selectedRoute.getProhibitions(),
|
|
1185
|
+
rules: [...this.agent.getRules(), ...selectedRoute.getRules()],
|
|
1186
|
+
prohibitions: [...this.agent.getProhibitions(), ...selectedRoute.getProhibitions()],
|
|
588
1187
|
directives: responseDirectives,
|
|
589
1188
|
history: historyEvents, // Use Event[] for buildResponsePrompt
|
|
590
1189
|
lastMessage: lastMessageText, // Use string for buildResponsePrompt
|
|
@@ -641,6 +1240,10 @@ class ResponseModal {
|
|
|
641
1240
|
if (chunk.done) {
|
|
642
1241
|
await this.finalizeSession(session, context);
|
|
643
1242
|
}
|
|
1243
|
+
// Response structure completeness (Requirement 8.1, 8.2, 8.3)
|
|
1244
|
+
// - executedSteps: single step executed in this response
|
|
1245
|
+
// - stoppedReason: 'needs_input' for single-step execution (waiting for user input)
|
|
1246
|
+
// - session.currentStep: reflects the executed step
|
|
644
1247
|
yield {
|
|
645
1248
|
delta: chunk.delta,
|
|
646
1249
|
accumulated: chunk.accumulated,
|
|
@@ -648,6 +1251,8 @@ class ResponseModal {
|
|
|
648
1251
|
session,
|
|
649
1252
|
toolCalls,
|
|
650
1253
|
isRouteComplete: false,
|
|
1254
|
+
executedSteps: chunk.done ? [{ id: nextStep.id, routeId: selectedRoute.id }] : undefined,
|
|
1255
|
+
stoppedReason: chunk.done ? 'needs_input' : undefined,
|
|
651
1256
|
metadata: chunk.metadata,
|
|
652
1257
|
structured: chunk.structured,
|
|
653
1258
|
};
|
|
@@ -666,7 +1271,7 @@ class ResponseModal {
|
|
|
666
1271
|
const historyEvents = (0, utils_1.historyToEvents)(history);
|
|
667
1272
|
// Execute initial dynamic tool calls
|
|
668
1273
|
if (toolCalls && toolCalls.length > 0) {
|
|
669
|
-
utils_1.logger.debug(`[ResponseModal] Executing ${toolCalls.length} dynamic tool calls
|
|
1274
|
+
utils_1.logger.debug(`[ResponseModal] Executing ${toolCalls.length} dynamic tool calls:`, toolCalls.map(tc => tc.toolName));
|
|
670
1275
|
for (const toolCall of toolCalls) {
|
|
671
1276
|
const tool = this.findAvailableTool(toolCall.toolName, selectedRoute);
|
|
672
1277
|
if (!tool) {
|
|
@@ -736,7 +1341,7 @@ class ResponseModal {
|
|
|
736
1341
|
let finalMessage;
|
|
737
1342
|
while (hasToolCalls && toolLoopCount < MAX_TOOL_LOOPS) {
|
|
738
1343
|
toolLoopCount++;
|
|
739
|
-
utils_1.logger.debug(`[ResponseModal] Starting tool loop ${toolLoopCount}/${MAX_TOOL_LOOPS}`);
|
|
1344
|
+
utils_1.logger.debug(`[ResponseModal] Starting tool loop ${toolLoopCount}/${MAX_TOOL_LOOPS} with ${toolCalls?.length || 0} tool calls`);
|
|
740
1345
|
// Create tool result events with proper Event format structure
|
|
741
1346
|
const toolResultEvents = [];
|
|
742
1347
|
for (const toolCall of toolCalls || []) {
|
|
@@ -765,12 +1370,19 @@ class ResponseModal {
|
|
|
765
1370
|
// Create updated history with tool results (combine Event arrays)
|
|
766
1371
|
const updatedHistoryEvents = [...historyEvents, ...toolResultEvents];
|
|
767
1372
|
// Make follow-up AI call to see if more tools are needed
|
|
1373
|
+
// After first iteration, don't provide tools to force a text response
|
|
768
1374
|
const agentOptions = this.agent.getAgentOptions();
|
|
1375
|
+
const shouldProvideTools = toolLoopCount === 1;
|
|
1376
|
+
utils_1.logger.debug(`[ResponseModal] Making follow-up AI call (loop ${toolLoopCount}):`, {
|
|
1377
|
+
providingTools: shouldProvideTools,
|
|
1378
|
+
toolsCount: shouldProvideTools ? availableTools.length : 0,
|
|
1379
|
+
addingTextInstruction: toolLoopCount > 1,
|
|
1380
|
+
});
|
|
769
1381
|
const followUpResult = await agentOptions.provider.generateMessage({
|
|
770
|
-
prompt: responsePrompt,
|
|
1382
|
+
prompt: responsePrompt + (toolLoopCount > 1 ? "\n\nProvide a text response to the user based on the tool results." : ""),
|
|
771
1383
|
history: updatedHistoryEvents, // Use Event[] for AI provider
|
|
772
1384
|
context,
|
|
773
|
-
tools: availableTools,
|
|
1385
|
+
tools: shouldProvideTools ? availableTools : [], // Only provide tools on first iteration
|
|
774
1386
|
parameters: responseSchema ? {
|
|
775
1387
|
jsonSchema: responseSchema,
|
|
776
1388
|
schemaName: "tool_followup",
|
|
@@ -780,6 +1392,13 @@ class ResponseModal {
|
|
|
780
1392
|
// Check if follow-up call has more tool calls
|
|
781
1393
|
const followUpToolCalls = followUpResult.structured?.toolCalls;
|
|
782
1394
|
hasToolCalls = followUpToolCalls && followUpToolCalls.length > 0;
|
|
1395
|
+
utils_1.logger.debug(`[ResponseModal] Follow-up AI response (loop ${toolLoopCount}):`, {
|
|
1396
|
+
hasMessage: !!followUpResult.message,
|
|
1397
|
+
messageLength: followUpResult.message?.length || 0,
|
|
1398
|
+
hasToolCalls,
|
|
1399
|
+
toolCallsCount: followUpToolCalls?.length || 0,
|
|
1400
|
+
toolNames: followUpToolCalls?.map(tc => tc.toolName) || [],
|
|
1401
|
+
});
|
|
783
1402
|
if (hasToolCalls) {
|
|
784
1403
|
utils_1.logger.debug(`[ResponseModal] Follow-up call produced ${followUpToolCalls.length} additional tool calls`);
|
|
785
1404
|
// Execute the follow-up tool calls
|
|
@@ -853,6 +1472,12 @@ class ResponseModal {
|
|
|
853
1472
|
if (toolLoopCount >= MAX_TOOL_LOOPS) {
|
|
854
1473
|
utils_1.logger.warn(`[ResponseModal] Tool loop limit reached (${MAX_TOOL_LOOPS}), stopping`);
|
|
855
1474
|
}
|
|
1475
|
+
utils_1.logger.debug(`[ResponseModal] Tool loop completed:`, {
|
|
1476
|
+
totalIterations: toolLoopCount,
|
|
1477
|
+
hasFinalMessage: !!finalMessage,
|
|
1478
|
+
finalMessageLength: finalMessage?.length || 0,
|
|
1479
|
+
finalToolCallsCount: toolCalls?.length || 0,
|
|
1480
|
+
});
|
|
856
1481
|
return {
|
|
857
1482
|
session,
|
|
858
1483
|
finalToolCalls: toolCalls,
|
|
@@ -874,14 +1499,29 @@ class ResponseModal {
|
|
|
874
1499
|
const { result, selectedRoute, nextStep, session } = params;
|
|
875
1500
|
let updatedSession = session;
|
|
876
1501
|
// Extract collected data from final response (only for route-based interactions)
|
|
877
|
-
if (selectedRoute && result.structured
|
|
1502
|
+
if (selectedRoute && result.structured) {
|
|
878
1503
|
try {
|
|
879
1504
|
const collectedData = {};
|
|
880
1505
|
// AgentStructuredResponse extends Record<string, unknown>, so we can safely access properties
|
|
881
1506
|
const structuredData = result.structured;
|
|
882
|
-
|
|
1507
|
+
// Collect ALL route fields (required + optional) from structured response
|
|
1508
|
+
const allRouteFields = new Set();
|
|
1509
|
+
// Add route required fields
|
|
1510
|
+
if (selectedRoute.requiredFields) {
|
|
1511
|
+
selectedRoute.requiredFields.forEach(field => allRouteFields.add(String(field)));
|
|
1512
|
+
}
|
|
1513
|
+
// Add route optional fields
|
|
1514
|
+
if (selectedRoute.optionalFields) {
|
|
1515
|
+
selectedRoute.optionalFields.forEach(field => allRouteFields.add(String(field)));
|
|
1516
|
+
}
|
|
1517
|
+
// Also include current step's collect fields (in case they're not in route fields)
|
|
1518
|
+
if (nextStep?.collect) {
|
|
1519
|
+
nextStep.collect.forEach(field => allRouteFields.add(String(field)));
|
|
1520
|
+
}
|
|
1521
|
+
// Extract all available fields from structured response
|
|
1522
|
+
for (const field of allRouteFields) {
|
|
883
1523
|
const fieldKey = String(field);
|
|
884
|
-
if (fieldKey in structuredData) {
|
|
1524
|
+
if (fieldKey in structuredData && structuredData[fieldKey] !== undefined && structuredData[fieldKey] !== null) {
|
|
885
1525
|
collectedData[fieldKey] = structuredData[fieldKey];
|
|
886
1526
|
}
|
|
887
1527
|
}
|
|
@@ -944,34 +1584,60 @@ class ResponseModal {
|
|
|
944
1584
|
requires: endStepSpec.requires,
|
|
945
1585
|
prompt: endStepSpec.prompt || "Summarize what was accomplished and confirm completion based on the conversation history and collected data",
|
|
946
1586
|
});
|
|
947
|
-
// Build response schema for completion
|
|
948
|
-
const
|
|
949
|
-
|
|
950
|
-
|
|
1587
|
+
// Build response schema for completion (message only, no data collection)
|
|
1588
|
+
const completionSchema = {
|
|
1589
|
+
type: "object",
|
|
1590
|
+
properties: {
|
|
1591
|
+
message: {
|
|
1592
|
+
type: "string",
|
|
1593
|
+
description: "Completion message confirming what was accomplished",
|
|
1594
|
+
},
|
|
1595
|
+
},
|
|
1596
|
+
required: ["message"],
|
|
1597
|
+
additionalProperties: false,
|
|
1598
|
+
};
|
|
1599
|
+
const templateContext = (0, template_1.createTemplateContext)({ context, session, history: historyEvents });
|
|
1600
|
+
// Build completion response prompt using ResponseEngine
|
|
1601
|
+
// Filter out conditional guidelines - only include always-active ones
|
|
1602
|
+
const alwaysActiveGuidelines = [
|
|
1603
|
+
...this.agent.getGuidelines().filter(g => !g.condition),
|
|
1604
|
+
...selectedRoute.getGuidelines().filter(g => !g.condition),
|
|
1605
|
+
];
|
|
1606
|
+
let completitionPrompt = "Summarize what was accomplished and confirm completion";
|
|
1607
|
+
if (endStepSpec.prompt) {
|
|
1608
|
+
completitionPrompt = await (0, utils_1.render)(endStepSpec.prompt, templateContext);
|
|
1609
|
+
}
|
|
951
1610
|
const completionPrompt = await this.responseEngine.buildResponsePrompt({
|
|
952
1611
|
route: selectedRoute,
|
|
953
1612
|
currentStep: completionStep,
|
|
954
1613
|
rules: selectedRoute.getRules(),
|
|
955
1614
|
prohibitions: selectedRoute.getProhibitions(),
|
|
956
|
-
directives:
|
|
957
|
-
|
|
958
|
-
|
|
1615
|
+
directives: [
|
|
1616
|
+
`Task completed: ${selectedRoute.title}`,
|
|
1617
|
+
`Collected data: ${JSON.stringify(session.data, null, 2)}`,
|
|
1618
|
+
"Do NOT ask for more information - the task is complete",
|
|
1619
|
+
completitionPrompt,
|
|
1620
|
+
],
|
|
1621
|
+
history: historyEvents,
|
|
1622
|
+
lastMessage: lastMessageText,
|
|
959
1623
|
agentOptions: this.agent.getAgentOptions(),
|
|
960
|
-
combinedGuidelines:
|
|
1624
|
+
combinedGuidelines: alwaysActiveGuidelines, // Only non-conditional guidelines
|
|
961
1625
|
combinedTerms: this.mergeTerms(this.agent.getTerms(), selectedRoute.getTerms()),
|
|
962
1626
|
context,
|
|
963
1627
|
session,
|
|
964
|
-
agentSchema:
|
|
1628
|
+
agentSchema: undefined, // No data collection schema for completion
|
|
965
1629
|
});
|
|
966
1630
|
// Generate completion message using AI provider
|
|
967
1631
|
const agentOptions = this.agent.getAgentOptions();
|
|
1632
|
+
utils_1.logger.debug(`[ResponseModal] Calling AI provider for completion message...`);
|
|
968
1633
|
const completionResult = await agentOptions.provider.generateMessage({
|
|
969
1634
|
prompt: completionPrompt,
|
|
970
|
-
history: historyEvents,
|
|
1635
|
+
history: historyEvents,
|
|
971
1636
|
context,
|
|
972
1637
|
signal,
|
|
973
|
-
parameters: { jsonSchema:
|
|
1638
|
+
parameters: { jsonSchema: completionSchema, schemaName: "completion_message" },
|
|
974
1639
|
});
|
|
1640
|
+
utils_1.logger.debug(`[ResponseModal] AI provider returned completion result`);
|
|
975
1641
|
const message = completionResult.structured?.message || completionResult.message;
|
|
976
1642
|
utils_1.logger.debug(`[ResponseModal] Generated completion message for route: ${selectedRoute.title}`);
|
|
977
1643
|
// Check for onComplete transition
|
|
@@ -1014,7 +1680,7 @@ class ResponseModal {
|
|
|
1014
1680
|
});
|
|
1015
1681
|
// Build response schema for completion
|
|
1016
1682
|
const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute, completionStep, this.agent.getSchema());
|
|
1017
|
-
const templateContext = { context, session, history: historyEvents }; // Use Event[] for template context
|
|
1683
|
+
const templateContext = (0, template_1.createTemplateContext)({ context, session, history: historyEvents }); // Use Event[] for template context
|
|
1018
1684
|
// Build completion response prompt
|
|
1019
1685
|
const completionPrompt = await this.responseEngine.buildResponsePrompt({
|
|
1020
1686
|
route: selectedRoute,
|
|
@@ -1072,6 +1738,10 @@ class ResponseModal {
|
|
|
1072
1738
|
if (chunk.done) {
|
|
1073
1739
|
await this.finalizeSession(session, context);
|
|
1074
1740
|
}
|
|
1741
|
+
// Response structure completeness (Requirement 8.1, 8.2, 8.3)
|
|
1742
|
+
// - executedSteps: empty for route completion (no new steps executed)
|
|
1743
|
+
// - stoppedReason: 'route_complete' for completed routes
|
|
1744
|
+
// - session.currentStep: set to END_ROUTE
|
|
1075
1745
|
yield {
|
|
1076
1746
|
delta: chunk.delta,
|
|
1077
1747
|
accumulated: chunk.accumulated,
|
|
@@ -1079,6 +1749,8 @@ class ResponseModal {
|
|
|
1079
1749
|
session,
|
|
1080
1750
|
toolCalls: undefined,
|
|
1081
1751
|
isRouteComplete: true,
|
|
1752
|
+
executedSteps: chunk.done ? [] : undefined,
|
|
1753
|
+
stoppedReason: chunk.done ? 'route_complete' : undefined,
|
|
1082
1754
|
metadata: chunk.metadata,
|
|
1083
1755
|
structured: chunk.structured,
|
|
1084
1756
|
};
|
|
@@ -1153,6 +1825,10 @@ class ResponseModal {
|
|
|
1153
1825
|
if (chunk.done) {
|
|
1154
1826
|
await this.finalizeSession(session, context);
|
|
1155
1827
|
}
|
|
1828
|
+
// Response structure completeness (Requirement 8.1, 8.2, 8.3)
|
|
1829
|
+
// - executedSteps: empty for fallback (no route/step execution)
|
|
1830
|
+
// - stoppedReason: undefined for fallback (no route context)
|
|
1831
|
+
// - session.currentStep: unchanged (no step progression)
|
|
1156
1832
|
yield {
|
|
1157
1833
|
delta: chunk.delta,
|
|
1158
1834
|
accumulated: chunk.accumulated,
|
|
@@ -1160,6 +1836,8 @@ class ResponseModal {
|
|
|
1160
1836
|
session,
|
|
1161
1837
|
toolCalls: undefined,
|
|
1162
1838
|
isRouteComplete: false,
|
|
1839
|
+
executedSteps: chunk.done ? [] : undefined,
|
|
1840
|
+
stoppedReason: undefined,
|
|
1163
1841
|
metadata: chunk.metadata,
|
|
1164
1842
|
structured: chunk.structured,
|
|
1165
1843
|
};
|