@johpaz/hive-sdk 0.0.12 → 0.0.15

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 (199) hide show
  1. package/.github/CODEOWNERS +9 -0
  2. package/.github/workflows/publish.yml +89 -0
  3. package/.github/workflows/version-bump.yml +102 -0
  4. package/CHANGELOG.md +38 -0
  5. package/README.md +158 -0
  6. package/bun.lock +543 -0
  7. package/bunfig.toml +7 -0
  8. package/docs/API-AGENTS.md +316 -0
  9. package/docs/API-CONTEXT-COMPILER.md +252 -0
  10. package/docs/API-DAG-SCHEDULER.md +273 -0
  11. package/docs/API-TOOLS-SKILLS-CHANNELS.md +293 -0
  12. package/docs/API-WORKERS-EVENTS.md +152 -0
  13. package/docs/INDEX.md +141 -0
  14. package/docs/README.md +68 -0
  15. package/package.json +54 -105
  16. package/packages/cli/package.json +17 -0
  17. package/packages/cli/src/commands/init.ts +56 -0
  18. package/packages/cli/src/commands/run.ts +45 -0
  19. package/packages/cli/src/commands/test.ts +42 -0
  20. package/packages/cli/src/commands/trace.ts +55 -0
  21. package/packages/cli/src/index.ts +43 -0
  22. package/packages/core/package.json +58 -0
  23. package/packages/core/src/ace/Curator.ts +158 -0
  24. package/packages/core/src/ace/Reflector.ts +200 -0
  25. package/packages/core/src/ace/Tracer.ts +100 -0
  26. package/packages/core/src/ace/index.ts +4 -0
  27. package/packages/core/src/agent/AgentRunner.ts +699 -0
  28. package/packages/core/src/agent/Compaction.ts +221 -0
  29. package/packages/core/src/agent/ContextCompiler.ts +567 -0
  30. package/packages/core/src/agent/ContextGuard.ts +91 -0
  31. package/packages/core/src/agent/ConversationStore.ts +244 -0
  32. package/packages/core/src/agent/Hooks.ts +166 -0
  33. package/packages/core/src/agent/NativeTools.ts +31 -0
  34. package/packages/core/src/agent/PromptBuilder.ts +169 -0
  35. package/packages/core/src/agent/Service.ts +267 -0
  36. package/packages/core/src/agent/StuckLoop.ts +133 -0
  37. package/packages/core/src/agent/index.ts +12 -0
  38. package/packages/core/src/agent/providers/LLMClient.ts +149 -0
  39. package/packages/core/src/agent/providers/anthropic.ts +212 -0
  40. package/packages/core/src/agent/providers/gemini.ts +215 -0
  41. package/packages/core/src/agent/providers/index.ts +199 -0
  42. package/packages/core/src/agent/providers/interface.ts +195 -0
  43. package/packages/core/src/agent/providers/ollama.ts +175 -0
  44. package/packages/core/src/agent/providers/openai-compat.ts +231 -0
  45. package/packages/core/src/agent/providers.ts +1 -0
  46. package/packages/core/src/agent/selectors/PlaybookSelector.ts +147 -0
  47. package/packages/core/src/agent/selectors/SkillSelector.ts +478 -0
  48. package/packages/core/src/agent/selectors/ToolSelector.ts +577 -0
  49. package/packages/core/src/agent/selectors/index.ts +6 -0
  50. package/packages/core/src/api/createAgent.test.ts +48 -0
  51. package/packages/core/src/api/createAgent.ts +122 -0
  52. package/packages/core/src/api/index.ts +2 -0
  53. package/packages/core/src/canvas/CanvasManager.ts +390 -0
  54. package/packages/core/src/canvas/a2ui-tools.ts +255 -0
  55. package/packages/core/src/canvas/canvas-tools.ts +448 -0
  56. package/packages/core/src/canvas/emitter.ts +149 -0
  57. package/packages/core/src/canvas/index.ts +6 -0
  58. package/packages/core/src/config/index.ts +2 -0
  59. package/packages/core/src/config/loader.ts +554 -0
  60. package/packages/core/src/ethics/EthicsGuard.test.ts +54 -0
  61. package/packages/core/src/ethics/EthicsGuard.ts +66 -0
  62. package/packages/core/src/ethics/index.ts +2 -0
  63. package/packages/core/src/gateway/channel-notify.test.ts +14 -0
  64. package/packages/core/src/gateway/channel-notify.ts +12 -0
  65. package/packages/core/src/gateway/index.ts +1 -0
  66. package/packages/core/src/index.ts +37 -0
  67. package/packages/core/src/mcp/MCPClient.ts +439 -0
  68. package/packages/core/src/mcp/MCPToolAdapter.ts +176 -0
  69. package/packages/core/src/mcp/config.ts +13 -0
  70. package/packages/core/src/mcp/hot-reload.ts +147 -0
  71. package/packages/core/src/mcp/index.ts +11 -0
  72. package/packages/core/src/mcp/logger.ts +42 -0
  73. package/packages/core/src/mcp/singleton.ts +21 -0
  74. package/packages/core/src/mcp/transports/index.ts +67 -0
  75. package/packages/core/src/mcp/transports/sse.ts +241 -0
  76. package/packages/core/src/mcp/transports/websocket.ts +159 -0
  77. package/packages/core/src/memory/Scratchpad.test.ts +47 -0
  78. package/packages/core/src/memory/Scratchpad.ts +37 -0
  79. package/packages/core/src/memory/Storage.ts +6 -0
  80. package/packages/core/src/memory/index.ts +2 -0
  81. package/packages/core/src/multimodal/VisionService.ts +293 -0
  82. package/packages/core/src/multimodal/index.ts +2 -0
  83. package/packages/core/src/multimodal/types.ts +28 -0
  84. package/packages/core/src/security/Pairing.ts +250 -0
  85. package/packages/core/src/security/RateLimit.ts +270 -0
  86. package/packages/core/src/security/index.ts +4 -0
  87. package/packages/core/src/skills/SkillLoader.ts +388 -0
  88. package/packages/core/src/skills/bundled-data.generated.ts +3332 -0
  89. package/packages/core/src/skills/defineSkill.ts +18 -0
  90. package/packages/core/src/skills/index.ts +4 -0
  91. package/packages/core/src/state/index.ts +2 -0
  92. package/packages/core/src/state/store.ts +312 -0
  93. package/packages/core/src/storage/SQLiteStorage.ts +407 -0
  94. package/packages/core/src/storage/crypto.ts +101 -0
  95. package/packages/core/src/storage/index.ts +10 -0
  96. package/packages/core/src/storage/onboarding.ts +1603 -0
  97. package/packages/core/src/storage/schema.ts +689 -0
  98. package/packages/core/src/storage/seed.ts +740 -0
  99. package/packages/core/src/storage/usage.ts +374 -0
  100. package/packages/core/src/swarm/AgentBus.ts +460 -0
  101. package/packages/core/src/swarm/AgentExecutor.ts +53 -0
  102. package/packages/core/src/swarm/Coordinator.ts +251 -0
  103. package/packages/core/src/swarm/EventBridge.ts +122 -0
  104. package/packages/core/src/swarm/EventBus.ts +169 -0
  105. package/packages/core/src/swarm/TaskGraph.ts +192 -0
  106. package/packages/core/src/swarm/TaskNode.ts +97 -0
  107. package/packages/core/src/swarm/TaskResult.ts +22 -0
  108. package/packages/core/src/swarm/WorkerPool.ts +236 -0
  109. package/packages/core/src/swarm/errors.ts +37 -0
  110. package/packages/core/src/swarm/index.ts +30 -0
  111. package/packages/core/src/swarm/presets/HiveLearnPreset.ts +99 -0
  112. package/packages/core/src/swarm/presets/ResearchPreset.ts +97 -0
  113. package/packages/core/src/swarm/presets/index.ts +4 -0
  114. package/packages/core/src/swarm/strategies/ParallelStrategy.ts +21 -0
  115. package/packages/core/src/swarm/strategies/PriorityStrategy.ts +46 -0
  116. package/packages/core/src/swarm/strategies/index.ts +3 -0
  117. package/packages/core/src/swarm/types.ts +164 -0
  118. package/packages/core/src/tools/ToolExecutor.ts +58 -0
  119. package/packages/core/src/tools/ToolRegistry.test.ts +98 -0
  120. package/packages/core/src/tools/ToolRegistry.ts +61 -0
  121. package/packages/core/src/tools/agents/get-available-models.ts +118 -0
  122. package/packages/core/src/tools/agents/index.ts +715 -0
  123. package/packages/core/src/tools/bridge-events.ts +26 -0
  124. package/packages/core/src/tools/canvas/index.ts +375 -0
  125. package/packages/core/src/tools/cli/index.ts +142 -0
  126. package/packages/core/src/tools/codebridge/index.ts +342 -0
  127. package/packages/core/src/tools/core/index.ts +476 -0
  128. package/packages/core/src/tools/cron/index.ts +626 -0
  129. package/packages/core/src/tools/filesystem/fs-delete.ts +78 -0
  130. package/packages/core/src/tools/filesystem/fs-edit.ts +106 -0
  131. package/packages/core/src/tools/filesystem/fs-exists.ts +63 -0
  132. package/packages/core/src/tools/filesystem/fs-glob.ts +108 -0
  133. package/packages/core/src/tools/filesystem/fs-list.ts +129 -0
  134. package/packages/core/src/tools/filesystem/fs-read.ts +72 -0
  135. package/packages/core/src/tools/filesystem/fs-write.ts +67 -0
  136. package/packages/core/src/tools/filesystem/index.ts +34 -0
  137. package/packages/core/src/tools/filesystem/workspace-guard.ts +62 -0
  138. package/packages/core/src/tools/index.ts +231 -0
  139. package/packages/core/src/tools/meeting/index.ts +363 -0
  140. package/packages/core/src/tools/office/index.ts +47 -0
  141. package/packages/core/src/tools/office/office-escribir-docx.ts +192 -0
  142. package/packages/core/src/tools/office/office-escribir-pdf.ts +172 -0
  143. package/packages/core/src/tools/office/office-escribir-pptx.ts +174 -0
  144. package/packages/core/src/tools/office/office-escribir-xlsx.ts +116 -0
  145. package/packages/core/src/tools/office/office-leer-docx.ts +93 -0
  146. package/packages/core/src/tools/office/office-leer-pdf.ts +114 -0
  147. package/packages/core/src/tools/office/office-leer-pptx.ts +136 -0
  148. package/packages/core/src/tools/office/office-leer-xlsx.ts +124 -0
  149. package/packages/core/src/tools/projects/index.ts +37 -0
  150. package/packages/core/src/tools/projects/project-create.ts +94 -0
  151. package/packages/core/src/tools/projects/project-done.ts +66 -0
  152. package/packages/core/src/tools/projects/project-fail.ts +66 -0
  153. package/packages/core/src/tools/projects/project-list.ts +96 -0
  154. package/packages/core/src/tools/projects/project-update.ts +72 -0
  155. package/packages/core/src/tools/projects/task-create.ts +68 -0
  156. package/packages/core/src/tools/projects/task-evaluate.ts +93 -0
  157. package/packages/core/src/tools/projects/task-update.ts +93 -0
  158. package/packages/core/src/tools/types.ts +39 -0
  159. package/packages/core/src/tools/voice/index.ts +104 -0
  160. package/packages/core/src/tools/web/browser-click.ts +78 -0
  161. package/packages/core/src/tools/web/browser-extract.ts +139 -0
  162. package/packages/core/src/tools/web/browser-navigate.ts +106 -0
  163. package/packages/core/src/tools/web/browser-screenshot.ts +87 -0
  164. package/packages/core/src/tools/web/browser-script.ts +88 -0
  165. package/packages/core/src/tools/web/browser-service.ts +554 -0
  166. package/packages/core/src/tools/web/browser-type.ts +101 -0
  167. package/packages/core/src/tools/web/browser-wait.ts +136 -0
  168. package/packages/core/src/tools/web/index.ts +41 -0
  169. package/packages/core/src/tools/web/web-fetch.ts +78 -0
  170. package/packages/core/src/tools/web/web-search.ts +123 -0
  171. package/packages/core/src/utils/benchmark.ts +80 -0
  172. package/packages/core/src/utils/crypto.ts +73 -0
  173. package/packages/core/src/utils/date.ts +42 -0
  174. package/packages/core/src/utils/index.ts +10 -0
  175. package/packages/core/src/utils/logger.ts +389 -0
  176. package/packages/core/src/utils/retry.ts +70 -0
  177. package/packages/core/src/utils/toon.ts +253 -0
  178. package/packages/core/src/voice/index.ts +656 -0
  179. package/test/setup-db.ts +216 -0
  180. package/tsconfig.json +39 -0
  181. package/src/agents.ts +0 -1
  182. package/src/canvas.ts +0 -1
  183. package/src/channels.ts +0 -1
  184. package/src/config.ts +0 -1
  185. package/src/events.ts +0 -1
  186. package/src/gateway.ts +0 -1
  187. package/src/index.ts +0 -304
  188. package/src/mcp.ts +0 -1
  189. package/src/multimodal.ts +0 -1
  190. package/src/scheduler.ts +0 -1
  191. package/src/security.ts +0 -1
  192. package/src/skills.ts +0 -1
  193. package/src/state.ts +0 -1
  194. package/src/storage.ts +0 -1
  195. package/src/tools.ts +0 -1
  196. package/src/tts.ts +0 -1
  197. package/src/types.ts +0 -82
  198. package/src/utils.ts +0 -1
  199. package/src/voice.ts +0 -1
