@gguf/coder 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +16 -0
- package/.env.example +63 -0
- package/.gitattributes +1 -0
- package/.semgrepignore +19 -0
- package/coder-dummy-file.ts +52 -0
- package/coder.config.example.json +59 -0
- package/coder.config.json +13 -0
- package/color_picker.html +36 -0
- package/package.json +2 -14
- package/scripts/extract-changelog.js +73 -0
- package/scripts/fetch-models.js +143 -0
- package/scripts/test.sh +40 -0
- package/scripts/update-homebrew-formula.sh +125 -0
- package/scripts/update-nix-version.sh +157 -0
- package/source/ai-sdk-client/AISDKClient.spec.ts +117 -0
- package/source/ai-sdk-client/AISDKClient.ts +155 -0
- package/source/ai-sdk-client/chat/chat-handler.spec.ts +121 -0
- package/source/ai-sdk-client/chat/chat-handler.ts +276 -0
- package/source/ai-sdk-client/chat/streaming-handler.spec.ts +173 -0
- package/source/ai-sdk-client/chat/streaming-handler.ts +110 -0
- package/source/ai-sdk-client/chat/tool-processor.spec.ts +92 -0
- package/source/ai-sdk-client/chat/tool-processor.ts +70 -0
- package/source/ai-sdk-client/converters/message-converter.spec.ts +220 -0
- package/source/ai-sdk-client/converters/message-converter.ts +113 -0
- package/source/ai-sdk-client/converters/tool-converter.spec.ts +90 -0
- package/source/ai-sdk-client/converters/tool-converter.ts +46 -0
- package/source/ai-sdk-client/error-handling/error-extractor.spec.ts +55 -0
- package/source/ai-sdk-client/error-handling/error-extractor.ts +15 -0
- package/source/ai-sdk-client/error-handling/error-parser.spec.ts +169 -0
- package/source/ai-sdk-client/error-handling/error-parser.ts +161 -0
- package/source/ai-sdk-client/index.ts +7 -0
- package/source/ai-sdk-client/providers/provider-factory.spec.ts +71 -0
- package/source/ai-sdk-client/providers/provider-factory.ts +41 -0
- package/source/ai-sdk-client/types.ts +9 -0
- package/source/ai-sdk-client-empty-message.spec.ts +141 -0
- package/source/ai-sdk-client-error-handling.spec.ts +186 -0
- package/source/ai-sdk-client-maxretries.spec.ts +114 -0
- package/source/ai-sdk-client-preparestep.spec.ts +279 -0
- package/source/app/App.spec.tsx +32 -0
- package/source/app/App.tsx +480 -0
- package/source/app/components/AppContainer.spec.tsx +96 -0
- package/source/app/components/AppContainer.tsx +56 -0
- package/source/app/components/ChatInterface.spec.tsx +163 -0
- package/source/app/components/ChatInterface.tsx +144 -0
- package/source/app/components/ModalSelectors.spec.tsx +141 -0
- package/source/app/components/ModalSelectors.tsx +135 -0
- package/source/app/helpers.spec.ts +97 -0
- package/source/app/helpers.ts +63 -0
- package/source/app/index.ts +4 -0
- package/source/app/types.ts +39 -0
- package/source/app/utils/appUtils.ts +294 -0
- package/source/app/utils/conversationState.ts +310 -0
- package/source/app.spec.tsx +244 -0
- package/source/cli.spec.ts +73 -0
- package/source/cli.tsx +51 -0
- package/source/client-factory.spec.ts +48 -0
- package/source/client-factory.ts +178 -0
- package/source/command-parser.spec.ts +127 -0
- package/source/command-parser.ts +36 -0
- package/source/commands/checkpoint.spec.tsx +277 -0
- package/source/commands/checkpoint.tsx +366 -0
- package/source/commands/clear.tsx +22 -0
- package/source/commands/custom-commands.tsx +121 -0
- package/source/commands/exit.ts +21 -0
- package/source/commands/export.spec.tsx +131 -0
- package/source/commands/export.tsx +79 -0
- package/source/commands/help.tsx +120 -0
- package/source/commands/index.ts +17 -0
- package/source/commands/init.tsx +339 -0
- package/source/commands/lsp-command.spec.tsx +281 -0
- package/source/commands/lsp.tsx +120 -0
- package/source/commands/mcp-command.spec.tsx +313 -0
- package/source/commands/mcp.tsx +162 -0
- package/source/commands/model-database.spec.tsx +758 -0
- package/source/commands/model-database.tsx +418 -0
- package/source/commands/model.ts +12 -0
- package/source/commands/provider.ts +12 -0
- package/source/commands/setup-config.tsx +16 -0
- package/source/commands/simple-commands.spec.tsx +175 -0
- package/source/commands/status.ts +12 -0
- package/source/commands/theme.ts +12 -0
- package/source/commands/update.spec.tsx +261 -0
- package/source/commands/update.tsx +201 -0
- package/source/commands/usage.spec.tsx +495 -0
- package/source/commands/usage.tsx +100 -0
- package/source/commands.spec.ts +436 -0
- package/source/commands.ts +83 -0
- package/source/components/assistant-message.spec.tsx +796 -0
- package/source/components/assistant-message.tsx +34 -0
- package/source/components/bash-execution-indicator.tsx +21 -0
- package/source/components/cancelling-indicator.tsx +16 -0
- package/source/components/chat-queue.spec.tsx +83 -0
- package/source/components/chat-queue.tsx +36 -0
- package/source/components/checkpoint-display.spec.tsx +219 -0
- package/source/components/checkpoint-display.tsx +126 -0
- package/source/components/checkpoint-selector.spec.tsx +173 -0
- package/source/components/checkpoint-selector.tsx +173 -0
- package/source/components/development-mode-indicator.spec.tsx +268 -0
- package/source/components/development-mode-indicator.tsx +38 -0
- package/source/components/message-box.spec.tsx +427 -0
- package/source/components/message-box.tsx +87 -0
- package/source/components/model-selector.tsx +132 -0
- package/source/components/provider-selector.tsx +75 -0
- package/source/components/random-spinner.tsx +19 -0
- package/source/components/security-disclaimer.tsx +73 -0
- package/source/components/status-connection-display.spec.tsx +133 -0
- package/source/components/status.tsx +267 -0
- package/source/components/theme-selector.tsx +126 -0
- package/source/components/tool-confirmation.tsx +190 -0
- package/source/components/tool-execution-indicator.tsx +33 -0
- package/source/components/tool-message.tsx +85 -0
- package/source/components/ui/titled-box.spec.tsx +207 -0
- package/source/components/ui/titled-box.tsx +57 -0
- package/source/components/usage/progress-bar.spec.tsx +398 -0
- package/source/components/usage/progress-bar.tsx +30 -0
- package/source/components/usage/usage-display.spec.tsx +780 -0
- package/source/components/usage/usage-display.tsx +291 -0
- package/source/components/user-input.spec.tsx +327 -0
- package/source/components/user-input.tsx +533 -0
- package/source/components/user-message.spec.tsx +230 -0
- package/source/components/user-message.tsx +84 -0
- package/source/components/welcome-message.tsx +76 -0
- package/source/config/env-substitution.ts +65 -0
- package/source/config/index.spec.ts +171 -0
- package/source/config/index.ts +154 -0
- package/source/config/paths.spec.ts +241 -0
- package/source/config/paths.ts +55 -0
- package/source/config/preferences.ts +51 -0
- package/source/config/themes.ts +315 -0
- package/source/constants.ts +130 -0
- package/source/context/mode-context.spec.ts +79 -0
- package/source/context/mode-context.ts +24 -0
- package/source/custom-commands/executor.spec.ts +142 -0
- package/source/custom-commands/executor.ts +64 -0
- package/source/custom-commands/loader.spec.ts +314 -0
- package/source/custom-commands/loader.ts +153 -0
- package/source/custom-commands/parser.ts +196 -0
- package/source/hooks/chat-handler/conversation/conversation-loop.spec.ts +39 -0
- package/source/hooks/chat-handler/conversation/conversation-loop.tsx +511 -0
- package/source/hooks/chat-handler/conversation/tool-executor.spec.ts +50 -0
- package/source/hooks/chat-handler/conversation/tool-executor.tsx +109 -0
- package/source/hooks/chat-handler/index.ts +12 -0
- package/source/hooks/chat-handler/state/streaming-state.spec.ts +26 -0
- package/source/hooks/chat-handler/state/streaming-state.ts +19 -0
- package/source/hooks/chat-handler/types.ts +38 -0
- package/source/hooks/chat-handler/useChatHandler.spec.tsx +321 -0
- package/source/hooks/chat-handler/useChatHandler.tsx +194 -0
- package/source/hooks/chat-handler/utils/context-checker.spec.ts +60 -0
- package/source/hooks/chat-handler/utils/context-checker.tsx +73 -0
- package/source/hooks/chat-handler/utils/message-helpers.spec.ts +42 -0
- package/source/hooks/chat-handler/utils/message-helpers.tsx +36 -0
- package/source/hooks/chat-handler/utils/tool-filters.spec.ts +109 -0
- package/source/hooks/chat-handler/utils/tool-filters.ts +64 -0
- package/source/hooks/useAppHandlers.tsx +291 -0
- package/source/hooks/useAppInitialization.tsx +422 -0
- package/source/hooks/useAppState.tsx +311 -0
- package/source/hooks/useDirectoryTrust.tsx +98 -0
- package/source/hooks/useInputState.ts +414 -0
- package/source/hooks/useModeHandlers.tsx +302 -0
- package/source/hooks/useNonInteractiveMode.ts +140 -0
- package/source/hooks/useTerminalWidth.tsx +81 -0
- package/source/hooks/useTheme.ts +18 -0
- package/source/hooks/useToolHandler.tsx +349 -0
- package/source/hooks/useUIState.ts +61 -0
- package/source/init/agents-template-generator.ts +421 -0
- package/source/init/existing-rules-extractor.ts +319 -0
- package/source/init/file-scanner.spec.ts +227 -0
- package/source/init/file-scanner.ts +238 -0
- package/source/init/framework-detector.ts +382 -0
- package/source/init/language-detector.ts +269 -0
- package/source/init/project-analyzer.spec.ts +231 -0
- package/source/init/project-analyzer.ts +458 -0
- package/source/lsp/index.ts +31 -0
- package/source/lsp/lsp-client.spec.ts +508 -0
- package/source/lsp/lsp-client.ts +487 -0
- package/source/lsp/lsp-manager.spec.ts +477 -0
- package/source/lsp/lsp-manager.ts +419 -0
- package/source/lsp/protocol.spec.ts +502 -0
- package/source/lsp/protocol.ts +360 -0
- package/source/lsp/server-discovery.spec.ts +654 -0
- package/source/lsp/server-discovery.ts +515 -0
- package/source/markdown-parser/html-entities.spec.ts +88 -0
- package/source/markdown-parser/html-entities.ts +45 -0
- package/source/markdown-parser/index.spec.ts +281 -0
- package/source/markdown-parser/index.ts +126 -0
- package/source/markdown-parser/table-parser.spec.ts +133 -0
- package/source/markdown-parser/table-parser.ts +114 -0
- package/source/markdown-parser/utils.spec.ts +70 -0
- package/source/markdown-parser/utils.ts +13 -0
- package/source/mcp/mcp-client.spec.ts +81 -0
- package/source/mcp/mcp-client.ts +625 -0
- package/source/mcp/transport-factory.spec.ts +406 -0
- package/source/mcp/transport-factory.ts +312 -0
- package/source/message-handler.ts +67 -0
- package/source/model-database/database-engine.spec.ts +494 -0
- package/source/model-database/database-engine.ts +50 -0
- package/source/model-database/model-database.spec.ts +363 -0
- package/source/model-database/model-database.ts +91 -0
- package/source/model-database/model-engine.spec.ts +447 -0
- package/source/model-database/model-engine.ts +65 -0
- package/source/model-database/model-fetcher.spec.ts +583 -0
- package/source/model-database/model-fetcher.ts +330 -0
- package/source/models/index.ts +1 -0
- package/source/models/models-cache.spec.ts +214 -0
- package/source/models/models-cache.ts +78 -0
- package/source/models/models-dev-client.spec.ts +379 -0
- package/source/models/models-dev-client.ts +329 -0
- package/source/models/models-types.ts +68 -0
- package/source/prompt-history.ts +155 -0
- package/source/security/command-injection.spec.ts +240 -0
- package/source/services/checkpoint-manager.spec.ts +523 -0
- package/source/services/checkpoint-manager.ts +466 -0
- package/source/services/file-snapshot.spec.ts +569 -0
- package/source/services/file-snapshot.ts +220 -0
- package/source/test-utils/render-with-theme.tsx +48 -0
- package/source/tokenization/index.ts +1 -0
- package/source/tokenization/tokenizer-factory.spec.ts +170 -0
- package/source/tokenization/tokenizer-factory.ts +125 -0
- package/source/tokenization/tokenizers/anthropic-tokenizer.spec.ts +200 -0
- package/source/tokenization/tokenizers/anthropic-tokenizer.ts +43 -0
- package/source/tokenization/tokenizers/fallback-tokenizer.spec.ts +236 -0
- package/source/tokenization/tokenizers/fallback-tokenizer.ts +26 -0
- package/source/tokenization/tokenizers/llama-tokenizer.spec.ts +224 -0
- package/source/tokenization/tokenizers/llama-tokenizer.ts +41 -0
- package/source/tokenization/tokenizers/openai-tokenizer.spec.ts +184 -0
- package/source/tokenization/tokenizers/openai-tokenizer.ts +57 -0
- package/source/tool-calling/index.ts +5 -0
- package/source/tool-calling/json-parser.spec.ts +639 -0
- package/source/tool-calling/json-parser.ts +247 -0
- package/source/tool-calling/tool-parser.spec.ts +395 -0
- package/source/tool-calling/tool-parser.ts +120 -0
- package/source/tool-calling/xml-parser.spec.ts +662 -0
- package/source/tool-calling/xml-parser.ts +289 -0
- package/source/tools/execute-bash.spec.tsx +353 -0
- package/source/tools/execute-bash.tsx +219 -0
- package/source/tools/execute-function.spec.ts +130 -0
- package/source/tools/fetch-url.spec.tsx +342 -0
- package/source/tools/fetch-url.tsx +172 -0
- package/source/tools/find-files.spec.tsx +924 -0
- package/source/tools/find-files.tsx +293 -0
- package/source/tools/index.ts +102 -0
- package/source/tools/lsp-get-diagnostics.tsx +192 -0
- package/source/tools/needs-approval.spec.ts +282 -0
- package/source/tools/read-file.spec.tsx +801 -0
- package/source/tools/read-file.tsx +387 -0
- package/source/tools/search-file-contents.spec.tsx +1273 -0
- package/source/tools/search-file-contents.tsx +293 -0
- package/source/tools/string-replace.spec.tsx +730 -0
- package/source/tools/string-replace.tsx +548 -0
- package/source/tools/tool-manager.ts +210 -0
- package/source/tools/tool-registry.spec.ts +415 -0
- package/source/tools/tool-registry.ts +228 -0
- package/source/tools/web-search.tsx +223 -0
- package/source/tools/write-file.spec.tsx +559 -0
- package/source/tools/write-file.tsx +228 -0
- package/source/types/app.ts +37 -0
- package/source/types/checkpoint.ts +48 -0
- package/source/types/commands.ts +46 -0
- package/source/types/components.ts +27 -0
- package/source/types/config.ts +103 -0
- package/source/types/core-connection-status.spec.ts +67 -0
- package/source/types/core.ts +181 -0
- package/source/types/hooks.ts +50 -0
- package/source/types/index.ts +12 -0
- package/source/types/markdown-parser.ts +11 -0
- package/source/types/mcp.ts +52 -0
- package/source/types/system.ts +16 -0
- package/source/types/tokenization.ts +41 -0
- package/source/types/ui.ts +40 -0
- package/source/types/usage.ts +58 -0
- package/source/types/utils.ts +16 -0
- package/source/usage/calculator.spec.ts +385 -0
- package/source/usage/calculator.ts +104 -0
- package/source/usage/storage.spec.ts +703 -0
- package/source/usage/storage.ts +238 -0
- package/source/usage/tracker.spec.ts +456 -0
- package/source/usage/tracker.ts +102 -0
- package/source/utils/atomic-deletion.spec.ts +194 -0
- package/source/utils/atomic-deletion.ts +127 -0
- package/source/utils/bounded-map.spec.ts +300 -0
- package/source/utils/bounded-map.ts +193 -0
- package/source/utils/checkpoint-utils.spec.ts +222 -0
- package/source/utils/checkpoint-utils.ts +92 -0
- package/source/utils/error-formatter.spec.ts +169 -0
- package/source/utils/error-formatter.ts +194 -0
- package/source/utils/file-autocomplete.spec.ts +173 -0
- package/source/utils/file-autocomplete.ts +196 -0
- package/source/utils/file-cache.spec.ts +309 -0
- package/source/utils/file-cache.ts +195 -0
- package/source/utils/file-content-loader.spec.ts +180 -0
- package/source/utils/file-content-loader.ts +179 -0
- package/source/utils/file-mention-handler.spec.ts +261 -0
- package/source/utils/file-mention-handler.ts +84 -0
- package/source/utils/file-mention-parser.spec.ts +182 -0
- package/source/utils/file-mention-parser.ts +170 -0
- package/source/utils/fuzzy-matching.spec.ts +149 -0
- package/source/utils/fuzzy-matching.ts +146 -0
- package/source/utils/indentation-normalizer.spec.ts +216 -0
- package/source/utils/indentation-normalizer.ts +76 -0
- package/source/utils/installation-detector.spec.ts +178 -0
- package/source/utils/installation-detector.ts +153 -0
- package/source/utils/logging/config.spec.ts +311 -0
- package/source/utils/logging/config.ts +210 -0
- package/source/utils/logging/console-facade.spec.ts +184 -0
- package/source/utils/logging/console-facade.ts +384 -0
- package/source/utils/logging/correlation.spec.ts +679 -0
- package/source/utils/logging/correlation.ts +474 -0
- package/source/utils/logging/formatters.spec.ts +464 -0
- package/source/utils/logging/formatters.ts +207 -0
- package/source/utils/logging/health-monitor/alerts/alert-manager.spec.ts +93 -0
- package/source/utils/logging/health-monitor/alerts/alert-manager.ts +79 -0
- package/source/utils/logging/health-monitor/checks/configuration-check.spec.ts +56 -0
- package/source/utils/logging/health-monitor/checks/configuration-check.ts +43 -0
- package/source/utils/logging/health-monitor/checks/logging-check.spec.ts +56 -0
- package/source/utils/logging/health-monitor/checks/logging-check.ts +58 -0
- package/source/utils/logging/health-monitor/checks/memory-check.spec.ts +100 -0
- package/source/utils/logging/health-monitor/checks/memory-check.ts +78 -0
- package/source/utils/logging/health-monitor/checks/performance-check.spec.ts +56 -0
- package/source/utils/logging/health-monitor/checks/performance-check.ts +56 -0
- package/source/utils/logging/health-monitor/checks/request-check.spec.ts +56 -0
- package/source/utils/logging/health-monitor/checks/request-check.ts +76 -0
- package/source/utils/logging/health-monitor/core/health-check-runner.spec.ts +70 -0
- package/source/utils/logging/health-monitor/core/health-check-runner.ts +138 -0
- package/source/utils/logging/health-monitor/core/health-monitor.spec.ts +58 -0
- package/source/utils/logging/health-monitor/core/health-monitor.ts +344 -0
- package/source/utils/logging/health-monitor/core/scoring.spec.ts +65 -0
- package/source/utils/logging/health-monitor/core/scoring.ts +91 -0
- package/source/utils/logging/health-monitor/index.ts +15 -0
- package/source/utils/logging/health-monitor/instances.ts +48 -0
- package/source/utils/logging/health-monitor/middleware/http-middleware.spec.ts +141 -0
- package/source/utils/logging/health-monitor/middleware/http-middleware.ts +75 -0
- package/source/utils/logging/health-monitor/types.ts +126 -0
- package/source/utils/logging/index.spec.ts +284 -0
- package/source/utils/logging/index.ts +236 -0
- package/source/utils/logging/integration.spec.ts +441 -0
- package/source/utils/logging/log-method-factory.spec.ts +573 -0
- package/source/utils/logging/log-method-factory.ts +233 -0
- package/source/utils/logging/log-query/aggregation/aggregator.spec.ts +277 -0
- package/source/utils/logging/log-query/aggregation/aggregator.ts +159 -0
- package/source/utils/logging/log-query/aggregation/facet-generator.spec.ts +159 -0
- package/source/utils/logging/log-query/aggregation/facet-generator.ts +47 -0
- package/source/utils/logging/log-query/index.ts +23 -0
- package/source/utils/logging/log-query/query/filter-predicates.spec.ts +247 -0
- package/source/utils/logging/log-query/query/filter-predicates.ts +154 -0
- package/source/utils/logging/log-query/query/query-builder.spec.ts +182 -0
- package/source/utils/logging/log-query/query/query-builder.ts +151 -0
- package/source/utils/logging/log-query/query/query-engine.spec.ts +214 -0
- package/source/utils/logging/log-query/query/query-engine.ts +45 -0
- package/source/utils/logging/log-query/storage/circular-buffer.spec.ts +143 -0
- package/source/utils/logging/log-query/storage/circular-buffer.ts +75 -0
- package/source/utils/logging/log-query/storage/index-manager.spec.ts +150 -0
- package/source/utils/logging/log-query/storage/index-manager.ts +71 -0
- package/source/utils/logging/log-query/storage/log-storage.spec.ts +257 -0
- package/source/utils/logging/log-query/storage/log-storage.ts +80 -0
- package/source/utils/logging/log-query/types.ts +163 -0
- package/source/utils/logging/log-query/utils/helpers.spec.ts +263 -0
- package/source/utils/logging/log-query/utils/helpers.ts +72 -0
- package/source/utils/logging/log-query/utils/sorting.spec.ts +182 -0
- package/source/utils/logging/log-query/utils/sorting.ts +61 -0
- package/source/utils/logging/logger-provider.spec.ts +262 -0
- package/source/utils/logging/logger-provider.ts +362 -0
- package/source/utils/logging/performance.spec.ts +209 -0
- package/source/utils/logging/performance.ts +757 -0
- package/source/utils/logging/pino-logger.spec.ts +425 -0
- package/source/utils/logging/pino-logger.ts +514 -0
- package/source/utils/logging/redaction.spec.ts +490 -0
- package/source/utils/logging/redaction.ts +267 -0
- package/source/utils/logging/request-tracker.spec.ts +1198 -0
- package/source/utils/logging/request-tracker.ts +803 -0
- package/source/utils/logging/transports.spec.ts +505 -0
- package/source/utils/logging/transports.ts +305 -0
- package/source/utils/logging/types.ts +216 -0
- package/source/utils/message-builder.spec.ts +179 -0
- package/source/utils/message-builder.ts +101 -0
- package/source/utils/message-queue.tsx +486 -0
- package/source/utils/paste-detection.spec.ts +69 -0
- package/source/utils/paste-detection.ts +124 -0
- package/source/utils/paste-roundtrip.spec.ts +442 -0
- package/source/utils/paste-utils.spec.ts +128 -0
- package/source/utils/paste-utils.ts +52 -0
- package/source/utils/programming-language-helper.spec.ts +74 -0
- package/source/utils/programming-language-helper.ts +32 -0
- package/source/utils/prompt-assembly.spec.ts +221 -0
- package/source/utils/prompt-processor.ts +173 -0
- package/source/utils/tool-args-parser.spec.ts +136 -0
- package/source/utils/tool-args-parser.ts +54 -0
- package/source/utils/tool-cancellation.spec.ts +230 -0
- package/source/utils/tool-cancellation.ts +28 -0
- package/source/utils/tool-result-display.spec.tsx +469 -0
- package/source/utils/tool-result-display.tsx +90 -0
- package/source/utils/update-checker.spec.ts +383 -0
- package/source/utils/update-checker.ts +183 -0
- package/source/wizard/config-wizard.spec.tsx +103 -0
- package/source/wizard/config-wizard.tsx +382 -0
- package/source/wizard/steps/location-step.spec.tsx +186 -0
- package/source/wizard/steps/location-step.tsx +147 -0
- package/source/wizard/steps/mcp-step.spec.tsx +607 -0
- package/source/wizard/steps/mcp-step.tsx +632 -0
- package/source/wizard/steps/provider-step.spec.tsx +342 -0
- package/source/wizard/steps/provider-step.tsx +957 -0
- package/source/wizard/steps/summary-step.spec.tsx +749 -0
- package/source/wizard/steps/summary-step.tsx +228 -0
- package/source/wizard/templates/mcp-templates.spec.ts +613 -0
- package/source/wizard/templates/mcp-templates.ts +570 -0
- package/source/wizard/templates/provider-templates.spec.ts +152 -0
- package/source/wizard/templates/provider-templates.ts +485 -0
- package/source/wizard/utils/fetch-cloud-models.spec.ts +428 -0
- package/source/wizard/utils/fetch-cloud-models.ts +223 -0
- package/source/wizard/utils/fetch-local-models.spec.ts +297 -0
- package/source/wizard/utils/fetch-local-models.ts +192 -0
- package/source/wizard/validation-array.spec.ts +264 -0
- package/source/wizard/validation.spec.ts +373 -0
- package/source/wizard/validation.ts +232 -0
- package/source/app/prompts/main-prompt.md +0 -122
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import {execSync} from 'child_process';
|
|
2
|
+
import {existsSync} from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import {MAX_CHECKPOINT_FILES} from '@/constants';
|
|
5
|
+
import {logWarning} from '@/utils/message-queue';
|
|
6
|
+
import * as fs from 'fs/promises';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Service for capturing and restoring file snapshots for checkpoints
|
|
10
|
+
*/
|
|
11
|
+
export class FileSnapshotService {
|
|
12
|
+
private readonly workspaceRoot: string;
|
|
13
|
+
|
|
14
|
+
constructor(workspaceRoot: string = process.cwd()) {
|
|
15
|
+
this.workspaceRoot = workspaceRoot;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Capture the contents of specified files
|
|
20
|
+
*/
|
|
21
|
+
async captureFiles(filePaths: string[]): Promise<Map<string, string>> {
|
|
22
|
+
const snapshots = new Map<string, string>();
|
|
23
|
+
|
|
24
|
+
for (const filePath of filePaths) {
|
|
25
|
+
try {
|
|
26
|
+
const absolutePath = path.resolve(this.workspaceRoot, filePath); // nosemgrep
|
|
27
|
+
const content = await fs.readFile(absolutePath, 'utf-8');
|
|
28
|
+
const relativePath = path.relative(this.workspaceRoot, absolutePath);
|
|
29
|
+
snapshots.set(relativePath, content);
|
|
30
|
+
} catch (error) {
|
|
31
|
+
logWarning('Could not capture file', true, {
|
|
32
|
+
context: {
|
|
33
|
+
filePath,
|
|
34
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return snapshots;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Restore files from snapshots
|
|
45
|
+
*/
|
|
46
|
+
async restoreFiles(snapshots: Map<string, string>): Promise<void> {
|
|
47
|
+
const errors: string[] = [];
|
|
48
|
+
|
|
49
|
+
for (const [relativePath, content] of snapshots) {
|
|
50
|
+
try {
|
|
51
|
+
const absolutePath = path.resolve(this.workspaceRoot, relativePath);
|
|
52
|
+
const directory = path.dirname(absolutePath);
|
|
53
|
+
|
|
54
|
+
await fs.mkdir(directory, {recursive: true});
|
|
55
|
+
await fs.writeFile(absolutePath, content, 'utf-8');
|
|
56
|
+
} catch (error) {
|
|
57
|
+
errors.push(
|
|
58
|
+
`Failed to restore ${relativePath}: ${
|
|
59
|
+
error instanceof Error ? error.message : 'Unknown error'
|
|
60
|
+
}`,
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (errors.length > 0) {
|
|
66
|
+
throw new Error(`Failed to restore some files:\n${errors.join('\n')}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Get list of modified files in the workspace
|
|
72
|
+
* Uses git to detect modified files if available, otherwise returns empty array
|
|
73
|
+
*/
|
|
74
|
+
getModifiedFiles(): string[] {
|
|
75
|
+
try {
|
|
76
|
+
const modifiedOutput = execSync('git diff --name-only HEAD', {
|
|
77
|
+
cwd: this.workspaceRoot,
|
|
78
|
+
encoding: 'utf-8',
|
|
79
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
80
|
+
}).trim();
|
|
81
|
+
|
|
82
|
+
const untrackedOutput = execSync(
|
|
83
|
+
'git ls-files --others --exclude-standard',
|
|
84
|
+
{
|
|
85
|
+
cwd: this.workspaceRoot,
|
|
86
|
+
encoding: 'utf-8',
|
|
87
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
88
|
+
},
|
|
89
|
+
).trim();
|
|
90
|
+
|
|
91
|
+
const modifiedFiles = modifiedOutput
|
|
92
|
+
? modifiedOutput.split('\n').filter(Boolean)
|
|
93
|
+
: [];
|
|
94
|
+
const untrackedFiles = untrackedOutput
|
|
95
|
+
? untrackedOutput.split('\n').filter(Boolean)
|
|
96
|
+
: [];
|
|
97
|
+
|
|
98
|
+
const allFiles = [...new Set([...modifiedFiles, ...untrackedFiles])];
|
|
99
|
+
|
|
100
|
+
const filtered = allFiles.filter(file => {
|
|
101
|
+
const ignorePatterns = [
|
|
102
|
+
'node_modules/',
|
|
103
|
+
'dist/',
|
|
104
|
+
'build/',
|
|
105
|
+
'.git/',
|
|
106
|
+
'.coder/',
|
|
107
|
+
'coverage/',
|
|
108
|
+
'*.log',
|
|
109
|
+
];
|
|
110
|
+
|
|
111
|
+
return !ignorePatterns.some(pattern => {
|
|
112
|
+
if (pattern.endsWith('/')) {
|
|
113
|
+
return file.startsWith(pattern);
|
|
114
|
+
}
|
|
115
|
+
if (pattern.startsWith('*.')) {
|
|
116
|
+
return file.endsWith(pattern.slice(1));
|
|
117
|
+
}
|
|
118
|
+
return file.includes(pattern);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
if (filtered.length > MAX_CHECKPOINT_FILES) {
|
|
123
|
+
logWarning(
|
|
124
|
+
'Too many modified files detected, limiting to maximum',
|
|
125
|
+
true,
|
|
126
|
+
{
|
|
127
|
+
context: {
|
|
128
|
+
fileCount: filtered.length,
|
|
129
|
+
maxFiles: MAX_CHECKPOINT_FILES,
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
);
|
|
133
|
+
return filtered.slice(0, MAX_CHECKPOINT_FILES);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return filtered;
|
|
137
|
+
} catch {
|
|
138
|
+
logWarning('Git not available for file tracking', true, {
|
|
139
|
+
context: {
|
|
140
|
+
workspaceRoot: this.workspaceRoot,
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
return [];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Get the size of a file snapshot
|
|
149
|
+
*/
|
|
150
|
+
getSnapshotSize(snapshots: Map<string, string>): number {
|
|
151
|
+
let totalSize = 0;
|
|
152
|
+
for (const content of snapshots.values()) {
|
|
153
|
+
totalSize += Buffer.byteLength(content, 'utf-8');
|
|
154
|
+
}
|
|
155
|
+
return totalSize;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Validate that all files in the snapshot can be written to their locations
|
|
160
|
+
*/
|
|
161
|
+
async validateRestorePath(
|
|
162
|
+
snapshots: Map<string, string>,
|
|
163
|
+
): Promise<{valid: boolean; errors: string[]}> {
|
|
164
|
+
const errors: string[] = [];
|
|
165
|
+
|
|
166
|
+
for (const relativePath of snapshots.keys()) {
|
|
167
|
+
const absolutePath = path.resolve(this.workspaceRoot, relativePath); // nosemgrep
|
|
168
|
+
const directory = path.dirname(absolutePath);
|
|
169
|
+
|
|
170
|
+
try {
|
|
171
|
+
let dirWritable = true;
|
|
172
|
+
try {
|
|
173
|
+
await fs.access(directory, fs.constants.W_OK);
|
|
174
|
+
} catch (_err) {
|
|
175
|
+
// Directory is not writable or does not exist, so try to create it
|
|
176
|
+
try {
|
|
177
|
+
await fs.mkdir(directory, {recursive: true});
|
|
178
|
+
} catch (mkdirError) {
|
|
179
|
+
dirWritable = false;
|
|
180
|
+
errors.push(
|
|
181
|
+
`Cannot create directory "${directory}": ${mkdirError instanceof Error ? mkdirError.message : 'Unknown error'}`,
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// After attempting to create the directory, verify it's writable
|
|
187
|
+
if (dirWritable) {
|
|
188
|
+
try {
|
|
189
|
+
await fs.access(directory, fs.constants.W_OK);
|
|
190
|
+
} catch (accessError) {
|
|
191
|
+
dirWritable = false;
|
|
192
|
+
errors.push(
|
|
193
|
+
`Directory "${directory}" is not writable: ${accessError instanceof Error ? accessError.message : 'Unknown error'}`,
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// If directory is not writable or was not successfully created, skip further checks for this file
|
|
199
|
+
if (!dirWritable) {
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (existsSync(absolutePath)) {
|
|
204
|
+
try {
|
|
205
|
+
await fs.access(absolutePath, fs.constants.W_OK);
|
|
206
|
+
} catch (fileError) {
|
|
207
|
+
errors.push(
|
|
208
|
+
`Cannot write to file "${absolutePath}": ${fileError instanceof Error ? fileError.message : 'Unknown error'}`,
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
} catch (error) {
|
|
213
|
+
errors.push(
|
|
214
|
+
`Cannot validate path for ${relativePath}: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return {valid: errors.length === 0, errors};
|
|
219
|
+
}
|
|
220
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import {ThemeContext} from '@/hooks/useTheme';
|
|
2
|
+
import type {Colors, ThemePreset} from '@/types/ui';
|
|
3
|
+
import {render} from 'ink-testing-library';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
|
|
6
|
+
// Default test colors that match the structure used in the app
|
|
7
|
+
const testColors: Colors = {
|
|
8
|
+
primary: 'blue',
|
|
9
|
+
secondary: 'gray',
|
|
10
|
+
white: 'white',
|
|
11
|
+
black: 'black',
|
|
12
|
+
info: 'cyan',
|
|
13
|
+
warning: 'yellow',
|
|
14
|
+
error: 'red',
|
|
15
|
+
success: 'green',
|
|
16
|
+
tool: 'magenta',
|
|
17
|
+
diffAdded: 'green',
|
|
18
|
+
diffRemoved: 'red',
|
|
19
|
+
diffAddedText: 'white',
|
|
20
|
+
diffRemovedText: 'white',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// Test theme context value
|
|
24
|
+
const testThemeContext = {
|
|
25
|
+
currentTheme: 'tokyo-night' as ThemePreset,
|
|
26
|
+
colors: testColors,
|
|
27
|
+
setCurrentTheme: () => {},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Wrapper component that provides ThemeContext for tests
|
|
32
|
+
*/
|
|
33
|
+
function TestThemeProvider({children}: {children: React.ReactNode}) {
|
|
34
|
+
return (
|
|
35
|
+
<ThemeContext.Provider value={testThemeContext}>
|
|
36
|
+
{children}
|
|
37
|
+
</ThemeContext.Provider>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Render a component wrapped with ThemeContext for testing
|
|
43
|
+
*/
|
|
44
|
+
export function renderWithTheme(
|
|
45
|
+
element: React.ReactElement,
|
|
46
|
+
): ReturnType<typeof render> {
|
|
47
|
+
return render(<TestThemeProvider>{element}</TestThemeProvider>);
|
|
48
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {createTokenizer} from './tokenizer-factory.js';
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for tokenizer-factory.ts
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import test from 'ava';
|
|
6
|
+
import {
|
|
7
|
+
createTokenizer,
|
|
8
|
+
createTokenizerForProvider,
|
|
9
|
+
} from './tokenizer-factory.js';
|
|
10
|
+
import {AnthropicTokenizer} from './tokenizers/anthropic-tokenizer.js';
|
|
11
|
+
import {FallbackTokenizer} from './tokenizers/fallback-tokenizer.js';
|
|
12
|
+
import {LlamaTokenizer} from './tokenizers/llama-tokenizer.js';
|
|
13
|
+
import {OpenAITokenizer} from './tokenizers/openai-tokenizer.js';
|
|
14
|
+
|
|
15
|
+
console.log(`\ntokenizer-factory.spec.ts`);
|
|
16
|
+
|
|
17
|
+
// Test createTokenizer with OpenAI provider detection
|
|
18
|
+
test('createTokenizer detects OpenAI from provider name', t => {
|
|
19
|
+
const tokenizer = createTokenizer('openai', 'custom-model');
|
|
20
|
+
t.true(tokenizer instanceof OpenAITokenizer);
|
|
21
|
+
t.is(tokenizer.getName(), 'openai-custom-model');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('createTokenizer detects OpenAI from GPT model name', t => {
|
|
25
|
+
const tokenizer = createTokenizer('custom', 'gpt-4-turbo');
|
|
26
|
+
t.true(tokenizer instanceof OpenAITokenizer);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test('createTokenizer detects OpenAI from model name with openai keyword', t => {
|
|
30
|
+
const tokenizer = createTokenizer('custom', 'openai-model');
|
|
31
|
+
t.true(tokenizer instanceof OpenAITokenizer);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Test createTokenizer with Anthropic provider detection
|
|
35
|
+
test('createTokenizer detects Anthropic from provider name', t => {
|
|
36
|
+
const tokenizer = createTokenizer('anthropic', 'custom-model');
|
|
37
|
+
t.true(tokenizer instanceof AnthropicTokenizer);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('createTokenizer detects Anthropic from provider name with claude keyword', t => {
|
|
41
|
+
const tokenizer = createTokenizer('claude-provider', 'model');
|
|
42
|
+
t.true(tokenizer instanceof AnthropicTokenizer);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test('createTokenizer detects Anthropic from claude model name', t => {
|
|
46
|
+
const tokenizer = createTokenizer('custom', 'claude-3-opus');
|
|
47
|
+
t.true(tokenizer instanceof AnthropicTokenizer);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// Test createTokenizer with Llama provider detection
|
|
51
|
+
test('createTokenizer detects Llama from llama model name', t => {
|
|
52
|
+
const tokenizer = createTokenizer('custom', 'llama-3-8b');
|
|
53
|
+
t.true(tokenizer instanceof LlamaTokenizer);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test('createTokenizer detects Llama from mistral model name', t => {
|
|
57
|
+
const tokenizer = createTokenizer('custom', 'mistral-7b');
|
|
58
|
+
t.true(tokenizer instanceof LlamaTokenizer);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('createTokenizer detects Llama from qwen model name', t => {
|
|
62
|
+
const tokenizer = createTokenizer('custom', 'qwen-2.5');
|
|
63
|
+
t.true(tokenizer instanceof LlamaTokenizer);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('createTokenizer detects Llama from gemma model name', t => {
|
|
67
|
+
const tokenizer = createTokenizer('custom', 'gemma-2b');
|
|
68
|
+
t.true(tokenizer instanceof LlamaTokenizer);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test('createTokenizer detects Llama from phi model name', t => {
|
|
72
|
+
const tokenizer = createTokenizer('custom', 'phi-3');
|
|
73
|
+
t.true(tokenizer instanceof LlamaTokenizer);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test('createTokenizer detects Llama from codellama model name', t => {
|
|
77
|
+
const tokenizer = createTokenizer('custom', 'codellama-7b');
|
|
78
|
+
t.true(tokenizer instanceof LlamaTokenizer);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test('createTokenizer detects Llama from deepseek model name', t => {
|
|
82
|
+
const tokenizer = createTokenizer('custom', 'deepseek-coder');
|
|
83
|
+
t.true(tokenizer instanceof LlamaTokenizer);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test('createTokenizer detects Llama from mixtral model name', t => {
|
|
87
|
+
const tokenizer = createTokenizer('custom', 'mixtral-8x7b');
|
|
88
|
+
t.true(tokenizer instanceof LlamaTokenizer);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('createTokenizer detects Llama from ollama provider', t => {
|
|
92
|
+
const tokenizer = createTokenizer('ollama', 'custom-model');
|
|
93
|
+
t.true(tokenizer instanceof LlamaTokenizer);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('createTokenizer detects Llama from llama.cpp provider', t => {
|
|
97
|
+
const tokenizer = createTokenizer('llama.cpp', 'custom-model');
|
|
98
|
+
t.true(tokenizer instanceof LlamaTokenizer);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
test('createTokenizer detects Llama from local provider', t => {
|
|
102
|
+
const tokenizer = createTokenizer('local', 'custom-model');
|
|
103
|
+
t.true(tokenizer instanceof LlamaTokenizer);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Test createTokenizer with fallback
|
|
107
|
+
test('createTokenizer returns FallbackTokenizer for unknown provider', t => {
|
|
108
|
+
const tokenizer = createTokenizer('unknown', 'unknown-model');
|
|
109
|
+
t.true(tokenizer instanceof FallbackTokenizer);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// Test cloud suffix stripping
|
|
113
|
+
test('createTokenizer strips :cloud suffix from model name', t => {
|
|
114
|
+
const tokenizer = createTokenizer('ollama', 'llama-3:cloud');
|
|
115
|
+
t.true(tokenizer instanceof LlamaTokenizer);
|
|
116
|
+
t.is(tokenizer.getName(), 'llama-llama-3');
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
test('createTokenizer strips -cloud suffix from model name', t => {
|
|
120
|
+
const tokenizer = createTokenizer('ollama', 'llama-3-cloud');
|
|
121
|
+
t.true(tokenizer instanceof LlamaTokenizer);
|
|
122
|
+
t.is(tokenizer.getName(), 'llama-llama-3');
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// Test case insensitivity
|
|
126
|
+
test('createTokenizer is case insensitive for provider detection', t => {
|
|
127
|
+
const tokenizer = createTokenizer('OPENAI', 'model');
|
|
128
|
+
t.true(tokenizer instanceof OpenAITokenizer);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
test('createTokenizer is case insensitive for model detection', t => {
|
|
132
|
+
const tokenizer = createTokenizer('custom', 'GPT-4-TURBO');
|
|
133
|
+
t.true(tokenizer instanceof OpenAITokenizer);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// Test createTokenizerForProvider
|
|
137
|
+
test('createTokenizerForProvider creates OpenAI tokenizer', t => {
|
|
138
|
+
const tokenizer = createTokenizerForProvider('openai', 'gpt-4');
|
|
139
|
+
t.true(tokenizer instanceof OpenAITokenizer);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
test('createTokenizerForProvider creates Anthropic tokenizer', t => {
|
|
143
|
+
const tokenizer = createTokenizerForProvider('anthropic', 'claude-3');
|
|
144
|
+
t.true(tokenizer instanceof AnthropicTokenizer);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
test('createTokenizerForProvider creates Llama tokenizer', t => {
|
|
148
|
+
const tokenizer = createTokenizerForProvider('llama', 'llama-3');
|
|
149
|
+
t.true(tokenizer instanceof LlamaTokenizer);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
test('createTokenizerForProvider creates FallbackTokenizer', t => {
|
|
153
|
+
const tokenizer = createTokenizerForProvider('fallback');
|
|
154
|
+
t.true(tokenizer instanceof FallbackTokenizer);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
test('createTokenizerForProvider handles auto mode with model ID', t => {
|
|
158
|
+
const tokenizer = createTokenizerForProvider('auto', 'gpt-4');
|
|
159
|
+
t.true(tokenizer instanceof OpenAITokenizer);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
test('createTokenizerForProvider handles auto mode without model ID', t => {
|
|
163
|
+
const tokenizer = createTokenizerForProvider('auto');
|
|
164
|
+
t.true(tokenizer instanceof FallbackTokenizer);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test('createTokenizerForProvider works without model ID', t => {
|
|
168
|
+
const tokenizer = createTokenizerForProvider('openai');
|
|
169
|
+
t.true(tokenizer instanceof OpenAITokenizer);
|
|
170
|
+
});
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tokenizer factory
|
|
3
|
+
* Creates appropriate tokenizer based on provider and model
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type {Tokenizer, TokenizerProvider} from '../types/tokenization.js';
|
|
7
|
+
import {AnthropicTokenizer} from './tokenizers/anthropic-tokenizer.js';
|
|
8
|
+
import {FallbackTokenizer} from './tokenizers/fallback-tokenizer.js';
|
|
9
|
+
import {LlamaTokenizer} from './tokenizers/llama-tokenizer.js';
|
|
10
|
+
import {OpenAITokenizer} from './tokenizers/openai-tokenizer.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Detect provider from model ID or provider name
|
|
14
|
+
*/
|
|
15
|
+
function detectProvider(
|
|
16
|
+
providerName: string,
|
|
17
|
+
modelId: string,
|
|
18
|
+
): TokenizerProvider {
|
|
19
|
+
const lowerProvider = providerName.toLowerCase();
|
|
20
|
+
const lowerModel = modelId.toLowerCase();
|
|
21
|
+
|
|
22
|
+
// Check provider name
|
|
23
|
+
if (lowerProvider.includes('openai')) {
|
|
24
|
+
return 'openai';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (lowerProvider.includes('anthropic') || lowerProvider.includes('claude')) {
|
|
28
|
+
return 'anthropic';
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Check model ID for common patterns
|
|
32
|
+
if (lowerModel.includes('gpt') || lowerModel.includes('openai')) {
|
|
33
|
+
return 'openai';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (lowerModel.includes('claude')) {
|
|
37
|
+
return 'anthropic';
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (
|
|
41
|
+
lowerModel.includes('llama') ||
|
|
42
|
+
lowerModel.includes('mistral') ||
|
|
43
|
+
lowerModel.includes('qwen') ||
|
|
44
|
+
lowerModel.includes('gemma') ||
|
|
45
|
+
lowerModel.includes('phi') ||
|
|
46
|
+
lowerModel.includes('codellama') ||
|
|
47
|
+
lowerModel.includes('deepseek') ||
|
|
48
|
+
lowerModel.includes('mixtral')
|
|
49
|
+
) {
|
|
50
|
+
return 'llama';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Default to llama for local models (most common for local inference)
|
|
54
|
+
if (
|
|
55
|
+
lowerProvider.includes('ollama') ||
|
|
56
|
+
lowerProvider.includes('llama.cpp') ||
|
|
57
|
+
lowerProvider.includes('local')
|
|
58
|
+
) {
|
|
59
|
+
return 'llama';
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return 'fallback';
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Create a tokenizer based on provider and model
|
|
67
|
+
*/
|
|
68
|
+
export function createTokenizer(
|
|
69
|
+
providerName: string,
|
|
70
|
+
modelId: string,
|
|
71
|
+
): Tokenizer {
|
|
72
|
+
// Strip :cloud suffix if present (Ollama cloud models)
|
|
73
|
+
const normalizedModelId =
|
|
74
|
+
modelId.endsWith(':cloud') || modelId.endsWith('-cloud')
|
|
75
|
+
? modelId.slice(0, -6)
|
|
76
|
+
: modelId;
|
|
77
|
+
|
|
78
|
+
const provider = detectProvider(providerName, normalizedModelId);
|
|
79
|
+
|
|
80
|
+
switch (provider) {
|
|
81
|
+
case 'openai':
|
|
82
|
+
return new OpenAITokenizer(normalizedModelId);
|
|
83
|
+
|
|
84
|
+
case 'anthropic':
|
|
85
|
+
return new AnthropicTokenizer(normalizedModelId);
|
|
86
|
+
|
|
87
|
+
case 'llama':
|
|
88
|
+
return new LlamaTokenizer(normalizedModelId);
|
|
89
|
+
|
|
90
|
+
case 'fallback':
|
|
91
|
+
default:
|
|
92
|
+
return new FallbackTokenizer();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Create a tokenizer with explicit provider
|
|
98
|
+
*/
|
|
99
|
+
export function createTokenizerForProvider(
|
|
100
|
+
provider: TokenizerProvider,
|
|
101
|
+
modelId?: string,
|
|
102
|
+
): Tokenizer {
|
|
103
|
+
switch (provider) {
|
|
104
|
+
case 'openai':
|
|
105
|
+
return new OpenAITokenizer(modelId);
|
|
106
|
+
|
|
107
|
+
case 'anthropic':
|
|
108
|
+
return new AnthropicTokenizer(modelId);
|
|
109
|
+
|
|
110
|
+
case 'llama':
|
|
111
|
+
return new LlamaTokenizer(modelId);
|
|
112
|
+
|
|
113
|
+
case 'auto':
|
|
114
|
+
// Auto-detect based on model ID if provided
|
|
115
|
+
if (modelId) {
|
|
116
|
+
return createTokenizer('', modelId);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return new FallbackTokenizer();
|
|
120
|
+
|
|
121
|
+
case 'fallback':
|
|
122
|
+
default:
|
|
123
|
+
return new FallbackTokenizer();
|
|
124
|
+
}
|
|
125
|
+
}
|