@falai/agent 0.8.0 → 0.9.0-alpha-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 +306 -133
- package/dist/{adapters → cjs/src/adapters}/MemoryAdapter.d.ts +4 -4
- package/dist/cjs/src/adapters/MemoryAdapter.d.ts.map +1 -0
- package/dist/cjs/{adapters → src/adapters}/MemoryAdapter.js +41 -21
- package/dist/cjs/src/adapters/MemoryAdapter.js.map +1 -0
- package/dist/{adapters → cjs/src/adapters}/MongoAdapter.d.ts +3 -3
- package/dist/cjs/src/adapters/MongoAdapter.d.ts.map +1 -0
- package/dist/cjs/{adapters → src/adapters}/MongoAdapter.js +2 -1
- package/dist/cjs/src/adapters/MongoAdapter.js.map +1 -0
- package/dist/cjs/{adapters → src/adapters}/OpenSearchAdapter.d.ts +3 -3
- package/dist/cjs/src/adapters/OpenSearchAdapter.d.ts.map +1 -0
- package/dist/cjs/{adapters → src/adapters}/OpenSearchAdapter.js +10 -13
- package/dist/cjs/src/adapters/OpenSearchAdapter.js.map +1 -0
- package/dist/cjs/{adapters → src/adapters}/PostgreSQLAdapter.d.ts +3 -3
- package/dist/cjs/src/adapters/PostgreSQLAdapter.d.ts.map +1 -0
- package/dist/cjs/{adapters → src/adapters}/PostgreSQLAdapter.js +1 -1
- package/dist/cjs/src/adapters/PostgreSQLAdapter.js.map +1 -0
- package/dist/cjs/{adapters → src/adapters}/PrismaAdapter.d.ts +3 -3
- package/dist/cjs/src/adapters/PrismaAdapter.d.ts.map +1 -0
- package/dist/cjs/{adapters → src/adapters}/PrismaAdapter.js +35 -5
- package/dist/cjs/src/adapters/PrismaAdapter.js.map +1 -0
- package/dist/cjs/{adapters → src/adapters}/RedisAdapter.d.ts +3 -3
- package/dist/cjs/src/adapters/RedisAdapter.d.ts.map +1 -0
- package/dist/cjs/{adapters → src/adapters}/RedisAdapter.js +3 -2
- package/dist/cjs/src/adapters/RedisAdapter.js.map +1 -0
- package/dist/{adapters → cjs/src/adapters}/SQLiteAdapter.d.ts +3 -3
- package/dist/cjs/src/adapters/SQLiteAdapter.d.ts.map +1 -0
- package/dist/cjs/{adapters → src/adapters}/SQLiteAdapter.js +2 -1
- package/dist/cjs/src/adapters/SQLiteAdapter.js.map +1 -0
- package/dist/cjs/src/adapters/index.d.ts.map +1 -0
- package/dist/cjs/src/adapters/index.js.map +1 -0
- package/dist/cjs/src/constants/index.d.ts.map +1 -0
- package/dist/cjs/src/constants/index.js.map +1 -0
- package/dist/{core → cjs/src/core}/Agent.d.ts +67 -69
- package/dist/cjs/src/core/Agent.d.ts.map +1 -0
- package/dist/cjs/src/core/Agent.js +1433 -0
- package/dist/cjs/src/core/Agent.js.map +1 -0
- package/dist/cjs/src/core/Events.d.ts +26 -0
- package/dist/cjs/src/core/Events.d.ts.map +1 -0
- package/dist/cjs/src/core/Events.js +144 -0
- package/dist/cjs/src/core/Events.js.map +1 -0
- package/dist/cjs/src/core/PersistenceManager.d.ts +98 -0
- package/dist/cjs/src/core/PersistenceManager.d.ts.map +1 -0
- package/dist/cjs/{core → src/core}/PersistenceManager.js +62 -32
- package/dist/cjs/src/core/PersistenceManager.js.map +1 -0
- package/dist/cjs/src/core/PromptComposer.d.ts +27 -0
- package/dist/cjs/src/core/PromptComposer.d.ts.map +1 -0
- package/dist/cjs/src/core/PromptComposer.js +157 -0
- package/dist/cjs/src/core/PromptComposer.js.map +1 -0
- package/dist/cjs/src/core/ResponseEngine.d.ts +31 -0
- package/dist/cjs/src/core/ResponseEngine.d.ts.map +1 -0
- package/dist/cjs/src/core/ResponseEngine.js +84 -0
- package/dist/cjs/src/core/ResponseEngine.js.map +1 -0
- package/dist/cjs/src/core/ResponsePipeline.d.ts +143 -0
- package/dist/cjs/src/core/ResponsePipeline.d.ts.map +1 -0
- package/dist/cjs/src/core/ResponsePipeline.js +446 -0
- package/dist/cjs/src/core/ResponsePipeline.js.map +1 -0
- package/dist/cjs/src/core/Route.d.ts +126 -0
- package/dist/cjs/src/core/Route.d.ts.map +1 -0
- package/dist/cjs/{core → src/core}/Route.js +116 -20
- package/dist/cjs/src/core/Route.js.map +1 -0
- package/dist/{core → cjs/src/core}/RoutingEngine.d.ts +33 -38
- package/dist/cjs/src/core/RoutingEngine.d.ts.map +1 -0
- package/dist/cjs/{core → src/core}/RoutingEngine.js +102 -108
- package/dist/cjs/src/core/RoutingEngine.js.map +1 -0
- package/dist/cjs/src/core/SessionManager.d.ts +76 -0
- package/dist/cjs/src/core/SessionManager.d.ts.map +1 -0
- package/dist/cjs/src/core/SessionManager.js +197 -0
- package/dist/cjs/src/core/SessionManager.js.map +1 -0
- package/dist/cjs/src/core/Step.d.ts +96 -0
- package/dist/cjs/src/core/Step.d.ts.map +1 -0
- package/dist/cjs/src/core/Step.js +206 -0
- package/dist/cjs/src/core/Step.js.map +1 -0
- package/dist/cjs/src/core/ToolExecutor.d.ts +43 -0
- package/dist/cjs/src/core/ToolExecutor.d.ts.map +1 -0
- package/dist/cjs/{core → src/core}/ToolExecutor.js +19 -18
- package/dist/cjs/src/core/ToolExecutor.js.map +1 -0
- package/dist/{index.d.ts → cjs/src/index.d.ts} +7 -15
- package/dist/cjs/src/index.d.ts.map +1 -0
- package/dist/cjs/{index.js → src/index.js} +21 -19
- package/dist/cjs/src/index.js.map +1 -0
- package/dist/cjs/{providers → src/providers}/AnthropicProvider.d.ts +1 -1
- package/dist/cjs/src/providers/AnthropicProvider.d.ts.map +1 -0
- package/dist/cjs/{providers → src/providers}/AnthropicProvider.js +54 -2
- package/dist/cjs/src/providers/AnthropicProvider.js.map +1 -0
- package/dist/{providers → cjs/src/providers}/GeminiProvider.d.ts +1 -1
- package/dist/cjs/src/providers/GeminiProvider.d.ts.map +1 -0
- package/dist/cjs/{providers → src/providers}/GeminiProvider.js +65 -0
- package/dist/cjs/src/providers/GeminiProvider.js.map +1 -0
- package/dist/cjs/{providers → src/providers}/OpenAIProvider.d.ts +1 -1
- package/dist/cjs/src/providers/OpenAIProvider.d.ts.map +1 -0
- package/dist/cjs/{providers → src/providers}/OpenAIProvider.js +70 -1
- package/dist/cjs/src/providers/OpenAIProvider.js.map +1 -0
- package/dist/{providers → cjs/src/providers}/OpenRouterProvider.d.ts +1 -1
- package/dist/cjs/src/providers/OpenRouterProvider.d.ts.map +1 -0
- package/dist/cjs/{providers → src/providers}/OpenRouterProvider.js +76 -0
- package/dist/cjs/src/providers/OpenRouterProvider.js.map +1 -0
- package/dist/cjs/src/providers/index.d.ts.map +1 -0
- package/dist/cjs/src/providers/index.js.map +1 -0
- package/dist/cjs/{types → src/types}/agent.d.ts +54 -35
- package/dist/cjs/src/types/agent.d.ts.map +1 -0
- package/dist/cjs/src/types/agent.js.map +1 -0
- package/dist/cjs/{types → src/types}/ai.d.ts +7 -0
- package/dist/cjs/src/types/ai.d.ts.map +1 -0
- package/dist/cjs/src/types/ai.js.map +1 -0
- package/dist/{types → cjs/src/types}/history.d.ts +76 -18
- package/dist/cjs/src/types/history.d.ts.map +1 -0
- package/dist/cjs/src/types/history.js +33 -0
- package/dist/cjs/src/types/history.js.map +1 -0
- package/dist/cjs/src/types/index.d.ts +20 -0
- package/dist/cjs/src/types/index.d.ts.map +1 -0
- package/dist/cjs/src/types/index.js +30 -0
- package/dist/cjs/src/types/index.js.map +1 -0
- package/dist/{types → cjs/src/types}/persistence.d.ts +39 -23
- package/dist/cjs/src/types/persistence.d.ts.map +1 -0
- package/dist/cjs/src/types/persistence.js.map +1 -0
- package/dist/cjs/{types → src/types}/route.d.ts +85 -31
- package/dist/cjs/src/types/route.d.ts.map +1 -0
- package/dist/cjs/{types → src/types}/route.js.map +1 -1
- package/dist/cjs/src/types/routing.d.ts.map +1 -0
- package/dist/{types → cjs/src/types}/routing.js.map +1 -1
- package/dist/cjs/src/types/schema.d.ts.map +1 -0
- package/dist/{types → cjs/src/types}/schema.js.map +1 -1
- package/dist/cjs/src/types/session.d.ts +70 -0
- package/dist/cjs/src/types/session.d.ts.map +1 -0
- package/dist/cjs/src/types/session.js +6 -0
- package/dist/cjs/src/types/session.js.map +1 -0
- package/dist/cjs/src/types/template.d.ts +30 -0
- package/dist/cjs/src/types/template.d.ts.map +1 -0
- package/dist/cjs/src/types/template.js +3 -0
- package/dist/cjs/src/types/template.js.map +1 -0
- package/dist/cjs/{types → src/types}/tool.d.ts +6 -8
- package/dist/cjs/src/types/tool.d.ts.map +1 -0
- package/dist/cjs/{types → src/types}/tool.js.map +1 -1
- package/dist/cjs/src/utils/clone.d.ts +8 -0
- package/dist/cjs/src/utils/clone.d.ts.map +1 -0
- package/dist/cjs/src/utils/clone.js +36 -0
- package/dist/cjs/src/utils/clone.js.map +1 -0
- package/dist/{utils → cjs/src/utils}/event.d.ts +1 -1
- package/dist/cjs/src/utils/event.d.ts.map +1 -0
- package/dist/cjs/{utils → src/utils}/event.js +2 -2
- package/dist/cjs/src/utils/event.js.map +1 -0
- package/dist/cjs/src/utils/history.d.ts +31 -0
- package/dist/cjs/src/utils/history.d.ts.map +1 -0
- package/dist/cjs/src/utils/history.js +128 -0
- package/dist/cjs/src/utils/history.js.map +1 -0
- package/dist/cjs/src/utils/id.d.ts.map +1 -0
- package/dist/cjs/src/utils/id.js.map +1 -0
- package/dist/cjs/src/utils/index.d.ts +13 -0
- package/dist/cjs/src/utils/index.d.ts.map +1 -0
- package/dist/cjs/src/utils/index.js +49 -0
- package/dist/cjs/src/utils/index.js.map +1 -0
- package/dist/cjs/src/utils/logger.d.ts.map +1 -0
- package/dist/cjs/src/utils/logger.js.map +1 -0
- package/dist/cjs/src/utils/retry.d.ts.map +1 -0
- package/dist/cjs/src/utils/retry.js.map +1 -0
- package/dist/cjs/src/utils/session.d.ts +51 -0
- package/dist/cjs/src/utils/session.d.ts.map +1 -0
- package/dist/cjs/{types → src/utils}/session.js +36 -13
- package/dist/cjs/src/utils/session.js.map +1 -0
- package/dist/cjs/src/utils/template.d.ts +107 -0
- package/dist/cjs/src/utils/template.d.ts.map +1 -0
- package/dist/cjs/src/utils/template.js +283 -0
- package/dist/cjs/src/utils/template.js.map +1 -0
- package/dist/{cjs → src}/adapters/MemoryAdapter.d.ts +4 -4
- package/dist/src/adapters/MemoryAdapter.d.ts.map +1 -0
- package/dist/{adapters → src/adapters}/MemoryAdapter.js +41 -21
- package/dist/src/adapters/MemoryAdapter.js.map +1 -0
- package/dist/{cjs → src}/adapters/MongoAdapter.d.ts +3 -3
- package/dist/src/adapters/MongoAdapter.d.ts.map +1 -0
- package/dist/{adapters → src/adapters}/MongoAdapter.js +2 -1
- package/dist/src/adapters/MongoAdapter.js.map +1 -0
- package/dist/{adapters → src/adapters}/OpenSearchAdapter.d.ts +3 -3
- package/dist/src/adapters/OpenSearchAdapter.d.ts.map +1 -0
- package/dist/{adapters → src/adapters}/OpenSearchAdapter.js +10 -13
- package/dist/src/adapters/OpenSearchAdapter.js.map +1 -0
- package/dist/{adapters → src/adapters}/PostgreSQLAdapter.d.ts +3 -3
- package/dist/src/adapters/PostgreSQLAdapter.d.ts.map +1 -0
- package/dist/{adapters → src/adapters}/PostgreSQLAdapter.js +1 -1
- package/dist/src/adapters/PostgreSQLAdapter.js.map +1 -0
- package/dist/{adapters → src/adapters}/PrismaAdapter.d.ts +3 -3
- package/dist/src/adapters/PrismaAdapter.d.ts.map +1 -0
- package/dist/{adapters → src/adapters}/PrismaAdapter.js +35 -5
- package/dist/src/adapters/PrismaAdapter.js.map +1 -0
- package/dist/{adapters → src/adapters}/RedisAdapter.d.ts +3 -3
- package/dist/src/adapters/RedisAdapter.d.ts.map +1 -0
- package/dist/{adapters → src/adapters}/RedisAdapter.js +3 -2
- package/dist/src/adapters/RedisAdapter.js.map +1 -0
- package/dist/{cjs → src}/adapters/SQLiteAdapter.d.ts +3 -3
- package/dist/src/adapters/SQLiteAdapter.d.ts.map +1 -0
- package/dist/{adapters → src/adapters}/SQLiteAdapter.js +2 -1
- package/dist/src/adapters/SQLiteAdapter.js.map +1 -0
- package/dist/src/adapters/index.js.map +1 -0
- package/dist/src/constants/index.js.map +1 -0
- package/dist/{cjs → src}/core/Agent.d.ts +67 -69
- package/dist/src/core/Agent.d.ts.map +1 -0
- package/dist/src/core/Agent.js +1429 -0
- package/dist/src/core/Agent.js.map +1 -0
- package/dist/src/core/Events.d.ts +26 -0
- package/dist/src/core/Events.d.ts.map +1 -0
- package/dist/src/core/Events.js +137 -0
- package/dist/src/core/Events.js.map +1 -0
- package/dist/src/core/PersistenceManager.d.ts +98 -0
- package/dist/src/core/PersistenceManager.d.ts.map +1 -0
- package/dist/{core → src/core}/PersistenceManager.js +56 -26
- package/dist/src/core/PersistenceManager.js.map +1 -0
- package/dist/src/core/PromptComposer.d.ts +27 -0
- package/dist/src/core/PromptComposer.d.ts.map +1 -0
- package/dist/src/core/PromptComposer.js +153 -0
- package/dist/src/core/PromptComposer.js.map +1 -0
- package/dist/src/core/ResponseEngine.d.ts +31 -0
- package/dist/src/core/ResponseEngine.d.ts.map +1 -0
- package/dist/src/core/ResponseEngine.js +80 -0
- package/dist/src/core/ResponseEngine.js.map +1 -0
- package/dist/src/core/ResponsePipeline.d.ts +143 -0
- package/dist/src/core/ResponsePipeline.d.ts.map +1 -0
- package/dist/src/core/ResponsePipeline.js +442 -0
- package/dist/src/core/ResponsePipeline.js.map +1 -0
- package/dist/src/core/Route.d.ts +126 -0
- package/dist/src/core/Route.d.ts.map +1 -0
- package/dist/{core → src/core}/Route.js +116 -20
- package/dist/src/core/Route.js.map +1 -0
- package/dist/{cjs → src}/core/RoutingEngine.d.ts +33 -38
- package/dist/src/core/RoutingEngine.d.ts.map +1 -0
- package/dist/{core → src/core}/RoutingEngine.js +98 -104
- package/dist/src/core/RoutingEngine.js.map +1 -0
- package/dist/src/core/SessionManager.d.ts +76 -0
- package/dist/src/core/SessionManager.d.ts.map +1 -0
- package/dist/src/core/SessionManager.js +193 -0
- package/dist/src/core/SessionManager.js.map +1 -0
- package/dist/src/core/Step.d.ts +96 -0
- package/dist/src/core/Step.d.ts.map +1 -0
- package/dist/src/core/Step.js +202 -0
- package/dist/src/core/Step.js.map +1 -0
- package/dist/src/core/ToolExecutor.d.ts +43 -0
- package/dist/src/core/ToolExecutor.d.ts.map +1 -0
- package/dist/src/core/ToolExecutor.js +70 -0
- package/dist/src/core/ToolExecutor.js.map +1 -0
- package/dist/{cjs → src}/index.d.ts +7 -15
- package/dist/src/index.d.ts.map +1 -0
- package/dist/{index.js → src/index.js} +6 -7
- package/dist/src/index.js.map +1 -0
- package/dist/{providers → src/providers}/AnthropicProvider.d.ts +1 -1
- package/dist/src/providers/AnthropicProvider.d.ts.map +1 -0
- package/dist/{providers → src/providers}/AnthropicProvider.js +54 -2
- package/dist/src/providers/AnthropicProvider.js.map +1 -0
- package/dist/{cjs → src}/providers/GeminiProvider.d.ts +1 -1
- package/dist/{cjs → src}/providers/GeminiProvider.d.ts.map +1 -1
- package/dist/{providers → src/providers}/GeminiProvider.js +65 -0
- package/dist/src/providers/GeminiProvider.js.map +1 -0
- package/dist/{providers → src/providers}/OpenAIProvider.d.ts +1 -1
- package/dist/{cjs → src}/providers/OpenAIProvider.d.ts.map +1 -1
- package/dist/{providers → src/providers}/OpenAIProvider.js +70 -1
- package/dist/src/providers/OpenAIProvider.js.map +1 -0
- package/dist/{cjs → src}/providers/OpenRouterProvider.d.ts +1 -1
- package/dist/{cjs → src}/providers/OpenRouterProvider.d.ts.map +1 -1
- package/dist/{providers → src/providers}/OpenRouterProvider.js +76 -0
- package/dist/src/providers/OpenRouterProvider.js.map +1 -0
- package/dist/src/providers/index.js.map +1 -0
- package/dist/{types → src/types}/agent.d.ts +54 -35
- package/dist/src/types/agent.d.ts.map +1 -0
- package/dist/src/types/agent.js.map +1 -0
- package/dist/{types → src/types}/ai.d.ts +7 -0
- package/dist/src/types/ai.d.ts.map +1 -0
- package/dist/{cjs → src}/types/ai.js.map +1 -1
- package/dist/{cjs → src}/types/history.d.ts +76 -18
- package/dist/src/types/history.d.ts.map +1 -0
- package/dist/src/types/history.js +30 -0
- package/dist/src/types/history.js.map +1 -0
- package/dist/src/types/index.d.ts +20 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/types/index.js +10 -0
- package/dist/src/types/index.js.map +1 -0
- package/dist/{cjs → src}/types/persistence.d.ts +39 -23
- package/dist/src/types/persistence.d.ts.map +1 -0
- package/dist/src/types/persistence.js.map +1 -0
- package/dist/{types → src/types}/route.d.ts +85 -31
- package/dist/src/types/route.d.ts.map +1 -0
- package/dist/{types → src/types}/route.js.map +1 -1
- package/dist/src/types/session.d.ts +70 -0
- package/dist/src/types/session.d.ts.map +1 -0
- package/dist/src/types/session.js +5 -0
- package/dist/src/types/session.js.map +1 -0
- package/dist/src/types/template.d.ts +30 -0
- package/dist/src/types/template.d.ts.map +1 -0
- package/dist/src/types/template.js +2 -0
- package/dist/src/types/template.js.map +1 -0
- package/dist/{types → src/types}/tool.d.ts +6 -8
- package/dist/{cjs → src}/types/tool.d.ts.map +1 -1
- package/dist/{types → src/types}/tool.js.map +1 -1
- package/dist/src/utils/clone.d.ts +8 -0
- package/dist/src/utils/clone.d.ts.map +1 -0
- package/dist/src/utils/clone.js +33 -0
- package/dist/src/utils/clone.js.map +1 -0
- package/dist/{cjs → src}/utils/event.d.ts +1 -1
- package/dist/{cjs → src}/utils/event.d.ts.map +1 -1
- package/dist/{utils → src/utils}/event.js +1 -1
- package/dist/src/utils/event.js.map +1 -0
- package/dist/src/utils/history.d.ts +31 -0
- package/dist/src/utils/history.d.ts.map +1 -0
- package/dist/src/utils/history.js +121 -0
- package/dist/src/utils/history.js.map +1 -0
- package/dist/src/utils/id.js.map +1 -0
- package/dist/src/utils/index.d.ts +13 -0
- package/dist/src/utils/index.d.ts.map +1 -0
- package/dist/src/utils/index.js +19 -0
- package/dist/src/utils/index.js.map +1 -0
- package/dist/src/utils/logger.js.map +1 -0
- package/dist/src/utils/retry.js.map +1 -0
- package/dist/src/utils/session.d.ts +51 -0
- package/dist/src/utils/session.d.ts.map +1 -0
- package/dist/{types → src/utils}/session.js +34 -13
- package/dist/src/utils/session.js.map +1 -0
- package/dist/src/utils/template.d.ts +107 -0
- package/dist/src/utils/template.d.ts.map +1 -0
- package/dist/src/utils/template.js +276 -0
- package/dist/src/utils/template.js.map +1 -0
- package/docs/README.md +174 -68
- package/docs/{API_REFERENCE.md → api/README.md} +902 -263
- package/docs/api/overview.md +798 -0
- package/docs/core/agent/README.md +642 -0
- package/docs/{CONTEXT_MANAGEMENT.md → core/agent/context-management.md} +144 -95
- package/docs/{ARCHITECTURE.md → core/agent/session-management.md} +74 -59
- package/docs/core/ai-integration/prompt-composition.md +196 -0
- package/docs/core/ai-integration/providers.md +515 -0
- package/docs/core/ai-integration/response-processing.md +165 -0
- package/docs/core/conversation-flows/data-collection.md +545 -0
- package/docs/core/conversation-flows/route-dsl.md +479 -0
- package/docs/core/conversation-flows/routes.md +61 -0
- package/docs/core/conversation-flows/step-transitions.md +595 -0
- package/docs/core/conversation-flows/steps.md +130 -0
- package/docs/{ADAPTERS.md → core/persistence/adapters.md} +2 -2
- package/docs/core/persistence/session-storage.md +644 -0
- package/docs/core/routing/intelligent-routing.md +339 -0
- package/docs/core/tools/tool-definition.md +346 -0
- package/docs/core/tools/tool-execution.md +815 -0
- package/docs/core/tools/tool-scoping.md +628 -0
- package/docs/guides/getting-started/README.md +384 -0
- package/examples/{company-qna-agent.ts → advanced-patterns/knowledge-based-agent.ts} +104 -69
- package/examples/{persistent-onboarding.ts → advanced-patterns/persistent-onboarding.ts} +181 -103
- package/examples/{rules-prohibitions.ts → advanced-patterns/route-lifecycle-hooks.ts} +102 -82
- package/examples/{streaming-agent.ts → advanced-patterns/streaming-responses.ts} +90 -69
- package/examples/ai-providers/anthropic-integration.ts +377 -0
- package/examples/{openai-agent.ts → ai-providers/openai-integration.ts} +37 -43
- package/examples/{route-transitions.ts → conversation-flows/completion-transitions.ts} +115 -108
- package/examples/{declarative-agent.ts → core-concepts/basic-agent.ts} +175 -131
- package/examples/core-concepts/schema-driven-extraction.ts +301 -0
- package/examples/core-concepts/session-management.ts +394 -0
- package/examples/integrations/database-integration.ts +615 -0
- package/examples/{healthcare-agent.ts → integrations/healthcare-integration.ts} +204 -111
- package/examples/{opensearch-persistence.ts → integrations/search-integration.ts} +159 -128
- package/examples/integrations/server-session-management.ts +299 -0
- package/examples/persistence/custom-adapter.ts +529 -0
- package/examples/{prisma-persistence.ts → persistence/database-persistence.ts} +168 -241
- package/examples/persistence/memory-sessions.ts +506 -0
- package/examples/{prisma-schema.example.prisma → persistence/prisma-schema.example.prisma} +1 -1
- package/examples/{redis-persistence.ts → persistence/redis-persistence.ts} +152 -173
- package/examples/tools/basic-tools.ts +550 -0
- package/examples/{extracted-data-modification.ts → tools/data-enrichment-tools.ts} +82 -79
- package/package.json +14 -10
- package/src/adapters/MemoryAdapter.ts +74 -46
- package/src/adapters/MongoAdapter.ts +33 -24
- package/src/adapters/OpenSearchAdapter.ts +41 -37
- package/src/adapters/PostgreSQLAdapter.ts +35 -24
- package/src/adapters/PrismaAdapter.ts +69 -27
- package/src/adapters/RedisAdapter.ts +38 -26
- package/src/adapters/SQLiteAdapter.ts +32 -22
- package/src/core/Agent.ts +1102 -487
- package/src/core/Events.ts +100 -112
- package/src/core/PersistenceManager.ts +87 -57
- package/src/core/PromptComposer.ts +158 -85
- package/src/core/ResponseEngine.ts +118 -38
- package/src/core/ResponsePipeline.ts +715 -0
- package/src/core/Route.ts +168 -51
- package/src/core/RoutingEngine.ts +178 -209
- package/src/core/SessionManager.ts +241 -0
- package/src/core/Step.ts +149 -67
- package/src/core/ToolExecutor.ts +37 -42
- package/src/index.ts +31 -37
- package/src/providers/AnthropicProvider.ts +71 -5
- package/src/providers/GeminiProvider.ts +83 -2
- package/src/providers/OpenAIProvider.ts +95 -3
- package/src/providers/OpenRouterProvider.ts +102 -2
- package/src/types/agent.ts +50 -38
- package/src/types/ai.ts +7 -0
- package/src/types/history.ts +91 -18
- package/src/types/index.ts +43 -7
- package/src/types/persistence.ts +46 -28
- package/src/types/route.ts +104 -45
- package/src/types/session.ts +19 -213
- package/src/types/template.ts +36 -0
- package/src/types/tool.ts +9 -11
- package/src/utils/clone.ts +36 -0
- package/src/utils/event.ts +1 -1
- package/src/utils/history.ts +143 -0
- package/src/utils/index.ts +53 -0
- package/src/utils/session.ts +229 -0
- package/src/utils/template.ts +335 -0
- package/dist/adapters/MemoryAdapter.d.ts.map +0 -1
- package/dist/adapters/MemoryAdapter.js.map +0 -1
- package/dist/adapters/MongoAdapter.d.ts.map +0 -1
- package/dist/adapters/MongoAdapter.js.map +0 -1
- package/dist/adapters/OpenSearchAdapter.d.ts.map +0 -1
- package/dist/adapters/OpenSearchAdapter.js.map +0 -1
- package/dist/adapters/PostgreSQLAdapter.d.ts.map +0 -1
- package/dist/adapters/PostgreSQLAdapter.js.map +0 -1
- package/dist/adapters/PrismaAdapter.d.ts.map +0 -1
- package/dist/adapters/PrismaAdapter.js.map +0 -1
- package/dist/adapters/RedisAdapter.d.ts.map +0 -1
- package/dist/adapters/RedisAdapter.js.map +0 -1
- package/dist/adapters/SQLiteAdapter.d.ts.map +0 -1
- package/dist/adapters/SQLiteAdapter.js.map +0 -1
- package/dist/adapters/index.d.ts.map +0 -1
- package/dist/adapters/index.js.map +0 -1
- package/dist/cjs/adapters/MemoryAdapter.d.ts.map +0 -1
- package/dist/cjs/adapters/MemoryAdapter.js.map +0 -1
- package/dist/cjs/adapters/MongoAdapter.d.ts.map +0 -1
- package/dist/cjs/adapters/MongoAdapter.js.map +0 -1
- package/dist/cjs/adapters/OpenSearchAdapter.d.ts.map +0 -1
- package/dist/cjs/adapters/OpenSearchAdapter.js.map +0 -1
- package/dist/cjs/adapters/PostgreSQLAdapter.d.ts.map +0 -1
- package/dist/cjs/adapters/PostgreSQLAdapter.js.map +0 -1
- package/dist/cjs/adapters/PrismaAdapter.d.ts.map +0 -1
- package/dist/cjs/adapters/PrismaAdapter.js.map +0 -1
- package/dist/cjs/adapters/RedisAdapter.d.ts.map +0 -1
- package/dist/cjs/adapters/RedisAdapter.js.map +0 -1
- package/dist/cjs/adapters/SQLiteAdapter.d.ts.map +0 -1
- package/dist/cjs/adapters/SQLiteAdapter.js.map +0 -1
- package/dist/cjs/adapters/index.js.map +0 -1
- package/dist/cjs/constants/index.js.map +0 -1
- package/dist/cjs/core/Agent.d.ts.map +0 -1
- package/dist/cjs/core/Agent.js +0 -966
- package/dist/cjs/core/Agent.js.map +0 -1
- package/dist/cjs/core/DomainRegistry.d.ts +0 -36
- package/dist/cjs/core/DomainRegistry.d.ts.map +0 -1
- package/dist/cjs/core/DomainRegistry.js +0 -72
- package/dist/cjs/core/DomainRegistry.js.map +0 -1
- package/dist/cjs/core/Events.d.ts +0 -41
- package/dist/cjs/core/Events.d.ts.map +0 -1
- package/dist/cjs/core/Events.js +0 -99
- package/dist/cjs/core/Events.js.map +0 -1
- package/dist/cjs/core/PersistenceManager.d.ts +0 -96
- package/dist/cjs/core/PersistenceManager.d.ts.map +0 -1
- package/dist/cjs/core/PersistenceManager.js.map +0 -1
- package/dist/cjs/core/PromptComposer.d.ts +0 -24
- package/dist/cjs/core/PromptComposer.d.ts.map +0 -1
- package/dist/cjs/core/PromptComposer.js +0 -127
- package/dist/cjs/core/PromptComposer.js.map +0 -1
- package/dist/cjs/core/ResponseEngine.d.ts +0 -14
- package/dist/cjs/core/ResponseEngine.d.ts.map +0 -1
- package/dist/cjs/core/ResponseEngine.js +0 -56
- package/dist/cjs/core/ResponseEngine.js.map +0 -1
- package/dist/cjs/core/Route.d.ts +0 -90
- package/dist/cjs/core/Route.d.ts.map +0 -1
- package/dist/cjs/core/Route.js.map +0 -1
- package/dist/cjs/core/RoutingEngine.d.ts.map +0 -1
- package/dist/cjs/core/RoutingEngine.js.map +0 -1
- package/dist/cjs/core/Step.d.ts +0 -72
- package/dist/cjs/core/Step.d.ts.map +0 -1
- package/dist/cjs/core/Step.js +0 -150
- package/dist/cjs/core/Step.js.map +0 -1
- package/dist/cjs/core/Tool.d.ts +0 -39
- package/dist/cjs/core/Tool.d.ts.map +0 -1
- package/dist/cjs/core/Tool.js +0 -34
- package/dist/cjs/core/Tool.js.map +0 -1
- package/dist/cjs/core/ToolExecutor.d.ts +0 -29
- package/dist/cjs/core/ToolExecutor.d.ts.map +0 -1
- package/dist/cjs/core/ToolExecutor.js.map +0 -1
- package/dist/cjs/core/Transition.d.ts +0 -32
- package/dist/cjs/core/Transition.d.ts.map +0 -1
- package/dist/cjs/core/Transition.js +0 -89
- package/dist/cjs/core/Transition.js.map +0 -1
- package/dist/cjs/index.d.ts.map +0 -1
- package/dist/cjs/index.js.map +0 -1
- package/dist/cjs/providers/AnthropicProvider.d.ts.map +0 -1
- package/dist/cjs/providers/AnthropicProvider.js.map +0 -1
- package/dist/cjs/providers/GeminiProvider.js.map +0 -1
- package/dist/cjs/providers/OpenAIProvider.js.map +0 -1
- package/dist/cjs/providers/OpenRouterProvider.js.map +0 -1
- package/dist/cjs/providers/index.js.map +0 -1
- package/dist/cjs/types/agent.d.ts.map +0 -1
- package/dist/cjs/types/agent.js.map +0 -1
- package/dist/cjs/types/ai.d.ts.map +0 -1
- package/dist/cjs/types/history.d.ts.map +0 -1
- package/dist/cjs/types/history.js +0 -37
- package/dist/cjs/types/history.js.map +0 -1
- package/dist/cjs/types/index.d.ts +0 -12
- package/dist/cjs/types/index.d.ts.map +0 -1
- package/dist/cjs/types/index.js +0 -12
- package/dist/cjs/types/index.js.map +0 -1
- package/dist/cjs/types/persistence.d.ts.map +0 -1
- package/dist/cjs/types/persistence.js.map +0 -1
- package/dist/cjs/types/route.d.ts.map +0 -1
- package/dist/cjs/types/session.d.ts +0 -104
- package/dist/cjs/types/session.d.ts.map +0 -1
- package/dist/cjs/types/session.js.map +0 -1
- package/dist/cjs/utils/event.js.map +0 -1
- package/dist/cjs/utils/id.js.map +0 -1
- package/dist/cjs/utils/logger.js.map +0 -1
- package/dist/cjs/utils/retry.js.map +0 -1
- package/dist/constants/index.d.ts.map +0 -1
- package/dist/constants/index.js.map +0 -1
- package/dist/core/Agent.d.ts.map +0 -1
- package/dist/core/Agent.js +0 -962
- package/dist/core/Agent.js.map +0 -1
- package/dist/core/DomainRegistry.d.ts +0 -36
- package/dist/core/DomainRegistry.d.ts.map +0 -1
- package/dist/core/DomainRegistry.js +0 -68
- package/dist/core/DomainRegistry.js.map +0 -1
- package/dist/core/Events.d.ts +0 -41
- package/dist/core/Events.d.ts.map +0 -1
- package/dist/core/Events.js +0 -94
- package/dist/core/Events.js.map +0 -1
- package/dist/core/PersistenceManager.d.ts +0 -96
- package/dist/core/PersistenceManager.d.ts.map +0 -1
- package/dist/core/PersistenceManager.js.map +0 -1
- package/dist/core/PromptComposer.d.ts +0 -24
- package/dist/core/PromptComposer.d.ts.map +0 -1
- package/dist/core/PromptComposer.js +0 -123
- package/dist/core/PromptComposer.js.map +0 -1
- package/dist/core/ResponseEngine.d.ts +0 -14
- package/dist/core/ResponseEngine.d.ts.map +0 -1
- package/dist/core/ResponseEngine.js +0 -52
- package/dist/core/ResponseEngine.js.map +0 -1
- package/dist/core/Route.d.ts +0 -90
- package/dist/core/Route.d.ts.map +0 -1
- package/dist/core/Route.js.map +0 -1
- package/dist/core/RoutingEngine.d.ts.map +0 -1
- package/dist/core/RoutingEngine.js.map +0 -1
- package/dist/core/Step.d.ts +0 -72
- package/dist/core/Step.d.ts.map +0 -1
- package/dist/core/Step.js +0 -146
- package/dist/core/Step.js.map +0 -1
- package/dist/core/Tool.d.ts +0 -39
- package/dist/core/Tool.d.ts.map +0 -1
- package/dist/core/Tool.js +0 -31
- package/dist/core/Tool.js.map +0 -1
- package/dist/core/ToolExecutor.d.ts +0 -29
- package/dist/core/ToolExecutor.d.ts.map +0 -1
- package/dist/core/ToolExecutor.js +0 -69
- package/dist/core/ToolExecutor.js.map +0 -1
- package/dist/core/Transition.d.ts +0 -32
- package/dist/core/Transition.d.ts.map +0 -1
- package/dist/core/Transition.js +0 -85
- package/dist/core/Transition.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/providers/AnthropicProvider.d.ts.map +0 -1
- package/dist/providers/AnthropicProvider.js.map +0 -1
- package/dist/providers/GeminiProvider.d.ts.map +0 -1
- package/dist/providers/GeminiProvider.js.map +0 -1
- package/dist/providers/OpenAIProvider.d.ts.map +0 -1
- package/dist/providers/OpenAIProvider.js.map +0 -1
- package/dist/providers/OpenRouterProvider.d.ts.map +0 -1
- package/dist/providers/OpenRouterProvider.js.map +0 -1
- package/dist/providers/index.d.ts.map +0 -1
- package/dist/providers/index.js.map +0 -1
- package/dist/types/agent.d.ts.map +0 -1
- package/dist/types/agent.js.map +0 -1
- package/dist/types/ai.d.ts.map +0 -1
- package/dist/types/ai.js.map +0 -1
- package/dist/types/history.d.ts.map +0 -1
- package/dist/types/history.js +0 -34
- package/dist/types/history.js.map +0 -1
- package/dist/types/index.d.ts +0 -12
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -6
- package/dist/types/index.js.map +0 -1
- package/dist/types/persistence.d.ts.map +0 -1
- package/dist/types/persistence.js.map +0 -1
- package/dist/types/route.d.ts.map +0 -1
- package/dist/types/routing.d.ts.map +0 -1
- package/dist/types/schema.d.ts.map +0 -1
- package/dist/types/session.d.ts +0 -104
- package/dist/types/session.d.ts.map +0 -1
- package/dist/types/session.js.map +0 -1
- package/dist/types/tool.d.ts.map +0 -1
- package/dist/utils/event.d.ts.map +0 -1
- package/dist/utils/event.js.map +0 -1
- package/dist/utils/id.d.ts.map +0 -1
- package/dist/utils/id.js.map +0 -1
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/logger.js.map +0 -1
- package/dist/utils/retry.d.ts.map +0 -1
- package/dist/utils/retry.js.map +0 -1
- package/docs/AGENT.md +0 -535
- package/docs/DOCS.md +0 -263
- package/docs/DOMAINS.md +0 -735
- package/docs/EXAMPLES.md +0 -467
- package/docs/GETTING_STARTED.md +0 -424
- package/docs/PERSISTENCE.md +0 -815
- package/docs/PROVIDERS.md +0 -612
- package/docs/ROUTES.md +0 -1085
- package/docs/STEPS.md +0 -883
- package/examples/business-onboarding.ts +0 -791
- package/examples/custom-database-persistence.ts +0 -574
- package/examples/domain-scoping.ts +0 -366
- package/examples/travel-agent.ts +0 -584
- package/src/core/DomainRegistry.ts +0 -80
- package/src/core/Tool.ts +0 -112
- package/src/core/Transition.ts +0 -115
- /package/dist/{adapters → cjs/src/adapters}/index.d.ts +0 -0
- /package/dist/cjs/{adapters → src/adapters}/index.js +0 -0
- /package/dist/cjs/{constants → src/constants}/index.d.ts +0 -0
- /package/dist/cjs/{constants → src/constants}/index.js +0 -0
- /package/dist/cjs/{providers → src/providers}/index.d.ts +0 -0
- /package/dist/cjs/{providers → src/providers}/index.js +0 -0
- /package/dist/cjs/{types → src/types}/agent.js +0 -0
- /package/dist/cjs/{types → src/types}/ai.js +0 -0
- /package/dist/cjs/{types → src/types}/persistence.js +0 -0
- /package/dist/cjs/{types → src/types}/route.js +0 -0
- /package/dist/cjs/{types → src/types}/routing.d.ts +0 -0
- /package/dist/cjs/{types → src/types}/routing.js +0 -0
- /package/dist/cjs/{types → src/types}/schema.d.ts +0 -0
- /package/dist/cjs/{types → src/types}/schema.js +0 -0
- /package/dist/cjs/{types → src/types}/tool.js +0 -0
- /package/dist/cjs/{utils → src/utils}/id.d.ts +0 -0
- /package/dist/cjs/{utils → src/utils}/id.js +0 -0
- /package/dist/cjs/{utils → src/utils}/logger.d.ts +0 -0
- /package/dist/cjs/{utils → src/utils}/logger.js +0 -0
- /package/dist/cjs/{utils → src/utils}/retry.d.ts +0 -0
- /package/dist/cjs/{utils → src/utils}/retry.js +0 -0
- /package/dist/{cjs → src}/adapters/index.d.ts +0 -0
- /package/dist/{cjs → src}/adapters/index.d.ts.map +0 -0
- /package/dist/{adapters → src/adapters}/index.js +0 -0
- /package/dist/{constants → src/constants}/index.d.ts +0 -0
- /package/dist/{cjs → src}/constants/index.d.ts.map +0 -0
- /package/dist/{constants → src/constants}/index.js +0 -0
- /package/dist/{providers → src/providers}/index.d.ts +0 -0
- /package/dist/{cjs → src}/providers/index.d.ts.map +0 -0
- /package/dist/{providers → src/providers}/index.js +0 -0
- /package/dist/{types → src/types}/agent.js +0 -0
- /package/dist/{types → src/types}/ai.js +0 -0
- /package/dist/{types → src/types}/persistence.js +0 -0
- /package/dist/{types → src/types}/route.js +0 -0
- /package/dist/{types → src/types}/routing.d.ts +0 -0
- /package/dist/{cjs → src}/types/routing.d.ts.map +0 -0
- /package/dist/{types → src/types}/routing.js +0 -0
- /package/dist/{cjs → src}/types/routing.js.map +0 -0
- /package/dist/{types → src/types}/schema.d.ts +0 -0
- /package/dist/{cjs → src}/types/schema.d.ts.map +0 -0
- /package/dist/{types → src/types}/schema.js +0 -0
- /package/dist/{cjs → src}/types/schema.js.map +0 -0
- /package/dist/{types → src/types}/tool.js +0 -0
- /package/dist/{utils → src/utils}/id.d.ts +0 -0
- /package/dist/{cjs → src}/utils/id.d.ts.map +0 -0
- /package/dist/{utils → src/utils}/id.js +0 -0
- /package/dist/{utils → src/utils}/logger.d.ts +0 -0
- /package/dist/{cjs → src}/utils/logger.d.ts.map +0 -0
- /package/dist/{utils → src/utils}/logger.js +0 -0
- /package/dist/{utils → src/utils}/retry.d.ts +0 -0
- /package/dist/{cjs → src}/utils/retry.d.ts.map +0 -0
- /package/dist/{utils → src/utils}/retry.js +0 -0
- /package/docs/{PUBLISHING.md → guides/advanced-patterns/publishing.md} +0 -0
|
@@ -0,0 +1,1433 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Core Agent implementation
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Agent = void 0;
|
|
7
|
+
const history_1 = require("../types/history");
|
|
8
|
+
const utils_1 = require("../utils");
|
|
9
|
+
const Route_1 = require("./Route");
|
|
10
|
+
const Step_1 = require("./Step");
|
|
11
|
+
const PersistenceManager_1 = require("./PersistenceManager");
|
|
12
|
+
const SessionManager_1 = require("./SessionManager");
|
|
13
|
+
const RoutingEngine_1 = require("./RoutingEngine");
|
|
14
|
+
const ResponseEngine_1 = require("./ResponseEngine");
|
|
15
|
+
const ToolExecutor_1 = require("./ToolExecutor");
|
|
16
|
+
const ResponsePipeline_1 = require("./ResponsePipeline");
|
|
17
|
+
const constants_1 = require("../constants");
|
|
18
|
+
/**
|
|
19
|
+
* Main Agent class with generic context support
|
|
20
|
+
*/
|
|
21
|
+
class Agent {
|
|
22
|
+
constructor(options) {
|
|
23
|
+
this.options = options;
|
|
24
|
+
this.terms = [];
|
|
25
|
+
this.guidelines = [];
|
|
26
|
+
this.tools = [];
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
28
|
+
this.routes = [];
|
|
29
|
+
this.knowledgeBase = {};
|
|
30
|
+
// Set log level based on debug option
|
|
31
|
+
if (options.debug) {
|
|
32
|
+
utils_1.logger.setLevel(utils_1.LoggerLevel.DEBUG);
|
|
33
|
+
}
|
|
34
|
+
// Validate context configuration
|
|
35
|
+
if (options.context !== undefined && options.contextProvider) {
|
|
36
|
+
throw new Error("Cannot provide both 'context' and 'contextProvider'. Choose one.");
|
|
37
|
+
}
|
|
38
|
+
// Initialize context if provided
|
|
39
|
+
this.context = options.context;
|
|
40
|
+
// Initialize current session if provided
|
|
41
|
+
this.currentSession = options.session;
|
|
42
|
+
// Initialize routing and response engines
|
|
43
|
+
this.routingEngine = new RoutingEngine_1.RoutingEngine({
|
|
44
|
+
maxCandidates: 5,
|
|
45
|
+
allowRouteSwitch: true,
|
|
46
|
+
switchThreshold: 70,
|
|
47
|
+
});
|
|
48
|
+
this.responseEngine = new ResponseEngine_1.ResponseEngine();
|
|
49
|
+
this.responsePipeline = new ResponsePipeline_1.ResponsePipeline(options, this.routes, this.tools, this.routingEngine, this.updateContext.bind(this), this.updateData.bind(this));
|
|
50
|
+
// Initialize persistence if configured
|
|
51
|
+
if (options.persistence) {
|
|
52
|
+
this.persistenceManager = new PersistenceManager_1.PersistenceManager(options.persistence);
|
|
53
|
+
// Initialize the adapter if it has an initialize method
|
|
54
|
+
if (options.persistence.adapter.initialize) {
|
|
55
|
+
options.persistence.adapter.initialize().catch((error) => {
|
|
56
|
+
utils_1.logger.error("[Agent] Persistence adapter initialization failed:", error);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Initialize from options - use create methods for consistency
|
|
61
|
+
if (options.terms) {
|
|
62
|
+
options.terms.forEach((term) => {
|
|
63
|
+
this.createTerm(term);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
if (options.guidelines) {
|
|
67
|
+
options.guidelines.forEach((guideline) => {
|
|
68
|
+
this.createGuideline(guideline);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
if (options.tools) {
|
|
72
|
+
options.tools.forEach((tool) => {
|
|
73
|
+
this.createTool(tool);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
if (options.routes) {
|
|
77
|
+
options.routes.forEach((routeOptions) => {
|
|
78
|
+
this.createRoute(routeOptions);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
// Initialize knowledge base
|
|
82
|
+
if (options.knowledgeBase) {
|
|
83
|
+
this.knowledgeBase = { ...options.knowledgeBase };
|
|
84
|
+
}
|
|
85
|
+
// Initialize session manager
|
|
86
|
+
this.session = new SessionManager_1.SessionManager(this.persistenceManager);
|
|
87
|
+
// Store sessionId for later use in getOrCreate calls
|
|
88
|
+
if (options.sessionId) {
|
|
89
|
+
// The session will be loaded on first getOrCreate call
|
|
90
|
+
this.session.getOrCreate(options.sessionId).catch((err) => {
|
|
91
|
+
utils_1.logger.error("Failed to start session", err);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Get agent name
|
|
97
|
+
*/
|
|
98
|
+
get name() {
|
|
99
|
+
return this.options.name;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Get agent description
|
|
103
|
+
*/
|
|
104
|
+
get description() {
|
|
105
|
+
return this.options.description;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get agent goal
|
|
109
|
+
*/
|
|
110
|
+
get goal() {
|
|
111
|
+
return this.options.goal;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Get agent identity
|
|
115
|
+
*/
|
|
116
|
+
get identity() {
|
|
117
|
+
return this.options.identity;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Create a new route (journey)
|
|
121
|
+
* @template TData - Type of data collected throughout the route
|
|
122
|
+
*/
|
|
123
|
+
createRoute(options) {
|
|
124
|
+
const route = new Route_1.Route(options);
|
|
125
|
+
this.routes.push(route);
|
|
126
|
+
return route;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Create a domain term for the glossary
|
|
130
|
+
*/
|
|
131
|
+
createTerm(term) {
|
|
132
|
+
this.terms.push(term);
|
|
133
|
+
return this;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Create a behavioral guideline
|
|
137
|
+
*/
|
|
138
|
+
createGuideline(guideline) {
|
|
139
|
+
const guidelineWithId = {
|
|
140
|
+
...guideline,
|
|
141
|
+
id: guideline.id || `guideline_${this.guidelines.length}`,
|
|
142
|
+
enabled: guideline.enabled !== false, // Default to true
|
|
143
|
+
};
|
|
144
|
+
this.guidelines.push(guidelineWithId);
|
|
145
|
+
return this;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Register a tool at the agent level
|
|
149
|
+
*/
|
|
150
|
+
createTool(tool) {
|
|
151
|
+
this.tools.push(tool);
|
|
152
|
+
return this;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Register multiple tools at the agent level
|
|
156
|
+
*/
|
|
157
|
+
registerTools(tools) {
|
|
158
|
+
tools.forEach((tool) => this.createTool(tool));
|
|
159
|
+
return this;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Update the agent's context
|
|
163
|
+
* Triggers both agent-level and route-specific onContextUpdate lifecycle hooks if configured
|
|
164
|
+
*/
|
|
165
|
+
async updateContext(updates) {
|
|
166
|
+
const previousContext = this.context;
|
|
167
|
+
// Merge updates with current context
|
|
168
|
+
this.context = {
|
|
169
|
+
...this.context,
|
|
170
|
+
...updates,
|
|
171
|
+
};
|
|
172
|
+
// Trigger route-specific lifecycle hook if configured and session has current route
|
|
173
|
+
if (this.currentSession?.currentRoute) {
|
|
174
|
+
const currentRoute = this.routes.find((r) => r.id === this.currentSession.currentRoute?.id);
|
|
175
|
+
if (currentRoute?.hooks?.onContextUpdate &&
|
|
176
|
+
previousContext !== undefined) {
|
|
177
|
+
await currentRoute.handleContextUpdate(this.context, previousContext);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// Trigger agent-level lifecycle hook if configured
|
|
181
|
+
if (this.options.hooks?.onContextUpdate && previousContext !== undefined) {
|
|
182
|
+
await this.options.hooks.onContextUpdate(this.context, previousContext);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Update collected data in session with lifecycle hook support
|
|
187
|
+
* Triggers both agent-level and route-specific onDataUpdate lifecycle hooks if configured
|
|
188
|
+
* @internal
|
|
189
|
+
*/
|
|
190
|
+
async updateData(session, dataUpdate) {
|
|
191
|
+
const previousCollected = { ...session.data };
|
|
192
|
+
// Merge new collected data
|
|
193
|
+
let newCollected = {
|
|
194
|
+
...session.data,
|
|
195
|
+
...dataUpdate,
|
|
196
|
+
};
|
|
197
|
+
// Trigger route-specific lifecycle hook if configured and session has a current route
|
|
198
|
+
if (session.currentRoute) {
|
|
199
|
+
const currentRoute = this.routes.find((r) => r.id === session.currentRoute?.id);
|
|
200
|
+
if (currentRoute?.hooks?.onDataUpdate) {
|
|
201
|
+
newCollected = await currentRoute.handleDataUpdate(newCollected, previousCollected);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
// Trigger agent-level lifecycle hook if configured
|
|
205
|
+
if (this.options.hooks?.onDataUpdate) {
|
|
206
|
+
newCollected = (await this.options.hooks.onDataUpdate(newCollected, previousCollected));
|
|
207
|
+
}
|
|
208
|
+
// Return updated session
|
|
209
|
+
return (0, utils_1.mergeCollected)(session, newCollected);
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Get current context (fetches from provider if configured)
|
|
213
|
+
*/
|
|
214
|
+
async getContext() {
|
|
215
|
+
// If context provider is configured, use it to fetch fresh context
|
|
216
|
+
if (this.options.contextProvider) {
|
|
217
|
+
return await this.options.contextProvider();
|
|
218
|
+
}
|
|
219
|
+
// Otherwise return the stored context
|
|
220
|
+
return this.context;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Generate a response based on history and context as a stream
|
|
224
|
+
*/
|
|
225
|
+
async *respondStream(params) {
|
|
226
|
+
const { history: simpleHistory, signal } = params;
|
|
227
|
+
const history = (0, utils_1.normalizeHistory)(simpleHistory);
|
|
228
|
+
// Prepare context and session using the response pipeline
|
|
229
|
+
this.responsePipeline.setContext(this.context);
|
|
230
|
+
this.responsePipeline.setCurrentSession(this.currentSession);
|
|
231
|
+
let session;
|
|
232
|
+
const responseContext = await this.responsePipeline.prepareResponseContext({
|
|
233
|
+
contextOverride: params.contextOverride,
|
|
234
|
+
session: params.session ? (0, utils_1.cloneDeep)(params.session) : undefined,
|
|
235
|
+
});
|
|
236
|
+
const { effectiveContext } = responseContext;
|
|
237
|
+
session = responseContext.session;
|
|
238
|
+
// Update our stored context if it was modified by beforeRespond hook
|
|
239
|
+
this.context = this.responsePipeline.getStoredContext();
|
|
240
|
+
// PHASE 1: PREPARE - Execute prepare function if current step has one
|
|
241
|
+
if (session.currentRoute && session.currentStep) {
|
|
242
|
+
const currentRoute = this.routes.find((r) => r.id === session.currentRoute?.id);
|
|
243
|
+
if (currentRoute) {
|
|
244
|
+
const currentStep = currentRoute.getStep(session.currentStep.id);
|
|
245
|
+
if (currentStep?.prepare) {
|
|
246
|
+
utils_1.logger.debug(`[Agent] Executing prepare for step: ${currentStep.id}`);
|
|
247
|
+
await this.executePrepareFinalize(currentStep.prepare, effectiveContext, session.data, currentRoute, currentStep);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
// PHASE 2: ROUTING + STEP SELECTION - Use response pipeline
|
|
252
|
+
const routingResult = await this.responsePipeline.handleRoutingAndStepSelection({
|
|
253
|
+
session,
|
|
254
|
+
history,
|
|
255
|
+
context: effectiveContext,
|
|
256
|
+
signal,
|
|
257
|
+
});
|
|
258
|
+
const selectedRoute = routingResult.selectedRoute;
|
|
259
|
+
const selectedStep = routingResult.selectedStep;
|
|
260
|
+
const responseDirectives = routingResult.responseDirectives;
|
|
261
|
+
const isRouteComplete = routingResult.isRouteComplete;
|
|
262
|
+
session = routingResult.session;
|
|
263
|
+
// PHASE 3: DETERMINE NEXT STEP - Use pipeline method
|
|
264
|
+
const stepResult = this.responsePipeline.determineNextStep({
|
|
265
|
+
selectedRoute,
|
|
266
|
+
selectedStep,
|
|
267
|
+
session,
|
|
268
|
+
isRouteComplete,
|
|
269
|
+
});
|
|
270
|
+
const nextStep = stepResult.nextStep;
|
|
271
|
+
session = stepResult.session;
|
|
272
|
+
if (selectedRoute && !isRouteComplete) {
|
|
273
|
+
// PHASE 4: RESPONSE GENERATION - Stream message using selected route and step
|
|
274
|
+
// Get last user message
|
|
275
|
+
const lastUserMessage = (0, utils_1.getLastMessageFromHistory)(history);
|
|
276
|
+
// Build response schema for this route (with collect fields from step)
|
|
277
|
+
const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute, nextStep);
|
|
278
|
+
// Check if selected route and next step are defined
|
|
279
|
+
if (!selectedRoute || !nextStep) {
|
|
280
|
+
utils_1.logger.error("[Agent] Selected route or next step is not defined", {
|
|
281
|
+
selectedRoute,
|
|
282
|
+
nextStep,
|
|
283
|
+
});
|
|
284
|
+
throw new Error("Selected route or next step is not defined");
|
|
285
|
+
}
|
|
286
|
+
// Build response prompt
|
|
287
|
+
const responsePrompt = await this.responseEngine.buildResponsePrompt({
|
|
288
|
+
route: selectedRoute,
|
|
289
|
+
currentStep: nextStep,
|
|
290
|
+
rules: selectedRoute.getRules(),
|
|
291
|
+
prohibitions: selectedRoute.getProhibitions(),
|
|
292
|
+
directives: responseDirectives,
|
|
293
|
+
history,
|
|
294
|
+
lastMessage: lastUserMessage,
|
|
295
|
+
agentOptions: this.options,
|
|
296
|
+
// Combine agent and route properties according to the specified logic
|
|
297
|
+
combinedGuidelines: [
|
|
298
|
+
...this.getGuidelines(),
|
|
299
|
+
...selectedRoute.getGuidelines(),
|
|
300
|
+
],
|
|
301
|
+
combinedTerms: this.mergeTerms(this.getTerms(), selectedRoute.getTerms()),
|
|
302
|
+
context: effectiveContext,
|
|
303
|
+
session,
|
|
304
|
+
});
|
|
305
|
+
// Collect available tools for AI
|
|
306
|
+
const availableTools = this.collectAvailableTools(selectedRoute, nextStep);
|
|
307
|
+
// Generate message stream using AI provider
|
|
308
|
+
const stream = this.options.provider.generateMessageStream({
|
|
309
|
+
prompt: responsePrompt,
|
|
310
|
+
history,
|
|
311
|
+
context: effectiveContext,
|
|
312
|
+
tools: availableTools,
|
|
313
|
+
signal,
|
|
314
|
+
parameters: {
|
|
315
|
+
jsonSchema: responseSchema,
|
|
316
|
+
schemaName: "response_stream_output",
|
|
317
|
+
},
|
|
318
|
+
});
|
|
319
|
+
// Stream chunks to caller
|
|
320
|
+
for await (const chunk of stream) {
|
|
321
|
+
let toolCalls = undefined;
|
|
322
|
+
// Extract tool calls from AI response on final chunk
|
|
323
|
+
if (chunk.done && chunk.structured?.toolCalls) {
|
|
324
|
+
toolCalls = chunk.structured.toolCalls;
|
|
325
|
+
// Execute dynamic tool calls
|
|
326
|
+
if (toolCalls.length > 0) {
|
|
327
|
+
utils_1.logger.debug(`[Agent] Executing ${toolCalls.length} dynamic tool calls`);
|
|
328
|
+
for (const toolCall of toolCalls) {
|
|
329
|
+
const tool = this.findAvailableTool(toolCall.toolName, selectedRoute);
|
|
330
|
+
if (!tool) {
|
|
331
|
+
utils_1.logger.warn(`[Agent] Tool not found: ${toolCall.toolName}`);
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
const toolExecutor = new ToolExecutor_1.ToolExecutor();
|
|
335
|
+
const result = await toolExecutor.executeTool({
|
|
336
|
+
tool: tool,
|
|
337
|
+
context: effectiveContext,
|
|
338
|
+
updateContext: this.updateContext.bind(this),
|
|
339
|
+
history,
|
|
340
|
+
data: session.data,
|
|
341
|
+
toolArguments: toolCall.arguments,
|
|
342
|
+
});
|
|
343
|
+
// Update context with tool results
|
|
344
|
+
if (result.contextUpdate) {
|
|
345
|
+
await this.updateContext(result.contextUpdate);
|
|
346
|
+
}
|
|
347
|
+
// Update collected data with tool results
|
|
348
|
+
if (result.dataUpdate) {
|
|
349
|
+
session = await this.updateData(session, result.dataUpdate);
|
|
350
|
+
utils_1.logger.debug(`[Agent] Tool updated collected data:`, result.dataUpdate);
|
|
351
|
+
}
|
|
352
|
+
utils_1.logger.debug(`[Agent] Executed dynamic tool: ${result.toolName} (success: ${result.success})`);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
// TOOL LOOP: Allow AI to make follow-up tool calls after initial tool execution (streaming)
|
|
357
|
+
const MAX_TOOL_LOOPS = 5;
|
|
358
|
+
let toolLoopCount = 0;
|
|
359
|
+
let hasToolCalls = toolCalls && toolCalls.length > 0;
|
|
360
|
+
while (hasToolCalls && toolLoopCount < MAX_TOOL_LOOPS) {
|
|
361
|
+
toolLoopCount++;
|
|
362
|
+
utils_1.logger.debug(`[Agent] Starting streaming tool loop ${toolLoopCount}/${MAX_TOOL_LOOPS}`);
|
|
363
|
+
// Add tool execution results to history so AI knows what happened
|
|
364
|
+
const toolResultsEvents = [];
|
|
365
|
+
for (const toolCall of toolCalls || []) {
|
|
366
|
+
const tool = this.findAvailableTool(toolCall.toolName, selectedRoute);
|
|
367
|
+
if (tool) {
|
|
368
|
+
toolResultsEvents.push({
|
|
369
|
+
kind: history_1.EventKind.TOOL,
|
|
370
|
+
source: history_1.MessageRole.AGENT,
|
|
371
|
+
timestamp: new Date().toISOString(),
|
|
372
|
+
data: {
|
|
373
|
+
tool_calls: [
|
|
374
|
+
{
|
|
375
|
+
tool_id: toolCall.toolName,
|
|
376
|
+
arguments: toolCall.arguments,
|
|
377
|
+
result: {
|
|
378
|
+
data: "Tool executed successfully",
|
|
379
|
+
},
|
|
380
|
+
},
|
|
381
|
+
],
|
|
382
|
+
},
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
// Create updated history with tool results
|
|
387
|
+
const updatedHistory = [...history, ...toolResultsEvents];
|
|
388
|
+
// Make follow-up streaming AI call to see if more tools are needed
|
|
389
|
+
const followUpStream = this.options.provider.generateMessageStream({
|
|
390
|
+
prompt: responsePrompt,
|
|
391
|
+
history: updatedHistory,
|
|
392
|
+
context: effectiveContext,
|
|
393
|
+
tools: availableTools,
|
|
394
|
+
parameters: {
|
|
395
|
+
jsonSchema: responseSchema,
|
|
396
|
+
schemaName: "tool_followup",
|
|
397
|
+
},
|
|
398
|
+
signal,
|
|
399
|
+
});
|
|
400
|
+
let followUpToolCalls;
|
|
401
|
+
for await (const followUpChunk of followUpStream) {
|
|
402
|
+
// Extract tool calls from follow-up stream
|
|
403
|
+
if (followUpChunk.done && followUpChunk.structured?.toolCalls) {
|
|
404
|
+
followUpToolCalls = followUpChunk.structured.toolCalls;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
hasToolCalls = followUpToolCalls && followUpToolCalls.length > 0;
|
|
408
|
+
if (hasToolCalls) {
|
|
409
|
+
utils_1.logger.debug(`[Agent] Follow-up streaming call produced ${followUpToolCalls.length} additional tool calls`);
|
|
410
|
+
// Execute the follow-up tool calls
|
|
411
|
+
for (const toolCall of followUpToolCalls) {
|
|
412
|
+
const tool = this.findAvailableTool(toolCall.toolName, selectedRoute);
|
|
413
|
+
if (!tool) {
|
|
414
|
+
utils_1.logger.warn(`[Agent] Tool not found in streaming follow-up: ${toolCall.toolName}`);
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
417
|
+
const toolExecutor = new ToolExecutor_1.ToolExecutor();
|
|
418
|
+
const result = await toolExecutor.executeTool({
|
|
419
|
+
tool: tool,
|
|
420
|
+
context: effectiveContext,
|
|
421
|
+
updateContext: this.updateContext.bind(this),
|
|
422
|
+
history: updatedHistory,
|
|
423
|
+
data: session.data,
|
|
424
|
+
toolArguments: toolCall.arguments,
|
|
425
|
+
});
|
|
426
|
+
// Update context with follow-up tool results
|
|
427
|
+
if (result.contextUpdate) {
|
|
428
|
+
await this.updateContext(result.contextUpdate);
|
|
429
|
+
}
|
|
430
|
+
if (result.dataUpdate) {
|
|
431
|
+
session = await this.updateData(session, result.dataUpdate);
|
|
432
|
+
utils_1.logger.debug(`[Agent] Streaming follow-up tool updated collected data:`, result.dataUpdate);
|
|
433
|
+
}
|
|
434
|
+
utils_1.logger.debug(`[Agent] Executed streaming follow-up tool: ${result.toolName} (success: ${result.success})`);
|
|
435
|
+
}
|
|
436
|
+
// Update toolCalls for next iteration
|
|
437
|
+
toolCalls = followUpToolCalls;
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
utils_1.logger.debug(`[Agent] Streaming tool loop completed after ${toolLoopCount} iterations`);
|
|
441
|
+
// Update toolCalls for final response
|
|
442
|
+
toolCalls = followUpToolCalls || [];
|
|
443
|
+
break;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
if (toolLoopCount >= MAX_TOOL_LOOPS) {
|
|
447
|
+
utils_1.logger.warn(`[Agent] Streaming tool loop limit reached (${MAX_TOOL_LOOPS}), stopping`);
|
|
448
|
+
}
|
|
449
|
+
// Extract collected data on final chunk
|
|
450
|
+
if (chunk.done && chunk.structured && nextStep.collect) {
|
|
451
|
+
const collectedData = {};
|
|
452
|
+
// The structured response includes both base fields and collected extraction fields
|
|
453
|
+
const structuredData = chunk.structured;
|
|
454
|
+
for (const field of nextStep.collect) {
|
|
455
|
+
if (field in structuredData) {
|
|
456
|
+
collectedData[field] = structuredData[field];
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
// Merge collected data into session
|
|
460
|
+
if (Object.keys(collectedData).length > 0) {
|
|
461
|
+
session = await this.updateData(session, collectedData);
|
|
462
|
+
utils_1.logger.debug(`[Agent] Collected data:`, collectedData);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
// Extract any additional data from structured response on final chunk
|
|
466
|
+
if (chunk.done &&
|
|
467
|
+
chunk.structured &&
|
|
468
|
+
typeof chunk.structured === "object" &&
|
|
469
|
+
"contextUpdate" in chunk.structured) {
|
|
470
|
+
await this.updateContext(chunk.structured
|
|
471
|
+
.contextUpdate);
|
|
472
|
+
}
|
|
473
|
+
// Auto-save session step on final chunk
|
|
474
|
+
if (chunk.done &&
|
|
475
|
+
this.persistenceManager &&
|
|
476
|
+
session.id &&
|
|
477
|
+
this.options.persistence?.autoSave !== false) {
|
|
478
|
+
await this.persistenceManager.saveSessionState(session.id, session);
|
|
479
|
+
utils_1.logger.debug(`[Agent] Auto-saved session step to persistence: ${session.id}`);
|
|
480
|
+
}
|
|
481
|
+
// Execute finalize function on final chunk
|
|
482
|
+
if (chunk.done && session.currentRoute && session.currentStep) {
|
|
483
|
+
const currentRoute = this.routes.find((r) => r.id === session.currentRoute?.id);
|
|
484
|
+
if (currentRoute) {
|
|
485
|
+
const currentStep = currentRoute.getStep(session.currentStep.id);
|
|
486
|
+
if (currentStep?.finalize) {
|
|
487
|
+
utils_1.logger.debug(`[Agent] Executing finalize for step: ${currentStep.id}`);
|
|
488
|
+
await this.executePrepareFinalize(currentStep.finalize, effectiveContext, session.data, currentRoute, currentStep);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
// Update current session if we have one
|
|
493
|
+
if (chunk.done && this.currentSession) {
|
|
494
|
+
this.currentSession = session;
|
|
495
|
+
}
|
|
496
|
+
yield {
|
|
497
|
+
delta: chunk.delta,
|
|
498
|
+
accumulated: chunk.accumulated,
|
|
499
|
+
done: chunk.done,
|
|
500
|
+
session, // Return updated session
|
|
501
|
+
toolCalls,
|
|
502
|
+
isRouteComplete,
|
|
503
|
+
metadata: chunk.metadata,
|
|
504
|
+
structured: chunk.structured,
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
else if (isRouteComplete && selectedRoute) {
|
|
509
|
+
// Route is complete - generate completion message then check for onComplete transition
|
|
510
|
+
const lastUserMessage = (0, utils_1.getLastMessageFromHistory)(history);
|
|
511
|
+
// Get endStep spec from route
|
|
512
|
+
const endStepSpec = selectedRoute.endStepSpec;
|
|
513
|
+
// Create a temporary step for completion message generation using endStep configuration
|
|
514
|
+
const completionStep = new Step_1.Step(selectedRoute.id, {
|
|
515
|
+
description: endStepSpec.description,
|
|
516
|
+
id: endStepSpec.id || constants_1.END_ROUTE_ID,
|
|
517
|
+
collect: endStepSpec.collect,
|
|
518
|
+
requires: endStepSpec.requires,
|
|
519
|
+
prompt: endStepSpec.prompt ||
|
|
520
|
+
"Summarize what was accomplished and confirm completion based on the conversation history and collected data",
|
|
521
|
+
});
|
|
522
|
+
// Build response schema for completion
|
|
523
|
+
const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute, completionStep);
|
|
524
|
+
const templateContext = {
|
|
525
|
+
context: effectiveContext,
|
|
526
|
+
session,
|
|
527
|
+
history,
|
|
528
|
+
};
|
|
529
|
+
// Build completion response prompt
|
|
530
|
+
const completionPrompt = await this.responseEngine.buildResponsePrompt({
|
|
531
|
+
route: selectedRoute,
|
|
532
|
+
currentStep: completionStep,
|
|
533
|
+
rules: selectedRoute.getRules(),
|
|
534
|
+
prohibitions: selectedRoute.getProhibitions(),
|
|
535
|
+
directives: undefined, // No directives for completion
|
|
536
|
+
history,
|
|
537
|
+
lastMessage: lastUserMessage,
|
|
538
|
+
agentOptions: this.options,
|
|
539
|
+
// Combine agent and route properties according to the specified logic
|
|
540
|
+
combinedGuidelines: [
|
|
541
|
+
...this.getGuidelines(),
|
|
542
|
+
...selectedRoute.getGuidelines(),
|
|
543
|
+
],
|
|
544
|
+
combinedTerms: this.mergeTerms(this.getTerms(), selectedRoute.getTerms()),
|
|
545
|
+
context: effectiveContext,
|
|
546
|
+
session,
|
|
547
|
+
});
|
|
548
|
+
// Stream completion message using AI provider
|
|
549
|
+
const stream = this.options.provider.generateMessageStream({
|
|
550
|
+
prompt: completionPrompt,
|
|
551
|
+
history,
|
|
552
|
+
context: effectiveContext,
|
|
553
|
+
signal,
|
|
554
|
+
parameters: {
|
|
555
|
+
jsonSchema: responseSchema,
|
|
556
|
+
schemaName: "completion_message_stream",
|
|
557
|
+
},
|
|
558
|
+
});
|
|
559
|
+
utils_1.logger.debug(`[Agent] Streaming completion message for route: ${selectedRoute.title}`);
|
|
560
|
+
// Check for onComplete transition
|
|
561
|
+
const transitionConfig = await selectedRoute.evaluateOnComplete({ data: session.data }, effectiveContext);
|
|
562
|
+
if (transitionConfig) {
|
|
563
|
+
// Find target route by ID or title
|
|
564
|
+
const targetRoute = this.routes.find((r) => r.id === transitionConfig.nextStep ||
|
|
565
|
+
r.title === transitionConfig.nextStep);
|
|
566
|
+
if (targetRoute) {
|
|
567
|
+
const renderedCondition = await (0, utils_1.render)(transitionConfig.condition, templateContext);
|
|
568
|
+
// Set pending transition in session
|
|
569
|
+
session = {
|
|
570
|
+
...session,
|
|
571
|
+
pendingTransition: {
|
|
572
|
+
targetRouteId: targetRoute.id,
|
|
573
|
+
condition: renderedCondition,
|
|
574
|
+
reason: "route_complete",
|
|
575
|
+
},
|
|
576
|
+
};
|
|
577
|
+
utils_1.logger.debug(`[Agent] Route ${selectedRoute.title} completed with pending transition to: ${targetRoute.title}`);
|
|
578
|
+
}
|
|
579
|
+
else {
|
|
580
|
+
utils_1.logger.warn(`[Agent] Route ${selectedRoute.title} completed but target route not found: ${transitionConfig.nextStep}`);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
// Set step to END_ROUTE marker
|
|
584
|
+
session = (0, utils_1.enterStep)(session, constants_1.END_ROUTE_ID, "Route completed");
|
|
585
|
+
utils_1.logger.debug(`[Agent] Route ${selectedRoute.title} completed. Entered END_ROUTE step.`);
|
|
586
|
+
// Stream completion chunks
|
|
587
|
+
for await (const chunk of stream) {
|
|
588
|
+
// Update current session if we have one
|
|
589
|
+
if (chunk.done && this.currentSession) {
|
|
590
|
+
this.currentSession = session;
|
|
591
|
+
}
|
|
592
|
+
yield {
|
|
593
|
+
delta: chunk.delta,
|
|
594
|
+
accumulated: chunk.accumulated,
|
|
595
|
+
done: chunk.done,
|
|
596
|
+
session,
|
|
597
|
+
toolCalls: undefined,
|
|
598
|
+
isRouteComplete: true,
|
|
599
|
+
metadata: chunk.metadata,
|
|
600
|
+
structured: chunk.structured,
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
else {
|
|
605
|
+
// Fallback: No routes defined, stream a simple response
|
|
606
|
+
const fallbackPrompt = await this.responseEngine.buildFallbackPrompt({
|
|
607
|
+
history,
|
|
608
|
+
agentOptions: this.options,
|
|
609
|
+
terms: this.terms,
|
|
610
|
+
guidelines: this.guidelines,
|
|
611
|
+
context: effectiveContext,
|
|
612
|
+
session,
|
|
613
|
+
});
|
|
614
|
+
const stream = this.options.provider.generateMessageStream({
|
|
615
|
+
prompt: fallbackPrompt,
|
|
616
|
+
history,
|
|
617
|
+
context: effectiveContext,
|
|
618
|
+
signal,
|
|
619
|
+
parameters: {
|
|
620
|
+
jsonSchema: {
|
|
621
|
+
type: "object",
|
|
622
|
+
properties: {
|
|
623
|
+
message: { type: "string" },
|
|
624
|
+
},
|
|
625
|
+
required: ["message"],
|
|
626
|
+
additionalProperties: false,
|
|
627
|
+
},
|
|
628
|
+
schemaName: "fallback_stream_response",
|
|
629
|
+
},
|
|
630
|
+
});
|
|
631
|
+
for await (const chunk of stream) {
|
|
632
|
+
// Update current session if we have one
|
|
633
|
+
if (chunk.done && this.currentSession) {
|
|
634
|
+
this.currentSession = session;
|
|
635
|
+
}
|
|
636
|
+
yield {
|
|
637
|
+
delta: chunk.delta,
|
|
638
|
+
accumulated: chunk.accumulated,
|
|
639
|
+
done: chunk.done,
|
|
640
|
+
session, // Return updated session
|
|
641
|
+
toolCalls: undefined,
|
|
642
|
+
isRouteComplete: false,
|
|
643
|
+
metadata: chunk.metadata,
|
|
644
|
+
structured: chunk.structured,
|
|
645
|
+
};
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* Generate a response based on history and context
|
|
651
|
+
*/
|
|
652
|
+
async respond(params) {
|
|
653
|
+
const { history: simpleHistory, contextOverride, signal } = params;
|
|
654
|
+
const history = (0, utils_1.normalizeHistory)(simpleHistory);
|
|
655
|
+
// Get current context (may fetch from provider)
|
|
656
|
+
let currentContext = await this.getContext();
|
|
657
|
+
// Call beforeRespond hook if configured
|
|
658
|
+
if (this.options.hooks?.beforeRespond && currentContext !== undefined) {
|
|
659
|
+
currentContext = await this.options.hooks.beforeRespond(currentContext);
|
|
660
|
+
// Update stored context with the result from beforeRespond
|
|
661
|
+
this.context = currentContext;
|
|
662
|
+
}
|
|
663
|
+
// Merge context with override
|
|
664
|
+
const effectiveContext = {
|
|
665
|
+
...currentContext,
|
|
666
|
+
...contextOverride,
|
|
667
|
+
};
|
|
668
|
+
// Initialize or get session (use current session if available)
|
|
669
|
+
let session = (0, utils_1.cloneDeep)(params.session) ||
|
|
670
|
+
(0, utils_1.cloneDeep)(this.currentSession) ||
|
|
671
|
+
(await this.session.getOrCreate());
|
|
672
|
+
// PHASE 1: PREPARE - Execute prepare function if current step has one
|
|
673
|
+
if (session.currentRoute && session.currentStep) {
|
|
674
|
+
const currentRoute = this.routes.find((r) => r.id === session.currentRoute?.id);
|
|
675
|
+
if (currentRoute) {
|
|
676
|
+
const currentStep = currentRoute.getStep(session.currentStep.id);
|
|
677
|
+
if (currentStep?.prepare) {
|
|
678
|
+
utils_1.logger.debug(`[Agent] Executing prepare for step: ${currentStep.id}`);
|
|
679
|
+
await this.executePrepareFinalize(currentStep.prepare, effectiveContext, session.data, currentRoute, currentStep);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
// PHASE 2: ROUTING + STEP SELECTION - Determine which route and step to use (combined)
|
|
684
|
+
let selectedRoute;
|
|
685
|
+
let responseDirectives;
|
|
686
|
+
let selectedStep;
|
|
687
|
+
let isRouteComplete = false;
|
|
688
|
+
// Check for pending transition from previous route completion
|
|
689
|
+
if (session.pendingTransition) {
|
|
690
|
+
const targetRoute = this.routes.find((r) => r.id === session.pendingTransition?.targetRouteId);
|
|
691
|
+
if (targetRoute) {
|
|
692
|
+
utils_1.logger.debug(`[Agent] Auto-transitioning from pending transition to route: ${targetRoute.title}`);
|
|
693
|
+
// Clear pending transition and enter new route
|
|
694
|
+
session = {
|
|
695
|
+
...session,
|
|
696
|
+
pendingTransition: undefined,
|
|
697
|
+
};
|
|
698
|
+
session = (0, utils_1.enterRoute)(session, targetRoute.id, targetRoute.title);
|
|
699
|
+
// Merge initial data if available
|
|
700
|
+
if (targetRoute.initialData) {
|
|
701
|
+
session = (0, utils_1.mergeCollected)(session, targetRoute.initialData);
|
|
702
|
+
}
|
|
703
|
+
selectedRoute = targetRoute;
|
|
704
|
+
}
|
|
705
|
+
else {
|
|
706
|
+
utils_1.logger.warn(`[Agent] Pending transition target route not found: ${session.pendingTransition.targetRouteId}`);
|
|
707
|
+
// Clear invalid transition
|
|
708
|
+
session = {
|
|
709
|
+
...session,
|
|
710
|
+
pendingTransition: undefined,
|
|
711
|
+
};
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
// If no pending transition or transition handled, do normal routing
|
|
715
|
+
if (this.routes.length > 0 && !selectedRoute) {
|
|
716
|
+
const orchestration = await this.routingEngine.decideRouteAndStep({
|
|
717
|
+
routes: this.routes,
|
|
718
|
+
session,
|
|
719
|
+
history,
|
|
720
|
+
agentOptions: this.options,
|
|
721
|
+
provider: this.options.provider,
|
|
722
|
+
context: effectiveContext,
|
|
723
|
+
signal,
|
|
724
|
+
});
|
|
725
|
+
selectedRoute = orchestration.selectedRoute;
|
|
726
|
+
selectedStep = orchestration.selectedStep;
|
|
727
|
+
responseDirectives = orchestration.responseDirectives;
|
|
728
|
+
session = orchestration.session;
|
|
729
|
+
isRouteComplete = orchestration.isRouteComplete || false;
|
|
730
|
+
// Log if route is complete
|
|
731
|
+
if (isRouteComplete) {
|
|
732
|
+
utils_1.logger.debug(`[Agent] Route complete: all required data collected, END_ROUTE reached`);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
// PHASE 3: DETERMINE NEXT STEP - Use step from combined decision or get initial step
|
|
736
|
+
let message;
|
|
737
|
+
let toolCalls = undefined;
|
|
738
|
+
let responsePrompt;
|
|
739
|
+
let availableTools = [];
|
|
740
|
+
let responseSchema;
|
|
741
|
+
let nextStep;
|
|
742
|
+
// Get last user message (needed for both route and completion handling)
|
|
743
|
+
const lastUserMessage = (0, utils_1.getLastMessageFromHistory)(history);
|
|
744
|
+
if (selectedRoute && !isRouteComplete) {
|
|
745
|
+
// If we have a selected step from the combined routing decision, use it
|
|
746
|
+
if (selectedStep) {
|
|
747
|
+
nextStep = selectedStep;
|
|
748
|
+
}
|
|
749
|
+
else {
|
|
750
|
+
// New route or no step selected - get initial step or first valid step
|
|
751
|
+
const candidates = this.routingEngine.getCandidateSteps(selectedRoute, undefined, session.data || {});
|
|
752
|
+
if (candidates.length > 0) {
|
|
753
|
+
nextStep = candidates[0].step;
|
|
754
|
+
utils_1.logger.debug(`[Agent] Using first valid step: ${nextStep.id} for new route`);
|
|
755
|
+
}
|
|
756
|
+
else {
|
|
757
|
+
// Fallback to initial step even if it should be skipped
|
|
758
|
+
nextStep = selectedRoute.initialStep;
|
|
759
|
+
utils_1.logger.warn(`[Agent] No valid steps found, using initial step: ${nextStep.id}`);
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
// Update session with next step
|
|
763
|
+
session = (0, utils_1.enterStep)(session, nextStep.id, nextStep.description);
|
|
764
|
+
utils_1.logger.debug(`[Agent] Entered step: ${nextStep.id}`);
|
|
765
|
+
// PHASE 4: RESPONSE GENERATION - Generate message using selected route and step
|
|
766
|
+
// Get last user message
|
|
767
|
+
const lastUserMessage = (0, utils_1.getLastMessageFromHistory)(history);
|
|
768
|
+
// Build response schema for this route (with collect fields from step)
|
|
769
|
+
responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute, nextStep);
|
|
770
|
+
// Build response prompt
|
|
771
|
+
responsePrompt = await this.responseEngine.buildResponsePrompt({
|
|
772
|
+
route: selectedRoute,
|
|
773
|
+
currentStep: nextStep,
|
|
774
|
+
rules: selectedRoute.getRules(),
|
|
775
|
+
prohibitions: selectedRoute.getProhibitions(),
|
|
776
|
+
directives: responseDirectives,
|
|
777
|
+
history,
|
|
778
|
+
lastMessage: lastUserMessage,
|
|
779
|
+
agentOptions: this.options,
|
|
780
|
+
// Combine agent and route properties according to the specified logic
|
|
781
|
+
combinedGuidelines: [
|
|
782
|
+
...this.getGuidelines(),
|
|
783
|
+
...selectedRoute.getGuidelines(),
|
|
784
|
+
],
|
|
785
|
+
combinedTerms: this.mergeTerms(this.getTerms(), selectedRoute.getTerms()),
|
|
786
|
+
context: effectiveContext,
|
|
787
|
+
session,
|
|
788
|
+
});
|
|
789
|
+
// Collect available tools for AI
|
|
790
|
+
availableTools = this.collectAvailableTools(selectedRoute, nextStep);
|
|
791
|
+
}
|
|
792
|
+
else {
|
|
793
|
+
// No route selected - generate basic response without route context
|
|
794
|
+
utils_1.logger.debug(`[Agent] No route selected, generating basic response`);
|
|
795
|
+
// Build basic response prompt without route context
|
|
796
|
+
responsePrompt = await this.responseEngine.buildFallbackPrompt({
|
|
797
|
+
history,
|
|
798
|
+
agentOptions: this.options,
|
|
799
|
+
terms: this.getTerms(),
|
|
800
|
+
guidelines: this.getGuidelines(),
|
|
801
|
+
context: effectiveContext,
|
|
802
|
+
session,
|
|
803
|
+
});
|
|
804
|
+
// Use agent-level tools only
|
|
805
|
+
availableTools = [...this.tools];
|
|
806
|
+
responseSchema = undefined;
|
|
807
|
+
}
|
|
808
|
+
// Generate message using AI provider (common for both route and no-route cases)
|
|
809
|
+
const result = await this.options.provider.generateMessage({
|
|
810
|
+
prompt: responsePrompt,
|
|
811
|
+
history,
|
|
812
|
+
context: effectiveContext,
|
|
813
|
+
tools: availableTools,
|
|
814
|
+
signal,
|
|
815
|
+
parameters: responseSchema
|
|
816
|
+
? {
|
|
817
|
+
jsonSchema: responseSchema,
|
|
818
|
+
schemaName: "response_output",
|
|
819
|
+
}
|
|
820
|
+
: undefined,
|
|
821
|
+
});
|
|
822
|
+
message = result.structured?.message || result.message;
|
|
823
|
+
// Process dynamic tool calls from AI response (common for both route and no-route cases)
|
|
824
|
+
if (result.structured?.toolCalls) {
|
|
825
|
+
toolCalls = result.structured.toolCalls;
|
|
826
|
+
// Execute dynamic tool calls
|
|
827
|
+
if (toolCalls.length > 0) {
|
|
828
|
+
utils_1.logger.debug(`[Agent] Executing ${toolCalls.length} dynamic tool calls`);
|
|
829
|
+
for (const toolCall of toolCalls) {
|
|
830
|
+
const tool = this.findAvailableTool(toolCall.toolName, selectedRoute);
|
|
831
|
+
if (!tool) {
|
|
832
|
+
utils_1.logger.warn(`[Agent] Tool not found: ${toolCall.toolName}`);
|
|
833
|
+
continue;
|
|
834
|
+
}
|
|
835
|
+
const toolExecutor = new ToolExecutor_1.ToolExecutor();
|
|
836
|
+
const toolResult = await toolExecutor.executeTool({
|
|
837
|
+
tool: tool,
|
|
838
|
+
context: effectiveContext,
|
|
839
|
+
updateContext: this.updateContext.bind(this),
|
|
840
|
+
history,
|
|
841
|
+
data: session.data,
|
|
842
|
+
toolArguments: toolCall.arguments,
|
|
843
|
+
});
|
|
844
|
+
// Update context with tool results
|
|
845
|
+
if (toolResult.contextUpdate) {
|
|
846
|
+
await this.updateContext(toolResult.contextUpdate);
|
|
847
|
+
}
|
|
848
|
+
// Update collected data with tool results
|
|
849
|
+
if (toolResult.dataUpdate) {
|
|
850
|
+
session = await this.updateData(session, toolResult.dataUpdate);
|
|
851
|
+
utils_1.logger.debug(`[Agent] Tool updated collected data:`, toolResult.dataUpdate);
|
|
852
|
+
}
|
|
853
|
+
utils_1.logger.debug(`[Agent] Executed dynamic tool: ${toolResult.toolName} (success: ${toolResult.success})`);
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
// TOOL LOOP: Allow AI to make follow-up tool calls after initial tool execution
|
|
858
|
+
const MAX_TOOL_LOOPS = 5;
|
|
859
|
+
let toolLoopCount = 0;
|
|
860
|
+
let hasToolCalls = toolCalls && toolCalls.length > 0;
|
|
861
|
+
while (hasToolCalls && toolLoopCount < MAX_TOOL_LOOPS) {
|
|
862
|
+
toolLoopCount++;
|
|
863
|
+
utils_1.logger.debug(`[Agent] Starting tool loop ${toolLoopCount}/${MAX_TOOL_LOOPS}`);
|
|
864
|
+
// Add tool execution results to history so AI knows what happened
|
|
865
|
+
const toolResultsEvents = [];
|
|
866
|
+
for (const toolCall of toolCalls || []) {
|
|
867
|
+
const tool = this.findAvailableTool(toolCall.toolName, selectedRoute);
|
|
868
|
+
if (tool) {
|
|
869
|
+
toolResultsEvents.push({
|
|
870
|
+
kind: history_1.EventKind.TOOL,
|
|
871
|
+
source: history_1.MessageRole.AGENT,
|
|
872
|
+
timestamp: new Date().toISOString(),
|
|
873
|
+
data: {
|
|
874
|
+
tool_calls: [
|
|
875
|
+
{
|
|
876
|
+
tool_id: toolCall.toolName,
|
|
877
|
+
arguments: toolCall.arguments,
|
|
878
|
+
result: {
|
|
879
|
+
data: "Tool executed successfully",
|
|
880
|
+
},
|
|
881
|
+
},
|
|
882
|
+
],
|
|
883
|
+
},
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
// Create updated history with tool results
|
|
888
|
+
const updatedHistory = [...history, ...toolResultsEvents];
|
|
889
|
+
// Make follow-up AI call to see if more tools are needed
|
|
890
|
+
const followUpResult = await this.options.provider.generateMessage({
|
|
891
|
+
prompt: responsePrompt,
|
|
892
|
+
history: updatedHistory,
|
|
893
|
+
context: effectiveContext,
|
|
894
|
+
tools: availableTools,
|
|
895
|
+
parameters: {
|
|
896
|
+
jsonSchema: responseSchema,
|
|
897
|
+
schemaName: "tool_followup",
|
|
898
|
+
},
|
|
899
|
+
signal,
|
|
900
|
+
});
|
|
901
|
+
// Check if follow-up call has more tool calls
|
|
902
|
+
const followUpToolCalls = followUpResult.structured?.toolCalls;
|
|
903
|
+
hasToolCalls = followUpToolCalls && followUpToolCalls.length > 0;
|
|
904
|
+
if (hasToolCalls) {
|
|
905
|
+
utils_1.logger.debug(`[Agent] Follow-up call produced ${followUpToolCalls.length} additional tool calls`);
|
|
906
|
+
// Execute the follow-up tool calls
|
|
907
|
+
for (const toolCall of followUpToolCalls) {
|
|
908
|
+
const tool = this.findAvailableTool(toolCall.toolName, selectedRoute);
|
|
909
|
+
if (!tool) {
|
|
910
|
+
utils_1.logger.warn(`[Agent] Tool not found in follow-up: ${toolCall.toolName}`);
|
|
911
|
+
continue;
|
|
912
|
+
}
|
|
913
|
+
const toolExecutor = new ToolExecutor_1.ToolExecutor();
|
|
914
|
+
const toolResult = await toolExecutor.executeTool({
|
|
915
|
+
tool: tool,
|
|
916
|
+
context: effectiveContext,
|
|
917
|
+
updateContext: this.updateContext.bind(this),
|
|
918
|
+
history: updatedHistory,
|
|
919
|
+
data: session.data,
|
|
920
|
+
toolArguments: toolCall.arguments,
|
|
921
|
+
});
|
|
922
|
+
// Update context with follow-up tool results
|
|
923
|
+
if (toolResult.contextUpdate) {
|
|
924
|
+
await this.updateContext(toolResult.contextUpdate);
|
|
925
|
+
}
|
|
926
|
+
if (toolResult.dataUpdate) {
|
|
927
|
+
session = await this.updateData(session, toolResult.dataUpdate);
|
|
928
|
+
utils_1.logger.debug(`[Agent] Follow-up tool updated collected data:`, toolResult.dataUpdate);
|
|
929
|
+
}
|
|
930
|
+
utils_1.logger.debug(`[Agent] Executed follow-up tool: ${toolResult.toolName} (success: ${toolResult.success})`);
|
|
931
|
+
}
|
|
932
|
+
// Update toolCalls for next iteration or final response
|
|
933
|
+
toolCalls = followUpToolCalls;
|
|
934
|
+
}
|
|
935
|
+
else {
|
|
936
|
+
utils_1.logger.debug(`[Agent] Tool loop completed after ${toolLoopCount} iterations`);
|
|
937
|
+
// Update final message and toolCalls from follow-up result if no more tools
|
|
938
|
+
message = followUpResult.structured?.message || followUpResult.message;
|
|
939
|
+
toolCalls = followUpToolCalls || [];
|
|
940
|
+
break;
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
if (toolLoopCount >= MAX_TOOL_LOOPS) {
|
|
944
|
+
utils_1.logger.warn(`[Agent] Tool loop limit reached (${MAX_TOOL_LOOPS}), stopping`);
|
|
945
|
+
}
|
|
946
|
+
// Extract collected data from final response (only for route-based interactions)
|
|
947
|
+
if (selectedRoute && result.structured && nextStep?.collect) {
|
|
948
|
+
const collectedData = {};
|
|
949
|
+
// The structured response includes both base fields and collected extraction fields
|
|
950
|
+
const structuredData = result.structured;
|
|
951
|
+
for (const field of nextStep.collect) {
|
|
952
|
+
if (field in structuredData) {
|
|
953
|
+
collectedData[field] = structuredData[field];
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
// Merge collected data into session
|
|
957
|
+
if (Object.keys(collectedData).length > 0) {
|
|
958
|
+
session = await this.updateData(session, collectedData);
|
|
959
|
+
utils_1.logger.debug(`[Agent] Collected data:`, collectedData);
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
// Extract any additional data from structured response
|
|
963
|
+
if (result.structured &&
|
|
964
|
+
typeof result.structured === "object" &&
|
|
965
|
+
"contextUpdate" in result.structured) {
|
|
966
|
+
await this.updateContext(result.structured
|
|
967
|
+
.contextUpdate);
|
|
968
|
+
}
|
|
969
|
+
// Handle route completion if route is complete
|
|
970
|
+
if (isRouteComplete) {
|
|
971
|
+
// Route is complete - generate completion message then check for onComplete transition
|
|
972
|
+
// Get endStep spec from route
|
|
973
|
+
const endStepSpec = selectedRoute.endStepSpec;
|
|
974
|
+
// Create a temporary step for completion message generation using endStep configuration
|
|
975
|
+
const completionStep = new Step_1.Step(selectedRoute.id, {
|
|
976
|
+
description: endStepSpec.description,
|
|
977
|
+
id: endStepSpec.id || constants_1.END_ROUTE_ID,
|
|
978
|
+
collect: endStepSpec.collect,
|
|
979
|
+
requires: endStepSpec.requires,
|
|
980
|
+
prompt: endStepSpec.prompt ||
|
|
981
|
+
"Summarize what was accomplished and confirm completion based on the conversation history and collected data",
|
|
982
|
+
});
|
|
983
|
+
// Build response schema for completion
|
|
984
|
+
const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute, completionStep);
|
|
985
|
+
const templateContext = {
|
|
986
|
+
context: effectiveContext,
|
|
987
|
+
session,
|
|
988
|
+
history,
|
|
989
|
+
};
|
|
990
|
+
if (!selectedRoute) {
|
|
991
|
+
throw new Error("Selected route is not defined");
|
|
992
|
+
}
|
|
993
|
+
// Build completion response prompt
|
|
994
|
+
const completionPrompt = await this.responseEngine.buildResponsePrompt({
|
|
995
|
+
route: selectedRoute,
|
|
996
|
+
currentStep: completionStep,
|
|
997
|
+
rules: selectedRoute.getRules(),
|
|
998
|
+
prohibitions: selectedRoute.getProhibitions(),
|
|
999
|
+
directives: undefined, // No directives for completion
|
|
1000
|
+
history,
|
|
1001
|
+
lastMessage: lastUserMessage,
|
|
1002
|
+
agentOptions: this.options,
|
|
1003
|
+
// Combine agent and route properties according to the specified logic
|
|
1004
|
+
combinedGuidelines: [
|
|
1005
|
+
...this.getGuidelines(),
|
|
1006
|
+
...selectedRoute.getGuidelines(),
|
|
1007
|
+
],
|
|
1008
|
+
combinedTerms: this.mergeTerms(this.getTerms(), selectedRoute.getTerms()),
|
|
1009
|
+
context: effectiveContext,
|
|
1010
|
+
session,
|
|
1011
|
+
});
|
|
1012
|
+
// Generate completion message using AI provider
|
|
1013
|
+
const completionResult = await this.options.provider.generateMessage({
|
|
1014
|
+
prompt: completionPrompt,
|
|
1015
|
+
history,
|
|
1016
|
+
context: effectiveContext,
|
|
1017
|
+
signal,
|
|
1018
|
+
parameters: {
|
|
1019
|
+
jsonSchema: responseSchema,
|
|
1020
|
+
schemaName: "completion_message",
|
|
1021
|
+
},
|
|
1022
|
+
});
|
|
1023
|
+
message =
|
|
1024
|
+
completionResult.structured?.message || completionResult.message;
|
|
1025
|
+
utils_1.logger.debug(`[Agent] Generated completion message for route: ${selectedRoute.title}`);
|
|
1026
|
+
// Check for onComplete transition
|
|
1027
|
+
const transitionConfig = await selectedRoute.evaluateOnComplete({ data: session.data }, effectiveContext);
|
|
1028
|
+
if (transitionConfig) {
|
|
1029
|
+
// Find target route by ID or title
|
|
1030
|
+
const targetRoute = this.routes.find((r) => r.id === transitionConfig.nextStep ||
|
|
1031
|
+
r.title === transitionConfig.nextStep);
|
|
1032
|
+
if (targetRoute) {
|
|
1033
|
+
const renderedCondition = await (0, utils_1.render)(transitionConfig.condition, templateContext);
|
|
1034
|
+
// Set pending transition in session
|
|
1035
|
+
session = {
|
|
1036
|
+
...session,
|
|
1037
|
+
pendingTransition: {
|
|
1038
|
+
targetRouteId: targetRoute.id,
|
|
1039
|
+
condition: renderedCondition,
|
|
1040
|
+
reason: "route_complete",
|
|
1041
|
+
},
|
|
1042
|
+
};
|
|
1043
|
+
utils_1.logger.debug(`[Agent] Route ${selectedRoute.title} completed with pending transition to: ${targetRoute.title}`);
|
|
1044
|
+
}
|
|
1045
|
+
else {
|
|
1046
|
+
utils_1.logger.warn(`[Agent] Route ${selectedRoute.title} completed but target route not found: ${transitionConfig.nextStep}`);
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
// Set step to END_ROUTE marker
|
|
1050
|
+
session = (0, utils_1.enterStep)(session, constants_1.END_ROUTE_ID, "Route completed");
|
|
1051
|
+
utils_1.logger.debug(`[Agent] Route ${selectedRoute.title} completed. Entered END_ROUTE step.`);
|
|
1052
|
+
}
|
|
1053
|
+
else {
|
|
1054
|
+
// Fallback: No routes defined, generate a simple response
|
|
1055
|
+
const fallbackPrompt = await this.responseEngine.buildFallbackPrompt({
|
|
1056
|
+
history,
|
|
1057
|
+
agentOptions: this.options,
|
|
1058
|
+
terms: this.terms,
|
|
1059
|
+
guidelines: this.guidelines,
|
|
1060
|
+
context: effectiveContext,
|
|
1061
|
+
session,
|
|
1062
|
+
});
|
|
1063
|
+
const result = await this.options.provider.generateMessage({
|
|
1064
|
+
prompt: fallbackPrompt,
|
|
1065
|
+
history,
|
|
1066
|
+
context: effectiveContext,
|
|
1067
|
+
signal,
|
|
1068
|
+
parameters: {
|
|
1069
|
+
jsonSchema: {
|
|
1070
|
+
type: "object",
|
|
1071
|
+
properties: {
|
|
1072
|
+
message: { type: "string" },
|
|
1073
|
+
},
|
|
1074
|
+
required: ["message"],
|
|
1075
|
+
additionalProperties: false,
|
|
1076
|
+
},
|
|
1077
|
+
schemaName: "fallback_response",
|
|
1078
|
+
},
|
|
1079
|
+
});
|
|
1080
|
+
message = result.structured?.message || result.message;
|
|
1081
|
+
}
|
|
1082
|
+
// Auto-save session step to persistence if configured
|
|
1083
|
+
if (this.persistenceManager &&
|
|
1084
|
+
session.id &&
|
|
1085
|
+
this.options.persistence?.autoSave !== false) {
|
|
1086
|
+
await this.persistenceManager.saveSessionState(session.id, session);
|
|
1087
|
+
utils_1.logger.debug(`[Agent] Auto-saved session step to persistence: ${session.id}`);
|
|
1088
|
+
}
|
|
1089
|
+
// Execute finalize function
|
|
1090
|
+
if (session.currentRoute && session.currentStep) {
|
|
1091
|
+
const currentRoute = this.routes.find((r) => r.id === session.currentRoute?.id);
|
|
1092
|
+
if (currentRoute) {
|
|
1093
|
+
const currentStep = currentRoute.getStep(session.currentStep.id);
|
|
1094
|
+
if (currentStep?.finalize) {
|
|
1095
|
+
utils_1.logger.debug(`[Agent] Executing finalize for step: ${currentStep.id}`);
|
|
1096
|
+
await this.executePrepareFinalize(currentStep.finalize, effectiveContext, session.data, currentRoute, currentStep);
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
// Update current session if we have one
|
|
1101
|
+
if (this.currentSession) {
|
|
1102
|
+
this.currentSession = session;
|
|
1103
|
+
}
|
|
1104
|
+
return {
|
|
1105
|
+
message,
|
|
1106
|
+
session, // Return updated session with route/step info
|
|
1107
|
+
toolCalls,
|
|
1108
|
+
isRouteComplete, // Indicates if the route has reached END_ROUTE with all data collected
|
|
1109
|
+
};
|
|
1110
|
+
}
|
|
1111
|
+
/**
|
|
1112
|
+
* Get all routes
|
|
1113
|
+
*/
|
|
1114
|
+
getRoutes() {
|
|
1115
|
+
return [...this.routes];
|
|
1116
|
+
}
|
|
1117
|
+
/**
|
|
1118
|
+
* Get all terms
|
|
1119
|
+
*/
|
|
1120
|
+
getTerms() {
|
|
1121
|
+
return [...this.terms];
|
|
1122
|
+
}
|
|
1123
|
+
/**
|
|
1124
|
+
* Get all tools
|
|
1125
|
+
*/
|
|
1126
|
+
getTools() {
|
|
1127
|
+
return [...this.tools];
|
|
1128
|
+
}
|
|
1129
|
+
/**
|
|
1130
|
+
* Find an available tool by name for the given route
|
|
1131
|
+
* Route-level tools take precedence over agent-level tools
|
|
1132
|
+
* @private
|
|
1133
|
+
*/
|
|
1134
|
+
findAvailableTool(toolName, route) {
|
|
1135
|
+
// Check route-level tools first (if route provided)
|
|
1136
|
+
if (route) {
|
|
1137
|
+
const routeTool = route
|
|
1138
|
+
.getTools()
|
|
1139
|
+
.find((tool) => tool.id === toolName || tool.name === toolName);
|
|
1140
|
+
if (routeTool)
|
|
1141
|
+
return routeTool;
|
|
1142
|
+
}
|
|
1143
|
+
// Fall back to agent-level tools
|
|
1144
|
+
return this.tools.find((tool) => tool.id === toolName || tool.name === toolName);
|
|
1145
|
+
}
|
|
1146
|
+
/**
|
|
1147
|
+
* Collect all available tools for the given route and step context
|
|
1148
|
+
* @private
|
|
1149
|
+
*/
|
|
1150
|
+
collectAvailableTools(route, step) {
|
|
1151
|
+
const availableTools = new Map();
|
|
1152
|
+
// Add agent-level tools
|
|
1153
|
+
this.tools.forEach((tool) => {
|
|
1154
|
+
availableTools.set(tool.id, tool);
|
|
1155
|
+
});
|
|
1156
|
+
// Add route-level tools (these take precedence)
|
|
1157
|
+
if (route) {
|
|
1158
|
+
route.getTools().forEach((tool) => {
|
|
1159
|
+
availableTools.set(tool.id, tool);
|
|
1160
|
+
});
|
|
1161
|
+
}
|
|
1162
|
+
// Filter by step-level allowed tools if specified
|
|
1163
|
+
if (step?.tools) {
|
|
1164
|
+
const allowedToolIds = new Set();
|
|
1165
|
+
const stepTools = [];
|
|
1166
|
+
for (const toolRef of step.tools) {
|
|
1167
|
+
if (typeof toolRef === "string") {
|
|
1168
|
+
// Reference to registered tool
|
|
1169
|
+
allowedToolIds.add(toolRef);
|
|
1170
|
+
}
|
|
1171
|
+
else {
|
|
1172
|
+
// Inline tool definition
|
|
1173
|
+
if (toolRef.id) {
|
|
1174
|
+
allowedToolIds.add(toolRef.id);
|
|
1175
|
+
stepTools.push(toolRef);
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
// If step specifies tools, only include those
|
|
1180
|
+
if (allowedToolIds.size > 0) {
|
|
1181
|
+
const filteredTools = new Map();
|
|
1182
|
+
for (const toolId of allowedToolIds) {
|
|
1183
|
+
const tool = availableTools.get(toolId);
|
|
1184
|
+
if (tool) {
|
|
1185
|
+
filteredTools.set(toolId, tool);
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
// Add inline tools
|
|
1189
|
+
stepTools.forEach((tool) => {
|
|
1190
|
+
if (tool.id) {
|
|
1191
|
+
filteredTools.set(tool.id, tool);
|
|
1192
|
+
}
|
|
1193
|
+
});
|
|
1194
|
+
availableTools.clear();
|
|
1195
|
+
filteredTools.forEach((tool, id) => availableTools.set(id, tool));
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
// Convert to the format expected by AI providers
|
|
1199
|
+
return Array.from(availableTools.values()).map((tool) => ({
|
|
1200
|
+
id: tool.id,
|
|
1201
|
+
name: tool.name || tool.id,
|
|
1202
|
+
description: tool.description,
|
|
1203
|
+
parameters: tool.parameters,
|
|
1204
|
+
}));
|
|
1205
|
+
}
|
|
1206
|
+
/**
|
|
1207
|
+
* Execute a prepare or finalize function/tool
|
|
1208
|
+
* @private
|
|
1209
|
+
*/
|
|
1210
|
+
async executePrepareFinalize(prepareOrFinalize, context, data, route, step) {
|
|
1211
|
+
if (!prepareOrFinalize)
|
|
1212
|
+
return;
|
|
1213
|
+
if (typeof prepareOrFinalize === "function") {
|
|
1214
|
+
// It's a function - call it directly
|
|
1215
|
+
await prepareOrFinalize(context, data);
|
|
1216
|
+
}
|
|
1217
|
+
else {
|
|
1218
|
+
// It's a tool reference - find and execute the tool
|
|
1219
|
+
let tool;
|
|
1220
|
+
if (typeof prepareOrFinalize === "string") {
|
|
1221
|
+
// Tool ID - find it in available tools
|
|
1222
|
+
const availableTools = new Map();
|
|
1223
|
+
// Add agent-level tools
|
|
1224
|
+
this.tools.forEach((t) => {
|
|
1225
|
+
availableTools.set(t.id, t);
|
|
1226
|
+
});
|
|
1227
|
+
// Add route-level tools
|
|
1228
|
+
if (route) {
|
|
1229
|
+
route.getTools().forEach((t) => {
|
|
1230
|
+
availableTools.set(t.id, t);
|
|
1231
|
+
});
|
|
1232
|
+
}
|
|
1233
|
+
// Add step-level tools
|
|
1234
|
+
if (step?.tools) {
|
|
1235
|
+
for (const toolRef of step.tools) {
|
|
1236
|
+
if (typeof toolRef === "string") {
|
|
1237
|
+
// Keep as is
|
|
1238
|
+
}
|
|
1239
|
+
else if (toolRef.id) {
|
|
1240
|
+
availableTools.set(toolRef.id, toolRef);
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
tool = availableTools.get(prepareOrFinalize);
|
|
1245
|
+
}
|
|
1246
|
+
else {
|
|
1247
|
+
// Tool object - use directly
|
|
1248
|
+
tool = prepareOrFinalize;
|
|
1249
|
+
}
|
|
1250
|
+
if (tool) {
|
|
1251
|
+
const toolExecutor = new ToolExecutor_1.ToolExecutor();
|
|
1252
|
+
const result = await toolExecutor.executeTool({
|
|
1253
|
+
tool,
|
|
1254
|
+
context,
|
|
1255
|
+
updateContext: this.updateContext.bind(this),
|
|
1256
|
+
history: [], // Empty history for prepare/finalize
|
|
1257
|
+
data,
|
|
1258
|
+
});
|
|
1259
|
+
if (!result.success) {
|
|
1260
|
+
utils_1.logger.error(`[Agent] Tool execution failed in prepare/finalize: ${result.error}`);
|
|
1261
|
+
throw new Error(`Tool execution failed: ${result.error}`);
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
else {
|
|
1265
|
+
utils_1.logger.warn(`[Agent] Tool not found for prepare/finalize: ${typeof prepareOrFinalize === "string"
|
|
1266
|
+
? prepareOrFinalize
|
|
1267
|
+
: "inline tool"}`);
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
/**
|
|
1272
|
+
* Get all guidelines
|
|
1273
|
+
*/
|
|
1274
|
+
getGuidelines() {
|
|
1275
|
+
return [...this.guidelines];
|
|
1276
|
+
}
|
|
1277
|
+
/**
|
|
1278
|
+
* Get the agent's knowledge base
|
|
1279
|
+
*/
|
|
1280
|
+
getKnowledgeBase() {
|
|
1281
|
+
return { ...this.knowledgeBase };
|
|
1282
|
+
}
|
|
1283
|
+
/**
|
|
1284
|
+
* Merge terms with route-specific taking precedence on conflicts
|
|
1285
|
+
* @private
|
|
1286
|
+
*/
|
|
1287
|
+
mergeTerms(agentTerms, routeTerms) {
|
|
1288
|
+
const merged = new Map();
|
|
1289
|
+
// Add agent terms first
|
|
1290
|
+
agentTerms.forEach((term) => {
|
|
1291
|
+
const name = typeof term.name === "string" ? term.name : term.name.toString();
|
|
1292
|
+
merged.set(name, term);
|
|
1293
|
+
});
|
|
1294
|
+
// Add route terms (these take precedence)
|
|
1295
|
+
routeTerms.forEach((term) => {
|
|
1296
|
+
const name = typeof term.name === "string" ? term.name : term.name.toString();
|
|
1297
|
+
merged.set(name, term);
|
|
1298
|
+
});
|
|
1299
|
+
return Array.from(merged.values());
|
|
1300
|
+
}
|
|
1301
|
+
/**
|
|
1302
|
+
* Get the persistence manager (if configured)
|
|
1303
|
+
*/
|
|
1304
|
+
getPersistenceManager() {
|
|
1305
|
+
return this.persistenceManager;
|
|
1306
|
+
}
|
|
1307
|
+
/**
|
|
1308
|
+
* Check if persistence is enabled
|
|
1309
|
+
*/
|
|
1310
|
+
hasPersistence() {
|
|
1311
|
+
return this.persistenceManager !== undefined;
|
|
1312
|
+
}
|
|
1313
|
+
/**
|
|
1314
|
+
* Set the current session for convenience methods
|
|
1315
|
+
* @param session - Session step to use for subsequent calls
|
|
1316
|
+
*/
|
|
1317
|
+
setCurrentSession(session) {
|
|
1318
|
+
this.currentSession = session;
|
|
1319
|
+
}
|
|
1320
|
+
/**
|
|
1321
|
+
* Get the current session (if set)
|
|
1322
|
+
*/
|
|
1323
|
+
getCurrentSession() {
|
|
1324
|
+
return this.currentSession;
|
|
1325
|
+
}
|
|
1326
|
+
/**
|
|
1327
|
+
* Clear the current session
|
|
1328
|
+
*/
|
|
1329
|
+
clearCurrentSession() {
|
|
1330
|
+
this.currentSession = undefined;
|
|
1331
|
+
}
|
|
1332
|
+
/**
|
|
1333
|
+
* Get collected data from current session
|
|
1334
|
+
* @param routeId - Optional route ID to get data for (uses current route if not provided)
|
|
1335
|
+
* @returns The collected data from the current session
|
|
1336
|
+
*/
|
|
1337
|
+
getData(routeId) {
|
|
1338
|
+
if (!this.currentSession) {
|
|
1339
|
+
return {};
|
|
1340
|
+
}
|
|
1341
|
+
if (routeId) {
|
|
1342
|
+
return (this.currentSession.dataByRoute?.[routeId] ||
|
|
1343
|
+
{});
|
|
1344
|
+
}
|
|
1345
|
+
return this.currentSession.data || {};
|
|
1346
|
+
}
|
|
1347
|
+
/**
|
|
1348
|
+
* Manually transition to a different route
|
|
1349
|
+
* Sets a pending transition that will be executed on the next respond() call
|
|
1350
|
+
*
|
|
1351
|
+
* @param routeIdOrTitle - Route ID or title to transition to
|
|
1352
|
+
* @param session - Session step to update (uses current session if not provided)
|
|
1353
|
+
* @param condition - Optional AI-evaluated condition for the transition
|
|
1354
|
+
* @returns Updated session with pending transition
|
|
1355
|
+
*
|
|
1356
|
+
* @example
|
|
1357
|
+
* // After route completes
|
|
1358
|
+
* if (response.isRouteComplete && response.session) {
|
|
1359
|
+
* const updatedSession = agent.nextStepRoute("feedback-collection", response.session);
|
|
1360
|
+
* // Next respond() call will automatically transition to feedback route
|
|
1361
|
+
* const nextResponse = await agent.respond({ history, session: updatedSession });
|
|
1362
|
+
* }
|
|
1363
|
+
*/
|
|
1364
|
+
async nextStepRoute(routeIdOrTitle, session, condition, history) {
|
|
1365
|
+
const targetSession = session || this.currentSession;
|
|
1366
|
+
if (!targetSession) {
|
|
1367
|
+
throw new Error("No session provided and no current session available. Please provide a session to transition.");
|
|
1368
|
+
}
|
|
1369
|
+
// Find target route by ID or title
|
|
1370
|
+
const targetRoute = this.routes.find((r) => r.id === routeIdOrTitle || r.title === routeIdOrTitle);
|
|
1371
|
+
if (!targetRoute) {
|
|
1372
|
+
throw new Error(`Route not found: ${routeIdOrTitle}. Available routes: ${this.routes
|
|
1373
|
+
.map((r) => r.title)
|
|
1374
|
+
.join(", ")}`);
|
|
1375
|
+
}
|
|
1376
|
+
const templateContext = {
|
|
1377
|
+
context: this.context,
|
|
1378
|
+
session,
|
|
1379
|
+
history,
|
|
1380
|
+
data: this.currentSession?.data,
|
|
1381
|
+
};
|
|
1382
|
+
const renderedCondition = await (0, utils_1.render)(condition, templateContext);
|
|
1383
|
+
const updatedSession = {
|
|
1384
|
+
...targetSession,
|
|
1385
|
+
pendingTransition: {
|
|
1386
|
+
targetRouteId: targetRoute.id,
|
|
1387
|
+
condition: renderedCondition,
|
|
1388
|
+
reason: "manual",
|
|
1389
|
+
},
|
|
1390
|
+
};
|
|
1391
|
+
// Update current session if using it
|
|
1392
|
+
if (!session && this.currentSession) {
|
|
1393
|
+
this.currentSession = updatedSession;
|
|
1394
|
+
}
|
|
1395
|
+
utils_1.logger.debug(`[Agent] Set pending manual transition to route: ${targetRoute.title}`);
|
|
1396
|
+
return updatedSession;
|
|
1397
|
+
}
|
|
1398
|
+
/**
|
|
1399
|
+
* Simplified respond method using SessionManager
|
|
1400
|
+
* Automatically manages conversation history through the session
|
|
1401
|
+
*/
|
|
1402
|
+
async chat(message, options) {
|
|
1403
|
+
// Determine which history to use
|
|
1404
|
+
let history;
|
|
1405
|
+
if (options?.history) {
|
|
1406
|
+
// Use provided history for this response only
|
|
1407
|
+
history = options.history;
|
|
1408
|
+
}
|
|
1409
|
+
else {
|
|
1410
|
+
// Add user message to session history if provided
|
|
1411
|
+
if (message) {
|
|
1412
|
+
await this.session.addMessage("user", message);
|
|
1413
|
+
}
|
|
1414
|
+
history = this.session.getHistory();
|
|
1415
|
+
}
|
|
1416
|
+
// Get or create session
|
|
1417
|
+
const session = await this.session.getOrCreate();
|
|
1418
|
+
// Use existing respond method with session-managed history
|
|
1419
|
+
const result = await this.respond({
|
|
1420
|
+
history,
|
|
1421
|
+
session,
|
|
1422
|
+
contextOverride: options?.contextOverride,
|
|
1423
|
+
signal: options?.signal,
|
|
1424
|
+
});
|
|
1425
|
+
// Add agent response to session history (only if not using override history)
|
|
1426
|
+
if (!options?.history) {
|
|
1427
|
+
await this.session.addMessage("assistant", result.message);
|
|
1428
|
+
}
|
|
1429
|
+
return result;
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
exports.Agent = Agent;
|
|
1433
|
+
//# sourceMappingURL=Agent.js.map
|