@dexto/core 1.2.6 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -13
- package/dist/agent/DextoAgent.cjs +627 -228
- package/dist/agent/DextoAgent.d.ts +157 -34
- package/dist/agent/DextoAgent.d.ts.map +1 -1
- package/dist/agent/DextoAgent.js +625 -227
- package/dist/agent/agentCard.js +1 -1
- package/dist/agent/error-codes.cjs +1 -0
- package/dist/agent/error-codes.d.ts +2 -1
- package/dist/agent/error-codes.d.ts.map +1 -1
- package/dist/agent/error-codes.js +2 -1
- package/dist/agent/errors.cjs +13 -0
- package/dist/agent/errors.d.ts +4 -0
- package/dist/agent/errors.d.ts.map +1 -1
- package/dist/agent/errors.js +14 -1
- package/dist/agent/index.d.ts +1 -1
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +1 -1
- package/dist/agent/schemas.cjs +4 -1
- package/dist/agent/schemas.d.ts +92 -55
- package/dist/agent/schemas.d.ts.map +1 -1
- package/dist/agent/schemas.js +7 -3
- package/dist/agent/state-manager.cjs +5 -5
- package/dist/agent/state-manager.d.ts +4 -4
- package/dist/agent/state-manager.js +6 -6
- package/dist/agent/types.d.ts +24 -11
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/approval/error-codes.js +1 -1
- package/dist/approval/errors.js +1 -1
- package/dist/approval/factory.js +1 -1
- package/dist/approval/index.js +1 -1
- package/dist/approval/manager.cjs +69 -3
- package/dist/approval/manager.d.ts +41 -3
- package/dist/approval/manager.d.ts.map +1 -1
- package/dist/approval/manager.js +70 -4
- package/dist/approval/schemas.cjs +20 -5
- package/dist/approval/schemas.d.ts +127 -52
- package/dist/approval/schemas.d.ts.map +1 -1
- package/dist/approval/schemas.js +21 -6
- package/dist/approval/types.d.ts +6 -0
- package/dist/approval/types.d.ts.map +1 -1
- package/dist/approval/types.js +1 -1
- package/dist/{chunk-C6A6W6XS.js → chunk-PTJYTZNU.js} +44 -1
- package/dist/{llm/tokenizer/factory.cjs → context/compression/overflow.cjs} +20 -21
- package/dist/context/compression/overflow.d.ts +33 -0
- package/dist/context/compression/overflow.d.ts.map +1 -0
- package/dist/context/compression/overflow.js +19 -0
- package/dist/context/compression/reactive-overflow.cjs +201 -0
- package/dist/context/compression/reactive-overflow.d.ts +81 -0
- package/dist/context/compression/reactive-overflow.d.ts.map +1 -0
- package/dist/context/compression/reactive-overflow.js +178 -0
- package/dist/context/compression/types.d.ts +9 -7
- package/dist/context/compression/types.d.ts.map +1 -1
- package/dist/context/error-codes.cjs +3 -0
- package/dist/context/error-codes.d.ts +4 -1
- package/dist/context/error-codes.d.ts.map +1 -1
- package/dist/context/error-codes.js +4 -1
- package/dist/context/errors.cjs +28 -0
- package/dist/context/errors.d.ts +7 -0
- package/dist/context/errors.d.ts.map +1 -1
- package/dist/context/errors.js +29 -1
- package/dist/context/index.js +1 -1
- package/dist/context/manager.cjs +287 -323
- package/dist/context/manager.d.ts +65 -111
- package/dist/context/manager.d.ts.map +1 -1
- package/dist/context/manager.js +287 -328
- package/dist/context/media-helpers.js +1 -1
- package/dist/context/types.cjs +49 -0
- package/dist/context/types.d.ts +185 -72
- package/dist/context/types.d.ts.map +1 -1
- package/dist/context/types.js +35 -0
- package/dist/context/utils.cjs +266 -283
- package/dist/context/utils.d.ts +32 -18
- package/dist/context/utils.d.ts.map +1 -1
- package/dist/context/utils.js +266 -283
- package/dist/errors/DextoBaseError.js +1 -1
- package/dist/errors/DextoRuntimeError.js +1 -1
- package/dist/errors/DextoValidationError.js +1 -1
- package/dist/errors/index.js +1 -1
- package/dist/errors/result-bridge.js +1 -1
- package/dist/errors/types.cjs +1 -0
- package/dist/errors/types.d.ts +4 -2
- package/dist/errors/types.d.ts.map +1 -1
- package/dist/errors/types.js +2 -1
- package/dist/events/index.cjs +22 -2
- package/dist/events/index.d.ts +170 -62
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +23 -3
- package/dist/filesystem/error-codes.js +1 -1
- package/dist/filesystem/errors.js +1 -1
- package/dist/filesystem/filesystem-service.js +1 -1
- package/dist/filesystem/index.js +1 -1
- package/dist/filesystem/path-validator.js +1 -1
- package/dist/index.browser.cjs +23 -8
- package/dist/index.browser.d.ts +4 -3
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +20 -3
- package/dist/index.js +1 -1
- package/dist/llm/error-codes.cjs +0 -1
- package/dist/llm/error-codes.d.ts +0 -1
- package/dist/llm/error-codes.d.ts.map +1 -1
- package/dist/llm/error-codes.js +1 -2
- package/dist/llm/errors.cjs +10 -10
- package/dist/llm/errors.d.ts +5 -6
- package/dist/llm/errors.d.ts.map +1 -1
- package/dist/llm/errors.js +12 -12
- package/dist/llm/executor/stream-processor.cjs +367 -0
- package/dist/llm/executor/stream-processor.d.ts +55 -0
- package/dist/llm/executor/stream-processor.d.ts.map +1 -0
- package/dist/llm/executor/stream-processor.js +344 -0
- package/dist/llm/executor/tool-output-truncator.cjs +75 -0
- package/dist/llm/executor/tool-output-truncator.d.ts +27 -0
- package/dist/llm/executor/tool-output-truncator.d.ts.map +1 -0
- package/dist/llm/executor/tool-output-truncator.js +48 -0
- package/dist/llm/executor/turn-executor.cjs +753 -0
- package/dist/llm/executor/turn-executor.d.ts +166 -0
- package/dist/llm/executor/turn-executor.d.ts.map +1 -0
- package/dist/llm/executor/turn-executor.js +684 -0
- package/dist/llm/executor/types.d.ts +27 -0
- package/dist/llm/executor/types.d.ts.map +1 -0
- package/dist/llm/formatters/vercel.cjs +20 -186
- package/dist/llm/formatters/vercel.d.ts +2 -14
- package/dist/llm/formatters/vercel.d.ts.map +1 -1
- package/dist/llm/formatters/vercel.js +19 -185
- package/dist/llm/registry.cjs +36 -45
- package/dist/llm/registry.d.ts +53 -39
- package/dist/llm/registry.d.ts.map +1 -1
- package/dist/llm/registry.js +34 -42
- package/dist/llm/resolver.cjs +1 -31
- package/dist/llm/resolver.d.ts.map +1 -1
- package/dist/llm/resolver.js +2 -34
- package/dist/llm/schemas.cjs +2 -17
- package/dist/llm/schemas.d.ts +10 -23
- package/dist/llm/schemas.d.ts.map +1 -1
- package/dist/llm/schemas.js +5 -22
- package/dist/llm/services/factory.cjs +3 -92
- package/dist/llm/services/factory.d.ts +14 -4
- package/dist/llm/services/factory.d.ts.map +1 -1
- package/dist/llm/services/factory.js +4 -83
- package/dist/llm/services/test-utils.integration.cjs +6 -8
- package/dist/llm/services/test-utils.integration.d.ts.map +1 -1
- package/dist/llm/services/test-utils.integration.js +7 -9
- package/dist/llm/services/types.d.ts +1 -28
- package/dist/llm/services/types.d.ts.map +1 -1
- package/dist/llm/services/vercel.cjs +54 -468
- package/dist/llm/services/vercel.d.ts +38 -21
- package/dist/llm/services/vercel.d.ts.map +1 -1
- package/dist/llm/services/vercel.js +56 -475
- package/dist/llm/types.cjs +0 -3
- package/dist/llm/types.d.ts +8 -8
- package/dist/llm/types.d.ts.map +1 -1
- package/dist/llm/types.js +1 -3
- package/dist/llm/validation.js +1 -1
- package/dist/logger/browser.js +1 -1
- package/dist/logger/factory.js +1 -1
- package/dist/logger/index.js +1 -1
- package/dist/logger/logger.js +1 -1
- package/dist/logger/v2/dexto-logger.cjs +34 -6
- package/dist/logger/v2/dexto-logger.d.ts +20 -2
- package/dist/logger/v2/dexto-logger.d.ts.map +1 -1
- package/dist/logger/v2/dexto-logger.js +35 -7
- package/dist/logger/v2/error-codes.js +1 -1
- package/dist/logger/v2/errors.js +1 -1
- package/dist/logger/v2/schemas.cjs +1 -1
- package/dist/logger/v2/schemas.js +2 -2
- package/dist/logger/v2/test-utils.cjs +70 -0
- package/dist/logger/v2/test-utils.d.ts +17 -0
- package/dist/logger/v2/test-utils.d.ts.map +1 -0
- package/dist/logger/v2/test-utils.js +46 -0
- package/dist/logger/v2/transport-factory.js +1 -1
- package/dist/logger/v2/transports/console-transport.js +1 -1
- package/dist/logger/v2/transports/file-transport.cjs +6 -0
- package/dist/logger/v2/transports/file-transport.d.ts +4 -0
- package/dist/logger/v2/transports/file-transport.d.ts.map +1 -1
- package/dist/logger/v2/transports/file-transport.js +7 -1
- package/dist/logger/v2/types.cjs +1 -0
- package/dist/logger/v2/types.d.ts +18 -2
- package/dist/logger/v2/types.d.ts.map +1 -1
- package/dist/logger/v2/types.js +2 -1
- package/dist/mcp/error-codes.cjs +1 -0
- package/dist/mcp/error-codes.d.ts +1 -0
- package/dist/mcp/error-codes.d.ts.map +1 -1
- package/dist/mcp/error-codes.js +2 -1
- package/dist/mcp/errors.cjs +13 -0
- package/dist/mcp/errors.d.ts +7 -0
- package/dist/mcp/errors.d.ts.map +1 -1
- package/dist/mcp/errors.js +14 -1
- package/dist/mcp/manager.cjs +4 -0
- package/dist/mcp/manager.d.ts.map +1 -1
- package/dist/mcp/manager.js +5 -1
- package/dist/mcp/mcp-client.js +1 -1
- package/dist/mcp/resolver.js +1 -1
- package/dist/mcp/schemas.cjs +6 -0
- package/dist/mcp/schemas.d.ts +52 -0
- package/dist/mcp/schemas.d.ts.map +1 -1
- package/dist/mcp/schemas.js +6 -1
- package/dist/memory/error-codes.js +1 -1
- package/dist/memory/errors.js +1 -1
- package/dist/memory/index.js +1 -1
- package/dist/memory/manager.js +1 -1
- package/dist/memory/schemas.d.ts +2 -2
- package/dist/memory/schemas.js +1 -1
- package/dist/plugins/builtins/content-policy.js +1 -1
- package/dist/plugins/builtins/response-sanitizer.js +1 -1
- package/dist/plugins/error-codes.cjs +1 -0
- package/dist/plugins/error-codes.d.ts +3 -1
- package/dist/plugins/error-codes.d.ts.map +1 -1
- package/dist/plugins/error-codes.js +2 -1
- package/dist/plugins/index.js +1 -1
- package/dist/plugins/loader.cjs +25 -5
- package/dist/plugins/loader.d.ts.map +1 -1
- package/dist/plugins/loader.js +26 -6
- package/dist/plugins/manager.js +1 -1
- package/dist/plugins/registrations/builtins.js +1 -1
- package/dist/plugins/schemas.d.ts +3 -3
- package/dist/plugins/schemas.js +1 -1
- package/dist/plugins/types.d.ts +0 -1
- package/dist/plugins/types.d.ts.map +1 -1
- package/dist/process/command-validator.js +1 -1
- package/dist/process/error-codes.js +1 -1
- package/dist/process/errors.js +1 -1
- package/dist/process/index.js +1 -1
- package/dist/process/process-service.cjs +78 -26
- package/dist/process/process-service.d.ts +6 -1
- package/dist/process/process-service.d.ts.map +1 -1
- package/dist/process/process-service.js +79 -27
- package/dist/process/types.d.ts +2 -2
- package/dist/process/types.d.ts.map +1 -1
- package/dist/prompts/error-codes.cjs +1 -0
- package/dist/prompts/error-codes.d.ts +2 -1
- package/dist/prompts/error-codes.d.ts.map +1 -1
- package/dist/prompts/error-codes.js +2 -1
- package/dist/prompts/errors.cjs +15 -0
- package/dist/prompts/errors.d.ts +4 -0
- package/dist/prompts/errors.d.ts.map +1 -1
- package/dist/prompts/errors.js +16 -1
- package/dist/prompts/index.js +1 -1
- package/dist/prompts/name-validation.js +1 -1
- package/dist/prompts/prompt-manager.cjs +13 -2
- package/dist/prompts/prompt-manager.d.ts +7 -0
- package/dist/prompts/prompt-manager.d.ts.map +1 -1
- package/dist/prompts/prompt-manager.js +14 -3
- package/dist/prompts/providers/config-prompt-provider.cjs +12 -3
- package/dist/prompts/providers/config-prompt-provider.d.ts +2 -1
- package/dist/prompts/providers/config-prompt-provider.d.ts.map +1 -1
- package/dist/prompts/providers/config-prompt-provider.js +13 -4
- package/dist/prompts/providers/custom-prompt-provider.cjs +2 -2
- package/dist/prompts/providers/custom-prompt-provider.d.ts +1 -1
- package/dist/prompts/providers/custom-prompt-provider.d.ts.map +1 -1
- package/dist/prompts/providers/custom-prompt-provider.js +3 -3
- package/dist/prompts/providers/mcp-prompt-provider.js +1 -1
- package/dist/prompts/schemas.d.ts +12 -0
- package/dist/prompts/schemas.d.ts.map +1 -1
- package/dist/prompts/schemas.js +1 -1
- package/dist/prompts/types.d.ts +2 -0
- package/dist/prompts/types.d.ts.map +1 -1
- package/dist/prompts/utils.js +1 -1
- package/dist/resources/error-codes.js +1 -1
- package/dist/resources/errors.js +1 -1
- package/dist/resources/handlers/blob-handler.js +1 -1
- package/dist/resources/handlers/factory.js +1 -1
- package/dist/resources/handlers/filesystem-handler.js +1 -1
- package/dist/resources/index.js +1 -1
- package/dist/resources/internal-provider.js +1 -1
- package/dist/resources/manager.js +1 -1
- package/dist/resources/reference-parser.js +1 -1
- package/dist/resources/schemas.js +1 -1
- package/dist/search/index.js +1 -1
- package/dist/search/search-service.js +1 -1
- package/dist/session/chat-session.cjs +149 -51
- package/dist/session/chat-session.d.ts +69 -29
- package/dist/session/chat-session.d.ts.map +1 -1
- package/dist/session/chat-session.js +150 -52
- package/dist/session/error-codes.js +1 -1
- package/dist/session/errors.js +1 -1
- package/dist/session/history/database.cjs +134 -21
- package/dist/session/history/database.d.ts +37 -8
- package/dist/session/history/database.d.ts.map +1 -1
- package/dist/session/history/database.js +135 -22
- package/dist/session/history/factory.js +1 -1
- package/dist/session/history/memory.cjs +18 -0
- package/dist/session/history/memory.d.ts +8 -0
- package/dist/session/history/memory.d.ts.map +1 -1
- package/dist/session/history/memory.js +19 -1
- package/dist/session/history/types.d.ts +13 -1
- package/dist/session/history/types.d.ts.map +1 -1
- package/dist/session/index.cjs +3 -0
- package/dist/session/index.d.ts +3 -0
- package/dist/session/index.d.ts.map +1 -1
- package/dist/session/index.js +3 -1
- package/dist/session/message-queue.cjs +201 -0
- package/dist/session/message-queue.d.ts +114 -0
- package/dist/session/message-queue.d.ts.map +1 -0
- package/dist/session/message-queue.js +178 -0
- package/dist/session/schemas.js +1 -1
- package/dist/session/session-manager.cjs +57 -7
- package/dist/session/session-manager.d.ts +18 -0
- package/dist/session/session-manager.d.ts.map +1 -1
- package/dist/session/session-manager.js +58 -8
- package/dist/session/title-generator.cjs +4 -8
- package/dist/session/title-generator.d.ts +1 -2
- package/dist/session/title-generator.d.ts.map +1 -1
- package/dist/session/title-generator.js +5 -9
- package/dist/session/types.cjs +16 -0
- package/dist/session/types.d.ts +14 -0
- package/dist/session/types.d.ts.map +1 -0
- package/dist/session/types.js +0 -0
- package/dist/storage/blob/factory.js +1 -1
- package/dist/storage/blob/local-blob-store.js +1 -1
- package/dist/storage/blob/memory-blob-store.js +1 -1
- package/dist/storage/blob/schemas.js +1 -1
- package/dist/storage/cache/factory.cjs +6 -2
- package/dist/storage/cache/factory.d.ts +2 -1
- package/dist/storage/cache/factory.d.ts.map +1 -1
- package/dist/storage/cache/factory.js +7 -3
- package/dist/storage/cache/memory-cache-store.js +1 -1
- package/dist/storage/cache/redis-store.js +1 -1
- package/dist/storage/cache/schemas.js +1 -1
- package/dist/storage/database/factory.cjs +11 -17
- package/dist/storage/database/factory.d.ts +2 -1
- package/dist/storage/database/factory.d.ts.map +1 -1
- package/dist/storage/database/factory.js +12 -18
- package/dist/storage/database/memory-database-store.js +1 -1
- package/dist/storage/database/postgres-store.cjs +12 -0
- package/dist/storage/database/postgres-store.d.ts.map +1 -1
- package/dist/storage/database/postgres-store.js +13 -1
- package/dist/storage/database/schemas.js +1 -1
- package/dist/storage/database/sqlite-store.cjs +8 -0
- package/dist/storage/database/sqlite-store.d.ts.map +1 -1
- package/dist/storage/database/sqlite-store.js +9 -1
- package/dist/storage/error-codes.cjs +1 -0
- package/dist/storage/error-codes.d.ts +1 -0
- package/dist/storage/error-codes.d.ts.map +1 -1
- package/dist/storage/error-codes.js +2 -1
- package/dist/storage/errors.cjs +17 -0
- package/dist/storage/errors.d.ts +9 -0
- package/dist/storage/errors.d.ts.map +1 -1
- package/dist/storage/errors.js +18 -1
- package/dist/storage/index.js +1 -1
- package/dist/storage/schemas.js +1 -1
- package/dist/storage/storage-manager.js +1 -1
- package/dist/systemPrompt/contributors.js +1 -1
- package/dist/systemPrompt/error-codes.js +1 -1
- package/dist/systemPrompt/errors.js +1 -1
- package/dist/systemPrompt/in-built-prompts.js +1 -1
- package/dist/systemPrompt/index.js +1 -1
- package/dist/systemPrompt/manager.js +1 -1
- package/dist/systemPrompt/registry.js +1 -1
- package/dist/systemPrompt/schemas.d.ts +5 -5
- package/dist/systemPrompt/schemas.js +1 -1
- package/dist/telemetry/decorators.js +1 -1
- package/dist/{llm/tokenizer/default.cjs → telemetry/error-codes.cjs} +14 -19
- package/dist/telemetry/error-codes.d.ts +13 -0
- package/dist/telemetry/error-codes.d.ts.map +1 -0
- package/dist/telemetry/error-codes.js +13 -0
- package/dist/telemetry/errors.cjs +105 -0
- package/dist/telemetry/errors.d.ts +28 -0
- package/dist/telemetry/errors.d.ts.map +1 -0
- package/dist/telemetry/errors.js +82 -0
- package/dist/telemetry/exporters.js +1 -1
- package/dist/telemetry/index.js +1 -1
- package/dist/telemetry/schemas.js +1 -1
- package/dist/telemetry/telemetry.cjs +92 -26
- package/dist/telemetry/telemetry.d.ts +1 -1
- package/dist/telemetry/telemetry.d.ts.map +1 -1
- package/dist/telemetry/telemetry.js +75 -19
- package/dist/telemetry/utils.js +1 -1
- package/dist/tools/bash-pattern-utils.cjs +91 -0
- package/dist/tools/bash-pattern-utils.d.ts +58 -0
- package/dist/tools/bash-pattern-utils.d.ts.map +1 -0
- package/dist/tools/bash-pattern-utils.js +64 -0
- package/dist/tools/confirmation/allowed-tools-provider/factory.js +1 -1
- package/dist/tools/confirmation/allowed-tools-provider/in-memory.js +1 -1
- package/dist/tools/confirmation/allowed-tools-provider/storage.js +1 -1
- package/dist/tools/display-types.cjs +60 -0
- package/dist/tools/display-types.d.ts +133 -0
- package/dist/tools/display-types.d.ts.map +1 -0
- package/dist/tools/display-types.js +32 -0
- package/dist/tools/error-codes.cjs +2 -0
- package/dist/tools/error-codes.d.ts +3 -1
- package/dist/tools/error-codes.d.ts.map +1 -1
- package/dist/tools/error-codes.js +3 -1
- package/dist/tools/errors.cjs +30 -0
- package/dist/tools/errors.d.ts +16 -0
- package/dist/tools/errors.d.ts.map +1 -1
- package/dist/tools/errors.js +31 -1
- package/dist/tools/index.cjs +2 -0
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -1
- package/dist/tools/internal-tools/constants.js +1 -1
- package/dist/tools/internal-tools/implementations/ask-user-tool.cjs +1 -1
- package/dist/tools/internal-tools/implementations/ask-user-tool.js +2 -2
- package/dist/tools/internal-tools/implementations/bash-exec-tool.cjs +42 -18
- package/dist/tools/internal-tools/implementations/bash-exec-tool.d.ts +3 -3
- package/dist/tools/internal-tools/implementations/bash-exec-tool.d.ts.map +1 -1
- package/dist/tools/internal-tools/implementations/bash-exec-tool.js +43 -19
- package/dist/tools/internal-tools/implementations/bash-output-tool.js +1 -1
- package/dist/tools/internal-tools/implementations/delegate-to-url-tool.js +1 -1
- package/dist/tools/internal-tools/implementations/edit-file-tool.cjs +66 -1
- package/dist/tools/internal-tools/implementations/edit-file-tool.d.ts.map +1 -1
- package/dist/tools/internal-tools/implementations/edit-file-tool.js +67 -2
- package/dist/tools/internal-tools/implementations/glob-files-tool.cjs +14 -1
- package/dist/tools/internal-tools/implementations/glob-files-tool.d.ts.map +1 -1
- package/dist/tools/internal-tools/implementations/glob-files-tool.js +15 -2
- package/dist/tools/internal-tools/implementations/grep-content-tool.cjs +16 -1
- package/dist/tools/internal-tools/implementations/grep-content-tool.d.ts.map +1 -1
- package/dist/tools/internal-tools/implementations/grep-content-tool.js +17 -2
- package/dist/tools/internal-tools/implementations/kill-process-tool.js +1 -1
- package/dist/tools/internal-tools/implementations/read-file-tool.cjs +9 -1
- package/dist/tools/internal-tools/implementations/read-file-tool.d.ts.map +1 -1
- package/dist/tools/internal-tools/implementations/read-file-tool.js +10 -2
- package/dist/tools/internal-tools/implementations/search-history-tool.js +1 -1
- package/dist/tools/internal-tools/implementations/write-file-tool.cjs +69 -1
- package/dist/tools/internal-tools/implementations/write-file-tool.d.ts.map +1 -1
- package/dist/tools/internal-tools/implementations/write-file-tool.js +72 -2
- package/dist/tools/internal-tools/provider.cjs +27 -10
- package/dist/tools/internal-tools/provider.d.ts +8 -5
- package/dist/tools/internal-tools/provider.d.ts.map +1 -1
- package/dist/tools/internal-tools/provider.js +28 -11
- package/dist/tools/internal-tools/registry.cjs +4 -3
- package/dist/tools/internal-tools/registry.d.ts +28 -7
- package/dist/tools/internal-tools/registry.d.ts.map +1 -1
- package/dist/tools/internal-tools/registry.js +5 -4
- package/dist/tools/schemas.cjs +17 -7
- package/dist/tools/schemas.d.ts +31 -4
- package/dist/tools/schemas.d.ts.map +1 -1
- package/dist/tools/schemas.js +15 -7
- package/dist/tools/tool-manager.cjs +140 -18
- package/dist/tools/tool-manager.d.ts +23 -1
- package/dist/tools/tool-manager.d.ts.map +1 -1
- package/dist/tools/tool-manager.js +145 -19
- package/dist/tools/types.d.ts +20 -11
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/utils/api-key-resolver.js +1 -1
- package/dist/utils/async-context.js +1 -1
- package/dist/utils/debug.js +1 -1
- package/dist/{llm/tokenizer/types.cjs → utils/defer.cjs} +19 -10
- package/dist/utils/defer.d.ts +63 -0
- package/dist/utils/defer.d.ts.map +1 -0
- package/dist/utils/defer.js +19 -0
- package/dist/utils/env-file.js +1 -1
- package/dist/utils/error-conversion.js +1 -1
- package/dist/utils/execution-context.js +1 -1
- package/dist/utils/fs-walk.js +1 -1
- package/dist/utils/index.cjs +3 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/path.js +1 -1
- package/dist/utils/redactor.js +1 -1
- package/dist/utils/result.js +1 -1
- package/dist/utils/safe-stringify.js +1 -1
- package/dist/utils/schema-metadata.js +1 -1
- package/dist/utils/schema.d.ts +6 -0
- package/dist/utils/schema.d.ts.map +1 -1
- package/dist/utils/schema.js +1 -1
- package/dist/utils/service-initializer.cjs +6 -2
- package/dist/utils/service-initializer.d.ts.map +1 -1
- package/dist/utils/service-initializer.js +7 -3
- package/dist/utils/user-info.js +1 -1
- package/dist/utils/zod-schema-converter.js +1 -1
- package/package.json +54 -17
- package/dist/context/compression/middle-removal.cjs +0 -95
- package/dist/context/compression/middle-removal.d.ts +0 -47
- package/dist/context/compression/middle-removal.d.ts.map +0 -1
- package/dist/context/compression/middle-removal.js +0 -72
- package/dist/context/compression/oldest-removal.cjs +0 -83
- package/dist/context/compression/oldest-removal.d.ts +0 -42
- package/dist/context/compression/oldest-removal.d.ts.map +0 -1
- package/dist/context/compression/oldest-removal.js +0 -60
- package/dist/llm/formatters/anthropic.cjs +0 -257
- package/dist/llm/formatters/anthropic.d.ts +0 -46
- package/dist/llm/formatters/anthropic.d.ts.map +0 -1
- package/dist/llm/formatters/anthropic.js +0 -239
- package/dist/llm/formatters/factory.cjs +0 -50
- package/dist/llm/formatters/factory.d.ts +0 -10
- package/dist/llm/formatters/factory.d.ts.map +0 -1
- package/dist/llm/formatters/factory.js +0 -27
- package/dist/llm/formatters/openai.cjs +0 -196
- package/dist/llm/formatters/openai.d.ts +0 -39
- package/dist/llm/formatters/openai.d.ts.map +0 -1
- package/dist/llm/formatters/openai.js +0 -177
- package/dist/llm/formatters/types.d.ts +0 -41
- package/dist/llm/formatters/types.d.ts.map +0 -1
- package/dist/llm/services/anthropic.cjs +0 -511
- package/dist/llm/services/anthropic.d.ts +0 -48
- package/dist/llm/services/anthropic.d.ts.map +0 -1
- package/dist/llm/services/anthropic.js +0 -447
- package/dist/llm/services/openai.cjs +0 -611
- package/dist/llm/services/openai.d.ts +0 -48
- package/dist/llm/services/openai.d.ts.map +0 -1
- package/dist/llm/services/openai.js +0 -547
- package/dist/llm/tokenizer/anthropic.cjs +0 -43
- package/dist/llm/tokenizer/anthropic.d.ts +0 -19
- package/dist/llm/tokenizer/anthropic.d.ts.map +0 -1
- package/dist/llm/tokenizer/anthropic.js +0 -20
- package/dist/llm/tokenizer/default.d.ts +0 -14
- package/dist/llm/tokenizer/default.d.ts.map +0 -1
- package/dist/llm/tokenizer/default.js +0 -18
- package/dist/llm/tokenizer/factory.d.ts +0 -12
- package/dist/llm/tokenizer/factory.d.ts.map +0 -1
- package/dist/llm/tokenizer/factory.js +0 -21
- package/dist/llm/tokenizer/google.cjs +0 -52
- package/dist/llm/tokenizer/google.d.ts +0 -29
- package/dist/llm/tokenizer/google.d.ts.map +0 -1
- package/dist/llm/tokenizer/google.js +0 -29
- package/dist/llm/tokenizer/openai.cjs +0 -115
- package/dist/llm/tokenizer/openai.d.ts +0 -33
- package/dist/llm/tokenizer/openai.d.ts.map +0 -1
- package/dist/llm/tokenizer/openai.js +0 -91
- package/dist/llm/tokenizer/types.d.ts +0 -18
- package/dist/llm/tokenizer/types.d.ts.map +0 -1
- package/dist/llm/tokenizer/types.js +0 -10
- /package/dist/llm/{formatters → executor}/types.cjs +0 -0
- /package/dist/llm/{formatters → executor}/types.js +0 -0
|
@@ -66,6 +66,8 @@ __export(DextoAgent_exports, {
|
|
|
66
66
|
DextoAgent: () => DextoAgent
|
|
67
67
|
});
|
|
68
68
|
module.exports = __toCommonJS(DextoAgent_exports);
|
|
69
|
+
var import_crypto = require("crypto");
|
|
70
|
+
var import_events = require("events");
|
|
69
71
|
var import_resources = require("../resources/index.js");
|
|
70
72
|
var import_utils = require("../context/utils.js");
|
|
71
73
|
var import_prompts = require("../prompts/index.js");
|
|
@@ -81,13 +83,14 @@ var import_errors = require("../llm/errors.js");
|
|
|
81
83
|
var import_errors2 = require("./errors.js");
|
|
82
84
|
var import_errors3 = require("../mcp/errors.js");
|
|
83
85
|
var import_DextoRuntimeError = require("../errors/DextoRuntimeError.js");
|
|
86
|
+
var import_DextoValidationError = require("../errors/DextoValidationError.js");
|
|
84
87
|
var import_result_bridge = require("../errors/result-bridge.cjs");
|
|
85
88
|
var import_result = require("../utils/result.cjs");
|
|
86
89
|
var import_resolver2 = require("../mcp/resolver.js");
|
|
87
90
|
var import_registry = require("../llm/registry.js");
|
|
88
91
|
var import_service_initializer2 = require("../utils/service-initializer.js");
|
|
89
92
|
var import_schemas2 = require("./schemas.js");
|
|
90
|
-
var
|
|
93
|
+
var import_events2 = require("../events/index.js");
|
|
91
94
|
var import_safe_stringify = require("../utils/safe-stringify.cjs");
|
|
92
95
|
var import_title_generator = require("../session/title-generator.js");
|
|
93
96
|
var _DextoAgent_decorators, _init;
|
|
@@ -127,7 +130,7 @@ class DextoAgent {
|
|
|
127
130
|
agentId: this.config.agentId,
|
|
128
131
|
component: import_types.DextoLogComponent.AGENT
|
|
129
132
|
});
|
|
130
|
-
this.agentEventBus = new
|
|
133
|
+
this.agentEventBus = new import_events2.AgentEventBus();
|
|
131
134
|
this.logger.info("DextoAgent created.");
|
|
132
135
|
}
|
|
133
136
|
/**
|
|
@@ -159,6 +162,8 @@ class DextoAgent {
|
|
|
159
162
|
// Approval handler for manual tool confirmation and elicitation
|
|
160
163
|
// Set via setApprovalHandler() before start() if needed
|
|
161
164
|
approvalHandler;
|
|
165
|
+
// Active stream controllers per session - allows cancel() to abort iterators
|
|
166
|
+
activeStreamControllers = /* @__PURE__ */ new Map();
|
|
162
167
|
// Logger instance for this agent (dependency injection)
|
|
163
168
|
logger;
|
|
164
169
|
/**
|
|
@@ -234,10 +239,6 @@ Either:
|
|
|
234
239
|
for (const subscriber of this.eventSubscribers) {
|
|
235
240
|
subscriber.subscribe(this.agentEventBus);
|
|
236
241
|
}
|
|
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
|
-
}
|
|
241
242
|
} catch (error) {
|
|
242
243
|
this.logger.error("Failed to start DextoAgent", {
|
|
243
244
|
error: error instanceof Error ? error.message : String(error)
|
|
@@ -368,173 +369,88 @@ Either:
|
|
|
368
369
|
}
|
|
369
370
|
// ============= CORE AGENT FUNCTIONALITY =============
|
|
370
371
|
/**
|
|
371
|
-
*
|
|
372
|
-
*
|
|
372
|
+
* Process user input and return the response.
|
|
373
|
+
*
|
|
374
|
+
* @deprecated Use generate() or stream() instead for multi-image support.
|
|
375
|
+
* This method is kept for backward compatibility and only supports single image/file.
|
|
373
376
|
*
|
|
374
|
-
* @param textInput - The user's text message
|
|
375
|
-
* @param imageDataInput - Optional image data
|
|
376
|
-
* @param fileDataInput - Optional file data
|
|
377
|
+
* @param textInput - The user's text message
|
|
378
|
+
* @param imageDataInput - Optional single image data
|
|
379
|
+
* @param fileDataInput - Optional single file data
|
|
377
380
|
* @param sessionId - Session ID for the conversation (required)
|
|
378
|
-
* @param
|
|
379
|
-
* @returns Promise that resolves to the AI's response text
|
|
380
|
-
* @throws Error if processing fails
|
|
381
|
+
* @param _stream - Ignored (streaming is handled internally)
|
|
382
|
+
* @returns Promise that resolves to the AI's response text
|
|
381
383
|
*/
|
|
382
|
-
async run(textInput, imageDataInput, fileDataInput, sessionId,
|
|
383
|
-
|
|
384
|
-
if (
|
|
385
|
-
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
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 };
|
|
384
|
+
async run(textInput, imageDataInput, fileDataInput, sessionId, _stream = false) {
|
|
385
|
+
const parts = [];
|
|
386
|
+
if (textInput) {
|
|
387
|
+
parts.push({ type: "text", text: textInput });
|
|
388
|
+
}
|
|
389
|
+
if (imageDataInput) {
|
|
390
|
+
parts.push({
|
|
391
|
+
type: "image",
|
|
392
|
+
image: imageDataInput.image,
|
|
393
|
+
mimeType: imageDataInput.mimeType
|
|
398
394
|
});
|
|
399
395
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
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)
|
|
442
|
-
);
|
|
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}`
|
|
447
|
-
);
|
|
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
|
-
);
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
if (!finalText.trim() && !finalImageData && !fileDataInput) {
|
|
476
|
-
this.logger.warn(
|
|
477
|
-
"Resource expansion resulted in empty content. Using original message."
|
|
478
|
-
);
|
|
479
|
-
finalText = textInput;
|
|
480
|
-
}
|
|
481
|
-
const response = await session.run(
|
|
482
|
-
finalText,
|
|
483
|
-
finalImageData,
|
|
484
|
-
fileDataInput,
|
|
485
|
-
stream
|
|
486
|
-
);
|
|
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
|
-
});
|
|
396
|
+
if (fileDataInput) {
|
|
397
|
+
parts.push({
|
|
398
|
+
type: "file",
|
|
399
|
+
data: fileDataInput.data,
|
|
400
|
+
mimeType: fileDataInput.mimeType,
|
|
401
|
+
...fileDataInput.filename && { filename: fileDataInput.filename }
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
const response = await this.generate(parts.length > 0 ? parts : textInput, sessionId);
|
|
405
|
+
return response.content;
|
|
500
406
|
}
|
|
501
407
|
/**
|
|
502
408
|
* Generate a complete response (waits for full completion).
|
|
503
409
|
* This is the recommended method for non-streaming use cases.
|
|
504
410
|
*
|
|
505
|
-
* @param message
|
|
506
|
-
* @param
|
|
411
|
+
* @param content String message or array of content parts (text, images, files)
|
|
412
|
+
* @param sessionId Session ID for the conversation
|
|
413
|
+
* @param options Optional configuration (signal for cancellation)
|
|
507
414
|
* @returns Promise that resolves to the complete response
|
|
508
415
|
*
|
|
509
416
|
* @example
|
|
510
417
|
* ```typescript
|
|
511
|
-
*
|
|
418
|
+
* // Simple text message
|
|
419
|
+
* const response = await agent.generate('What is 2+2?', 'session-1');
|
|
512
420
|
* console.log(response.content); // "4"
|
|
513
|
-
*
|
|
421
|
+
*
|
|
422
|
+
* // Multimodal with image
|
|
423
|
+
* const response = await agent.generate(
|
|
424
|
+
* [
|
|
425
|
+
* { type: 'text', text: 'Describe this image' },
|
|
426
|
+
* { type: 'image', image: base64Data, mimeType: 'image/png' }
|
|
427
|
+
* ],
|
|
428
|
+
* 'session-1'
|
|
429
|
+
* );
|
|
514
430
|
* ```
|
|
515
431
|
*/
|
|
516
|
-
async generate(
|
|
432
|
+
async generate(content, sessionId, options) {
|
|
517
433
|
const events = [];
|
|
518
|
-
for await (const event of await this.stream(
|
|
434
|
+
for await (const event of await this.stream(content, sessionId, options)) {
|
|
519
435
|
events.push(event);
|
|
520
436
|
}
|
|
521
|
-
const
|
|
522
|
-
(e) => e.
|
|
437
|
+
const fatalErrorEvent = events.find(
|
|
438
|
+
(e) => e.name === "llm:error" && e.recoverable !== true
|
|
523
439
|
);
|
|
524
|
-
if (
|
|
525
|
-
if (
|
|
526
|
-
throw
|
|
440
|
+
if (fatalErrorEvent) {
|
|
441
|
+
if (fatalErrorEvent.error instanceof import_DextoRuntimeError.DextoRuntimeError || fatalErrorEvent.error instanceof import_DextoValidationError.DextoValidationError) {
|
|
442
|
+
throw fatalErrorEvent.error;
|
|
527
443
|
}
|
|
528
|
-
const llmConfig = this.stateManager.getLLMConfig(
|
|
444
|
+
const llmConfig = this.stateManager.getLLMConfig(sessionId);
|
|
529
445
|
throw import_errors.LLMError.generationFailed(
|
|
530
|
-
|
|
446
|
+
fatalErrorEvent.error.message,
|
|
531
447
|
llmConfig.provider,
|
|
532
448
|
llmConfig.model
|
|
533
449
|
);
|
|
534
450
|
}
|
|
535
|
-
const responseEvent = events.find((e) => e.
|
|
536
|
-
if (!responseEvent || responseEvent.
|
|
537
|
-
const llmConfig = this.stateManager.getLLMConfig(
|
|
451
|
+
const responseEvent = events.find((e) => e.name === "llm:response");
|
|
452
|
+
if (!responseEvent || responseEvent.name !== "llm:response") {
|
|
453
|
+
const llmConfig = this.stateManager.getLLMConfig(sessionId);
|
|
538
454
|
throw import_errors.LLMError.generationFailed(
|
|
539
455
|
"Stream did not complete successfully - no response received",
|
|
540
456
|
llmConfig.provider,
|
|
@@ -542,10 +458,10 @@ Either:
|
|
|
542
458
|
);
|
|
543
459
|
}
|
|
544
460
|
const toolCallEvents = events.filter(
|
|
545
|
-
(e) => e.
|
|
461
|
+
(e) => e.name === "llm:tool-call"
|
|
546
462
|
);
|
|
547
463
|
const toolResultEvents = events.filter(
|
|
548
|
-
(e) => e.
|
|
464
|
+
(e) => e.name === "llm:tool-result"
|
|
549
465
|
);
|
|
550
466
|
const toolCalls = toolCallEvents.map((tc) => {
|
|
551
467
|
const toolResult = toolResultEvents.find((tr) => tr.callId === tc.callId);
|
|
@@ -559,7 +475,6 @@ Either:
|
|
|
559
475
|
} : void 0
|
|
560
476
|
};
|
|
561
477
|
});
|
|
562
|
-
const messageId = `msg_${Date.now()}_${Math.random().toString(36).substring(7)}`;
|
|
563
478
|
const defaultUsage = {
|
|
564
479
|
inputTokens: 0,
|
|
565
480
|
outputTokens: 0,
|
|
@@ -571,8 +486,7 @@ Either:
|
|
|
571
486
|
reasoning: responseEvent.reasoning,
|
|
572
487
|
usage,
|
|
573
488
|
toolCalls,
|
|
574
|
-
sessionId
|
|
575
|
-
messageId
|
|
489
|
+
sessionId
|
|
576
490
|
};
|
|
577
491
|
}
|
|
578
492
|
/**
|
|
@@ -586,45 +500,51 @@ Either:
|
|
|
586
500
|
* Events are forwarded directly from the AgentEventBus with no mapping layer,
|
|
587
501
|
* providing a unified event system across all API layers.
|
|
588
502
|
*
|
|
589
|
-
* @param message
|
|
590
|
-
* @param
|
|
591
|
-
* @
|
|
503
|
+
* @param content String message or array of content parts (text, images, files)
|
|
504
|
+
* @param sessionId Session ID for the conversation
|
|
505
|
+
* @param options Optional configuration (signal for cancellation)
|
|
506
|
+
* @returns AsyncIterator that yields StreamingEvent objects (core events with name property)
|
|
592
507
|
*
|
|
593
508
|
* @example
|
|
594
509
|
* ```typescript
|
|
595
|
-
*
|
|
596
|
-
*
|
|
597
|
-
*
|
|
598
|
-
* }
|
|
599
|
-
* if (event.type === 'llm:tool-call') {
|
|
600
|
-
* console.log(`\n[Using ${event.toolName}]\n`);
|
|
601
|
-
* }
|
|
510
|
+
* // Simple text
|
|
511
|
+
* for await (const event of await agent.stream('Write a poem', 'session-1')) {
|
|
512
|
+
* if (event.name === 'llm:chunk') process.stdout.write(event.content);
|
|
602
513
|
* }
|
|
514
|
+
*
|
|
515
|
+
* // Multimodal
|
|
516
|
+
* for await (const event of await agent.stream(
|
|
517
|
+
* [{ type: 'text', text: 'Describe this' }, { type: 'image', image: data, mimeType: 'image/png' }],
|
|
518
|
+
* 'session-1'
|
|
519
|
+
* )) { ... }
|
|
603
520
|
* ```
|
|
604
521
|
*/
|
|
605
|
-
async stream(
|
|
522
|
+
async stream(content, sessionId, options) {
|
|
606
523
|
this.ensureStarted();
|
|
607
|
-
if (!
|
|
608
|
-
throw
|
|
524
|
+
if (!sessionId) {
|
|
525
|
+
throw import_errors2.AgentError.apiValidationError("sessionId is required");
|
|
609
526
|
}
|
|
610
|
-
const
|
|
611
|
-
|
|
612
|
-
const fileData = options.fileData;
|
|
613
|
-
const signal = options.signal;
|
|
527
|
+
const signal = options?.signal;
|
|
528
|
+
let contentParts = typeof content === "string" ? [{ type: "text", text: content }] : [...content];
|
|
614
529
|
const eventQueue = [];
|
|
615
530
|
let completed = false;
|
|
616
|
-
let _streamError = null;
|
|
617
531
|
const controller = new AbortController();
|
|
618
532
|
const cleanupSignal = controller.signal;
|
|
533
|
+
this.activeStreamControllers.set(sessionId, controller);
|
|
534
|
+
(0, import_events.setMaxListeners)(30, cleanupSignal);
|
|
619
535
|
const listeners = [];
|
|
620
536
|
const cleanupListeners = () => {
|
|
621
537
|
if (listeners.length === 0) {
|
|
622
538
|
return;
|
|
623
539
|
}
|
|
624
540
|
for (const { event, listener } of listeners) {
|
|
625
|
-
this.agentEventBus.off(
|
|
541
|
+
this.agentEventBus.off(
|
|
542
|
+
event,
|
|
543
|
+
listener
|
|
544
|
+
);
|
|
626
545
|
}
|
|
627
546
|
listeners.length = 0;
|
|
547
|
+
this.activeStreamControllers.delete(sessionId);
|
|
628
548
|
};
|
|
629
549
|
if (signal) {
|
|
630
550
|
const abortHandler = () => {
|
|
@@ -633,49 +553,262 @@ Either:
|
|
|
633
553
|
};
|
|
634
554
|
signal.addEventListener("abort", abortHandler, { once: true });
|
|
635
555
|
}
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
556
|
+
const thinkingListener = (data) => {
|
|
557
|
+
if (data.sessionId !== sessionId) return;
|
|
558
|
+
eventQueue.push({ name: "llm:thinking", ...data });
|
|
559
|
+
};
|
|
560
|
+
this.agentEventBus.on("llm:thinking", thinkingListener, { signal: cleanupSignal });
|
|
561
|
+
listeners.push({ event: "llm:thinking", listener: thinkingListener });
|
|
562
|
+
const chunkListener = (data) => {
|
|
563
|
+
if (data.sessionId !== sessionId) return;
|
|
564
|
+
eventQueue.push({ name: "llm:chunk", ...data });
|
|
565
|
+
};
|
|
566
|
+
this.agentEventBus.on("llm:chunk", chunkListener, { signal: cleanupSignal });
|
|
567
|
+
listeners.push({ event: "llm:chunk", listener: chunkListener });
|
|
568
|
+
const responseListener = (data) => {
|
|
569
|
+
if (data.sessionId !== sessionId) return;
|
|
570
|
+
eventQueue.push({ name: "llm:response", ...data });
|
|
571
|
+
};
|
|
572
|
+
this.agentEventBus.on("llm:response", responseListener, { signal: cleanupSignal });
|
|
573
|
+
listeners.push({ event: "llm:response", listener: responseListener });
|
|
574
|
+
const toolCallListener = (data) => {
|
|
575
|
+
if (data.sessionId !== sessionId) return;
|
|
576
|
+
eventQueue.push({ name: "llm:tool-call", ...data });
|
|
577
|
+
};
|
|
578
|
+
this.agentEventBus.on("llm:tool-call", toolCallListener, { signal: cleanupSignal });
|
|
579
|
+
listeners.push({ event: "llm:tool-call", listener: toolCallListener });
|
|
580
|
+
const toolResultListener = (data) => {
|
|
581
|
+
if (data.sessionId !== sessionId) return;
|
|
582
|
+
eventQueue.push({ name: "llm:tool-result", ...data });
|
|
583
|
+
};
|
|
584
|
+
this.agentEventBus.on("llm:tool-result", toolResultListener, { signal: cleanupSignal });
|
|
585
|
+
listeners.push({ event: "llm:tool-result", listener: toolResultListener });
|
|
586
|
+
const errorListener = (data) => {
|
|
587
|
+
if (data.sessionId !== sessionId) return;
|
|
588
|
+
eventQueue.push({ name: "llm:error", ...data });
|
|
589
|
+
if (!data.recoverable) {
|
|
590
|
+
completed = true;
|
|
591
|
+
}
|
|
592
|
+
};
|
|
593
|
+
this.agentEventBus.on("llm:error", errorListener, { signal: cleanupSignal });
|
|
594
|
+
listeners.push({ event: "llm:error", listener: errorListener });
|
|
595
|
+
const unsupportedInputListener = (data) => {
|
|
596
|
+
if (data.sessionId !== sessionId) return;
|
|
597
|
+
eventQueue.push({ name: "llm:unsupported-input", ...data });
|
|
598
|
+
};
|
|
599
|
+
this.agentEventBus.on("llm:unsupported-input", unsupportedInputListener, {
|
|
600
|
+
signal: cleanupSignal
|
|
601
|
+
});
|
|
602
|
+
listeners.push({ event: "llm:unsupported-input", listener: unsupportedInputListener });
|
|
603
|
+
const titleUpdatedListener = (data) => {
|
|
604
|
+
if (data.sessionId !== sessionId) return;
|
|
605
|
+
eventQueue.push({ name: "session:title-updated", ...data });
|
|
606
|
+
};
|
|
607
|
+
this.agentEventBus.on("session:title-updated", titleUpdatedListener, {
|
|
608
|
+
signal: cleanupSignal
|
|
609
|
+
});
|
|
610
|
+
listeners.push({ event: "session:title-updated", listener: titleUpdatedListener });
|
|
611
|
+
const approvalRequestListener = (data) => {
|
|
612
|
+
if (data.sessionId !== sessionId) return;
|
|
613
|
+
eventQueue.push({ name: "approval:request", ...data });
|
|
614
|
+
};
|
|
615
|
+
this.agentEventBus.on("approval:request", approvalRequestListener, {
|
|
616
|
+
signal: cleanupSignal
|
|
617
|
+
});
|
|
618
|
+
listeners.push({ event: "approval:request", listener: approvalRequestListener });
|
|
619
|
+
const approvalResponseListener = (data) => {
|
|
620
|
+
if (data.sessionId !== sessionId) return;
|
|
621
|
+
eventQueue.push({ name: "approval:response", ...data });
|
|
622
|
+
};
|
|
623
|
+
this.agentEventBus.on("approval:response", approvalResponseListener, {
|
|
624
|
+
signal: cleanupSignal
|
|
625
|
+
});
|
|
626
|
+
listeners.push({ event: "approval:response", listener: approvalResponseListener });
|
|
627
|
+
const toolRunningListener = (data) => {
|
|
628
|
+
if (data.sessionId !== sessionId) return;
|
|
629
|
+
eventQueue.push({ name: "tool:running", ...data });
|
|
630
|
+
};
|
|
631
|
+
this.agentEventBus.on("tool:running", toolRunningListener, {
|
|
632
|
+
signal: cleanupSignal
|
|
633
|
+
});
|
|
634
|
+
listeners.push({ event: "tool:running", listener: toolRunningListener });
|
|
635
|
+
const messageQueuedListener = (data) => {
|
|
636
|
+
if (data.sessionId !== sessionId) return;
|
|
637
|
+
eventQueue.push({ name: "message:queued", ...data });
|
|
638
|
+
};
|
|
639
|
+
this.agentEventBus.on("message:queued", messageQueuedListener, {
|
|
640
|
+
signal: cleanupSignal
|
|
641
|
+
});
|
|
642
|
+
listeners.push({ event: "message:queued", listener: messageQueuedListener });
|
|
643
|
+
const messageDequeuedListener = (data) => {
|
|
644
|
+
if (data.sessionId !== sessionId) return;
|
|
645
|
+
eventQueue.push({ name: "message:dequeued", ...data });
|
|
646
|
+
};
|
|
647
|
+
this.agentEventBus.on("message:dequeued", messageDequeuedListener, {
|
|
648
|
+
signal: cleanupSignal
|
|
649
|
+
});
|
|
650
|
+
listeners.push({ event: "message:dequeued", listener: messageDequeuedListener });
|
|
651
|
+
const runCompleteListener = (data) => {
|
|
652
|
+
if (data.sessionId !== sessionId) return;
|
|
653
|
+
eventQueue.push({ name: "run:complete", ...data });
|
|
662
654
|
completed = true;
|
|
663
|
-
|
|
664
|
-
|
|
655
|
+
};
|
|
656
|
+
this.agentEventBus.on("run:complete", runCompleteListener, {
|
|
657
|
+
signal: cleanupSignal
|
|
658
|
+
});
|
|
659
|
+
listeners.push({ event: "run:complete", listener: runCompleteListener });
|
|
660
|
+
(async () => {
|
|
661
|
+
const activeContext = import_api.context.active();
|
|
662
|
+
const activeSpan = import_api.trace.getActiveSpan();
|
|
663
|
+
if (activeSpan) {
|
|
664
|
+
activeSpan.setAttribute("sessionId", sessionId);
|
|
665
|
+
}
|
|
666
|
+
const existingBaggage = import_api.propagation.getBaggage(activeContext);
|
|
667
|
+
const baggageEntries = {};
|
|
668
|
+
if (existingBaggage) {
|
|
669
|
+
existingBaggage.getAllEntries().forEach(([key, entry]) => {
|
|
670
|
+
baggageEntries[key] = { ...entry };
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
baggageEntries.sessionId = { ...baggageEntries.sessionId, value: sessionId };
|
|
674
|
+
const updatedContext = import_api.propagation.setBaggage(
|
|
675
|
+
activeContext,
|
|
676
|
+
import_api.propagation.createBaggage(baggageEntries)
|
|
665
677
|
);
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
678
|
+
await import_api.context.with(updatedContext, async () => {
|
|
679
|
+
try {
|
|
680
|
+
const llmConfig = this.stateManager.getLLMConfig(sessionId);
|
|
681
|
+
const textParts = contentParts.filter(
|
|
682
|
+
(p) => p.type === "text"
|
|
683
|
+
);
|
|
684
|
+
const textContent = textParts.map((p) => p.text).join("\n");
|
|
685
|
+
const imageParts = contentParts.filter(
|
|
686
|
+
(p) => p.type === "image"
|
|
687
|
+
);
|
|
688
|
+
const fileParts = contentParts.filter(
|
|
689
|
+
(p) => p.type === "file"
|
|
690
|
+
);
|
|
691
|
+
this.logger.debug(
|
|
692
|
+
`DextoAgent.stream: sessionId=${sessionId}, textLength=${textContent?.length ?? 0}, imageCount=${imageParts.length}, fileCount=${fileParts.length}`
|
|
693
|
+
);
|
|
694
|
+
const textValidation = (0, import_validation.validateInputForLLM)(
|
|
695
|
+
{ text: textContent },
|
|
696
|
+
{ provider: llmConfig.provider, model: llmConfig.model },
|
|
697
|
+
this.logger
|
|
698
|
+
);
|
|
699
|
+
(0, import_result_bridge.ensureOk)(textValidation, this.logger);
|
|
700
|
+
for (const imagePart of imageParts) {
|
|
701
|
+
const imageValidation = (0, import_validation.validateInputForLLM)(
|
|
702
|
+
{
|
|
703
|
+
imageData: {
|
|
704
|
+
image: typeof imagePart.image === "string" ? imagePart.image : imagePart.image.toString(),
|
|
705
|
+
mimeType: imagePart.mimeType || "image/png"
|
|
706
|
+
}
|
|
707
|
+
},
|
|
708
|
+
{ provider: llmConfig.provider, model: llmConfig.model },
|
|
709
|
+
this.logger
|
|
710
|
+
);
|
|
711
|
+
(0, import_result_bridge.ensureOk)(imageValidation, this.logger);
|
|
712
|
+
}
|
|
713
|
+
for (const filePart of fileParts) {
|
|
714
|
+
const fileValidation = (0, import_validation.validateInputForLLM)(
|
|
715
|
+
{
|
|
716
|
+
fileData: {
|
|
717
|
+
data: typeof filePart.data === "string" ? filePart.data : filePart.data.toString(),
|
|
718
|
+
mimeType: filePart.mimeType
|
|
719
|
+
}
|
|
720
|
+
},
|
|
721
|
+
{ provider: llmConfig.provider, model: llmConfig.model },
|
|
722
|
+
this.logger
|
|
723
|
+
);
|
|
724
|
+
(0, import_result_bridge.ensureOk)(fileValidation, this.logger);
|
|
725
|
+
}
|
|
726
|
+
if (textContent.includes("@")) {
|
|
727
|
+
try {
|
|
728
|
+
const resources = await this.resourceManager.list();
|
|
729
|
+
const expansion = await (0, import_resources.expandMessageReferences)(
|
|
730
|
+
textContent,
|
|
731
|
+
resources,
|
|
732
|
+
(uri) => this.resourceManager.read(uri)
|
|
733
|
+
);
|
|
734
|
+
if (expansion.unresolvedReferences.length > 0) {
|
|
735
|
+
const unresolvedNames = expansion.unresolvedReferences.map((ref) => ref.originalRef).join(", ");
|
|
736
|
+
this.logger.warn(
|
|
737
|
+
`Could not resolve ${expansion.unresolvedReferences.length} resource reference(s): ${unresolvedNames}`
|
|
738
|
+
);
|
|
739
|
+
}
|
|
740
|
+
const MAX_EXPANDED_SIZE = 5 * 1024 * 1024;
|
|
741
|
+
const expandedSize = Buffer.byteLength(
|
|
742
|
+
expansion.expandedMessage,
|
|
743
|
+
"utf-8"
|
|
744
|
+
);
|
|
745
|
+
if (expandedSize > MAX_EXPANDED_SIZE) {
|
|
746
|
+
this.logger.warn(
|
|
747
|
+
`Expanded message size (${(expandedSize / 1024 / 1024).toFixed(2)}MB) exceeds limit (${MAX_EXPANDED_SIZE / 1024 / 1024}MB). Content may be truncated.`
|
|
748
|
+
);
|
|
749
|
+
}
|
|
750
|
+
contentParts = contentParts.filter((p) => p.type !== "text");
|
|
751
|
+
if (expansion.expandedMessage.trim()) {
|
|
752
|
+
contentParts.unshift({
|
|
753
|
+
type: "text",
|
|
754
|
+
text: expansion.expandedMessage
|
|
755
|
+
});
|
|
756
|
+
}
|
|
757
|
+
for (const img of expansion.extractedImages) {
|
|
758
|
+
contentParts.push({
|
|
759
|
+
type: "image",
|
|
760
|
+
image: img.image,
|
|
761
|
+
mimeType: img.mimeType
|
|
762
|
+
});
|
|
763
|
+
this.logger.debug(
|
|
764
|
+
`Added extracted image: ${img.name} (${img.mimeType})`
|
|
765
|
+
);
|
|
766
|
+
}
|
|
767
|
+
} catch (error) {
|
|
768
|
+
this.logger.error(
|
|
769
|
+
`Failed to expand resource references: ${error instanceof Error ? error.message : String(error)}. Continuing with original message.`
|
|
770
|
+
);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
const hasTextContent = contentParts.some(
|
|
774
|
+
(p) => p.type === "text" && p.text.trim()
|
|
775
|
+
);
|
|
776
|
+
const hasMediaContent = contentParts.some(
|
|
777
|
+
(p) => p.type === "image" || p.type === "file"
|
|
778
|
+
);
|
|
779
|
+
if (!hasTextContent && !hasMediaContent) {
|
|
780
|
+
this.logger.warn(
|
|
781
|
+
"Resource expansion resulted in empty content. Using original message."
|
|
782
|
+
);
|
|
783
|
+
contentParts = [{ type: "text", text: textContent }];
|
|
784
|
+
}
|
|
785
|
+
const session = await this.sessionManager.getSession(sessionId) || await this.sessionManager.createSession(sessionId);
|
|
786
|
+
await session.stream(contentParts, signal ? { signal } : void 0);
|
|
787
|
+
this.sessionManager.incrementMessageCount(session.id).catch(
|
|
788
|
+
(error) => this.logger.warn(
|
|
789
|
+
`Failed to increment message count: ${error instanceof Error ? error.message : String(error)}`
|
|
790
|
+
)
|
|
791
|
+
);
|
|
792
|
+
} catch (err) {
|
|
793
|
+
const error = err instanceof import_DextoRuntimeError.DextoRuntimeError || err instanceof import_DextoValidationError.DextoValidationError ? err : err instanceof Error ? err : import_errors2.AgentError.streamFailed(String(err));
|
|
794
|
+
completed = true;
|
|
795
|
+
this.logger.error(`Error in DextoAgent.stream: ${error.message}`);
|
|
796
|
+
const errorEvent = {
|
|
797
|
+
name: "llm:error",
|
|
798
|
+
error,
|
|
799
|
+
recoverable: false,
|
|
800
|
+
context: "run_failed",
|
|
801
|
+
sessionId
|
|
802
|
+
};
|
|
803
|
+
eventQueue.push(errorEvent);
|
|
804
|
+
}
|
|
672
805
|
});
|
|
673
|
-
});
|
|
806
|
+
})();
|
|
674
807
|
const iterator = {
|
|
675
808
|
async next() {
|
|
676
809
|
while (!completed && eventQueue.length === 0) {
|
|
677
810
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
678
|
-
if (signal?.aborted) {
|
|
811
|
+
if (signal?.aborted || cleanupSignal.aborted) {
|
|
679
812
|
cleanupListeners();
|
|
680
813
|
controller.abort();
|
|
681
814
|
return { done: true, value: void 0 };
|
|
@@ -703,6 +836,73 @@ Either:
|
|
|
703
836
|
};
|
|
704
837
|
return iterator;
|
|
705
838
|
}
|
|
839
|
+
/**
|
|
840
|
+
* Check if a session is currently processing a message.
|
|
841
|
+
* @param sessionId Session id
|
|
842
|
+
* @returns true if the session is busy processing; false otherwise
|
|
843
|
+
*/
|
|
844
|
+
async isSessionBusy(sessionId) {
|
|
845
|
+
this.ensureStarted();
|
|
846
|
+
const session = await this.sessionManager.getSession(sessionId, false);
|
|
847
|
+
return session?.isBusy() ?? false;
|
|
848
|
+
}
|
|
849
|
+
/**
|
|
850
|
+
* Queue a message for processing when a session is busy.
|
|
851
|
+
* The message will be injected into the conversation when the current turn completes.
|
|
852
|
+
*
|
|
853
|
+
* @param sessionId Session id
|
|
854
|
+
* @param message The user message to queue
|
|
855
|
+
* @returns Queue position and message ID
|
|
856
|
+
* @throws Error if session doesn't support message queueing
|
|
857
|
+
*/
|
|
858
|
+
async queueMessage(sessionId, message) {
|
|
859
|
+
this.ensureStarted();
|
|
860
|
+
const session = await this.sessionManager.getSession(sessionId, false);
|
|
861
|
+
if (!session) {
|
|
862
|
+
throw import_session.SessionError.notFound(sessionId);
|
|
863
|
+
}
|
|
864
|
+
return session.queueMessage(message);
|
|
865
|
+
}
|
|
866
|
+
/**
|
|
867
|
+
* Get all queued messages for a session.
|
|
868
|
+
* @param sessionId Session id
|
|
869
|
+
* @returns Array of queued messages
|
|
870
|
+
*/
|
|
871
|
+
async getQueuedMessages(sessionId) {
|
|
872
|
+
this.ensureStarted();
|
|
873
|
+
const session = await this.sessionManager.getSession(sessionId, false);
|
|
874
|
+
if (!session) {
|
|
875
|
+
throw import_session.SessionError.notFound(sessionId);
|
|
876
|
+
}
|
|
877
|
+
return session.getQueuedMessages();
|
|
878
|
+
}
|
|
879
|
+
/**
|
|
880
|
+
* Remove a queued message.
|
|
881
|
+
* @param sessionId Session id
|
|
882
|
+
* @param messageId The ID of the queued message to remove
|
|
883
|
+
* @returns true if message was found and removed, false otherwise
|
|
884
|
+
*/
|
|
885
|
+
async removeQueuedMessage(sessionId, messageId) {
|
|
886
|
+
this.ensureStarted();
|
|
887
|
+
const session = await this.sessionManager.getSession(sessionId, false);
|
|
888
|
+
if (!session) {
|
|
889
|
+
throw import_session.SessionError.notFound(sessionId);
|
|
890
|
+
}
|
|
891
|
+
return session.removeQueuedMessage(messageId);
|
|
892
|
+
}
|
|
893
|
+
/**
|
|
894
|
+
* Clear all queued messages for a session.
|
|
895
|
+
* @param sessionId Session id
|
|
896
|
+
* @returns Number of messages that were cleared
|
|
897
|
+
*/
|
|
898
|
+
async clearMessageQueue(sessionId) {
|
|
899
|
+
this.ensureStarted();
|
|
900
|
+
const session = await this.sessionManager.getSession(sessionId, false);
|
|
901
|
+
if (!session) {
|
|
902
|
+
throw import_session.SessionError.notFound(sessionId);
|
|
903
|
+
}
|
|
904
|
+
return session.clearMessageQueue();
|
|
905
|
+
}
|
|
706
906
|
/**
|
|
707
907
|
* Cancels the currently running turn for a session.
|
|
708
908
|
* Safe to call even if no run is in progress.
|
|
@@ -712,13 +912,20 @@ Either:
|
|
|
712
912
|
async cancel(sessionId) {
|
|
713
913
|
this.ensureStarted();
|
|
714
914
|
if (!sessionId || typeof sessionId !== "string") {
|
|
715
|
-
throw
|
|
915
|
+
throw import_errors2.AgentError.apiValidationError(
|
|
916
|
+
"sessionId is required and must be a non-empty string"
|
|
917
|
+
);
|
|
918
|
+
}
|
|
919
|
+
const streamController = this.activeStreamControllers.get(sessionId);
|
|
920
|
+
if (streamController) {
|
|
921
|
+
streamController.abort();
|
|
922
|
+
this.activeStreamControllers.delete(sessionId);
|
|
716
923
|
}
|
|
717
924
|
const existing = await this.sessionManager.getSession(sessionId, false);
|
|
718
925
|
if (existing) {
|
|
719
926
|
return existing.cancel();
|
|
720
927
|
}
|
|
721
|
-
return
|
|
928
|
+
return !!streamController;
|
|
722
929
|
}
|
|
723
930
|
// ============= SESSION MANAGEMENT =============
|
|
724
931
|
/**
|
|
@@ -825,7 +1032,6 @@ Either:
|
|
|
825
1032
|
const llmConfig = this.getEffectiveConfig(sessionId).llm;
|
|
826
1033
|
const result = await (0, import_title_generator.generateSessionTitle)(
|
|
827
1034
|
llmConfig,
|
|
828
|
-
llmConfig.router,
|
|
829
1035
|
this.toolManager,
|
|
830
1036
|
this.systemPromptManager,
|
|
831
1037
|
this.resourceManager,
|
|
@@ -908,7 +1114,9 @@ Either:
|
|
|
908
1114
|
async resetConversation(sessionId) {
|
|
909
1115
|
this.ensureStarted();
|
|
910
1116
|
if (!sessionId || typeof sessionId !== "string") {
|
|
911
|
-
throw
|
|
1117
|
+
throw import_errors2.AgentError.apiValidationError(
|
|
1118
|
+
"sessionId is required and must be a non-empty string"
|
|
1119
|
+
);
|
|
912
1120
|
}
|
|
913
1121
|
try {
|
|
914
1122
|
await this.sessionManager.resetSession(sessionId);
|
|
@@ -923,6 +1131,37 @@ Either:
|
|
|
923
1131
|
throw error;
|
|
924
1132
|
}
|
|
925
1133
|
}
|
|
1134
|
+
/**
|
|
1135
|
+
* Clears the context window for a session without deleting history.
|
|
1136
|
+
*
|
|
1137
|
+
* This adds a "context clear" marker to the conversation history. When the
|
|
1138
|
+
* context is loaded for LLM, messages before this marker are filtered out
|
|
1139
|
+
* (via filterCompacted). The full history remains in the database for
|
|
1140
|
+
* review via /resume or session history.
|
|
1141
|
+
*
|
|
1142
|
+
* Use this for /clear command - it preserves history but gives a fresh
|
|
1143
|
+
* context window to the LLM.
|
|
1144
|
+
*
|
|
1145
|
+
* @param sessionId Session ID (required)
|
|
1146
|
+
*/
|
|
1147
|
+
async clearContext(sessionId) {
|
|
1148
|
+
this.ensureStarted();
|
|
1149
|
+
if (!sessionId || typeof sessionId !== "string") {
|
|
1150
|
+
throw import_errors2.AgentError.apiValidationError(
|
|
1151
|
+
"sessionId is required and must be a non-empty string"
|
|
1152
|
+
);
|
|
1153
|
+
}
|
|
1154
|
+
const session = await this.sessionManager.getSession(sessionId);
|
|
1155
|
+
if (!session) {
|
|
1156
|
+
throw import_session.SessionError.notFound(sessionId);
|
|
1157
|
+
}
|
|
1158
|
+
const contextManager = session.getContextManager();
|
|
1159
|
+
await contextManager.clearContext();
|
|
1160
|
+
this.logger.info(`Context cleared for session: ${sessionId}`);
|
|
1161
|
+
this.agentEventBus.emit("context:cleared", {
|
|
1162
|
+
sessionId
|
|
1163
|
+
});
|
|
1164
|
+
}
|
|
926
1165
|
// ============= LLM MANAGEMENT =============
|
|
927
1166
|
/**
|
|
928
1167
|
* Gets the current LLM configuration with all defaults applied.
|
|
@@ -937,7 +1176,7 @@ Either:
|
|
|
937
1176
|
* This is a comprehensive method that handles ALL validation, configuration building, and switching internally.
|
|
938
1177
|
*
|
|
939
1178
|
* Design:
|
|
940
|
-
* - Input: Partial<LLMConfig> (allows optional fields like maxIterations
|
|
1179
|
+
* - Input: Partial<LLMConfig> (allows optional fields like maxIterations?)
|
|
941
1180
|
* - Output: LLMConfig (user-friendly type with all defaults applied)
|
|
942
1181
|
*
|
|
943
1182
|
* Key features:
|
|
@@ -962,8 +1201,8 @@ Either:
|
|
|
962
1201
|
* // Switch to a different provider with explicit API key
|
|
963
1202
|
* await agent.switchLLM({ provider: 'anthropic', model: 'claude-4-sonnet-20250514', apiKey: 'sk-ant-...' });
|
|
964
1203
|
*
|
|
965
|
-
* // Switch with
|
|
966
|
-
* await agent.switchLLM({ provider: 'anthropic', model: 'claude-4-sonnet-20250514'
|
|
1204
|
+
* // Switch with session options
|
|
1205
|
+
* await agent.switchLLM({ provider: 'anthropic', model: 'claude-4-sonnet-20250514' }, 'user-123');
|
|
967
1206
|
*
|
|
968
1207
|
* // Switch for all sessions
|
|
969
1208
|
* await agent.switchLLM({ model: 'gpt-5' }, '*');
|
|
@@ -1115,19 +1354,23 @@ Either:
|
|
|
1115
1354
|
}
|
|
1116
1355
|
// ============= MCP SERVER MANAGEMENT =============
|
|
1117
1356
|
/**
|
|
1118
|
-
*
|
|
1357
|
+
* Adds a new MCP server to the runtime configuration and connects it if enabled.
|
|
1119
1358
|
* This method handles validation, state management, and establishing the connection.
|
|
1120
1359
|
*
|
|
1121
|
-
* @param name The name of the server to
|
|
1360
|
+
* @param name The name of the server to add.
|
|
1122
1361
|
* @param config The configuration object for the server.
|
|
1123
1362
|
* @throws DextoError if validation fails or connection fails
|
|
1124
1363
|
*/
|
|
1125
|
-
async
|
|
1364
|
+
async addMcpServer(name, config) {
|
|
1126
1365
|
this.ensureStarted();
|
|
1127
1366
|
const existingServerNames = Object.keys(this.stateManager.getRuntimeConfig().mcpServers);
|
|
1128
1367
|
const validation = (0, import_resolver2.resolveAndValidateMcpServerConfig)(name, config, existingServerNames);
|
|
1129
1368
|
const validatedConfig = (0, import_result_bridge.ensureOk)(validation, this.logger);
|
|
1130
|
-
this.stateManager.
|
|
1369
|
+
this.stateManager.setMcpServer(name, validatedConfig);
|
|
1370
|
+
if (validatedConfig.enabled === false) {
|
|
1371
|
+
this.logger.info(`MCP server '${name}' added but not connected (disabled)`);
|
|
1372
|
+
return;
|
|
1373
|
+
}
|
|
1131
1374
|
try {
|
|
1132
1375
|
await this.mcpManager.connectServer(name, validatedConfig);
|
|
1133
1376
|
await this.toolManager.refresh();
|
|
@@ -1139,9 +1382,7 @@ Either:
|
|
|
1139
1382
|
tools: Object.keys(await this.toolManager.getAllTools()),
|
|
1140
1383
|
source: "mcp"
|
|
1141
1384
|
});
|
|
1142
|
-
this.logger.info(
|
|
1143
|
-
`DextoAgent: Successfully added and connected to MCP server '${name}'.`
|
|
1144
|
-
);
|
|
1385
|
+
this.logger.info(`MCP server '${name}' added and connected successfully`);
|
|
1145
1386
|
const warnings = validation.issues.filter((i) => i.severity === "warning");
|
|
1146
1387
|
if (warnings.length > 0) {
|
|
1147
1388
|
this.logger.warn(
|
|
@@ -1150,9 +1391,7 @@ Either:
|
|
|
1150
1391
|
}
|
|
1151
1392
|
} catch (error) {
|
|
1152
1393
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1153
|
-
this.logger.error(
|
|
1154
|
-
`DextoAgent: Failed to connect to MCP server '${name}': ${errorMessage}`
|
|
1155
|
-
);
|
|
1394
|
+
this.logger.error(`Failed to connect MCP server '${name}': ${errorMessage}`);
|
|
1156
1395
|
this.stateManager.removeMcpServer(name);
|
|
1157
1396
|
this.agentEventBus.emit("mcp:server-connected", {
|
|
1158
1397
|
name,
|
|
@@ -1163,14 +1402,81 @@ Either:
|
|
|
1163
1402
|
}
|
|
1164
1403
|
}
|
|
1165
1404
|
/**
|
|
1166
|
-
*
|
|
1405
|
+
* @deprecated Use `addMcpServer` instead. This method will be removed in a future version.
|
|
1406
|
+
*/
|
|
1407
|
+
async connectMcpServer(name, config) {
|
|
1408
|
+
return this.addMcpServer(name, config);
|
|
1409
|
+
}
|
|
1410
|
+
/**
|
|
1411
|
+
* Enables a disabled MCP server and connects it.
|
|
1412
|
+
* Updates the runtime state to enabled=true and establishes the connection.
|
|
1413
|
+
*
|
|
1414
|
+
* @param name The name of the server to enable.
|
|
1415
|
+
* @throws MCPError if server is not found or connection fails
|
|
1416
|
+
*/
|
|
1417
|
+
async enableMcpServer(name) {
|
|
1418
|
+
this.ensureStarted();
|
|
1419
|
+
const currentConfig = this.stateManager.getRuntimeConfig().mcpServers[name];
|
|
1420
|
+
if (!currentConfig) {
|
|
1421
|
+
throw import_errors3.MCPError.serverNotFound(name);
|
|
1422
|
+
}
|
|
1423
|
+
const updatedConfig = { ...currentConfig, enabled: true };
|
|
1424
|
+
this.stateManager.setMcpServer(name, updatedConfig);
|
|
1425
|
+
try {
|
|
1426
|
+
await this.mcpManager.connectServer(name, updatedConfig);
|
|
1427
|
+
await this.toolManager.refresh();
|
|
1428
|
+
this.agentEventBus.emit("mcp:server-connected", { name, success: true });
|
|
1429
|
+
this.logger.info(`MCP server '${name}' enabled and connected`);
|
|
1430
|
+
} catch (error) {
|
|
1431
|
+
this.stateManager.setMcpServer(name, currentConfig);
|
|
1432
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1433
|
+
this.logger.error(`Failed to enable MCP server '${name}': ${errorMessage}`);
|
|
1434
|
+
throw import_errors3.MCPError.connectionFailed(name, errorMessage);
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
/**
|
|
1438
|
+
* Disables an MCP server and disconnects it.
|
|
1439
|
+
* Updates the runtime state to enabled=false and closes the connection.
|
|
1440
|
+
*
|
|
1441
|
+
* @param name The name of the server to disable.
|
|
1442
|
+
* @throws MCPError if server is not found or disconnect fails
|
|
1443
|
+
*/
|
|
1444
|
+
async disableMcpServer(name) {
|
|
1445
|
+
this.ensureStarted();
|
|
1446
|
+
const currentConfig = this.stateManager.getRuntimeConfig().mcpServers[name];
|
|
1447
|
+
if (!currentConfig) {
|
|
1448
|
+
throw import_errors3.MCPError.serverNotFound(name);
|
|
1449
|
+
}
|
|
1450
|
+
const updatedConfig = { ...currentConfig, enabled: false };
|
|
1451
|
+
this.stateManager.setMcpServer(name, updatedConfig);
|
|
1452
|
+
try {
|
|
1453
|
+
await this.mcpManager.removeClient(name);
|
|
1454
|
+
await this.toolManager.refresh();
|
|
1455
|
+
this.logger.info(`MCP server '${name}' disabled and disconnected`);
|
|
1456
|
+
} catch (error) {
|
|
1457
|
+
this.stateManager.setMcpServer(name, currentConfig);
|
|
1458
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1459
|
+
this.logger.error(`Failed to disable MCP server '${name}': ${errorMessage}`);
|
|
1460
|
+
throw import_errors3.MCPError.disconnectionFailed(name, errorMessage);
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
/**
|
|
1464
|
+
* Removes and disconnects an MCP server completely.
|
|
1465
|
+
* Use this for deleting a server - removes from both runtime state and disconnects.
|
|
1167
1466
|
* @param name The name of the server to remove.
|
|
1467
|
+
* @throws MCPError if disconnection fails
|
|
1168
1468
|
*/
|
|
1169
1469
|
async removeMcpServer(name) {
|
|
1170
1470
|
this.ensureStarted();
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1471
|
+
try {
|
|
1472
|
+
await this.mcpManager.removeClient(name);
|
|
1473
|
+
this.stateManager.removeMcpServer(name);
|
|
1474
|
+
await this.toolManager.refresh();
|
|
1475
|
+
} catch (error) {
|
|
1476
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1477
|
+
this.logger.error(`Failed to remove MCP server '${name}': ${errorMessage}`);
|
|
1478
|
+
throw import_errors3.MCPError.disconnectionFailed(name, errorMessage);
|
|
1479
|
+
}
|
|
1174
1480
|
}
|
|
1175
1481
|
/**
|
|
1176
1482
|
* Restarts an MCP server by disconnecting and reconnecting with its original configuration.
|
|
@@ -1203,13 +1509,18 @@ Either:
|
|
|
1203
1509
|
/**
|
|
1204
1510
|
* Executes a tool from any source (MCP servers, custom tools, or internal tools).
|
|
1205
1511
|
* This is the unified interface for tool execution that can handle all tool types.
|
|
1512
|
+
*
|
|
1513
|
+
* Note: This is for direct/programmatic tool execution outside of LLM flow.
|
|
1514
|
+
* A toolCallId is generated automatically for tracking purposes.
|
|
1515
|
+
*
|
|
1206
1516
|
* @param toolName The name of the tool to execute
|
|
1207
1517
|
* @param args The arguments to pass to the tool
|
|
1208
1518
|
* @returns The result of the tool execution
|
|
1209
1519
|
*/
|
|
1210
1520
|
async executeTool(toolName, args) {
|
|
1211
1521
|
this.ensureStarted();
|
|
1212
|
-
|
|
1522
|
+
const toolCallId = `direct-${(0, import_crypto.randomUUID)()}`;
|
|
1523
|
+
return await this.toolManager.executeTool(toolName, args, toolCallId);
|
|
1213
1524
|
}
|
|
1214
1525
|
/**
|
|
1215
1526
|
* Gets all available tools from all connected MCP servers.
|
|
@@ -1247,6 +1558,79 @@ Either:
|
|
|
1247
1558
|
this.ensureStarted();
|
|
1248
1559
|
return this.mcpManager.getFailedConnections();
|
|
1249
1560
|
}
|
|
1561
|
+
/**
|
|
1562
|
+
* Gets the connection status of a single MCP server.
|
|
1563
|
+
* @param name The server name
|
|
1564
|
+
* @returns The connection status, or undefined if server not configured
|
|
1565
|
+
*
|
|
1566
|
+
* TODO: Move to MCPManager once it has access to server configs (enabled state).
|
|
1567
|
+
* Currently here because MCPManager only tracks connections, not config.
|
|
1568
|
+
*/
|
|
1569
|
+
getMcpServerStatus(name) {
|
|
1570
|
+
this.ensureStarted();
|
|
1571
|
+
const config = this.stateManager.getRuntimeConfig();
|
|
1572
|
+
const serverConfig = config.mcpServers[name];
|
|
1573
|
+
if (!serverConfig) return void 0;
|
|
1574
|
+
const enabled = serverConfig.enabled !== false;
|
|
1575
|
+
const connectedClients = this.mcpManager.getClients();
|
|
1576
|
+
const failedConnections = this.mcpManager.getFailedConnections();
|
|
1577
|
+
let status;
|
|
1578
|
+
if (!enabled) {
|
|
1579
|
+
status = "disconnected";
|
|
1580
|
+
} else if (connectedClients.has(name)) {
|
|
1581
|
+
status = "connected";
|
|
1582
|
+
} else {
|
|
1583
|
+
status = "error";
|
|
1584
|
+
}
|
|
1585
|
+
const result = {
|
|
1586
|
+
name,
|
|
1587
|
+
type: serverConfig.type,
|
|
1588
|
+
enabled,
|
|
1589
|
+
status
|
|
1590
|
+
};
|
|
1591
|
+
if (failedConnections[name]) {
|
|
1592
|
+
result.error = failedConnections[name];
|
|
1593
|
+
}
|
|
1594
|
+
return result;
|
|
1595
|
+
}
|
|
1596
|
+
/**
|
|
1597
|
+
* Gets all configured MCP servers with their connection status.
|
|
1598
|
+
* Centralizes the status computation logic used by CLI, server, and webui.
|
|
1599
|
+
* @returns Array of server info with computed status
|
|
1600
|
+
*
|
|
1601
|
+
* TODO: Move to MCPManager once it has access to server configs (enabled state).
|
|
1602
|
+
* Currently here because MCPManager only tracks connections, not config.
|
|
1603
|
+
*/
|
|
1604
|
+
getMcpServersWithStatus() {
|
|
1605
|
+
this.ensureStarted();
|
|
1606
|
+
const config = this.stateManager.getRuntimeConfig();
|
|
1607
|
+
const mcpServers = config.mcpServers || {};
|
|
1608
|
+
const connectedClients = this.mcpManager.getClients();
|
|
1609
|
+
const failedConnections = this.mcpManager.getFailedConnections();
|
|
1610
|
+
const servers = [];
|
|
1611
|
+
for (const [name, serverConfig] of Object.entries(mcpServers)) {
|
|
1612
|
+
const enabled = serverConfig.enabled !== false;
|
|
1613
|
+
let status;
|
|
1614
|
+
if (!enabled) {
|
|
1615
|
+
status = "disconnected";
|
|
1616
|
+
} else if (connectedClients.has(name)) {
|
|
1617
|
+
status = "connected";
|
|
1618
|
+
} else {
|
|
1619
|
+
status = "error";
|
|
1620
|
+
}
|
|
1621
|
+
const server = {
|
|
1622
|
+
name,
|
|
1623
|
+
type: serverConfig.type,
|
|
1624
|
+
enabled,
|
|
1625
|
+
status
|
|
1626
|
+
};
|
|
1627
|
+
if (failedConnections[name]) {
|
|
1628
|
+
server.error = failedConnections[name];
|
|
1629
|
+
}
|
|
1630
|
+
servers.push(server);
|
|
1631
|
+
}
|
|
1632
|
+
return servers;
|
|
1633
|
+
}
|
|
1250
1634
|
// ============= RESOURCE MANAGEMENT =============
|
|
1251
1635
|
/**
|
|
1252
1636
|
* Lists all available resources with their info.
|
|
@@ -1342,6 +1726,21 @@ Either:
|
|
|
1342
1726
|
this.ensureStarted();
|
|
1343
1727
|
return await this.promptManager.has(name);
|
|
1344
1728
|
}
|
|
1729
|
+
/**
|
|
1730
|
+
* Refreshes the prompts cache, reloading from all providers.
|
|
1731
|
+
* Call this after adding/deleting prompts to make them immediately available.
|
|
1732
|
+
*
|
|
1733
|
+
* @param newPrompts Optional - if provided, updates the config prompts before refreshing.
|
|
1734
|
+
* Use this when you've modified the agent config file and need to
|
|
1735
|
+
* update both the runtime config and refresh the cache.
|
|
1736
|
+
*/
|
|
1737
|
+
async refreshPrompts(newPrompts) {
|
|
1738
|
+
this.ensureStarted();
|
|
1739
|
+
if (newPrompts) {
|
|
1740
|
+
this.promptManager.updateConfigPrompts(newPrompts);
|
|
1741
|
+
}
|
|
1742
|
+
await this.promptManager.refresh();
|
|
1743
|
+
}
|
|
1345
1744
|
/**
|
|
1346
1745
|
* Gets a prompt with its messages.
|
|
1347
1746
|
* @param name The name of the prompt
|