@johpaz/hive-sdk 0.1.3 → 0.1.5

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 (272) hide show
  1. package/CHANGELOG.md +97 -0
  2. package/README.md +78 -23
  3. package/bunfig.toml +4 -2
  4. package/docs/API-AGENTS.md +78 -27
  5. package/docs/API-CONTEXT-COMPILER.md +31 -34
  6. package/docs/API-TOOLS-SKILLS-CHANNELS.md +58 -22
  7. package/docs/HIVE-HARNESS.md +1 -1
  8. package/docs/INDEX.md +4 -4
  9. package/docs/TEMPLATE-HIVE-APP.md +10 -10
  10. package/package.json +9 -4
  11. package/packages/cli/package.json +2 -2
  12. package/packages/cli/src/commands/create-app.test.ts +36 -7
  13. package/packages/cli/src/commands/init.ts +3 -3
  14. package/packages/cli/src/commands/run.ts +1 -1
  15. package/packages/cli/src/commands/test.ts +37 -25
  16. package/packages/cli/src/commands/trace.ts +30 -28
  17. package/packages/cli/templates/hive-app/.env.example +10 -2
  18. package/packages/cli/templates/hive-app/README.md +103 -0
  19. package/packages/cli/templates/hive-app/hive.config.ts +9 -3
  20. package/packages/cli/templates/hive-app/src/agents/coordinator.ts +8 -1
  21. package/packages/cli/templates/hive-app/src/main.ts +12 -19
  22. package/packages/core/package.json +5 -4
  23. package/packages/core/src/agent/acceptance-checks.ts +166 -0
  24. package/packages/core/src/agent/agent-catalog.ts +348 -0
  25. package/packages/core/src/agent/agent-loop.ts +1373 -0
  26. package/packages/core/src/agent/capability-search.ts +186 -0
  27. package/packages/core/src/agent/catalog-selector.ts +103 -0
  28. package/packages/core/src/agent/{Compaction.ts → compaction.ts} +86 -63
  29. package/packages/core/src/agent/context-compiler.ts +689 -0
  30. package/packages/core/src/agent/conversation-store.ts +381 -0
  31. package/packages/core/src/agent/curator.ts +276 -0
  32. package/packages/core/src/agent/delegation-runtime.ts +241 -0
  33. package/packages/core/src/agent/goal-runner.ts +323 -0
  34. package/packages/core/src/agent/index.ts +17 -12
  35. package/packages/core/src/agent/llm-client.ts +266 -0
  36. package/packages/core/src/agent/llm-providers/anthropic.ts +264 -0
  37. package/packages/core/src/agent/llm-providers/deepseek.ts +8 -0
  38. package/packages/core/src/agent/{providers → llm-providers}/gemini.ts +98 -60
  39. package/packages/core/src/agent/llm-providers/groq.ts +5 -0
  40. package/packages/core/src/agent/llm-providers/hiveagents.ts +253 -0
  41. package/packages/core/src/agent/{providers → llm-providers}/interface.ts +73 -13
  42. package/packages/core/src/agent/llm-providers/kimi.ts +8 -0
  43. package/packages/core/src/agent/llm-providers/minimax.ts +13 -0
  44. package/packages/core/src/agent/llm-providers/mistral.ts +5 -0
  45. package/packages/core/src/agent/llm-providers/modelscope.ts +5 -0
  46. package/packages/core/src/agent/llm-providers/nvidia.ts +5 -0
  47. package/packages/core/src/agent/{providers → llm-providers}/ollama.ts +31 -5
  48. package/packages/core/src/agent/llm-providers/openai-compat-base.ts +418 -0
  49. package/packages/core/src/agent/llm-providers/openai.ts +5 -0
  50. package/packages/core/src/agent/llm-providers/opencode-go.ts +9 -0
  51. package/packages/core/src/agent/llm-providers/openrouter.ts +5 -0
  52. package/packages/core/src/agent/llm-providers/qwen.ts +5 -0
  53. package/packages/core/src/agent/llm-providers/z-ai.ts +5 -0
  54. package/packages/core/src/agent/minimal-loadout.ts +47 -0
  55. package/packages/core/src/agent/playbook-selector.ts +119 -0
  56. package/packages/core/src/agent/{PromptBuilder.ts → prompt-builder.ts} +21 -22
  57. package/packages/core/src/{harness → agent}/proof-packet.ts +16 -21
  58. package/packages/core/src/agent/providers/index.ts +35 -16
  59. package/packages/core/src/agent/reflector.ts +320 -0
  60. package/packages/core/src/agent/routing-intent.ts +22 -0
  61. package/packages/core/src/{harness → agent}/run-epoch.ts +4 -3
  62. package/packages/core/src/{harness → agent}/run-store.ts +142 -81
  63. package/packages/core/src/agent/{Service.ts → service.ts} +37 -26
  64. package/packages/core/src/agent/skill-selector.ts +374 -0
  65. package/packages/core/src/agent/stuck-loop.ts +209 -0
  66. package/packages/core/src/agent/{selectors/ToolSelector.ts → tool-selector.ts} +188 -178
  67. package/packages/core/src/{ace/Tracer.ts → agent/tracer.ts} +37 -27
  68. package/packages/core/src/api/createAgent.test.ts +139 -27
  69. package/packages/core/src/api/createAgent.ts +232 -44
  70. package/packages/core/src/artifacts/store.ts +162 -0
  71. package/packages/core/src/canvas/canvas-manager.ts +161 -0
  72. package/packages/core/src/canvas/canvas.test.ts +8 -4
  73. package/packages/core/src/canvas/emitter.ts +131 -80
  74. package/packages/core/src/canvas/index.ts +1 -3
  75. package/packages/core/src/channels/base.ts +9 -1
  76. package/packages/core/src/channels/discord.ts +5 -4
  77. package/packages/core/src/channels/manager.ts +122 -30
  78. package/packages/core/src/channels/slack.ts +5 -4
  79. package/packages/core/src/channels/telegram.ts +36 -6
  80. package/packages/core/src/channels/webchat.ts +11 -10
  81. package/packages/core/src/channels/whatsapp.ts +23 -7
  82. package/packages/core/src/config/index.ts +13 -2
  83. package/packages/core/src/config/loader.ts +71 -29
  84. package/packages/core/src/ethics/EthicsGuard.test.ts +90 -36
  85. package/packages/core/src/ethics/EthicsGuard.ts +51 -47
  86. package/packages/core/src/events/agent-bus.ts +44 -68
  87. package/packages/core/src/events/channel-narration.ts +150 -0
  88. package/packages/core/src/events/narration.ts +82 -0
  89. package/packages/core/src/events/tool-narration.ts +62 -0
  90. package/packages/core/src/gateway/delegation-groups.ts +258 -0
  91. package/packages/core/src/{harness → gateway}/durable-queue.ts +102 -42
  92. package/packages/core/src/{harness → gateway}/job-store.ts +85 -48
  93. package/packages/core/src/gateway/lane-queue.ts +173 -0
  94. package/packages/core/src/gateway/notification-inbox.ts +57 -0
  95. package/packages/core/src/gateway/server.ts +1 -1
  96. package/packages/core/src/harness/index.ts +46 -27
  97. package/packages/core/src/index.ts +33 -20
  98. package/packages/core/src/mcp/hot-reload.ts +32 -23
  99. package/packages/core/src/mcp/index.ts +6 -3
  100. package/packages/core/src/mcp/singleton.ts +1 -4
  101. package/packages/core/src/mcp/tool-sync.ts +138 -0
  102. package/packages/core/src/memory/Scratchpad.test.ts +39 -20
  103. package/packages/core/src/memory/Scratchpad.ts +27 -34
  104. package/packages/core/src/multimodal/vision-service.ts +44 -38
  105. package/packages/core/src/resilience/retry.ts +95 -0
  106. package/packages/core/src/scheduler/CronScheduler.ts +334 -287
  107. package/packages/core/src/scheduler/index.ts +9 -7
  108. package/packages/core/src/scheduler/integration.ts +46 -26
  109. package/packages/core/src/scheduler/scheduler.test.ts +9 -13
  110. package/packages/core/src/scheduler/types.ts +7 -2
  111. package/packages/core/src/security/Pairing.ts +1 -1
  112. package/packages/core/src/skills/bundled/a2ui/a2ui_dashboard/SKILL.md +176 -0
  113. package/packages/core/src/skills/bundled/a2ui/a2ui_form/SKILL.md +202 -0
  114. package/packages/core/src/skills/bundled/a2ui/a2ui_interactive/SKILL.md +206 -0
  115. package/packages/core/src/skills/bundled/agents/agent_spawner/SKILL.md +173 -0
  116. package/packages/core/src/skills/bundled/agents/memory_manager/SKILL.md +143 -0
  117. package/packages/core/src/skills/bundled/agents/research_and_remember/SKILL.md +139 -0
  118. package/packages/core/src/skills/bundled/agents/task_orchestrator/SKILL.md +98 -0
  119. package/packages/core/src/skills/bundled/api/api_client/SKILL.md +132 -0
  120. package/packages/core/src/skills/bundled/cli/cli_pipeline/SKILL.md +135 -0
  121. package/packages/core/src/skills/bundled/cli/cli_safe_exec/SKILL.md +125 -0
  122. package/packages/core/src/skills/bundled/cli/software_engineering/SKILL.md +23 -0
  123. package/packages/core/src/skills/bundled/cron_manager/SKILL.md +188 -0
  124. package/packages/core/src/skills/bundled/cron_reminder/SKILL.md +112 -0
  125. package/packages/core/src/skills/bundled/filesystem/file_manager/SKILL.md +118 -0
  126. package/packages/core/src/skills/bundled/filesystem/file_read_and_summarize/SKILL.md +109 -0
  127. package/packages/core/src/skills/bundled/filesystem/file_writer/SKILL.md +129 -0
  128. package/packages/core/src/skills/bundled/filesystem/workspace_file_operator/SKILL.md +22 -0
  129. package/packages/core/src/skills/bundled/office/office_document_manager/SKILL.md +262 -0
  130. package/packages/core/src/skills/bundled/search_knowledge/capability_discovery/SKILL.md +75 -0
  131. package/packages/core/src/skills/bundled/web/browser_automate/SKILL.md +120 -0
  132. package/packages/core/src/skills/bundled/web/browser_scrape/SKILL.md +109 -0
  133. package/packages/core/src/skills/bundled/web/web_monitor/SKILL.md +127 -0
  134. package/packages/core/src/skills/bundled/web/web_research/SKILL.md +119 -0
  135. package/packages/core/src/skills/bundled-data.generated.ts +731 -2678
  136. package/packages/core/src/skills/skills.test.ts +52 -11
  137. package/packages/core/src/{harness → storage}/boot-id.ts +5 -2
  138. package/packages/core/src/storage/bootstrap.ts +151 -0
  139. package/packages/core/src/storage/causal-events.ts +84 -0
  140. package/packages/core/src/storage/collections.ts +680 -0
  141. package/packages/core/src/storage/crypto.ts +205 -74
  142. package/packages/core/src/{harness/db-helpers.ts → storage/hive.ts} +63 -7
  143. package/packages/core/src/storage/hivedb.ts +61 -0
  144. package/packages/core/src/storage/index.ts +111 -17
  145. package/packages/core/src/storage/model-id.ts +53 -0
  146. package/packages/core/src/storage/onboarding.ts +540 -972
  147. package/packages/core/src/storage/reconcile.ts +238 -0
  148. package/packages/core/src/storage/seed.ts +572 -406
  149. package/packages/core/src/storage/usage.ts +285 -225
  150. package/packages/core/src/storage/user-email.ts +11 -0
  151. package/packages/core/src/swarm/AgentExecutor.ts +1 -1
  152. package/packages/core/src/swarm/EventBridge.ts +1 -1
  153. package/packages/core/src/swarm/index.ts +12 -9
  154. package/packages/core/src/tool-runtime/index.ts +146 -23
  155. package/packages/core/src/tool-runtime/tool-worker.ts +2 -2
  156. package/packages/core/src/tool-runtime/worker-tools.ts +27 -0
  157. package/packages/core/src/{canvas/a2ui-tools.ts → tools/a2ui/index.ts} +17 -8
  158. package/packages/core/src/tools/agents/get-available-models.ts +36 -54
  159. package/packages/core/src/tools/agents/index.ts +784 -292
  160. package/packages/core/src/tools/api/api-request.test.ts +164 -0
  161. package/packages/core/src/tools/api/api-request.ts +174 -0
  162. package/packages/core/src/tools/api/index.ts +16 -0
  163. package/packages/core/src/tools/cli/index.ts +4 -0
  164. package/packages/core/src/tools/core/index.ts +281 -112
  165. package/packages/core/src/tools/cron/index.ts +121 -124
  166. package/packages/core/src/tools/index.ts +63 -78
  167. package/packages/core/src/tools/office/office-escribir-xlsx.ts +3 -1
  168. package/packages/core/src/tools/types.ts +3 -1
  169. package/packages/core/src/tools/web/artifact-inspect.ts +23 -0
  170. package/packages/core/src/tools/web/browser-screenshot.ts +26 -5
  171. package/packages/core/src/tools/web/browser-service.ts +5 -0
  172. package/packages/core/src/tools/web/browser-type.ts +3 -8
  173. package/packages/core/src/tools/web/index.ts +4 -4
  174. package/packages/core/src/voice/index.ts +89 -63
  175. package/packages/core/src/workers/agent.worker.ts +2 -2
  176. package/packages/core/src/workers/workers.test.ts +3 -10
  177. package/scripts/bump-version.ts +248 -0
  178. package/scripts/generate-skill-bundle.ts +108 -0
  179. package/test/agent-loop-terminal-synthesis.test.ts +32 -0
  180. package/test/catalog-agents-stay-enabled.test.ts +117 -0
  181. package/test/causal-events.test.ts +117 -0
  182. package/test/compaction.test.ts +105 -0
  183. package/test/context-compiler.test.ts +269 -0
  184. package/test/curator.test.ts +130 -0
  185. package/test/durable-queue.test.ts +114 -0
  186. package/test/harness-barrel.test.ts +64 -0
  187. package/test/hive-helpers.test.ts +130 -0
  188. package/test/hivedb-search.test.ts +189 -0
  189. package/test/internal-turns.test.ts +166 -0
  190. package/test/job-idempotency.test.ts +68 -0
  191. package/test/job-retry-backoff.test.ts +184 -0
  192. package/test/job-store.test.ts +381 -0
  193. package/test/llm-retry.test.ts +97 -0
  194. package/test/memory-perf.test.ts +774 -0
  195. package/test/minimal-loadout.test.ts +78 -0
  196. package/test/model-catalog.test.ts +105 -0
  197. package/test/preload.ts +12 -0
  198. package/test/reflector.test.ts +320 -0
  199. package/test/retention-cap.test.ts +91 -0
  200. package/test/retired-capabilities-pruned.test.ts +192 -0
  201. package/test/run-store.test.ts +355 -0
  202. package/test/scratchpad.test.ts +74 -0
  203. package/test/secrets-durability.test.ts +119 -0
  204. package/test/seed-model-reseed.test.ts +155 -0
  205. package/test/setup-agent-seed.test.ts +264 -0
  206. package/test/tool-inventory.test.ts +65 -0
  207. package/test/tool-runtime.test.ts +258 -0
  208. package/test/toon.test.ts +429 -0
  209. package/tsconfig.json +2 -0
  210. package/packages/core/src/ace/Curator.ts +0 -158
  211. package/packages/core/src/ace/Reflector.ts +0 -200
  212. package/packages/core/src/ace/index.ts +0 -4
  213. package/packages/core/src/agent/AgentRunner.ts +0 -711
  214. package/packages/core/src/agent/ContextCompiler.ts +0 -567
  215. package/packages/core/src/agent/ContextGuard.ts +0 -91
  216. package/packages/core/src/agent/ConversationStore.ts +0 -254
  217. package/packages/core/src/agent/Hooks.ts +0 -166
  218. package/packages/core/src/agent/StuckLoop.ts +0 -133
  219. package/packages/core/src/agent/providers/LLMClient.ts +0 -149
  220. package/packages/core/src/agent/providers/anthropic.ts +0 -212
  221. package/packages/core/src/agent/providers/openai-compat.ts +0 -231
  222. package/packages/core/src/agent/selectors/PlaybookSelector.ts +0 -121
  223. package/packages/core/src/agent/selectors/SkillSelector.ts +0 -322
  224. package/packages/core/src/agent/selectors/index.ts +0 -6
  225. package/packages/core/src/auth/auth.ts +0 -121
  226. package/packages/core/src/auth/index.ts +0 -1
  227. package/packages/core/src/canvas/CanvasManager.ts +0 -390
  228. package/packages/core/src/canvas/canvas-tools.ts +0 -448
  229. package/packages/core/src/harness/collections.ts +0 -98
  230. package/packages/core/src/harness/goal-verifier.ts +0 -141
  231. package/packages/core/src/harness/harness.test.ts +0 -236
  232. package/packages/core/src/harness/reconcile.ts +0 -149
  233. package/packages/core/src/mcp/MCPToolAdapter.ts +0 -176
  234. package/packages/core/src/multimodal/VisionService.ts +0 -293
  235. package/packages/core/src/scheduler/dag/AgentExecutor.ts +0 -53
  236. package/packages/core/src/scheduler/dag/DAGScheduler.ts +0 -250
  237. package/packages/core/src/scheduler/dag/EventBridge.ts +0 -122
  238. package/packages/core/src/scheduler/dag/TaskGraph.ts +0 -192
  239. package/packages/core/src/scheduler/dag/TaskNode.ts +0 -97
  240. package/packages/core/src/scheduler/dag/TaskResult.ts +0 -22
  241. package/packages/core/src/scheduler/dag/errors.ts +0 -37
  242. package/packages/core/src/scheduler/dag/index.ts +0 -26
  243. package/packages/core/src/scheduler/dag/presets/ResearchPreset.ts +0 -97
  244. package/packages/core/src/scheduler/dag/strategies/ParallelStrategy.ts +0 -21
  245. package/packages/core/src/scheduler/dag/strategies/PriorityStrategy.ts +0 -46
  246. package/packages/core/src/storage/HiveDBStorage.ts +0 -64
  247. package/packages/core/src/storage/SQLiteStorage.ts +0 -414
  248. package/packages/core/src/storage/hiveSeed.ts +0 -308
  249. package/packages/core/src/storage/hiveStorage.test.ts +0 -38
  250. package/packages/core/src/storage/schema.ts +0 -689
  251. package/packages/core/src/storage/storage.test.ts +0 -37
  252. package/packages/core/src/swarm/AgentBus.ts +0 -460
  253. package/packages/core/src/swarm/EventBus.ts +0 -169
  254. package/packages/core/src/swarm/WorkerPool.ts +0 -236
  255. package/packages/core/src/tools/bridge-events.ts +0 -26
  256. package/packages/core/src/tools/canvas/index.ts +0 -375
  257. package/packages/core/src/tools/codebridge/index.ts +0 -342
  258. package/packages/core/src/tools/meeting/index.ts +0 -353
  259. package/packages/core/src/tools/projects/index.ts +0 -37
  260. package/packages/core/src/tools/projects/project-create.ts +0 -94
  261. package/packages/core/src/tools/projects/project-done.ts +0 -66
  262. package/packages/core/src/tools/projects/project-fail.ts +0 -66
  263. package/packages/core/src/tools/projects/project-list.ts +0 -96
  264. package/packages/core/src/tools/projects/project-update.ts +0 -72
  265. package/packages/core/src/tools/projects/task-create.ts +0 -68
  266. package/packages/core/src/tools/projects/task-evaluate.ts +0 -93
  267. package/packages/core/src/tools/projects/task-update.ts +0 -93
  268. package/packages/core/src/tools/voice/index.ts +0 -104
  269. package/packages/core/src/tools/web/api-request.test.ts +0 -170
  270. package/packages/core/src/tools/web/api-request.ts +0 -239
  271. package/test/setup-db.ts +0 -216
  272. /package/packages/core/src/agent/{NativeTools.ts → native-tools.ts} +0 -0
