cowork-os 0.3.21 → 0.3.23

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.
Files changed (170) hide show
  1. package/README.md +293 -6
  2. package/connectors/README.md +20 -0
  3. package/connectors/asana-mcp/README.md +24 -0
  4. package/connectors/asana-mcp/dist/index.js +427 -0
  5. package/connectors/asana-mcp/package.json +15 -0
  6. package/connectors/asana-mcp/src/index.ts +553 -0
  7. package/connectors/asana-mcp/tsconfig.json +13 -0
  8. package/connectors/hubspot-mcp/README.md +35 -0
  9. package/connectors/hubspot-mcp/dist/index.js +454 -0
  10. package/connectors/hubspot-mcp/package.json +15 -0
  11. package/connectors/hubspot-mcp/src/index.ts +562 -0
  12. package/connectors/hubspot-mcp/tsconfig.json +13 -0
  13. package/connectors/jira-mcp/README.md +49 -0
  14. package/connectors/jira-mcp/dist/index.js +588 -0
  15. package/connectors/jira-mcp/package.json +15 -0
  16. package/connectors/jira-mcp/src/index.ts +711 -0
  17. package/connectors/jira-mcp/tsconfig.json +13 -0
  18. package/connectors/linear-mcp/README.md +22 -0
  19. package/connectors/linear-mcp/dist/index.js +402 -0
  20. package/connectors/linear-mcp/package.json +15 -0
  21. package/connectors/linear-mcp/src/index.ts +522 -0
  22. package/connectors/linear-mcp/tsconfig.json +13 -0
  23. package/connectors/okta-mcp/README.md +24 -0
  24. package/connectors/okta-mcp/dist/index.js +411 -0
  25. package/connectors/okta-mcp/package.json +15 -0
  26. package/connectors/okta-mcp/src/index.ts +520 -0
  27. package/connectors/okta-mcp/tsconfig.json +13 -0
  28. package/connectors/salesforce-mcp/README.md +47 -0
  29. package/connectors/salesforce-mcp/dist/index.js +584 -0
  30. package/connectors/salesforce-mcp/package.json +15 -0
  31. package/connectors/salesforce-mcp/src/index.ts +722 -0
  32. package/connectors/salesforce-mcp/tsconfig.json +13 -0
  33. package/connectors/servicenow-mcp/README.md +26 -0
  34. package/connectors/servicenow-mcp/dist/index.js +400 -0
  35. package/connectors/servicenow-mcp/package.json +15 -0
  36. package/connectors/servicenow-mcp/src/index.ts +500 -0
  37. package/connectors/servicenow-mcp/tsconfig.json +13 -0
  38. package/connectors/templates/mcp-connector/README.md +31 -0
  39. package/connectors/templates/mcp-connector/package.json +15 -0
  40. package/connectors/templates/mcp-connector/src/index.ts +330 -0
  41. package/connectors/templates/mcp-connector/tsconfig.json +13 -0
  42. package/connectors/zendesk-mcp/README.md +40 -0
  43. package/connectors/zendesk-mcp/dist/index.js +431 -0
  44. package/connectors/zendesk-mcp/package.json +15 -0
  45. package/connectors/zendesk-mcp/src/index.ts +543 -0
  46. package/connectors/zendesk-mcp/tsconfig.json +13 -0
  47. package/dist/electron/electron/agent/daemon.js +25 -0
  48. package/dist/electron/electron/agent/executor.js +181 -26
  49. package/dist/electron/electron/agent/llm/anthropic-compatible-provider.js +177 -0
  50. package/dist/electron/electron/agent/llm/github-copilot-provider.js +97 -0
  51. package/dist/electron/electron/agent/llm/groq-provider.js +33 -0
  52. package/dist/electron/electron/agent/llm/index.js +11 -1
  53. package/dist/electron/electron/agent/llm/kimi-provider.js +33 -0
  54. package/dist/electron/electron/agent/llm/openai-compatible-provider.js +116 -0
  55. package/dist/electron/electron/agent/llm/openai-compatible.js +111 -0
  56. package/dist/electron/electron/agent/llm/openai-oauth.js +2 -1
  57. package/dist/electron/electron/agent/llm/openrouter-provider.js +1 -1
  58. package/dist/electron/electron/agent/llm/provider-factory.js +318 -4
  59. package/dist/electron/electron/agent/llm/types.js +66 -1
  60. package/dist/electron/electron/agent/llm/xai-provider.js +33 -0
  61. package/dist/electron/electron/agent/tools/box-tools.js +231 -0
  62. package/dist/electron/electron/agent/tools/builtin-settings.js +28 -0
  63. package/dist/electron/electron/agent/tools/dropbox-tools.js +237 -0
  64. package/dist/electron/electron/agent/tools/google-drive-tools.js +227 -0
  65. package/dist/electron/electron/agent/tools/notion-tools.js +312 -0
  66. package/dist/electron/electron/agent/tools/onedrive-tools.js +217 -0
  67. package/dist/electron/electron/agent/tools/registry.js +541 -0
  68. package/dist/electron/electron/agent/tools/sharepoint-tools.js +243 -0
  69. package/dist/electron/electron/agent/tools/shell-tools.js +12 -3
  70. package/dist/electron/electron/agent/tools/x-tools.js +1 -1
  71. package/dist/electron/electron/gateway/index.js +1 -0
  72. package/dist/electron/electron/gateway/router.js +123 -143
  73. package/dist/electron/electron/ipc/canvas-handlers.js +5 -0
  74. package/dist/electron/electron/ipc/handlers.js +627 -158
  75. package/dist/electron/electron/main.js +63 -0
  76. package/dist/electron/electron/mcp/oauth/connector-oauth.js +333 -0
  77. package/dist/electron/electron/mcp/registry/MCPRegistryManager.js +503 -154
  78. package/dist/electron/electron/memory/MemoryService.js +1 -1
  79. package/dist/electron/electron/preload.js +74 -1
  80. package/dist/electron/electron/settings/box-manager.js +54 -0
  81. package/dist/electron/electron/settings/dropbox-manager.js +54 -0
  82. package/dist/electron/electron/settings/google-drive-manager.js +54 -0
  83. package/dist/electron/electron/settings/notion-manager.js +56 -0
  84. package/dist/electron/electron/settings/onedrive-manager.js +54 -0
  85. package/dist/electron/electron/settings/sharepoint-manager.js +54 -0
  86. package/dist/electron/electron/utils/box-api.js +153 -0
  87. package/dist/electron/electron/utils/dropbox-api.js +144 -0
  88. package/dist/electron/electron/utils/env-migration.js +19 -0
  89. package/dist/electron/electron/utils/google-drive-api.js +152 -0
  90. package/dist/electron/electron/utils/notion-api.js +103 -0
  91. package/dist/electron/electron/utils/onedrive-api.js +113 -0
  92. package/dist/electron/electron/utils/sharepoint-api.js +109 -0
  93. package/dist/electron/electron/utils/validation.js +82 -3
  94. package/dist/electron/electron/utils/x-cli.js +1 -1
  95. package/dist/electron/shared/channelMessages.js +284 -3
  96. package/dist/electron/shared/llm-provider-catalog.js +198 -0
  97. package/dist/electron/shared/types.js +88 -1
  98. package/package.json +12 -2
  99. package/src/electron/agent/executor.ts +205 -28
  100. package/src/electron/agent/llm/anthropic-compatible-provider.ts +214 -0
  101. package/src/electron/agent/llm/github-copilot-provider.ts +117 -0
  102. package/src/electron/agent/llm/groq-provider.ts +39 -0
  103. package/src/electron/agent/llm/index.ts +5 -0
  104. package/src/electron/agent/llm/kimi-provider.ts +39 -0
  105. package/src/electron/agent/llm/openai-compatible-provider.ts +153 -0
  106. package/src/electron/agent/llm/openai-compatible.ts +133 -0
  107. package/src/electron/agent/llm/openai-oauth.ts +2 -1
  108. package/src/electron/agent/llm/openrouter-provider.ts +2 -1
  109. package/src/electron/agent/llm/provider-factory.ts +414 -6
  110. package/src/electron/agent/llm/types.ts +90 -1
  111. package/src/electron/agent/llm/xai-provider.ts +39 -0
  112. package/src/electron/agent/tools/box-tools.ts +239 -0
  113. package/src/electron/agent/tools/builtin-settings.ts +34 -0
  114. package/src/electron/agent/tools/dropbox-tools.ts +237 -0
  115. package/src/electron/agent/tools/google-drive-tools.ts +228 -0
  116. package/src/electron/agent/tools/notion-tools.ts +330 -0
  117. package/src/electron/agent/tools/onedrive-tools.ts +217 -0
  118. package/src/electron/agent/tools/registry.ts +565 -0
  119. package/src/electron/agent/tools/sharepoint-tools.ts +247 -0
  120. package/src/electron/agent/tools/shell-tools.ts +11 -3
  121. package/src/electron/agent/tools/x-tools.ts +1 -1
  122. package/src/electron/database/SecureSettingsRepository.ts +7 -1
  123. package/src/electron/gateway/index.ts +1 -0
  124. package/src/electron/gateway/router.ts +134 -149
  125. package/src/electron/ipc/canvas-handlers.ts +10 -0
  126. package/src/electron/ipc/handlers.ts +673 -153
  127. package/src/electron/main.ts +35 -0
  128. package/src/electron/mcp/oauth/connector-oauth.ts +448 -0
  129. package/src/electron/mcp/registry/MCPRegistryManager.ts +343 -12
  130. package/src/electron/memory/MemoryService.ts +5 -1
  131. package/src/electron/preload.ts +167 -4
  132. package/src/electron/settings/box-manager.ts +58 -0
  133. package/src/electron/settings/dropbox-manager.ts +58 -0
  134. package/src/electron/settings/google-drive-manager.ts +58 -0
  135. package/src/electron/settings/notion-manager.ts +60 -0
  136. package/src/electron/settings/onedrive-manager.ts +58 -0
  137. package/src/electron/settings/sharepoint-manager.ts +58 -0
  138. package/src/electron/utils/box-api.ts +184 -0
  139. package/src/electron/utils/dropbox-api.ts +171 -0
  140. package/src/electron/utils/env-migration.ts +22 -0
  141. package/src/electron/utils/google-drive-api.ts +183 -0
  142. package/src/electron/utils/notion-api.ts +126 -0
  143. package/src/electron/utils/onedrive-api.ts +137 -0
  144. package/src/electron/utils/sharepoint-api.ts +132 -0
  145. package/src/electron/utils/validation.ts +102 -1
  146. package/src/electron/utils/x-cli.ts +1 -1
  147. package/src/renderer/App.tsx +20 -2
  148. package/src/renderer/components/BoxSettings.tsx +203 -0
  149. package/src/renderer/components/BrowserView.tsx +101 -0
  150. package/src/renderer/components/BuiltinToolsSettings.tsx +105 -0
  151. package/src/renderer/components/CanvasPreview.tsx +68 -1
  152. package/src/renderer/components/ConnectorEnvModal.tsx +116 -0
  153. package/src/renderer/components/ConnectorSetupModal.tsx +566 -0
  154. package/src/renderer/components/ConnectorsSettings.tsx +397 -0
  155. package/src/renderer/components/DropboxSettings.tsx +202 -0
  156. package/src/renderer/components/GoogleDriveSettings.tsx +201 -0
  157. package/src/renderer/components/MCPSettings.tsx +56 -0
  158. package/src/renderer/components/MainContent.tsx +270 -34
  159. package/src/renderer/components/NotionSettings.tsx +231 -0
  160. package/src/renderer/components/Onboarding/Onboarding.tsx +13 -1
  161. package/src/renderer/components/OnboardingModal.tsx +70 -1
  162. package/src/renderer/components/OneDriveSettings.tsx +212 -0
  163. package/src/renderer/components/Settings.tsx +611 -8
  164. package/src/renderer/components/SharePointSettings.tsx +224 -0
  165. package/src/renderer/components/Sidebar.tsx +25 -9
  166. package/src/renderer/hooks/useOnboardingFlow.ts +21 -0
  167. package/src/renderer/styles/index.css +438 -25
  168. package/src/shared/channelMessages.ts +367 -4
  169. package/src/shared/llm-provider-catalog.ts +217 -0
  170. package/src/shared/types.ts +226 -1
