@dexto/core 1.2.4 → 1.2.5
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 +164 -64
- package/dist/agent/schemas.d.ts +2605 -517
- package/dist/agent/schemas.d.ts.map +1 -1
- package/dist/agent/schemas.js +167 -64
- 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/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.d.ts +6 -6
- 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/prompt-manager.cjs +25 -18
- 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 -18
- 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/file-prompt-provider.cjs +14 -12
- package/dist/prompts/providers/file-prompt-provider.d.ts +3 -1
- package/dist/prompts/providers/file-prompt-provider.d.ts.map +1 -1
- package/dist/prompts/providers/file-prompt-provider.js +14 -12
- 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/providers/starter-prompt-provider.cjs +7 -5
- package/dist/prompts/providers/starter-prompt-provider.d.ts +3 -1
- package/dist/prompts/providers/starter-prompt-provider.d.ts.map +1 -1
- package/dist/prompts/providers/starter-prompt-provider.js +7 -5
- package/dist/prompts/schemas.d.ts +3 -3
- 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/manager.cjs +11 -8
- package/dist/systemPrompt/manager.d.ts +4 -2
- package/dist/systemPrompt/manager.d.ts.map +1 -1
- package/dist/systemPrompt/manager.js +11 -8
- package/dist/systemPrompt/schemas.cjs +21 -1
- package/dist/systemPrompt/schemas.d.ts +53 -53
- package/dist/systemPrompt/schemas.d.ts.map +1 -1
- package/dist/systemPrompt/schemas.js +11 -1
- 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 +87 -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 +69 -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/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
|
@@ -70,25 +70,25 @@ var import_resources = require("../resources/index.js");
|
|
|
70
70
|
var import_utils = require("../context/utils.js");
|
|
71
71
|
var import_prompts = require("../prompts/index.js");
|
|
72
72
|
var import_session = require("../session/index.js");
|
|
73
|
-
var
|
|
73
|
+
var import_factory = require("../logger/factory.js");
|
|
74
|
+
var import_types = require("../logger/v2/types.js");
|
|
74
75
|
var import_decorators = require("../telemetry/decorators.js");
|
|
76
|
+
var import_api = require("@opentelemetry/api");
|
|
75
77
|
var import_schemas = require("../llm/schemas.cjs");
|
|
76
78
|
var import_resolver = require("../llm/resolver.js");
|
|
77
79
|
var import_validation = require("../llm/validation.js");
|
|
78
|
-
var import_errors = require("
|
|
79
|
-
var import_errors2 = require("
|
|
80
|
+
var import_errors = require("../llm/errors.js");
|
|
81
|
+
var import_errors2 = require("./errors.js");
|
|
82
|
+
var import_errors3 = require("../mcp/errors.js");
|
|
83
|
+
var import_DextoRuntimeError = require("../errors/DextoRuntimeError.js");
|
|
80
84
|
var import_result_bridge = require("../errors/result-bridge.cjs");
|
|
81
85
|
var import_result = require("../utils/result.cjs");
|
|
82
|
-
var import_DextoValidationError = require("../errors/DextoValidationError.cjs");
|
|
83
86
|
var import_resolver2 = require("../mcp/resolver.js");
|
|
84
87
|
var import_registry = require("../llm/registry.js");
|
|
85
88
|
var import_service_initializer2 = require("../utils/service-initializer.js");
|
|
86
89
|
var import_schemas2 = require("./schemas.js");
|
|
87
|
-
var
|
|
90
|
+
var import_events = require("../events/index.js");
|
|
88
91
|
var import_safe_stringify = require("../utils/safe-stringify.cjs");
|
|
89
|
-
var import_loader = require("../config/loader.js");
|
|
90
|
-
var import_fs = require("fs");
|
|
91
|
-
var import_yaml = require("yaml");
|
|
92
92
|
var import_title_generator = require("../session/title-generator.js");
|
|
93
93
|
var _DextoAgent_decorators, _init;
|
|
94
94
|
const requiredServices = [
|
|
@@ -113,10 +113,22 @@ _DextoAgent_decorators = [(0, import_decorators.InstrumentClass)({
|
|
|
113
113
|
]
|
|
114
114
|
})];
|
|
115
115
|
class DextoAgent {
|
|
116
|
+
/**
|
|
117
|
+
* Creates a DextoAgent instance.
|
|
118
|
+
*
|
|
119
|
+
* @param config - Agent configuration (validated and enriched)
|
|
120
|
+
* @param configPath - Optional path to config file (for relative path resolution)
|
|
121
|
+
*/
|
|
116
122
|
constructor(config, configPath) {
|
|
117
123
|
this.configPath = configPath;
|
|
118
124
|
this.config = import_schemas2.AgentConfigSchema.parse(config);
|
|
119
|
-
|
|
125
|
+
this.logger = (0, import_factory.createLogger)({
|
|
126
|
+
config: this.config.logger,
|
|
127
|
+
agentId: this.config.agentId,
|
|
128
|
+
component: import_types.DextoLogComponent.AGENT
|
|
129
|
+
});
|
|
130
|
+
this.agentEventBus = new import_events.AgentEventBus();
|
|
131
|
+
this.logger.info("DextoAgent created.");
|
|
120
132
|
}
|
|
121
133
|
/**
|
|
122
134
|
* These services are public for use by the outside world
|
|
@@ -135,19 +147,20 @@ class DextoAgent {
|
|
|
135
147
|
services;
|
|
136
148
|
// Search service for conversation search
|
|
137
149
|
searchService;
|
|
138
|
-
// Default session for backward compatibility
|
|
139
|
-
defaultSession = null;
|
|
140
|
-
// Current default session ID for loadSession functionality
|
|
141
|
-
currentDefaultSessionId = "default";
|
|
142
150
|
// Track initialization state
|
|
143
151
|
_isStarted = false;
|
|
144
152
|
_isStopped = false;
|
|
145
|
-
// Store config for async initialization
|
|
153
|
+
// Store config for async initialization (accessible before start() for setup)
|
|
146
154
|
config;
|
|
147
|
-
// Event subscribers (e.g.,
|
|
155
|
+
// Event subscribers (e.g., SSE, Webhook handlers)
|
|
148
156
|
eventSubscribers = /* @__PURE__ */ new Set();
|
|
149
157
|
// Telemetry instance for distributed tracing
|
|
150
158
|
telemetry;
|
|
159
|
+
// Approval handler for manual tool confirmation and elicitation
|
|
160
|
+
// Set via setApprovalHandler() before start() if needed
|
|
161
|
+
approvalHandler;
|
|
162
|
+
// Logger instance for this agent (dependency injection)
|
|
163
|
+
logger;
|
|
151
164
|
/**
|
|
152
165
|
* Starts the agent by initializing all async services.
|
|
153
166
|
* This method handles storage backends, MCP connections, session manager initialization, and other async operations.
|
|
@@ -157,24 +170,48 @@ class DextoAgent {
|
|
|
157
170
|
*/
|
|
158
171
|
async start() {
|
|
159
172
|
if (this._isStarted) {
|
|
160
|
-
throw
|
|
173
|
+
throw import_errors2.AgentError.alreadyStarted();
|
|
161
174
|
}
|
|
162
175
|
try {
|
|
163
|
-
|
|
164
|
-
const services = await (0, import_service_initializer2.createAgentServices)(
|
|
176
|
+
this.logger.info("Starting DextoAgent...");
|
|
177
|
+
const services = await (0, import_service_initializer2.createAgentServices)(
|
|
178
|
+
this.config,
|
|
179
|
+
this.configPath,
|
|
180
|
+
this.logger,
|
|
181
|
+
this.agentEventBus
|
|
182
|
+
);
|
|
165
183
|
for (const service of requiredServices) {
|
|
166
184
|
if (!services[service]) {
|
|
167
|
-
throw
|
|
185
|
+
throw import_errors2.AgentError.initializationFailed(
|
|
168
186
|
`Required service ${service} is missing during agent start`
|
|
169
187
|
);
|
|
170
188
|
}
|
|
171
189
|
}
|
|
190
|
+
const needsHandler = this.config.toolConfirmation.mode === "manual" || this.config.elicitation.enabled;
|
|
191
|
+
if (needsHandler && !this.approvalHandler) {
|
|
192
|
+
const reasons = [];
|
|
193
|
+
if (this.config.toolConfirmation.mode === "manual") {
|
|
194
|
+
reasons.push('tool confirmation mode is "manual"');
|
|
195
|
+
}
|
|
196
|
+
if (this.config.elicitation.enabled) {
|
|
197
|
+
reasons.push("elicitation is enabled");
|
|
198
|
+
}
|
|
199
|
+
throw import_errors2.AgentError.initializationFailed(
|
|
200
|
+
`An approval handler is required but not configured (${reasons.join(" and ")}).
|
|
201
|
+
Either:
|
|
202
|
+
\u2022 Call agent.setApprovalHandler() before starting
|
|
203
|
+
\u2022 Set toolConfirmation: { mode: "auto-approve" } or { mode: "auto-deny" }
|
|
204
|
+
\u2022 Disable elicitation: { enabled: false }`
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
if (this.approvalHandler) {
|
|
208
|
+
services.approvalManager.setHandler(this.approvalHandler);
|
|
209
|
+
}
|
|
172
210
|
Object.assign(this, {
|
|
173
211
|
mcpManager: services.mcpManager,
|
|
174
212
|
toolManager: services.toolManager,
|
|
175
213
|
resourceManager: services.resourceManager,
|
|
176
214
|
systemPromptManager: services.systemPromptManager,
|
|
177
|
-
agentEventBus: services.agentEventBus,
|
|
178
215
|
stateManager: services.stateManager,
|
|
179
216
|
sessionManager: services.sessionManager,
|
|
180
217
|
memoryManager: services.memoryManager,
|
|
@@ -186,20 +223,25 @@ class DextoAgent {
|
|
|
186
223
|
this.resourceManager,
|
|
187
224
|
this.config,
|
|
188
225
|
this.agentEventBus,
|
|
189
|
-
services.storageManager.getDatabase()
|
|
226
|
+
services.storageManager.getDatabase(),
|
|
227
|
+
this.logger
|
|
190
228
|
);
|
|
191
229
|
await promptManager.initialize();
|
|
192
230
|
Object.assign(this, { promptManager });
|
|
193
231
|
this._isStarted = true;
|
|
194
232
|
this._isStopped = false;
|
|
195
|
-
|
|
233
|
+
this.logger.info("DextoAgent started successfully.");
|
|
196
234
|
for (const subscriber of this.eventSubscribers) {
|
|
197
235
|
subscriber.subscribe(this.agentEventBus);
|
|
198
236
|
}
|
|
199
|
-
const
|
|
200
|
-
|
|
237
|
+
const fileTransport = this.config.logger?.transports?.find((t) => t.type === "file");
|
|
238
|
+
if (fileTransport && "path" in fileTransport) {
|
|
239
|
+
console.log(`\u{1F4CB} Logs available at: ${fileTransport.path}`);
|
|
240
|
+
}
|
|
201
241
|
} catch (error) {
|
|
202
|
-
|
|
242
|
+
this.logger.error("Failed to start DextoAgent", {
|
|
243
|
+
error: error instanceof Error ? error.message : String(error)
|
|
244
|
+
});
|
|
203
245
|
throw error;
|
|
204
246
|
}
|
|
205
247
|
}
|
|
@@ -212,19 +254,19 @@ class DextoAgent {
|
|
|
212
254
|
*/
|
|
213
255
|
async stop() {
|
|
214
256
|
if (this._isStopped) {
|
|
215
|
-
|
|
257
|
+
this.logger.warn("Agent is already stopped");
|
|
216
258
|
return;
|
|
217
259
|
}
|
|
218
260
|
if (!this._isStarted) {
|
|
219
|
-
throw
|
|
261
|
+
throw import_errors2.AgentError.notStarted();
|
|
220
262
|
}
|
|
221
263
|
try {
|
|
222
|
-
|
|
264
|
+
this.logger.info("Stopping DextoAgent...");
|
|
223
265
|
const shutdownErrors = [];
|
|
224
266
|
try {
|
|
225
267
|
if (this.sessionManager) {
|
|
226
268
|
await this.sessionManager.cleanup();
|
|
227
|
-
|
|
269
|
+
this.logger.debug("SessionManager cleaned up successfully");
|
|
228
270
|
}
|
|
229
271
|
} catch (error) {
|
|
230
272
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
@@ -233,7 +275,7 @@ class DextoAgent {
|
|
|
233
275
|
try {
|
|
234
276
|
if (this.services?.pluginManager) {
|
|
235
277
|
await this.services.pluginManager.cleanup();
|
|
236
|
-
|
|
278
|
+
this.logger.debug("PluginManager cleaned up successfully");
|
|
237
279
|
}
|
|
238
280
|
} catch (error) {
|
|
239
281
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
@@ -242,7 +284,7 @@ class DextoAgent {
|
|
|
242
284
|
try {
|
|
243
285
|
if (this.mcpManager) {
|
|
244
286
|
await this.mcpManager.disconnectAll();
|
|
245
|
-
|
|
287
|
+
this.logger.debug("MCPManager disconnected all clients successfully");
|
|
246
288
|
}
|
|
247
289
|
} catch (error) {
|
|
248
290
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
@@ -251,7 +293,7 @@ class DextoAgent {
|
|
|
251
293
|
try {
|
|
252
294
|
if (this.services?.storageManager) {
|
|
253
295
|
await this.services.storageManager.disconnect();
|
|
254
|
-
|
|
296
|
+
this.logger.debug("Storage manager disconnected successfully");
|
|
255
297
|
}
|
|
256
298
|
} catch (error) {
|
|
257
299
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
@@ -261,18 +303,20 @@ class DextoAgent {
|
|
|
261
303
|
this._isStarted = false;
|
|
262
304
|
if (shutdownErrors.length > 0) {
|
|
263
305
|
const errorMessages = shutdownErrors.map((e) => e.message).join("; ");
|
|
264
|
-
|
|
306
|
+
this.logger.warn(`DextoAgent stopped with some errors: ${errorMessages}`);
|
|
265
307
|
} else {
|
|
266
|
-
|
|
308
|
+
this.logger.info("DextoAgent stopped successfully.");
|
|
267
309
|
}
|
|
268
310
|
} catch (error) {
|
|
269
|
-
|
|
311
|
+
this.logger.error("Failed to stop DextoAgent", {
|
|
312
|
+
error: error instanceof Error ? error.message : String(error)
|
|
313
|
+
});
|
|
270
314
|
throw error;
|
|
271
315
|
}
|
|
272
316
|
}
|
|
273
317
|
/**
|
|
274
318
|
* Register an event subscriber that will be automatically re-subscribed on agent restart.
|
|
275
|
-
* Subscribers are typically API layer components (
|
|
319
|
+
* Subscribers are typically API layer components (SSE, Webhook handlers) that need
|
|
276
320
|
* to receive agent events. If the agent is already started, the subscriber is immediately subscribed.
|
|
277
321
|
*
|
|
278
322
|
* @param subscriber - Object implementing AgentEventSubscriber interface
|
|
@@ -314,12 +358,12 @@ class DextoAgent {
|
|
|
314
358
|
*/
|
|
315
359
|
ensureStarted() {
|
|
316
360
|
if (this._isStopped) {
|
|
317
|
-
|
|
318
|
-
throw
|
|
361
|
+
this.logger.warn("Agent is stopped");
|
|
362
|
+
throw import_errors2.AgentError.stopped();
|
|
319
363
|
}
|
|
320
364
|
if (!this._isStarted) {
|
|
321
|
-
|
|
322
|
-
throw
|
|
365
|
+
this.logger.warn("Agent is not started");
|
|
366
|
+
throw import_errors2.AgentError.notStarted();
|
|
323
367
|
}
|
|
324
368
|
}
|
|
325
369
|
// ============= CORE AGENT FUNCTIONALITY =============
|
|
@@ -330,110 +374,347 @@ class DextoAgent {
|
|
|
330
374
|
* @param textInput - The user's text message or query to process
|
|
331
375
|
* @param imageDataInput - Optional image data and MIME type for multimodal input
|
|
332
376
|
* @param fileDataInput - Optional file data and MIME type for file input
|
|
333
|
-
* @param sessionId -
|
|
377
|
+
* @param sessionId - Session ID for the conversation (required)
|
|
378
|
+
* @param stream - Whether to stream the response (default: false)
|
|
334
379
|
* @returns Promise that resolves to the AI's response text, or null if no significant response
|
|
335
380
|
* @throws Error if processing fails
|
|
336
381
|
*/
|
|
337
382
|
async run(textInput, imageDataInput, fileDataInput, sessionId, stream = false) {
|
|
338
383
|
this.ensureStarted();
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
384
|
+
if (!sessionId || typeof sessionId !== "string") {
|
|
385
|
+
throw new Error("sessionId is required and must be a non-empty string");
|
|
386
|
+
}
|
|
387
|
+
const targetSessionId = sessionId;
|
|
388
|
+
const activeContext = import_api.context.active();
|
|
389
|
+
const span = import_api.trace.getActiveSpan();
|
|
390
|
+
if (span) {
|
|
391
|
+
span.setAttribute("sessionId", targetSessionId);
|
|
392
|
+
}
|
|
393
|
+
const existingBaggage = import_api.propagation.getBaggage(activeContext);
|
|
394
|
+
const baggageEntries = {};
|
|
395
|
+
if (existingBaggage) {
|
|
396
|
+
existingBaggage.getAllEntries().forEach(([key, entry]) => {
|
|
397
|
+
baggageEntries[key] = { ...entry };
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
baggageEntries.sessionId = { ...baggageEntries.sessionId, value: targetSessionId };
|
|
401
|
+
const updatedContext = import_api.propagation.setBaggage(
|
|
402
|
+
activeContext,
|
|
403
|
+
import_api.propagation.createBaggage(baggageEntries)
|
|
404
|
+
);
|
|
405
|
+
const verifyBaggage = import_api.propagation.getBaggage(updatedContext);
|
|
406
|
+
this.logger.debug(
|
|
407
|
+
`Baggage after setting sessionId: ${JSON.stringify(
|
|
408
|
+
Array.from(verifyBaggage?.getAllEntries() || [])
|
|
409
|
+
)}`
|
|
410
|
+
);
|
|
411
|
+
return await import_api.context.with(updatedContext, async () => {
|
|
412
|
+
try {
|
|
413
|
+
const llmConfig = this.stateManager.getLLMConfig(targetSessionId);
|
|
414
|
+
const validation = (0, import_validation.validateInputForLLM)(
|
|
415
|
+
{
|
|
416
|
+
text: textInput,
|
|
417
|
+
...imageDataInput && { imageData: imageDataInput },
|
|
418
|
+
...fileDataInput && { fileData: fileDataInput }
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
provider: llmConfig.provider,
|
|
422
|
+
model: llmConfig.model
|
|
423
|
+
},
|
|
424
|
+
this.logger
|
|
425
|
+
);
|
|
426
|
+
(0, import_result_bridge.ensureOk)(validation, this.logger);
|
|
427
|
+
const session = await this.sessionManager.getSession(targetSessionId) || await this.sessionManager.createSession(targetSessionId);
|
|
428
|
+
this.logger.debug(
|
|
429
|
+
`DextoAgent.run: sessionId=${targetSessionId}, textLength=${textInput?.length ?? 0}, hasImage=${Boolean(
|
|
430
|
+
imageDataInput
|
|
431
|
+
)}, hasFile=${Boolean(fileDataInput)}`
|
|
432
|
+
);
|
|
433
|
+
let finalText = textInput;
|
|
434
|
+
let finalImageData = imageDataInput;
|
|
435
|
+
if (textInput && textInput.includes("@")) {
|
|
436
|
+
try {
|
|
437
|
+
const resources = await this.resourceManager.list();
|
|
438
|
+
const expansion = await (0, import_resources.expandMessageReferences)(
|
|
439
|
+
textInput,
|
|
440
|
+
resources,
|
|
441
|
+
(uri) => this.resourceManager.read(uri)
|
|
382
442
|
);
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
if (firstImage) {
|
|
388
|
-
finalImageData = {
|
|
389
|
-
image: firstImage.image,
|
|
390
|
-
mimeType: firstImage.mimeType
|
|
391
|
-
};
|
|
392
|
-
import_logger.logger.debug(
|
|
393
|
-
`Using extracted image: ${firstImage.name} (${firstImage.mimeType})`
|
|
443
|
+
if (expansion.unresolvedReferences.length > 0) {
|
|
444
|
+
const unresolvedNames = expansion.unresolvedReferences.map((ref) => ref.originalRef).join(", ");
|
|
445
|
+
this.logger.warn(
|
|
446
|
+
`Could not resolve ${expansion.unresolvedReferences.length} resource reference(s): ${unresolvedNames}`
|
|
394
447
|
);
|
|
395
448
|
}
|
|
449
|
+
const MAX_EXPANDED_SIZE = 5 * 1024 * 1024;
|
|
450
|
+
const expandedSize = Buffer.byteLength(expansion.expandedMessage, "utf-8");
|
|
451
|
+
if (expandedSize > MAX_EXPANDED_SIZE) {
|
|
452
|
+
this.logger.warn(
|
|
453
|
+
`Expanded message size (${(expandedSize / 1024 / 1024).toFixed(2)}MB) exceeds limit (${MAX_EXPANDED_SIZE / 1024 / 1024}MB). Content may be truncated.`
|
|
454
|
+
);
|
|
455
|
+
}
|
|
456
|
+
finalText = expansion.expandedMessage;
|
|
457
|
+
if (expansion.extractedImages.length > 0 && !imageDataInput) {
|
|
458
|
+
const firstImage = expansion.extractedImages[0];
|
|
459
|
+
if (firstImage) {
|
|
460
|
+
finalImageData = {
|
|
461
|
+
image: firstImage.image,
|
|
462
|
+
mimeType: firstImage.mimeType
|
|
463
|
+
};
|
|
464
|
+
this.logger.debug(
|
|
465
|
+
`Using extracted image: ${firstImage.name} (${firstImage.mimeType})`
|
|
466
|
+
);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
} catch (error) {
|
|
470
|
+
this.logger.error(
|
|
471
|
+
`Failed to expand resource references: ${error instanceof Error ? error.message : String(error)}. Continuing with original message.`
|
|
472
|
+
);
|
|
396
473
|
}
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
|
|
474
|
+
}
|
|
475
|
+
if (!finalText.trim() && !finalImageData && !fileDataInput) {
|
|
476
|
+
this.logger.warn(
|
|
477
|
+
"Resource expansion resulted in empty content. Using original message."
|
|
400
478
|
);
|
|
479
|
+
finalText = textInput;
|
|
401
480
|
}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
481
|
+
const response = await session.run(
|
|
482
|
+
finalText,
|
|
483
|
+
finalImageData,
|
|
484
|
+
fileDataInput,
|
|
485
|
+
stream
|
|
406
486
|
);
|
|
407
|
-
|
|
487
|
+
this.sessionManager.incrementMessageCount(session.id).catch(
|
|
488
|
+
(error) => this.logger.warn(
|
|
489
|
+
`Failed to increment message count: ${error instanceof Error ? error.message : String(error)}`
|
|
490
|
+
)
|
|
491
|
+
);
|
|
492
|
+
return response;
|
|
493
|
+
} catch (error) {
|
|
494
|
+
this.logger.error(
|
|
495
|
+
`Error during DextoAgent.run: ${error instanceof Error ? error.message : JSON.stringify(error)}`
|
|
496
|
+
);
|
|
497
|
+
throw error;
|
|
498
|
+
}
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Generate a complete response (waits for full completion).
|
|
503
|
+
* This is the recommended method for non-streaming use cases.
|
|
504
|
+
*
|
|
505
|
+
* @param message The user's message
|
|
506
|
+
* @param options Configuration options (sessionId is required, imageData, fileData, signal are optional)
|
|
507
|
+
* @returns Promise that resolves to the complete response
|
|
508
|
+
*
|
|
509
|
+
* @example
|
|
510
|
+
* ```typescript
|
|
511
|
+
* const response = await agent.generate("What is 2+2?", { sessionId: "default" });
|
|
512
|
+
* console.log(response.content); // "4"
|
|
513
|
+
* console.log(response.usage.totalTokens); // 50
|
|
514
|
+
* ```
|
|
515
|
+
*/
|
|
516
|
+
async generate(message, options) {
|
|
517
|
+
const events = [];
|
|
518
|
+
for await (const event of await this.stream(message, options)) {
|
|
519
|
+
events.push(event);
|
|
520
|
+
}
|
|
521
|
+
const errorEvent = events.find(
|
|
522
|
+
(e) => e.type === "llm:error"
|
|
523
|
+
);
|
|
524
|
+
if (errorEvent) {
|
|
525
|
+
if (errorEvent.error instanceof import_DextoRuntimeError.DextoRuntimeError) {
|
|
526
|
+
throw errorEvent.error;
|
|
408
527
|
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
)
|
|
528
|
+
const llmConfig = this.stateManager.getLLMConfig(options.sessionId);
|
|
529
|
+
throw import_errors.LLMError.generationFailed(
|
|
530
|
+
errorEvent.error.message,
|
|
531
|
+
llmConfig.provider,
|
|
532
|
+
llmConfig.model
|
|
415
533
|
);
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
534
|
+
}
|
|
535
|
+
const responseEvent = events.find((e) => e.type === "llm:response");
|
|
536
|
+
if (!responseEvent || responseEvent.type !== "llm:response") {
|
|
537
|
+
const llmConfig = this.stateManager.getLLMConfig(options.sessionId);
|
|
538
|
+
throw import_errors.LLMError.generationFailed(
|
|
539
|
+
"Stream did not complete successfully - no response received",
|
|
540
|
+
llmConfig.provider,
|
|
541
|
+
llmConfig.model
|
|
420
542
|
);
|
|
421
|
-
throw error;
|
|
422
543
|
}
|
|
544
|
+
const toolCallEvents = events.filter(
|
|
545
|
+
(e) => e.type === "llm:tool-call"
|
|
546
|
+
);
|
|
547
|
+
const toolResultEvents = events.filter(
|
|
548
|
+
(e) => e.type === "llm:tool-result"
|
|
549
|
+
);
|
|
550
|
+
const toolCalls = toolCallEvents.map((tc) => {
|
|
551
|
+
const toolResult = toolResultEvents.find((tr) => tr.callId === tc.callId);
|
|
552
|
+
return {
|
|
553
|
+
toolName: tc.toolName,
|
|
554
|
+
args: tc.args,
|
|
555
|
+
callId: tc.callId || `tool_${Date.now()}`,
|
|
556
|
+
result: toolResult ? {
|
|
557
|
+
success: toolResult.success,
|
|
558
|
+
data: toolResult.sanitized
|
|
559
|
+
} : void 0
|
|
560
|
+
};
|
|
561
|
+
});
|
|
562
|
+
const messageId = `msg_${Date.now()}_${Math.random().toString(36).substring(7)}`;
|
|
563
|
+
const defaultUsage = {
|
|
564
|
+
inputTokens: 0,
|
|
565
|
+
outputTokens: 0,
|
|
566
|
+
totalTokens: 0
|
|
567
|
+
};
|
|
568
|
+
const usage = responseEvent.tokenUsage ?? defaultUsage;
|
|
569
|
+
return {
|
|
570
|
+
content: responseEvent.content,
|
|
571
|
+
reasoning: responseEvent.reasoning,
|
|
572
|
+
usage,
|
|
573
|
+
toolCalls,
|
|
574
|
+
sessionId: options.sessionId,
|
|
575
|
+
messageId
|
|
576
|
+
};
|
|
423
577
|
}
|
|
424
578
|
/**
|
|
425
|
-
*
|
|
579
|
+
* Stream a response (yields events as they arrive).
|
|
580
|
+
* This is the recommended method for real-time streaming UI updates.
|
|
581
|
+
*
|
|
582
|
+
* TODO: Refactor to move AsyncIterator down to LLM service level (Option 1).
|
|
583
|
+
* Streaming message API that returns core AgentEvents in real-time.
|
|
584
|
+
* Only emits STREAMING_EVENTS (tier 1 visibility) - events designed for real-time chat UIs.
|
|
585
|
+
*
|
|
586
|
+
* Events are forwarded directly from the AgentEventBus with no mapping layer,
|
|
587
|
+
* providing a unified event system across all API layers.
|
|
588
|
+
*
|
|
589
|
+
* @param message The user's message
|
|
590
|
+
* @param options Configuration options (sessionId is required, imageData, fileData, signal are optional)
|
|
591
|
+
* @returns AsyncIterator that yields StreamingEvent objects (core events with type property)
|
|
592
|
+
*
|
|
593
|
+
* @example
|
|
594
|
+
* ```typescript
|
|
595
|
+
* for await (const event of await agent.stream("Write a poem", { sessionId: "default" })) {
|
|
596
|
+
* if (event.type === 'llm:chunk') {
|
|
597
|
+
* process.stdout.write(event.content);
|
|
598
|
+
* }
|
|
599
|
+
* if (event.type === 'llm:tool-call') {
|
|
600
|
+
* console.log(`\n[Using ${event.toolName}]\n`);
|
|
601
|
+
* }
|
|
602
|
+
* }
|
|
603
|
+
* ```
|
|
604
|
+
*/
|
|
605
|
+
async stream(message, options) {
|
|
606
|
+
this.ensureStarted();
|
|
607
|
+
if (!options.sessionId) {
|
|
608
|
+
throw new Error("sessionId is required in StreamOptions");
|
|
609
|
+
}
|
|
610
|
+
const sessionId = options.sessionId;
|
|
611
|
+
const imageData = options.imageData;
|
|
612
|
+
const fileData = options.fileData;
|
|
613
|
+
const signal = options.signal;
|
|
614
|
+
const eventQueue = [];
|
|
615
|
+
let completed = false;
|
|
616
|
+
let _streamError = null;
|
|
617
|
+
const controller = new AbortController();
|
|
618
|
+
const cleanupSignal = controller.signal;
|
|
619
|
+
const listeners = [];
|
|
620
|
+
const cleanupListeners = () => {
|
|
621
|
+
if (listeners.length === 0) {
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
624
|
+
for (const { event, listener } of listeners) {
|
|
625
|
+
this.agentEventBus.off(event, listener);
|
|
626
|
+
}
|
|
627
|
+
listeners.length = 0;
|
|
628
|
+
};
|
|
629
|
+
if (signal) {
|
|
630
|
+
const abortHandler = () => {
|
|
631
|
+
cleanupListeners();
|
|
632
|
+
controller.abort();
|
|
633
|
+
};
|
|
634
|
+
signal.addEventListener("abort", abortHandler, { once: true });
|
|
635
|
+
}
|
|
636
|
+
for (const eventName of import_events.STREAMING_EVENTS) {
|
|
637
|
+
const listener = (data) => {
|
|
638
|
+
if (data.sessionId !== void 0 && data.sessionId !== sessionId) {
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
eventQueue.push({ type: eventName, ...data });
|
|
642
|
+
if (eventName === "llm:response" || eventName === "llm:error" && !data.recoverable) {
|
|
643
|
+
completed = true;
|
|
644
|
+
}
|
|
645
|
+
};
|
|
646
|
+
this.agentEventBus.on(eventName, listener, {
|
|
647
|
+
signal: cleanupSignal
|
|
648
|
+
});
|
|
649
|
+
listeners.push({ event: eventName, listener });
|
|
650
|
+
}
|
|
651
|
+
const imageDataForRun = imageData ? {
|
|
652
|
+
image: typeof imageData.image === "string" ? imageData.image : imageData.image.toString(),
|
|
653
|
+
mimeType: imageData.mimeType || "image/png"
|
|
654
|
+
} : void 0;
|
|
655
|
+
const fileDataForRun = fileData ? {
|
|
656
|
+
data: typeof fileData.data === "string" ? fileData.data : fileData.data.toString(),
|
|
657
|
+
mimeType: fileData.mimeType,
|
|
658
|
+
...fileData.filename && { filename: fileData.filename }
|
|
659
|
+
} : void 0;
|
|
660
|
+
this.run(message, imageDataForRun, fileDataForRun, sessionId, true).catch((error) => {
|
|
661
|
+
_streamError = error;
|
|
662
|
+
completed = true;
|
|
663
|
+
this.logger.error(
|
|
664
|
+
`Error in DextoAgent.stream: ${error instanceof Error ? error.message : String(error)}`
|
|
665
|
+
);
|
|
666
|
+
eventQueue.push({
|
|
667
|
+
type: "llm:error",
|
|
668
|
+
error,
|
|
669
|
+
recoverable: false,
|
|
670
|
+
context: "run_failed",
|
|
671
|
+
sessionId
|
|
672
|
+
});
|
|
673
|
+
});
|
|
674
|
+
const iterator = {
|
|
675
|
+
async next() {
|
|
676
|
+
while (!completed && eventQueue.length === 0) {
|
|
677
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
678
|
+
if (signal?.aborted) {
|
|
679
|
+
cleanupListeners();
|
|
680
|
+
controller.abort();
|
|
681
|
+
return { done: true, value: void 0 };
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
if (eventQueue.length > 0) {
|
|
685
|
+
return { done: false, value: eventQueue.shift() };
|
|
686
|
+
}
|
|
687
|
+
if (completed) {
|
|
688
|
+
cleanupListeners();
|
|
689
|
+
controller.abort();
|
|
690
|
+
return { done: true, value: void 0 };
|
|
691
|
+
}
|
|
692
|
+
cleanupListeners();
|
|
693
|
+
return { done: true, value: void 0 };
|
|
694
|
+
},
|
|
695
|
+
async return() {
|
|
696
|
+
cleanupListeners();
|
|
697
|
+
controller.abort();
|
|
698
|
+
return { done: true, value: void 0 };
|
|
699
|
+
},
|
|
700
|
+
[Symbol.asyncIterator]() {
|
|
701
|
+
return iterator;
|
|
702
|
+
}
|
|
703
|
+
};
|
|
704
|
+
return iterator;
|
|
705
|
+
}
|
|
706
|
+
/**
|
|
707
|
+
* Cancels the currently running turn for a session.
|
|
426
708
|
* Safe to call even if no run is in progress.
|
|
427
|
-
* @param sessionId
|
|
709
|
+
* @param sessionId Session id (required)
|
|
428
710
|
* @returns true if a run was in progress and was signaled to abort; false otherwise
|
|
429
711
|
*/
|
|
430
712
|
async cancel(sessionId) {
|
|
431
713
|
this.ensureStarted();
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
return this.defaultSession.cancel();
|
|
714
|
+
if (!sessionId || typeof sessionId !== "string") {
|
|
715
|
+
throw new Error("sessionId is required and must be a non-empty string");
|
|
435
716
|
}
|
|
436
|
-
const existing = await this.sessionManager.getSession(
|
|
717
|
+
const existing = await this.sessionManager.getSession(sessionId, false);
|
|
437
718
|
if (existing) {
|
|
438
719
|
return existing.cancel();
|
|
439
720
|
}
|
|
@@ -473,9 +754,6 @@ class DextoAgent {
|
|
|
473
754
|
*/
|
|
474
755
|
async endSession(sessionId) {
|
|
475
756
|
this.ensureStarted();
|
|
476
|
-
if (sessionId === this.currentDefaultSessionId) {
|
|
477
|
-
this.defaultSession = null;
|
|
478
|
-
}
|
|
479
757
|
return this.sessionManager.endSession(sessionId);
|
|
480
758
|
}
|
|
481
759
|
/**
|
|
@@ -485,9 +763,6 @@ class DextoAgent {
|
|
|
485
763
|
*/
|
|
486
764
|
async deleteSession(sessionId) {
|
|
487
765
|
this.ensureStarted();
|
|
488
|
-
if (sessionId === this.currentDefaultSessionId) {
|
|
489
|
-
this.defaultSession = null;
|
|
490
|
-
}
|
|
491
766
|
return this.sessionManager.deleteSession(sessionId);
|
|
492
767
|
}
|
|
493
768
|
/**
|
|
@@ -514,66 +789,63 @@ class DextoAgent {
|
|
|
514
789
|
return await this.sessionManager.getSessionTitle(sessionId);
|
|
515
790
|
}
|
|
516
791
|
/**
|
|
517
|
-
*
|
|
518
|
-
*
|
|
519
|
-
*
|
|
792
|
+
* Generate a title for a session on-demand.
|
|
793
|
+
* Uses the first user message content to generate a descriptive title.
|
|
794
|
+
*
|
|
795
|
+
* @param sessionId Session ID to generate title for
|
|
796
|
+
* @returns Promise that resolves to the generated title, or null if generation failed
|
|
520
797
|
*/
|
|
521
|
-
async
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
if (metadata.title) {
|
|
531
|
-
import_logger.logger.debug(
|
|
532
|
-
`[SessionTitle] Session ${sessionId} already has title '${metadata.title}', skipping`
|
|
533
|
-
);
|
|
534
|
-
return;
|
|
535
|
-
}
|
|
536
|
-
if (!userText || !userText.trim()) {
|
|
537
|
-
import_logger.logger.debug(
|
|
538
|
-
`[SessionTitle] User text empty for session ${sessionId}, skipping title generation`
|
|
539
|
-
);
|
|
540
|
-
return;
|
|
541
|
-
}
|
|
542
|
-
import_logger.logger.debug(
|
|
543
|
-
`[SessionTitle] Checking title generation preconditions for session ${sessionId}`
|
|
544
|
-
);
|
|
545
|
-
const result = await (0, import_title_generator.generateSessionTitle)(
|
|
546
|
-
llmConfig,
|
|
547
|
-
llmConfig.router,
|
|
548
|
-
this.toolManager,
|
|
549
|
-
this.systemPromptManager,
|
|
550
|
-
this.resourceManager,
|
|
551
|
-
userText
|
|
798
|
+
async generateSessionTitle(sessionId) {
|
|
799
|
+
this.ensureStarted();
|
|
800
|
+
const metadata = await this.sessionManager.getSessionMetadata(sessionId);
|
|
801
|
+
if (!metadata) {
|
|
802
|
+
throw import_session.SessionError.notFound(sessionId);
|
|
803
|
+
}
|
|
804
|
+
if (metadata.title) {
|
|
805
|
+
this.logger.debug(
|
|
806
|
+
`[SessionTitle] Session ${sessionId} already has title '${metadata.title}'`
|
|
552
807
|
);
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
808
|
+
return metadata.title;
|
|
809
|
+
}
|
|
810
|
+
const session = await this.sessionManager.getSession(sessionId);
|
|
811
|
+
if (!session) {
|
|
812
|
+
throw import_session.SessionError.notFound(sessionId);
|
|
813
|
+
}
|
|
814
|
+
const history = await session.getHistory();
|
|
815
|
+
const firstUserMsg = history.find((m) => m.role === "user");
|
|
816
|
+
if (!firstUserMsg) {
|
|
817
|
+
this.logger.debug(`[SessionTitle] No user message found for session ${sessionId}`);
|
|
818
|
+
return null;
|
|
819
|
+
}
|
|
820
|
+
const userText = typeof firstUserMsg.content === "string" ? firstUserMsg.content : firstUserMsg.content?.filter((p) => p.type === "text").map((p) => p.text).join(" ");
|
|
821
|
+
if (!userText || !userText.trim()) {
|
|
822
|
+
this.logger.debug(`[SessionTitle] Empty user text for session ${sessionId}`);
|
|
823
|
+
return null;
|
|
824
|
+
}
|
|
825
|
+
const llmConfig = this.getEffectiveConfig(sessionId).llm;
|
|
826
|
+
const result = await (0, import_title_generator.generateSessionTitle)(
|
|
827
|
+
llmConfig,
|
|
828
|
+
llmConfig.router,
|
|
829
|
+
this.toolManager,
|
|
830
|
+
this.systemPromptManager,
|
|
831
|
+
this.resourceManager,
|
|
832
|
+
userText,
|
|
833
|
+
this.logger
|
|
834
|
+
);
|
|
835
|
+
let title = result.title;
|
|
836
|
+
if (!title) {
|
|
837
|
+
title = (0, import_title_generator.deriveHeuristicTitle)(userText);
|
|
838
|
+
if (title) {
|
|
839
|
+
this.logger.info(`[SessionTitle] Using heuristic title for ${sessionId}: ${title}`);
|
|
569
840
|
} else {
|
|
570
|
-
|
|
841
|
+
this.logger.debug(`[SessionTitle] No suitable title derived for ${sessionId}`);
|
|
842
|
+
return null;
|
|
571
843
|
}
|
|
572
|
-
|
|
573
|
-
this.
|
|
574
|
-
} catch (err) {
|
|
575
|
-
import_logger.logger.silly(`Title generation skipped/failed for ${sessionId}: ${String(err)}`);
|
|
844
|
+
} else {
|
|
845
|
+
this.logger.info(`[SessionTitle] Generated LLM title for ${sessionId}: ${title}`);
|
|
576
846
|
}
|
|
847
|
+
await this.sessionManager.setSessionTitle(sessionId, title, { ifUnsetOnly: true });
|
|
848
|
+
return title;
|
|
577
849
|
}
|
|
578
850
|
/**
|
|
579
851
|
* Gets the conversation history for a specific session.
|
|
@@ -594,14 +866,16 @@ class DextoAgent {
|
|
|
594
866
|
return await Promise.all(
|
|
595
867
|
history.map(async (message) => ({
|
|
596
868
|
...message,
|
|
597
|
-
content: await (0, import_utils.expandBlobReferences)(
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
869
|
+
content: await (0, import_utils.expandBlobReferences)(
|
|
870
|
+
message.content,
|
|
871
|
+
this.resourceManager,
|
|
872
|
+
this.logger
|
|
873
|
+
).catch((error) => {
|
|
874
|
+
this.logger.warn(
|
|
875
|
+
`Failed to expand blob references in message: ${error instanceof Error ? error.message : String(error)}`
|
|
876
|
+
);
|
|
877
|
+
return message.content;
|
|
878
|
+
})
|
|
605
879
|
}))
|
|
606
880
|
);
|
|
607
881
|
}
|
|
@@ -627,88 +901,23 @@ class DextoAgent {
|
|
|
627
901
|
return await this.searchService.searchSessions(query);
|
|
628
902
|
}
|
|
629
903
|
/**
|
|
630
|
-
*
|
|
631
|
-
* All subsequent operations that don't specify a session ID will use this session.
|
|
632
|
-
* This provides a clean "current working session" pattern for API users.
|
|
633
|
-
*
|
|
634
|
-
* @param sessionId The session ID to load as default, or null to reset to original default
|
|
635
|
-
* @throws Error if session doesn't exist
|
|
636
|
-
*
|
|
637
|
-
* @example
|
|
638
|
-
* ```typescript
|
|
639
|
-
* // Load a specific session as default
|
|
640
|
-
* await agent.loadSessionAsDefault('project-alpha');
|
|
641
|
-
* await agent.run("What's the status?"); // Uses project-alpha session
|
|
642
|
-
*
|
|
643
|
-
* // Reset to original default
|
|
644
|
-
* await agent.loadSessionAsDefault(null);
|
|
645
|
-
* await agent.run("Hello"); // Uses 'default' session
|
|
646
|
-
* ```
|
|
647
|
-
*/
|
|
648
|
-
async loadSessionAsDefault(sessionId = null) {
|
|
649
|
-
this.ensureStarted();
|
|
650
|
-
if (sessionId === null) {
|
|
651
|
-
this.currentDefaultSessionId = "default";
|
|
652
|
-
this.defaultSession = null;
|
|
653
|
-
import_logger.logger.debug("Agent default session reset to original default");
|
|
654
|
-
return;
|
|
655
|
-
}
|
|
656
|
-
const session = await this.sessionManager.getSession(sessionId);
|
|
657
|
-
if (!session) {
|
|
658
|
-
throw import_session.SessionError.notFound(sessionId);
|
|
659
|
-
}
|
|
660
|
-
this.currentDefaultSessionId = sessionId;
|
|
661
|
-
this.defaultSession = null;
|
|
662
|
-
import_logger.logger.info(`Agent default session changed to: ${sessionId}`);
|
|
663
|
-
}
|
|
664
|
-
/**
|
|
665
|
-
* Gets the currently loaded default session ID.
|
|
666
|
-
* This reflects the session loaded via loadSession().
|
|
667
|
-
*
|
|
668
|
-
* @returns The current default session ID
|
|
669
|
-
*/
|
|
670
|
-
getCurrentSessionId() {
|
|
671
|
-
this.ensureStarted();
|
|
672
|
-
return this.currentDefaultSessionId;
|
|
673
|
-
}
|
|
674
|
-
/**
|
|
675
|
-
* Gets the currently loaded default session.
|
|
676
|
-
* This respects the session loaded via loadSession().
|
|
677
|
-
*
|
|
678
|
-
* @returns The current default ChatSession
|
|
679
|
-
*/
|
|
680
|
-
async getDefaultSession() {
|
|
681
|
-
this.ensureStarted();
|
|
682
|
-
if (!this.defaultSession || this.defaultSession.id !== this.currentDefaultSessionId) {
|
|
683
|
-
this.defaultSession = await this.sessionManager.createSession(
|
|
684
|
-
this.currentDefaultSessionId
|
|
685
|
-
);
|
|
686
|
-
}
|
|
687
|
-
return this.defaultSession;
|
|
688
|
-
}
|
|
689
|
-
/**
|
|
690
|
-
* Resets the conversation history for a specific session or the default session.
|
|
904
|
+
* Resets the conversation history for a specific session.
|
|
691
905
|
* Keeps the session alive but the conversation history is cleared.
|
|
692
|
-
* @param sessionId
|
|
906
|
+
* @param sessionId Session ID (required)
|
|
693
907
|
*/
|
|
694
908
|
async resetConversation(sessionId) {
|
|
695
909
|
this.ensureStarted();
|
|
910
|
+
if (!sessionId || typeof sessionId !== "string") {
|
|
911
|
+
throw new Error("sessionId is required and must be a non-empty string");
|
|
912
|
+
}
|
|
696
913
|
try {
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
this.currentDefaultSessionId
|
|
702
|
-
);
|
|
703
|
-
}
|
|
704
|
-
}
|
|
705
|
-
await this.sessionManager.resetSession(targetSessionId);
|
|
706
|
-
import_logger.logger.info(`DextoAgent conversation reset for session: ${targetSessionId}`);
|
|
707
|
-
this.agentEventBus.emit("dexto:conversationReset", {
|
|
708
|
-
sessionId: targetSessionId
|
|
914
|
+
await this.sessionManager.resetSession(sessionId);
|
|
915
|
+
this.logger.info(`DextoAgent conversation reset for session: ${sessionId}`);
|
|
916
|
+
this.agentEventBus.emit("session:reset", {
|
|
917
|
+
sessionId
|
|
709
918
|
});
|
|
710
919
|
} catch (error) {
|
|
711
|
-
|
|
920
|
+
this.logger.error(
|
|
712
921
|
`Error during DextoAgent.resetConversation: ${error instanceof Error ? error.message : String(error)}`
|
|
713
922
|
);
|
|
714
923
|
throw error;
|
|
@@ -762,22 +971,24 @@ class DextoAgent {
|
|
|
762
971
|
*/
|
|
763
972
|
async switchLLM(llmUpdates, sessionId) {
|
|
764
973
|
this.ensureStarted();
|
|
765
|
-
|
|
974
|
+
this.logger.debug(`DextoAgent.switchLLM: llmUpdates: ${(0, import_safe_stringify.safeStringify)(llmUpdates)}`);
|
|
766
975
|
const parseResult = import_schemas.LLMUpdatesSchema.safeParse(llmUpdates);
|
|
767
976
|
if (!parseResult.success) {
|
|
768
977
|
const validation = (0, import_result.fail)((0, import_result.zodToIssues)(parseResult.error, "error"));
|
|
769
|
-
(0, import_result_bridge.ensureOk)(validation);
|
|
978
|
+
(0, import_result_bridge.ensureOk)(validation, this.logger);
|
|
770
979
|
throw new Error("Unreachable");
|
|
771
980
|
}
|
|
772
981
|
const validatedUpdates = parseResult.data;
|
|
773
982
|
const currentLLMConfig = sessionId ? this.stateManager.getRuntimeConfig(sessionId).llm : this.stateManager.getRuntimeConfig().llm;
|
|
774
|
-
const result = (0, import_resolver.resolveAndValidateLLMConfig)(currentLLMConfig, validatedUpdates);
|
|
775
|
-
const validatedConfig = (0, import_result_bridge.ensureOk)(result);
|
|
983
|
+
const result = (0, import_resolver.resolveAndValidateLLMConfig)(currentLLMConfig, validatedUpdates, this.logger);
|
|
984
|
+
const validatedConfig = (0, import_result_bridge.ensureOk)(result, this.logger);
|
|
776
985
|
await this.performLLMSwitch(validatedConfig, sessionId);
|
|
777
|
-
|
|
986
|
+
this.logger.info(
|
|
987
|
+
`DextoAgent.switchLLM: LLM switched to: ${(0, import_safe_stringify.safeStringify)(validatedConfig)}`
|
|
988
|
+
);
|
|
778
989
|
const warnings = result.issues.filter((issue) => issue.severity === "warning");
|
|
779
990
|
if (warnings.length > 0) {
|
|
780
|
-
|
|
991
|
+
this.logger.warn(
|
|
781
992
|
`LLM switch completed with warnings: ${warnings.map((w) => w.message).join(", ")}`
|
|
782
993
|
);
|
|
783
994
|
}
|
|
@@ -801,7 +1012,7 @@ class DextoAgent {
|
|
|
801
1012
|
}
|
|
802
1013
|
await this.sessionManager.switchLLMForSpecificSession(validatedConfig, sessionScope);
|
|
803
1014
|
} else {
|
|
804
|
-
|
|
1015
|
+
this.logger.debug("LLM config updated at agent level (no active session switches)");
|
|
805
1016
|
}
|
|
806
1017
|
}
|
|
807
1018
|
/**
|
|
@@ -915,36 +1126,40 @@ class DextoAgent {
|
|
|
915
1126
|
this.ensureStarted();
|
|
916
1127
|
const existingServerNames = Object.keys(this.stateManager.getRuntimeConfig().mcpServers);
|
|
917
1128
|
const validation = (0, import_resolver2.resolveAndValidateMcpServerConfig)(name, config, existingServerNames);
|
|
918
|
-
const validatedConfig = (0, import_result_bridge.ensureOk)(validation);
|
|
1129
|
+
const validatedConfig = (0, import_result_bridge.ensureOk)(validation, this.logger);
|
|
919
1130
|
this.stateManager.addMcpServer(name, validatedConfig);
|
|
920
1131
|
try {
|
|
921
1132
|
await this.mcpManager.connectServer(name, validatedConfig);
|
|
922
1133
|
await this.toolManager.refresh();
|
|
923
|
-
this.agentEventBus.emit("
|
|
1134
|
+
this.agentEventBus.emit("mcp:server-connected", {
|
|
924
1135
|
name,
|
|
925
1136
|
success: true
|
|
926
1137
|
});
|
|
927
|
-
this.agentEventBus.emit("
|
|
1138
|
+
this.agentEventBus.emit("tools:available-updated", {
|
|
928
1139
|
tools: Object.keys(await this.toolManager.getAllTools()),
|
|
929
1140
|
source: "mcp"
|
|
930
1141
|
});
|
|
931
|
-
|
|
1142
|
+
this.logger.info(
|
|
1143
|
+
`DextoAgent: Successfully added and connected to MCP server '${name}'.`
|
|
1144
|
+
);
|
|
932
1145
|
const warnings = validation.issues.filter((i) => i.severity === "warning");
|
|
933
1146
|
if (warnings.length > 0) {
|
|
934
|
-
|
|
1147
|
+
this.logger.warn(
|
|
935
1148
|
`MCP server connected with warnings: ${warnings.map((w) => w.message).join(", ")}`
|
|
936
1149
|
);
|
|
937
1150
|
}
|
|
938
1151
|
} catch (error) {
|
|
939
1152
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
940
|
-
|
|
1153
|
+
this.logger.error(
|
|
1154
|
+
`DextoAgent: Failed to connect to MCP server '${name}': ${errorMessage}`
|
|
1155
|
+
);
|
|
941
1156
|
this.stateManager.removeMcpServer(name);
|
|
942
|
-
this.agentEventBus.emit("
|
|
1157
|
+
this.agentEventBus.emit("mcp:server-connected", {
|
|
943
1158
|
name,
|
|
944
1159
|
success: false,
|
|
945
1160
|
error: errorMessage
|
|
946
1161
|
});
|
|
947
|
-
throw
|
|
1162
|
+
throw import_errors3.MCPError.connectionFailed(name, errorMessage);
|
|
948
1163
|
}
|
|
949
1164
|
}
|
|
950
1165
|
/**
|
|
@@ -966,20 +1181,22 @@ class DextoAgent {
|
|
|
966
1181
|
async restartMcpServer(name) {
|
|
967
1182
|
this.ensureStarted();
|
|
968
1183
|
try {
|
|
969
|
-
|
|
1184
|
+
this.logger.info(`DextoAgent: Restarting MCP server '${name}'...`);
|
|
970
1185
|
await this.mcpManager.restartServer(name);
|
|
971
1186
|
await this.toolManager.refresh();
|
|
972
|
-
this.agentEventBus.emit("
|
|
1187
|
+
this.agentEventBus.emit("mcp:server-restarted", {
|
|
973
1188
|
serverName: name
|
|
974
1189
|
});
|
|
975
|
-
this.agentEventBus.emit("
|
|
1190
|
+
this.agentEventBus.emit("tools:available-updated", {
|
|
976
1191
|
tools: Object.keys(await this.toolManager.getAllTools()),
|
|
977
1192
|
source: "mcp"
|
|
978
1193
|
});
|
|
979
|
-
|
|
1194
|
+
this.logger.info(`DextoAgent: Successfully restarted MCP server '${name}'.`);
|
|
980
1195
|
} catch (error) {
|
|
981
1196
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
982
|
-
|
|
1197
|
+
this.logger.error(
|
|
1198
|
+
`DextoAgent: Failed to restart MCP server '${name}': ${errorMessage}`
|
|
1199
|
+
);
|
|
983
1200
|
throw error;
|
|
984
1201
|
}
|
|
985
1202
|
}
|
|
@@ -1094,10 +1311,10 @@ class DextoAgent {
|
|
|
1094
1311
|
*/
|
|
1095
1312
|
async getSystemPrompt() {
|
|
1096
1313
|
this.ensureStarted();
|
|
1097
|
-
const
|
|
1314
|
+
const context2 = {
|
|
1098
1315
|
mcpManager: this.mcpManager
|
|
1099
1316
|
};
|
|
1100
|
-
return await this.systemPromptManager.build(
|
|
1317
|
+
return await this.systemPromptManager.build(context2);
|
|
1101
1318
|
}
|
|
1102
1319
|
/**
|
|
1103
1320
|
* Lists all available prompts from all providers (MCP, internal, starter, custom).
|
|
@@ -1171,7 +1388,8 @@ class DextoAgent {
|
|
|
1171
1388
|
/**
|
|
1172
1389
|
* Gets the effective configuration for a session or the default configuration.
|
|
1173
1390
|
* @param sessionId Optional session ID. If not provided, returns default config.
|
|
1174
|
-
* @returns The effective configuration object
|
|
1391
|
+
* @returns The effective configuration object (validated with defaults applied)
|
|
1392
|
+
* @remarks Requires agent to be started. Use `agent.config` for pre-start access.
|
|
1175
1393
|
*/
|
|
1176
1394
|
getEffectiveConfig(sessionId) {
|
|
1177
1395
|
this.ensureStarted();
|
|
@@ -1185,89 +1403,53 @@ class DextoAgent {
|
|
|
1185
1403
|
*/
|
|
1186
1404
|
getAgentFilePath() {
|
|
1187
1405
|
if (!this.configPath) {
|
|
1188
|
-
throw
|
|
1406
|
+
throw import_errors2.AgentError.noConfigPath();
|
|
1189
1407
|
}
|
|
1190
1408
|
return this.configPath;
|
|
1191
1409
|
}
|
|
1192
1410
|
/**
|
|
1193
|
-
* Reloads the agent configuration
|
|
1194
|
-
*
|
|
1195
|
-
*
|
|
1196
|
-
*
|
|
1197
|
-
* To apply changes: stop the agent and start it again with the new config.
|
|
1411
|
+
* Reloads the agent configuration with a new config object.
|
|
1412
|
+
* Validates the new config, detects what changed, and automatically
|
|
1413
|
+
* restarts the agent if necessary to apply the changes.
|
|
1198
1414
|
*
|
|
1199
|
-
* @
|
|
1200
|
-
* @
|
|
1415
|
+
* @param newConfig The new agent configuration to apply
|
|
1416
|
+
* @returns Object containing whether agent was restarted and list of changes applied
|
|
1417
|
+
* @throws Error if config is invalid or restart fails
|
|
1201
1418
|
*
|
|
1202
1419
|
* TODO: improve hot reload capabilites so that we don't always require a restart
|
|
1203
1420
|
*/
|
|
1204
|
-
async
|
|
1205
|
-
|
|
1206
|
-
throw import_errors.AgentError.noConfigPath();
|
|
1207
|
-
}
|
|
1208
|
-
import_logger.logger.info(`Reloading agent configuration from: ${this.configPath}`);
|
|
1421
|
+
async reload(newConfig) {
|
|
1422
|
+
this.logger.info("Reloading agent configuration");
|
|
1209
1423
|
const oldConfig = this.config;
|
|
1210
|
-
const newConfig = await (0, import_loader.loadAgentConfig)(this.configPath);
|
|
1211
1424
|
const validated = import_schemas2.AgentConfigSchema.parse(newConfig);
|
|
1212
|
-
const
|
|
1425
|
+
const changesApplied = this.detectConfigChanges(oldConfig, validated);
|
|
1213
1426
|
this.config = validated;
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1427
|
+
let restarted = false;
|
|
1428
|
+
if (changesApplied.length > 0) {
|
|
1429
|
+
this.logger.info(
|
|
1430
|
+
`Configuration changed. Restarting agent to apply: ${changesApplied.join(", ")}`
|
|
1217
1431
|
);
|
|
1432
|
+
await this.restart();
|
|
1433
|
+
restarted = true;
|
|
1434
|
+
this.logger.info("Agent restarted successfully with new configuration");
|
|
1218
1435
|
} else {
|
|
1219
|
-
|
|
1436
|
+
this.logger.info("Agent configuration reloaded successfully (no changes detected)");
|
|
1220
1437
|
}
|
|
1221
1438
|
return {
|
|
1222
|
-
|
|
1439
|
+
restarted,
|
|
1440
|
+
changesApplied
|
|
1223
1441
|
};
|
|
1224
1442
|
}
|
|
1225
|
-
/**
|
|
1226
|
-
* Updates and saves the agent configuration to disk.
|
|
1227
|
-
* This merges the updates with the raw config from disk, validates, and writes to file.
|
|
1228
|
-
* IMPORTANT: This preserves environment variable placeholders (e.g., $OPENAI_API_KEY)
|
|
1229
|
-
* to avoid leaking secrets into the config file.
|
|
1230
|
-
* @param updates Partial configuration updates to apply
|
|
1231
|
-
* @param targetPath Optional path to save to (defaults to current config path)
|
|
1232
|
-
* @returns Object containing list of changes that require restart
|
|
1233
|
-
* @throws Error if validation fails or file cannot be written
|
|
1234
|
-
*/
|
|
1235
|
-
async updateAndSaveConfig(updates, targetPath) {
|
|
1236
|
-
const path = targetPath || this.configPath;
|
|
1237
|
-
if (!path) {
|
|
1238
|
-
throw import_errors.AgentError.noConfigPath();
|
|
1239
|
-
}
|
|
1240
|
-
import_logger.logger.info(`Updating and saving agent configuration to: ${path}`);
|
|
1241
|
-
const rawYaml = await import_fs.promises.readFile(path, "utf-8");
|
|
1242
|
-
const doc = (0, import_yaml.parseDocument)(rawYaml);
|
|
1243
|
-
const rawConfig = doc.toJSON();
|
|
1244
|
-
const updatedRawConfig = { ...rawConfig, ...updates };
|
|
1245
|
-
const parsed = import_schemas2.AgentConfigSchema.safeParse(updatedRawConfig);
|
|
1246
|
-
if (!parsed.success) {
|
|
1247
|
-
const result = (0, import_result.fail)((0, import_result.zodToIssues)(parsed.error, "error"));
|
|
1248
|
-
throw new import_DextoValidationError.DextoValidationError(result.issues);
|
|
1249
|
-
}
|
|
1250
|
-
for (const [key, value] of Object.entries(updates)) {
|
|
1251
|
-
doc.set(key, value);
|
|
1252
|
-
}
|
|
1253
|
-
const yamlContent = String(doc);
|
|
1254
|
-
const tmpPath = `${path}.tmp`;
|
|
1255
|
-
await import_fs.promises.writeFile(tmpPath, yamlContent, "utf-8");
|
|
1256
|
-
await import_fs.promises.rename(tmpPath, path);
|
|
1257
|
-
const reloadResult = await this.reloadConfig();
|
|
1258
|
-
import_logger.logger.info(`Agent configuration saved to: ${path}`);
|
|
1259
|
-
return reloadResult;
|
|
1260
|
-
}
|
|
1261
1443
|
/**
|
|
1262
1444
|
* Detects configuration changes that require a full agent restart.
|
|
1445
|
+
* Pure comparison logic - no file I/O.
|
|
1263
1446
|
* Returns an array of change descriptions.
|
|
1264
1447
|
*
|
|
1265
1448
|
* @param oldConfig Previous validated configuration
|
|
1266
1449
|
* @param newConfig New validated configuration
|
|
1267
1450
|
* @returns Array of restart-required change descriptions
|
|
1268
|
-
* @private
|
|
1269
1451
|
*/
|
|
1270
|
-
|
|
1452
|
+
detectConfigChanges(oldConfig, newConfig) {
|
|
1271
1453
|
const changes = [];
|
|
1272
1454
|
if (JSON.stringify(oldConfig.storage) !== JSON.stringify(newConfig.storage)) {
|
|
1273
1455
|
changes.push("Storage backend");
|
|
@@ -1292,6 +1474,58 @@ class DextoAgent {
|
|
|
1292
1474
|
}
|
|
1293
1475
|
return changes;
|
|
1294
1476
|
}
|
|
1477
|
+
// ============= APPROVAL HANDLER API =============
|
|
1478
|
+
/**
|
|
1479
|
+
* Set a custom approval handler for manual approval mode.
|
|
1480
|
+
*
|
|
1481
|
+
* When `toolConfirmation.mode` is set to 'manual', an approval handler must be
|
|
1482
|
+
* provided to process tool confirmation requests. The handler will be called
|
|
1483
|
+
* whenever a tool execution requires user approval.
|
|
1484
|
+
*
|
|
1485
|
+
* The handler receives an approval request and must return a promise that resolves
|
|
1486
|
+
* to an approval response with the user's decision (approved/denied/cancelled).
|
|
1487
|
+
*
|
|
1488
|
+
* @param handler The approval handler function
|
|
1489
|
+
*
|
|
1490
|
+
* @example
|
|
1491
|
+
* ```typescript
|
|
1492
|
+
* import { ApprovalStatus } from '@dexto/core';
|
|
1493
|
+
*
|
|
1494
|
+
* agent.setApprovalHandler(async (request) => {
|
|
1495
|
+
* // Present approval request to user (CLI, UI, webhook, etc.)
|
|
1496
|
+
* console.log(`Approve tool: ${request.metadata.toolName}?`);
|
|
1497
|
+
* console.log(`Args: ${JSON.stringify(request.metadata.args)}`);
|
|
1498
|
+
*
|
|
1499
|
+
* // Collect user's decision (this is just an example)
|
|
1500
|
+
* const approved = await getUserInput();
|
|
1501
|
+
*
|
|
1502
|
+
* return {
|
|
1503
|
+
* approvalId: request.approvalId,
|
|
1504
|
+
* status: approved ? ApprovalStatus.APPROVED : ApprovalStatus.DENIED,
|
|
1505
|
+
* sessionId: request.sessionId,
|
|
1506
|
+
* };
|
|
1507
|
+
* });
|
|
1508
|
+
* ```
|
|
1509
|
+
*/
|
|
1510
|
+
setApprovalHandler(handler) {
|
|
1511
|
+
this.approvalHandler = handler;
|
|
1512
|
+
if (this._isStarted && this.services) {
|
|
1513
|
+
this.services.approvalManager.setHandler(handler);
|
|
1514
|
+
}
|
|
1515
|
+
this.logger.debug("Approval handler registered");
|
|
1516
|
+
}
|
|
1517
|
+
/**
|
|
1518
|
+
* Clear the current approval handler.
|
|
1519
|
+
*
|
|
1520
|
+
* After calling this, manual approval mode will fail if a tool requires approval.
|
|
1521
|
+
*/
|
|
1522
|
+
clearApprovalHandler() {
|
|
1523
|
+
this.approvalHandler = void 0;
|
|
1524
|
+
if (this._isStarted && this.services) {
|
|
1525
|
+
this.services.approvalManager.clearHandler();
|
|
1526
|
+
}
|
|
1527
|
+
this.logger.debug("Approval handler cleared");
|
|
1528
|
+
}
|
|
1295
1529
|
// ============= AGENT MANAGEMENT =============
|
|
1296
1530
|
// Note: Agent management methods have been moved to the Dexto orchestrator class.
|
|
1297
1531
|
// See: /packages/core/src/Dexto.ts
|