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.
- package/README.md +293 -6
- 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/daemon.js +25 -0
- package/dist/electron/electron/agent/executor.js +181 -26
- package/dist/electron/electron/agent/llm/anthropic-compatible-provider.js +177 -0
- 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 +11 -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 +318 -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/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/google-drive-tools.js +227 -0
- 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 +541 -0
- 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/gateway/index.js +1 -0
- package/dist/electron/electron/gateway/router.js +123 -143
- package/dist/electron/electron/ipc/canvas-handlers.js +5 -0
- package/dist/electron/electron/ipc/handlers.js +627 -158
- 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 +1 -1
- package/dist/electron/electron/preload.js +74 -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 +82 -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 +88 -1
- package/package.json +12 -2
- package/src/electron/agent/executor.ts +205 -28
- package/src/electron/agent/llm/anthropic-compatible-provider.ts +214 -0
- 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 +5 -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 +414 -6
- package/src/electron/agent/llm/types.ts +90 -1
- package/src/electron/agent/llm/xai-provider.ts +39 -0
- package/src/electron/agent/tools/box-tools.ts +239 -0
- package/src/electron/agent/tools/builtin-settings.ts +34 -0
- package/src/electron/agent/tools/dropbox-tools.ts +237 -0
- package/src/electron/agent/tools/google-drive-tools.ts +228 -0
- 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 +565 -0
- 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/database/SecureSettingsRepository.ts +7 -1
- package/src/electron/gateway/index.ts +1 -0
- package/src/electron/gateway/router.ts +134 -149
- package/src/electron/ipc/canvas-handlers.ts +10 -0
- package/src/electron/ipc/handlers.ts +673 -153
- 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 +5 -1
- package/src/electron/preload.ts +167 -4
- package/src/electron/settings/box-manager.ts +58 -0
- package/src/electron/settings/dropbox-manager.ts +58 -0
- package/src/electron/settings/google-drive-manager.ts +58 -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/google-drive-api.ts +183 -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 +102 -1
- package/src/electron/utils/x-cli.ts +1 -1
- package/src/renderer/App.tsx +20 -2
- 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/DropboxSettings.tsx +202 -0
- package/src/renderer/components/GoogleDriveSettings.tsx +201 -0
- package/src/renderer/components/MCPSettings.tsx +56 -0
- package/src/renderer/components/MainContent.tsx +270 -34
- 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/Settings.tsx +611 -8
- package/src/renderer/components/SharePointSettings.tsx +224 -0
- package/src/renderer/components/Sidebar.tsx +25 -9
- package/src/renderer/hooks/useOnboardingFlow.ts +21 -0
- package/src/renderer/styles/index.css +438 -25
- package/src/shared/channelMessages.ts +367 -4
- package/src/shared/llm-provider-catalog.ts +217 -0
- package/src/shared/types.ts +226 -1
|
@@ -44,6 +44,7 @@ const path = __importStar(require("path"));
|
|
|
44
44
|
const fs = __importStar(require("fs/promises"));
|
|
45
45
|
const fsSync = __importStar(require("fs"));
|
|
46
46
|
const mammoth_1 = __importDefault(require("mammoth"));
|
|
47
|
+
const mime_types_1 = __importDefault(require("mime-types"));
|
|
47
48
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
48
49
|
const pdfParseModule = require('pdf-parse');
|
|
49
50
|
// Handle both ESM default export and CommonJS module.exports
|
|
@@ -57,6 +58,7 @@ const TaskLabelRepository_1 = require("../database/TaskLabelRepository");
|
|
|
57
58
|
const WorkingStateRepository_1 = require("../agents/WorkingStateRepository");
|
|
58
59
|
const context_policy_1 = require("../gateway/context-policy");
|
|
59
60
|
const types_1 = require("../../shared/types");
|
|
61
|
+
const llm_provider_catalog_1 = require("../../shared/llm-provider-catalog");
|
|
60
62
|
const os = __importStar(require("os"));
|
|
61
63
|
const llm_1 = require("../agent/llm");
|
|
62
64
|
const search_1 = require("../agent/search");
|
|
@@ -66,6 +68,19 @@ const validation_1 = require("../utils/validation");
|
|
|
66
68
|
const guardrail_manager_1 = require("../guardrails/guardrail-manager");
|
|
67
69
|
const appearance_manager_1 = require("../settings/appearance-manager");
|
|
68
70
|
const personality_manager_1 = require("../settings/personality-manager");
|
|
71
|
+
const notion_manager_1 = require("../settings/notion-manager");
|
|
72
|
+
const notion_api_1 = require("../utils/notion-api");
|
|
73
|
+
const box_manager_1 = require("../settings/box-manager");
|
|
74
|
+
const onedrive_manager_1 = require("../settings/onedrive-manager");
|
|
75
|
+
const google_drive_manager_1 = require("../settings/google-drive-manager");
|
|
76
|
+
const dropbox_manager_1 = require("../settings/dropbox-manager");
|
|
77
|
+
const sharepoint_manager_1 = require("../settings/sharepoint-manager");
|
|
78
|
+
const box_api_1 = require("../utils/box-api");
|
|
79
|
+
const onedrive_api_1 = require("../utils/onedrive-api");
|
|
80
|
+
const google_drive_api_1 = require("../utils/google-drive-api");
|
|
81
|
+
const dropbox_api_1 = require("../utils/dropbox-api");
|
|
82
|
+
const sharepoint_api_1 = require("../utils/sharepoint-api");
|
|
83
|
+
const connector_oauth_1 = require("../mcp/oauth/connector-oauth");
|
|
69
84
|
const normalizeMentionToken = (value) => value.toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
70
85
|
const buildAgentMentionIndex = (roles) => {
|
|
71
86
|
const index = new Map();
|
|
@@ -124,7 +139,8 @@ const scoreAgentForTask = (role, text) => {
|
|
|
124
139
|
}
|
|
125
140
|
return score;
|
|
126
141
|
};
|
|
127
|
-
const
|
|
142
|
+
const MAX_AUTO_AGENTS = 4;
|
|
143
|
+
const selectBestAgentsForTask = (text, roles, maxAgents = MAX_AUTO_AGENTS) => {
|
|
128
144
|
if (roles.length === 0)
|
|
129
145
|
return roles;
|
|
130
146
|
const scored = roles
|
|
@@ -140,24 +156,23 @@ const selectBestAgentsForTask = (text, roles) => {
|
|
|
140
156
|
const threshold = Math.max(1, maxScore - 2);
|
|
141
157
|
const selected = withScore
|
|
142
158
|
.filter((entry) => entry.score >= threshold)
|
|
143
|
-
.slice(0,
|
|
159
|
+
.slice(0, maxAgents)
|
|
144
160
|
.map((entry) => entry.role);
|
|
145
|
-
return selected.length > 0 ? selected : withScore.slice(0,
|
|
161
|
+
return selected.length > 0 ? selected : withScore.slice(0, maxAgents).map((entry) => entry.role);
|
|
146
162
|
}
|
|
147
163
|
const leads = roles
|
|
148
164
|
.filter((role) => role.autonomyLevel === 'lead')
|
|
149
165
|
.sort((a, b) => (a.sortOrder ?? 0) - (b.sortOrder ?? 0));
|
|
150
166
|
if (leads.length > 0) {
|
|
151
|
-
return leads.slice(0,
|
|
167
|
+
return leads.slice(0, maxAgents);
|
|
152
168
|
}
|
|
153
|
-
return roles.slice(0, Math.min(
|
|
169
|
+
return roles.slice(0, Math.min(maxAgents, roles.length));
|
|
154
170
|
};
|
|
155
171
|
const extractMentionedRoles = (text, roles) => {
|
|
156
172
|
const normalizedText = text.toLowerCase();
|
|
157
|
-
const useSmartSelection = /\B@everybody\b/.test(normalizedText)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
173
|
+
const useSmartSelection = /\B@everybody\b/.test(normalizedText) ||
|
|
174
|
+
/\B@all\b/.test(normalizedText) ||
|
|
175
|
+
/\B@everyone\b/.test(normalizedText);
|
|
161
176
|
const index = buildAgentMentionIndex(roles);
|
|
162
177
|
const matches = new Map();
|
|
163
178
|
const regex = /@([a-zA-Z0-9][a-zA-Z0-9 _-]{0,50})/g;
|
|
@@ -172,11 +187,15 @@ const extractMentionedRoles = (text, roles) => {
|
|
|
172
187
|
}
|
|
173
188
|
if (matches.size > 0) {
|
|
174
189
|
if (useSmartSelection) {
|
|
175
|
-
const selected = selectBestAgentsForTask(text, roles);
|
|
176
190
|
const merged = new Map();
|
|
177
|
-
selected.forEach((role) => merged.set(role.id, role));
|
|
178
191
|
matches.forEach((role) => merged.set(role.id, role));
|
|
179
|
-
|
|
192
|
+
const selected = selectBestAgentsForTask(text, roles, MAX_AUTO_AGENTS);
|
|
193
|
+
selected.forEach((role) => {
|
|
194
|
+
if (merged.size < MAX_AUTO_AGENTS) {
|
|
195
|
+
merged.set(role.id, role);
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
return Array.from(merged.values()).slice(0, MAX_AUTO_AGENTS);
|
|
180
199
|
}
|
|
181
200
|
return Array.from(matches.values());
|
|
182
201
|
}
|
|
@@ -189,7 +208,7 @@ const extractMentionedRoles = (text, roles) => {
|
|
|
189
208
|
}
|
|
190
209
|
});
|
|
191
210
|
if (useSmartSelection) {
|
|
192
|
-
return selectBestAgentsForTask(text, roles);
|
|
211
|
+
return selectBestAgentsForTask(text, roles, MAX_AUTO_AGENTS);
|
|
193
212
|
}
|
|
194
213
|
return Array.from(matches.values());
|
|
195
214
|
};
|
|
@@ -263,6 +282,7 @@ const voice_settings_manager_1 = require("../voice/voice-settings-manager");
|
|
|
263
282
|
const VoiceService_1 = require("../voice/VoiceService");
|
|
264
283
|
// Global notification service instance
|
|
265
284
|
let notificationService = null;
|
|
285
|
+
const resolveCustomProviderId = (providerType) => providerType === 'kimi-coding' ? 'kimi-code' : providerType;
|
|
266
286
|
/**
|
|
267
287
|
* Get the notification service instance
|
|
268
288
|
*/
|
|
@@ -286,6 +306,9 @@ rate_limiter_1.rateLimiter.configure(types_1.IPC_CHANNELS.LLM_GET_OLLAMA_MODELS,
|
|
|
286
306
|
rate_limiter_1.rateLimiter.configure(types_1.IPC_CHANNELS.LLM_GET_GEMINI_MODELS, rate_limiter_1.RATE_LIMIT_CONFIGS.standard);
|
|
287
307
|
rate_limiter_1.rateLimiter.configure(types_1.IPC_CHANNELS.LLM_GET_OPENROUTER_MODELS, rate_limiter_1.RATE_LIMIT_CONFIGS.standard);
|
|
288
308
|
rate_limiter_1.rateLimiter.configure(types_1.IPC_CHANNELS.LLM_GET_BEDROCK_MODELS, rate_limiter_1.RATE_LIMIT_CONFIGS.standard);
|
|
309
|
+
rate_limiter_1.rateLimiter.configure(types_1.IPC_CHANNELS.LLM_GET_GROQ_MODELS, rate_limiter_1.RATE_LIMIT_CONFIGS.standard);
|
|
310
|
+
rate_limiter_1.rateLimiter.configure(types_1.IPC_CHANNELS.LLM_GET_XAI_MODELS, rate_limiter_1.RATE_LIMIT_CONFIGS.standard);
|
|
311
|
+
rate_limiter_1.rateLimiter.configure(types_1.IPC_CHANNELS.LLM_GET_KIMI_MODELS, rate_limiter_1.RATE_LIMIT_CONFIGS.standard);
|
|
289
312
|
rate_limiter_1.rateLimiter.configure(types_1.IPC_CHANNELS.SEARCH_SAVE_SETTINGS, rate_limiter_1.RATE_LIMIT_CONFIGS.limited);
|
|
290
313
|
rate_limiter_1.rateLimiter.configure(types_1.IPC_CHANNELS.SEARCH_TEST_PROVIDER, rate_limiter_1.RATE_LIMIT_CONFIGS.expensive);
|
|
291
314
|
rate_limiter_1.rateLimiter.configure(types_1.IPC_CHANNELS.GATEWAY_ADD_CHANNEL, rate_limiter_1.RATE_LIMIT_CONFIGS.limited);
|
|
@@ -543,6 +566,76 @@ async function setupIpcHandlers(dbManager, agentDaemon, gateway) {
|
|
|
543
566
|
return { success: false, error: `Failed to read file: ${error.message}` };
|
|
544
567
|
}
|
|
545
568
|
});
|
|
569
|
+
// File import handler - copy selected files into the workspace for attachment use
|
|
570
|
+
electron_1.ipcMain.handle('file:importToWorkspace', async (_, data) => {
|
|
571
|
+
const validated = (0, validation_1.validateInput)(validation_1.FileImportSchema, data, 'file import');
|
|
572
|
+
const workspace = workspaceRepo.findById(validated.workspaceId);
|
|
573
|
+
if (!workspace) {
|
|
574
|
+
throw new Error(`Workspace not found: ${validated.workspaceId}`);
|
|
575
|
+
}
|
|
576
|
+
if (!workspace.permissions.write) {
|
|
577
|
+
throw new Error('Write permission not granted for workspace');
|
|
578
|
+
}
|
|
579
|
+
const sanitizeFileName = (fileName) => {
|
|
580
|
+
const sanitized = fileName.replace(/[<>:"/\\|?*\x00-\x1F]/g, '_').trim();
|
|
581
|
+
return sanitized.length > 0 ? sanitized : 'file';
|
|
582
|
+
};
|
|
583
|
+
const ensureUniqueName = (dir, baseName, usedNames) => {
|
|
584
|
+
const ext = path.extname(baseName);
|
|
585
|
+
const stem = path.basename(baseName, ext);
|
|
586
|
+
let candidate = baseName;
|
|
587
|
+
let counter = 1;
|
|
588
|
+
while (usedNames.has(candidate) || fsSync.existsSync(path.join(dir, candidate))) {
|
|
589
|
+
candidate = `${stem}-${counter}${ext}`;
|
|
590
|
+
counter += 1;
|
|
591
|
+
}
|
|
592
|
+
usedNames.add(candidate);
|
|
593
|
+
return candidate;
|
|
594
|
+
};
|
|
595
|
+
let uploadRoot = null;
|
|
596
|
+
const usedNames = new Set();
|
|
597
|
+
const ensureUploadRoot = async () => {
|
|
598
|
+
if (uploadRoot)
|
|
599
|
+
return uploadRoot;
|
|
600
|
+
uploadRoot = path.join(workspace.path, '.cowork', 'uploads', `${Date.now()}`);
|
|
601
|
+
await fs.mkdir(uploadRoot, { recursive: true });
|
|
602
|
+
return uploadRoot;
|
|
603
|
+
};
|
|
604
|
+
const results = [];
|
|
605
|
+
for (const filePath of validated.files) {
|
|
606
|
+
const absolutePath = path.isAbsolute(filePath) ? filePath : path.resolve(filePath);
|
|
607
|
+
const stats = await fs.stat(absolutePath);
|
|
608
|
+
if (!stats.isFile()) {
|
|
609
|
+
throw new Error(`Not a file: ${filePath}`);
|
|
610
|
+
}
|
|
611
|
+
const sizeCheck = guardrail_manager_1.GuardrailManager.isFileSizeExceeded(stats.size);
|
|
612
|
+
if (sizeCheck.exceeded) {
|
|
613
|
+
throw new Error(`File "${path.basename(filePath)}" is ${sizeCheck.sizeMB.toFixed(1)}MB and exceeds the ${sizeCheck.limitMB}MB limit.`);
|
|
614
|
+
}
|
|
615
|
+
const mimeType = (mime_types_1.default.lookup(absolutePath) || undefined);
|
|
616
|
+
if (isPathWithinWorkspace(absolutePath, workspace.path)) {
|
|
617
|
+
results.push({
|
|
618
|
+
relativePath: path.relative(workspace.path, absolutePath),
|
|
619
|
+
fileName: path.basename(absolutePath),
|
|
620
|
+
size: stats.size,
|
|
621
|
+
mimeType,
|
|
622
|
+
});
|
|
623
|
+
continue;
|
|
624
|
+
}
|
|
625
|
+
const safeName = sanitizeFileName(path.basename(absolutePath));
|
|
626
|
+
const targetRoot = await ensureUploadRoot();
|
|
627
|
+
const uniqueName = ensureUniqueName(targetRoot, safeName, usedNames);
|
|
628
|
+
const destination = path.join(targetRoot, uniqueName);
|
|
629
|
+
await fs.copyFile(absolutePath, destination);
|
|
630
|
+
results.push({
|
|
631
|
+
relativePath: path.relative(workspace.path, destination),
|
|
632
|
+
fileName: uniqueName,
|
|
633
|
+
size: stats.size,
|
|
634
|
+
mimeType,
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
return results;
|
|
638
|
+
});
|
|
546
639
|
// Workspace handlers
|
|
547
640
|
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.WORKSPACE_CREATE, async (_, data) => {
|
|
548
641
|
const validated = (0, validation_1.validateInput)(validation_1.WorkspaceCreateSchema, data, 'workspace');
|
|
@@ -612,12 +705,14 @@ async function setupIpcHandlers(dbManager, agentDaemon, gateway) {
|
|
|
612
705
|
try {
|
|
613
706
|
const activeRoles = agentRoleRepo.findAll(false).filter((role) => role.isActive);
|
|
614
707
|
const mentionedRoles = extractMentionedRoles(`${title}\n${prompt}`, activeRoles);
|
|
615
|
-
const dispatchRoles = mentionedRoles
|
|
708
|
+
const dispatchRoles = mentionedRoles;
|
|
616
709
|
if (dispatchRoles.length > 0) {
|
|
617
|
-
|
|
710
|
+
const taskUpdate = {
|
|
618
711
|
mentionedAgentRoleIds: dispatchRoles.map((role) => role.id),
|
|
619
|
-
}
|
|
620
|
-
|
|
712
|
+
};
|
|
713
|
+
taskRepo.update(task.id, taskUpdate);
|
|
714
|
+
// Parallelize child task creation for better performance
|
|
715
|
+
const dispatchPromises = dispatchRoles.map(async (role) => {
|
|
621
716
|
const childPrompt = buildAgentDispatchPrompt(role, task);
|
|
622
717
|
const childTask = await agentDaemon.createChildTask({
|
|
623
718
|
title: `@${role.displayName}: ${task.title}`,
|
|
@@ -631,10 +726,11 @@ async function setupIpcHandlers(dbManager, agentDaemon, gateway) {
|
|
|
631
726
|
retainMemory: false,
|
|
632
727
|
},
|
|
633
728
|
});
|
|
634
|
-
|
|
729
|
+
const childUpdate = {
|
|
635
730
|
assignedAgentRoleId: role.id,
|
|
636
731
|
boardColumn: 'todo',
|
|
637
|
-
}
|
|
732
|
+
};
|
|
733
|
+
taskRepo.update(childTask.id, childUpdate);
|
|
638
734
|
const dispatchActivity = activityRepo.create({
|
|
639
735
|
workspaceId: task.workspaceId,
|
|
640
736
|
taskId: task.id,
|
|
@@ -664,11 +760,24 @@ async function setupIpcHandlers(dbManager, agentDaemon, gateway) {
|
|
|
664
760
|
metadata: { mentionId: mention.id, mentionType: mention.mentionType },
|
|
665
761
|
});
|
|
666
762
|
getMainWindow()?.webContents.send(types_1.IPC_CHANNELS.ACTIVITY_EVENT, { type: 'created', activity: mentionActivity });
|
|
667
|
-
|
|
763
|
+
return { role, childTask };
|
|
764
|
+
});
|
|
765
|
+
await Promise.all(dispatchPromises);
|
|
668
766
|
}
|
|
669
767
|
}
|
|
670
768
|
catch (error) {
|
|
769
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
671
770
|
console.error('Failed to dispatch to mentioned agents:', error);
|
|
771
|
+
// Notify user of dispatch failure via activity feed
|
|
772
|
+
const errorActivity = activityRepo.create({
|
|
773
|
+
workspaceId: task.workspaceId,
|
|
774
|
+
taskId: task.id,
|
|
775
|
+
actorType: 'system',
|
|
776
|
+
activityType: 'error',
|
|
777
|
+
title: 'Agent dispatch failed',
|
|
778
|
+
description: `Failed to dispatch task to mentioned agents: ${errorMessage}`,
|
|
779
|
+
});
|
|
780
|
+
getMainWindow()?.webContents.send(types_1.IPC_CHANNELS.ACTIVITY_EVENT, { type: 'created', activity: errorActivity });
|
|
672
781
|
}
|
|
673
782
|
return task;
|
|
674
783
|
});
|
|
@@ -881,12 +990,19 @@ async function setupIpcHandlers(dbManager, agentDaemon, gateway) {
|
|
|
881
990
|
gemini: validated.gemini,
|
|
882
991
|
openrouter: validated.openrouter,
|
|
883
992
|
openai: openaiSettings,
|
|
993
|
+
groq: validated.groq,
|
|
994
|
+
xai: validated.xai,
|
|
995
|
+
kimi: validated.kimi,
|
|
996
|
+
customProviders: validated.customProviders ?? existingSettings.customProviders,
|
|
884
997
|
// Preserve cached models from existing settings
|
|
885
998
|
cachedGeminiModels: existingSettings.cachedGeminiModels,
|
|
886
999
|
cachedOpenRouterModels: existingSettings.cachedOpenRouterModels,
|
|
887
1000
|
cachedOllamaModels: existingSettings.cachedOllamaModels,
|
|
888
1001
|
cachedBedrockModels: existingSettings.cachedBedrockModels,
|
|
889
1002
|
cachedOpenAIModels: existingSettings.cachedOpenAIModels,
|
|
1003
|
+
cachedGroqModels: existingSettings.cachedGroqModels,
|
|
1004
|
+
cachedXaiModels: existingSettings.cachedXaiModels,
|
|
1005
|
+
cachedKimiModels: existingSettings.cachedKimiModels,
|
|
890
1006
|
});
|
|
891
1007
|
// Clear cache so next task uses new settings
|
|
892
1008
|
llm_1.LLMProviderFactory.clearCache();
|
|
@@ -902,9 +1018,11 @@ async function setupIpcHandlers(dbManager, agentDaemon, gateway) {
|
|
|
902
1018
|
openaiAccessToken = settings.openai?.accessToken;
|
|
903
1019
|
openaiRefreshToken = settings.openai?.refreshToken;
|
|
904
1020
|
}
|
|
1021
|
+
const resolvedProviderType = resolveCustomProviderId(config.providerType);
|
|
1022
|
+
const customProviderConfig = config.customProviders?.[resolvedProviderType] || config.customProviders?.[config.providerType];
|
|
905
1023
|
const providerConfig = {
|
|
906
1024
|
type: config.providerType,
|
|
907
|
-
model: llm_1.LLMProviderFactory.getModelId(config.modelKey, config.providerType, config.ollama?.model, config.gemini?.model, config.openrouter?.model, config.openai?.model),
|
|
1025
|
+
model: llm_1.LLMProviderFactory.getModelId(config.modelKey, config.providerType, config.ollama?.model, config.gemini?.model, config.openrouter?.model, config.openai?.model, config.groq?.model, config.xai?.model, config.kimi?.model, config.customProviders),
|
|
908
1026
|
anthropicApiKey: config.anthropic?.apiKey,
|
|
909
1027
|
awsRegion: config.bedrock?.region,
|
|
910
1028
|
awsAccessKeyId: config.bedrock?.accessKeyId,
|
|
@@ -915,9 +1033,18 @@ async function setupIpcHandlers(dbManager, agentDaemon, gateway) {
|
|
|
915
1033
|
ollamaApiKey: config.ollama?.apiKey,
|
|
916
1034
|
geminiApiKey: config.gemini?.apiKey,
|
|
917
1035
|
openrouterApiKey: config.openrouter?.apiKey,
|
|
1036
|
+
openrouterBaseUrl: config.openrouter?.baseUrl,
|
|
918
1037
|
openaiApiKey: config.openai?.apiKey,
|
|
919
1038
|
openaiAccessToken: openaiAccessToken,
|
|
920
1039
|
openaiRefreshToken: openaiRefreshToken,
|
|
1040
|
+
groqApiKey: config.groq?.apiKey,
|
|
1041
|
+
groqBaseUrl: config.groq?.baseUrl,
|
|
1042
|
+
xaiApiKey: config.xai?.apiKey,
|
|
1043
|
+
xaiBaseUrl: config.xai?.baseUrl,
|
|
1044
|
+
kimiApiKey: config.kimi?.apiKey,
|
|
1045
|
+
kimiBaseUrl: config.kimi?.baseUrl,
|
|
1046
|
+
providerApiKey: customProviderConfig?.apiKey,
|
|
1047
|
+
providerBaseUrl: customProviderConfig?.baseUrl,
|
|
921
1048
|
};
|
|
922
1049
|
return llm_1.LLMProviderFactory.testProvider(providerConfig);
|
|
923
1050
|
});
|
|
@@ -936,132 +1063,213 @@ async function setupIpcHandlers(dbManager, agentDaemon, gateway) {
|
|
|
936
1063
|
// Get models based on the current provider type
|
|
937
1064
|
let models = [];
|
|
938
1065
|
let currentModel = settings.modelKey;
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
}
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
models =
|
|
958
|
-
|
|
959
|
-
else {
|
|
960
|
-
// Fall back to static models
|
|
961
|
-
models = Object.values(llm_1.GEMINI_MODELS).map((value) => ({
|
|
962
|
-
key: value.id,
|
|
1066
|
+
const resolvedProviderType = resolveCustomProviderId(settings.providerType);
|
|
1067
|
+
const customEntry = llm_provider_catalog_1.CUSTOM_PROVIDER_MAP.get(resolvedProviderType);
|
|
1068
|
+
if (customEntry) {
|
|
1069
|
+
const customConfig = settings.customProviders?.[resolvedProviderType] || settings.customProviders?.[settings.providerType];
|
|
1070
|
+
currentModel = customConfig?.model || customEntry.defaultModel;
|
|
1071
|
+
models = [
|
|
1072
|
+
{
|
|
1073
|
+
key: currentModel,
|
|
1074
|
+
displayName: currentModel,
|
|
1075
|
+
description: customEntry.description || `${customEntry.name} model`,
|
|
1076
|
+
},
|
|
1077
|
+
];
|
|
1078
|
+
}
|
|
1079
|
+
else {
|
|
1080
|
+
switch (settings.providerType) {
|
|
1081
|
+
case 'anthropic':
|
|
1082
|
+
case 'bedrock':
|
|
1083
|
+
// Use Anthropic/Bedrock models from MODELS
|
|
1084
|
+
models = Object.entries(llm_1.MODELS).map(([key, value]) => ({
|
|
1085
|
+
key,
|
|
963
1086
|
displayName: value.displayName,
|
|
964
|
-
description:
|
|
1087
|
+
description: key.includes('opus') ? 'Most capable for complex work' :
|
|
1088
|
+
key.includes('sonnet') ? 'Balanced performance and speed' :
|
|
1089
|
+
'Fast and efficient',
|
|
965
1090
|
}));
|
|
1091
|
+
break;
|
|
1092
|
+
case 'gemini': {
|
|
1093
|
+
// For Gemini, use the specific model from settings (full model ID)
|
|
1094
|
+
currentModel = settings.gemini?.model || 'gemini-2.0-flash';
|
|
1095
|
+
// Use cached models if available, otherwise fall back to static list
|
|
1096
|
+
const cachedGemini = llm_1.LLMProviderFactory.getCachedModels('gemini');
|
|
1097
|
+
if (cachedGemini && cachedGemini.length > 0) {
|
|
1098
|
+
models = cachedGemini;
|
|
1099
|
+
}
|
|
1100
|
+
else {
|
|
1101
|
+
// Fall back to static models
|
|
1102
|
+
models = Object.values(llm_1.GEMINI_MODELS).map((value) => ({
|
|
1103
|
+
key: value.id,
|
|
1104
|
+
displayName: value.displayName,
|
|
1105
|
+
description: value.description,
|
|
1106
|
+
}));
|
|
1107
|
+
}
|
|
1108
|
+
// Ensure the currently selected model is in the list
|
|
1109
|
+
if (currentModel && !models.some(m => m.key === currentModel)) {
|
|
1110
|
+
models.unshift({
|
|
1111
|
+
key: currentModel,
|
|
1112
|
+
displayName: currentModel,
|
|
1113
|
+
description: 'Selected model',
|
|
1114
|
+
});
|
|
1115
|
+
}
|
|
1116
|
+
break;
|
|
966
1117
|
}
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
1118
|
+
case 'openrouter': {
|
|
1119
|
+
// For OpenRouter, use the specific model from settings (full model ID)
|
|
1120
|
+
currentModel = settings.openrouter?.model || 'anthropic/claude-3.5-sonnet';
|
|
1121
|
+
// Use cached models if available, otherwise fall back to static list
|
|
1122
|
+
const cachedOpenRouter = llm_1.LLMProviderFactory.getCachedModels('openrouter');
|
|
1123
|
+
if (cachedOpenRouter && cachedOpenRouter.length > 0) {
|
|
1124
|
+
models = cachedOpenRouter;
|
|
1125
|
+
}
|
|
1126
|
+
else {
|
|
1127
|
+
// Fall back to static models
|
|
1128
|
+
models = Object.values(llm_1.OPENROUTER_MODELS).map((value) => ({
|
|
1129
|
+
key: value.id,
|
|
1130
|
+
displayName: value.displayName,
|
|
1131
|
+
description: value.description,
|
|
1132
|
+
}));
|
|
1133
|
+
}
|
|
1134
|
+
// Ensure the currently selected model is in the list
|
|
1135
|
+
if (currentModel && !models.some(m => m.key === currentModel)) {
|
|
1136
|
+
models.unshift({
|
|
1137
|
+
key: currentModel,
|
|
1138
|
+
displayName: currentModel,
|
|
1139
|
+
description: 'Selected model',
|
|
1140
|
+
});
|
|
1141
|
+
}
|
|
1142
|
+
break;
|
|
974
1143
|
}
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
1144
|
+
case 'ollama': {
|
|
1145
|
+
// For Ollama, use the specific model from settings
|
|
1146
|
+
currentModel = settings.ollama?.model || 'llama3.2';
|
|
1147
|
+
// Use cached models if available, otherwise fall back to static list
|
|
1148
|
+
const cachedOllama = llm_1.LLMProviderFactory.getCachedModels('ollama');
|
|
1149
|
+
if (cachedOllama && cachedOllama.length > 0) {
|
|
1150
|
+
models = cachedOllama;
|
|
1151
|
+
}
|
|
1152
|
+
else {
|
|
1153
|
+
// Fall back to static models
|
|
1154
|
+
models = Object.entries(llm_1.OLLAMA_MODELS).map(([key, value]) => ({
|
|
1155
|
+
key,
|
|
1156
|
+
displayName: value.displayName,
|
|
1157
|
+
description: `${value.size} parameter model`,
|
|
1158
|
+
}));
|
|
1159
|
+
}
|
|
1160
|
+
// Ensure the currently selected model is in the list
|
|
1161
|
+
if (currentModel && !models.some(m => m.key === currentModel)) {
|
|
1162
|
+
models.unshift({
|
|
1163
|
+
key: currentModel,
|
|
1164
|
+
displayName: currentModel,
|
|
1165
|
+
description: 'Selected model',
|
|
1166
|
+
});
|
|
1167
|
+
}
|
|
1168
|
+
break;
|
|
984
1169
|
}
|
|
985
|
-
|
|
986
|
-
//
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
1170
|
+
case 'openai': {
|
|
1171
|
+
// For OpenAI, use the specific model from settings
|
|
1172
|
+
currentModel = settings.openai?.model || 'gpt-4o-mini';
|
|
1173
|
+
// Use cached models if available, otherwise fall back to static list
|
|
1174
|
+
const cachedOpenAI = llm_1.LLMProviderFactory.getCachedModels('openai');
|
|
1175
|
+
if (cachedOpenAI && cachedOpenAI.length > 0) {
|
|
1176
|
+
models = cachedOpenAI;
|
|
1177
|
+
}
|
|
1178
|
+
else {
|
|
1179
|
+
// Fall back to static models
|
|
1180
|
+
models = [
|
|
1181
|
+
{ key: 'gpt-4o', displayName: 'GPT-4o', description: 'Most capable model for complex tasks' },
|
|
1182
|
+
{ key: 'gpt-4o-mini', displayName: 'GPT-4o Mini', description: 'Fast and affordable for most tasks' },
|
|
1183
|
+
{ key: 'gpt-4-turbo', displayName: 'GPT-4 Turbo', description: 'Previous generation flagship' },
|
|
1184
|
+
{ key: 'gpt-3.5-turbo', displayName: 'GPT-3.5 Turbo', description: 'Fast and cost-effective' },
|
|
1185
|
+
{ key: 'o1', displayName: 'o1', description: 'Advanced reasoning model' },
|
|
1186
|
+
{ key: 'o1-mini', displayName: 'o1 Mini', description: 'Fast reasoning model' },
|
|
1187
|
+
];
|
|
1188
|
+
}
|
|
1189
|
+
// Ensure the currently selected model is in the list
|
|
1190
|
+
if (currentModel && !models.some(m => m.key === currentModel)) {
|
|
1191
|
+
models.unshift({
|
|
1192
|
+
key: currentModel,
|
|
1193
|
+
displayName: currentModel,
|
|
1194
|
+
description: 'Selected model',
|
|
1195
|
+
});
|
|
1196
|
+
}
|
|
1197
|
+
break;
|
|
992
1198
|
}
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1199
|
+
case 'groq': {
|
|
1200
|
+
currentModel = settings.groq?.model || 'llama-3.1-8b-instant';
|
|
1201
|
+
const cachedGroq = llm_1.LLMProviderFactory.getCachedModels('groq');
|
|
1202
|
+
if (cachedGroq && cachedGroq.length > 0) {
|
|
1203
|
+
models = cachedGroq;
|
|
1204
|
+
}
|
|
1205
|
+
else {
|
|
1206
|
+
models = Object.values(llm_1.GROQ_MODELS).map((value) => ({
|
|
1207
|
+
key: value.id,
|
|
1208
|
+
displayName: value.displayName,
|
|
1209
|
+
description: value.description,
|
|
1210
|
+
}));
|
|
1211
|
+
}
|
|
1212
|
+
if (currentModel && !models.some(m => m.key === currentModel)) {
|
|
1213
|
+
models.unshift({
|
|
1214
|
+
key: currentModel,
|
|
1215
|
+
displayName: currentModel,
|
|
1216
|
+
description: 'Selected model',
|
|
1217
|
+
});
|
|
1218
|
+
}
|
|
1219
|
+
break;
|
|
1000
1220
|
}
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1221
|
+
case 'xai': {
|
|
1222
|
+
currentModel = settings.xai?.model || 'grok-4-fast-non-reasoning';
|
|
1223
|
+
const cachedXai = llm_1.LLMProviderFactory.getCachedModels('xai');
|
|
1224
|
+
if (cachedXai && cachedXai.length > 0) {
|
|
1225
|
+
models = cachedXai;
|
|
1226
|
+
}
|
|
1227
|
+
else {
|
|
1228
|
+
models = Object.values(llm_1.XAI_MODELS).map((value) => ({
|
|
1229
|
+
key: value.id,
|
|
1230
|
+
displayName: value.displayName,
|
|
1231
|
+
description: value.description,
|
|
1232
|
+
}));
|
|
1233
|
+
}
|
|
1234
|
+
if (currentModel && !models.some(m => m.key === currentModel)) {
|
|
1235
|
+
models.unshift({
|
|
1236
|
+
key: currentModel,
|
|
1237
|
+
displayName: currentModel,
|
|
1238
|
+
description: 'Selected model',
|
|
1239
|
+
});
|
|
1240
|
+
}
|
|
1241
|
+
break;
|
|
1010
1242
|
}
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1243
|
+
case 'kimi': {
|
|
1244
|
+
currentModel = settings.kimi?.model || 'kimi-k2.5';
|
|
1245
|
+
const cachedKimi = llm_1.LLMProviderFactory.getCachedModels('kimi');
|
|
1246
|
+
if (cachedKimi && cachedKimi.length > 0) {
|
|
1247
|
+
models = cachedKimi;
|
|
1248
|
+
}
|
|
1249
|
+
else {
|
|
1250
|
+
models = Object.values(llm_1.KIMI_MODELS).map((value) => ({
|
|
1251
|
+
key: value.id,
|
|
1252
|
+
displayName: value.displayName,
|
|
1253
|
+
description: value.description,
|
|
1254
|
+
}));
|
|
1255
|
+
}
|
|
1256
|
+
if (currentModel && !models.some(m => m.key === currentModel)) {
|
|
1257
|
+
models.unshift({
|
|
1258
|
+
key: currentModel,
|
|
1259
|
+
displayName: currentModel,
|
|
1260
|
+
description: 'Selected model',
|
|
1261
|
+
});
|
|
1262
|
+
}
|
|
1263
|
+
break;
|
|
1264
|
+
}
|
|
1265
|
+
default:
|
|
1266
|
+
// Fallback to Anthropic models
|
|
1267
|
+
models = Object.entries(llm_1.MODELS).map(([key, value]) => ({
|
|
1014
1268
|
key,
|
|
1015
1269
|
displayName: value.displayName,
|
|
1016
|
-
description:
|
|
1270
|
+
description: 'Claude model',
|
|
1017
1271
|
}));
|
|
1018
|
-
}
|
|
1019
|
-
// Ensure the currently selected model is in the list
|
|
1020
|
-
if (currentModel && !models.some(m => m.key === currentModel)) {
|
|
1021
|
-
models.unshift({
|
|
1022
|
-
key: currentModel,
|
|
1023
|
-
displayName: currentModel,
|
|
1024
|
-
description: 'Selected model',
|
|
1025
|
-
});
|
|
1026
|
-
}
|
|
1027
|
-
break;
|
|
1028
1272
|
}
|
|
1029
|
-
case 'openai': {
|
|
1030
|
-
// For OpenAI, use the specific model from settings
|
|
1031
|
-
currentModel = settings.openai?.model || 'gpt-4o-mini';
|
|
1032
|
-
// Use cached models if available, otherwise fall back to static list
|
|
1033
|
-
const cachedOpenAI = llm_1.LLMProviderFactory.getCachedModels('openai');
|
|
1034
|
-
if (cachedOpenAI && cachedOpenAI.length > 0) {
|
|
1035
|
-
models = cachedOpenAI;
|
|
1036
|
-
}
|
|
1037
|
-
else {
|
|
1038
|
-
// Fall back to static models
|
|
1039
|
-
models = [
|
|
1040
|
-
{ key: 'gpt-4o', displayName: 'GPT-4o', description: 'Most capable model for complex tasks' },
|
|
1041
|
-
{ key: 'gpt-4o-mini', displayName: 'GPT-4o Mini', description: 'Fast and affordable for most tasks' },
|
|
1042
|
-
{ key: 'gpt-4-turbo', displayName: 'GPT-4 Turbo', description: 'Previous generation flagship' },
|
|
1043
|
-
{ key: 'gpt-3.5-turbo', displayName: 'GPT-3.5 Turbo', description: 'Fast and cost-effective' },
|
|
1044
|
-
{ key: 'o1', displayName: 'o1', description: 'Advanced reasoning model' },
|
|
1045
|
-
{ key: 'o1-mini', displayName: 'o1 Mini', description: 'Fast reasoning model' },
|
|
1046
|
-
];
|
|
1047
|
-
}
|
|
1048
|
-
// Ensure the currently selected model is in the list
|
|
1049
|
-
if (currentModel && !models.some(m => m.key === currentModel)) {
|
|
1050
|
-
models.unshift({
|
|
1051
|
-
key: currentModel,
|
|
1052
|
-
displayName: currentModel,
|
|
1053
|
-
description: 'Selected model',
|
|
1054
|
-
});
|
|
1055
|
-
}
|
|
1056
|
-
break;
|
|
1057
|
-
}
|
|
1058
|
-
default:
|
|
1059
|
-
// Fallback to Anthropic models
|
|
1060
|
-
models = Object.entries(llm_1.MODELS).map(([key, value]) => ({
|
|
1061
|
-
key,
|
|
1062
|
-
displayName: value.displayName,
|
|
1063
|
-
description: 'Claude model',
|
|
1064
|
-
}));
|
|
1065
1273
|
}
|
|
1066
1274
|
return {
|
|
1067
1275
|
currentProvider: settings.providerType,
|
|
@@ -1073,26 +1281,48 @@ async function setupIpcHandlers(dbManager, agentDaemon, gateway) {
|
|
|
1073
1281
|
// Set the current model (persists selection across sessions)
|
|
1074
1282
|
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.LLM_SET_MODEL, async (_, modelKey) => {
|
|
1075
1283
|
const settings = llm_1.LLMProviderFactory.loadSettings();
|
|
1284
|
+
const resolvedProviderType = resolveCustomProviderId(settings.providerType);
|
|
1076
1285
|
// Update the model key based on the current provider
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1286
|
+
if (llm_provider_catalog_1.CUSTOM_PROVIDER_IDS.has(resolvedProviderType)) {
|
|
1287
|
+
const existing = settings.customProviders?.[resolvedProviderType] || {};
|
|
1288
|
+
settings.customProviders = {
|
|
1289
|
+
...(settings.customProviders || {}),
|
|
1290
|
+
[resolvedProviderType]: {
|
|
1291
|
+
...existing,
|
|
1292
|
+
model: modelKey,
|
|
1293
|
+
},
|
|
1294
|
+
};
|
|
1295
|
+
}
|
|
1296
|
+
else {
|
|
1297
|
+
switch (settings.providerType) {
|
|
1298
|
+
case 'gemini':
|
|
1299
|
+
settings.gemini = { ...settings.gemini, model: modelKey };
|
|
1300
|
+
break;
|
|
1301
|
+
case 'openrouter':
|
|
1302
|
+
settings.openrouter = { ...settings.openrouter, model: modelKey };
|
|
1303
|
+
break;
|
|
1304
|
+
case 'ollama':
|
|
1305
|
+
settings.ollama = { ...settings.ollama, model: modelKey };
|
|
1306
|
+
break;
|
|
1307
|
+
case 'openai':
|
|
1308
|
+
settings.openai = { ...settings.openai, model: modelKey };
|
|
1309
|
+
break;
|
|
1310
|
+
case 'groq':
|
|
1311
|
+
settings.groq = { ...settings.groq, model: modelKey };
|
|
1312
|
+
break;
|
|
1313
|
+
case 'xai':
|
|
1314
|
+
settings.xai = { ...settings.xai, model: modelKey };
|
|
1315
|
+
break;
|
|
1316
|
+
case 'kimi':
|
|
1317
|
+
settings.kimi = { ...settings.kimi, model: modelKey };
|
|
1318
|
+
break;
|
|
1319
|
+
case 'anthropic':
|
|
1320
|
+
case 'bedrock':
|
|
1321
|
+
default:
|
|
1322
|
+
// For Anthropic/Bedrock, use the modelKey field
|
|
1323
|
+
settings.modelKey = modelKey;
|
|
1324
|
+
break;
|
|
1325
|
+
}
|
|
1096
1326
|
}
|
|
1097
1327
|
llm_1.LLMProviderFactory.saveSettings(settings);
|
|
1098
1328
|
return { success: true };
|
|
@@ -1123,9 +1353,9 @@ async function setupIpcHandlers(dbManager, agentDaemon, gateway) {
|
|
|
1123
1353
|
llm_1.LLMProviderFactory.saveCachedModels('gemini', cachedModels);
|
|
1124
1354
|
return models;
|
|
1125
1355
|
});
|
|
1126
|
-
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.LLM_GET_OPENROUTER_MODELS, async (_, apiKey) => {
|
|
1356
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.LLM_GET_OPENROUTER_MODELS, async (_, apiKey, baseUrl) => {
|
|
1127
1357
|
checkRateLimit(types_1.IPC_CHANNELS.LLM_GET_OPENROUTER_MODELS);
|
|
1128
|
-
const models = await llm_1.LLMProviderFactory.getOpenRouterModels(apiKey);
|
|
1358
|
+
const models = await llm_1.LLMProviderFactory.getOpenRouterModels(apiKey, baseUrl);
|
|
1129
1359
|
// Cache the models for use in config status
|
|
1130
1360
|
const cachedModels = models.map(m => ({
|
|
1131
1361
|
key: m.id,
|
|
@@ -1148,6 +1378,39 @@ async function setupIpcHandlers(dbManager, agentDaemon, gateway) {
|
|
|
1148
1378
|
llm_1.LLMProviderFactory.saveCachedModels('openai', cachedModels);
|
|
1149
1379
|
return models;
|
|
1150
1380
|
});
|
|
1381
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.LLM_GET_GROQ_MODELS, async (_, apiKey, baseUrl) => {
|
|
1382
|
+
checkRateLimit(types_1.IPC_CHANNELS.LLM_GET_GROQ_MODELS);
|
|
1383
|
+
const models = await llm_1.LLMProviderFactory.getGroqModels(apiKey, baseUrl);
|
|
1384
|
+
const cachedModels = models.map(m => ({
|
|
1385
|
+
key: m.id,
|
|
1386
|
+
displayName: m.name,
|
|
1387
|
+
description: 'Groq model',
|
|
1388
|
+
}));
|
|
1389
|
+
llm_1.LLMProviderFactory.saveCachedModels('groq', cachedModels);
|
|
1390
|
+
return models;
|
|
1391
|
+
});
|
|
1392
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.LLM_GET_XAI_MODELS, async (_, apiKey, baseUrl) => {
|
|
1393
|
+
checkRateLimit(types_1.IPC_CHANNELS.LLM_GET_XAI_MODELS);
|
|
1394
|
+
const models = await llm_1.LLMProviderFactory.getXAIModels(apiKey, baseUrl);
|
|
1395
|
+
const cachedModels = models.map(m => ({
|
|
1396
|
+
key: m.id,
|
|
1397
|
+
displayName: m.name,
|
|
1398
|
+
description: 'xAI model',
|
|
1399
|
+
}));
|
|
1400
|
+
llm_1.LLMProviderFactory.saveCachedModels('xai', cachedModels);
|
|
1401
|
+
return models;
|
|
1402
|
+
});
|
|
1403
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.LLM_GET_KIMI_MODELS, async (_, apiKey, baseUrl) => {
|
|
1404
|
+
checkRateLimit(types_1.IPC_CHANNELS.LLM_GET_KIMI_MODELS);
|
|
1405
|
+
const models = await llm_1.LLMProviderFactory.getKimiModels(apiKey, baseUrl);
|
|
1406
|
+
const cachedModels = models.map(m => ({
|
|
1407
|
+
key: m.id,
|
|
1408
|
+
displayName: m.name,
|
|
1409
|
+
description: 'Kimi model',
|
|
1410
|
+
}));
|
|
1411
|
+
llm_1.LLMProviderFactory.saveCachedModels('kimi', cachedModels);
|
|
1412
|
+
return models;
|
|
1413
|
+
});
|
|
1151
1414
|
// OpenAI OAuth handlers
|
|
1152
1415
|
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.LLM_OPENAI_OAUTH_START, async () => {
|
|
1153
1416
|
checkRateLimit(types_1.IPC_CHANNELS.LLM_OPENAI_OAUTH_START);
|
|
@@ -1260,6 +1523,204 @@ async function setupIpcHandlers(dbManager, agentDaemon, gateway) {
|
|
|
1260
1523
|
error: result.success ? undefined : result.error,
|
|
1261
1524
|
};
|
|
1262
1525
|
});
|
|
1526
|
+
// Notion Settings handlers
|
|
1527
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.NOTION_GET_SETTINGS, async () => {
|
|
1528
|
+
return notion_manager_1.NotionSettingsManager.loadSettings();
|
|
1529
|
+
});
|
|
1530
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.NOTION_SAVE_SETTINGS, async (_, settings) => {
|
|
1531
|
+
checkRateLimit(types_1.IPC_CHANNELS.NOTION_SAVE_SETTINGS);
|
|
1532
|
+
const validated = (0, validation_1.validateInput)(validation_1.NotionSettingsSchema, settings, 'notion settings');
|
|
1533
|
+
notion_manager_1.NotionSettingsManager.saveSettings(validated);
|
|
1534
|
+
notion_manager_1.NotionSettingsManager.clearCache();
|
|
1535
|
+
return { success: true };
|
|
1536
|
+
});
|
|
1537
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.NOTION_TEST_CONNECTION, async () => {
|
|
1538
|
+
checkRateLimit(types_1.IPC_CHANNELS.NOTION_TEST_CONNECTION);
|
|
1539
|
+
const settings = notion_manager_1.NotionSettingsManager.loadSettings();
|
|
1540
|
+
return (0, notion_api_1.testNotionConnection)(settings);
|
|
1541
|
+
});
|
|
1542
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.NOTION_GET_STATUS, async () => {
|
|
1543
|
+
checkRateLimit(types_1.IPC_CHANNELS.NOTION_GET_STATUS);
|
|
1544
|
+
const settings = notion_manager_1.NotionSettingsManager.loadSettings();
|
|
1545
|
+
if (!settings.apiKey) {
|
|
1546
|
+
return { configured: false, connected: false };
|
|
1547
|
+
}
|
|
1548
|
+
if (!settings.enabled) {
|
|
1549
|
+
return { configured: true, connected: false };
|
|
1550
|
+
}
|
|
1551
|
+
const result = await (0, notion_api_1.testNotionConnection)(settings);
|
|
1552
|
+
return {
|
|
1553
|
+
configured: true,
|
|
1554
|
+
connected: result.success,
|
|
1555
|
+
name: result.name,
|
|
1556
|
+
error: result.success ? undefined : result.error,
|
|
1557
|
+
};
|
|
1558
|
+
});
|
|
1559
|
+
// Box Settings handlers
|
|
1560
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.BOX_GET_SETTINGS, async () => {
|
|
1561
|
+
return box_manager_1.BoxSettingsManager.loadSettings();
|
|
1562
|
+
});
|
|
1563
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.BOX_SAVE_SETTINGS, async (_, settings) => {
|
|
1564
|
+
checkRateLimit(types_1.IPC_CHANNELS.BOX_SAVE_SETTINGS);
|
|
1565
|
+
const validated = (0, validation_1.validateInput)(validation_1.BoxSettingsSchema, settings, 'box settings');
|
|
1566
|
+
box_manager_1.BoxSettingsManager.saveSettings(validated);
|
|
1567
|
+
box_manager_1.BoxSettingsManager.clearCache();
|
|
1568
|
+
return { success: true };
|
|
1569
|
+
});
|
|
1570
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.BOX_TEST_CONNECTION, async () => {
|
|
1571
|
+
checkRateLimit(types_1.IPC_CHANNELS.BOX_TEST_CONNECTION);
|
|
1572
|
+
const settings = box_manager_1.BoxSettingsManager.loadSettings();
|
|
1573
|
+
return (0, box_api_1.testBoxConnection)(settings);
|
|
1574
|
+
});
|
|
1575
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.BOX_GET_STATUS, async () => {
|
|
1576
|
+
checkRateLimit(types_1.IPC_CHANNELS.BOX_GET_STATUS);
|
|
1577
|
+
const settings = box_manager_1.BoxSettingsManager.loadSettings();
|
|
1578
|
+
if (!settings.accessToken) {
|
|
1579
|
+
return { configured: false, connected: false };
|
|
1580
|
+
}
|
|
1581
|
+
if (!settings.enabled) {
|
|
1582
|
+
return { configured: true, connected: false };
|
|
1583
|
+
}
|
|
1584
|
+
const result = await (0, box_api_1.testBoxConnection)(settings);
|
|
1585
|
+
return {
|
|
1586
|
+
configured: true,
|
|
1587
|
+
connected: result.success,
|
|
1588
|
+
name: result.name,
|
|
1589
|
+
error: result.success ? undefined : result.error,
|
|
1590
|
+
};
|
|
1591
|
+
});
|
|
1592
|
+
// OneDrive Settings handlers
|
|
1593
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.ONEDRIVE_GET_SETTINGS, async () => {
|
|
1594
|
+
return onedrive_manager_1.OneDriveSettingsManager.loadSettings();
|
|
1595
|
+
});
|
|
1596
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.ONEDRIVE_SAVE_SETTINGS, async (_, settings) => {
|
|
1597
|
+
checkRateLimit(types_1.IPC_CHANNELS.ONEDRIVE_SAVE_SETTINGS);
|
|
1598
|
+
const validated = (0, validation_1.validateInput)(validation_1.OneDriveSettingsSchema, settings, 'onedrive settings');
|
|
1599
|
+
onedrive_manager_1.OneDriveSettingsManager.saveSettings(validated);
|
|
1600
|
+
onedrive_manager_1.OneDriveSettingsManager.clearCache();
|
|
1601
|
+
return { success: true };
|
|
1602
|
+
});
|
|
1603
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.ONEDRIVE_TEST_CONNECTION, async () => {
|
|
1604
|
+
checkRateLimit(types_1.IPC_CHANNELS.ONEDRIVE_TEST_CONNECTION);
|
|
1605
|
+
const settings = onedrive_manager_1.OneDriveSettingsManager.loadSettings();
|
|
1606
|
+
return (0, onedrive_api_1.testOneDriveConnection)(settings);
|
|
1607
|
+
});
|
|
1608
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.ONEDRIVE_GET_STATUS, async () => {
|
|
1609
|
+
checkRateLimit(types_1.IPC_CHANNELS.ONEDRIVE_GET_STATUS);
|
|
1610
|
+
const settings = onedrive_manager_1.OneDriveSettingsManager.loadSettings();
|
|
1611
|
+
if (!settings.accessToken) {
|
|
1612
|
+
return { configured: false, connected: false };
|
|
1613
|
+
}
|
|
1614
|
+
if (!settings.enabled) {
|
|
1615
|
+
return { configured: true, connected: false };
|
|
1616
|
+
}
|
|
1617
|
+
const result = await (0, onedrive_api_1.testOneDriveConnection)(settings);
|
|
1618
|
+
return {
|
|
1619
|
+
configured: true,
|
|
1620
|
+
connected: result.success,
|
|
1621
|
+
name: result.name,
|
|
1622
|
+
error: result.success ? undefined : result.error,
|
|
1623
|
+
};
|
|
1624
|
+
});
|
|
1625
|
+
// Google Drive Settings handlers
|
|
1626
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.GOOGLE_DRIVE_GET_SETTINGS, async () => {
|
|
1627
|
+
return google_drive_manager_1.GoogleDriveSettingsManager.loadSettings();
|
|
1628
|
+
});
|
|
1629
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.GOOGLE_DRIVE_SAVE_SETTINGS, async (_, settings) => {
|
|
1630
|
+
checkRateLimit(types_1.IPC_CHANNELS.GOOGLE_DRIVE_SAVE_SETTINGS);
|
|
1631
|
+
const validated = (0, validation_1.validateInput)(validation_1.GoogleDriveSettingsSchema, settings, 'google drive settings');
|
|
1632
|
+
google_drive_manager_1.GoogleDriveSettingsManager.saveSettings(validated);
|
|
1633
|
+
google_drive_manager_1.GoogleDriveSettingsManager.clearCache();
|
|
1634
|
+
return { success: true };
|
|
1635
|
+
});
|
|
1636
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.GOOGLE_DRIVE_TEST_CONNECTION, async () => {
|
|
1637
|
+
checkRateLimit(types_1.IPC_CHANNELS.GOOGLE_DRIVE_TEST_CONNECTION);
|
|
1638
|
+
const settings = google_drive_manager_1.GoogleDriveSettingsManager.loadSettings();
|
|
1639
|
+
return (0, google_drive_api_1.testGoogleDriveConnection)(settings);
|
|
1640
|
+
});
|
|
1641
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.GOOGLE_DRIVE_GET_STATUS, async () => {
|
|
1642
|
+
checkRateLimit(types_1.IPC_CHANNELS.GOOGLE_DRIVE_GET_STATUS);
|
|
1643
|
+
const settings = google_drive_manager_1.GoogleDriveSettingsManager.loadSettings();
|
|
1644
|
+
if (!settings.accessToken) {
|
|
1645
|
+
return { configured: false, connected: false };
|
|
1646
|
+
}
|
|
1647
|
+
if (!settings.enabled) {
|
|
1648
|
+
return { configured: true, connected: false };
|
|
1649
|
+
}
|
|
1650
|
+
const result = await (0, google_drive_api_1.testGoogleDriveConnection)(settings);
|
|
1651
|
+
return {
|
|
1652
|
+
configured: true,
|
|
1653
|
+
connected: result.success,
|
|
1654
|
+
name: result.name,
|
|
1655
|
+
error: result.success ? undefined : result.error,
|
|
1656
|
+
};
|
|
1657
|
+
});
|
|
1658
|
+
// Dropbox Settings handlers
|
|
1659
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.DROPBOX_GET_SETTINGS, async () => {
|
|
1660
|
+
return dropbox_manager_1.DropboxSettingsManager.loadSettings();
|
|
1661
|
+
});
|
|
1662
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.DROPBOX_SAVE_SETTINGS, async (_, settings) => {
|
|
1663
|
+
checkRateLimit(types_1.IPC_CHANNELS.DROPBOX_SAVE_SETTINGS);
|
|
1664
|
+
const validated = (0, validation_1.validateInput)(validation_1.DropboxSettingsSchema, settings, 'dropbox settings');
|
|
1665
|
+
dropbox_manager_1.DropboxSettingsManager.saveSettings(validated);
|
|
1666
|
+
dropbox_manager_1.DropboxSettingsManager.clearCache();
|
|
1667
|
+
return { success: true };
|
|
1668
|
+
});
|
|
1669
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.DROPBOX_TEST_CONNECTION, async () => {
|
|
1670
|
+
checkRateLimit(types_1.IPC_CHANNELS.DROPBOX_TEST_CONNECTION);
|
|
1671
|
+
const settings = dropbox_manager_1.DropboxSettingsManager.loadSettings();
|
|
1672
|
+
return (0, dropbox_api_1.testDropboxConnection)(settings);
|
|
1673
|
+
});
|
|
1674
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.DROPBOX_GET_STATUS, async () => {
|
|
1675
|
+
checkRateLimit(types_1.IPC_CHANNELS.DROPBOX_GET_STATUS);
|
|
1676
|
+
const settings = dropbox_manager_1.DropboxSettingsManager.loadSettings();
|
|
1677
|
+
if (!settings.accessToken) {
|
|
1678
|
+
return { configured: false, connected: false };
|
|
1679
|
+
}
|
|
1680
|
+
if (!settings.enabled) {
|
|
1681
|
+
return { configured: true, connected: false };
|
|
1682
|
+
}
|
|
1683
|
+
const result = await (0, dropbox_api_1.testDropboxConnection)(settings);
|
|
1684
|
+
return {
|
|
1685
|
+
configured: true,
|
|
1686
|
+
connected: result.success,
|
|
1687
|
+
name: result.name,
|
|
1688
|
+
error: result.success ? undefined : result.error,
|
|
1689
|
+
};
|
|
1690
|
+
});
|
|
1691
|
+
// SharePoint Settings handlers
|
|
1692
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.SHAREPOINT_GET_SETTINGS, async () => {
|
|
1693
|
+
return sharepoint_manager_1.SharePointSettingsManager.loadSettings();
|
|
1694
|
+
});
|
|
1695
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.SHAREPOINT_SAVE_SETTINGS, async (_, settings) => {
|
|
1696
|
+
checkRateLimit(types_1.IPC_CHANNELS.SHAREPOINT_SAVE_SETTINGS);
|
|
1697
|
+
const validated = (0, validation_1.validateInput)(validation_1.SharePointSettingsSchema, settings, 'sharepoint settings');
|
|
1698
|
+
sharepoint_manager_1.SharePointSettingsManager.saveSettings(validated);
|
|
1699
|
+
sharepoint_manager_1.SharePointSettingsManager.clearCache();
|
|
1700
|
+
return { success: true };
|
|
1701
|
+
});
|
|
1702
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.SHAREPOINT_TEST_CONNECTION, async () => {
|
|
1703
|
+
checkRateLimit(types_1.IPC_CHANNELS.SHAREPOINT_TEST_CONNECTION);
|
|
1704
|
+
const settings = sharepoint_manager_1.SharePointSettingsManager.loadSettings();
|
|
1705
|
+
return (0, sharepoint_api_1.testSharePointConnection)(settings);
|
|
1706
|
+
});
|
|
1707
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.SHAREPOINT_GET_STATUS, async () => {
|
|
1708
|
+
checkRateLimit(types_1.IPC_CHANNELS.SHAREPOINT_GET_STATUS);
|
|
1709
|
+
const settings = sharepoint_manager_1.SharePointSettingsManager.loadSettings();
|
|
1710
|
+
if (!settings.accessToken) {
|
|
1711
|
+
return { configured: false, connected: false };
|
|
1712
|
+
}
|
|
1713
|
+
if (!settings.enabled) {
|
|
1714
|
+
return { configured: true, connected: false };
|
|
1715
|
+
}
|
|
1716
|
+
const result = await (0, sharepoint_api_1.testSharePointConnection)(settings);
|
|
1717
|
+
return {
|
|
1718
|
+
configured: true,
|
|
1719
|
+
connected: result.success,
|
|
1720
|
+
name: result.name,
|
|
1721
|
+
error: result.success ? undefined : result.error,
|
|
1722
|
+
};
|
|
1723
|
+
});
|
|
1263
1724
|
// Gateway / Channel handlers
|
|
1264
1725
|
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.GATEWAY_GET_CHANNELS, async () => {
|
|
1265
1726
|
if (!gateway)
|
|
@@ -1679,7 +2140,8 @@ async function setupIpcHandlers(dbManager, agentDaemon, gateway) {
|
|
|
1679
2140
|
throw new Error('Agent role not found');
|
|
1680
2141
|
}
|
|
1681
2142
|
}
|
|
1682
|
-
|
|
2143
|
+
const taskUpdate = { assignedAgentRoleId: agentRoleId ?? undefined };
|
|
2144
|
+
taskRepo.update(validatedTaskId, taskUpdate);
|
|
1683
2145
|
const task = taskRepo.findById(validatedTaskId);
|
|
1684
2146
|
if (task) {
|
|
1685
2147
|
if (agentRoleId) {
|
|
@@ -2030,6 +2492,7 @@ function setupMCPHandlers() {
|
|
|
2030
2492
|
rate_limiter_1.rateLimiter.configure(types_1.IPC_CHANNELS.MCP_CONNECT_SERVER, rate_limiter_1.RATE_LIMIT_CONFIGS.expensive);
|
|
2031
2493
|
rate_limiter_1.rateLimiter.configure(types_1.IPC_CHANNELS.MCP_TEST_SERVER, rate_limiter_1.RATE_LIMIT_CONFIGS.expensive);
|
|
2032
2494
|
rate_limiter_1.rateLimiter.configure(types_1.IPC_CHANNELS.MCP_REGISTRY_INSTALL, rate_limiter_1.RATE_LIMIT_CONFIGS.expensive);
|
|
2495
|
+
rate_limiter_1.rateLimiter.configure(types_1.IPC_CHANNELS.MCP_CONNECTOR_OAUTH_START, rate_limiter_1.RATE_LIMIT_CONFIGS.expensive);
|
|
2033
2496
|
// Initialize MCP settings manager
|
|
2034
2497
|
settings_1.MCPSettingsManager.initialize();
|
|
2035
2498
|
// Get settings
|
|
@@ -2053,7 +2516,7 @@ function setupMCPHandlers() {
|
|
|
2053
2516
|
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.MCP_ADD_SERVER, async (_, serverConfig) => {
|
|
2054
2517
|
checkRateLimit(types_1.IPC_CHANNELS.MCP_ADD_SERVER);
|
|
2055
2518
|
const validated = (0, validation_1.validateInput)(validation_2.MCPServerConfigSchema, serverConfig, 'MCP server config');
|
|
2056
|
-
const { id, ...configWithoutId } = validated;
|
|
2519
|
+
const { id: _id, ...configWithoutId } = validated;
|
|
2057
2520
|
return settings_1.MCPSettingsManager.addServer(configWithoutId);
|
|
2058
2521
|
});
|
|
2059
2522
|
// Update a server
|
|
@@ -2136,6 +2599,12 @@ function setupMCPHandlers() {
|
|
|
2136
2599
|
const validatedId = (0, validation_1.validateInput)(validation_1.UUIDSchema, serverId, 'server ID');
|
|
2137
2600
|
return MCPRegistryManager_1.MCPRegistryManager.updateServer(validatedId);
|
|
2138
2601
|
});
|
|
2602
|
+
// MCP Connector OAuth (Salesforce/Jira)
|
|
2603
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.MCP_CONNECTOR_OAUTH_START, async (_, payload) => {
|
|
2604
|
+
checkRateLimit(types_1.IPC_CHANNELS.MCP_CONNECTOR_OAUTH_START);
|
|
2605
|
+
const validated = (0, validation_1.validateInput)(validation_1.MCPConnectorOAuthSchema, payload, 'connector oauth');
|
|
2606
|
+
return (0, connector_oauth_1.startConnectorOAuth)(validated);
|
|
2607
|
+
});
|
|
2139
2608
|
// MCP Host handlers
|
|
2140
2609
|
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.MCP_HOST_START, async () => {
|
|
2141
2610
|
const hostServer = MCPHostServer_1.MCPHostServer.getInstance();
|