@@ -45,10 +45,86 @@ 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 groq_provider_1 = require("./groq-provider");
49
+ const xai_provider_1 = require("./xai-provider");
50
+ const kimi_provider_1 = require("./kimi-provider");
51
+ const anthropic_compatible_provider_1 = require("./anthropic-compatible-provider");
52
+ const openai_compatible_provider_1 = require("./openai-compatible-provider");
53
+ const github_copilot_provider_1 = require("./github-copilot-provider");
48
54
  const SecureSettingsRepository_1 = require("../../database/SecureSettingsRepository");
55
+ const llm_provider_catalog_1 = require("../../../shared/llm-provider-catalog");
49
56
  const LEGACY_SETTINGS_FILE = 'llm-settings.json';
50
57
  const MASKED_VALUE = '***configured***';
51
58
  const ENCRYPTED_PREFIX = 'encrypted:';
59
+ const CUSTOM_PROVIDER_ALIASES = {
60
+ 'kimi-coding': 'kimi-code',
61
+ };
62
+ function resolveCustomProviderId(providerType) {
63
+ return CUSTOM_PROVIDER_ALIASES[providerType] || providerType;
64
+ }
65
+ function getCustomProviderEntry(providerType) {
66
+ return llm_provider_catalog_1.CUSTOM_PROVIDER_MAP.get(resolveCustomProviderId(providerType));
67
+ }
68
+ function getCustomProviderConfig(customProviders, providerType) {
69
+ if (!customProviders)
70
+ return undefined;
71
+ const resolved = resolveCustomProviderId(providerType);
72
+ const resolvedConfig = customProviders[resolved];
73
+ if (resolvedConfig) {
74
+ return resolvedConfig;
75
+ }
76
+ const fallbackConfig = customProviders[providerType];
77
+ if (fallbackConfig && resolved !== providerType) {
78
+ console.log(`[LLMProviderFactory] Custom provider config not found for "${resolved}", falling back to "${providerType}".`);
79
+ }
80
+ return fallbackConfig;
81
+ }
82
+ function isCustomProviderConfigured(entry, config) {
83
+ if (!config)
84
+ return false;
85
+ const hasApiKey = !!config.apiKey?.trim();
86
+ const hasBaseUrl = !!config.baseUrl?.trim() || !!entry.baseUrl;
87
+ const hasUserConfig = hasApiKey || !!config.baseUrl?.trim() || !!config.model?.trim();
88
+ if (!hasUserConfig)
89
+ return false;
90
+ if (entry.apiKeyOptional) {
91
+ return entry.requiresBaseUrl ? hasBaseUrl : hasApiKey || hasBaseUrl;
92
+ }
93
+ return entry.requiresBaseUrl ? hasApiKey && hasBaseUrl : hasApiKey;
94
+ }
95
+ function createCustomProvider(config, entry, resolvedType) {
96
+ if (resolvedType === 'github-copilot') {
97
+ return new github_copilot_provider_1.GitHubCopilotProvider(config);
98
+ }
99
+ const apiKey = config.providerApiKey || '';
100
+ const baseUrl = config.providerBaseUrl || entry.baseUrl || '';
101
+ if (entry.requiresBaseUrl && !baseUrl) {
102
+ throw new Error(`${entry.name} base URL is required. Configure it in Settings.`);
103
+ }
104
+ if (!apiKey && !entry.apiKeyOptional) {
105
+ throw new Error(`${entry.name} API key is required. Configure it in Settings.`);
106
+ }
107
+ const model = config.model || entry.defaultModel;
108
+ if (!model) {
109
+ throw new Error(`${entry.name} model is required. Configure it in Settings.`);
110
+ }
111
+ if (entry.compatibility === 'openai') {
112
+ return new openai_compatible_provider_1.OpenAICompatibleProvider({
113
+ type: resolvedType,
114
+ providerName: entry.name,
115
+ apiKey,
116
+ baseUrl,
117
+ defaultModel: model,
118
+ });
119
+ }
120
+ return new anthropic_compatible_provider_1.AnthropicCompatibleProvider({
121
+ type: resolvedType,
122
+ providerName: entry.name,
123
+ apiKey,
124
+ baseUrl,
125
+ defaultModel: model,
126
+ });
127
+ }
52
128
  // ============ Legacy Encryption Functions (for migration only) ============