@@ -1,37 +0,0 @@
1
- import { describe, expect, it, beforeAll, afterAll } from "bun:test";
2
- import { setupTestDb, teardownTestDb, getTestDb, insertTestAgent, insertTestProvider } from "../../../../test/setup-db.ts";
3
-
4
- describe("storage", () => {
5
- beforeAll(() => {
6
- setupTestDb();
7
- // Insert a test user to satisfy foreign key constraints
8
- const db = getTestDb();
9
- db.query(`INSERT OR IGNORE INTO users (id, name, created_at) VALUES ('test-user', 'Test User', unixepoch())`).run();
10
- });
11
-
12
- afterAll(() => {
13
- teardownTestDb();
14
- });
15
-
16
- it("initializes in-memory test database", () => {
17
- const db = getTestDb();
18
- expect(db).toBeDefined();
19
-
20
- const tables = db.query("SELECT name FROM sqlite_master WHERE type='table'").all() as any[];
21
- const tableNames = tables.map((t) => t.name);
22
- expect(tableNames).toContain("agents");
23
- expect(tableNames).toContain("conversations");
24
- });
25
-
26
- it("inserts test agent", () => {
27
- const agentId = insertTestAgent({ name: "Test Agent", userId: "test-user" });
28
- expect(agentId).toBeDefined();
29
- expect(typeof agentId).toBe("string");
30
- });
31
-
32
- it("inserts test provider", () => {
33
- const providerId = insertTestProvider({ name: "test-provider" });
34
- expect(providerId).toBeDefined();
35
- expect(typeof providerId).toBe("string");
36
- });
37
- });
@@ -1,460 +0,0 @@
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;
@@ -1,169 +0,0 @@
1
- import { EventEmitter } from "events";
2
- import { logger } from "../utils/logger.ts";
3
-
4
- export interface EventMap {
5
- "message:received": {
6
- channel: string;
7
- userId: string;
8
- content: string;
9
- timestamp: number;
10
- sessionId: string;
11
- };
12
- "message:sent": {
13
- channel: string;
14
- userId: string;
15
- content: string;
16
- messageId: string;
17
- sessionId: string;
18
- };
19
- "agent:thinking": {
20
- agentId: string;
21
- sessionId: string;
22
- stage: "planning" | "executing" | "responding";
23
- };
24
- "agent:response": {
25
- agentId: string;
26
- sessionId: string;
27
- content: string;
28
- toolsUsed: string[];
29
- duration: number;
30
- };
31
- "tool:executing": {
32
- toolName: string;
33
- args: Record<string, unknown>;
34
- sessionId: string;
35
- };
36
- "tool:completed": {
37
- toolName: string;
38
- result: unknown;
39
- duration: number;
40
- success: boolean;
41
- };
42
- "tool:error": {
43
- toolName: string;
44
- error: Error;
45
- args: Record<string, unknown>;
46
- };
47
- "error": {
48
- source: string;
49
- error: Error;
50
- context: Record<string, unknown>;
51
- recoverable: boolean;
52
- };
53
- "session:started": {
54
- sessionId: string;
55
- agentId: string;
56
- channel: string;
57
- userId: string;
58
- };
59
- "session:ended": {
60
- sessionId: string;
61
- duration: number;
62
- messageCount: number;
63
- reason: "completed" | "cancelled" | "error" | "timeout";
64
- };
65
- "mcp:connected": {
66
- serverName: string;
67
- toolsCount: number;
68
- resourcesCount: number;
69
- };
70
- "mcp:disconnected": {
71
- serverName: string;
72
- reason: string;
73
- };
74
- "mcp:error": {
75
- serverName: string;
76
- error: Error;
77
- };
78
- "channel:started": {
79
- channel: string;
80
- accountId: string;
81
- };
82
- "channel:stopped": {
83
- channel: string;
84
- accountId: string;
85
- reason: string;
86
- };
87
- "gateway:started": {
88
- host: string;
89
- port: number;
90
- };
91
- "gateway:stopped": {
92
- reason: string;
93
- };
94
- "pairing:requested": {
95
- channel: string;
96
- userId: string;
97
- code: string;
98
- expiresAt: number;
99
- };
100
- "pairing:approved": {
101
- channel: string;
102
- userId: string;
103
- };
104
- "pairing:rejected": {
105
- channel: string;
106
- userId: string;
107
- reason: string;
108
- };
109
- "pairing:expired": {
110
- code: string;
111
- channel: string;
112
- userId: string;
113
- };
114
- }
115
-
116
- export type EventKey = keyof EventMap;
117
-
118
- export interface EventHandler<K extends EventKey> {
119
- (data: EventMap[K]): void | Promise<void>;
120
- }
121
-
122
- class TypedEventBusImpl {
123
- private emitter = new EventEmitter();
124
- private logPrefix = "[events]";
125
-
126
- emit<K extends EventKey>(event: K, data: EventMap[K]): void {
127
- const enrichedData = {
128
- ...data,
129
- _eventId: crypto.randomUUID(),
130
- _timestamp: Date.now(),
131
- _event: event,
132
- } as EventMap[K] & { _eventId: string; _timestamp: number; _event: string };
133
-
134
- this.emitter.emit(event, enrichedData);
135
-
136
- if (process.env.DEBUG_EVENTS === "true") {
137
- logger.debug(`${this.logPrefix} emitted: ${event}`, { data });
138
- }
139
- }
140
-
141
- on<K extends EventKey>(event: K, handler: EventHandler<K>): () => void {
142
- this.emitter.on(event, handler);
143
- return () => this.off(event, handler);
144
- }
145
-
146
- once<K extends EventKey>(event: K, handler: EventHandler<K>): void {
147
- this.emitter.once(event, handler);
148
- }
149
-
150
- off<K extends EventKey>(event: K, handler: EventHandler<K>): void {
151
- this.emitter.off(event, handler);
152
- }
153
-
154
- removeAllListeners<K extends EventKey>(event?: K): void {
155
- if (event) {
156
- this.emitter.removeAllListeners(event);
157
- } else {
158
- this.emitter.removeAllListeners();
159
- }
160
- }
161
-
162
- listenerCount<K extends EventKey>(event: K): number {
163
- return this.emitter.listenerCount(event);
164
- }
165
- }
166
-
167
- export const eventBus = new TypedEventBusImpl();
168
-
169
- export type TypedEventBus = typeof eventBus;