cowork-os 0.3.21 → 0.3.25
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 +372 -10
- package/connectors/README.md +20 -0
- package/connectors/asana-mcp/README.md +24 -0
- package/connectors/asana-mcp/dist/index.js +427 -0
- package/connectors/asana-mcp/package.json +15 -0
- package/connectors/asana-mcp/src/index.ts +553 -0
- package/connectors/asana-mcp/tsconfig.json +13 -0
- package/connectors/hubspot-mcp/README.md +35 -0
- package/connectors/hubspot-mcp/dist/index.js +454 -0
- package/connectors/hubspot-mcp/package.json +15 -0
- package/connectors/hubspot-mcp/src/index.ts +562 -0
- package/connectors/hubspot-mcp/tsconfig.json +13 -0
- package/connectors/jira-mcp/README.md +49 -0
- package/connectors/jira-mcp/dist/index.js +588 -0
- package/connectors/jira-mcp/package.json +15 -0
- package/connectors/jira-mcp/src/index.ts +711 -0
- package/connectors/jira-mcp/tsconfig.json +13 -0
- package/connectors/linear-mcp/README.md +22 -0
- package/connectors/linear-mcp/dist/index.js +402 -0
- package/connectors/linear-mcp/package.json +15 -0
- package/connectors/linear-mcp/src/index.ts +522 -0
- package/connectors/linear-mcp/tsconfig.json +13 -0
- package/connectors/okta-mcp/README.md +24 -0
- package/connectors/okta-mcp/dist/index.js +411 -0
- package/connectors/okta-mcp/package.json +15 -0
- package/connectors/okta-mcp/src/index.ts +520 -0
- package/connectors/okta-mcp/tsconfig.json +13 -0
- package/connectors/salesforce-mcp/README.md +47 -0
- package/connectors/salesforce-mcp/dist/index.js +584 -0
- package/connectors/salesforce-mcp/package.json +15 -0
- package/connectors/salesforce-mcp/src/index.ts +722 -0
- package/connectors/salesforce-mcp/tsconfig.json +13 -0
- package/connectors/servicenow-mcp/README.md +26 -0
- package/connectors/servicenow-mcp/dist/index.js +400 -0
- package/connectors/servicenow-mcp/package.json +15 -0
- package/connectors/servicenow-mcp/src/index.ts +500 -0
- package/connectors/servicenow-mcp/tsconfig.json +13 -0
- package/connectors/templates/mcp-connector/README.md +31 -0
- package/connectors/templates/mcp-connector/package.json +15 -0
- package/connectors/templates/mcp-connector/src/index.ts +330 -0
- package/connectors/templates/mcp-connector/tsconfig.json +13 -0
- package/connectors/zendesk-mcp/README.md +40 -0
- package/connectors/zendesk-mcp/dist/index.js +431 -0
- package/connectors/zendesk-mcp/package.json +15 -0
- package/connectors/zendesk-mcp/src/index.ts +543 -0
- package/connectors/zendesk-mcp/tsconfig.json +13 -0
- package/dist/electron/electron/agent/custom-skill-loader.js +31 -1
- package/dist/electron/electron/agent/daemon.js +189 -13
- package/dist/electron/electron/agent/executor.js +895 -78
- package/dist/electron/electron/agent/llm/anthropic-compatible-provider.js +177 -0
- package/dist/electron/electron/agent/llm/azure-openai-provider.js +328 -0
- package/dist/electron/electron/agent/llm/bedrock-provider.js +49 -9
- package/dist/electron/electron/agent/llm/github-copilot-provider.js +97 -0
- package/dist/electron/electron/agent/llm/groq-provider.js +33 -0
- package/dist/electron/electron/agent/llm/index.js +13 -1
- package/dist/electron/electron/agent/llm/kimi-provider.js +33 -0
- package/dist/electron/electron/agent/llm/openai-compatible-provider.js +116 -0
- package/dist/electron/electron/agent/llm/openai-compatible.js +111 -0
- package/dist/electron/electron/agent/llm/openai-oauth.js +2 -1
- package/dist/electron/electron/agent/llm/openrouter-provider.js +1 -1
- package/dist/electron/electron/agent/llm/provider-factory.js +350 -4
- package/dist/electron/electron/agent/llm/types.js +66 -1
- package/dist/electron/electron/agent/llm/xai-provider.js +33 -0
- package/dist/electron/electron/agent/search/provider-factory.js +38 -2
- package/dist/electron/electron/agent/tools/box-tools.js +231 -0
- package/dist/electron/electron/agent/tools/builtin-settings.js +28 -0
- package/dist/electron/electron/agent/tools/dropbox-tools.js +237 -0
- package/dist/electron/electron/agent/tools/file-tools.js +66 -3
- package/dist/electron/electron/agent/tools/google-drive-tools.js +227 -0
- package/dist/electron/electron/agent/tools/grep-tools.js +90 -10
- package/dist/electron/electron/agent/tools/image-tools.js +11 -1
- package/dist/electron/electron/agent/tools/notion-tools.js +312 -0
- package/dist/electron/electron/agent/tools/onedrive-tools.js +217 -0
- package/dist/electron/electron/agent/tools/registry.js +548 -10
- package/dist/electron/electron/agent/tools/search-tools.js +28 -10
- package/dist/electron/electron/agent/tools/sharepoint-tools.js +243 -0
- package/dist/electron/electron/agent/tools/shell-tools.js +12 -3
- package/dist/electron/electron/agent/tools/x-tools.js +1 -1
- package/dist/electron/electron/agents/agent-dispatch.js +63 -0
- package/dist/electron/electron/database/repositories.js +19 -5
- package/dist/electron/electron/database/schema.js +8 -0
- package/dist/electron/electron/gateway/channels/whatsapp.js +55 -0
- package/dist/electron/electron/gateway/index.js +75 -1
- package/dist/electron/electron/gateway/router.js +209 -154
- package/dist/electron/electron/ipc/canvas-handlers.js +5 -0
- package/dist/electron/electron/ipc/handlers.js +763 -267
- package/dist/electron/electron/main.js +63 -0
- package/dist/electron/electron/mcp/oauth/connector-oauth.js +333 -0
- package/dist/electron/electron/mcp/registry/MCPRegistryManager.js +503 -154
- package/dist/electron/electron/memory/MemoryService.js +2 -1
- package/dist/electron/electron/preload.js +78 -1
- package/dist/electron/electron/settings/appearance-manager.js +18 -1
- package/dist/electron/electron/settings/box-manager.js +54 -0
- package/dist/electron/electron/settings/dropbox-manager.js +54 -0
- package/dist/electron/electron/settings/google-drive-manager.js +54 -0
- package/dist/electron/electron/settings/notion-manager.js +56 -0
- package/dist/electron/electron/settings/onedrive-manager.js +54 -0
- package/dist/electron/electron/settings/sharepoint-manager.js +54 -0
- package/dist/electron/electron/utils/box-api.js +153 -0
- package/dist/electron/electron/utils/dropbox-api.js +144 -0
- package/dist/electron/electron/utils/env-migration.js +19 -0
- package/dist/electron/electron/utils/google-drive-api.js +152 -0
- package/dist/electron/electron/utils/notion-api.js +103 -0
- package/dist/electron/electron/utils/onedrive-api.js +113 -0
- package/dist/electron/electron/utils/sharepoint-api.js +109 -0
- package/dist/electron/electron/utils/validation.js +98 -3
- package/dist/electron/electron/utils/x-cli.js +1 -1
- package/dist/electron/shared/channelMessages.js +284 -3
- package/dist/electron/shared/llm-provider-catalog.js +198 -0
- package/dist/electron/shared/types.js +90 -1
- package/package.json +14 -3
- package/resources/skills/nano-banana-pro.json +4 -4
- package/resources/skills/openai-image-gen.json +3 -3
- package/resources/skills/scripts/gen.py +163 -0
- package/resources/skills/scripts/generate_image.py +91 -0
- package/src/electron/agent/custom-skill-loader.ts +34 -1
- package/src/electron/agent/daemon.ts +210 -14
- package/src/electron/agent/executor.ts +1124 -85
- package/src/electron/agent/llm/anthropic-compatible-provider.ts +214 -0
- package/src/electron/agent/llm/azure-openai-provider.ts +388 -0
- package/src/electron/agent/llm/bedrock-provider.ts +62 -9
- package/src/electron/agent/llm/github-copilot-provider.ts +117 -0
- package/src/electron/agent/llm/groq-provider.ts +39 -0
- package/src/electron/agent/llm/index.ts +6 -0
- package/src/electron/agent/llm/kimi-provider.ts +39 -0
- package/src/electron/agent/llm/openai-compatible-provider.ts +153 -0
- package/src/electron/agent/llm/openai-compatible.ts +133 -0
- package/src/electron/agent/llm/openai-oauth.ts +2 -1
- package/src/electron/agent/llm/openrouter-provider.ts +2 -1
- package/src/electron/agent/llm/provider-factory.ts +459 -6
- package/src/electron/agent/llm/types.ts +95 -1
- package/src/electron/agent/llm/xai-provider.ts +39 -0
- package/src/electron/agent/search/provider-factory.ts +43 -2
- package/src/electron/agent/tools/box-tools.ts +239 -0
- package/src/electron/agent/tools/builtin-settings.ts +36 -0
- package/src/electron/agent/tools/dropbox-tools.ts +237 -0
- package/src/electron/agent/tools/file-tools.ts +66 -3
- package/src/electron/agent/tools/gmail-tools.ts +240 -0
- package/src/electron/agent/tools/google-calendar-tools.ts +258 -0
- package/src/electron/agent/tools/google-drive-tools.ts +228 -0
- package/src/electron/agent/tools/grep-tools.ts +97 -12
- package/src/electron/agent/tools/image-tools.ts +11 -1
- package/src/electron/agent/tools/notion-tools.ts +330 -0
- package/src/electron/agent/tools/onedrive-tools.ts +217 -0
- package/src/electron/agent/tools/registry.ts +794 -10
- package/src/electron/agent/tools/search-tools.ts +29 -11
- package/src/electron/agent/tools/sharepoint-tools.ts +247 -0
- package/src/electron/agent/tools/shell-tools.ts +11 -3
- package/src/electron/agent/tools/x-tools.ts +1 -1
- package/src/electron/agents/agent-dispatch.ts +79 -0
- package/src/electron/database/SecureSettingsRepository.ts +7 -1
- package/src/electron/database/repositories.ts +58 -6
- package/src/electron/database/schema.ts +8 -0
- package/src/electron/gateway/channels/discord.ts +4 -0
- package/src/electron/gateway/channels/google-chat.ts +3 -0
- package/src/electron/gateway/channels/line.ts +3 -0
- package/src/electron/gateway/channels/matrix-client.ts +15 -0
- package/src/electron/gateway/channels/matrix.ts +31 -0
- package/src/electron/gateway/channels/mattermost.ts +3 -0
- package/src/electron/gateway/channels/signal.ts +3 -0
- package/src/electron/gateway/channels/slack.ts +9 -4
- package/src/electron/gateway/channels/teams.ts +4 -0
- package/src/electron/gateway/channels/telegram.ts +2 -0
- package/src/electron/gateway/channels/twitch.ts +2 -0
- package/src/electron/gateway/channels/types.ts +8 -0
- package/src/electron/gateway/channels/whatsapp.ts +66 -0
- package/src/electron/gateway/index.ts +95 -2
- package/src/electron/gateway/router.ts +231 -161
- package/src/electron/gateway/security.ts +21 -9
- package/src/electron/ipc/canvas-handlers.ts +10 -0
- package/src/electron/ipc/handlers.ts +848 -292
- package/src/electron/main.ts +35 -0
- package/src/electron/mcp/oauth/connector-oauth.ts +448 -0
- package/src/electron/mcp/registry/MCPRegistryManager.ts +343 -12
- package/src/electron/memory/MemoryService.ts +7 -1
- package/src/electron/preload.ts +200 -5
- package/src/electron/settings/appearance-manager.ts +20 -2
- package/src/electron/settings/box-manager.ts +58 -0
- package/src/electron/settings/dropbox-manager.ts +58 -0
- package/src/electron/settings/google-workspace-manager.ts +59 -0
- package/src/electron/settings/notion-manager.ts +60 -0
- package/src/electron/settings/onedrive-manager.ts +58 -0
- package/src/electron/settings/sharepoint-manager.ts +58 -0
- package/src/electron/utils/box-api.ts +184 -0
- package/src/electron/utils/dropbox-api.ts +171 -0
- package/src/electron/utils/env-migration.ts +22 -0
- package/src/electron/utils/gmail-api.ts +121 -0
- package/src/electron/utils/google-calendar-api.ts +115 -0
- package/src/electron/utils/google-workspace-api.ts +228 -0
- package/src/electron/utils/google-workspace-auth.ts +109 -0
- package/src/electron/utils/google-workspace-oauth.ts +232 -0
- package/src/electron/utils/notion-api.ts +126 -0
- package/src/electron/utils/onedrive-api.ts +137 -0
- package/src/electron/utils/sharepoint-api.ts +132 -0
- package/src/electron/utils/validation.ts +128 -1
- package/src/electron/utils/x-cli.ts +1 -1
- package/src/renderer/App.tsx +119 -8
- package/src/renderer/components/ActivityFeedItem.tsx +34 -17
- package/src/renderer/components/AgentWorkingStatePanel.tsx +7 -5
- package/src/renderer/components/AppearanceSettings.tsx +37 -2
- package/src/renderer/components/BlueBubblesSettings.tsx +18 -7
- package/src/renderer/components/BoxSettings.tsx +203 -0
- package/src/renderer/components/BrowserView.tsx +101 -0
- package/src/renderer/components/BuiltinToolsSettings.tsx +105 -0
- package/src/renderer/components/CanvasPreview.tsx +68 -1
- package/src/renderer/components/ConnectorEnvModal.tsx +116 -0
- package/src/renderer/components/ConnectorSetupModal.tsx +566 -0
- package/src/renderer/components/ConnectorsSettings.tsx +397 -0
- package/src/renderer/components/ControlPlaneSettings.tsx +2 -0
- package/src/renderer/components/DiscordSettings.tsx +18 -7
- package/src/renderer/components/DropboxSettings.tsx +202 -0
- package/src/renderer/components/EmailSettings.tsx +18 -7
- package/src/renderer/components/FileViewer.tsx +21 -13
- package/src/renderer/components/GoogleChatSettings.tsx +17 -7
- package/src/renderer/components/GoogleWorkspaceSettings.tsx +332 -0
- package/src/renderer/components/ImessageSettings.tsx +22 -11
- package/src/renderer/components/LineIcons.tsx +376 -0
- package/src/renderer/components/LineSettings.tsx +18 -7
- package/src/renderer/components/MCPSettings.tsx +56 -0
- package/src/renderer/components/MainContent.tsx +740 -76
- package/src/renderer/components/MatrixSettings.tsx +18 -7
- package/src/renderer/components/MattermostSettings.tsx +18 -7
- package/src/renderer/components/NodesSettings.tsx +58 -99
- package/src/renderer/components/NotificationPanel.tsx +25 -11
- package/src/renderer/components/NotionSettings.tsx +231 -0
- package/src/renderer/components/Onboarding/Onboarding.tsx +13 -1
- package/src/renderer/components/OnboardingModal.tsx +70 -1
- package/src/renderer/components/OneDriveSettings.tsx +212 -0
- package/src/renderer/components/RightPanel.tsx +141 -28
- package/src/renderer/components/ScheduledTasksSettings.tsx +10 -62
- package/src/renderer/components/SearchSettings.tsx +118 -114
- package/src/renderer/components/Settings.tsx +1425 -651
- package/src/renderer/components/SharePointSettings.tsx +224 -0
- package/src/renderer/components/Sidebar.tsx +94 -19
- package/src/renderer/components/SignalSettings.tsx +18 -7
- package/src/renderer/components/SkillHubBrowser.tsx +144 -185
- package/src/renderer/components/SlackSettings.tsx +18 -7
- package/src/renderer/components/TaskQuickActions.tsx +11 -6
- package/src/renderer/components/TaskTimeline.tsx +58 -26
- package/src/renderer/components/TeamsSettings.tsx +18 -7
- package/src/renderer/components/TelegramSettings.tsx +18 -7
- package/src/renderer/components/ThemeIcon.tsx +16 -0
- package/src/renderer/components/TwitchSettings.tsx +18 -7
- package/src/renderer/components/VoiceSettings.tsx +30 -74
- package/src/renderer/components/WhatsAppSettings.tsx +48 -37
- package/src/renderer/components/WorkingStateHistory.tsx +7 -5
- package/src/renderer/components/WorkspaceSelector.tsx +42 -13
- package/src/renderer/hooks/useOnboardingFlow.ts +21 -0
- package/src/renderer/styles/index.css +2333 -209
- package/src/shared/channelMessages.ts +367 -4
- package/src/shared/llm-provider-catalog.ts +217 -0
- package/src/shared/types.ts +251 -2
|
@@ -45,10 +45,87 @@ const ollama_provider_1 = require("./ollama-provider");
|
|
|
45
45
|
const gemini_provider_1 = require("./gemini-provider");
|
|
46
46
|
const openrouter_provider_1 = require("./openrouter-provider");
|
|
47
47
|
const openai_provider_1 = require("./openai-provider");
|
|
48
|
+
const azure_openai_provider_1 = require("./azure-openai-provider");
|
|
49
|
+
const groq_provider_1 = require("./groq-provider");
|
|
50
|
+
const xai_provider_1 = require("./xai-provider");
|
|
51
|
+
const kimi_provider_1 = require("./kimi-provider");
|
|
52
|
+
const anthropic_compatible_provider_1 = require("./anthropic-compatible-provider");
|
|
53
|
+
const openai_compatible_provider_1 = require("./openai-compatible-provider");
|
|
54
|
+
const github_copilot_provider_1 = require("./github-copilot-provider");
|
|
48
55
|
const SecureSettingsRepository_1 = require("../../database/SecureSettingsRepository");
|
|
56
|
+
const llm_provider_catalog_1 = require("../../../shared/llm-provider-catalog");
|
|
49
57
|
const LEGACY_SETTINGS_FILE = 'llm-settings.json';
|
|
50
58
|
const MASKED_VALUE = '***configured***';
|
|
51
59
|
const ENCRYPTED_PREFIX = 'encrypted:';
|
|
60
|
+
const CUSTOM_PROVIDER_ALIASES = {
|
|
61
|
+
'kimi-coding': 'kimi-code',
|
|
62
|
+
};
|
|
63
|
+
function resolveCustomProviderId(providerType) {
|
|
64
|
+
return CUSTOM_PROVIDER_ALIASES[providerType] || providerType;
|
|
65
|
+
}
|
|
66
|
+
function getCustomProviderEntry(providerType) {
|
|
67
|
+
return llm_provider_catalog_1.CUSTOM_PROVIDER_MAP.get(resolveCustomProviderId(providerType));
|
|
68
|
+
}
|
|
69
|
+
function getCustomProviderConfig(customProviders, providerType) {
|
|
70
|
+
if (!customProviders)
|
|
71
|
+
return undefined;
|
|
72
|
+
const resolved = resolveCustomProviderId(providerType);
|
|
73
|
+
const resolvedConfig = customProviders[resolved];
|
|
74
|
+
if (resolvedConfig) {
|
|
75
|
+
return resolvedConfig;
|
|
76
|
+
}
|
|
77
|
+
const fallbackConfig = customProviders[providerType];
|
|
78
|
+
if (fallbackConfig && resolved !== providerType) {
|
|
79
|
+
console.log(`[LLMProviderFactory] Custom provider config not found for "${resolved}", falling back to "${providerType}".`);
|
|
80
|
+
}
|
|
81
|
+
return fallbackConfig;
|
|
82
|
+
}
|
|
83
|
+
function isCustomProviderConfigured(entry, config) {
|
|
84
|
+
if (!config)
|
|
85
|
+
return false;
|
|
86
|
+
const hasApiKey = !!config.apiKey?.trim();
|
|
87
|
+
const hasBaseUrl = !!config.baseUrl?.trim() || !!entry.baseUrl;
|
|
88
|
+
const hasUserConfig = hasApiKey || !!config.baseUrl?.trim() || !!config.model?.trim();
|
|
89
|
+
if (!hasUserConfig)
|
|
90
|
+
return false;
|
|
91
|
+
if (entry.apiKeyOptional) {
|
|
92
|
+
return entry.requiresBaseUrl ? hasBaseUrl : hasApiKey || hasBaseUrl;
|
|
93
|
+
}
|
|
94
|
+
return entry.requiresBaseUrl ? hasApiKey && hasBaseUrl : hasApiKey;
|
|
95
|
+
}
|
|
96
|
+
function createCustomProvider(config, entry, resolvedType) {
|
|
97
|
+
if (resolvedType === 'github-copilot') {
|
|
98
|
+
return new github_copilot_provider_1.GitHubCopilotProvider(config);
|
|
99
|
+
}
|
|
100
|
+
const apiKey = config.providerApiKey || '';
|
|
101
|
+
const baseUrl = config.providerBaseUrl || entry.baseUrl || '';
|
|
102
|
+
if (entry.requiresBaseUrl && !baseUrl) {
|
|
103
|
+
throw new Error(`${entry.name} base URL is required. Configure it in Settings.`);
|
|
104
|
+
}
|
|
105
|
+
if (!apiKey && !entry.apiKeyOptional) {
|
|
106
|
+
throw new Error(`${entry.name} API key is required. Configure it in Settings.`);
|
|
107
|
+
}
|
|
108
|
+
const model = config.model || entry.defaultModel;
|
|
109
|
+
if (!model) {
|
|
110
|
+
throw new Error(`${entry.name} model is required. Configure it in Settings.`);
|
|
111
|
+
}
|
|
112
|
+
if (entry.compatibility === 'openai') {
|
|
113
|
+
return new openai_compatible_provider_1.OpenAICompatibleProvider({
|
|
114
|
+
type: resolvedType,
|
|
115
|
+
providerName: entry.name,
|
|
116
|
+
apiKey,
|
|
117
|
+
baseUrl,
|
|
118
|
+
defaultModel: model,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
return new anthropic_compatible_provider_1.AnthropicCompatibleProvider({
|
|
122
|
+
type: resolvedType,
|
|
123
|
+
providerName: entry.name,
|
|
124
|
+
apiKey,
|
|
125
|
+
baseUrl,
|
|
126
|
+
defaultModel: model,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
52
129
|
// ============ Legacy Encryption Functions (for migration only) ============
|
|
53
130
|
// These functions are only used to decrypt settings from legacy JSON files
|
|
54
131
|
// during migration to the encrypted database. New settings use full-object
|
|
@@ -178,6 +255,40 @@ function sanitizeSettings(settings) {
|
|
|
178
255
|
refreshToken: decryptedRefreshToken,
|
|
179
256
|
};
|
|
180
257
|
}
|
|
258
|
+
if (sanitized.azure) {
|
|
259
|
+
sanitized.azure = {
|
|
260
|
+
...sanitized.azure,
|
|
261
|
+
apiKey: decryptSecret(sanitized.azure.apiKey),
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
if (sanitized.groq) {
|
|
265
|
+
sanitized.groq = {
|
|
266
|
+
...sanitized.groq,
|
|
267
|
+
apiKey: decryptSecret(sanitized.groq.apiKey),
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
if (sanitized.xai) {
|
|
271
|
+
sanitized.xai = {
|
|
272
|
+
...sanitized.xai,
|
|
273
|
+
apiKey: decryptSecret(sanitized.xai.apiKey),
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
if (sanitized.kimi) {
|
|
277
|
+
sanitized.kimi = {
|
|
278
|
+
...sanitized.kimi,
|
|
279
|
+
apiKey: decryptSecret(sanitized.kimi.apiKey),
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
if (sanitized.customProviders) {
|
|
283
|
+
const normalized = {};
|
|
284
|
+
for (const [key, value] of Object.entries(sanitized.customProviders)) {
|
|
285
|
+
normalized[key] = {
|
|
286
|
+
...value,
|
|
287
|
+
apiKey: decryptSecret(value.apiKey),
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
sanitized.customProviders = normalized;
|
|
291
|
+
}
|
|
181
292
|
return sanitized;
|
|
182
293
|
}
|
|
183
294
|
const DEFAULT_SETTINGS = {
|
|
@@ -188,6 +299,20 @@ const DEFAULT_SETTINGS = {
|
|
|
188
299
|
* Factory for creating LLM providers
|
|
189
300
|
*/
|
|
190
301
|
class LLMProviderFactory {
|
|
302
|
+
static normalizeCustomProviders(settings) {
|
|
303
|
+
if (!settings.customProviders)
|
|
304
|
+
return;
|
|
305
|
+
const legacyKey = settings.customProviders['kimi-coding'];
|
|
306
|
+
if (legacyKey && !settings.customProviders['kimi-code']) {
|
|
307
|
+
settings.customProviders['kimi-code'] = legacyKey;
|
|
308
|
+
}
|
|
309
|
+
if (settings.customProviders['kimi-coding']) {
|
|
310
|
+
delete settings.customProviders['kimi-coding'];
|
|
311
|
+
}
|
|
312
|
+
if (settings.providerType === 'kimi-coding') {
|
|
313
|
+
settings.providerType = 'kimi-code';
|
|
314
|
+
}
|
|
315
|
+
}
|
|
191
316
|
/**
|
|
192
317
|
* Initialize the factory
|
|
193
318
|
*/
|
|
@@ -270,6 +395,7 @@ class LLMProviderFactory {
|
|
|
270
395
|
const stored = repository.load('llm');
|
|
271
396
|
if (stored) {
|
|
272
397
|
settings = { ...DEFAULT_SETTINGS, ...stored };
|
|
398
|
+
this.normalizeCustomProviders(settings);
|
|
273
399
|
settingsExist = true;
|
|
274
400
|
}
|
|
275
401
|
}
|
|
@@ -307,12 +433,33 @@ class LLMProviderFactory {
|
|
|
307
433
|
if (settings.openai?.apiKey || settings.openai?.accessToken) {
|
|
308
434
|
return 'openai';
|
|
309
435
|
}
|
|
436
|
+
const azureDeployment = settings.azure?.deployment || settings.azure?.deployments?.[0];
|
|
437
|
+
if (settings.azure?.apiKey && settings.azure?.endpoint && azureDeployment) {
|
|
438
|
+
return 'azure';
|
|
439
|
+
}
|
|
440
|
+
if (settings.groq?.apiKey) {
|
|
441
|
+
return 'groq';
|
|
442
|
+
}
|
|
443
|
+
if (settings.xai?.apiKey) {
|
|
444
|
+
return 'xai';
|
|
445
|
+
}
|
|
446
|
+
if (settings.kimi?.apiKey) {
|
|
447
|
+
return 'kimi';
|
|
448
|
+
}
|
|
310
449
|
if (settings.bedrock?.accessKeyId || settings.bedrock?.profile) {
|
|
311
450
|
return 'bedrock';
|
|
312
451
|
}
|
|
313
452
|
if (settings.ollama?.baseUrl || settings.ollama?.model) {
|
|
314
453
|
return 'ollama';
|
|
315
454
|
}
|
|
455
|
+
if (settings.customProviders) {
|
|
456
|
+
for (const entry of llm_provider_catalog_1.CUSTOM_PROVIDER_CATALOG) {
|
|
457
|
+
const config = getCustomProviderConfig(settings.customProviders, entry.id);
|
|
458
|
+
if (isCustomProviderConfigured(entry, config)) {
|
|
459
|
+
return entry.id;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
316
463
|
// No valid credentials detected - user needs to configure via Settings
|
|
317
464
|
return null;
|
|
318
465
|
}
|
|
@@ -350,9 +497,13 @@ class LLMProviderFactory {
|
|
|
350
497
|
static createProvider(overrideConfig) {
|
|
351
498
|
const settings = this.loadSettings();
|
|
352
499
|
const providerType = overrideConfig?.type || settings.providerType;
|
|
500
|
+
const customConfig = getCustomProviderConfig(settings.customProviders, providerType);
|
|
501
|
+
const azureDeployment = overrideConfig?.azureDeployment
|
|
502
|
+
|| settings.azure?.deployment
|
|
503
|
+
|| settings.azure?.deployments?.[0];
|
|
353
504
|
const config = {
|
|
354
505
|
type: providerType,
|
|
355
|
-
model: this.getModelId(settings.modelKey, providerType, settings.ollama?.model, settings.gemini?.model, settings.openrouter?.model, settings.openai?.model),
|
|
506
|
+
model: this.getModelId(settings.modelKey, providerType, settings.ollama?.model, settings.gemini?.model, settings.openrouter?.model, settings.openai?.model, azureDeployment, settings.groq?.model, settings.xai?.model, settings.kimi?.model, settings.customProviders),
|
|
356
507
|
// Anthropic config - from settings only
|
|
357
508
|
anthropicApiKey: normalizeSecret(overrideConfig?.anthropicApiKey) || settings.anthropic?.apiKey,
|
|
358
509
|
// Bedrock config - from settings only
|
|
@@ -368,11 +519,29 @@ class LLMProviderFactory {
|
|
|
368
519
|
geminiApiKey: normalizeSecret(overrideConfig?.geminiApiKey) || settings.gemini?.apiKey,
|
|
369
520
|
// OpenRouter config - from settings only
|
|
370
521
|
openrouterApiKey: normalizeSecret(overrideConfig?.openrouterApiKey) || settings.openrouter?.apiKey,
|
|
522
|
+
openrouterBaseUrl: overrideConfig?.openrouterBaseUrl || settings.openrouter?.baseUrl,
|
|
371
523
|
// OpenAI config - from settings only
|
|
372
524
|
openaiApiKey: normalizeSecret(overrideConfig?.openaiApiKey) || settings.openai?.apiKey,
|
|
373
525
|
openaiAccessToken: normalizeSecret(overrideConfig?.openaiAccessToken) || settings.openai?.accessToken,
|
|
374
526
|
openaiRefreshToken: settings.openai?.refreshToken,
|
|
375
527
|
openaiTokenExpiresAt: settings.openai?.tokenExpiresAt,
|
|
528
|
+
// Azure OpenAI config - from settings only
|
|
529
|
+
azureApiKey: normalizeSecret(overrideConfig?.azureApiKey) || settings.azure?.apiKey,
|
|
530
|
+
azureEndpoint: overrideConfig?.azureEndpoint || settings.azure?.endpoint,
|
|
531
|
+
azureDeployment,
|
|
532
|
+
azureApiVersion: overrideConfig?.azureApiVersion || settings.azure?.apiVersion,
|
|
533
|
+
// Groq config - from settings only
|
|
534
|
+
groqApiKey: normalizeSecret(overrideConfig?.groqApiKey) || settings.groq?.apiKey,
|
|
535
|
+
groqBaseUrl: overrideConfig?.groqBaseUrl || settings.groq?.baseUrl,
|
|
536
|
+
// xAI config - from settings only
|
|
537
|
+
xaiApiKey: normalizeSecret(overrideConfig?.xaiApiKey) || settings.xai?.apiKey,
|
|
538
|
+
xaiBaseUrl: overrideConfig?.xaiBaseUrl || settings.xai?.baseUrl,
|
|
539
|
+
// Kimi config - from settings only
|
|
540
|
+
kimiApiKey: normalizeSecret(overrideConfig?.kimiApiKey) || settings.kimi?.apiKey,
|
|
541
|
+
kimiBaseUrl: overrideConfig?.kimiBaseUrl || settings.kimi?.baseUrl,
|
|
542
|
+
// Custom provider config
|
|
543
|
+
providerApiKey: normalizeSecret(overrideConfig?.providerApiKey) || customConfig?.apiKey,
|
|
544
|
+
providerBaseUrl: overrideConfig?.providerBaseUrl || customConfig?.baseUrl,
|
|
376
545
|
};
|
|
377
546
|
return this.createProviderFromConfig(config);
|
|
378
547
|
}
|
|
@@ -380,6 +549,11 @@ class LLMProviderFactory {
|
|
|
380
549
|
* Create a provider from explicit config
|
|
381
550
|
*/
|
|
382
551
|
static createProviderFromConfig(config) {
|
|
552
|
+
const customEntry = getCustomProviderEntry(config.type);
|
|
553
|
+
if (customEntry) {
|
|
554
|
+
const resolvedType = resolveCustomProviderId(config.type);
|
|
555
|
+
return createCustomProvider(config, customEntry, resolvedType);
|
|
556
|
+
}
|
|
383
557
|
switch (config.type) {
|
|
384
558
|
case 'anthropic':
|
|
385
559
|
return new anthropic_provider_1.AnthropicProvider(config);
|
|
@@ -393,6 +567,14 @@ class LLMProviderFactory {
|
|
|
393
567
|
return new openrouter_provider_1.OpenRouterProvider(config);
|
|
394
568
|
case 'openai':
|
|
395
569
|
return new openai_provider_1.OpenAIProvider(config);
|
|
570
|
+
case 'azure':
|
|
571
|
+
return new azure_openai_provider_1.AzureOpenAIProvider(config);
|
|
572
|
+
case 'groq':
|
|
573
|
+
return new groq_provider_1.GroqProvider(config);
|
|
574
|
+
case 'xai':
|
|
575
|
+
return new xai_provider_1.XAIProvider(config);
|
|
576
|
+
case 'kimi':
|
|
577
|
+
return new kimi_provider_1.KimiProvider(config);
|
|
396
578
|
default:
|
|
397
579
|
throw new Error(`Unknown provider type: ${config.type}`);
|
|
398
580
|
}
|
|
@@ -400,7 +582,12 @@ class LLMProviderFactory {
|
|
|
400
582
|
/**
|
|
401
583
|
* Get the model ID for a provider
|
|
402
584
|
*/
|
|
403
|
-
static getModelId(modelKey, providerType, ollamaModel, geminiModel, openrouterModel, openaiModel) {
|
|
585
|
+
static getModelId(modelKey, providerType, ollamaModel, geminiModel, openrouterModel, openaiModel, azureDeployment, groqModel, xaiModel, kimiModel, customProviders) {
|
|
586
|
+
const customEntry = getCustomProviderEntry(providerType);
|
|
587
|
+
if (customEntry) {
|
|
588
|
+
const customConfig = getCustomProviderConfig(customProviders, providerType);
|
|
589
|
+
return customConfig?.model || customEntry.defaultModel;
|
|
590
|
+
}
|
|
404
591
|
// For Ollama, use the specific Ollama model if provided
|
|
405
592
|
if (providerType === 'ollama') {
|
|
406
593
|
return ollamaModel || 'gpt-oss:20b';
|
|
@@ -417,6 +604,22 @@ class LLMProviderFactory {
|
|
|
417
604
|
if (providerType === 'openai') {
|
|
418
605
|
return openaiModel || 'gpt-4o-mini';
|
|
419
606
|
}
|
|
607
|
+
// For Azure OpenAI, use the deployment name
|
|
608
|
+
if (providerType === 'azure') {
|
|
609
|
+
return azureDeployment || '';
|
|
610
|
+
}
|
|
611
|
+
// For Groq, use the specific model if provided or default
|
|
612
|
+
if (providerType === 'groq') {
|
|
613
|
+
return groqModel || 'llama-3.1-8b-instant';
|
|
614
|
+
}
|
|
615
|
+
// For xAI, use the specific model if provided or default
|
|
616
|
+
if (providerType === 'xai') {
|
|
617
|
+
return xaiModel || 'grok-4-fast-non-reasoning';
|
|
618
|
+
}
|
|
619
|
+
// For Kimi, use the specific model if provided or default
|
|
620
|
+
if (providerType === 'kimi') {
|
|
621
|
+
return kimiModel || 'kimi-k2.5';
|
|
622
|
+
}
|
|
420
623
|
// For other providers, look up in MODELS
|
|
421
624
|
const model = types_1.MODELS[modelKey];
|
|
422
625
|
if (!model) {
|
|
@@ -445,7 +648,7 @@ class LLMProviderFactory {
|
|
|
445
648
|
*/
|
|
446
649
|
static getAvailableProviders() {
|
|
447
650
|
const settings = this.loadSettings();
|
|
448
|
-
|
|
651
|
+
const builtIns = [
|
|
449
652
|
{
|
|
450
653
|
type: 'anthropic',
|
|
451
654
|
name: 'Anthropic API',
|
|
@@ -466,6 +669,28 @@ class LLMProviderFactory {
|
|
|
466
669
|
name: 'OpenAI',
|
|
467
670
|
configured: !!(settings.openai?.apiKey || settings.openai?.accessToken),
|
|
468
671
|
},
|
|
672
|
+
{
|
|
673
|
+
type: 'azure',
|
|
674
|
+
name: 'Azure OpenAI',
|
|
675
|
+
configured: !!(settings.azure?.apiKey
|
|
676
|
+
&& settings.azure?.endpoint
|
|
677
|
+
&& (settings.azure?.deployment || settings.azure?.deployments?.length)),
|
|
678
|
+
},
|
|
679
|
+
{
|
|
680
|
+
type: 'groq',
|
|
681
|
+
name: 'Groq',
|
|
682
|
+
configured: !!settings.groq?.apiKey,
|
|
683
|
+
},
|
|
684
|
+
{
|
|
685
|
+
type: 'xai',
|
|
686
|
+
name: 'xAI (Grok)',
|
|
687
|
+
configured: !!settings.xai?.apiKey,
|
|
688
|
+
},
|
|
689
|
+
{
|
|
690
|
+
type: 'kimi',
|
|
691
|
+
name: 'Kimi',
|
|
692
|
+
configured: !!settings.kimi?.apiKey,
|
|
693
|
+
},
|
|
469
694
|
{
|
|
470
695
|
type: 'bedrock',
|
|
471
696
|
name: 'AWS Bedrock',
|
|
@@ -477,6 +702,15 @@ class LLMProviderFactory {
|
|
|
477
702
|
configured: !!(settings.ollama?.baseUrl || settings.ollama?.model),
|
|
478
703
|
},
|
|
479
704
|
];
|
|
705
|
+
const customProviders = llm_provider_catalog_1.CUSTOM_PROVIDER_CATALOG.map((entry) => {
|
|
706
|
+
const config = getCustomProviderConfig(settings.customProviders, entry.id);
|
|
707
|
+
return {
|
|
708
|
+
type: entry.id,
|
|
709
|
+
name: entry.name,
|
|
710
|
+
configured: isCustomProviderConfigured(entry, config),
|
|
711
|
+
};
|
|
712
|
+
});
|
|
713
|
+
return [...builtIns, ...customProviders];
|
|
480
714
|
}
|
|
481
715
|
/**
|
|
482
716
|
* Get current configuration status
|
|
@@ -645,11 +879,13 @@ class LLMProviderFactory {
|
|
|
645
879
|
/**
|
|
646
880
|
* Fetch available OpenRouter models from the API
|
|
647
881
|
*/
|
|
648
|
-
static async getOpenRouterModels(apiKey) {
|
|
882
|
+
static async getOpenRouterModels(apiKey, baseUrl) {
|
|
649
883
|
const settings = this.loadSettings();
|
|
650
884
|
// Normalize empty strings to undefined
|
|
651
885
|
const normalizedApiKey = apiKey?.trim() || undefined;
|
|
652
886
|
const key = normalizedApiKey || settings.openrouter?.apiKey;
|
|
887
|
+
const normalizedBaseUrl = baseUrl?.trim() || undefined;
|
|
888
|
+
const resolvedBaseUrl = normalizedBaseUrl || settings.openrouter?.baseUrl;
|
|
653
889
|
const defaultModels = [
|
|
654
890
|
{ id: 'anthropic/claude-3.5-sonnet', name: 'Claude 3.5 Sonnet', context_length: 200000 },
|
|
655
891
|
{ id: 'anthropic/claude-3-opus', name: 'Claude 3 Opus', context_length: 200000 },
|
|
@@ -667,6 +903,7 @@ class LLMProviderFactory {
|
|
|
667
903
|
type: 'openrouter',
|
|
668
904
|
model: '',
|
|
669
905
|
openrouterApiKey: key,
|
|
906
|
+
openrouterBaseUrl: resolvedBaseUrl,
|
|
670
907
|
});
|
|
671
908
|
return await provider.getAvailableModels();
|
|
672
909
|
}
|
|
@@ -758,6 +995,100 @@ class LLMProviderFactory {
|
|
|
758
995
|
return defaultModels;
|
|
759
996
|
}
|
|
760
997
|
}
|
|
998
|
+
/**
|
|
999
|
+
* Fetch available Groq models from the API
|
|
1000
|
+
*/
|
|
1001
|
+
static async getGroqModels(apiKey, baseUrl) {
|
|
1002
|
+
const settings = this.loadSettings();
|
|
1003
|
+
const normalizedApiKey = apiKey?.trim() || undefined;
|
|
1004
|
+
const key = normalizedApiKey || settings.groq?.apiKey;
|
|
1005
|
+
const normalizedBaseUrl = baseUrl?.trim() || undefined;
|
|
1006
|
+
const resolvedBaseUrl = normalizedBaseUrl || settings.groq?.baseUrl;
|
|
1007
|
+
const defaultModels = [
|
|
1008
|
+
{ id: 'llama-3.1-8b-instant', name: 'Llama 3.1 8B Instant' },
|
|
1009
|
+
{ id: 'llama-3.3-70b-versatile', name: 'Llama 3.3 70B Versatile' },
|
|
1010
|
+
];
|
|
1011
|
+
if (!key) {
|
|
1012
|
+
return defaultModels;
|
|
1013
|
+
}
|
|
1014
|
+
try {
|
|
1015
|
+
const provider = new groq_provider_1.GroqProvider({
|
|
1016
|
+
type: 'groq',
|
|
1017
|
+
model: '',
|
|
1018
|
+
groqApiKey: key,
|
|
1019
|
+
groqBaseUrl: resolvedBaseUrl,
|
|
1020
|
+
});
|
|
1021
|
+
return await provider.getAvailableModels();
|
|
1022
|
+
}
|
|
1023
|
+
catch (error) {
|
|
1024
|
+
console.error('Failed to fetch Groq models:', error);
|
|
1025
|
+
return defaultModels;
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
/**
|
|
1029
|
+
* Fetch available xAI models from the API
|
|
1030
|
+
*/
|
|
1031
|
+
static async getXAIModels(apiKey, baseUrl) {
|
|
1032
|
+
const settings = this.loadSettings();
|
|
1033
|
+
const normalizedApiKey = apiKey?.trim() || undefined;
|
|
1034
|
+
const key = normalizedApiKey || settings.xai?.apiKey;
|
|
1035
|
+
const normalizedBaseUrl = baseUrl?.trim() || undefined;
|
|
1036
|
+
const resolvedBaseUrl = normalizedBaseUrl || settings.xai?.baseUrl;
|
|
1037
|
+
const defaultModels = [
|
|
1038
|
+
{ id: 'grok-4', name: 'Grok 4' },
|
|
1039
|
+
{ id: 'grok-4-fast-non-reasoning', name: 'Grok 4 Fast (Non-Reasoning)' },
|
|
1040
|
+
{ id: 'grok-4-fast-reasoning', name: 'Grok 4 Fast (Reasoning)' },
|
|
1041
|
+
];
|
|
1042
|
+
if (!key) {
|
|
1043
|
+
return defaultModels;
|
|
1044
|
+
}
|
|
1045
|
+
try {
|
|
1046
|
+
const provider = new xai_provider_1.XAIProvider({
|
|
1047
|
+
type: 'xai',
|
|
1048
|
+
model: '',
|
|
1049
|
+
xaiApiKey: key,
|
|
1050
|
+
xaiBaseUrl: resolvedBaseUrl,
|
|
1051
|
+
});
|
|
1052
|
+
return await provider.getAvailableModels();
|
|
1053
|
+
}
|
|
1054
|
+
catch (error) {
|
|
1055
|
+
console.error('Failed to fetch xAI models:', error);
|
|
1056
|
+
return defaultModels;
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
/**
|
|
1060
|
+
* Fetch available Kimi models from the API
|
|
1061
|
+
*/
|
|
1062
|
+
static async getKimiModels(apiKey, baseUrl) {
|
|
1063
|
+
const settings = this.loadSettings();
|
|
1064
|
+
const normalizedApiKey = apiKey?.trim() || undefined;
|
|
1065
|
+
const key = normalizedApiKey || settings.kimi?.apiKey;
|
|
1066
|
+
const normalizedBaseUrl = baseUrl?.trim() || undefined;
|
|
1067
|
+
const resolvedBaseUrl = normalizedBaseUrl || settings.kimi?.baseUrl;
|
|
1068
|
+
const defaultModels = [
|
|
1069
|
+
{ id: 'kimi-k2.5', name: 'Kimi K2.5' },
|
|
1070
|
+
{ id: 'kimi-k2-0905-preview', name: 'Kimi K2.5 Preview' },
|
|
1071
|
+
{ id: 'kimi-k2-turbo-preview', name: 'Kimi K2 Turbo (Preview)' },
|
|
1072
|
+
{ id: 'kimi-k2-thinking', name: 'Kimi K2 Thinking' },
|
|
1073
|
+
{ id: 'kimi-k2-thinking-turbo', name: 'Kimi K2 Thinking Turbo' },
|
|
1074
|
+
];
|
|
1075
|
+
if (!key) {
|
|
1076
|
+
return defaultModels;
|
|
1077
|
+
}
|
|
1078
|
+
try {
|
|
1079
|
+
const provider = new kimi_provider_1.KimiProvider({
|
|
1080
|
+
type: 'kimi',
|
|
1081
|
+
model: '',
|
|
1082
|
+
kimiApiKey: key,
|
|
1083
|
+
kimiBaseUrl: resolvedBaseUrl,
|
|
1084
|
+
});
|
|
1085
|
+
return await provider.getAvailableModels();
|
|
1086
|
+
}
|
|
1087
|
+
catch (error) {
|
|
1088
|
+
console.error('Failed to fetch Kimi models:', error);
|
|
1089
|
+
return defaultModels;
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
761
1092
|
/**
|
|
762
1093
|
* Format OpenAI model ID to display name
|
|
763
1094
|
*/
|
|
@@ -851,6 +1182,15 @@ class LLMProviderFactory {
|
|
|
851
1182
|
case 'openai':
|
|
852
1183
|
settings.cachedOpenAIModels = models;
|
|
853
1184
|
break;
|
|
1185
|
+
case 'groq':
|
|
1186
|
+
settings.cachedGroqModels = models;
|
|
1187
|
+
break;
|
|
1188
|
+
case 'xai':
|
|
1189
|
+
settings.cachedXaiModels = models;
|
|
1190
|
+
break;
|
|
1191
|
+
case 'kimi':
|
|
1192
|
+
settings.cachedKimiModels = models;
|
|
1193
|
+
break;
|
|
854
1194
|
}
|
|
855
1195
|
this.saveSettings(settings);
|
|
856
1196
|
}
|
|
@@ -870,6 +1210,12 @@ class LLMProviderFactory {
|
|
|
870
1210
|
return settings.cachedBedrockModels;
|
|
871
1211
|
case 'openai':
|
|
872
1212
|
return settings.cachedOpenAIModels;
|
|
1213
|
+
case 'groq':
|
|
1214
|
+
return settings.cachedGroqModels;
|
|
1215
|
+
case 'xai':
|
|
1216
|
+
return settings.cachedXaiModels;
|
|
1217
|
+
case 'kimi':
|
|
1218
|
+
return settings.cachedKimiModels;
|
|
873
1219
|
default:
|
|
874
1220
|
return undefined;
|
|
875
1221
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Allows switching between Anthropic API and AWS Bedrock
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.DEFAULT_MODEL = exports.OLLAMA_MODELS = exports.OPENAI_MODELS = exports.OPENROUTER_MODELS = exports.GEMINI_MODELS = exports.MODELS = void 0;
|
|
7
|
+
exports.DEFAULT_MODEL = exports.OLLAMA_MODELS = exports.KIMI_MODELS = exports.XAI_MODELS = exports.GROQ_MODELS = exports.OPENAI_MODELS = exports.OPENROUTER_MODELS = exports.GEMINI_MODELS = exports.MODELS = void 0;
|
|
8
8
|
/**
|
|
9
9
|
* Available AI models with their IDs for each provider
|
|
10
10
|
* Note: Bedrock uses inference profile IDs (us. prefix) for newer models
|
|
@@ -159,6 +159,71 @@ exports.OPENAI_MODELS = {
|
|
|
159
159
|
description: 'Fast reasoning model',
|
|
160
160
|
},
|
|
161
161
|
};
|
|
162
|
+
/**
|
|
163
|
+
* Popular Groq models
|
|
164
|
+
*/
|
|
165
|
+
exports.GROQ_MODELS = {
|
|
166
|
+
'llama-3.1-8b-instant': {
|
|
167
|
+
id: 'llama-3.1-8b-instant',
|
|
168
|
+
displayName: 'Llama 3.1 8B Instant',
|
|
169
|
+
description: 'Fast, cost-efficient Groq model',
|
|
170
|
+
},
|
|
171
|
+
'llama-3.3-70b-versatile': {
|
|
172
|
+
id: 'llama-3.3-70b-versatile',
|
|
173
|
+
displayName: 'Llama 3.3 70B Versatile',
|
|
174
|
+
description: 'Higher capability Groq model',
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
/**
|
|
178
|
+
* Popular xAI (Grok) models
|
|
179
|
+
*/
|
|
180
|
+
exports.XAI_MODELS = {
|
|
181
|
+
'grok-4': {
|
|
182
|
+
id: 'grok-4',
|
|
183
|
+
displayName: 'Grok 4',
|
|
184
|
+
description: 'Flagship model',
|
|
185
|
+
},
|
|
186
|
+
'grok-4-fast-non-reasoning': {
|
|
187
|
+
id: 'grok-4-fast-non-reasoning',
|
|
188
|
+
displayName: 'Grok 4 Fast (Non-Reasoning)',
|
|
189
|
+
description: 'Fast responses without explicit reasoning',
|
|
190
|
+
},
|
|
191
|
+
'grok-4-fast-reasoning': {
|
|
192
|
+
id: 'grok-4-fast-reasoning',
|
|
193
|
+
displayName: 'Grok 4 Fast (Reasoning)',
|
|
194
|
+
description: 'Faster model with reasoning support',
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
/**
|
|
198
|
+
* Kimi (Moonshot) models
|
|
199
|
+
*/
|
|
200
|
+
exports.KIMI_MODELS = {
|
|
201
|
+
'kimi-k2.5': {
|
|
202
|
+
id: 'kimi-k2.5',
|
|
203
|
+
displayName: 'Kimi K2.5',
|
|
204
|
+
description: 'Latest Kimi K2.5 model',
|
|
205
|
+
},
|
|
206
|
+
'kimi-k2-0905-preview': {
|
|
207
|
+
id: 'kimi-k2-0905-preview',
|
|
208
|
+
displayName: 'Kimi K2.5 Preview',
|
|
209
|
+
description: 'Preview K2.5 model',
|
|
210
|
+
},
|
|
211
|
+
'kimi-k2-turbo-preview': {
|
|
212
|
+
id: 'kimi-k2-turbo-preview',
|
|
213
|
+
displayName: 'Kimi K2 Turbo (Preview)',
|
|
214
|
+
description: 'Faster K2 preview model',
|
|
215
|
+
},
|
|
216
|
+
'kimi-k2-thinking': {
|
|
217
|
+
id: 'kimi-k2-thinking',
|
|
218
|
+
displayName: 'Kimi K2 Thinking',
|
|
219
|
+
description: 'Reasoning-focused K2 model',
|
|
220
|
+
},
|
|
221
|
+
'kimi-k2-thinking-turbo': {
|
|
222
|
+
id: 'kimi-k2-thinking-turbo',
|
|
223
|
+
displayName: 'Kimi K2 Thinking Turbo',
|
|
224
|
+
description: 'Faster reasoning K2 model',
|
|
225
|
+
},
|
|
226
|
+
};
|
|
162
227
|
/**
|
|
163
228
|
* Popular Ollama models with their details
|
|
164
229
|
* Users can use any model available on their Ollama server
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.XAIProvider = void 0;
|
|
4
|
+
const openai_compatible_provider_1 = require("./openai-compatible-provider");
|
|
5
|
+
const XAI_BASE_URL = 'https://api.x.ai/v1';
|
|
6
|
+
const DEFAULT_XAI_MODEL = 'grok-4-fast-non-reasoning';
|
|
7
|
+
class XAIProvider {
|
|
8
|
+
constructor(config) {
|
|
9
|
+
this.type = 'xai';
|
|
10
|
+
const apiKey = config.xaiApiKey;
|
|
11
|
+
if (!apiKey) {
|
|
12
|
+
throw new Error('xAI API key is required. Configure it in Settings.');
|
|
13
|
+
}
|
|
14
|
+
const baseUrl = config.xaiBaseUrl || XAI_BASE_URL;
|
|
15
|
+
this.client = new openai_compatible_provider_1.OpenAICompatibleProvider({
|
|
16
|
+
type: 'xai',
|
|
17
|
+
providerName: 'xAI',
|
|
18
|
+
apiKey,
|
|
19
|
+
baseUrl,
|
|
20
|
+
defaultModel: config.model || DEFAULT_XAI_MODEL,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
createMessage(request) {
|
|
24
|
+
return this.client.createMessage(request);
|
|
25
|
+
}
|
|
26
|
+
testConnection() {
|
|
27
|
+
return this.client.testConnection();
|
|
28
|
+
}
|
|
29
|
+
getAvailableModels() {
|
|
30
|
+
return this.client.getAvailableModels();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.XAIProvider = XAIProvider;
|
|
@@ -52,6 +52,42 @@ const DEFAULT_SETTINGS = {
|
|
|
52
52
|
* Factory for creating Search providers with fallback support
|
|
53
53
|
*/
|
|
54
54
|
class SearchProviderFactory {
|
|
55
|
+
static async sleep(ms) {
|
|
56
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
57
|
+
}
|
|
58
|
+
static isTransientSearchError(error) {
|
|
59
|
+
const message = String(error?.message || '');
|
|
60
|
+
return (/rate limit/i.test(message) ||
|
|
61
|
+
/429/.test(message) ||
|
|
62
|
+
/too many requests/i.test(message) ||
|
|
63
|
+
/timeout/i.test(message) ||
|
|
64
|
+
/ETIMEDOUT/i.test(message) ||
|
|
65
|
+
/ECONNRESET/i.test(message) ||
|
|
66
|
+
/EAI_AGAIN/i.test(message) ||
|
|
67
|
+
/503/.test(message) ||
|
|
68
|
+
/502/.test(message) ||
|
|
69
|
+
/504/.test(message) ||
|
|
70
|
+
/service unavailable/i.test(message));
|
|
71
|
+
}
|
|
72
|
+
static async searchWithRetry(provider, query, maxAttempts = 3) {
|
|
73
|
+
let lastError;
|
|
74
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
75
|
+
try {
|
|
76
|
+
return await provider.search(query);
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
lastError = error;
|
|
80
|
+
if (!this.isTransientSearchError(error) || attempt === maxAttempts) {
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
// Exponential backoff with jitter: ~1s, ~2s, ~4s
|
|
84
|
+
const baseDelay = 1000 * Math.pow(2, attempt - 1);
|
|
85
|
+
const jitter = Math.random() * 500;
|
|
86
|
+
await this.sleep(baseDelay + jitter);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
throw lastError || new Error('Search failed');
|
|
90
|
+
}
|
|
55
91
|
/**
|
|
56
92
|
* Initialize the factory
|
|
57
93
|
*/
|
|
@@ -288,7 +324,7 @@ class SearchProviderFactory {
|
|
|
288
324
|
try {
|
|
289
325
|
const primaryConfig = this.getProviderConfig(primaryType);
|
|
290
326
|
const primaryProvider = this.createProviderFromConfig(primaryConfig);
|
|
291
|
-
return await
|
|
327
|
+
return await this.searchWithRetry(primaryProvider, query);
|
|
292
328
|
}
|
|
293
329
|
catch (primaryError) {
|
|
294
330
|
console.error(`Primary search provider (${primaryType}) failed:`, primaryError.message);
|
|
@@ -303,7 +339,7 @@ class SearchProviderFactory {
|
|
|
303
339
|
try {
|
|
304
340
|
const fallbackConfig = this.getProviderConfig(fallbackType);
|
|
305
341
|
const fallbackProvider = this.createProviderFromConfig(fallbackConfig);
|
|
306
|
-
const response = await
|
|
342
|
+
const response = await this.searchWithRetry(fallbackProvider, query);
|
|
307
343
|
// Indicate this came from fallback
|
|
308
344
|
console.log(`Fallback search with ${fallbackType} succeeded`);
|
|
309
345
|
return response;
|