53
129
  // These functions are only used to decrypt settings from legacy JSON files
54
130
  // during migration to the encrypted database. New settings use full-object
@@ -178,6 +254,34 @@ function sanitizeSettings(settings) {
178
254
  refreshToken: decryptedRefreshToken,
179
255
  };
180
256
  }
257
+ if (sanitized.groq) {
258
+ sanitized.groq = {
259
+ ...sanitized.groq,
260
+ apiKey: decryptSecret(sanitized.groq.apiKey),
261
+ };
262
+ }
263
+ if (sanitized.xai) {
264
+ sanitized.xai = {
265
+ ...sanitized.xai,
266
+ apiKey: decryptSecret(sanitized.xai.apiKey),
267
+ };
268
+ }
269
+ if (sanitized.kimi) {
270
+ sanitized.kimi = {
271
+ ...sanitized.kimi,
272
+ apiKey: decryptSecret(sanitized.kimi.apiKey),
273
+ };
274
+ }
275
+ if (sanitized.customProviders) {
276
+ const normalized = {};
277
+ for (const [key, value] of Object.entries(sanitized.customProviders)) {
278
+ normalized[key] = {
279
+ ...value,
280
+ apiKey: decryptSecret(value.apiKey),
281
+ };
282
+ }
283
+ sanitized.customProviders = normalized;
284
+ }
181
285
  return sanitized;