@@ -0,0 +1,460 @@
1
+ /**
2
+ * Agent Bus - Sistema de mensajería pub/sub para comunicación entre workers
3
+ *
4
+ * Permite que los workers se comuniquen entre sí sin pasar por el coordinador.
5
+ * Útil para:
6
+ * - Notificar completado de tareas con dependencias
7
+ * - Solicitar ayuda entre workers
8
+ * - Compartir resultados intermedios
9
+ * - Coordinar ejecución en paralelo
10
+ */
11
+
12
+ import { EventEmitter } from "events";
13
+ import { logger } from "../utils/logger.ts";
14
+ import { getDb } from "../storage/SQLiteStorage.ts";
15
+
16
+ const log = logger.child("agent-bus");
17
+
18
+ // ─── Tipos de eventos ────────────────────────────────────────────────────────
19
+
20
+ export interface AgentBusEventMap {
21
+ "worker:task_started": {
22
+ workerId: string;
23
+ workerName: string;
24
+ taskId: number;
25
+ taskName: string;
26
+ projectId: string;
27
+ timestamp: number;
28
+ };
29
+ "worker:task_completed": {
30
+ workerId: string;
31
+ workerName: string;
32
+ taskId: number;
33
+ taskName: string;
34
+ projectId: string;
35
+ result: string;
36
+ timestamp: number;
37
+ };
38
+ "worker:task_failed": {
39
+ workerId: string;
40
+ workerName: string;
41
+ taskId: number;
42
+ taskName: string;
43
+ projectId: string;
44
+ error: string;
45
+ timestamp: number;
46
+ };
47
+ "worker:help_request": {
48
+ fromWorkerId: string;
49
+ fromWorkerName: string;
50
+ taskId: number;
51
+ request: string;
52
+ requiredSkill?: string;
53
+ timestamp: number;
54
+ };
55
+ "worker:help_response": {
56
+ toWorkerId: string;
57
+ fromWorkerId: string;
58
+ fromWorkerName: string;
59
+ taskId: number;
60
+ response: string;
61
+ timestamp: number;
62
+ };
63
+ "worker:blocked": {
64
+ workerId: string;
65
+ workerName: string;
66
+ taskId: number;
67
+ blockedBy: string;
68
+ reason: string;
69
+ timestamp: number;
70
+ };
71
+ "worker:unblocked": {
72
+ workerId: string;
73
+ workerName: string;
74
+ taskId: number;
75
+ unblockedBy: string;
76
+ timestamp: number;
77
+ };
78
+ "project:started": {
79
+ projectId: string;
80
+ projectName: string;
81
+ coordinatorId: string;
82
+ timestamp: number;
83
+ };
84
+ "project:completed": {
85
+ projectId: string;
86
+ projectName: string;
87
+ coordinatorId: string;
88
+ summary: string;
89
+ timestamp: number;
90
+ };
91
+ "message:custom": {
92
+ fromWorkerId: string;
93
+ fromWorkerName: string;
94
+ toWorkerId?: string;
95
+ topic: string;
96
+ content: string;
97
+ timestamp: number;
98
+ };
99
+ }
100
+
101
+ export type AgentBusEventKey = keyof AgentBusEventMap;
102
+
103
+ export interface AgentBusEventHandler<K extends AgentBusEventKey> {
104
+ (data: AgentBusEventMap[K]): void | Promise<void>;
105
+ }
106
+
107
+ // ─── Message Store - Persistencia de mensajes en BD ─────────────────────────
108
+
109
+ export interface AgentBusMessage {
110
+ id: number;
111
+ event_type: string;
112
+ from_worker_id: string | null;
113
+ to_worker_id: string | null;
114
+ topic: string | null;
115
+ content: string;
116
+ metadata: string | null;
117
+ created_at: number;
118
+ read: number;
119
+ }
120
+
121
+ /**
122
+ * Guarda un mensaje en la base de datos para persistencia
123
+ */
124
+ function persistMessage(event: AgentBusEventKey, data: any, metadata?: Record<string, unknown>): void {
125
+ const db = getDb();
126
+
127
+ // Extraer IDs de worker según el tipo de evento
128
+ let fromWorkerId: string | null = null;
129
+ let toWorkerId: string | null = null;
130
+ let topic: string | null = null;
131
+ let content: string;
132
+
133
+ switch (event) {
134
+ case "worker:task_started":
135
+ case "worker:task_completed":
136
+ case "worker:task_failed":
137
+ fromWorkerId = (data as any).workerId || null;
138
+ topic = event;
139
+ content = JSON.stringify(data);
140
+ break;
141
+ case "worker:help_request":
142
+ fromWorkerId = (data as any).fromWorkerId || null;
143
+ topic = "help_request";
144
+ content = (data as any).request || "";
145
+ break;
146
+ case "worker:help_response":
147
+ fromWorkerId = (data as any).fromWorkerId || null;
148
+ toWorkerId = (data as any).toWorkerId || null;
149
+ topic = "help_response";
150
+ content = (data as any).response || "";
151
+ break;
152
+ case "worker:blocked":
153
+ case "worker:unblocked":
154
+ fromWorkerId = (data as any).workerId || null;
155
+ topic = event;
156
+ content = JSON.stringify(data);
157
+ break;
158
+ case "message:custom":
159
+ fromWorkerId = (data as any).fromWorkerId || null;
160
+ toWorkerId = (data as any).toWorkerId || null;
161
+ topic = (data as any).topic || null;
162
+ content = (data as any).content || "";
163
+ break;
164
+ default:
165
+ fromWorkerId = (data as any).workerId || (data as any).fromWorkerId || null;
166
+ topic = event;
167
+ content = JSON.stringify(data);
168
+ }
169
+
170
+ try {
171
+ db.query(`
172
+ INSERT OR IGNORE INTO agent_bus_messages
173
+ (event_type, from_worker_id, to_worker_id, topic, content, metadata, created_at, read)
174
+ VALUES (?, ?, ?, ?, ?, ?, unixepoch(), 0)
175
+ `).run(
176
+ event,
177
+ fromWorkerId,
178
+ toWorkerId,
179
+ topic,
180
+ content,
181
+ metadata ? JSON.stringify(metadata) : null
182
+ );
183
+ } catch (err) {
184
+ log.warn(`Failed to persist message (non-critical): ${(err as Error).message}`);
185
+ }
186
+ }
187
+
188
+ /**
189
+ * Obtiene mensajes no leídos para un worker específico
190
+ */
191
+ export function getUnreadMessagesForWorker(workerId: string, limit: number = 50): AgentBusMessage[] {
192
+ const db = getDb();
193
+
194
+ try {
195
+ const messages = db.query<any, [string, number]>(`
196
+ SELECT * FROM agent_bus_messages
197
+ WHERE (to_worker_id = ? OR to_worker_id IS NULL) AND read = 0
198
+ ORDER BY created_at ASC
199
+ LIMIT ?
200
+ `).all(workerId, limit);
201
+
202
+ // Marcar como leídos
203
+ if (messages.length > 0) {
204
+ const ids = messages.map((m: AgentBusMessage) => m.id).join(",");
205
+ db.query(`UPDATE agent_bus_messages SET read = 1 WHERE id IN (${ids})`).run();
206
+ }
207
+
208
+ return messages;
209
+ } catch (err) {
210
+ log.error(`Failed to get unread messages: ${(err as Error).message}`);
211
+ return [];
212
+ }
213
+ }
214
+
215
+ /**
216
+ * Obtiene el historial de mensajes de un proyecto
217
+ */
218
+ export function getProjectMessageHistory(projectId: string, limit: number = 100): AgentBusMessage[] {
219
+ const db = getDb();
220
+
221
+ try {
222
+ // Primero obtenemos los task_ids del proyecto
223
+ const tasks = db.query<any, [string]>(
224
+ "SELECT id FROM tasks WHERE project_id = ?"
225
+ ).all(projectId);
226
+
227
+ if (tasks.length === 0) return [];
228
+
229
+ // Obtenemos los agent_ids de las tareas
230
+ const agentIds = tasks
231
+ .map((t: any) => t.agent_id)
232
+ .filter((id: string | null) => id !== null);
233
+
234
+ if (agentIds.length === 0) return [];
235
+
236
+ // Obtenemos mensajes relacionados a estos agents
237
+ const placeholders = agentIds.map(() => "?").join(",");
238
+ const messages = db.query<any, any[]>(`
239
+ SELECT * FROM agent_bus_messages
240
+ WHERE from_worker_id IN (${placeholders})
241
+ ORDER BY created_at DESC
242
+ LIMIT ?
243
+ `).all([...agentIds, limit]);
244
+
245
+ return messages;
246
+ } catch (err) {
247
+ log.error(`Failed to get project message history: ${(err as Error).message}`);
248
+ return [];
249
+ }
250
+ }
251
+
252
+ // ─── Agent Bus Implementation ────────────────────────────────────────────────
253
+
254
+ class AgentBusImpl {
255
+ private emitter = new EventEmitter();
256
+ private logPrefix = "[agent-bus]";
257
+
258
+ /**
259
+ * Publica un evento en el bus
260
+ */
261
+ publish<K extends AgentBusEventKey>(event: K, data: AgentBusEventMap[K], metadata?: Record<string, unknown>): void {
262
+ const enrichedData = {
263
+ ...data,
264
+ _eventId: crypto.randomUUID(),
265
+ _timestamp: Date.now(),
266
+ _event: event,
267
+ } as AgentBusEventMap[K] & { _eventId: string; _timestamp: number; _event: string };
268
+
269
+ // Emitir evento en memoria
270
+ this.emitter.emit(event, enrichedData);
271
+
272
+ // Persistir en BD
273
+ persistMessage(event, enrichedData, metadata);
274
+
275
+ log.info(`${this.logPrefix} published: ${event}`, {
276
+ event,
277
+ fromWorkerId: (data as any).workerId || (data as any).fromWorkerId,
278
+ toWorkerId: (data as any).toWorkerId
279
+ });
280
+ }
281
+
282
+ /**
283
+ * Se suscribe a un tipo de evento
284
+ */
285
+ subscribe<K extends AgentBusEventKey>(
286
+ event: K,
287
+ handler: AgentBusEventHandler<K>
288
+ ): () => void {
289
+ this.emitter.on(event, handler);
290
+ log.debug(`${this.logPrefix} subscribed to: ${event}`);
291
+
292
+ return () => this.unsubscribe(event, handler);
293
+ }
294
+
295
+ /**
296
+ * Se suscribe una vez a un evento
297
+ */
298
+ subscribeOnce<K extends AgentBusEventKey>(
299
+ event: K,
300
+ handler: AgentBusEventHandler<K>
301
+ ): void {
302
+ this.emitter.once(event, handler);
303
+ }
304
+
305
+ /**
306
+ * Cancela suscripción
307
+ */
308
+ unsubscribe<K extends AgentBusEventKey>(
309
+ event: K,
310
+ handler: AgentBusEventHandler<K>
311
+ ): void {
312
+ this.emitter.off(event, handler);
313
+ }
314
+
315
+ /**
316
+ * Elimina todos los listeners
317
+ */
318
+ removeAllListeners<K extends AgentBusEventKey>(event?: K): void {
319
+ if (event) {
320
+ this.emitter.removeAllListeners(event);
321
+ } else {
322
+ this.emitter.removeAllListeners();
323
+ }
324
+ }
325
+
326
+ /**
327
+ * Obtiene cantidad de listeners para un evento
328
+ */
329
+ listenerCount<K extends AgentBusEventKey>(event: K): number {
330
+ return this.emitter.listenerCount(event);
331
+ }
332
+
333
+ /**
334
+ * Publica un mensaje personalizado de worker a worker
335
+ */
336
+ sendMessage(
337
+ fromWorkerId: string,
338
+ fromWorkerName: string,
339
+ content: string,
340
+ options?: { toWorkerId?: string; topic?: string }
341
+ ): void {
342
+ this.publish("message:custom", {
343
+ fromWorkerId,
344
+ fromWorkerName,
345
+ toWorkerId: options?.toWorkerId,
346
+ topic: options?.topic || "general",
347
+ content,
348
+ timestamp: Date.now(),
349
+ });
350
+ }
351
+
352
+ /**
353
+ * Notifica que una tarea comenzó
354
+ */
355
+ notifyTaskStarted(
356
+ workerId: string,
357
+ workerName: string,
358
+ taskId: number,
359
+ taskName: string,
360
+ projectId: string
361
+ ): void {
362
+ this.publish("worker:task_started", {
363
+ workerId,
364
+ workerName,
365
+ taskId,
366
+ taskName,
367
+ projectId,
368
+ timestamp: Date.now(),
369
+ });
370
+ }
371
+
372
+ /**
373
+ * Notifica que una tarea completó
374
+ */
375
+ notifyTaskCompleted(
376
+ workerId: string,
377
+ workerName: string,
378
+ taskId: number,
379
+ taskName: string,
380
+ projectId: string,
381
+ result: string
382
+ ): void {
383
+ this.publish("worker:task_completed", {
384
+ workerId,
385
+ workerName,
386
+ taskId,
387
+ taskName,
388
+ projectId,
389
+ result,
390
+ timestamp: Date.now(),
391
+ });
392
+ }
393
+
394
+ /**
395
+ * Notifica que una tarea falló
396
+ */
397
+ notifyTaskFailed(
398
+ workerId: string,
399
+ workerName: string,
400
+ taskId: number,
401
+ taskName: string,
402
+ projectId: string,
403
+ error: string
404
+ ): void {
405
+ this.publish("worker:task_failed", {
406
+ workerId,
407
+ workerName,
408
+ taskId,
409
+ taskName,
410
+ projectId,
411
+ error,
412
+ timestamp: Date.now(),
413
+ });
414
+ }
415
+
416
+ /**
417
+ * Solicita ayuda a otros workers
418
+ */
419
+ requestHelp(
420
+ fromWorkerId: string,
421
+ fromWorkerName: string,
422
+ taskId: number,
423
+ request: string,
424
+ requiredSkill?: string
425
+ ): void {
426
+ this.publish("worker:help_request", {
427
+ fromWorkerId,
428
+ fromWorkerName,
429
+ taskId,
430
+ request,
431
+ requiredSkill,
432
+ timestamp: Date.now(),
433
+ });
434
+ }
435
+
436
+ /**
437
+ * Responde a una solicitud de ayuda
438
+ */
439
+ respondToHelp(
440
+ toWorkerId: string,
441
+ fromWorkerId: string,
442
+ fromWorkerName: string,
443
+ taskId: number,
444
+ response: string
445
+ ): void {
446
+ this.publish("worker:help_response", {
447
+ toWorkerId,
448
+ fromWorkerId,
449
+ fromWorkerName,
450
+ taskId,
451
+ response,
452
+ timestamp: Date.now(),
453
+ });
454
+ }
455
+ }
456
+
457
+ // Singleton
458
+ export const agentBus = new AgentBusImpl();
459
+
460
+ export type AgentBus = typeof agentBus;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * DAGScheduler — AgentExecutor
3
+ *
4
+ * Bridges the DAGScheduler to the existing runAgentIsolated() call.
5
+ * Adds timeout enforcement via Promise.race().
6
+ *
7
+ * NOTE: There are no Bun Worker threads in Hive OSS. "Workers" are logical
8
+ * agents stored in the DB and executed as async calls in the same process.
9
+ * Parallelism is achieved by launching multiple runAgentIsolated() calls
10
+ * concurrently without awaiting each one serially.
11
+ */
12
+
13
+ import { runAgentIsolated } from "../agent/AgentRunner.ts"
14
+ import { TaskNode } from "./TaskNode"
15
+ import { TaskTimeoutError } from "./errors"
16
+
17
+ export class AgentExecutor {
18
+ /**
19
+ * Execute a TaskNode.
20
+ * Injects dependency results into the task description as context.
21
+ * Returns the final text output from the agent.
22
+ */
23
+ async execute(
24
+ node: TaskNode,
25
+ depResults: Record<string, string>,
26
+ threadId: string
27
+ ): Promise<string> {
28
+ const hasDeps = Object.keys(depResults).length > 0
29
+ const contextBlock = hasDeps
30
+ ? `\n\n---\nContext from completed dependencies:\n${JSON.stringify(depResults, null, 2)}\n---`
31
+ : ""
32
+
33
+ const taskDescription = node.taskDescription + contextBlock
34
+
35
+ const agentPromise = runAgentIsolated({
36
+ agentId: node.agentId,
37
+ taskDescription,
38
+ threadId,
39
+ })
40
+
41
+ const timeoutPromise = new Promise<never>((_, reject) => {
42
+ const t = setTimeout(() => {
43
+ reject(new TaskTimeoutError(node.id, node.timeout))
44
+ }, node.timeout)
45
+ // Ensure the timeout timer doesn't prevent process exit
46
+ if (typeof t === "object" && t !== null && "unref" in t) {
47
+ (t as any).unref()
48
+ }
49
+ })
50
+
51
+ return Promise.race([agentPromise, timeoutPromise])
52
+ }
53
+ }