cowork-os 0.3.21 → 0.3.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +372 -10
- package/connectors/README.md +20 -0
- package/connectors/asana-mcp/README.md +24 -0
- package/connectors/asana-mcp/dist/index.js +427 -0
- package/connectors/asana-mcp/package.json +15 -0
- package/connectors/asana-mcp/src/index.ts +553 -0
- package/connectors/asana-mcp/tsconfig.json +13 -0
- package/connectors/hubspot-mcp/README.md +35 -0
- package/connectors/hubspot-mcp/dist/index.js +454 -0
- package/connectors/hubspot-mcp/package.json +15 -0
- package/connectors/hubspot-mcp/src/index.ts +562 -0
- package/connectors/hubspot-mcp/tsconfig.json +13 -0
- package/connectors/jira-mcp/README.md +49 -0
- package/connectors/jira-mcp/dist/index.js +588 -0
- package/connectors/jira-mcp/package.json +15 -0
- package/connectors/jira-mcp/src/index.ts +711 -0
- package/connectors/jira-mcp/tsconfig.json +13 -0
- package/connectors/linear-mcp/README.md +22 -0
- package/connectors/linear-mcp/dist/index.js +402 -0
- package/connectors/linear-mcp/package.json +15 -0
- package/connectors/linear-mcp/src/index.ts +522 -0
- package/connectors/linear-mcp/tsconfig.json +13 -0
- package/connectors/okta-mcp/README.md +24 -0
- package/connectors/okta-mcp/dist/index.js +411 -0
- package/connectors/okta-mcp/package.json +15 -0
- package/connectors/okta-mcp/src/index.ts +520 -0
- package/connectors/okta-mcp/tsconfig.json +13 -0
- package/connectors/salesforce-mcp/README.md +47 -0
- package/connectors/salesforce-mcp/dist/index.js +584 -0
- package/connectors/salesforce-mcp/package.json +15 -0
- package/connectors/salesforce-mcp/src/index.ts +722 -0
- package/connectors/salesforce-mcp/tsconfig.json +13 -0
- package/connectors/servicenow-mcp/README.md +26 -0
- package/connectors/servicenow-mcp/dist/index.js +400 -0
- package/connectors/servicenow-mcp/package.json +15 -0
- package/connectors/servicenow-mcp/src/index.ts +500 -0
- package/connectors/servicenow-mcp/tsconfig.json +13 -0
- package/connectors/templates/mcp-connector/README.md +31 -0
- package/connectors/templates/mcp-connector/package.json +15 -0
- package/connectors/templates/mcp-connector/src/index.ts +330 -0
- package/connectors/templates/mcp-connector/tsconfig.json +13 -0
- package/connectors/zendesk-mcp/README.md +40 -0
- package/connectors/zendesk-mcp/dist/index.js +431 -0
- package/connectors/zendesk-mcp/package.json +15 -0
- package/connectors/zendesk-mcp/src/index.ts +543 -0
- package/connectors/zendesk-mcp/tsconfig.json +13 -0
- package/dist/electron/electron/agent/custom-skill-loader.js +31 -1
- package/dist/electron/electron/agent/daemon.js +189 -13
- package/dist/electron/electron/agent/executor.js +895 -78
- package/dist/electron/electron/agent/llm/anthropic-compatible-provider.js +177 -0
- package/dist/electron/electron/agent/llm/azure-openai-provider.js +328 -0
- package/dist/electron/electron/agent/llm/bedrock-provider.js +49 -9
- package/dist/electron/electron/agent/llm/github-copilot-provider.js +97 -0
- package/dist/electron/electron/agent/llm/groq-provider.js +33 -0
- package/dist/electron/electron/agent/llm/index.js +13 -1
- package/dist/electron/electron/agent/llm/kimi-provider.js +33 -0
- package/dist/electron/electron/agent/llm/openai-compatible-provider.js +116 -0
- package/dist/electron/electron/agent/llm/openai-compatible.js +111 -0
- package/dist/electron/electron/agent/llm/openai-oauth.js +2 -1
- package/dist/electron/electron/agent/llm/openrouter-provider.js +1 -1
- package/dist/electron/electron/agent/llm/provider-factory.js +350 -4
- package/dist/electron/electron/agent/llm/types.js +66 -1
- package/dist/electron/electron/agent/llm/xai-provider.js +33 -0
- package/dist/electron/electron/agent/search/provider-factory.js +38 -2
- package/dist/electron/electron/agent/tools/box-tools.js +231 -0
- package/dist/electron/electron/agent/tools/builtin-settings.js +28 -0
- package/dist/electron/electron/agent/tools/dropbox-tools.js +237 -0
- package/dist/electron/electron/agent/tools/file-tools.js +66 -3
- package/dist/electron/electron/agent/tools/google-drive-tools.js +227 -0
- package/dist/electron/electron/agent/tools/grep-tools.js +90 -10
- package/dist/electron/electron/agent/tools/image-tools.js +11 -1
- package/dist/electron/electron/agent/tools/notion-tools.js +312 -0
- package/dist/electron/electron/agent/tools/onedrive-tools.js +217 -0
- package/dist/electron/electron/agent/tools/registry.js +548 -10
- package/dist/electron/electron/agent/tools/search-tools.js +28 -10
- package/dist/electron/electron/agent/tools/sharepoint-tools.js +243 -0
- package/dist/electron/electron/agent/tools/shell-tools.js +12 -3
- package/dist/electron/electron/agent/tools/x-tools.js +1 -1
- package/dist/electron/electron/agents/agent-dispatch.js +63 -0
- package/dist/electron/electron/database/repositories.js +19 -5
- package/dist/electron/electron/database/schema.js +8 -0
- package/dist/electron/electron/gateway/channels/whatsapp.js +55 -0
- package/dist/electron/electron/gateway/index.js +75 -1
- package/dist/electron/electron/gateway/router.js +209 -154
- package/dist/electron/electron/ipc/canvas-handlers.js +5 -0
- package/dist/electron/electron/ipc/handlers.js +763 -267
- package/dist/electron/electron/main.js +63 -0
- package/dist/electron/electron/mcp/oauth/connector-oauth.js +333 -0
- package/dist/electron/electron/mcp/registry/MCPRegistryManager.js +503 -154
- package/dist/electron/electron/memory/MemoryService.js +2 -1
- package/dist/electron/electron/preload.js +78 -1
- package/dist/electron/electron/settings/appearance-manager.js +18 -1
- package/dist/electron/electron/settings/box-manager.js +54 -0
- package/dist/electron/electron/settings/dropbox-manager.js +54 -0
- package/dist/electron/electron/settings/google-drive-manager.js +54 -0
- package/dist/electron/electron/settings/notion-manager.js +56 -0
- package/dist/electron/electron/settings/onedrive-manager.js +54 -0
- package/dist/electron/electron/settings/sharepoint-manager.js +54 -0
- package/dist/electron/electron/utils/box-api.js +153 -0
- package/dist/electron/electron/utils/dropbox-api.js +144 -0
- package/dist/electron/electron/utils/env-migration.js +19 -0
- package/dist/electron/electron/utils/google-drive-api.js +152 -0
- package/dist/electron/electron/utils/notion-api.js +103 -0
- package/dist/electron/electron/utils/onedrive-api.js +113 -0
- package/dist/electron/electron/utils/sharepoint-api.js +109 -0
- package/dist/electron/electron/utils/validation.js +98 -3
- package/dist/electron/electron/utils/x-cli.js +1 -1
- package/dist/electron/shared/channelMessages.js +284 -3
- package/dist/electron/shared/llm-provider-catalog.js +198 -0
- package/dist/electron/shared/types.js +90 -1
- package/package.json +14 -3
- package/resources/skills/nano-banana-pro.json +4 -4
- package/resources/skills/openai-image-gen.json +3 -3
- package/resources/skills/scripts/gen.py +163 -0
- package/resources/skills/scripts/generate_image.py +91 -0
- package/src/electron/agent/custom-skill-loader.ts +34 -1
- package/src/electron/agent/daemon.ts +210 -14
- package/src/electron/agent/executor.ts +1124 -85
- package/src/electron/agent/llm/anthropic-compatible-provider.ts +214 -0
- package/src/electron/agent/llm/azure-openai-provider.ts +388 -0
- package/src/electron/agent/llm/bedrock-provider.ts +62 -9
- package/src/electron/agent/llm/github-copilot-provider.ts +117 -0
- package/src/electron/agent/llm/groq-provider.ts +39 -0
- package/src/electron/agent/llm/index.ts +6 -0
- package/src/electron/agent/llm/kimi-provider.ts +39 -0
- package/src/electron/agent/llm/openai-compatible-provider.ts +153 -0
- package/src/electron/agent/llm/openai-compatible.ts +133 -0
- package/src/electron/agent/llm/openai-oauth.ts +2 -1
- package/src/electron/agent/llm/openrouter-provider.ts +2 -1
- package/src/electron/agent/llm/provider-factory.ts +459 -6
- package/src/electron/agent/llm/types.ts +95 -1
- package/src/electron/agent/llm/xai-provider.ts +39 -0
- package/src/electron/agent/search/provider-factory.ts +43 -2
- package/src/electron/agent/tools/box-tools.ts +239 -0
- package/src/electron/agent/tools/builtin-settings.ts +36 -0
- package/src/electron/agent/tools/dropbox-tools.ts +237 -0
- package/src/electron/agent/tools/file-tools.ts +66 -3
- package/src/electron/agent/tools/gmail-tools.ts +240 -0
- package/src/electron/agent/tools/google-calendar-tools.ts +258 -0
- package/src/electron/agent/tools/google-drive-tools.ts +228 -0
- package/src/electron/agent/tools/grep-tools.ts +97 -12
- package/src/electron/agent/tools/image-tools.ts +11 -1
- package/src/electron/agent/tools/notion-tools.ts +330 -0
- package/src/electron/agent/tools/onedrive-tools.ts +217 -0
- package/src/electron/agent/tools/registry.ts +794 -10
- package/src/electron/agent/tools/search-tools.ts +29 -11
- package/src/electron/agent/tools/sharepoint-tools.ts +247 -0
- package/src/electron/agent/tools/shell-tools.ts +11 -3
- package/src/electron/agent/tools/x-tools.ts +1 -1
- package/src/electron/agents/agent-dispatch.ts +79 -0
- package/src/electron/database/SecureSettingsRepository.ts +7 -1
- package/src/electron/database/repositories.ts +58 -6
- package/src/electron/database/schema.ts +8 -0
- package/src/electron/gateway/channels/discord.ts +4 -0
- package/src/electron/gateway/channels/google-chat.ts +3 -0
- package/src/electron/gateway/channels/line.ts +3 -0
- package/src/electron/gateway/channels/matrix-client.ts +15 -0
- package/src/electron/gateway/channels/matrix.ts +31 -0
- package/src/electron/gateway/channels/mattermost.ts +3 -0
- package/src/electron/gateway/channels/signal.ts +3 -0
- package/src/electron/gateway/channels/slack.ts +9 -4
- package/src/electron/gateway/channels/teams.ts +4 -0
- package/src/electron/gateway/channels/telegram.ts +2 -0
- package/src/electron/gateway/channels/twitch.ts +2 -0
- package/src/electron/gateway/channels/types.ts +8 -0
- package/src/electron/gateway/channels/whatsapp.ts +66 -0
- package/src/electron/gateway/index.ts +95 -2
- package/src/electron/gateway/router.ts +231 -161
- package/src/electron/gateway/security.ts +21 -9
- package/src/electron/ipc/canvas-handlers.ts +10 -0
- package/src/electron/ipc/handlers.ts +848 -292
- package/src/electron/main.ts +35 -0
- package/src/electron/mcp/oauth/connector-oauth.ts +448 -0
- package/src/electron/mcp/registry/MCPRegistryManager.ts +343 -12
- package/src/electron/memory/MemoryService.ts +7 -1
- package/src/electron/preload.ts +200 -5
- package/src/electron/settings/appearance-manager.ts +20 -2
- package/src/electron/settings/box-manager.ts +58 -0
- package/src/electron/settings/dropbox-manager.ts +58 -0
- package/src/electron/settings/google-workspace-manager.ts +59 -0
- package/src/electron/settings/notion-manager.ts +60 -0
- package/src/electron/settings/onedrive-manager.ts +58 -0
- package/src/electron/settings/sharepoint-manager.ts +58 -0
- package/src/electron/utils/box-api.ts +184 -0
- package/src/electron/utils/dropbox-api.ts +171 -0
- package/src/electron/utils/env-migration.ts +22 -0
- package/src/electron/utils/gmail-api.ts +121 -0
- package/src/electron/utils/google-calendar-api.ts +115 -0
- package/src/electron/utils/google-workspace-api.ts +228 -0
- package/src/electron/utils/google-workspace-auth.ts +109 -0
- package/src/electron/utils/google-workspace-oauth.ts +232 -0
- package/src/electron/utils/notion-api.ts +126 -0
- package/src/electron/utils/onedrive-api.ts +137 -0
- package/src/electron/utils/sharepoint-api.ts +132 -0
- package/src/electron/utils/validation.ts +128 -1
- package/src/electron/utils/x-cli.ts +1 -1
- package/src/renderer/App.tsx +119 -8
- package/src/renderer/components/ActivityFeedItem.tsx +34 -17
- package/src/renderer/components/AgentWorkingStatePanel.tsx +7 -5
- package/src/renderer/components/AppearanceSettings.tsx +37 -2
- package/src/renderer/components/BlueBubblesSettings.tsx +18 -7
- package/src/renderer/components/BoxSettings.tsx +203 -0
- package/src/renderer/components/BrowserView.tsx +101 -0
- package/src/renderer/components/BuiltinToolsSettings.tsx +105 -0
- package/src/renderer/components/CanvasPreview.tsx +68 -1
- package/src/renderer/components/ConnectorEnvModal.tsx +116 -0
- package/src/renderer/components/ConnectorSetupModal.tsx +566 -0
- package/src/renderer/components/ConnectorsSettings.tsx +397 -0
- package/src/renderer/components/ControlPlaneSettings.tsx +2 -0
- package/src/renderer/components/DiscordSettings.tsx +18 -7
- package/src/renderer/components/DropboxSettings.tsx +202 -0
- package/src/renderer/components/EmailSettings.tsx +18 -7
- package/src/renderer/components/FileViewer.tsx +21 -13
- package/src/renderer/components/GoogleChatSettings.tsx +17 -7
- package/src/renderer/components/GoogleWorkspaceSettings.tsx +332 -0
- package/src/renderer/components/ImessageSettings.tsx +22 -11
- package/src/renderer/components/LineIcons.tsx +376 -0
- package/src/renderer/components/LineSettings.tsx +18 -7
- package/src/renderer/components/MCPSettings.tsx +56 -0
- package/src/renderer/components/MainContent.tsx +740 -76
- package/src/renderer/components/MatrixSettings.tsx +18 -7
- package/src/renderer/components/MattermostSettings.tsx +18 -7
- package/src/renderer/components/NodesSettings.tsx +58 -99
- package/src/renderer/components/NotificationPanel.tsx +25 -11
- package/src/renderer/components/NotionSettings.tsx +231 -0
- package/src/renderer/components/Onboarding/Onboarding.tsx +13 -1
- package/src/renderer/components/OnboardingModal.tsx +70 -1
- package/src/renderer/components/OneDriveSettings.tsx +212 -0
- package/src/renderer/components/RightPanel.tsx +141 -28
- package/src/renderer/components/ScheduledTasksSettings.tsx +10 -62
- package/src/renderer/components/SearchSettings.tsx +118 -114
- package/src/renderer/components/Settings.tsx +1425 -651
- package/src/renderer/components/SharePointSettings.tsx +224 -0
- package/src/renderer/components/Sidebar.tsx +94 -19
- package/src/renderer/components/SignalSettings.tsx +18 -7
- package/src/renderer/components/SkillHubBrowser.tsx +144 -185
- package/src/renderer/components/SlackSettings.tsx +18 -7
- package/src/renderer/components/TaskQuickActions.tsx +11 -6
- package/src/renderer/components/TaskTimeline.tsx +58 -26
- package/src/renderer/components/TeamsSettings.tsx +18 -7
- package/src/renderer/components/TelegramSettings.tsx +18 -7
- package/src/renderer/components/ThemeIcon.tsx +16 -0
- package/src/renderer/components/TwitchSettings.tsx +18 -7
- package/src/renderer/components/VoiceSettings.tsx +30 -74
- package/src/renderer/components/WhatsAppSettings.tsx +48 -37
- package/src/renderer/components/WorkingStateHistory.tsx +7 -5
- package/src/renderer/components/WorkspaceSelector.tsx +42 -13
- package/src/renderer/hooks/useOnboardingFlow.ts +21 -0
- package/src/renderer/styles/index.css +2333 -209
- package/src/shared/channelMessages.ts +367 -4
- package/src/shared/llm-provider-catalog.ts +217 -0
- package/src/shared/types.ts +251 -2
|
@@ -40,6 +40,9 @@ const fs = __importStar(require("fs"));
|
|
|
40
40
|
const crypto = __importStar(require("crypto"));
|
|
41
41
|
const repositories_1 = require("../database/repositories");
|
|
42
42
|
const ActivityRepository_1 = require("../activity/ActivityRepository");
|
|
43
|
+
const AgentRoleRepository_1 = require("../agents/AgentRoleRepository");
|
|
44
|
+
const MentionRepository_1 = require("../agents/MentionRepository");
|
|
45
|
+
const agent_dispatch_1 = require("../agents/agent-dispatch");
|
|
43
46
|
const types_1 = require("../../shared/types");
|
|
44
47
|
const executor_1 = require("./executor");
|
|
45
48
|
const queue_manager_1 = require("./queue-manager");
|
|
@@ -48,6 +51,9 @@ const MemoryService_1 = require("../memory/MemoryService");
|
|
|
48
51
|
// Memory management constants
|
|
49
52
|
const MAX_CACHED_EXECUTORS = 10; // Maximum number of completed task executors to keep in memory
|
|
50
53
|
const EXECUTOR_CACHE_TTL_MS = 30 * 60 * 1000; // 30 minutes - time before completed executors are cleaned up
|
|
54
|
+
// Activity throttling constants
|
|
55
|
+
const ACTIVITY_THROTTLE_WINDOW_MS = 2000; // 2 seconds - window for deduping similar activities
|
|
56
|
+
const THROTTLED_ACTIVITY_TYPES = new Set(['tool_call', 'file_created', 'file_modified', 'file_deleted']);
|
|
51
57
|
/**
|
|
52
58
|
* AgentDaemon is the core orchestrator that manages task execution
|
|
53
59
|
* It coordinates between the database, task executors, and UI
|
|
@@ -58,6 +64,12 @@ class AgentDaemon extends events_1.EventEmitter {
|
|
|
58
64
|
this.dbManager = dbManager;
|
|
59
65
|
this.activeTasks = new Map();
|
|
60
66
|
this.pendingApprovals = new Map();
|
|
67
|
+
// Activity throttle: Map<taskId:eventType, lastTimestamp>
|
|
68
|
+
this.activityThrottle = new Map();
|
|
69
|
+
this.pendingRetries = new Map();
|
|
70
|
+
this.retryCounts = new Map();
|
|
71
|
+
this.maxTaskRetries = 2;
|
|
72
|
+
this.retryDelayMs = 30 * 1000;
|
|
61
73
|
const db = dbManager.getDatabase();
|
|
62
74
|
this.taskRepo = new repositories_1.TaskRepository(db);
|
|
63
75
|
this.eventRepo = new repositories_1.TaskEventRepository(db);
|
|
@@ -65,6 +77,8 @@ class AgentDaemon extends events_1.EventEmitter {
|
|
|
65
77
|
this.approvalRepo = new repositories_1.ApprovalRepository(db);
|
|
66
78
|
this.artifactRepo = new repositories_1.ArtifactRepository(db);
|
|
67
79
|
this.activityRepo = new ActivityRepository_1.ActivityRepository(db);
|
|
80
|
+
this.agentRoleRepo = new AgentRoleRepository_1.AgentRoleRepository(db);
|
|
81
|
+
this.mentionRepo = new MentionRepository_1.MentionRepository(db);
|
|
68
82
|
// Initialize queue manager with callbacks
|
|
69
83
|
this.queueManager = new queue_manager_1.TaskQueueManager({
|
|
70
84
|
startTaskImmediate: (task) => this.startTaskImmediate(task),
|
|
@@ -245,6 +259,123 @@ class AgentDaemon extends events_1.EventEmitter {
|
|
|
245
259
|
await this.startTask(task);
|
|
246
260
|
return task;
|
|
247
261
|
}
|
|
262
|
+
buildPlanSummary(plan) {
|
|
263
|
+
if (!plan)
|
|
264
|
+
return undefined;
|
|
265
|
+
const lines = [];
|
|
266
|
+
if (plan.description) {
|
|
267
|
+
lines.push(`Plan: ${plan.description}`);
|
|
268
|
+
}
|
|
269
|
+
if (plan.steps && plan.steps.length > 0) {
|
|
270
|
+
lines.push('Steps:');
|
|
271
|
+
const stepLines = plan.steps
|
|
272
|
+
.slice(0, 7)
|
|
273
|
+
.map((step) => `- ${step.description}`);
|
|
274
|
+
lines.push(...stepLines);
|
|
275
|
+
if (plan.steps.length > 7) {
|
|
276
|
+
lines.push(`- …and ${plan.steps.length - 7} more steps`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return lines.length > 0 ? lines.join('\n') : undefined;
|
|
280
|
+
}
|
|
281
|
+
emitActivityEvent(activity) {
|
|
282
|
+
const windows = electron_1.BrowserWindow.getAllWindows();
|
|
283
|
+
windows.forEach(window => {
|
|
284
|
+
try {
|
|
285
|
+
if (!window.isDestroyed() && window.webContents && !window.webContents.isDestroyed()) {
|
|
286
|
+
window.webContents.send(types_1.IPC_CHANNELS.ACTIVITY_EVENT, { type: 'created', activity });
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
catch (error) {
|
|
290
|
+
console.error('[AgentDaemon] Error sending activity IPC:', error);
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
emitMentionEvent(mention) {
|
|
295
|
+
const windows = electron_1.BrowserWindow.getAllWindows();
|
|
296
|
+
windows.forEach(window => {
|
|
297
|
+
try {
|
|
298
|
+
if (!window.isDestroyed() && window.webContents && !window.webContents.isDestroyed()) {
|
|
299
|
+
window.webContents.send(types_1.IPC_CHANNELS.MENTION_EVENT, { type: 'created', mention });
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
catch (error) {
|
|
303
|
+
console.error('[AgentDaemon] Error sending mention IPC:', error);
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Dispatch mentioned agent roles after the main plan is created.
|
|
309
|
+
* This avoids starting sub-agents before the task is clearly defined.
|
|
310
|
+
*/
|
|
311
|
+
async dispatchMentionedAgents(taskId, plan) {
|
|
312
|
+
const task = this.taskRepo.findById(taskId);
|
|
313
|
+
if (!task || task.parentTaskId)
|
|
314
|
+
return;
|
|
315
|
+
const mentionedRoleIds = (task.mentionedAgentRoleIds || []).filter(Boolean);
|
|
316
|
+
if (mentionedRoleIds.length === 0)
|
|
317
|
+
return;
|
|
318
|
+
const activeRoles = this.agentRoleRepo.findAll(false).filter(role => role.isActive);
|
|
319
|
+
const mentionedRoles = activeRoles.filter(role => mentionedRoleIds.includes(role.id));
|
|
320
|
+
if (mentionedRoles.length === 0)
|
|
321
|
+
return;
|
|
322
|
+
const existingChildren = this.taskRepo.findByParent(taskId);
|
|
323
|
+
const assignedRoleIds = new Set(existingChildren
|
|
324
|
+
.map(child => child.assignedAgentRoleId)
|
|
325
|
+
.filter((id) => typeof id === 'string' && id.length > 0));
|
|
326
|
+
const rolesToDispatch = mentionedRoles.filter(role => !assignedRoleIds.has(role.id));
|
|
327
|
+
if (rolesToDispatch.length === 0)
|
|
328
|
+
return;
|
|
329
|
+
const planSummary = this.buildPlanSummary(plan);
|
|
330
|
+
for (const role of rolesToDispatch) {
|
|
331
|
+
const childPrompt = (0, agent_dispatch_1.buildAgentDispatchPrompt)(role, { title: task.title, prompt: task.prompt }, planSummary ? { planSummary } : undefined);
|
|
332
|
+
const childTask = await this.createChildTask({
|
|
333
|
+
title: `@${role.displayName}: ${task.title}`,
|
|
334
|
+
prompt: childPrompt,
|
|
335
|
+
workspaceId: task.workspaceId,
|
|
336
|
+
parentTaskId: task.id,
|
|
337
|
+
agentType: 'sub',
|
|
338
|
+
agentConfig: {
|
|
339
|
+
...(role.modelKey ? { modelKey: role.modelKey } : {}),
|
|
340
|
+
...(role.personalityId ? { personalityId: role.personalityId } : {}),
|
|
341
|
+
retainMemory: false,
|
|
342
|
+
},
|
|
343
|
+
});
|
|
344
|
+
this.taskRepo.update(childTask.id, {
|
|
345
|
+
assignedAgentRoleId: role.id,
|
|
346
|
+
boardColumn: 'todo',
|
|
347
|
+
});
|
|
348
|
+
const dispatchActivity = this.activityRepo.create({
|
|
349
|
+
workspaceId: task.workspaceId,
|
|
350
|
+
taskId: task.id,
|
|
351
|
+
agentRoleId: role.id,
|
|
352
|
+
actorType: 'system',
|
|
353
|
+
activityType: 'agent_assigned',
|
|
354
|
+
title: `Dispatched to ${role.displayName}`,
|
|
355
|
+
description: childTask.title,
|
|
356
|
+
});
|
|
357
|
+
this.emitActivityEvent(dispatchActivity);
|
|
358
|
+
const mention = this.mentionRepo.create({
|
|
359
|
+
workspaceId: task.workspaceId,
|
|
360
|
+
taskId: task.id,
|
|
361
|
+
toAgentRoleId: role.id,
|
|
362
|
+
mentionType: 'request',
|
|
363
|
+
context: `New task: ${task.title}`,
|
|
364
|
+
});
|
|
365
|
+
this.emitMentionEvent(mention);
|
|
366
|
+
const mentionActivity = this.activityRepo.create({
|
|
367
|
+
workspaceId: task.workspaceId,
|
|
368
|
+
taskId: task.id,
|
|
369
|
+
agentRoleId: role.id,
|
|
370
|
+
actorType: 'user',
|
|
371
|
+
activityType: 'mention',
|
|
372
|
+
title: `@${role.displayName} mentioned`,
|
|
373
|
+
description: mention.context,
|
|
374
|
+
metadata: { mentionId: mention.id, mentionType: mention.mentionType },
|
|
375
|
+
});
|
|
376
|
+
this.emitActivityEvent(mentionActivity);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
248
379
|
/**
|
|
249
380
|
* Cancel a running or queued task
|
|
250
381
|
*/
|
|
@@ -271,6 +402,44 @@ class AgentDaemon extends events_1.EventEmitter {
|
|
|
271
402
|
message: 'Task was stopped by user',
|
|
272
403
|
});
|
|
273
404
|
}
|
|
405
|
+
/**
|
|
406
|
+
* Handle transient provider errors by scheduling a retry instead of failing.
|
|
407
|
+
* Returns true if a retry was scheduled, false if retries are exhausted.
|
|
408
|
+
*/
|
|
409
|
+
handleTransientTaskFailure(taskId, reason, delayMs = this.retryDelayMs) {
|
|
410
|
+
const currentCount = this.retryCounts.get(taskId) ?? 0;
|
|
411
|
+
const nextCount = currentCount + 1;
|
|
412
|
+
if (nextCount > this.maxTaskRetries) {
|
|
413
|
+
return false;
|
|
414
|
+
}
|
|
415
|
+
this.retryCounts.set(taskId, nextCount);
|
|
416
|
+
if (this.pendingRetries.has(taskId)) {
|
|
417
|
+
return true;
|
|
418
|
+
}
|
|
419
|
+
// Mark as queued with a helpful message
|
|
420
|
+
this.taskRepo.update(taskId, {
|
|
421
|
+
status: 'queued',
|
|
422
|
+
error: `Transient provider error. Retry ${nextCount}/${this.maxTaskRetries} in ${Math.ceil(delayMs / 1000)}s.`,
|
|
423
|
+
});
|
|
424
|
+
this.logEvent(taskId, 'log', {
|
|
425
|
+
message: `Transient provider error detected. Scheduling retry ${nextCount}/${this.maxTaskRetries} in ${Math.ceil(delayMs / 1000)}s.`,
|
|
426
|
+
reason,
|
|
427
|
+
});
|
|
428
|
+
// Clear executor and free queue slot
|
|
429
|
+
this.activeTasks.delete(taskId);
|
|
430
|
+
this.queueManager.onTaskFinished(taskId);
|
|
431
|
+
const handle = setTimeout(async () => {
|
|
432
|
+
this.pendingRetries.delete(taskId);
|
|
433
|
+
const task = this.taskRepo.findById(taskId);
|
|
434
|
+
if (!task)
|
|
435
|
+
return;
|
|
436
|
+
if (task.status === 'cancelled' || task.status === 'completed')
|
|
437
|
+
return;
|
|
438
|
+
await this.startTask(task);
|
|
439
|
+
}, delayMs);
|
|
440
|
+
this.pendingRetries.set(taskId, handle);
|
|
441
|
+
return true;
|
|
442
|
+
}
|
|
274
443
|
/**
|
|
275
444
|
* Pause a running task
|
|
276
445
|
*/
|
|
@@ -485,6 +654,26 @@ class AgentDaemon extends events_1.EventEmitter {
|
|
|
485
654
|
const task = this.taskRepo.findById(taskId);
|
|
486
655
|
if (!task)
|
|
487
656
|
return;
|
|
657
|
+
// Throttle high-frequency activity types to reduce database writes
|
|
658
|
+
if (THROTTLED_ACTIVITY_TYPES.has(type)) {
|
|
659
|
+
const throttleKey = `${taskId}:${type}`;
|
|
660
|
+
const now = Date.now();
|
|
661
|
+
const lastTime = this.activityThrottle.get(throttleKey);
|
|
662
|
+
if (lastTime && (now - lastTime) < ACTIVITY_THROTTLE_WINDOW_MS) {
|
|
663
|
+
// Skip this activity - too soon after the last one of the same type
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
this.activityThrottle.set(throttleKey, now);
|
|
667
|
+
// Clean up old throttle entries periodically (keep map from growing unbounded)
|
|
668
|
+
if (this.activityThrottle.size > 1000) {
|
|
669
|
+
const cutoff = now - ACTIVITY_THROTTLE_WINDOW_MS * 10;
|
|
670
|
+
for (const [key, time] of this.activityThrottle) {
|
|
671
|
+
if (time < cutoff) {
|
|
672
|
+
this.activityThrottle.delete(key);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
}
|
|
488
677
|
const activity = this.buildActivityFromEvent(task, type, payload);
|
|
489
678
|
if (!activity)
|
|
490
679
|
return;
|
|
@@ -652,19 +841,6 @@ class AgentDaemon extends events_1.EventEmitter {
|
|
|
652
841
|
return undefined;
|
|
653
842
|
}
|
|
654
843
|
}
|
|
655
|
-
emitActivityEvent(activity) {
|
|
656
|
-
const windows = electron_1.BrowserWindow.getAllWindows();
|
|
657
|
-
windows.forEach(window => {
|
|
658
|
-
try {
|
|
659
|
-
if (!window.isDestroyed() && window.webContents && !window.webContents.isDestroyed()) {
|
|
660
|
-
window.webContents.send(types_1.IPC_CHANNELS.ACTIVITY_EVENT, { type: 'created', activity });
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
catch (error) {
|
|
664
|
-
console.error('[AgentDaemon] Error sending activity IPC:', error);
|
|
665
|
-
}
|
|
666
|
-
});
|
|
667
|
-
}
|
|
668
844
|
/**
|
|
669
845
|
* Register an artifact (file created during task execution)
|
|
670
846
|
* This allows files like screenshots to be sent back to the user
|