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
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.LLMProviderFactory = exports.OpenAIOAuth = exports.OpenAIProvider = exports.OpenRouterProvider = exports.GeminiProvider = exports.OllamaProvider = exports.BedrockProvider = exports.AnthropicProvider = void 0;
17
+ exports.LLMProviderFactory = exports.OpenAIOAuth = exports.GitHubCopilotProvider = exports.AnthropicCompatibleProvider = exports.KimiProvider = exports.XAIProvider = exports.GroqProvider = exports.OpenAIProvider = exports.OpenRouterProvider = exports.GeminiProvider = exports.OllamaProvider = exports.BedrockProvider = exports.AnthropicProvider = void 0;
18
18
  __exportStar(require("./types"), exports);
19
19
  var anthropic_provider_1 = require("./anthropic-provider");
20
20
  Object.defineProperty(exports, "AnthropicProvider", { enumerable: true, get: function () { return anthropic_provider_1.AnthropicProvider; } });
@@ -28,6 +28,16 @@ var openrouter_provider_1 = require("./openrouter-provider");
28
28
  Object.defineProperty(exports, "OpenRouterProvider", { enumerable: true, get: function () { return openrouter_provider_1.OpenRouterProvider; } });
29
29
  var openai_provider_1 = require("./openai-provider");
30
30
  Object.defineProperty(exports, "OpenAIProvider", { enumerable: true, get: function () { return openai_provider_1.OpenAIProvider; } });
31
+ var groq_provider_1 = require("./groq-provider");
32
+ Object.defineProperty(exports, "GroqProvider", { enumerable: true, get: function () { return groq_provider_1.GroqProvider; } });
33
+ var xai_provider_1 = require("./xai-provider");
34
+ Object.defineProperty(exports, "XAIProvider", { enumerable: true, get: function () { return xai_provider_1.XAIProvider; } });
35
+ var kimi_provider_1 = require("./kimi-provider");
36
+ Object.defineProperty(exports, "KimiProvider", { enumerable: true, get: function () { return kimi_provider_1.KimiProvider; } });
37
+ var anthropic_compatible_provider_1 = require("./anthropic-compatible-provider");
38
+ Object.defineProperty(exports, "AnthropicCompatibleProvider", { enumerable: true, get: function () { return anthropic_compatible_provider_1.AnthropicCompatibleProvider; } });
39
+ var github_copilot_provider_1 = require("./github-copilot-provider");
40
+ Object.defineProperty(exports, "GitHubCopilotProvider", { enumerable: true, get: function () { return github_copilot_provider_1.GitHubCopilotProvider; } });
31
41
  var openai_oauth_1 = require("./openai-oauth");
32
42
  Object.defineProperty(exports, "OpenAIOAuth", { enumerable: true, get: function () { return openai_oauth_1.OpenAIOAuth; } });
