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.
Files changed (252) hide show
  1. package/README.md +372 -10
  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/custom-skill-loader.js +31 -1
  48. package/dist/electron/electron/agent/daemon.js +189 -13
  49. package/dist/electron/electron/agent/executor.js +895 -78
  50. package/dist/electron/electron/agent/llm/anthropic-compatible-provider.js +177 -0
  51. package/dist/electron/electron/agent/llm/azure-openai-provider.js +328 -0
  52. package/dist/electron/electron/agent/llm/bedrock-provider.js +49 -9
  53. package/dist/electron/electron/agent/llm/github-copilot-provider.js +97 -0
  54. package/dist/electron/electron/agent/llm/groq-provider.js +33 -0
  55. package/dist/electron/electron/agent/llm/index.js +13 -1
  56. package/dist/electron/electron/agent/llm/kimi-provider.js +33 -0
  57. package/dist/electron/electron/agent/llm/openai-compatible-provider.js +116 -0
  58. package/dist/electron/electron/agent/llm/openai-compatible.js +111 -0
  59. package/dist/electron/electron/agent/llm/openai-oauth.js +2 -1
  60. package/dist/electron/electron/agent/llm/openrouter-provider.js +1 -1
  61. package/dist/electron/electron/agent/llm/provider-factory.js +350 -4
  62. package/dist/electron/electron/agent/llm/types.js +66 -1
  63. package/dist/electron/electron/agent/llm/xai-provider.js +33 -0
  64. package/dist/electron/electron/agent/search/provider-factory.js +38 -2
  65. package/dist/electron/electron/agent/tools/box-tools.js +231 -0
  66. package/dist/electron/electron/agent/tools/builtin-settings.js +28 -0
  67. package/dist/electron/electron/agent/tools/dropbox-tools.js +237 -0
  68. package/dist/electron/electron/agent/tools/file-tools.js +66 -3
  69. package/dist/electron/electron/agent/tools/google-drive-tools.js +227 -0
  70. package/dist/electron/electron/agent/tools/grep-tools.js +90 -10
  71. package/dist/electron/electron/agent/tools/image-tools.js +11 -1
  72. package/dist/electron/electron/agent/tools/notion-tools.js +312 -0
  73. package/dist/electron/electron/agent/tools/onedrive-tools.js +217 -0
  74. package/dist/electron/electron/agent/tools/registry.js +548 -10
  75. package/dist/electron/electron/agent/tools/search-tools.js +28 -10
  76. package/dist/electron/electron/agent/tools/sharepoint-tools.js +243 -0
  77. package/dist/electron/electron/agent/tools/shell-tools.js +12 -3
  78. package/dist/electron/electron/agent/tools/x-tools.js +1 -1
  79. package/dist/electron/electron/agents/agent-dispatch.js +63 -0
  80. package/dist/electron/electron/database/repositories.js +19 -5
  81. package/dist/electron/electron/database/schema.js +8 -0
  82. package/dist/electron/electron/gateway/channels/whatsapp.js +55 -0
  83. package/dist/electron/electron/gateway/index.js +75 -1
  84. package/dist/electron/electron/gateway/router.js +209 -154
  85. package/dist/electron/electron/ipc/canvas-handlers.js +5 -0
  86. package/dist/electron/electron/ipc/handlers.js +763 -267
  87. package/dist/electron/electron/main.js +63 -0
  88. package/dist/electron/electron/mcp/oauth/connector-oauth.js +333 -0
  89. package/dist/electron/electron/mcp/registry/MCPRegistryManager.js +503 -154
  90. package/dist/electron/electron/memory/MemoryService.js +2 -1
  91. package/dist/electron/electron/preload.js +78 -1
  92. package/dist/electron/electron/settings/appearance-manager.js +18 -1
  93. package/dist/electron/electron/settings/box-manager.js +54 -0
  94. package/dist/electron/electron/settings/dropbox-manager.js +54 -0
  95. package/dist/electron/electron/settings/google-drive-manager.js +54 -0
  96. package/dist/electron/electron/settings/notion-manager.js +56 -0
  97. package/dist/electron/electron/settings/onedrive-manager.js +54 -0
  98. package/dist/electron/electron/settings/sharepoint-manager.js +54 -0
  99. package/dist/electron/electron/utils/box-api.js +153 -0
  100. package/dist/electron/electron/utils/dropbox-api.js +144 -0
  101. package/dist/electron/electron/utils/env-migration.js +19 -0
  102. package/dist/electron/electron/utils/google-drive-api.js +152 -0
  103. package/dist/electron/electron/utils/notion-api.js +103 -0
  104. package/dist/electron/electron/utils/onedrive-api.js +113 -0
  105. package/dist/electron/electron/utils/sharepoint-api.js +109 -0
  106. package/dist/electron/electron/utils/validation.js +98 -3
  107. package/dist/electron/electron/utils/x-cli.js +1 -1
  108. package/dist/electron/shared/channelMessages.js +284 -3
  109. package/dist/electron/shared/llm-provider-catalog.js +198 -0
  110. package/dist/electron/shared/types.js +90 -1
  111. package/package.json +14 -3
  112. package/resources/skills/nano-banana-pro.json +4 -4
  113. package/resources/skills/openai-image-gen.json +3 -3
  114. package/resources/skills/scripts/gen.py +163 -0
  115. package/resources/skills/scripts/generate_image.py +91 -0
  116. package/src/electron/agent/custom-skill-loader.ts +34 -1
  117. package/src/electron/agent/daemon.ts +210 -14
  118. package/src/electron/agent/executor.ts +1124 -85
  119. package/src/electron/agent/llm/anthropic-compatible-provider.ts +214 -0
  120. package/src/electron/agent/llm/azure-openai-provider.ts +388 -0
  121. package/src/electron/agent/llm/bedrock-provider.ts +62 -9
  122. package/src/electron/agent/llm/github-copilot-provider.ts +117 -0
  123. package/src/electron/agent/llm/groq-provider.ts +39 -0
  124. package/src/electron/agent/llm/index.ts +6 -0
  125. package/src/electron/agent/llm/kimi-provider.ts +39 -0
  126. package/src/electron/agent/llm/openai-compatible-provider.ts +153 -0
  127. package/src/electron/agent/llm/openai-compatible.ts +133 -0
  128. package/src/electron/agent/llm/openai-oauth.ts +2 -1
  129. package/src/electron/agent/llm/openrouter-provider.ts +2 -1
  130. package/src/electron/agent/llm/provider-factory.ts +459 -6
  131. package/src/electron/agent/llm/types.ts +95 -1
  132. package/src/electron/agent/llm/xai-provider.ts +39 -0
  133. package/src/electron/agent/search/provider-factory.ts +43 -2
  134. package/src/electron/agent/tools/box-tools.ts +239 -0
  135. package/src/electron/agent/tools/builtin-settings.ts +36 -0
  136. package/src/electron/agent/tools/dropbox-tools.ts +237 -0
  137. package/src/electron/agent/tools/file-tools.ts +66 -3
  138. package/src/electron/agent/tools/gmail-tools.ts +240 -0
  139. package/src/electron/agent/tools/google-calendar-tools.ts +258 -0
  140. package/src/electron/agent/tools/google-drive-tools.ts +228 -0
  141. package/src/electron/agent/tools/grep-tools.ts +97 -12
  142. package/src/electron/agent/tools/image-tools.ts +11 -1
  143. package/src/electron/agent/tools/notion-tools.ts +330 -0
  144. package/src/electron/agent/tools/onedrive-tools.ts +217 -0
  145. package/src/electron/agent/tools/registry.ts +794 -10
  146. package/src/electron/agent/tools/search-tools.ts +29 -11
  147. package/src/electron/agent/tools/sharepoint-tools.ts +247 -0
  148. package/src/electron/agent/tools/shell-tools.ts +11 -3
  149. package/src/electron/agent/tools/x-tools.ts +1 -1
  150. package/src/electron/agents/agent-dispatch.ts +79 -0
  151. package/src/electron/database/SecureSettingsRepository.ts +7 -1
  152. package/src/electron/database/repositories.ts +58 -6
  153. package/src/electron/database/schema.ts +8 -0
  154. package/src/electron/gateway/channels/discord.ts +4 -0
  155. package/src/electron/gateway/channels/google-chat.ts +3 -0
  156. package/src/electron/gateway/channels/line.ts +3 -0
  157. package/src/electron/gateway/channels/matrix-client.ts +15 -0
  158. package/src/electron/gateway/channels/matrix.ts +31 -0
  159. package/src/electron/gateway/channels/mattermost.ts +3 -0
  160. package/src/electron/gateway/channels/signal.ts +3 -0
  161. package/src/electron/gateway/channels/slack.ts +9 -4
  162. package/src/electron/gateway/channels/teams.ts +4 -0
  163. package/src/electron/gateway/channels/telegram.ts +2 -0
  164. package/src/electron/gateway/channels/twitch.ts +2 -0
  165. package/src/electron/gateway/channels/types.ts +8 -0
  166. package/src/electron/gateway/channels/whatsapp.ts +66 -0
  167. package/src/electron/gateway/index.ts +95 -2
  168. package/src/electron/gateway/router.ts +231 -161
  169. package/src/electron/gateway/security.ts +21 -9
  170. package/src/electron/ipc/canvas-handlers.ts +10 -0
  171. package/src/electron/ipc/handlers.ts +848 -292
  172. package/src/electron/main.ts +35 -0
  173. package/src/electron/mcp/oauth/connector-oauth.ts +448 -0
  174. package/src/electron/mcp/registry/MCPRegistryManager.ts +343 -12
  175. package/src/electron/memory/MemoryService.ts +7 -1
  176. package/src/electron/preload.ts +200 -5
  177. package/src/electron/settings/appearance-manager.ts +20 -2
  178. package/src/electron/settings/box-manager.ts +58 -0
  179. package/src/electron/settings/dropbox-manager.ts +58 -0
  180. package/src/electron/settings/google-workspace-manager.ts +59 -0
  181. package/src/electron/settings/notion-manager.ts +60 -0
  182. package/src/electron/settings/onedrive-manager.ts +58 -0
  183. package/src/electron/settings/sharepoint-manager.ts +58 -0
  184. package/src/electron/utils/box-api.ts +184 -0
  185. package/src/electron/utils/dropbox-api.ts +171 -0
  186. package/src/electron/utils/env-migration.ts +22 -0
  187. package/src/electron/utils/gmail-api.ts +121 -0
  188. package/src/electron/utils/google-calendar-api.ts +115 -0
  189. package/src/electron/utils/google-workspace-api.ts +228 -0
  190. package/src/electron/utils/google-workspace-auth.ts +109 -0
  191. package/src/electron/utils/google-workspace-oauth.ts +232 -0
  192. package/src/electron/utils/notion-api.ts +126 -0
  193. package/src/electron/utils/onedrive-api.ts +137 -0
  194. package/src/electron/utils/sharepoint-api.ts +132 -0
  195. package/src/electron/utils/validation.ts +128 -1
  196. package/src/electron/utils/x-cli.ts +1 -1
  197. package/src/renderer/App.tsx +119 -8
  198. package/src/renderer/components/ActivityFeedItem.tsx +34 -17
  199. package/src/renderer/components/AgentWorkingStatePanel.tsx +7 -5
  200. package/src/renderer/components/AppearanceSettings.tsx +37 -2
  201. package/src/renderer/components/BlueBubblesSettings.tsx +18 -7
  202. package/src/renderer/components/BoxSettings.tsx +203 -0
  203. package/src/renderer/components/BrowserView.tsx +101 -0
  204. package/src/renderer/components/BuiltinToolsSettings.tsx +105 -0
  205. package/src/renderer/components/CanvasPreview.tsx +68 -1
  206. package/src/renderer/components/ConnectorEnvModal.tsx +116 -0
  207. package/src/renderer/components/ConnectorSetupModal.tsx +566 -0
  208. package/src/renderer/components/ConnectorsSettings.tsx +397 -0
  209. package/src/renderer/components/ControlPlaneSettings.tsx +2 -0
  210. package/src/renderer/components/DiscordSettings.tsx +18 -7
  211. package/src/renderer/components/DropboxSettings.tsx +202 -0
  212. package/src/renderer/components/EmailSettings.tsx +18 -7
  213. package/src/renderer/components/FileViewer.tsx +21 -13
  214. package/src/renderer/components/GoogleChatSettings.tsx +17 -7
  215. package/src/renderer/components/GoogleWorkspaceSettings.tsx +332 -0
  216. package/src/renderer/components/ImessageSettings.tsx +22 -11
  217. package/src/renderer/components/LineIcons.tsx +376 -0
  218. package/src/renderer/components/LineSettings.tsx +18 -7
  219. package/src/renderer/components/MCPSettings.tsx +56 -0
  220. package/src/renderer/components/MainContent.tsx +740 -76
  221. package/src/renderer/components/MatrixSettings.tsx +18 -7
  222. package/src/renderer/components/MattermostSettings.tsx +18 -7
  223. package/src/renderer/components/NodesSettings.tsx +58 -99
  224. package/src/renderer/components/NotificationPanel.tsx +25 -11
  225. package/src/renderer/components/NotionSettings.tsx +231 -0
  226. package/src/renderer/components/Onboarding/Onboarding.tsx +13 -1
  227. package/src/renderer/components/OnboardingModal.tsx +70 -1
  228. package/src/renderer/components/OneDriveSettings.tsx +212 -0
  229. package/src/renderer/components/RightPanel.tsx +141 -28
  230. package/src/renderer/components/ScheduledTasksSettings.tsx +10 -62
  231. package/src/renderer/components/SearchSettings.tsx +118 -114
  232. package/src/renderer/components/Settings.tsx +1425 -651
  233. package/src/renderer/components/SharePointSettings.tsx +224 -0
  234. package/src/renderer/components/Sidebar.tsx +94 -19
  235. package/src/renderer/components/SignalSettings.tsx +18 -7
  236. package/src/renderer/components/SkillHubBrowser.tsx +144 -185
  237. package/src/renderer/components/SlackSettings.tsx +18 -7
  238. package/src/renderer/components/TaskQuickActions.tsx +11 -6
  239. package/src/renderer/components/TaskTimeline.tsx +58 -26
  240. package/src/renderer/components/TeamsSettings.tsx +18 -7
  241. package/src/renderer/components/TelegramSettings.tsx +18 -7
  242. package/src/renderer/components/ThemeIcon.tsx +16 -0
  243. package/src/renderer/components/TwitchSettings.tsx +18 -7
  244. package/src/renderer/components/VoiceSettings.tsx +30 -74
  245. package/src/renderer/components/WhatsAppSettings.tsx +48 -37
  246. package/src/renderer/components/WorkingStateHistory.tsx +7 -5
  247. package/src/renderer/components/WorkspaceSelector.tsx +42 -13
  248. package/src/renderer/hooks/useOnboardingFlow.ts +21 -0
  249. package/src/renderer/styles/index.css +2333 -209
  250. package/src/shared/channelMessages.ts +367 -4
  251. package/src/shared/llm-provider-catalog.ts +217 -0
  252. 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