@dexto/core 1.2.4 → 1.2.6
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 +60 -0
- package/dist/agent/DextoAgent.cjs +579 -345
- package/dist/agent/DextoAgent.d.ts +131 -83
- package/dist/agent/DextoAgent.d.ts.map +1 -1
- package/dist/agent/DextoAgent.js +573 -336
- package/dist/agent/agentCard.cjs +4 -2
- package/dist/agent/agentCard.d.ts +0 -1
- package/dist/agent/agentCard.d.ts.map +1 -1
- package/dist/agent/agentCard.js +4 -2
- package/dist/agent/index.cjs +3 -7
- package/dist/agent/index.d.ts +3 -3
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +7 -6
- package/dist/agent/schemas.cjs +179 -75
- package/dist/agent/schemas.d.ts +2678 -586
- package/dist/agent/schemas.d.ts.map +1 -1
- package/dist/agent/schemas.js +172 -65
- package/dist/agent/state-manager.cjs +28 -23
- package/dist/agent/state-manager.d.ts +4 -1
- package/dist/agent/state-manager.d.ts.map +1 -1
- package/dist/agent/state-manager.js +28 -23
- package/dist/{preferences/constants.cjs → agent/types.cjs} +2 -14
- package/dist/agent/types.d.ts +54 -0
- package/dist/agent/types.d.ts.map +1 -0
- package/dist/agent/types.js +0 -0
- package/dist/approval/errors.cjs +89 -8
- package/dist/approval/errors.d.ts +5 -3
- package/dist/approval/errors.d.ts.map +1 -1
- package/dist/approval/errors.js +89 -8
- package/dist/approval/{providers/factory.d.ts → factory.d.ts} +2 -2
- package/dist/approval/factory.d.ts.map +1 -0
- package/dist/approval/{providers/factory.js → factory.js} +1 -1
- package/dist/approval/index.cjs +4 -6
- package/dist/approval/index.d.ts +3 -5
- package/dist/approval/index.d.ts.map +1 -1
- package/dist/approval/index.js +4 -5
- package/dist/approval/manager.cjs +140 -37
- package/dist/approval/manager.d.ts +56 -17
- package/dist/approval/manager.d.ts.map +1 -1
- package/dist/approval/manager.js +141 -38
- package/dist/approval/schemas.cjs +9 -1
- package/dist/approval/schemas.d.ts +120 -35
- package/dist/approval/schemas.d.ts.map +1 -1
- package/dist/approval/schemas.js +9 -2
- package/dist/approval/types.cjs +14 -2
- package/dist/approval/types.d.ts +64 -12
- package/dist/approval/types.d.ts.map +1 -1
- package/dist/approval/types.js +12 -1
- package/dist/context/compression/middle-removal.cjs +11 -11
- package/dist/context/compression/middle-removal.d.ts +3 -1
- package/dist/context/compression/middle-removal.d.ts.map +1 -1
- package/dist/context/compression/middle-removal.js +11 -11
- package/dist/context/compression/oldest-removal.cjs +18 -5
- package/dist/context/compression/oldest-removal.d.ts +3 -1
- package/dist/context/compression/oldest-removal.d.ts.map +1 -1
- package/dist/context/compression/oldest-removal.js +18 -5
- package/dist/context/manager.cjs +94 -67
- package/dist/context/manager.d.ts +13 -10
- package/dist/context/manager.d.ts.map +1 -1
- package/dist/context/manager.js +94 -67
- package/dist/context/utils.cjs +79 -65
- package/dist/context/utils.d.ts +15 -12
- package/dist/context/utils.d.ts.map +1 -1
- package/dist/context/utils.js +45 -31
- package/dist/errors/DextoRuntimeError.d.ts +5 -5
- package/dist/errors/DextoRuntimeError.d.ts.map +1 -1
- package/dist/errors/result-bridge.cjs +2 -3
- package/dist/errors/result-bridge.d.ts +5 -3
- package/dist/errors/result-bridge.d.ts.map +1 -1
- package/dist/errors/result-bridge.js +1 -2
- package/dist/errors/types.cjs +1 -2
- package/dist/errors/types.d.ts +5 -8
- package/dist/errors/types.d.ts.map +1 -1
- package/dist/errors/types.js +1 -2
- package/dist/events/index.cjs +125 -55
- package/dist/events/index.d.ts +204 -97
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +123 -55
- package/dist/filesystem/filesystem-service.cjs +40 -30
- package/dist/filesystem/filesystem-service.d.ts +9 -1
- package/dist/filesystem/filesystem-service.d.ts.map +1 -1
- package/dist/filesystem/filesystem-service.js +40 -30
- package/dist/filesystem/path-validator.cjs +4 -3
- package/dist/filesystem/path-validator.d.ts +3 -1
- package/dist/filesystem/path-validator.d.ts.map +1 -1
- package/dist/filesystem/path-validator.js +4 -3
- package/dist/filesystem/types.d.ts +3 -3
- package/dist/filesystem/types.d.ts.map +1 -1
- package/dist/index.browser.cjs +7 -0
- package/dist/index.browser.d.ts +2 -0
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +4 -0
- package/dist/index.cjs +0 -7
- package/dist/index.d.ts +12 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -4
- package/dist/llm/formatters/anthropic.cjs +32 -21
- package/dist/llm/formatters/anthropic.d.ts +3 -0
- package/dist/llm/formatters/anthropic.d.ts.map +1 -1
- package/dist/llm/formatters/anthropic.js +32 -21
- package/dist/llm/formatters/factory.cjs +6 -7
- package/dist/llm/formatters/factory.d.ts +2 -1
- package/dist/llm/formatters/factory.d.ts.map +1 -1
- package/dist/llm/formatters/factory.js +4 -5
- package/dist/llm/formatters/openai.cjs +38 -9
- package/dist/llm/formatters/openai.d.ts +3 -0
- package/dist/llm/formatters/openai.d.ts.map +1 -1
- package/dist/llm/formatters/openai.js +38 -9
- package/dist/llm/formatters/vercel.cjs +49 -8
- package/dist/llm/formatters/vercel.d.ts +3 -0
- package/dist/llm/formatters/vercel.d.ts.map +1 -1
- package/dist/llm/formatters/vercel.js +49 -8
- package/dist/llm/registry.cjs +153 -17
- package/dist/llm/registry.d.ts +5 -2
- package/dist/llm/registry.d.ts.map +1 -1
- package/dist/llm/registry.js +143 -7
- package/dist/llm/resolver.cjs +4 -4
- package/dist/llm/resolver.d.ts +3 -2
- package/dist/llm/resolver.d.ts.map +1 -1
- package/dist/llm/resolver.js +4 -4
- package/dist/llm/schemas.cjs +6 -3
- package/dist/llm/schemas.d.ts +51 -17
- package/dist/llm/schemas.d.ts.map +1 -1
- package/dist/llm/schemas.js +5 -3
- package/dist/llm/services/anthropic.cjs +216 -183
- package/dist/llm/services/anthropic.d.ts +3 -1
- package/dist/llm/services/anthropic.d.ts.map +1 -1
- package/dist/llm/services/anthropic.js +217 -184
- package/dist/llm/services/factory.cjs +15 -9
- package/dist/llm/services/factory.d.ts +2 -1
- package/dist/llm/services/factory.d.ts.map +1 -1
- package/dist/llm/services/factory.js +15 -9
- package/dist/llm/services/openai.cjs +262 -225
- package/dist/llm/services/openai.d.ts +3 -1
- package/dist/llm/services/openai.d.ts.map +1 -1
- package/dist/llm/services/openai.js +263 -226
- package/dist/llm/services/test-utils.integration.cjs +58 -12
- package/dist/llm/services/test-utils.integration.d.ts.map +1 -1
- package/dist/llm/services/test-utils.integration.js +58 -12
- package/dist/llm/services/types.d.ts +9 -0
- package/dist/llm/services/types.d.ts.map +1 -1
- package/dist/llm/services/vercel.cjs +163 -111
- package/dist/llm/services/vercel.d.ts +3 -1
- package/dist/llm/services/vercel.d.ts.map +1 -1
- package/dist/llm/services/vercel.js +157 -105
- package/dist/llm/tokenizer/factory.cjs +2 -2
- package/dist/llm/tokenizer/factory.d.ts +3 -1
- package/dist/llm/tokenizer/factory.d.ts.map +1 -1
- package/dist/llm/tokenizer/factory.js +2 -2
- package/dist/llm/tokenizer/openai.cjs +16 -9
- package/dist/llm/tokenizer/openai.d.ts +4 -1
- package/dist/llm/tokenizer/openai.d.ts.map +1 -1
- package/dist/llm/tokenizer/openai.js +16 -9
- package/dist/llm/validation.cjs +8 -9
- package/dist/llm/validation.d.ts +3 -1
- package/dist/llm/validation.d.ts.map +1 -1
- package/dist/llm/validation.js +5 -6
- package/dist/logger/factory.cjs +54 -0
- package/dist/logger/factory.d.ts +36 -0
- package/dist/logger/factory.d.ts.map +1 -0
- package/dist/logger/factory.js +31 -0
- package/dist/logger/index.cjs +42 -3
- package/dist/logger/index.d.ts +17 -1
- package/dist/logger/index.d.ts.map +1 -1
- package/dist/logger/index.js +26 -1
- package/dist/logger/logger.cjs +30 -17
- package/dist/logger/logger.d.ts.map +1 -1
- package/dist/logger/logger.js +30 -17
- package/dist/logger/v2/dexto-logger.cjs +141 -0
- package/dist/logger/v2/dexto-logger.d.ts +54 -0
- package/dist/logger/v2/dexto-logger.d.ts.map +1 -0
- package/dist/logger/v2/dexto-logger.js +118 -0
- package/dist/{preferences → logger/v2}/error-codes.cjs +11 -10
- package/dist/logger/v2/error-codes.d.ts +13 -0
- package/dist/logger/v2/error-codes.d.ts.map +1 -0
- package/dist/logger/v2/error-codes.js +13 -0
- package/dist/logger/v2/errors.cjs +107 -0
- package/dist/logger/v2/errors.d.ts +32 -0
- package/dist/logger/v2/errors.d.ts.map +1 -0
- package/dist/logger/v2/errors.js +84 -0
- package/dist/logger/v2/schemas.cjs +57 -0
- package/dist/logger/v2/schemas.d.ts +147 -0
- package/dist/logger/v2/schemas.d.ts.map +1 -0
- package/dist/logger/v2/schemas.js +33 -0
- package/dist/logger/v2/transport-factory.cjs +53 -0
- package/dist/logger/v2/transport-factory.d.ts +21 -0
- package/dist/logger/v2/transport-factory.d.ts.map +1 -0
- package/dist/logger/v2/transport-factory.js +29 -0
- package/dist/logger/v2/transports/console-transport.cjs +79 -0
- package/dist/logger/v2/transports/console-transport.d.ts +23 -0
- package/dist/logger/v2/transports/console-transport.d.ts.map +1 -0
- package/dist/logger/v2/transports/console-transport.js +46 -0
- package/dist/logger/v2/transports/file-transport.cjs +161 -0
- package/dist/logger/v2/transports/file-transport.d.ts +46 -0
- package/dist/logger/v2/transports/file-transport.d.ts.map +1 -0
- package/dist/logger/v2/transports/file-transport.js +128 -0
- package/dist/logger/v2/types.cjs +49 -0
- package/dist/logger/v2/types.d.ts +123 -0
- package/dist/logger/v2/types.d.ts.map +1 -0
- package/dist/logger/v2/types.js +26 -0
- package/dist/mcp/manager.cjs +88 -78
- package/dist/mcp/manager.d.ts +3 -1
- package/dist/mcp/manager.d.ts.map +1 -1
- package/dist/mcp/manager.js +88 -78
- package/dist/mcp/mcp-client.cjs +109 -79
- package/dist/mcp/mcp-client.d.ts +3 -0
- package/dist/mcp/mcp-client.d.ts.map +1 -1
- package/dist/mcp/mcp-client.js +102 -72
- package/dist/memory/index.cjs +2 -0
- package/dist/memory/index.d.ts +1 -1
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/memory/index.js +3 -1
- package/dist/memory/manager.cjs +9 -7
- package/dist/memory/manager.d.ts +3 -1
- package/dist/memory/manager.d.ts.map +1 -1
- package/dist/memory/manager.js +9 -7
- package/dist/memory/schemas.cjs +10 -0
- package/dist/memory/schemas.d.ts +37 -8
- package/dist/memory/schemas.d.ts.map +1 -1
- package/dist/memory/schemas.js +9 -0
- package/dist/plugins/manager.cjs +21 -19
- package/dist/plugins/manager.d.ts +3 -1
- package/dist/plugins/manager.d.ts.map +1 -1
- package/dist/plugins/manager.js +21 -19
- package/dist/plugins/schemas.d.ts +9 -9
- package/dist/plugins/types.d.ts +2 -2
- package/dist/plugins/types.d.ts.map +1 -1
- package/dist/process/command-validator.cjs +30 -20
- package/dist/process/command-validator.d.ts +4 -1
- package/dist/process/command-validator.d.ts.map +1 -1
- package/dist/process/command-validator.js +30 -20
- package/dist/process/process-service.cjs +23 -21
- package/dist/process/process-service.d.ts +3 -1
- package/dist/process/process-service.d.ts.map +1 -1
- package/dist/process/process-service.js +23 -21
- package/dist/prompts/index.cjs +6 -8
- package/dist/prompts/index.d.ts +2 -4
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +4 -6
- package/dist/prompts/prompt-manager.cjs +25 -20
- package/dist/prompts/prompt-manager.d.ts +3 -1
- package/dist/prompts/prompt-manager.d.ts.map +1 -1
- package/dist/prompts/prompt-manager.js +25 -20
- package/dist/prompts/providers/config-prompt-provider.cjs +331 -0
- package/dist/prompts/providers/config-prompt-provider.d.ts +34 -0
- package/dist/prompts/providers/config-prompt-provider.d.ts.map +1 -0
- package/dist/prompts/providers/config-prompt-provider.js +308 -0
- package/dist/prompts/providers/custom-prompt-provider.cjs +11 -7
- package/dist/prompts/providers/custom-prompt-provider.d.ts +3 -1
- package/dist/prompts/providers/custom-prompt-provider.d.ts.map +1 -1
- package/dist/prompts/providers/custom-prompt-provider.js +11 -7
- package/dist/prompts/providers/mcp-prompt-provider.cjs +7 -6
- package/dist/prompts/providers/mcp-prompt-provider.d.ts +3 -1
- package/dist/prompts/providers/mcp-prompt-provider.d.ts.map +1 -1
- package/dist/prompts/providers/mcp-prompt-provider.js +7 -6
- package/dist/prompts/schemas.cjs +42 -23
- package/dist/prompts/schemas.d.ts +123 -14
- package/dist/prompts/schemas.d.ts.map +1 -1
- package/dist/prompts/schemas.js +39 -22
- package/dist/prompts/types.d.ts +1 -1
- package/dist/prompts/types.d.ts.map +1 -1
- package/dist/resources/handlers/blob-handler.cjs +15 -11
- package/dist/resources/handlers/blob-handler.d.ts +3 -1
- package/dist/resources/handlers/blob-handler.d.ts.map +1 -1
- package/dist/resources/handlers/blob-handler.js +15 -11
- package/dist/resources/handlers/factory.cjs +3 -3
- package/dist/resources/handlers/factory.d.ts +2 -1
- package/dist/resources/handlers/factory.d.ts.map +1 -1
- package/dist/resources/handlers/factory.js +3 -3
- package/dist/resources/handlers/filesystem-handler.cjs +10 -8
- package/dist/resources/handlers/filesystem-handler.d.ts +3 -1
- package/dist/resources/handlers/filesystem-handler.d.ts.map +1 -1
- package/dist/resources/handlers/filesystem-handler.js +10 -8
- package/dist/resources/internal-provider.cjs +28 -20
- package/dist/resources/internal-provider.d.ts +3 -1
- package/dist/resources/internal-provider.d.ts.map +1 -1
- package/dist/resources/internal-provider.js +28 -20
- package/dist/resources/manager.cjs +34 -25
- package/dist/resources/manager.d.ts +3 -1
- package/dist/resources/manager.d.ts.map +1 -1
- package/dist/resources/manager.js +34 -25
- package/dist/resources/schemas.d.ts +6 -6
- package/dist/search/search-service.cjs +8 -6
- package/dist/search/search-service.d.ts +3 -1
- package/dist/search/search-service.d.ts.map +1 -1
- package/dist/search/search-service.js +8 -6
- package/dist/session/chat-session.cjs +40 -27
- package/dist/session/chat-session.d.ts +10 -7
- package/dist/session/chat-session.d.ts.map +1 -1
- package/dist/session/chat-session.js +40 -27
- package/dist/session/history/database.cjs +18 -11
- package/dist/session/history/database.d.ts +3 -1
- package/dist/session/history/database.d.ts.map +1 -1
- package/dist/session/history/database.js +18 -11
- package/dist/session/history/factory.cjs +2 -2
- package/dist/session/history/factory.d.ts +5 -1
- package/dist/session/history/factory.d.ts.map +1 -1
- package/dist/session/history/factory.js +2 -2
- package/dist/session/session-manager.cjs +37 -53
- package/dist/session/session-manager.d.ts +3 -17
- package/dist/session/session-manager.d.ts.map +1 -1
- package/dist/session/session-manager.js +37 -53
- package/dist/session/title-generator.cjs +3 -2
- package/dist/session/title-generator.d.ts +2 -1
- package/dist/session/title-generator.d.ts.map +1 -1
- package/dist/session/title-generator.js +3 -2
- package/dist/storage/blob/factory.cjs +9 -18
- package/dist/storage/blob/factory.d.ts +5 -4
- package/dist/storage/blob/factory.d.ts.map +1 -1
- package/dist/storage/blob/factory.js +8 -17
- package/dist/storage/blob/local-blob-store.cjs +25 -32
- package/dist/storage/blob/local-blob-store.d.ts +3 -2
- package/dist/storage/blob/local-blob-store.d.ts.map +1 -1
- package/dist/storage/blob/local-blob-store.js +25 -32
- package/dist/storage/blob/memory-blob-store.cjs +326 -0
- package/dist/storage/blob/memory-blob-store.d.ts +66 -0
- package/dist/storage/blob/memory-blob-store.d.ts.map +1 -0
- package/dist/storage/blob/memory-blob-store.js +303 -0
- package/dist/storage/blob/schemas.cjs +3 -1
- package/dist/storage/blob/schemas.d.ts +6 -6
- package/dist/storage/blob/schemas.d.ts.map +1 -1
- package/dist/storage/blob/schemas.js +3 -1
- package/dist/storage/cache/factory.cjs +7 -8
- package/dist/storage/cache/factory.d.ts +4 -1
- package/dist/storage/cache/factory.d.ts.map +1 -1
- package/dist/storage/cache/factory.js +4 -5
- package/dist/storage/cache/redis-store.cjs +4 -1
- package/dist/storage/cache/redis-store.d.ts +3 -1
- package/dist/storage/cache/redis-store.d.ts.map +1 -1
- package/dist/storage/cache/redis-store.js +4 -1
- package/dist/storage/database/factory.cjs +13 -16
- package/dist/storage/database/factory.d.ts +5 -3
- package/dist/storage/database/factory.d.ts.map +1 -1
- package/dist/storage/database/factory.js +9 -12
- package/dist/storage/database/postgres-store.cjs +4 -1
- package/dist/storage/database/postgres-store.d.ts +3 -1
- package/dist/storage/database/postgres-store.d.ts.map +1 -1
- package/dist/storage/database/postgres-store.js +4 -1
- package/dist/storage/database/schemas.cjs +3 -4
- package/dist/storage/database/schemas.d.ts +8 -16
- package/dist/storage/database/schemas.d.ts.map +1 -1
- package/dist/storage/database/schemas.js +3 -4
- package/dist/storage/database/sqlite-store.cjs +17 -45
- package/dist/storage/database/sqlite-store.d.ts +3 -3
- package/dist/storage/database/sqlite-store.d.ts.map +1 -1
- package/dist/storage/database/sqlite-store.js +17 -45
- package/dist/storage/schemas.cjs +3 -1
- package/dist/storage/schemas.d.ts +16 -23
- package/dist/storage/schemas.d.ts.map +1 -1
- package/dist/storage/schemas.js +3 -1
- package/dist/storage/storage-manager.cjs +15 -15
- package/dist/storage/storage-manager.d.ts +6 -6
- package/dist/storage/storage-manager.d.ts.map +1 -1
- package/dist/storage/storage-manager.js +15 -15
- package/dist/systemPrompt/contributors.cjs +15 -15
- package/dist/systemPrompt/contributors.d.ts +5 -3
- package/dist/systemPrompt/contributors.d.ts.map +1 -1
- package/dist/systemPrompt/contributors.js +15 -15
- package/dist/systemPrompt/in-built-prompts.cjs +0 -5
- package/dist/systemPrompt/in-built-prompts.d.ts +1 -2
- package/dist/systemPrompt/in-built-prompts.d.ts.map +1 -1
- package/dist/systemPrompt/in-built-prompts.js +0 -4
- package/dist/systemPrompt/manager.cjs +31 -23
- package/dist/systemPrompt/manager.d.ts +5 -3
- package/dist/systemPrompt/manager.d.ts.map +1 -1
- package/dist/systemPrompt/manager.js +31 -23
- package/dist/systemPrompt/registry.cjs +1 -2
- package/dist/systemPrompt/registry.d.ts +1 -1
- package/dist/systemPrompt/registry.d.ts.map +1 -1
- package/dist/systemPrompt/registry.js +1 -2
- package/dist/systemPrompt/schemas.cjs +24 -18
- package/dist/systemPrompt/schemas.d.ts +46 -222
- package/dist/systemPrompt/schemas.d.ts.map +1 -1
- package/dist/systemPrompt/schemas.js +14 -18
- package/dist/telemetry/decorators.cjs +54 -15
- package/dist/telemetry/decorators.d.ts.map +1 -1
- package/dist/telemetry/decorators.js +54 -15
- package/dist/telemetry/utils.cjs +21 -14
- package/dist/telemetry/utils.d.ts +7 -3
- package/dist/telemetry/utils.d.ts.map +1 -1
- package/dist/telemetry/utils.js +21 -14
- package/dist/tools/confirmation/allowed-tools-provider/factory.cjs +2 -2
- package/dist/tools/confirmation/allowed-tools-provider/factory.d.ts +2 -1
- package/dist/tools/confirmation/allowed-tools-provider/factory.d.ts.map +1 -1
- package/dist/tools/confirmation/allowed-tools-provider/factory.js +2 -2
- package/dist/tools/confirmation/allowed-tools-provider/storage.cjs +7 -6
- package/dist/tools/confirmation/allowed-tools-provider/storage.d.ts +3 -1
- package/dist/tools/confirmation/allowed-tools-provider/storage.d.ts.map +1 -1
- package/dist/tools/confirmation/allowed-tools-provider/storage.js +7 -6
- package/dist/tools/errors.cjs +2 -1
- package/dist/tools/errors.d.ts.map +1 -1
- package/dist/tools/errors.js +2 -1
- package/dist/tools/internal-tools/constants.cjs +2 -1
- package/dist/tools/internal-tools/constants.d.ts +1 -1
- package/dist/tools/internal-tools/constants.d.ts.map +1 -1
- package/dist/tools/internal-tools/constants.js +2 -1
- package/dist/tools/internal-tools/implementations/bash-exec-tool.cjs +1 -1
- package/dist/tools/internal-tools/implementations/bash-exec-tool.js +1 -1
- package/dist/tools/internal-tools/implementations/delegate-to-url-tool.cjs +192 -0
- package/dist/tools/internal-tools/implementations/delegate-to-url-tool.d.ts +33 -0
- package/dist/tools/internal-tools/implementations/delegate-to-url-tool.d.ts.map +1 -0
- package/dist/tools/internal-tools/implementations/delegate-to-url-tool.js +169 -0
- package/dist/tools/internal-tools/provider.cjs +21 -17
- package/dist/tools/internal-tools/provider.d.ts +3 -1
- package/dist/tools/internal-tools/provider.d.ts.map +1 -1
- package/dist/tools/internal-tools/provider.js +21 -17
- package/dist/tools/internal-tools/registry.cjs +5 -0
- package/dist/tools/internal-tools/registry.d.ts.map +1 -1
- package/dist/tools/internal-tools/registry.js +5 -0
- package/dist/tools/schemas.cjs +16 -4
- package/dist/tools/schemas.d.ts +21 -9
- package/dist/tools/schemas.d.ts.map +1 -1
- package/dist/tools/schemas.js +15 -4
- package/dist/tools/tool-manager.cjs +64 -47
- package/dist/tools/tool-manager.d.ts +4 -2
- package/dist/tools/tool-manager.d.ts.map +1 -1
- package/dist/tools/tool-manager.js +61 -44
- package/dist/tools/types.d.ts +0 -4
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/utils/env-file.cjs +118 -0
- package/dist/utils/env-file.d.ts +5 -0
- package/dist/utils/env-file.d.ts.map +1 -0
- package/dist/utils/env-file.js +85 -0
- package/dist/utils/error-conversion.cjs +23 -1
- package/dist/utils/error-conversion.d.ts +2 -1
- package/dist/utils/error-conversion.d.ts.map +1 -1
- package/dist/utils/error-conversion.js +23 -1
- package/dist/utils/execution-context.d.ts.map +1 -1
- package/dist/utils/fs-walk.d.ts.map +1 -1
- package/dist/utils/index.cjs +7 -9
- package/dist/utils/index.d.ts +3 -4
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +3 -4
- package/dist/utils/path.cjs +22 -57
- package/dist/utils/path.d.ts +8 -7
- package/dist/utils/path.d.ts.map +1 -1
- package/dist/utils/path.js +21 -54
- package/dist/utils/result.cjs +37 -14
- package/dist/utils/result.d.ts.map +1 -1
- package/dist/utils/result.js +37 -14
- package/dist/utils/schema.cjs +2 -3
- package/dist/utils/schema.d.ts +2 -1
- package/dist/utils/schema.d.ts.map +1 -1
- package/dist/utils/schema.js +1 -2
- package/dist/utils/service-initializer.cjs +88 -61
- package/dist/utils/service-initializer.d.ts +4 -2
- package/dist/utils/service-initializer.d.ts.map +1 -1
- package/dist/utils/service-initializer.js +70 -43
- package/package.json +7 -3
- package/dist/Dexto.cjs +0 -251
- package/dist/Dexto.d.ts +0 -191
- package/dist/Dexto.d.ts.map +0 -1
- package/dist/Dexto.js +0 -228
- package/dist/agent/registry/error-codes.cjs +0 -44
- package/dist/agent/registry/error-codes.d.ts +0 -21
- package/dist/agent/registry/error-codes.d.ts.map +0 -1
- package/dist/agent/registry/error-codes.js +0 -21
- package/dist/agent/registry/errors.cjs +0 -188
- package/dist/agent/registry/errors.d.ts +0 -63
- package/dist/agent/registry/errors.d.ts.map +0 -1
- package/dist/agent/registry/errors.js +0 -165
- package/dist/agent/registry/registry.cjs +0 -479
- package/dist/agent/registry/registry.d.ts +0 -130
- package/dist/agent/registry/registry.d.ts.map +0 -1
- package/dist/agent/registry/registry.js +0 -453
- package/dist/agent/registry/types.cjs +0 -74
- package/dist/agent/registry/types.d.ts +0 -142
- package/dist/agent/registry/types.d.ts.map +0 -1
- package/dist/agent/registry/types.js +0 -48
- package/dist/agent/registry/user-registry.cjs +0 -140
- package/dist/agent/registry/user-registry.d.ts +0 -34
- package/dist/agent/registry/user-registry.d.ts.map +0 -1
- package/dist/agent/registry/user-registry.js +0 -105
- package/dist/approval/providers/event-based-approval-provider.cjs +0 -156
- package/dist/approval/providers/event-based-approval-provider.d.ts +0 -39
- package/dist/approval/providers/event-based-approval-provider.d.ts.map +0 -1
- package/dist/approval/providers/event-based-approval-provider.js +0 -133
- package/dist/approval/providers/factory.d.ts.map +0 -1
- package/dist/approval/providers/noop-approval-provider.cjs +0 -54
- package/dist/approval/providers/noop-approval-provider.d.ts +0 -18
- package/dist/approval/providers/noop-approval-provider.d.ts.map +0 -1
- package/dist/approval/providers/noop-approval-provider.js +0 -31
- package/dist/config/agent-resolver.cjs +0 -153
- package/dist/config/agent-resolver.d.ts +0 -14
- package/dist/config/agent-resolver.d.ts.map +0 -1
- package/dist/config/agent-resolver.js +0 -123
- package/dist/config/error-codes.cjs +0 -39
- package/dist/config/error-codes.d.ts +0 -16
- package/dist/config/error-codes.d.ts.map +0 -1
- package/dist/config/error-codes.js +0 -16
- package/dist/config/errors.cjs +0 -126
- package/dist/config/errors.d.ts +0 -34
- package/dist/config/errors.d.ts.map +0 -1
- package/dist/config/errors.js +0 -103
- package/dist/config/index.cjs +0 -26
- package/dist/config/index.d.ts +0 -4
- package/dist/config/index.d.ts.map +0 -1
- package/dist/config/index.js +0 -3
- package/dist/config/loader.cjs +0 -119
- package/dist/config/loader.d.ts +0 -16
- package/dist/config/loader.d.ts.map +0 -1
- package/dist/config/loader.js +0 -86
- package/dist/config/writer.cjs +0 -182
- package/dist/config/writer.d.ts +0 -35
- package/dist/config/writer.d.ts.map +0 -1
- package/dist/config/writer.js +0 -147
- package/dist/preferences/constants.d.ts +0 -2
- package/dist/preferences/constants.d.ts.map +0 -1
- package/dist/preferences/constants.js +0 -5
- package/dist/preferences/error-codes.d.ts +0 -8
- package/dist/preferences/error-codes.d.ts.map +0 -1
- package/dist/preferences/error-codes.js +0 -12
- package/dist/preferences/errors.cjs +0 -75
- package/dist/preferences/errors.d.ts +0 -18
- package/dist/preferences/errors.d.ts.map +0 -1
- package/dist/preferences/errors.js +0 -51
- package/dist/preferences/index.cjs +0 -55
- package/dist/preferences/index.d.ts +0 -6
- package/dist/preferences/index.d.ts.map +0 -1
- package/dist/preferences/index.js +0 -32
- package/dist/preferences/loader.cjs +0 -138
- package/dist/preferences/loader.d.ts +0 -51
- package/dist/preferences/loader.d.ts.map +0 -1
- package/dist/preferences/loader.js +0 -110
- package/dist/preferences/schemas.cjs +0 -75
- package/dist/preferences/schemas.d.ts +0 -110
- package/dist/preferences/schemas.d.ts.map +0 -1
- package/dist/preferences/schemas.js +0 -49
- package/dist/prompts/providers/file-prompt-provider.cjs +0 -399
- package/dist/prompts/providers/file-prompt-provider.d.ts +0 -47
- package/dist/prompts/providers/file-prompt-provider.d.ts.map +0 -1
- package/dist/prompts/providers/file-prompt-provider.js +0 -376
- package/dist/prompts/providers/starter-prompt-provider.cjs +0 -170
- package/dist/prompts/providers/starter-prompt-provider.d.ts +0 -45
- package/dist/prompts/providers/starter-prompt-provider.d.ts.map +0 -1
- package/dist/prompts/providers/starter-prompt-provider.js +0 -147
- package/dist/utils/api-key-store.cjs +0 -56
- package/dist/utils/api-key-store.d.ts +0 -24
- package/dist/utils/api-key-store.d.ts.map +0 -1
- package/dist/utils/api-key-store.js +0 -31
- package/dist/utils/env.cjs +0 -154
- package/dist/utils/env.d.ts +0 -28
- package/dist/utils/env.d.ts.map +0 -1
- package/dist/utils/env.js +0 -119
- package/dist/utils/port-utils.cjs +0 -37
- package/dist/utils/port-utils.d.ts +0 -10
- package/dist/utils/port-utils.d.ts.map +0 -1
- package/dist/utils/port-utils.js +0 -14
- package/dist/utils/port-utils.spec.cjs +0 -26
- package/dist/utils/port-utils.spec.js +0 -25
- /package/dist/approval/{providers/factory.cjs → factory.cjs} +0 -0
package/dist/agent/DextoAgent.js
CHANGED
|
@@ -8,16 +8,19 @@ import { expandMessageReferences } from "../resources/index.js";
|
|
|
8
8
|
import { expandBlobReferences } from "../context/utils.js";
|
|
9
9
|
import { PromptManager } from "../prompts/index.js";
|
|
10
10
|
import { SessionError } from "../session/index.js";
|
|
11
|
-
import {
|
|
11
|
+
import { createLogger } from "../logger/factory.js";
|
|
12
|
+
import { DextoLogComponent } from "../logger/v2/types.js";
|
|
12
13
|
import { InstrumentClass } from "../telemetry/decorators.js";
|
|
14
|
+
import { trace, context, propagation } from "@opentelemetry/api";
|
|
13
15
|
import { LLMUpdatesSchema } from "../llm/schemas.js";
|
|
14
16
|
import { resolveAndValidateLLMConfig } from "../llm/resolver.js";
|
|
15
17
|
import { validateInputForLLM } from "../llm/validation.js";
|
|
18
|
+
import { LLMError } from "../llm/errors.js";
|
|
16
19
|
import { AgentError } from "./errors.js";
|
|
17
20
|
import { MCPError } from "../mcp/errors.js";
|
|
21
|
+
import { DextoRuntimeError } from "../errors/DextoRuntimeError.js";
|
|
18
22
|
import { ensureOk } from "../errors/result-bridge.js";
|
|
19
23
|
import { fail, zodToIssues } from "../utils/result.js";
|
|
20
|
-
import { DextoValidationError } from "../errors/DextoValidationError.js";
|
|
21
24
|
import { resolveAndValidateMcpServerConfig } from "../mcp/resolver.js";
|
|
22
25
|
import {
|
|
23
26
|
getSupportedProviders,
|
|
@@ -27,11 +30,11 @@ import {
|
|
|
27
30
|
} from "../llm/registry.js";
|
|
28
31
|
import { createAgentServices } from "../utils/service-initializer.js";
|
|
29
32
|
import { AgentConfigSchema } from "./schemas.js";
|
|
30
|
-
import {
|
|
33
|
+
import {
|
|
34
|
+
AgentEventBus,
|
|
35
|
+
STREAMING_EVENTS
|
|
36
|
+
} from "../events/index.js";
|
|
31
37
|
import { safeStringify } from "../utils/safe-stringify.js";
|
|
32
|
-
import { loadAgentConfig } from "../config/loader.js";
|
|
33
|
-
import { promises as fs } from "fs";
|
|
34
|
-
import { parseDocument } from "yaml";
|
|
35
38
|
import { deriveHeuristicTitle, generateSessionTitle } from "../session/title-generator.js";
|
|
36
39
|
const requiredServices = [
|
|
37
40
|
"mcpManager",
|
|
@@ -55,10 +58,22 @@ _DextoAgent_decorators = [InstrumentClass({
|
|
|
55
58
|
]
|
|
56
59
|
})];
|
|
57
60
|
class DextoAgent {
|
|
61
|
+
/**
|
|
62
|
+
* Creates a DextoAgent instance.
|
|
63
|
+
*
|
|
64
|
+
* @param config - Agent configuration (validated and enriched)
|
|
65
|
+
* @param configPath - Optional path to config file (for relative path resolution)
|
|
66
|
+
*/
|
|
58
67
|
constructor(config, configPath) {
|
|
59
68
|
this.configPath = configPath;
|
|
60
69
|
this.config = AgentConfigSchema.parse(config);
|
|
61
|
-
logger
|
|
70
|
+
this.logger = createLogger({
|
|
71
|
+
config: this.config.logger,
|
|
72
|
+
agentId: this.config.agentId,
|
|
73
|
+
component: DextoLogComponent.AGENT
|
|
74
|
+
});
|
|
75
|
+
this.agentEventBus = new AgentEventBus();
|
|
76
|
+
this.logger.info("DextoAgent created.");
|
|
62
77
|
}
|
|
63
78
|
/**
|
|
64
79
|
* These services are public for use by the outside world
|
|
@@ -77,19 +92,20 @@ class DextoAgent {
|
|
|
77
92
|
services;
|
|
78
93
|
// Search service for conversation search
|
|
79
94
|
searchService;
|
|
80
|
-
// Default session for backward compatibility
|
|
81
|
-
defaultSession = null;
|
|
82
|
-
// Current default session ID for loadSession functionality
|
|
83
|
-
currentDefaultSessionId = "default";
|
|
84
95
|
// Track initialization state
|
|
85
96
|
_isStarted = false;
|
|
86
97
|
_isStopped = false;
|
|
87
|
-
// Store config for async initialization
|
|
98
|
+
// Store config for async initialization (accessible before start() for setup)
|
|
88
99
|
config;
|
|
89
|
-
// Event subscribers (e.g.,
|
|
100
|
+
// Event subscribers (e.g., SSE, Webhook handlers)
|
|
90
101
|
eventSubscribers = /* @__PURE__ */ new Set();
|
|
91
102
|
// Telemetry instance for distributed tracing
|
|
92
103
|
telemetry;
|
|
104
|
+
// Approval handler for manual tool confirmation and elicitation
|
|
105
|
+
// Set via setApprovalHandler() before start() if needed
|
|
106
|
+
approvalHandler;
|
|
107
|
+
// Logger instance for this agent (dependency injection)
|
|
108
|
+
logger;
|
|
93
109
|
/**
|
|
94
110
|
* Starts the agent by initializing all async services.
|
|
95
111
|
* This method handles storage backends, MCP connections, session manager initialization, and other async operations.
|
|
@@ -102,8 +118,13 @@ class DextoAgent {
|
|
|
102
118
|
throw AgentError.alreadyStarted();
|
|
103
119
|
}
|
|
104
120
|
try {
|
|
105
|
-
logger.info("Starting DextoAgent...");
|
|
106
|
-
const services = await createAgentServices(
|
|
121
|
+
this.logger.info("Starting DextoAgent...");
|
|
122
|
+
const services = await createAgentServices(
|
|
123
|
+
this.config,
|
|
124
|
+
this.configPath,
|
|
125
|
+
this.logger,
|
|
126
|
+
this.agentEventBus
|
|
127
|
+
);
|
|
107
128
|
for (const service of requiredServices) {
|
|
108
129
|
if (!services[service]) {
|
|
109
130
|
throw AgentError.initializationFailed(
|
|
@@ -111,12 +132,31 @@ class DextoAgent {
|
|
|
111
132
|
);
|
|
112
133
|
}
|
|
113
134
|
}
|
|
135
|
+
const needsHandler = this.config.toolConfirmation.mode === "manual" || this.config.elicitation.enabled;
|
|
136
|
+
if (needsHandler && !this.approvalHandler) {
|
|
137
|
+
const reasons = [];
|
|
138
|
+
if (this.config.toolConfirmation.mode === "manual") {
|
|
139
|
+
reasons.push('tool confirmation mode is "manual"');
|
|
140
|
+
}
|
|
141
|
+
if (this.config.elicitation.enabled) {
|
|
142
|
+
reasons.push("elicitation is enabled");
|
|
143
|
+
}
|
|
144
|
+
throw AgentError.initializationFailed(
|
|
145
|
+
`An approval handler is required but not configured (${reasons.join(" and ")}).
|
|
146
|
+
Either:
|
|
147
|
+
\u2022 Call agent.setApprovalHandler() before starting
|
|
148
|
+
\u2022 Set toolConfirmation: { mode: "auto-approve" } or { mode: "auto-deny" }
|
|
149
|
+
\u2022 Disable elicitation: { enabled: false }`
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
if (this.approvalHandler) {
|
|
153
|
+
services.approvalManager.setHandler(this.approvalHandler);
|
|
154
|
+
}
|
|
114
155
|
Object.assign(this, {
|
|
115
156
|
mcpManager: services.mcpManager,
|
|
116
157
|
toolManager: services.toolManager,
|
|
117
158
|
resourceManager: services.resourceManager,
|
|
118
159
|
systemPromptManager: services.systemPromptManager,
|
|
119
|
-
agentEventBus: services.agentEventBus,
|
|
120
160
|
stateManager: services.stateManager,
|
|
121
161
|
sessionManager: services.sessionManager,
|
|
122
162
|
memoryManager: services.memoryManager,
|
|
@@ -128,20 +168,25 @@ class DextoAgent {
|
|
|
128
168
|
this.resourceManager,
|
|
129
169
|
this.config,
|
|
130
170
|
this.agentEventBus,
|
|
131
|
-
services.storageManager.getDatabase()
|
|
171
|
+
services.storageManager.getDatabase(),
|
|
172
|
+
this.logger
|
|
132
173
|
);
|
|
133
174
|
await promptManager.initialize();
|
|
134
175
|
Object.assign(this, { promptManager });
|
|
135
176
|
this._isStarted = true;
|
|
136
177
|
this._isStopped = false;
|
|
137
|
-
logger.info("DextoAgent started successfully.");
|
|
178
|
+
this.logger.info("DextoAgent started successfully.");
|
|
138
179
|
for (const subscriber of this.eventSubscribers) {
|
|
139
180
|
subscriber.subscribe(this.agentEventBus);
|
|
140
181
|
}
|
|
141
|
-
const
|
|
142
|
-
|
|
182
|
+
const fileTransport = this.config.logger?.transports?.find((t) => t.type === "file");
|
|
183
|
+
if (fileTransport && "path" in fileTransport) {
|
|
184
|
+
console.log(`\u{1F4CB} Logs available at: ${fileTransport.path}`);
|
|
185
|
+
}
|
|
143
186
|
} catch (error) {
|
|
144
|
-
logger.error("Failed to start DextoAgent",
|
|
187
|
+
this.logger.error("Failed to start DextoAgent", {
|
|
188
|
+
error: error instanceof Error ? error.message : String(error)
|
|
189
|
+
});
|
|
145
190
|
throw error;
|
|
146
191
|
}
|
|
147
192
|
}
|
|
@@ -154,19 +199,19 @@ class DextoAgent {
|
|
|
154
199
|
*/
|
|
155
200
|
async stop() {
|
|
156
201
|
if (this._isStopped) {
|
|
157
|
-
logger.warn("Agent is already stopped");
|
|
202
|
+
this.logger.warn("Agent is already stopped");
|
|
158
203
|
return;
|
|
159
204
|
}
|
|
160
205
|
if (!this._isStarted) {
|
|
161
206
|
throw AgentError.notStarted();
|
|
162
207
|
}
|
|
163
208
|
try {
|
|
164
|
-
logger.info("Stopping DextoAgent...");
|
|
209
|
+
this.logger.info("Stopping DextoAgent...");
|
|
165
210
|
const shutdownErrors = [];
|
|
166
211
|
try {
|
|
167
212
|
if (this.sessionManager) {
|
|
168
213
|
await this.sessionManager.cleanup();
|
|
169
|
-
logger.debug("SessionManager cleaned up successfully");
|
|
214
|
+
this.logger.debug("SessionManager cleaned up successfully");
|
|
170
215
|
}
|
|
171
216
|
} catch (error) {
|
|
172
217
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
@@ -175,7 +220,7 @@ class DextoAgent {
|
|
|
175
220
|
try {
|
|
176
221
|
if (this.services?.pluginManager) {
|
|
177
222
|
await this.services.pluginManager.cleanup();
|
|
178
|
-
logger.debug("PluginManager cleaned up successfully");
|
|
223
|
+
this.logger.debug("PluginManager cleaned up successfully");
|
|
179
224
|
}
|
|
180
225
|
} catch (error) {
|
|
181
226
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
@@ -184,7 +229,7 @@ class DextoAgent {
|
|
|
184
229
|
try {
|
|
185
230
|
if (this.mcpManager) {
|
|
186
231
|
await this.mcpManager.disconnectAll();
|
|
187
|
-
logger.debug("MCPManager disconnected all clients successfully");
|
|
232
|
+
this.logger.debug("MCPManager disconnected all clients successfully");
|
|
188
233
|
}
|
|
189
234
|
} catch (error) {
|
|
190
235
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
@@ -193,7 +238,7 @@ class DextoAgent {
|
|
|
193
238
|
try {
|
|
194
239
|
if (this.services?.storageManager) {
|
|
195
240
|
await this.services.storageManager.disconnect();
|
|
196
|
-
logger.debug("Storage manager disconnected successfully");
|
|
241
|
+
this.logger.debug("Storage manager disconnected successfully");
|
|
197
242
|
}
|
|
198
243
|
} catch (error) {
|
|
199
244
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
@@ -203,18 +248,20 @@ class DextoAgent {
|
|
|
203
248
|
this._isStarted = false;
|
|
204
249
|
if (shutdownErrors.length > 0) {
|
|
205
250
|
const errorMessages = shutdownErrors.map((e) => e.message).join("; ");
|
|
206
|
-
logger.warn(`DextoAgent stopped with some errors: ${errorMessages}`);
|
|
251
|
+
this.logger.warn(`DextoAgent stopped with some errors: ${errorMessages}`);
|
|
207
252
|
} else {
|
|
208
|
-
logger.info("DextoAgent stopped successfully.");
|
|
253
|
+
this.logger.info("DextoAgent stopped successfully.");
|
|
209
254
|
}
|
|
210
255
|
} catch (error) {
|
|
211
|
-
logger.error("Failed to stop DextoAgent",
|
|
256
|
+
this.logger.error("Failed to stop DextoAgent", {
|
|
257
|
+
error: error instanceof Error ? error.message : String(error)
|
|
258
|
+
});
|
|
212
259
|
throw error;
|
|
213
260
|
}
|
|
214
261
|
}
|
|
215
262
|
/**
|
|
216
263
|
* Register an event subscriber that will be automatically re-subscribed on agent restart.
|
|
217
|
-
* Subscribers are typically API layer components (
|
|
264
|
+
* Subscribers are typically API layer components (SSE, Webhook handlers) that need
|
|
218
265
|
* to receive agent events. If the agent is already started, the subscriber is immediately subscribed.
|
|
219
266
|
*
|
|
220
267
|
* @param subscriber - Object implementing AgentEventSubscriber interface
|
|
@@ -256,11 +303,11 @@ class DextoAgent {
|
|
|
256
303
|
*/
|
|
257
304
|
ensureStarted() {
|
|
258
305
|
if (this._isStopped) {
|
|
259
|
-
logger.warn("Agent is stopped");
|
|
306
|
+
this.logger.warn("Agent is stopped");
|
|
260
307
|
throw AgentError.stopped();
|
|
261
308
|
}
|
|
262
309
|
if (!this._isStarted) {
|
|
263
|
-
logger.warn("Agent is not started");
|
|
310
|
+
this.logger.warn("Agent is not started");
|
|
264
311
|
throw AgentError.notStarted();
|
|
265
312
|
}
|
|
266
313
|
}
|
|
@@ -272,110 +319,347 @@ class DextoAgent {
|
|
|
272
319
|
* @param textInput - The user's text message or query to process
|
|
273
320
|
* @param imageDataInput - Optional image data and MIME type for multimodal input
|
|
274
321
|
* @param fileDataInput - Optional file data and MIME type for file input
|
|
275
|
-
* @param sessionId -
|
|
322
|
+
* @param sessionId - Session ID for the conversation (required)
|
|
323
|
+
* @param stream - Whether to stream the response (default: false)
|
|
276
324
|
* @returns Promise that resolves to the AI's response text, or null if no significant response
|
|
277
325
|
* @throws Error if processing fails
|
|
278
326
|
*/
|
|
279
327
|
async run(textInput, imageDataInput, fileDataInput, sessionId, stream = false) {
|
|
280
328
|
this.ensureStarted();
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
329
|
+
if (!sessionId || typeof sessionId !== "string") {
|
|
330
|
+
throw new Error("sessionId is required and must be a non-empty string");
|
|
331
|
+
}
|
|
332
|
+
const targetSessionId = sessionId;
|
|
333
|
+
const activeContext = context.active();
|
|
334
|
+
const span = trace.getActiveSpan();
|
|
335
|
+
if (span) {
|
|
336
|
+
span.setAttribute("sessionId", targetSessionId);
|
|
337
|
+
}
|
|
338
|
+
const existingBaggage = propagation.getBaggage(activeContext);
|
|
339
|
+
const baggageEntries = {};
|
|
340
|
+
if (existingBaggage) {
|
|
341
|
+
existingBaggage.getAllEntries().forEach(([key, entry]) => {
|
|
342
|
+
baggageEntries[key] = { ...entry };
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
baggageEntries.sessionId = { ...baggageEntries.sessionId, value: targetSessionId };
|
|
346
|
+
const updatedContext = propagation.setBaggage(
|
|
347
|
+
activeContext,
|
|
348
|
+
propagation.createBaggage(baggageEntries)
|
|
349
|
+
);
|
|
350
|
+
const verifyBaggage = propagation.getBaggage(updatedContext);
|
|
351
|
+
this.logger.debug(
|
|
352
|
+
`Baggage after setting sessionId: ${JSON.stringify(
|
|
353
|
+
Array.from(verifyBaggage?.getAllEntries() || [])
|
|
354
|
+
)}`
|
|
355
|
+
);
|
|
356
|
+
return await context.with(updatedContext, async () => {
|
|
357
|
+
try {
|
|
358
|
+
const llmConfig = this.stateManager.getLLMConfig(targetSessionId);
|
|
359
|
+
const validation = validateInputForLLM(
|
|
360
|
+
{
|
|
361
|
+
text: textInput,
|
|
362
|
+
...imageDataInput && { imageData: imageDataInput },
|
|
363
|
+
...fileDataInput && { fileData: fileDataInput }
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
provider: llmConfig.provider,
|
|
367
|
+
model: llmConfig.model
|
|
368
|
+
},
|
|
369
|
+
this.logger
|
|
370
|
+
);
|
|
371
|
+
ensureOk(validation, this.logger);
|
|
372
|
+
const session = await this.sessionManager.getSession(targetSessionId) || await this.sessionManager.createSession(targetSessionId);
|
|
373
|
+
this.logger.debug(
|
|
374
|
+
`DextoAgent.run: sessionId=${targetSessionId}, textLength=${textInput?.length ?? 0}, hasImage=${Boolean(
|
|
375
|
+
imageDataInput
|
|
376
|
+
)}, hasFile=${Boolean(fileDataInput)}`
|
|
377
|
+
);
|
|
378
|
+
let finalText = textInput;
|
|
379
|
+
let finalImageData = imageDataInput;
|
|
380
|
+
if (textInput && textInput.includes("@")) {
|
|
381
|
+
try {
|
|
382
|
+
const resources = await this.resourceManager.list();
|
|
383
|
+
const expansion = await expandMessageReferences(
|
|
384
|
+
textInput,
|
|
385
|
+
resources,
|
|
386
|
+
(uri) => this.resourceManager.read(uri)
|
|
324
387
|
);
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
if (firstImage) {
|
|
330
|
-
finalImageData = {
|
|
331
|
-
image: firstImage.image,
|
|
332
|
-
mimeType: firstImage.mimeType
|
|
333
|
-
};
|
|
334
|
-
logger.debug(
|
|
335
|
-
`Using extracted image: ${firstImage.name} (${firstImage.mimeType})`
|
|
388
|
+
if (expansion.unresolvedReferences.length > 0) {
|
|
389
|
+
const unresolvedNames = expansion.unresolvedReferences.map((ref) => ref.originalRef).join(", ");
|
|
390
|
+
this.logger.warn(
|
|
391
|
+
`Could not resolve ${expansion.unresolvedReferences.length} resource reference(s): ${unresolvedNames}`
|
|
336
392
|
);
|
|
337
393
|
}
|
|
394
|
+
const MAX_EXPANDED_SIZE = 5 * 1024 * 1024;
|
|
395
|
+
const expandedSize = Buffer.byteLength(expansion.expandedMessage, "utf-8");
|
|
396
|
+
if (expandedSize > MAX_EXPANDED_SIZE) {
|
|
397
|
+
this.logger.warn(
|
|
398
|
+
`Expanded message size (${(expandedSize / 1024 / 1024).toFixed(2)}MB) exceeds limit (${MAX_EXPANDED_SIZE / 1024 / 1024}MB). Content may be truncated.`
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
finalText = expansion.expandedMessage;
|
|
402
|
+
if (expansion.extractedImages.length > 0 && !imageDataInput) {
|
|
403
|
+
const firstImage = expansion.extractedImages[0];
|
|
404
|
+
if (firstImage) {
|
|
405
|
+
finalImageData = {
|
|
406
|
+
image: firstImage.image,
|
|
407
|
+
mimeType: firstImage.mimeType
|
|
408
|
+
};
|
|
409
|
+
this.logger.debug(
|
|
410
|
+
`Using extracted image: ${firstImage.name} (${firstImage.mimeType})`
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
} catch (error) {
|
|
415
|
+
this.logger.error(
|
|
416
|
+
`Failed to expand resource references: ${error instanceof Error ? error.message : String(error)}. Continuing with original message.`
|
|
417
|
+
);
|
|
338
418
|
}
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
|
|
419
|
+
}
|
|
420
|
+
if (!finalText.trim() && !finalImageData && !fileDataInput) {
|
|
421
|
+
this.logger.warn(
|
|
422
|
+
"Resource expansion resulted in empty content. Using original message."
|
|
342
423
|
);
|
|
424
|
+
finalText = textInput;
|
|
343
425
|
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
426
|
+
const response = await session.run(
|
|
427
|
+
finalText,
|
|
428
|
+
finalImageData,
|
|
429
|
+
fileDataInput,
|
|
430
|
+
stream
|
|
348
431
|
);
|
|
349
|
-
|
|
432
|
+
this.sessionManager.incrementMessageCount(session.id).catch(
|
|
433
|
+
(error) => this.logger.warn(
|
|
434
|
+
`Failed to increment message count: ${error instanceof Error ? error.message : String(error)}`
|
|
435
|
+
)
|
|
436
|
+
);
|
|
437
|
+
return response;
|
|
438
|
+
} catch (error) {
|
|
439
|
+
this.logger.error(
|
|
440
|
+
`Error during DextoAgent.run: ${error instanceof Error ? error.message : JSON.stringify(error)}`
|
|
441
|
+
);
|
|
442
|
+
throw error;
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Generate a complete response (waits for full completion).
|
|
448
|
+
* This is the recommended method for non-streaming use cases.
|
|
449
|
+
*
|
|
450
|
+
* @param message The user's message
|
|
451
|
+
* @param options Configuration options (sessionId is required, imageData, fileData, signal are optional)
|
|
452
|
+
* @returns Promise that resolves to the complete response
|
|
453
|
+
*
|
|
454
|
+
* @example
|
|
455
|
+
* ```typescript
|
|
456
|
+
* const response = await agent.generate("What is 2+2?", { sessionId: "default" });
|
|
457
|
+
* console.log(response.content); // "4"
|
|
458
|
+
* console.log(response.usage.totalTokens); // 50
|
|
459
|
+
* ```
|
|
460
|
+
*/
|
|
461
|
+
async generate(message, options) {
|
|
462
|
+
const events = [];
|
|
463
|
+
for await (const event of await this.stream(message, options)) {
|
|
464
|
+
events.push(event);
|
|
465
|
+
}
|
|
466
|
+
const errorEvent = events.find(
|
|
467
|
+
(e) => e.type === "llm:error"
|
|
468
|
+
);
|
|
469
|
+
if (errorEvent) {
|
|
470
|
+
if (errorEvent.error instanceof DextoRuntimeError) {
|
|
471
|
+
throw errorEvent.error;
|
|
350
472
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
)
|
|
473
|
+
const llmConfig = this.stateManager.getLLMConfig(options.sessionId);
|
|
474
|
+
throw LLMError.generationFailed(
|
|
475
|
+
errorEvent.error.message,
|
|
476
|
+
llmConfig.provider,
|
|
477
|
+
llmConfig.model
|
|
357
478
|
);
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
479
|
+
}
|
|
480
|
+
const responseEvent = events.find((e) => e.type === "llm:response");
|
|
481
|
+
if (!responseEvent || responseEvent.type !== "llm:response") {
|
|
482
|
+
const llmConfig = this.stateManager.getLLMConfig(options.sessionId);
|
|
483
|
+
throw LLMError.generationFailed(
|
|
484
|
+
"Stream did not complete successfully - no response received",
|
|
485
|
+
llmConfig.provider,
|
|
486
|
+
llmConfig.model
|
|
362
487
|
);
|
|
363
|
-
throw error;
|
|
364
488
|
}
|
|
489
|
+
const toolCallEvents = events.filter(
|
|
490
|
+
(e) => e.type === "llm:tool-call"
|
|
491
|
+
);
|
|
492
|
+
const toolResultEvents = events.filter(
|
|
493
|
+
(e) => e.type === "llm:tool-result"
|
|
494
|
+
);
|
|
495
|
+
const toolCalls = toolCallEvents.map((tc) => {
|
|
496
|
+
const toolResult = toolResultEvents.find((tr) => tr.callId === tc.callId);
|
|
497
|
+
return {
|
|
498
|
+
toolName: tc.toolName,
|
|
499
|
+
args: tc.args,
|
|
500
|
+
callId: tc.callId || `tool_${Date.now()}`,
|
|
501
|
+
result: toolResult ? {
|
|
502
|
+
success: toolResult.success,
|
|
503
|
+
data: toolResult.sanitized
|
|
504
|
+
} : void 0
|
|
505
|
+
};
|
|
506
|
+
});
|
|
507
|
+
const messageId = `msg_${Date.now()}_${Math.random().toString(36).substring(7)}`;
|
|
508
|
+
const defaultUsage = {
|
|
509
|
+
inputTokens: 0,
|
|
510
|
+
outputTokens: 0,
|
|
511
|
+
totalTokens: 0
|
|
512
|
+
};
|
|
513
|
+
const usage = responseEvent.tokenUsage ?? defaultUsage;
|
|
514
|
+
return {
|
|
515
|
+
content: responseEvent.content,
|
|
516
|
+
reasoning: responseEvent.reasoning,
|
|
517
|
+
usage,
|
|
518
|
+
toolCalls,
|
|
519
|
+
sessionId: options.sessionId,
|
|
520
|
+
messageId
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Stream a response (yields events as they arrive).
|
|
525
|
+
* This is the recommended method for real-time streaming UI updates.
|
|
526
|
+
*
|
|
527
|
+
* TODO: Refactor to move AsyncIterator down to LLM service level (Option 1).
|
|
528
|
+
* Streaming message API that returns core AgentEvents in real-time.
|
|
529
|
+
* Only emits STREAMING_EVENTS (tier 1 visibility) - events designed for real-time chat UIs.
|
|
530
|
+
*
|
|
531
|
+
* Events are forwarded directly from the AgentEventBus with no mapping layer,
|
|
532
|
+
* providing a unified event system across all API layers.
|
|
533
|
+
*
|
|
534
|
+
* @param message The user's message
|
|
535
|
+
* @param options Configuration options (sessionId is required, imageData, fileData, signal are optional)
|
|
536
|
+
* @returns AsyncIterator that yields StreamingEvent objects (core events with type property)
|
|
537
|
+
*
|
|
538
|
+
* @example
|
|
539
|
+
* ```typescript
|
|
540
|
+
* for await (const event of await agent.stream("Write a poem", { sessionId: "default" })) {
|
|
541
|
+
* if (event.type === 'llm:chunk') {
|
|
542
|
+
* process.stdout.write(event.content);
|
|
543
|
+
* }
|
|
544
|
+
* if (event.type === 'llm:tool-call') {
|
|
545
|
+
* console.log(`\n[Using ${event.toolName}]\n`);
|
|
546
|
+
* }
|
|
547
|
+
* }
|
|
548
|
+
* ```
|
|
549
|
+
*/
|
|
550
|
+
async stream(message, options) {
|
|
551
|
+
this.ensureStarted();
|
|
552
|
+
if (!options.sessionId) {
|
|
553
|
+
throw new Error("sessionId is required in StreamOptions");
|
|
554
|
+
}
|
|
555
|
+
const sessionId = options.sessionId;
|
|
556
|
+
const imageData = options.imageData;
|
|
557
|
+
const fileData = options.fileData;
|
|
558
|
+
const signal = options.signal;
|
|
559
|
+
const eventQueue = [];
|
|
560
|
+
let completed = false;
|
|
561
|
+
let _streamError = null;
|
|
562
|
+
const controller = new AbortController();
|
|
563
|
+
const cleanupSignal = controller.signal;
|
|
564
|
+
const listeners = [];
|
|
565
|
+
const cleanupListeners = () => {
|
|
566
|
+
if (listeners.length === 0) {
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
for (const { event, listener } of listeners) {
|
|
570
|
+
this.agentEventBus.off(event, listener);
|
|
571
|
+
}
|
|
572
|
+
listeners.length = 0;
|
|
573
|
+
};
|
|
574
|
+
if (signal) {
|
|
575
|
+
const abortHandler = () => {
|
|
576
|
+
cleanupListeners();
|
|
577
|
+
controller.abort();
|
|
578
|
+
};
|
|
579
|
+
signal.addEventListener("abort", abortHandler, { once: true });
|
|
580
|
+
}
|
|
581
|
+
for (const eventName of STREAMING_EVENTS) {
|
|
582
|
+
const listener = (data) => {
|
|
583
|
+
if (data.sessionId !== void 0 && data.sessionId !== sessionId) {
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
eventQueue.push({ type: eventName, ...data });
|
|
587
|
+
if (eventName === "llm:response" || eventName === "llm:error" && !data.recoverable) {
|
|
588
|
+
completed = true;
|
|
589
|
+
}
|
|
590
|
+
};
|
|
591
|
+
this.agentEventBus.on(eventName, listener, {
|
|
592
|
+
signal: cleanupSignal
|
|
593
|
+
});
|
|
594
|
+
listeners.push({ event: eventName, listener });
|
|
595
|
+
}
|
|
596
|
+
const imageDataForRun = imageData ? {
|
|
597
|
+
image: typeof imageData.image === "string" ? imageData.image : imageData.image.toString(),
|
|
598
|
+
mimeType: imageData.mimeType || "image/png"
|
|
599
|
+
} : void 0;
|
|
600
|
+
const fileDataForRun = fileData ? {
|
|
601
|
+
data: typeof fileData.data === "string" ? fileData.data : fileData.data.toString(),
|
|
602
|
+
mimeType: fileData.mimeType,
|
|
603
|
+
...fileData.filename && { filename: fileData.filename }
|
|
604
|
+
} : void 0;
|
|
605
|
+
this.run(message, imageDataForRun, fileDataForRun, sessionId, true).catch((error) => {
|
|
606
|
+
_streamError = error;
|
|
607
|
+
completed = true;
|
|
608
|
+
this.logger.error(
|
|
609
|
+
`Error in DextoAgent.stream: ${error instanceof Error ? error.message : String(error)}`
|
|
610
|
+
);
|
|
611
|
+
eventQueue.push({
|
|
612
|
+
type: "llm:error",
|
|
613
|
+
error,
|
|
614
|
+
recoverable: false,
|
|
615
|
+
context: "run_failed",
|
|
616
|
+
sessionId
|
|
617
|
+
});
|
|
618
|
+
});
|
|
619
|
+
const iterator = {
|
|
620
|
+
async next() {
|
|
621
|
+
while (!completed && eventQueue.length === 0) {
|
|
622
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
623
|
+
if (signal?.aborted) {
|
|
624
|
+
cleanupListeners();
|
|
625
|
+
controller.abort();
|
|
626
|
+
return { done: true, value: void 0 };
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
if (eventQueue.length > 0) {
|
|
630
|
+
return { done: false, value: eventQueue.shift() };
|
|
631
|
+
}
|
|
632
|
+
if (completed) {
|
|
633
|
+
cleanupListeners();
|
|
634
|
+
controller.abort();
|
|
635
|
+
return { done: true, value: void 0 };
|
|
636
|
+
}
|
|
637
|
+
cleanupListeners();
|
|
638
|
+
return { done: true, value: void 0 };
|
|
639
|
+
},
|
|
640
|
+
async return() {
|
|
641
|
+
cleanupListeners();
|
|
642
|
+
controller.abort();
|
|
643
|
+
return { done: true, value: void 0 };
|
|
644
|
+
},
|
|
645
|
+
[Symbol.asyncIterator]() {
|
|
646
|
+
return iterator;
|
|
647
|
+
}
|
|
648
|
+
};
|
|
649
|
+
return iterator;
|
|
365
650
|
}
|
|
366
651
|
/**
|
|
367
|
-
* Cancels the currently running turn for a session
|
|
652
|
+
* Cancels the currently running turn for a session.
|
|
368
653
|
* Safe to call even if no run is in progress.
|
|
369
|
-
* @param sessionId
|
|
654
|
+
* @param sessionId Session id (required)
|
|
370
655
|
* @returns true if a run was in progress and was signaled to abort; false otherwise
|
|
371
656
|
*/
|
|
372
657
|
async cancel(sessionId) {
|
|
373
658
|
this.ensureStarted();
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
return this.defaultSession.cancel();
|
|
659
|
+
if (!sessionId || typeof sessionId !== "string") {
|
|
660
|
+
throw new Error("sessionId is required and must be a non-empty string");
|
|
377
661
|
}
|
|
378
|
-
const existing = await this.sessionManager.getSession(
|
|
662
|
+
const existing = await this.sessionManager.getSession(sessionId, false);
|
|
379
663
|
if (existing) {
|
|
380
664
|
return existing.cancel();
|
|
381
665
|
}
|
|
@@ -415,9 +699,6 @@ class DextoAgent {
|
|
|
415
699
|
*/
|
|
416
700
|
async endSession(sessionId) {
|
|
417
701
|
this.ensureStarted();
|
|
418
|
-
if (sessionId === this.currentDefaultSessionId) {
|
|
419
|
-
this.defaultSession = null;
|
|
420
|
-
}
|
|
421
702
|
return this.sessionManager.endSession(sessionId);
|
|
422
703
|
}
|
|
423
704
|
/**
|
|
@@ -427,9 +708,6 @@ class DextoAgent {
|
|
|
427
708
|
*/
|
|
428
709
|
async deleteSession(sessionId) {
|
|
429
710
|
this.ensureStarted();
|
|
430
|
-
if (sessionId === this.currentDefaultSessionId) {
|
|
431
|
-
this.defaultSession = null;
|
|
432
|
-
}
|
|
433
711
|
return this.sessionManager.deleteSession(sessionId);
|
|
434
712
|
}
|
|
435
713
|
/**
|
|
@@ -456,66 +734,63 @@ class DextoAgent {
|
|
|
456
734
|
return await this.sessionManager.getSessionTitle(sessionId);
|
|
457
735
|
}
|
|
458
736
|
/**
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
*
|
|
737
|
+
* Generate a title for a session on-demand.
|
|
738
|
+
* Uses the first user message content to generate a descriptive title.
|
|
739
|
+
*
|
|
740
|
+
* @param sessionId Session ID to generate title for
|
|
741
|
+
* @returns Promise that resolves to the generated title, or null if generation failed
|
|
462
742
|
*/
|
|
463
|
-
async
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
if (metadata.title) {
|
|
473
|
-
logger.debug(
|
|
474
|
-
`[SessionTitle] Session ${sessionId} already has title '${metadata.title}', skipping`
|
|
475
|
-
);
|
|
476
|
-
return;
|
|
477
|
-
}
|
|
478
|
-
if (!userText || !userText.trim()) {
|
|
479
|
-
logger.debug(
|
|
480
|
-
`[SessionTitle] User text empty for session ${sessionId}, skipping title generation`
|
|
481
|
-
);
|
|
482
|
-
return;
|
|
483
|
-
}
|
|
484
|
-
logger.debug(
|
|
485
|
-
`[SessionTitle] Checking title generation preconditions for session ${sessionId}`
|
|
486
|
-
);
|
|
487
|
-
const result = await generateSessionTitle(
|
|
488
|
-
llmConfig,
|
|
489
|
-
llmConfig.router,
|
|
490
|
-
this.toolManager,
|
|
491
|
-
this.systemPromptManager,
|
|
492
|
-
this.resourceManager,
|
|
493
|
-
userText
|
|
743
|
+
async generateSessionTitle(sessionId) {
|
|
744
|
+
this.ensureStarted();
|
|
745
|
+
const metadata = await this.sessionManager.getSessionMetadata(sessionId);
|
|
746
|
+
if (!metadata) {
|
|
747
|
+
throw SessionError.notFound(sessionId);
|
|
748
|
+
}
|
|
749
|
+
if (metadata.title) {
|
|
750
|
+
this.logger.debug(
|
|
751
|
+
`[SessionTitle] Session ${sessionId} already has title '${metadata.title}'`
|
|
494
752
|
);
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
753
|
+
return metadata.title;
|
|
754
|
+
}
|
|
755
|
+
const session = await this.sessionManager.getSession(sessionId);
|
|
756
|
+
if (!session) {
|
|
757
|
+
throw SessionError.notFound(sessionId);
|
|
758
|
+
}
|
|
759
|
+
const history = await session.getHistory();
|
|
760
|
+
const firstUserMsg = history.find((m) => m.role === "user");
|
|
761
|
+
if (!firstUserMsg) {
|
|
762
|
+
this.logger.debug(`[SessionTitle] No user message found for session ${sessionId}`);
|
|
763
|
+
return null;
|
|
764
|
+
}
|
|
765
|
+
const userText = typeof firstUserMsg.content === "string" ? firstUserMsg.content : firstUserMsg.content?.filter((p) => p.type === "text").map((p) => p.text).join(" ");
|
|
766
|
+
if (!userText || !userText.trim()) {
|
|
767
|
+
this.logger.debug(`[SessionTitle] Empty user text for session ${sessionId}`);
|
|
768
|
+
return null;
|
|
769
|
+
}
|
|
770
|
+
const llmConfig = this.getEffectiveConfig(sessionId).llm;
|
|
771
|
+
const result = await generateSessionTitle(
|
|
772
|
+
llmConfig,
|
|
773
|
+
llmConfig.router,
|
|
774
|
+
this.toolManager,
|
|
775
|
+
this.systemPromptManager,
|
|
776
|
+
this.resourceManager,
|
|
777
|
+
userText,
|
|
778
|
+
this.logger
|
|
779
|
+
);
|
|
780
|
+
let title = result.title;
|
|
781
|
+
if (!title) {
|
|
782
|
+
title = deriveHeuristicTitle(userText);
|
|
783
|
+
if (title) {
|
|
784
|
+
this.logger.info(`[SessionTitle] Using heuristic title for ${sessionId}: ${title}`);
|
|
511
785
|
} else {
|
|
512
|
-
logger.
|
|
786
|
+
this.logger.debug(`[SessionTitle] No suitable title derived for ${sessionId}`);
|
|
787
|
+
return null;
|
|
513
788
|
}
|
|
514
|
-
|
|
515
|
-
this.
|
|
516
|
-
} catch (err) {
|
|
517
|
-
logger.silly(`Title generation skipped/failed for ${sessionId}: ${String(err)}`);
|
|
789
|
+
} else {
|
|
790
|
+
this.logger.info(`[SessionTitle] Generated LLM title for ${sessionId}: ${title}`);
|
|
518
791
|
}
|
|
792
|
+
await this.sessionManager.setSessionTitle(sessionId, title, { ifUnsetOnly: true });
|
|
793
|
+
return title;
|
|
519
794
|
}
|
|
520
795
|
/**
|
|
521
796
|
* Gets the conversation history for a specific session.
|
|
@@ -536,14 +811,16 @@ class DextoAgent {
|
|
|
536
811
|
return await Promise.all(
|
|
537
812
|
history.map(async (message) => ({
|
|
538
813
|
...message,
|
|
539
|
-
content: await expandBlobReferences(
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
814
|
+
content: await expandBlobReferences(
|
|
815
|
+
message.content,
|
|
816
|
+
this.resourceManager,
|
|
817
|
+
this.logger
|
|
818
|
+
).catch((error) => {
|
|
819
|
+
this.logger.warn(
|
|
820
|
+
`Failed to expand blob references in message: ${error instanceof Error ? error.message : String(error)}`
|
|
821
|
+
);
|
|
822
|
+
return message.content;
|
|
823
|
+
})
|
|
547
824
|
}))
|
|
548
825
|
);
|
|
549
826
|
}
|
|
@@ -569,88 +846,23 @@ class DextoAgent {
|
|
|
569
846
|
return await this.searchService.searchSessions(query);
|
|
570
847
|
}
|
|
571
848
|
/**
|
|
572
|
-
*
|
|
573
|
-
* All subsequent operations that don't specify a session ID will use this session.
|
|
574
|
-
* This provides a clean "current working session" pattern for API users.
|
|
575
|
-
*
|
|
576
|
-
* @param sessionId The session ID to load as default, or null to reset to original default
|
|
577
|
-
* @throws Error if session doesn't exist
|
|
578
|
-
*
|
|
579
|
-
* @example
|
|
580
|
-
* ```typescript
|
|
581
|
-
* // Load a specific session as default
|
|
582
|
-
* await agent.loadSessionAsDefault('project-alpha');
|
|
583
|
-
* await agent.run("What's the status?"); // Uses project-alpha session
|
|
584
|
-
*
|
|
585
|
-
* // Reset to original default
|
|
586
|
-
* await agent.loadSessionAsDefault(null);
|
|
587
|
-
* await agent.run("Hello"); // Uses 'default' session
|
|
588
|
-
* ```
|
|
589
|
-
*/
|
|
590
|
-
async loadSessionAsDefault(sessionId = null) {
|
|
591
|
-
this.ensureStarted();
|
|
592
|
-
if (sessionId === null) {
|
|
593
|
-
this.currentDefaultSessionId = "default";
|
|
594
|
-
this.defaultSession = null;
|
|
595
|
-
logger.debug("Agent default session reset to original default");
|
|
596
|
-
return;
|
|
597
|
-
}
|
|
598
|
-
const session = await this.sessionManager.getSession(sessionId);
|
|
599
|
-
if (!session) {
|
|
600
|
-
throw SessionError.notFound(sessionId);
|
|
601
|
-
}
|
|
602
|
-
this.currentDefaultSessionId = sessionId;
|
|
603
|
-
this.defaultSession = null;
|
|
604
|
-
logger.info(`Agent default session changed to: ${sessionId}`);
|
|
605
|
-
}
|
|
606
|
-
/**
|
|
607
|
-
* Gets the currently loaded default session ID.
|
|
608
|
-
* This reflects the session loaded via loadSession().
|
|
609
|
-
*
|
|
610
|
-
* @returns The current default session ID
|
|
611
|
-
*/
|
|
612
|
-
getCurrentSessionId() {
|
|
613
|
-
this.ensureStarted();
|
|
614
|
-
return this.currentDefaultSessionId;
|
|
615
|
-
}
|
|
616
|
-
/**
|
|
617
|
-
* Gets the currently loaded default session.
|
|
618
|
-
* This respects the session loaded via loadSession().
|
|
619
|
-
*
|
|
620
|
-
* @returns The current default ChatSession
|
|
621
|
-
*/
|
|
622
|
-
async getDefaultSession() {
|
|
623
|
-
this.ensureStarted();
|
|
624
|
-
if (!this.defaultSession || this.defaultSession.id !== this.currentDefaultSessionId) {
|
|
625
|
-
this.defaultSession = await this.sessionManager.createSession(
|
|
626
|
-
this.currentDefaultSessionId
|
|
627
|
-
);
|
|
628
|
-
}
|
|
629
|
-
return this.defaultSession;
|
|
630
|
-
}
|
|
631
|
-
/**
|
|
632
|
-
* Resets the conversation history for a specific session or the default session.
|
|
849
|
+
* Resets the conversation history for a specific session.
|
|
633
850
|
* Keeps the session alive but the conversation history is cleared.
|
|
634
|
-
* @param sessionId
|
|
851
|
+
* @param sessionId Session ID (required)
|
|
635
852
|
*/
|
|
636
853
|
async resetConversation(sessionId) {
|
|
637
854
|
this.ensureStarted();
|
|
855
|
+
if (!sessionId || typeof sessionId !== "string") {
|
|
856
|
+
throw new Error("sessionId is required and must be a non-empty string");
|
|
857
|
+
}
|
|
638
858
|
try {
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
this.currentDefaultSessionId
|
|
644
|
-
);
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
await this.sessionManager.resetSession(targetSessionId);
|
|
648
|
-
logger.info(`DextoAgent conversation reset for session: ${targetSessionId}`);
|
|
649
|
-
this.agentEventBus.emit("dexto:conversationReset", {
|
|
650
|
-
sessionId: targetSessionId
|
|
859
|
+
await this.sessionManager.resetSession(sessionId);
|
|
860
|
+
this.logger.info(`DextoAgent conversation reset for session: ${sessionId}`);
|
|
861
|
+
this.agentEventBus.emit("session:reset", {
|
|
862
|
+
sessionId
|
|
651
863
|
});
|
|
652
864
|
} catch (error) {
|
|
653
|
-
logger.error(
|
|
865
|
+
this.logger.error(
|
|
654
866
|
`Error during DextoAgent.resetConversation: ${error instanceof Error ? error.message : String(error)}`
|
|
655
867
|
);
|
|
656
868
|
throw error;
|
|
@@ -704,22 +916,24 @@ class DextoAgent {
|
|
|
704
916
|
*/
|
|
705
917
|
async switchLLM(llmUpdates, sessionId) {
|
|
706
918
|
this.ensureStarted();
|
|
707
|
-
logger.debug(`DextoAgent.switchLLM: llmUpdates: ${safeStringify(llmUpdates)}`);
|
|
919
|
+
this.logger.debug(`DextoAgent.switchLLM: llmUpdates: ${safeStringify(llmUpdates)}`);
|
|
708
920
|
const parseResult = LLMUpdatesSchema.safeParse(llmUpdates);
|
|
709
921
|
if (!parseResult.success) {
|
|
710
922
|
const validation = fail(zodToIssues(parseResult.error, "error"));
|
|
711
|
-
ensureOk(validation);
|
|
923
|
+
ensureOk(validation, this.logger);
|
|
712
924
|
throw new Error("Unreachable");
|
|
713
925
|
}
|
|
714
926
|
const validatedUpdates = parseResult.data;
|
|
715
927
|
const currentLLMConfig = sessionId ? this.stateManager.getRuntimeConfig(sessionId).llm : this.stateManager.getRuntimeConfig().llm;
|
|
716
|
-
const result = resolveAndValidateLLMConfig(currentLLMConfig, validatedUpdates);
|
|
717
|
-
const validatedConfig = ensureOk(result);
|
|
928
|
+
const result = resolveAndValidateLLMConfig(currentLLMConfig, validatedUpdates, this.logger);
|
|
929
|
+
const validatedConfig = ensureOk(result, this.logger);
|
|
718
930
|
await this.performLLMSwitch(validatedConfig, sessionId);
|
|
719
|
-
logger.info(
|
|
931
|
+
this.logger.info(
|
|
932
|
+
`DextoAgent.switchLLM: LLM switched to: ${safeStringify(validatedConfig)}`
|
|
933
|
+
);
|
|
720
934
|
const warnings = result.issues.filter((issue) => issue.severity === "warning");
|
|
721
935
|
if (warnings.length > 0) {
|
|
722
|
-
logger.warn(
|
|
936
|
+
this.logger.warn(
|
|
723
937
|
`LLM switch completed with warnings: ${warnings.map((w) => w.message).join(", ")}`
|
|
724
938
|
);
|
|
725
939
|
}
|
|
@@ -743,7 +957,7 @@ class DextoAgent {
|
|
|
743
957
|
}
|
|
744
958
|
await this.sessionManager.switchLLMForSpecificSession(validatedConfig, sessionScope);
|
|
745
959
|
} else {
|
|
746
|
-
|
|
960
|
+
this.logger.debug("LLM config updated at agent level (no active session switches)");
|
|
747
961
|
}
|
|
748
962
|
}
|
|
749
963
|
/**
|
|
@@ -857,31 +1071,35 @@ class DextoAgent {
|
|
|
857
1071
|
this.ensureStarted();
|
|
858
1072
|
const existingServerNames = Object.keys(this.stateManager.getRuntimeConfig().mcpServers);
|
|
859
1073
|
const validation = resolveAndValidateMcpServerConfig(name, config, existingServerNames);
|
|
860
|
-
const validatedConfig = ensureOk(validation);
|
|
1074
|
+
const validatedConfig = ensureOk(validation, this.logger);
|
|
861
1075
|
this.stateManager.addMcpServer(name, validatedConfig);
|
|
862
1076
|
try {
|
|
863
1077
|
await this.mcpManager.connectServer(name, validatedConfig);
|
|
864
1078
|
await this.toolManager.refresh();
|
|
865
|
-
this.agentEventBus.emit("
|
|
1079
|
+
this.agentEventBus.emit("mcp:server-connected", {
|
|
866
1080
|
name,
|
|
867
1081
|
success: true
|
|
868
1082
|
});
|
|
869
|
-
this.agentEventBus.emit("
|
|
1083
|
+
this.agentEventBus.emit("tools:available-updated", {
|
|
870
1084
|
tools: Object.keys(await this.toolManager.getAllTools()),
|
|
871
1085
|
source: "mcp"
|
|
872
1086
|
});
|
|
873
|
-
logger.info(
|
|
1087
|
+
this.logger.info(
|
|
1088
|
+
`DextoAgent: Successfully added and connected to MCP server '${name}'.`
|
|
1089
|
+
);
|
|
874
1090
|
const warnings = validation.issues.filter((i) => i.severity === "warning");
|
|
875
1091
|
if (warnings.length > 0) {
|
|
876
|
-
logger.warn(
|
|
1092
|
+
this.logger.warn(
|
|
877
1093
|
`MCP server connected with warnings: ${warnings.map((w) => w.message).join(", ")}`
|
|
878
1094
|
);
|
|
879
1095
|
}
|
|
880
1096
|
} catch (error) {
|
|
881
1097
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
882
|
-
logger.error(
|
|
1098
|
+
this.logger.error(
|
|
1099
|
+
`DextoAgent: Failed to connect to MCP server '${name}': ${errorMessage}`
|
|
1100
|
+
);
|
|
883
1101
|
this.stateManager.removeMcpServer(name);
|
|
884
|
-
this.agentEventBus.emit("
|
|
1102
|
+
this.agentEventBus.emit("mcp:server-connected", {
|
|
885
1103
|
name,
|
|
886
1104
|
success: false,
|
|
887
1105
|
error: errorMessage
|
|
@@ -908,20 +1126,22 @@ class DextoAgent {
|
|
|
908
1126
|
async restartMcpServer(name) {
|
|
909
1127
|
this.ensureStarted();
|
|
910
1128
|
try {
|
|
911
|
-
logger.info(`DextoAgent: Restarting MCP server '${name}'...`);
|
|
1129
|
+
this.logger.info(`DextoAgent: Restarting MCP server '${name}'...`);
|
|
912
1130
|
await this.mcpManager.restartServer(name);
|
|
913
1131
|
await this.toolManager.refresh();
|
|
914
|
-
this.agentEventBus.emit("
|
|
1132
|
+
this.agentEventBus.emit("mcp:server-restarted", {
|
|
915
1133
|
serverName: name
|
|
916
1134
|
});
|
|
917
|
-
this.agentEventBus.emit("
|
|
1135
|
+
this.agentEventBus.emit("tools:available-updated", {
|
|
918
1136
|
tools: Object.keys(await this.toolManager.getAllTools()),
|
|
919
1137
|
source: "mcp"
|
|
920
1138
|
});
|
|
921
|
-
logger.info(`DextoAgent: Successfully restarted MCP server '${name}'.`);
|
|
1139
|
+
this.logger.info(`DextoAgent: Successfully restarted MCP server '${name}'.`);
|
|
922
1140
|
} catch (error) {
|
|
923
1141
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
924
|
-
logger.error(
|
|
1142
|
+
this.logger.error(
|
|
1143
|
+
`DextoAgent: Failed to restart MCP server '${name}': ${errorMessage}`
|
|
1144
|
+
);
|
|
925
1145
|
throw error;
|
|
926
1146
|
}
|
|
927
1147
|
}
|
|
@@ -1036,10 +1256,10 @@ class DextoAgent {
|
|
|
1036
1256
|
*/
|
|
1037
1257
|
async getSystemPrompt() {
|
|
1038
1258
|
this.ensureStarted();
|
|
1039
|
-
const
|
|
1259
|
+
const context2 = {
|
|
1040
1260
|
mcpManager: this.mcpManager
|
|
1041
1261
|
};
|
|
1042
|
-
return await this.systemPromptManager.build(
|
|
1262
|
+
return await this.systemPromptManager.build(context2);
|
|
1043
1263
|
}
|
|
1044
1264
|
/**
|
|
1045
1265
|
* Lists all available prompts from all providers (MCP, internal, starter, custom).
|
|
@@ -1113,7 +1333,8 @@ class DextoAgent {
|
|
|
1113
1333
|
/**
|
|
1114
1334
|
* Gets the effective configuration for a session or the default configuration.
|
|
1115
1335
|
* @param sessionId Optional session ID. If not provided, returns default config.
|
|
1116
|
-
* @returns The effective configuration object
|
|
1336
|
+
* @returns The effective configuration object (validated with defaults applied)
|
|
1337
|
+
* @remarks Requires agent to be started. Use `agent.config` for pre-start access.
|
|
1117
1338
|
*/
|
|
1118
1339
|
getEffectiveConfig(sessionId) {
|
|
1119
1340
|
this.ensureStarted();
|
|
@@ -1132,84 +1353,48 @@ class DextoAgent {
|
|
|
1132
1353
|
return this.configPath;
|
|
1133
1354
|
}
|
|
1134
1355
|
/**
|
|
1135
|
-
* Reloads the agent configuration
|
|
1136
|
-
*
|
|
1137
|
-
*
|
|
1356
|
+
* Reloads the agent configuration with a new config object.
|
|
1357
|
+
* Validates the new config, detects what changed, and automatically
|
|
1358
|
+
* restarts the agent if necessary to apply the changes.
|
|
1138
1359
|
*
|
|
1139
|
-
*
|
|
1140
|
-
*
|
|
1141
|
-
* @
|
|
1142
|
-
* @throws Error if config file cannot be read or is invalid
|
|
1360
|
+
* @param newConfig The new agent configuration to apply
|
|
1361
|
+
* @returns Object containing whether agent was restarted and list of changes applied
|
|
1362
|
+
* @throws Error if config is invalid or restart fails
|
|
1143
1363
|
*
|
|
1144
1364
|
* TODO: improve hot reload capabilites so that we don't always require a restart
|
|
1145
1365
|
*/
|
|
1146
|
-
async
|
|
1147
|
-
|
|
1148
|
-
throw AgentError.noConfigPath();
|
|
1149
|
-
}
|
|
1150
|
-
logger.info(`Reloading agent configuration from: ${this.configPath}`);
|
|
1366
|
+
async reload(newConfig) {
|
|
1367
|
+
this.logger.info("Reloading agent configuration");
|
|
1151
1368
|
const oldConfig = this.config;
|
|
1152
|
-
const newConfig = await loadAgentConfig(this.configPath);
|
|
1153
1369
|
const validated = AgentConfigSchema.parse(newConfig);
|
|
1154
|
-
const
|
|
1370
|
+
const changesApplied = this.detectConfigChanges(oldConfig, validated);
|
|
1155
1371
|
this.config = validated;
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1372
|
+
let restarted = false;
|
|
1373
|
+
if (changesApplied.length > 0) {
|
|
1374
|
+
this.logger.info(
|
|
1375
|
+
`Configuration changed. Restarting agent to apply: ${changesApplied.join(", ")}`
|
|
1159
1376
|
);
|
|
1377
|
+
await this.restart();
|
|
1378
|
+
restarted = true;
|
|
1379
|
+
this.logger.info("Agent restarted successfully with new configuration");
|
|
1160
1380
|
} else {
|
|
1161
|
-
logger.info("Agent configuration reloaded successfully (no changes detected)");
|
|
1381
|
+
this.logger.info("Agent configuration reloaded successfully (no changes detected)");
|
|
1162
1382
|
}
|
|
1163
1383
|
return {
|
|
1164
|
-
|
|
1384
|
+
restarted,
|
|
1385
|
+
changesApplied
|
|
1165
1386
|
};
|
|
1166
1387
|
}
|
|
1167
|
-
/**
|
|
1168
|
-
* Updates and saves the agent configuration to disk.
|
|
1169
|
-
* This merges the updates with the raw config from disk, validates, and writes to file.
|
|
1170
|
-
* IMPORTANT: This preserves environment variable placeholders (e.g., $OPENAI_API_KEY)
|
|
1171
|
-
* to avoid leaking secrets into the config file.
|
|
1172
|
-
* @param updates Partial configuration updates to apply
|
|
1173
|
-
* @param targetPath Optional path to save to (defaults to current config path)
|
|
1174
|
-
* @returns Object containing list of changes that require restart
|
|
1175
|
-
* @throws Error if validation fails or file cannot be written
|
|
1176
|
-
*/
|
|
1177
|
-
async updateAndSaveConfig(updates, targetPath) {
|
|
1178
|
-
const path = targetPath || this.configPath;
|
|
1179
|
-
if (!path) {
|
|
1180
|
-
throw AgentError.noConfigPath();
|
|
1181
|
-
}
|
|
1182
|
-
logger.info(`Updating and saving agent configuration to: ${path}`);
|
|
1183
|
-
const rawYaml = await fs.readFile(path, "utf-8");
|
|
1184
|
-
const doc = parseDocument(rawYaml);
|
|
1185
|
-
const rawConfig = doc.toJSON();
|
|
1186
|
-
const updatedRawConfig = { ...rawConfig, ...updates };
|
|
1187
|
-
const parsed = AgentConfigSchema.safeParse(updatedRawConfig);
|
|
1188
|
-
if (!parsed.success) {
|
|
1189
|
-
const result = fail(zodToIssues(parsed.error, "error"));
|
|
1190
|
-
throw new DextoValidationError(result.issues);
|
|
1191
|
-
}
|
|
1192
|
-
for (const [key, value] of Object.entries(updates)) {
|
|
1193
|
-
doc.set(key, value);
|
|
1194
|
-
}
|
|
1195
|
-
const yamlContent = String(doc);
|
|
1196
|
-
const tmpPath = `${path}.tmp`;
|
|
1197
|
-
await fs.writeFile(tmpPath, yamlContent, "utf-8");
|
|
1198
|
-
await fs.rename(tmpPath, path);
|
|
1199
|
-
const reloadResult = await this.reloadConfig();
|
|
1200
|
-
logger.info(`Agent configuration saved to: ${path}`);
|
|
1201
|
-
return reloadResult;
|
|
1202
|
-
}
|
|
1203
1388
|
/**
|
|
1204
1389
|
* Detects configuration changes that require a full agent restart.
|
|
1390
|
+
* Pure comparison logic - no file I/O.
|
|
1205
1391
|
* Returns an array of change descriptions.
|
|
1206
1392
|
*
|
|
1207
1393
|
* @param oldConfig Previous validated configuration
|
|
1208
1394
|
* @param newConfig New validated configuration
|
|
1209
1395
|
* @returns Array of restart-required change descriptions
|
|
1210
|
-
* @private
|
|
1211
1396
|
*/
|
|
1212
|
-
|
|
1397
|
+
detectConfigChanges(oldConfig, newConfig) {
|
|
1213
1398
|
const changes = [];
|
|
1214
1399
|
if (JSON.stringify(oldConfig.storage) !== JSON.stringify(newConfig.storage)) {
|
|
1215
1400
|
changes.push("Storage backend");
|
|
@@ -1234,6 +1419,58 @@ class DextoAgent {
|
|
|
1234
1419
|
}
|
|
1235
1420
|
return changes;
|
|
1236
1421
|
}
|
|
1422
|
+
// ============= APPROVAL HANDLER API =============
|
|
1423
|
+
/**
|
|
1424
|
+
* Set a custom approval handler for manual approval mode.
|
|
1425
|
+
*
|
|
1426
|
+
* When `toolConfirmation.mode` is set to 'manual', an approval handler must be
|
|
1427
|
+
* provided to process tool confirmation requests. The handler will be called
|
|
1428
|
+
* whenever a tool execution requires user approval.
|
|
1429
|
+
*
|
|
1430
|
+
* The handler receives an approval request and must return a promise that resolves
|
|
1431
|
+
* to an approval response with the user's decision (approved/denied/cancelled).
|
|
1432
|
+
*
|
|
1433
|
+
* @param handler The approval handler function
|
|
1434
|
+
*
|
|
1435
|
+
* @example
|
|
1436
|
+
* ```typescript
|
|
1437
|
+
* import { ApprovalStatus } from '@dexto/core';
|
|
1438
|
+
*
|
|
1439
|
+
* agent.setApprovalHandler(async (request) => {
|
|
1440
|
+
* // Present approval request to user (CLI, UI, webhook, etc.)
|
|
1441
|
+
* console.log(`Approve tool: ${request.metadata.toolName}?`);
|
|
1442
|
+
* console.log(`Args: ${JSON.stringify(request.metadata.args)}`);
|
|
1443
|
+
*
|
|
1444
|
+
* // Collect user's decision (this is just an example)
|
|
1445
|
+
* const approved = await getUserInput();
|
|
1446
|
+
*
|
|
1447
|
+
* return {
|
|
1448
|
+
* approvalId: request.approvalId,
|
|
1449
|
+
* status: approved ? ApprovalStatus.APPROVED : ApprovalStatus.DENIED,
|
|
1450
|
+
* sessionId: request.sessionId,
|
|
1451
|
+
* };
|
|
1452
|
+
* });
|
|
1453
|
+
* ```
|
|
1454
|
+
*/
|
|
1455
|
+
setApprovalHandler(handler) {
|
|
1456
|
+
this.approvalHandler = handler;
|
|
1457
|
+
if (this._isStarted && this.services) {
|
|
1458
|
+
this.services.approvalManager.setHandler(handler);
|
|
1459
|
+
}
|
|
1460
|
+
this.logger.debug("Approval handler registered");
|
|
1461
|
+
}
|
|
1462
|
+
/**
|
|
1463
|
+
* Clear the current approval handler.
|
|
1464
|
+
*
|
|
1465
|
+
* After calling this, manual approval mode will fail if a tool requires approval.
|
|
1466
|
+
*/
|
|
1467
|
+
clearApprovalHandler() {
|
|
1468
|
+
this.approvalHandler = void 0;
|
|
1469
|
+
if (this._isStarted && this.services) {
|
|
1470
|
+
this.services.approvalManager.clearHandler();
|
|
1471
|
+
}
|
|
1472
|
+
this.logger.debug("Approval handler cleared");
|
|
1473
|
+
}
|
|
1237
1474
|
// ============= AGENT MANAGEMENT =============
|
|
1238
1475
|
// Note: Agent management methods have been moved to the Dexto orchestrator class.
|
|
1239
1476
|
// See: /packages/core/src/Dexto.ts
|