@johpaz/hive-sdk 0.1.4 → 0.1.6

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 (278) hide show
  1. package/CHANGELOG.md +129 -0
  2. package/README.md +78 -23
  3. package/bun.lock +55 -29
  4. package/bunfig.toml +4 -2
  5. package/docs/API-AGENTS.md +78 -27
  6. package/docs/API-CONTEXT-COMPILER.md +31 -34
  7. package/docs/API-TOOLS-SKILLS-CHANNELS.md +58 -22
  8. package/docs/HIVE-HARNESS.md +1 -1
  9. package/docs/INDEX.md +4 -4
  10. package/docs/TEMPLATE-HIVE-APP.md +10 -10
  11. package/package.json +17 -12
  12. package/packages/cli/package.json +2 -2
  13. package/packages/cli/src/commands/create-app.test.ts +36 -7
  14. package/packages/cli/src/commands/init.ts +3 -3
  15. package/packages/cli/src/commands/run.ts +1 -1
  16. package/packages/cli/src/commands/test.ts +37 -25
  17. package/packages/cli/src/commands/trace.ts +30 -28
  18. package/packages/cli/templates/hive-app/.env.example +10 -2
  19. package/packages/cli/templates/hive-app/README.md +103 -0
  20. package/packages/cli/templates/hive-app/hive.config.ts +9 -3
  21. package/packages/cli/templates/hive-app/src/agents/coordinator.ts +8 -1
  22. package/packages/cli/templates/hive-app/src/main.ts +12 -19
  23. package/packages/core/package.json +13 -12
  24. package/packages/core/src/agent/acceptance-checks.ts +172 -0
  25. package/packages/core/src/agent/agent-catalog.ts +348 -0
  26. package/packages/core/src/agent/agent-loop.ts +1373 -0
  27. package/packages/core/src/agent/capability-search.ts +186 -0
  28. package/packages/core/src/agent/catalog-selector.ts +103 -0
  29. package/packages/core/src/agent/{Compaction.ts → compaction.ts} +86 -63
  30. package/packages/core/src/agent/context-compiler.ts +689 -0
  31. package/packages/core/src/agent/conversation-store.ts +381 -0
  32. package/packages/core/src/agent/curator.ts +276 -0
  33. package/packages/core/src/agent/delegation-runtime.ts +241 -0
  34. package/packages/core/src/agent/goal-runner.ts +323 -0
  35. package/packages/core/src/agent/index.ts +17 -12
  36. package/packages/core/src/agent/llm-client.ts +266 -0
  37. package/packages/core/src/agent/llm-providers/anthropic.ts +264 -0
  38. package/packages/core/src/agent/llm-providers/deepseek.ts +8 -0
  39. package/packages/core/src/agent/{providers → llm-providers}/gemini.ts +98 -60
  40. package/packages/core/src/agent/llm-providers/groq.ts +5 -0
  41. package/packages/core/src/agent/llm-providers/hiveagents.ts +253 -0
  42. package/packages/core/src/agent/{providers → llm-providers}/interface.ts +73 -13
  43. package/packages/core/src/agent/llm-providers/kimi.ts +8 -0
  44. package/packages/core/src/agent/llm-providers/minimax.ts +13 -0
  45. package/packages/core/src/agent/llm-providers/mistral.ts +5 -0
  46. package/packages/core/src/agent/llm-providers/modelscope.ts +5 -0
  47. package/packages/core/src/agent/llm-providers/nvidia.ts +5 -0
  48. package/packages/core/src/agent/{providers → llm-providers}/ollama.ts +31 -5
  49. package/packages/core/src/agent/llm-providers/openai-compat-base.ts +418 -0
  50. package/packages/core/src/agent/llm-providers/openai.ts +5 -0
  51. package/packages/core/src/agent/llm-providers/opencode-go.ts +9 -0
  52. package/packages/core/src/agent/llm-providers/openrouter.ts +5 -0
  53. package/packages/core/src/agent/llm-providers/qwen.ts +5 -0
  54. package/packages/core/src/agent/llm-providers/z-ai.ts +5 -0
  55. package/packages/core/src/agent/minimal-loadout.ts +47 -0
  56. package/packages/core/src/agent/playbook-selector.ts +119 -0
  57. package/packages/core/src/agent/{PromptBuilder.ts → prompt-builder.ts} +21 -22
  58. package/packages/core/src/{harness → agent}/proof-packet.ts +16 -21
  59. package/packages/core/src/agent/providers/index.ts +35 -16
  60. package/packages/core/src/agent/reflector.ts +320 -0
  61. package/packages/core/src/agent/routing-intent.ts +22 -0
  62. package/packages/core/src/{harness → agent}/run-epoch.ts +4 -3
  63. package/packages/core/src/{harness → agent}/run-store.ts +142 -81
  64. package/packages/core/src/agent/{Service.ts → service.ts} +37 -26
  65. package/packages/core/src/agent/skill-selector.ts +374 -0
  66. package/packages/core/src/agent/stuck-loop.ts +209 -0
  67. package/packages/core/src/agent/{selectors/ToolSelector.ts → tool-selector.ts} +188 -178
  68. package/packages/core/src/{ace/Tracer.ts → agent/tracer.ts} +37 -27
  69. package/packages/core/src/api/createAgent.test.ts +139 -27
  70. package/packages/core/src/api/createAgent.ts +232 -44
  71. package/packages/core/src/artifacts/store.ts +162 -0
  72. package/packages/core/src/canvas/canvas-manager.ts +161 -0
  73. package/packages/core/src/canvas/canvas.test.ts +8 -4
  74. package/packages/core/src/canvas/emitter.ts +131 -80
  75. package/packages/core/src/canvas/index.ts +1 -3
  76. package/packages/core/src/channels/base.ts +9 -1
  77. package/packages/core/src/channels/discord.ts +5 -4
  78. package/packages/core/src/channels/manager.ts +122 -30
  79. package/packages/core/src/channels/slack.ts +5 -4
  80. package/packages/core/src/channels/telegram.ts +36 -6
  81. package/packages/core/src/channels/webchat.ts +11 -10
  82. package/packages/core/src/channels/whatsapp.ts +23 -7
  83. package/packages/core/src/config/index.ts +13 -2
  84. package/packages/core/src/config/loader.ts +76 -29
  85. package/packages/core/src/ethics/EthicsGuard.test.ts +90 -36
  86. package/packages/core/src/ethics/EthicsGuard.ts +51 -47
  87. package/packages/core/src/events/agent-bus.ts +44 -68
  88. package/packages/core/src/events/channel-narration.ts +150 -0
  89. package/packages/core/src/events/narration.ts +82 -0
  90. package/packages/core/src/events/tool-narration.ts +62 -0
  91. package/packages/core/src/gateway/delegation-groups.ts +258 -0
  92. package/packages/core/src/{harness → gateway}/durable-queue.ts +102 -42
  93. package/packages/core/src/{harness → gateway}/job-store.ts +85 -48
  94. package/packages/core/src/gateway/lane-queue.ts +173 -0
  95. package/packages/core/src/gateway/notification-inbox.ts +57 -0
  96. package/packages/core/src/gateway/server.ts +1 -1
  97. package/packages/core/src/harness/index.ts +46 -27
  98. package/packages/core/src/index.ts +33 -27
  99. package/packages/core/src/mcp/hot-reload.ts +32 -23
  100. package/packages/core/src/mcp/index.ts +6 -3
  101. package/packages/core/src/mcp/singleton.ts +1 -4
  102. package/packages/core/src/mcp/tool-sync.ts +138 -0
  103. package/packages/core/src/memory/Scratchpad.test.ts +39 -20
  104. package/packages/core/src/memory/Scratchpad.ts +27 -34
  105. package/packages/core/src/multimodal/vision-service.ts +44 -38
  106. package/packages/core/src/resilience/retry.ts +95 -0
  107. package/packages/core/src/scheduler/CronScheduler.ts +334 -287
  108. package/packages/core/src/scheduler/index.ts +9 -7
  109. package/packages/core/src/scheduler/integration.ts +46 -26
  110. package/packages/core/src/scheduler/scheduler.test.ts +9 -13
  111. package/packages/core/src/scheduler/types.ts +7 -2
  112. package/packages/core/src/security/Pairing.ts +1 -1
  113. package/packages/core/src/skills/bundled/a2ui/a2ui_dashboard/SKILL.md +176 -0
  114. package/packages/core/src/skills/bundled/a2ui/a2ui_form/SKILL.md +202 -0
  115. package/packages/core/src/skills/bundled/a2ui/a2ui_interactive/SKILL.md +206 -0
  116. package/packages/core/src/skills/bundled/agents/agent_spawner/SKILL.md +173 -0
  117. package/packages/core/src/skills/bundled/agents/memory_manager/SKILL.md +143 -0
  118. package/packages/core/src/skills/bundled/agents/research_and_remember/SKILL.md +139 -0
  119. package/packages/core/src/skills/bundled/agents/task_orchestrator/SKILL.md +98 -0
  120. package/packages/core/src/skills/bundled/api/api_client/SKILL.md +132 -0
  121. package/packages/core/src/skills/bundled/cli/cli_pipeline/SKILL.md +135 -0
  122. package/packages/core/src/skills/bundled/cli/cli_safe_exec/SKILL.md +125 -0
  123. package/packages/core/src/skills/bundled/cli/software_engineering/SKILL.md +23 -0
  124. package/packages/core/src/skills/bundled/cron_manager/SKILL.md +188 -0
  125. package/packages/core/src/skills/bundled/cron_reminder/SKILL.md +112 -0
  126. package/packages/core/src/skills/bundled/filesystem/file_manager/SKILL.md +118 -0
  127. package/packages/core/src/skills/bundled/filesystem/file_read_and_summarize/SKILL.md +109 -0
  128. package/packages/core/src/skills/bundled/filesystem/file_writer/SKILL.md +129 -0
  129. package/packages/core/src/skills/bundled/filesystem/workspace_file_operator/SKILL.md +22 -0
  130. package/packages/core/src/skills/bundled/office/office_document_manager/SKILL.md +262 -0
  131. package/packages/core/src/skills/bundled/search_knowledge/capability_discovery/SKILL.md +75 -0
  132. package/packages/core/src/skills/bundled/web/browser_automate/SKILL.md +120 -0
  133. package/packages/core/src/skills/bundled/web/browser_scrape/SKILL.md +109 -0
  134. package/packages/core/src/skills/bundled/web/web_monitor/SKILL.md +127 -0
  135. package/packages/core/src/skills/bundled/web/web_research/SKILL.md +119 -0
  136. package/packages/core/src/skills/bundled-data.generated.ts +731 -2678
  137. package/packages/core/src/skills/skills.test.ts +52 -11
  138. package/packages/core/src/{harness → storage}/boot-id.ts +5 -2
  139. package/packages/core/src/storage/bootstrap.ts +151 -0
  140. package/packages/core/src/storage/causal-events.ts +84 -0
  141. package/packages/core/src/storage/collections.ts +680 -0
  142. package/packages/core/src/storage/crypto.ts +205 -74
  143. package/packages/core/src/{harness/db-helpers.ts → storage/hive.ts} +63 -7
  144. package/packages/core/src/storage/hivedb.ts +61 -0
  145. package/packages/core/src/storage/index.ts +111 -18
  146. package/packages/core/src/storage/model-id.ts +53 -0
  147. package/packages/core/src/storage/onboarding.ts +540 -972
  148. package/packages/core/src/storage/reconcile.ts +238 -0
  149. package/packages/core/src/storage/seed.ts +572 -406
  150. package/packages/core/src/storage/usage.ts +285 -225
  151. package/packages/core/src/storage/user-email.ts +11 -0
  152. package/packages/core/src/swarm/AgentExecutor.ts +1 -1
  153. package/packages/core/src/swarm/EventBridge.ts +1 -1
  154. package/packages/core/src/swarm/index.ts +12 -9
  155. package/packages/core/src/tool-runtime/index.ts +146 -23
  156. package/packages/core/src/tool-runtime/tool-worker.ts +2 -2
  157. package/packages/core/src/tool-runtime/worker-tools.ts +27 -0
  158. package/packages/core/src/{canvas/a2ui-tools.ts → tools/a2ui/index.ts} +17 -8
  159. package/packages/core/src/tools/agents/get-available-models.ts +36 -54
  160. package/packages/core/src/tools/agents/index.ts +784 -292
  161. package/packages/core/src/tools/api/api-request.test.ts +164 -0
  162. package/packages/core/src/tools/api/api-request.ts +174 -0
  163. package/packages/core/src/tools/api/index.ts +16 -0
  164. package/packages/core/src/tools/cli/index.ts +4 -0
  165. package/packages/core/src/tools/core/index.ts +281 -112
  166. package/packages/core/src/tools/cron/index.ts +121 -124
  167. package/packages/core/src/tools/index.ts +63 -78
  168. package/packages/core/src/tools/office/office-escribir-xlsx.ts +3 -1
  169. package/packages/core/src/tools/types.ts +3 -1
  170. package/packages/core/src/tools/web/artifact-inspect.ts +23 -0
  171. package/packages/core/src/tools/web/browser-backend.ts +129 -0
  172. package/packages/core/src/tools/web/browser-screenshot.ts +26 -5
  173. package/packages/core/src/tools/web/browser-service.ts +80 -35
  174. package/packages/core/src/tools/web/browser-type.ts +3 -8
  175. package/packages/core/src/tools/web/index.ts +4 -4
  176. package/packages/core/src/tools/web/webview-backend.ts +412 -0
  177. package/packages/core/src/voice/index.ts +89 -63
  178. package/packages/core/src/workers/agent.worker.ts +2 -2
  179. package/packages/core/src/workers/workers.test.ts +3 -10
  180. package/scripts/bump-version.ts +248 -0
  181. package/scripts/generate-skill-bundle.ts +108 -0
  182. package/test/acceptance-checks.test.ts +403 -0
  183. package/test/agent-loop-terminal-synthesis.test.ts +32 -0
  184. package/test/browser-backend.test.ts +308 -0
  185. package/test/catalog-agents-stay-enabled.test.ts +117 -0
  186. package/test/causal-events.test.ts +117 -0
  187. package/test/compaction.test.ts +105 -0
  188. package/test/context-compiler.test.ts +269 -0
  189. package/test/curator.test.ts +130 -0
  190. package/test/durable-queue.test.ts +114 -0
  191. package/test/harness-barrel.test.ts +64 -0
  192. package/test/hive-helpers.test.ts +130 -0
  193. package/test/hivedb-search.test.ts +189 -0
  194. package/test/internal-turns.test.ts +166 -0
  195. package/test/job-idempotency.test.ts +68 -0
  196. package/test/job-retry-backoff.test.ts +184 -0
  197. package/test/job-store.test.ts +381 -0
  198. package/test/llm-retry.test.ts +97 -0
  199. package/test/memory-perf.test.ts +774 -0
  200. package/test/minimal-loadout.test.ts +78 -0
  201. package/test/model-catalog.test.ts +105 -0
  202. package/test/preload.ts +12 -0
  203. package/test/reflector.test.ts +320 -0
  204. package/test/retention-cap.test.ts +91 -0
  205. package/test/retired-capabilities-pruned.test.ts +192 -0
  206. package/test/run-store.test.ts +355 -0
  207. package/test/scratchpad.test.ts +74 -0
  208. package/test/secrets-durability.test.ts +119 -0
  209. package/test/seed-model-reseed.test.ts +155 -0
  210. package/test/setup-agent-seed.test.ts +264 -0
  211. package/test/tool-inventory.test.ts +65 -0
  212. package/test/tool-runtime.test.ts +258 -0
  213. package/test/tool-selector-runtime-tools.test.ts +117 -0
  214. package/test/toon.test.ts +429 -0
  215. package/tsconfig.json +2 -0
  216. package/packages/core/src/ace/Curator.ts +0 -158
  217. package/packages/core/src/ace/Reflector.ts +0 -200
  218. package/packages/core/src/ace/index.ts +0 -4
  219. package/packages/core/src/agent/AgentRunner.ts +0 -711
  220. package/packages/core/src/agent/ContextCompiler.ts +0 -567
  221. package/packages/core/src/agent/ContextGuard.ts +0 -91
  222. package/packages/core/src/agent/ConversationStore.ts +0 -254
  223. package/packages/core/src/agent/Hooks.ts +0 -166
  224. package/packages/core/src/agent/StuckLoop.ts +0 -133
  225. package/packages/core/src/agent/providers/LLMClient.ts +0 -149
  226. package/packages/core/src/agent/providers/anthropic.ts +0 -212
  227. package/packages/core/src/agent/providers/openai-compat.ts +0 -231
  228. package/packages/core/src/agent/selectors/PlaybookSelector.ts +0 -121
  229. package/packages/core/src/agent/selectors/SkillSelector.ts +0 -322
  230. package/packages/core/src/agent/selectors/index.ts +0 -6
  231. package/packages/core/src/auth/auth.ts +0 -121
  232. package/packages/core/src/auth/index.ts +0 -1
  233. package/packages/core/src/canvas/CanvasManager.ts +0 -390
  234. package/packages/core/src/canvas/canvas-tools.ts +0 -448
  235. package/packages/core/src/harness/collections.ts +0 -98
  236. package/packages/core/src/harness/goal-verifier.ts +0 -141
  237. package/packages/core/src/harness/harness.test.ts +0 -236
  238. package/packages/core/src/harness/reconcile.ts +0 -149
  239. package/packages/core/src/mcp/MCPToolAdapter.ts +0 -176
  240. package/packages/core/src/multimodal/VisionService.ts +0 -293
  241. package/packages/core/src/scheduler/dag/AgentExecutor.ts +0 -53
  242. package/packages/core/src/scheduler/dag/DAGScheduler.ts +0 -250
  243. package/packages/core/src/scheduler/dag/EventBridge.ts +0 -122
  244. package/packages/core/src/scheduler/dag/TaskGraph.ts +0 -192
  245. package/packages/core/src/scheduler/dag/TaskNode.ts +0 -97
  246. package/packages/core/src/scheduler/dag/TaskResult.ts +0 -22
  247. package/packages/core/src/scheduler/dag/errors.ts +0 -37
  248. package/packages/core/src/scheduler/dag/index.ts +0 -26
  249. package/packages/core/src/scheduler/dag/presets/ResearchPreset.ts +0 -97
  250. package/packages/core/src/scheduler/dag/strategies/ParallelStrategy.ts +0 -21
  251. package/packages/core/src/scheduler/dag/strategies/PriorityStrategy.ts +0 -46
  252. package/packages/core/src/storage/HiveDBStorage.ts +0 -64
  253. package/packages/core/src/storage/SQLiteStorage.ts +0 -414
  254. package/packages/core/src/storage/hiveSeed.ts +0 -308
  255. package/packages/core/src/storage/hiveStorage.test.ts +0 -38
  256. package/packages/core/src/storage/schema.ts +0 -689
  257. package/packages/core/src/storage/storage.test.ts +0 -37
  258. package/packages/core/src/swarm/AgentBus.ts +0 -460
  259. package/packages/core/src/swarm/EventBus.ts +0 -169
  260. package/packages/core/src/swarm/WorkerPool.ts +0 -236
  261. package/packages/core/src/tools/bridge-events.ts +0 -26
  262. package/packages/core/src/tools/canvas/index.ts +0 -375
  263. package/packages/core/src/tools/codebridge/index.ts +0 -342
  264. package/packages/core/src/tools/meeting/index.ts +0 -353
  265. package/packages/core/src/tools/projects/index.ts +0 -37
  266. package/packages/core/src/tools/projects/project-create.ts +0 -94
  267. package/packages/core/src/tools/projects/project-done.ts +0 -66
  268. package/packages/core/src/tools/projects/project-fail.ts +0 -66
  269. package/packages/core/src/tools/projects/project-list.ts +0 -96
  270. package/packages/core/src/tools/projects/project-update.ts +0 -72
  271. package/packages/core/src/tools/projects/task-create.ts +0 -68
  272. package/packages/core/src/tools/projects/task-evaluate.ts +0 -93
  273. package/packages/core/src/tools/projects/task-update.ts +0 -93
  274. package/packages/core/src/tools/voice/index.ts +0 -104
  275. package/packages/core/src/tools/web/api-request.test.ts +0 -170
  276. package/packages/core/src/tools/web/api-request.ts +0 -239
  277. package/test/setup-db.ts +0 -216
  278. /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;