33
43
  var provider_factory_1 = require("./provider-factory");
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KimiProvider = void 0;
4
+ const openai_compatible_provider_1 = require("./openai-compatible-provider");
5
+ const KIMI_BASE_URL = 'https://api.moonshot.ai/v1';
6
+ const DEFAULT_KIMI_MODEL = 'kimi-k2.5';
7
+ class KimiProvider {
8
+ constructor(config) {
9
+ this.type = 'kimi';
10
+ const apiKey = config.kimiApiKey;
11
+ if (!apiKey) {
12
+ throw new Error('Kimi API key is required. Configure it in Settings.');
13
+ }
14
+ const baseUrl = config.kimiBaseUrl || KIMI_BASE_URL;
15
+ this.client = new openai_compatible_provider_1.OpenAICompatibleProvider({
16
+ type: 'kimi',
17
+ providerName: 'Kimi',
18
+ apiKey,
19
+ baseUrl,
20
+ defaultModel: config.model || DEFAULT_KIMI_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.KimiProvider = KimiProvider;
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OpenAICompatibleProvider = void 0;
4
+ const openai_compatible_1 = require("./openai-compatible");
5
+ class OpenAICompatibleProvider {
6
+ constructor(options) {
7
+ this.type = options.type;
8
+ this.apiKey = options.apiKey;
9
+ this.baseUrl = options.baseUrl;
10
+ this.defaultModel = options.defaultModel;
11
+ this.providerName = options.providerName;
12
+ this.extraHeaders = options.extraHeaders;
13
+ }
14
+ async createMessage(request) {
15
+ const messages = (0, openai_compatible_1.toOpenAICompatibleMessages)(request.messages, request.system);
16
+ const tools = request.tools ? (0, openai_compatible_1.toOpenAICompatibleTools)(request.tools) : undefined;
17
+ try {
18
+ const model = request.model || this.defaultModel;
19
+ console.log(`[${this.providerName}] Calling API with model: ${model}`);
20
+ const headers = {
21
+ 'Content-Type': 'application/json',
22
+ ...(this.extraHeaders || {}),
23
+ };
24
+ if (this.apiKey) {
25
+ headers.Authorization = `Bearer ${this.apiKey}`;
26
+ }
27
+ const response = await fetch(`${this.baseUrl}/chat/completions`, {
28
+ method: 'POST',
29
+ headers,
30
+ body: JSON.stringify({
31
+ model,
32
+ messages,
33
+ max_tokens: request.maxTokens,
34
+ ...(tools && { tools, tool_choice: 'auto' }),
35
+ }),
36
+ signal: request.signal,
37
+ });
38
+ if (!response.ok) {
39
+ const errorData = await response.json().catch(() => ({}));
40
+ throw new Error(`${this.providerName} API error: ${response.status} ${response.statusText}` +
41
+ (errorData.error?.message ? ` - ${errorData.error.message}` : ''));
42
+ }
43
+ const data = await response.json();
44
+ return (0, openai_compatible_1.fromOpenAICompatibleResponse)(data);
45
+ }
46
+ catch (error) {
47
+ if (error.name === 'AbortError' || error.message?.includes('aborted')) {
48
+ console.log(`[${this.providerName}] Request aborted`);
49
+ throw new Error('Request cancelled');
50
+ }
51
+ console.error(`[${this.providerName}] API error:`, {
52
+ message: error.message,
53
+ status: error.status,
54
+ });
55
+ throw error;
56
+ }
57
+ }
58
+ async testConnection() {
59
+ try {
60
+ const headers = {
61
+ 'Content-Type': 'application/json',
62
+ ...(this.extraHeaders || {}),
63
+ };
64
+ if (this.apiKey) {
65
+ headers.Authorization = `Bearer ${this.apiKey}`;
66
+ }
67
+ const response = await fetch(`${this.baseUrl}/chat/completions`, {
68
+ method: 'POST',
69
+ headers,
70
+ body: JSON.stringify({
71
+ model: this.defaultModel,
72
+ messages: [{ role: 'user', content: 'Hi' }],
73
+ max_tokens: 10,
74
+ }),
75
+ });
76
+ if (!response.ok) {
77
+ const errorData = await response.json().catch(() => ({}));
78
+ return {
79
+ success: false,
80
+ error: errorData.error?.message || `HTTP ${response.status}: ${response.statusText}`,
81
+ };
82
+ }
83
+ return { success: true };
84
+ }
85
+ catch (error) {
86
+ return {
87
+ success: false,
88
+ error: error.message || `Failed to connect to ${this.providerName} API`,
89
+ };
90
+ }
91
+ }
92
+ async getAvailableModels() {
93
+ try {
94
+ const headers = {};
95
+ if (this.apiKey) {
96
+ headers.Authorization = `Bearer ${this.apiKey}`;
97
+ }
98
+ const response = await fetch(`${this.baseUrl}/models`, {
99
+ headers,
100
+ });
101
+ if (!response.ok) {
102
+ return [];
103
+ }
104
+ const data = await response.json();
105
+ return (data.data || []).map((model) => ({
106
+ id: model.id,
107
+ name: model.id,
108
+ }));
109
+ }
110
+ catch (error) {
111
+ console.error(`[${this.providerName}] Failed to fetch models:`, error);
112
+ return [];
113
+ }
114
+ }
115
+ }
116
+ exports.OpenAICompatibleProvider = OpenAICompatibleProvider;
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toOpenAICompatibleMessages = toOpenAICompatibleMessages;
4
+ exports.toOpenAICompatibleTools = toOpenAICompatibleTools;
5
+ exports.fromOpenAICompatibleResponse = fromOpenAICompatibleResponse;
6
+ exports.mapStopReason = mapStopReason;
7
+ function toOpenAICompatibleMessages(messages, system) {
8
+ const result = [];
9
+ if (system) {
10
+ result.push({ role: 'system', content: system });
11
+ }
12
+ for (const msg of messages) {
13
+ if (typeof msg.content === 'string') {
14
+ result.push({ role: msg.role, content: msg.content });
15
+ continue;
16
+ }
17
+ for (const item of msg.content) {
18
+ if (item.type === 'tool_result') {
19
+ result.push({
20
+ role: 'tool',
21
+ content: item.content,
22
+ tool_call_id: item.tool_use_id,
23
+ });
24
+ }
25
+ else if (item.type === 'tool_use') {
26
+ result.push({
27
+ role: 'assistant',
28
+ content: null,
29
+ tool_calls: [{
30
+ id: item.id,
31
+ type: 'function',
32
+ function: {
33
+ name: item.name,
34
+ arguments: JSON.stringify(item.input),
35
+ },
36
+ }],
37
+ });
38
+ }
39
+ else if (item.type === 'text') {
40
+ result.push({ role: msg.role, content: item.text });
41
+ }
42
+ }
43
+ }
44
+ return result;
45
+ }
46
+ function toOpenAICompatibleTools(tools) {
47
+ return tools.map((tool) => ({
48
+ type: 'function',
49
+ function: {
50
+ name: tool.name,
51
+ description: tool.description,
52
+ parameters: tool.input_schema,
53
+ },
54
+ }));
55
+ }
56
+ function fromOpenAICompatibleResponse(response) {
57
+ const content = [];
58
+ const choice = response.choices?.[0];
59
+ if (!choice) {
60
+ return {
61
+ content: [{ type: 'text', text: '' }],
62
+ stopReason: 'end_turn',
63
+ };
64
+ }
65
+ const message = choice.message;
66
+ if (message?.content) {
67
+ content.push({
68
+ type: 'text',
69
+ text: message.content,
70
+ });
71
+ }
72
+ if (message?.tool_calls) {
73
+ for (const toolCall of message.tool_calls) {
74
+ if (toolCall.type === 'function') {
75
+ content.push({
76
+ type: 'tool_use',
77
+ id: toolCall.id,
78
+ name: toolCall.function.name,
79
+ input: JSON.parse(toolCall.function.arguments || '{}'),
80
+ });
81
+ }
82
+ }
83
+ }
84
+ if (content.length === 0) {
85
+ content.push({ type: 'text', text: '' });
86
+ }
87
+ return {
88
+ content,
89
+ stopReason: mapStopReason(choice.finish_reason),
90
+ usage: response.usage
91
+ ? {
92
+ inputTokens: response.usage.prompt_tokens || 0,
93
+ outputTokens: response.usage.completion_tokens || 0,
94
+ }
95
+ : undefined,
96
+ };
97
+ }
98
+ function mapStopReason(finishReason) {
99
+ switch (finishReason) {
100
+ case 'stop':
101
+ return 'end_turn';
102
+ case 'length':
103
+ return 'max_tokens';
104
+ case 'tool_calls':
105
+ return 'tool_use';
106
+ case 'content_filter':
107
+ return 'stop_sequence';
108
+ default:
109
+ return 'end_turn';
110
+ }
111
+ }
@@ -8,11 +8,12 @@ const pi_ai_1 = require("@mariozechner/pi-ai");
8
8
  * Convert pi-ai OAuthCredentials to our token format
9
9
  */
10
10
  function credentialsToTokens(credentials) {
11
+ const email = typeof credentials.email === 'string' ? credentials.email : undefined;
11
12
  return {
12
13
  access_token: credentials.access,
13
14
  refresh_token: credentials.refresh,
14
15
  expires_at: credentials.expires,
15
- email: credentials.email,
16
+ email,
16
17
  };
17
18
  }
18
19
  /**
@@ -8,12 +8,12 @@ exports.OpenRouterProvider = void 0;
8
8
  class OpenRouterProvider {
9
9
  constructor(config) {
10
10
  this.type = 'openrouter';
11
- this.baseUrl = 'https://openrouter.ai/api/v1';
12
11
  const apiKey = config.openrouterApiKey;
13
12
  if (!apiKey) {
14
13
  throw new Error('OpenRouter API key is required. Configure it in Settings or get one from https://openrouter.ai/keys');
15
14
  }
16
15
  this.apiKey = apiKey;
16
+ this.baseUrl = config.openrouterBaseUrl || 'https://openrouter.ai/api/v1';
17
17
  this.defaultModel = config.model || 'anthropic/claude-3.5-sonnet';
18
18
  }
19
19
  async createMessage(request) {