182
286
  }
183
287
  const DEFAULT_SETTINGS = {
@@ -188,6 +292,20 @@ const DEFAULT_SETTINGS = {
188
292
  * Factory for creating LLM providers
189
293
  */
190
294
  class LLMProviderFactory {
295
+ static normalizeCustomProviders(settings) {
296
+ if (!settings.customProviders)
297
+ return;
298
+ const legacyKey = settings.customProviders['kimi-coding'];
299
+ if (legacyKey && !settings.customProviders['kimi-code']) {
300
+ settings.customProviders['kimi-code'] = legacyKey;
301
+ }
302
+ if (settings.customProviders['kimi-coding']) {
303
+ delete settings.customProviders['kimi-coding'];
304
+ }
305
+ if (settings.providerType === 'kimi-coding') {
306
+ settings.providerType = 'kimi-code';
307
+ }
308
+ }
191
309
  /**
192
310
  * Initialize the factory
193
311
  */
@@ -270,6 +388,7 @@ class LLMProviderFactory {
270
388
  const stored = repository.load('llm');
271
389
  if (stored) {
272
390
  settings = { ...DEFAULT_SETTINGS, ...stored };
391
+ this.normalizeCustomProviders(settings);
273
392
  settingsExist = true;
274
393
  }
275
394
  }
@@ -307,12 +426,29 @@ class LLMProviderFactory {
307
426
  if (settings.openai?.apiKey || settings.openai?.accessToken) {
308
427
  return 'openai';
309
428
  }
429
+ if (settings.groq?.apiKey) {
430
+ return 'groq';
431
+ }
432
+ if (settings.xai?.apiKey) {
433
+ return 'xai';
434
+ }
435
+ if (settings.kimi?.apiKey) {
436
+ return 'kimi';
437
+ }
310
438
  if (settings.bedrock?.accessKeyId || settings.bedrock?.profile) {
311
439
  return 'bedrock';
312
440
  }
313
441
  if (settings.ollama?.baseUrl || settings.ollama?.model) {
314
442
  return 'ollama';
315
443
  }
444
+ if (settings.customProviders) {
445
+ for (const entry of llm_provider_catalog_1.CUSTOM_PROVIDER_CATALOG) {
446
+ const config = getCustomProviderConfig(settings.customProviders, entry.id);
447
+ if (isCustomProviderConfigured(entry, config)) {
448
+ return entry.id;
449
+ }
450
+ }
451
+ }
316
452
  // No valid credentials detected - user needs to configure via Settings
317
453
  return null;
318
454
  }
@@ -350,9 +486,10 @@ class LLMProviderFactory {
350
486
  static createProvider(overrideConfig) {
351
487
  const settings = this.loadSettings();
352
488
  const providerType = overrideConfig?.type || settings.providerType;
489
+ const customConfig = getCustomProviderConfig(settings.customProviders, providerType);
353
490
  const config = {
354
491
  type: providerType,
355
- model: this.getModelId(settings.modelKey, providerType, settings.ollama?.model, settings.gemini?.model, settings.openrouter?.model, settings.openai?.model),
492
+ model: this.getModelId(settings.modelKey, providerType, settings.ollama?.model, settings.gemini?.model, settings.openrouter?.model, settings.openai?.model, settings.groq?.model, settings.xai?.model, settings.kimi?.model, settings.customProviders),
356
493
  // Anthropic config - from settings only
357
494
  anthropicApiKey: normalizeSecret(overrideConfig?.anthropicApiKey) || settings.anthropic?.apiKey,
358
495
  // Bedrock config - from settings only
@@ -368,11 +505,24 @@ class LLMProviderFactory {
368
505
  geminiApiKey: normalizeSecret(overrideConfig?.geminiApiKey) || settings.gemini?.apiKey,
369
506
  // OpenRouter config - from settings only
370
507
  openrouterApiKey: normalizeSecret(overrideConfig?.openrouterApiKey) || settings.openrouter?.apiKey,
508
+ openrouterBaseUrl: overrideConfig?.openrouterBaseUrl || settings.openrouter?.baseUrl,
371
509
  // OpenAI config - from settings only
372
510
  openaiApiKey: normalizeSecret(overrideConfig?.openaiApiKey) || settings.openai?.apiKey,
373
511
  openaiAccessToken: normalizeSecret(overrideConfig?.openaiAccessToken) || settings.openai?.accessToken,
374
512
  openaiRefreshToken: settings.openai?.refreshToken,
375
513
  openaiTokenExpiresAt: settings.openai?.tokenExpiresAt,
514
+ // Groq config - from settings only
515
+ groqApiKey: normalizeSecret(overrideConfig?.groqApiKey) || settings.groq?.apiKey,
516
+ groqBaseUrl: overrideConfig?.groqBaseUrl || settings.groq?.baseUrl,
517
+ // xAI config - from settings only
518
+ xaiApiKey: normalizeSecret(overrideConfig?.xaiApiKey) || settings.xai?.apiKey,
519
+ xaiBaseUrl: overrideConfig?.xaiBaseUrl || settings.xai?.baseUrl,
520
+ // Kimi config - from settings only
521
+ kimiApiKey: normalizeSecret(overrideConfig?.kimiApiKey) || settings.kimi?.apiKey,
522
+ kimiBaseUrl: overrideConfig?.kimiBaseUrl || settings.kimi?.baseUrl,
523
+ // Custom provider config
524
+ providerApiKey: normalizeSecret(overrideConfig?.providerApiKey) || customConfig?.apiKey,
525
+ providerBaseUrl: overrideConfig?.providerBaseUrl || customConfig?.baseUrl,
376
526
  };
377
527
  return this.createProviderFromConfig(config);
378
528
  }
@@ -380,6 +530,11 @@ class LLMProviderFactory {
380
530
  * Create a provider from explicit config
381
531
  */
382
532
  static createProviderFromConfig(config) {
533
+ const customEntry = getCustomProviderEntry(config.type);
534
+ if (customEntry) {
535
+ const resolvedType = resolveCustomProviderId(config.type);
536
+ return createCustomProvider(config, customEntry, resolvedType);
537
+ }
383
538
  switch (config.type) {
384
539
  case 'anthropic':
385
540
  return new anthropic_provider_1.AnthropicProvider(config);
@@ -393,6 +548,12 @@ class LLMProviderFactory {
393
548
  return new openrouter_provider_1.OpenRouterProvider(config);
394
549
  case 'openai':
395
550
  return new openai_provider_1.OpenAIProvider(config);
551
+ case 'groq':
552
+ return new groq_provider_1.GroqProvider(config);
553
+ case 'xai':
554
+ return new xai_provider_1.XAIProvider(config);
555
+ case 'kimi':
556
+ return new kimi_provider_1.KimiProvider(config);
396
557
  default:
397
558
  throw new Error(`Unknown provider type: ${config.type}`);
398
559
  }
@@ -400,7 +561,12 @@ class LLMProviderFactory {
400
561
  /**
401
562
  * Get the model ID for a provider
402
563
  */
403
- static getModelId(modelKey, providerType, ollamaModel, geminiModel, openrouterModel, openaiModel) {
564
+ static getModelId(modelKey, providerType, ollamaModel, geminiModel, openrouterModel, openaiModel, groqModel, xaiModel, kimiModel, customProviders) {
565
+ const customEntry = getCustomProviderEntry(providerType);
566
+ if (customEntry) {
567
+ const customConfig = getCustomProviderConfig(customProviders, providerType);
568
+ return customConfig?.model || customEntry.defaultModel;
569
+ }
404
570
  // For Ollama, use the specific Ollama model if provided
405
571
  if (providerType === 'ollama') {
406
572
  return ollamaModel || 'gpt-oss:20b';
@@ -417,6 +583,18 @@ class LLMProviderFactory {
417
583
  if (providerType === 'openai') {
418
584
  return openaiModel || 'gpt-4o-mini';
419
585
  }
586
+ // For Groq, use the specific model if provided or default
587
+ if (providerType === 'groq') {
588
+ return groqModel || 'llama-3.1-8b-instant';
589
+ }
590
+ // For xAI, use the specific model if provided or default
591
+ if (providerType === 'xai') {
592
+ return xaiModel || 'grok-4-fast-non-reasoning';
593
+ }
594
+ // For Kimi, use the specific model if provided or default
595
+ if (providerType === 'kimi') {
596
+ return kimiModel || 'kimi-k2.5';
597
+ }
420
598
  // For other providers, look up in MODELS
421
599
  const model = types_1.MODELS[modelKey];
422
600
  if (!model) {
@@ -445,7 +623,7 @@ class LLMProviderFactory {
445
623
  */
446
624
  static getAvailableProviders() {
447
625
  const settings = this.loadSettings();
448
- return [
626
+ const builtIns = [
449
627
  {
450
628
  type: 'anthropic',
451
629
  name: 'Anthropic API',
@@ -466,6 +644,21 @@ class LLMProviderFactory {
466
644
  name: 'OpenAI',
467
645
  configured: !!(settings.openai?.apiKey || settings.openai?.accessToken),
468
646
  },
647
+ {
648
+ type: 'groq',
649
+ name: 'Groq',
650
+ configured: !!settings.groq?.apiKey,
651
+ },
652
+ {
653
+ type: 'xai',
654
+ name: 'xAI (Grok)',
655
+ configured: !!settings.xai?.apiKey,
656
+ },
657
+ {
658
+ type: 'kimi',
659
+ name: 'Kimi',
660
+ configured: !!settings.kimi?.apiKey,
661
+ },
469
662
  {
470
663
  type: 'bedrock',
471
664
  name: 'AWS Bedrock',
@@ -477,6 +670,15 @@ class LLMProviderFactory {
477
670
  configured: !!(settings.ollama?.baseUrl || settings.ollama?.model),
478
671
  },
479
672
  ];
673
+ const customProviders = llm_provider_catalog_1.CUSTOM_PROVIDER_CATALOG.map((entry) => {
674
+ const config = getCustomProviderConfig(settings.customProviders, entry.id);
675
+ return {
676
+ type: entry.id,
677
+ name: entry.name,
678
+ configured: isCustomProviderConfigured(entry, config),
679
+ };
680
+ });
681
+ return [...builtIns, ...customProviders];
480
682
  }
481
683
  /**
482
684
  * Get current configuration status
@@ -645,11 +847,13 @@ class LLMProviderFactory {
645
847
  /**
646
848
  * Fetch available OpenRouter models from the API
647
849
  */
648
- static async getOpenRouterModels(apiKey) {
850
+ static async getOpenRouterModels(apiKey, baseUrl) {
649
851
  const settings = this.loadSettings();
650
852
  // Normalize empty strings to undefined
651
853
  const normalizedApiKey = apiKey?.trim() || undefined;
652
854
  const key = normalizedApiKey || settings.openrouter?.apiKey;
855
+ const normalizedBaseUrl = baseUrl?.trim() || undefined;
856
+ const resolvedBaseUrl = normalizedBaseUrl || settings.openrouter?.baseUrl;
653
857
  const defaultModels = [
654
858
  { id: 'anthropic/claude-3.5-sonnet', name: 'Claude 3.5 Sonnet', context_length: 200000 },
655
859
  { id: 'anthropic/claude-3-opus', name: 'Claude 3 Opus', context_length: 200000 },
@@ -667,6 +871,7 @@ class LLMProviderFactory {
667
871
  type: 'openrouter',
668
872
  model: '',
669
873
  openrouterApiKey: key,
874
+ openrouterBaseUrl: resolvedBaseUrl,
670
875
  });
671
876
  return await provider.getAvailableModels();
672
877
  }
@@ -758,6 +963,100 @@ class LLMProviderFactory {
758
963
  return defaultModels;
759
964
  }
760
965
  }
966
+ /**
967
+ * Fetch available Groq models from the API
968
+ */
969
+ static async getGroqModels(apiKey, baseUrl) {
970
+ const settings = this.loadSettings();
971
+ const normalizedApiKey = apiKey?.trim() || undefined;
972
+ const key = normalizedApiKey || settings.groq?.apiKey;
973
+ const normalizedBaseUrl = baseUrl?.trim() || undefined;
974
+ const resolvedBaseUrl = normalizedBaseUrl || settings.groq?.baseUrl;
975
+ const defaultModels = [
976
+ { id: 'llama-3.1-8b-instant', name: 'Llama 3.1 8B Instant' },
977
+ { id: 'llama-3.3-70b-versatile', name: 'Llama 3.3 70B Versatile' },
978
+ ];
979
+ if (!key) {
980
+ return defaultModels;
981
+ }
982
+ try {
983
+ const provider = new groq_provider_1.GroqProvider({
984
+ type: 'groq',
985
+ model: '',
986
+ groqApiKey: key,
987
+ groqBaseUrl: resolvedBaseUrl,
988
+ });
989
+ return await provider.getAvailableModels();
990
+ }
991
+ catch (error) {
992
+ console.error('Failed to fetch Groq models:', error);
993
+ return defaultModels;
994
+ }
995
+ }
996
+ /**
997
+ * Fetch available xAI models from the API
998
+ */
999
+ static async getXAIModels(apiKey, baseUrl) {
1000
+ const settings = this.loadSettings();
1001
+ const normalizedApiKey = apiKey?.trim() || undefined;
1002
+ const key = normalizedApiKey || settings.xai?.apiKey;
1003
+ const normalizedBaseUrl = baseUrl?.trim() || undefined;
1004
+ const resolvedBaseUrl = normalizedBaseUrl || settings.xai?.baseUrl;
1005
+ const defaultModels = [
1006
+ { id: 'grok-4', name: 'Grok 4' },
1007
+ { id: 'grok-4-fast-non-reasoning', name: 'Grok 4 Fast (Non-Reasoning)' },
1008
+ { id: 'grok-4-fast-reasoning', name: 'Grok 4 Fast (Reasoning)' },
1009
+ ];
1010
+ if (!key) {
1011
+ return defaultModels;
1012
+ }
1013
+ try {
1014
+ const provider = new xai_provider_1.XAIProvider({
1015
+ type: 'xai',
1016
+ model: '',
1017
+ xaiApiKey: key,
1018
+ xaiBaseUrl: resolvedBaseUrl,
1019
+ });
1020
+ return await provider.getAvailableModels();
1021
+ }
1022
+ catch (error) {
1023
+ console.error('Failed to fetch xAI models:', error);
1024
+ return defaultModels;
1025
+ }
1026
+ }
1027
+ /**
1028
+ * Fetch available Kimi models from the API
1029
+ */
1030
+ static async getKimiModels(apiKey, baseUrl) {
1031
+ const settings = this.loadSettings();
1032
+ const normalizedApiKey = apiKey?.trim() || undefined;
1033
+ const key = normalizedApiKey || settings.kimi?.apiKey;
1034
+ const normalizedBaseUrl = baseUrl?.trim() || undefined;
1035
+ const resolvedBaseUrl = normalizedBaseUrl || settings.kimi?.baseUrl;
1036
+ const defaultModels = [
1037
+ { id: 'kimi-k2.5', name: 'Kimi K2.5' },
1038
+ { id: 'kimi-k2-0905-preview', name: 'Kimi K2.5 Preview' },
1039
+ { id: 'kimi-k2-turbo-preview', name: 'Kimi K2 Turbo (Preview)' },
1040
+ { id: 'kimi-k2-thinking', name: 'Kimi K2 Thinking' },
1041
+ { id: 'kimi-k2-thinking-turbo', name: 'Kimi K2 Thinking Turbo' },
1042
+ ];
1043
+ if (!key) {
1044
+ return defaultModels;
1045
+ }
1046
+ try {
1047
+ const provider = new kimi_provider_1.KimiProvider({
1048
+ type: 'kimi',
1049
+ model: '',
1050
+ kimiApiKey: key,
1051
+ kimiBaseUrl: resolvedBaseUrl,
1052
+ });
1053
+ return await provider.getAvailableModels();
1054
+ }
1055
+ catch (error) {
1056
+ console.error('Failed to fetch Kimi models:', error);
1057
+ return defaultModels;
1058
+ }
1059
+ }
761
1060
  /**
762
1061
  * Format OpenAI model ID to display name
763
1062
  */
@@ -851,6 +1150,15 @@ class LLMProviderFactory {
851
1150
  case 'openai':
852
1151
  settings.cachedOpenAIModels = models;
853
1152
  break;
1153
+ case 'groq':
1154
+ settings.cachedGroqModels = models;
1155
+ break;
1156
+ case 'xai':
1157
+ settings.cachedXaiModels = models;
1158
+ break;
1159
+ case 'kimi':
1160
+ settings.cachedKimiModels = models;
1161
+ break;
854
1162
  }
855
1163
  this.saveSettings(settings);
856
1164
  }
@@ -870,6 +1178,12 @@ class LLMProviderFactory {
870
1178
  return settings.cachedBedrockModels;
871
1179
  case 'openai':
872
1180
  return settings.cachedOpenAIModels;
1181
+ case 'groq':
1182
+ return settings.cachedGroqModels;
1183
+ case 'xai':
1184
+ return settings.cachedXaiModels;
1185
+ case 'kimi':
1186
+ return settings.cachedKimiModels;
873
1187
  default:
874
1188
  return undefined;
875
1189
  }
@@ -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;