@johpaz/hive-sdk 0.1.6 → 0.3.0

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 (238) hide show
  1. package/CHANGELOG.md +441 -0
  2. package/README.md +21 -3
  3. package/package.json +27 -5
  4. package/packages/core/src/agent/acceptance-checks.ts +9 -9
  5. package/packages/core/src/agent/agent-catalog.ts +82 -25
  6. package/packages/core/src/agent/agent-loop.ts +115 -26
  7. package/packages/core/src/agent/capability-search.ts +2 -2
  8. package/packages/core/src/agent/catalog-selector.ts +4 -4
  9. package/packages/core/src/agent/compaction.ts +30 -10
  10. package/packages/core/src/agent/context-compiler.ts +63 -36
  11. package/packages/core/src/agent/conversation-store.ts +167 -9
  12. package/packages/core/src/agent/curator.ts +16 -7
  13. package/packages/core/src/agent/delegation-runtime.ts +5 -5
  14. package/packages/core/src/agent/goal-runner.ts +9 -9
  15. package/packages/core/src/agent/index.ts +1 -0
  16. package/packages/core/src/agent/llm-client.ts +98 -37
  17. package/packages/core/src/agent/llm-providers/anthropic.ts +4 -4
  18. package/packages/core/src/agent/llm-providers/deepseek.ts +1 -1
  19. package/packages/core/src/agent/llm-providers/gemini.ts +4 -4
  20. package/packages/core/src/agent/llm-providers/groq.ts +1 -1
  21. package/packages/core/src/agent/llm-providers/hiveagents.ts +3 -3
  22. package/packages/core/src/agent/llm-providers/interface.ts +2 -2
  23. package/packages/core/src/agent/llm-providers/kimi.ts +1 -1
  24. package/packages/core/src/agent/llm-providers/minimax.ts +1 -1
  25. package/packages/core/src/agent/llm-providers/mistral.ts +1 -1
  26. package/packages/core/src/agent/llm-providers/modelscope.ts +1 -1
  27. package/packages/core/src/agent/llm-providers/nvidia.ts +40 -1
  28. package/packages/core/src/agent/llm-providers/ollama.ts +4 -4
  29. package/packages/core/src/agent/llm-providers/openai-compat-base.ts +47 -7
  30. package/packages/core/src/agent/llm-providers/openai.ts +1 -1
  31. package/packages/core/src/agent/llm-providers/opencode-go.ts +1 -1
  32. package/packages/core/src/agent/llm-providers/openrouter.ts +1 -1
  33. package/packages/core/src/agent/llm-providers/qwen.ts +1 -1
  34. package/packages/core/src/agent/llm-providers/z-ai.ts +1 -1
  35. package/packages/core/src/agent/mcp-result-normalizer.ts +192 -0
  36. package/packages/core/src/agent/playbook-selector.ts +22 -7
  37. package/packages/core/src/agent/prompt-builder.ts +5 -5
  38. package/packages/core/src/agent/proof-packet.ts +5 -5
  39. package/packages/core/src/agent/providers/index.ts +39 -4
  40. package/packages/core/src/agent/realtime-providers/gemini-live.ts +238 -0
  41. package/packages/core/src/agent/realtime-providers/index.ts +29 -0
  42. package/packages/core/src/agent/realtime-providers/interface.ts +108 -0
  43. package/packages/core/src/agent/reflector.ts +38 -15
  44. package/packages/core/src/agent/run-store.ts +8 -8
  45. package/packages/core/src/agent/service.ts +10 -10
  46. package/packages/core/src/agent/skill-selector.ts +6 -6
  47. package/packages/core/src/agent/thread-id.ts +71 -0
  48. package/packages/core/src/agent/thread-store.ts +293 -0
  49. package/packages/core/src/agent/tool-selector.ts +9 -5
  50. package/packages/core/src/agent/tracer.ts +5 -5
  51. package/packages/core/src/api/createAgent.ts +67 -2
  52. package/packages/core/src/artifacts/index.ts +15 -0
  53. package/packages/core/src/artifacts/store.ts +161 -5
  54. package/packages/core/src/canvas/emitter.ts +2 -2
  55. package/packages/core/src/canvas/index.ts +9 -0
  56. package/packages/core/src/channels/telegram.ts +1 -1
  57. package/packages/core/src/channels/webchat.ts +1 -1
  58. package/packages/core/src/config/loader.ts +14 -5
  59. package/packages/core/src/ethics/EthicsGuard.ts +7 -1
  60. package/packages/core/src/events/agent-bus.ts +3 -3
  61. package/packages/core/src/events/channel-narration.ts +3 -3
  62. package/packages/core/src/events/event-bus.ts +1 -1
  63. package/packages/core/src/events/index.ts +18 -0
  64. package/packages/core/src/events/narration.ts +3 -3
  65. package/packages/core/src/events/tool-narration.ts +4 -0
  66. package/packages/core/src/gateway/channel-notify.ts +103 -6
  67. package/packages/core/src/gateway/delegation-groups.ts +4 -4
  68. package/packages/core/src/gateway/durable-queue.ts +18 -6
  69. package/packages/core/src/gateway/index.ts +3 -0
  70. package/packages/core/src/gateway/job-store.ts +11 -5
  71. package/packages/core/src/gateway/notification-inbox.ts +2 -2
  72. package/packages/core/src/gateway/server.ts +2 -2
  73. package/packages/core/src/harness/executors.ts +493 -0
  74. package/packages/core/src/harness/index.ts +12 -2
  75. package/packages/core/src/hooks/index.ts +203 -0
  76. package/packages/core/src/images/index.ts +161 -0
  77. package/packages/core/src/index.ts +1 -0
  78. package/packages/core/src/mcp/MCPClient.ts +3 -3
  79. package/packages/core/src/mcp/hot-reload.ts +5 -5
  80. package/packages/core/src/mcp/tool-sync.ts +5 -5
  81. package/packages/core/src/mcp/transports/index.ts +2 -2
  82. package/packages/core/src/mcp/transports/sse.ts +1 -1
  83. package/packages/core/src/models/index.ts +36 -0
  84. package/packages/core/src/multimodal/index.ts +2 -2
  85. package/packages/core/src/multimodal/vision-service.ts +51 -19
  86. package/packages/core/src/plugins/loader.ts +4 -1
  87. package/packages/core/src/resilience/circuit-breaker.ts +16 -5
  88. package/packages/core/src/resilience/index.ts +13 -0
  89. package/packages/core/src/resilience/retry.ts +1 -1
  90. package/packages/core/src/scheduler/CronScheduler.ts +54 -27
  91. package/packages/core/src/scheduler/cron/expression.ts +165 -0
  92. package/packages/core/src/scheduler/cron/index.ts +10 -0
  93. package/packages/core/src/scheduler/cron/job.ts +339 -0
  94. package/packages/core/src/scheduler/cron/next-run.ts +121 -0
  95. package/packages/core/src/scheduler/cron/zoned-time.ts +138 -0
  96. package/packages/core/src/scheduler/index.ts +21 -3
  97. package/packages/core/src/scheduler/integration.ts +25 -14
  98. package/packages/core/src/scheduler/types.ts +3 -18
  99. package/packages/core/src/services/agents.ts +268 -0
  100. package/packages/core/src/services/cron.ts +257 -0
  101. package/packages/core/src/services/endpoints.ts +289 -0
  102. package/packages/core/src/services/ethics.ts +107 -0
  103. package/packages/core/src/services/images.ts +212 -0
  104. package/packages/core/src/services/index.ts +112 -0
  105. package/packages/core/src/services/mcp.ts +201 -0
  106. package/packages/core/src/services/memory.ts +133 -0
  107. package/packages/core/src/services/models.ts +179 -0
  108. package/packages/core/src/services/providers.ts +152 -0
  109. package/packages/core/src/services/setup.ts +222 -0
  110. package/packages/core/src/services/skills.ts +241 -0
  111. package/packages/core/src/services/swarms.ts +307 -0
  112. package/packages/core/src/services/tools.ts +106 -0
  113. package/packages/core/src/sessions/index.ts +268 -0
  114. package/packages/core/src/sessions/resolve.ts +108 -0
  115. package/packages/core/src/skills/SkillLoader.ts +8 -1
  116. package/packages/core/src/skills/bundled/artifacts/artifact_reader/SKILL.md +105 -0
  117. package/packages/core/src/skills/bundled/cron_manager/SKILL.md +21 -11
  118. package/packages/core/src/skills/bundled/images/image_editor/SKILL.md +120 -0
  119. package/packages/core/src/skills/bundled/web/browser_automate/SKILL.md +12 -3
  120. package/packages/core/src/skills/bundled/web/browser_scrape/SKILL.md +22 -7
  121. package/packages/core/src/skills/bundled-data.generated.ts +110 -12
  122. package/packages/core/src/storage/bootstrap.ts +107 -12
  123. package/packages/core/src/storage/causal-events.ts +1 -1
  124. package/packages/core/src/storage/collections.ts +138 -2
  125. package/packages/core/src/storage/crypto.ts +35 -4
  126. package/packages/core/src/storage/hive.ts +1 -1
  127. package/packages/core/src/storage/hivedb.ts +10 -1
  128. package/packages/core/src/storage/index.ts +2 -1
  129. package/packages/core/src/storage/onboarding.ts +61 -45
  130. package/packages/core/src/storage/reconcile.ts +11 -6
  131. package/packages/core/src/storage/seed.ts +191 -23
  132. package/packages/core/src/storage/usage.ts +3 -3
  133. package/packages/core/src/swarm/AgentExecutor.ts +2 -2
  134. package/packages/core/src/swarm/Coordinator.ts +8 -8
  135. package/packages/core/src/swarm/EventBridge.ts +2 -2
  136. package/packages/core/src/swarm/RoleSwarm.ts +234 -0
  137. package/packages/core/src/swarm/TaskGraph.ts +2 -2
  138. package/packages/core/src/swarm/index.ts +7 -0
  139. package/packages/core/src/swarm/presets/HiveLearnPreset.ts +2 -2
  140. package/packages/core/src/swarm/presets/ResearchPreset.ts +2 -2
  141. package/packages/core/src/swarm/strategies/ParallelStrategy.ts +1 -1
  142. package/packages/core/src/swarm/strategies/PriorityStrategy.ts +3 -3
  143. package/packages/core/src/swarm/types.ts +3 -18
  144. package/packages/core/src/tool-runtime/embedded-worker.generated.ts +21 -0
  145. package/packages/core/src/tool-runtime/index.ts +129 -14
  146. package/packages/core/src/tools/ToolExecutor.ts +7 -3
  147. package/packages/core/src/tools/agents/index.ts +18 -60
  148. package/packages/core/src/tools/cli/index.ts +55 -0
  149. package/packages/core/src/tools/core/index.ts +52 -4
  150. package/packages/core/src/tools/cron/index.ts +8 -8
  151. package/packages/core/src/tools/images/index.ts +130 -0
  152. package/packages/core/src/tools/index.ts +14 -1
  153. package/packages/core/src/tools/office/office-escribir-xlsx.ts +2 -1
  154. package/packages/core/src/tools/office/office-leer-xlsx.ts +2 -1
  155. package/packages/core/src/tools/office/xlsx-loader.ts +19 -0
  156. package/packages/core/src/tools/web/artifact-inspect.ts +2 -2
  157. package/packages/core/src/tools/web/artifact-read.ts +162 -0
  158. package/packages/core/src/tools/web/browser-backend.ts +141 -44
  159. package/packages/core/src/tools/web/browser-click.ts +2 -2
  160. package/packages/core/src/tools/web/browser-extract.ts +2 -2
  161. package/packages/core/src/tools/web/browser-navigate.ts +2 -2
  162. package/packages/core/src/tools/web/browser-screenshot.ts +12 -5
  163. package/packages/core/src/tools/web/browser-script.ts +2 -2
  164. package/packages/core/src/tools/web/browser-service.ts +63 -384
  165. package/packages/core/src/tools/web/browser-session.ts +125 -0
  166. package/packages/core/src/tools/web/browser-type.ts +2 -2
  167. package/packages/core/src/tools/web/browser-wait.ts +2 -2
  168. package/packages/core/src/tools/web/computer-use.ts +553 -0
  169. package/packages/core/src/tools/web/index.ts +8 -1
  170. package/packages/core/src/tools/web/webview-backend.ts +460 -21
  171. package/packages/core/src/utils/index.ts +1 -0
  172. package/packages/core/src/utils/logger.ts +12 -4
  173. package/packages/core/src/utils/redact-binary.ts +17 -0
  174. package/packages/core/src/utils/toon.ts +1 -1
  175. package/packages/core/src/voice/index.ts +6 -6
  176. package/bun.lock +0 -859
  177. package/bunfig.toml +0 -9
  178. package/docs/API-AGENTS.md +0 -367
  179. package/docs/API-CONTEXT-COMPILER.md +0 -249
  180. package/docs/API-DAG-SCHEDULER.md +0 -273
  181. package/docs/API-TOOLS-SKILLS-CHANNELS.md +0 -446
  182. package/docs/API-WORKERS-EVENTS.md +0 -299
  183. package/docs/HIVE-HARNESS.md +0 -113
  184. package/docs/INDEX.md +0 -190
  185. package/docs/TEMPLATE-HIVE-APP.md +0 -360
  186. package/packages/cli/package.json +0 -17
  187. package/packages/cli/src/commands/create-app.test.ts +0 -180
  188. package/packages/core/package.json +0 -70
  189. package/packages/core/src/api/createAgent.test.ts +0 -160
  190. package/packages/core/src/canvas/canvas.test.ts +0 -36
  191. package/packages/core/src/channels/channels.test.ts +0 -18
  192. package/packages/core/src/ethics/EthicsGuard.test.ts +0 -108
  193. package/packages/core/src/gateway/gateway.test.ts +0 -38
  194. package/packages/core/src/memory/Scratchpad.test.ts +0 -68
  195. package/packages/core/src/scheduler/scheduler.test.ts +0 -15
  196. package/packages/core/src/skills/skills.test.ts +0 -62
  197. package/packages/core/src/swarm/swarm.test.ts +0 -24
  198. package/packages/core/src/tool-runtime/tool-runtime.test.ts +0 -99
  199. package/packages/core/src/tools/ToolRegistry.test.ts +0 -98
  200. package/packages/core/src/tools/api/api-request.test.ts +0 -164
  201. package/packages/core/src/tools/web/browser-service.test.ts +0 -83
  202. package/packages/core/src/workers/workers.test.ts +0 -41
  203. package/scripts/bump-version.ts +0 -248
  204. package/scripts/generate-skill-bundle.ts +0 -108
  205. package/test/acceptance-checks.test.ts +0 -403
  206. package/test/agent-loop-terminal-synthesis.test.ts +0 -32
  207. package/test/browser-backend.test.ts +0 -308
  208. package/test/catalog-agents-stay-enabled.test.ts +0 -117
  209. package/test/causal-events.test.ts +0 -117
  210. package/test/compaction.test.ts +0 -105
  211. package/test/context-compiler.test.ts +0 -269
  212. package/test/curator.test.ts +0 -130
  213. package/test/durable-queue.test.ts +0 -114
  214. package/test/harness-barrel.test.ts +0 -64
  215. package/test/hive-helpers.test.ts +0 -130
  216. package/test/hivedb-search.test.ts +0 -189
  217. package/test/internal-turns.test.ts +0 -166
  218. package/test/job-idempotency.test.ts +0 -68
  219. package/test/job-retry-backoff.test.ts +0 -184
  220. package/test/job-store.test.ts +0 -381
  221. package/test/llm-retry.test.ts +0 -97
  222. package/test/memory-perf.test.ts +0 -774
  223. package/test/minimal-loadout.test.ts +0 -78
  224. package/test/model-catalog.test.ts +0 -105
  225. package/test/preload.ts +0 -12
  226. package/test/reflector.test.ts +0 -320
  227. package/test/retention-cap.test.ts +0 -91
  228. package/test/retired-capabilities-pruned.test.ts +0 -192
  229. package/test/run-store.test.ts +0 -355
  230. package/test/scratchpad.test.ts +0 -74
  231. package/test/secrets-durability.test.ts +0 -119
  232. package/test/seed-model-reseed.test.ts +0 -155
  233. package/test/setup-agent-seed.test.ts +0 -264
  234. package/test/tool-inventory.test.ts +0 -65
  235. package/test/tool-runtime.test.ts +0 -258
  236. package/test/tool-selector-runtime-tools.test.ts +0 -117
  237. package/test/toon.test.ts +0 -429
  238. package/tsconfig.json +0 -42
package/CHANGELOG.md CHANGED
@@ -2,16 +2,457 @@
2
2
 
3
3
  ## Sin publicar
4
4
 
5
+ ### Corregido
6
+
7
+ - **`browser_scrape` extraía con una tool que no ve lo que el navegador
8
+ renderizó.** La skill existe para sitios dinámicos, y su paso de extracción
9
+ usaba `web_fetch`, que vuelve a pedir la URL al servidor y recibe el HTML sin
10
+ JavaScript ejecutado: en un SPA, una cáscara vacía. Pasa a usar
11
+ `browser_extract`, que lee el DOM ya renderizado, con un `browser_wait` previo.
12
+ (Uno de sus ejemplos citaba además `browser_fetch`, que no existe.)
13
+
14
+ - **`browser_automate` no esperaba a los elementos.** Sus pasos iban de navegar a
15
+ hacer clic sin `browser_wait` en el medio, que es la falla más común de la
16
+ automatización web y falla en silencio. Se agregó el paso y el orden de
17
+ escalada: selector → `browser_script` → `computer_use_task`.
18
+
19
+ - **La tabla de campos de `cron_manager` omitía la mitad de lo que acepta la
20
+ tool**: `max_runs`, `payload`, `agent_id` y `tool_name`. También documentaba
21
+ expresiones de 5 campos cuando el motor acepta 6, y no aclaraba que la zona
22
+ horaria sale del perfil del usuario y no se pasa en la llamada.
23
+
24
+ - **Los contadores del scheduler perdían actualizaciones.** `run_count` y
25
+ `error_count` se calculaban desde una lectura hecha antes del bucle de
26
+ reintento de `updateJob`, así que al reintentar por conflicto de versión se
27
+ reescribía el valor viejo. Con dos corridas solapadas del mismo job —normal en
28
+ uno que tarda más que su intervalo y no declara `protect`, y garantizado en la
29
+ puesta al día por misfire, que llama a `execute()` en paralelo con el job ya
30
+ activado— ambas leían `error_count: 4` y ambas escribían 5. La consecuencia no
31
+ era el número: es que el umbral de auto-pausa (5 errores seguidos) no se
32
+ alcanzaba nunca y un job que fallaba siempre se quedaba reintentando para
33
+ siempre. `updateJob` ahora acepta un parche en forma de función, que se evalúa
34
+ contra la lectura fresca de cada intento. Es el mismo error que ya se corrigió
35
+ en `touchThread`. Cubierto por `packages/core/src/scheduler/scheduler.test.ts`.
36
+
37
+ ### Agregado
38
+
39
+ - **El seed inicial de especialistas es una elección.** `ensureHiveDb()` y
40
+ `seedAllData()` aceptan `specialists: "all" | "none" | string[]`. Con `"none"`
41
+ la colmena arranca sin ningún especialista y con sólo las `MINIMAL_TOOLS`
42
+ activas —la competencia del coordinador—, y son los enjambres los que traen
43
+ consigo a los suyos. `"all"` sigue siendo el default, así que nada cambia para
44
+ quien no lo pida.
45
+
46
+ La elección alcanza también a las **capacidades**, no sólo a los agentes: una
47
+ fila de tool o skill que nace en un arranque `"none"` nace inactiva. Antes
48
+ `active` defaulteaba a `true` para toda fila nueva, así que un arranque sin
49
+ especialistas dejaba igual las 62 tools encendidas — el usuario terminaba
50
+ apagando a mano lo que nunca pidió.
51
+
52
+ **Nunca borra.** La elección gobierna qué se crea, no qué se conserva: una
53
+ base que ya tiene sus ocho agentes no pierde ninguno por arrancar con
54
+ `"none"`, y se siguen reconciliando en cada arranque.
55
+
56
+ `createSwarm` acepta ahora miembros del catálogo que todavía no tienen fila:
57
+ con el seed en `"none"` un enjambre es el **pedido de instalación**, no una
58
+ referencia a algo que ya debería existir. Un id que no es del catálogo y no
59
+ existe sigue siendo un error.
60
+
61
+ - **Crear un enjambre ahora siembra sus especialistas.** El seed selectivo
62
+ (`applySeedPlan`) dejaba elegir qué personas del catálogo instalar, pero
63
+ `createSwarm` no lo miraba: guardaba el enjambre **sin una queja** con
64
+ miembros apagados y sus tools inactivas. La validación de "el agente existe"
65
+ pasaba igual, porque el seed crea las 8 filas siempre y sólo cambia `enabled`
66
+ — el enjambre quedaba definido y sin poder trabajar.
67
+
68
+ `createSwarm` y `updateSwarm` aceptan `activateMembers`, **`false` por
69
+ defecto**: crear un enjambre no debería cambiar en silencio qué capacidades
70
+ tiene la instalación entera, así que sin él el enjambre se crea igual y el
71
+ faltante vuelve en `pendingActivation` para que la UI lo muestre y el usuario
72
+ decida. Con `true` se activa la unión con lo que ya estaba, de modo que
73
+ encender los especialistas de un enjambre nunca apaga los de otro.
74
+
75
+ Se agregó `planActivationFor(agentIds)`, que devuelve el faltante **sin
76
+ encender nada** —para el "esto se va a activar" antes de confirmar— y
77
+ `enableCatalogAgents(ids)` en plural, porque activarlos de a uno reescribía el
78
+ catálogo entero una vez por agente. Cubierto por `test/swarm-seed.test.ts`.
79
+
80
+ - **Skills para las capacidades que no tenían ninguna.** `image_editor`
81
+ (`image_metadata`, `image_transform`, `artifact_inspect`) y `artifact_reader`
82
+ (`artifact_read`, `artifact_inspect`). Las tools existían pero ninguna skill
83
+ las enseñaba, así que el modelo sólo podía dar con ellas de casualidad vía
84
+ `search_knowledge` — y en el caso de los artefactos eso deja inerte todo el
85
+ mecanismo de `artifact_ref`, que existe justamente para que los archivos
86
+ grandes no entren en la ventana de contexto.
87
+
88
+
89
+ - **`sessionStart` y `sessionEnd` ya se disparan.** Eran registrables desde que
90
+ se implementaron los hooks, pero nada los invocaba. Van enganchados a las
91
+ cuatro transiciones del ciclo de vida del hilo (crear, reabrir, archivar,
92
+ borrar), todas en `agent/thread-store.ts`. `sessionStart` cuelga del `put` que
93
+ crea la fila y no de `createSession`, que es idempotente y se llama en cada
94
+ turno: enganchado ahí habría contado mensajes en vez de conversaciones.
95
+ `closeSession`/`reopenSession` pasan a delegar en los nuevos `archiveThread`
96
+ y `unarchiveThread` para que las cuatro transiciones vivan en un solo archivo.
97
+ Cubierto por `test/hooks.test.ts`.
98
+
99
+ ### Quitado
100
+
101
+ - **Cero dependencias para el cron: fuera `croner` y `cron-parser`.** El motor
102
+ ahora es propio (`scheduler/cron/`) y usa sólo `setTimeout` e `Intl` del
103
+ runtime. `cron-parser` además ni siquiera se importaba: estaba declarada en
104
+ los dos `package.json` y se la bajaba todo el que instalara el SDK.
105
+
106
+ `Bun.cron()` **no** sirve como reemplazo —evaluado contra el runtime 1.4.0—:
107
+ acepta sólo 5 campos, rechaza una fecha ISO como patrón (que es como se
108
+ agendan los jobs `one_shot`), ignora la zona horaria en `parse()`, y su handle
109
+ no expone la próxima corrida, de donde sale `next_run_at` y con lo que se
110
+ detectan las corridas perdidas al arrancar. Tampoco tiene equivalente de
111
+ `protect`, `maxRuns`, `interval`, `startAt`/`stopAt` ni `domAndDow`, todos
112
+ campos persistidos de `CronJobDoc`.
113
+
114
+ El motor propio conserva la superficie entera, así que `CronScheduler` no
115
+ cambió de comportamiento, e implementa además los dos casos de horario de
116
+ verano que se rompen callados: la hora que **no existe** al adelantar el
117
+ reloj (se saltea ese día en vez de correr a una hora inventada) y la que
118
+ **ocurre dos veces** al atrasarlo (corre en la primera, una sola vez). El
119
+ motor se exporta suelto desde `./scheduler` —`Cron`, `parseCronExpression`,
120
+ `isValidCronExpression`, `nextOccurrence`— para validar o previsualizar sin
121
+ montar un scheduler. Documentado en `docs/API-CRON.md`. Cubierto por
122
+ `packages/core/src/scheduler/cron/cron-engine.test.ts` (28 tests).
123
+
124
+ - **`CronerOptions` (tipo público).** Estaba declarado dos veces —en
125
+ `scheduler/types.ts` y en `swarm/types.ts`— y no tipaba nada en ninguna parte:
126
+ un tipo muerto con el nombre de una librería que ya no se usa. Su forma es la
127
+ de `CronOptions`, que ahora exporta el motor desde `./scheduler`.
128
+
129
+ - **Menciones a Croner en lo que lee el modelo.** Las descripciones de
130
+ `cron.create` (`start_at`, `stop_at`, `dom_and_dow`) y la skill `cron_manager`
131
+ citaban opciones "de Croner". Eso entra en el prompt: nombrarle al modelo una
132
+ librería que el código ya no usa lo manda a buscar documentación que no
133
+ aplica. Quedan sólo las referencias históricas que explican por qué el motor
134
+ es propio.
135
+
5
136
  ### Seguridad
6
137
 
138
+ - **El playbook ACE no distinguía de quién era lo aprendido.** `PlaybookDoc` y
139
+ `ReflectionDoc` no tenían `user_id`, así que la cadena entera —trazas →
140
+ reflexión → regla → inyección en el system prompt— era global: lo que el
141
+ agente aprendía interactuando con una persona se le aplicaba a todas las demás
142
+ del mismo proceso. Es el mismo supuesto de "un solo usuario" que ya se había
143
+ cerrado en `memory`. Ahora el reflector agrupa las trazas por usuario
144
+ (derivado del `thread_id`), el curador propaga el dueño a la regla y deduplica
145
+ dentro del usuario, y las tres puertas de lectura filtran a global + propio:
146
+ `selectPlaybookRules(texto, userId)`, `EthicsGuard.getRules(rol, userId)` y la
147
+ tool `search_knowledge`. Las reglas sembradas siguen siendo globales a
148
+ propósito (`user_id: ""`): son conocimiento del producto, no de nadie.
149
+ `ensureHiveDb()` migra las filas anteriores asignándolas al primer usuario de
150
+ la base — dejarlas sin dueño las volvería globales, que es justo lo que se
151
+ viene a cerrar. Cubierto por `test/playbook-isolation.test.ts`.
152
+
153
+ - **La lista blanca de tools no se aplicaba al descubrimiento dinámico.**
154
+ `compileContext` sólo recortaba `allTools` cuando el agente era de catálogo
155
+ (`source === "catalog"`). Un agente creado por el usuario veía su loadout
156
+ inicial restringido, pero `search_knowledge` busca contra el índice completo y
157
+ el agent loop inyecta lo que encuentre resolviéndolo contra `allTools`: la
158
+ tool excluida terminaba siendo llamable igual. Ahora la restricción depende de
159
+ que el agente declare una lista, no de su origen. Cubierto por
160
+ `test/tool-allowlist-discovery.test.ts`.
161
+
162
+ - **Aislamiento de credenciales entre inquilinos.** `AgentLoopOptions` no tenía
163
+ forma de recibir la key del proveedor, así que la única fuente era el secret
164
+ store de HiveDB o `process.env[PROVIDER_API_KEY]`, ambos globales al proceso.
165
+ Un host multi-tenant que corriera dos workspaces en el mismo proceso les daba
166
+ la misma credencial. Se agregó `credentials` en `AgentLoopOptions`,
167
+ `IsolatedAgentOptions` y `resolveProviderConfig`; la credencial de la llamada
168
+ gana y corta ahí, sin consultar las fuentes globales ni mutar `process.env`.
169
+ Retrocompatible: sin `credentials` el comportamiento es el de siempre.
170
+ Cubierto por `test/tenant-isolation.test.ts`.
171
+
172
+
7
173
  - **`sanitizeDiagnostic` dejaba el token en claro detrás del esquema de auth.**
8
174
  La regex consumía sólo la palabra `Bearer`, así que un diagnóstico con
9
175
  `authorization: Bearer <token>` quedaba como `authorization: [REDACTED] <token>`
10
176
  y la credencial viajaba al prompt del coordinador. Afecta a **0.1.5 y
11
177
  anteriores**: el archivo viaja en el tarball publicado.
12
178
 
179
+ ### Cambiado
180
+
181
+ - **Los tests que manejan un navegador real son opt-in (`BROWSER_TESTS=1`).**
182
+ Su guarda era `isWebViewSupported()`, que sólo comprueba que exista un binario
183
+ de Chromium — no que arranque. En un runner de CI (contenedor, a menudo root)
184
+ el binario está y Chromium muere igual sin `--no-sandbox`, así que ~90 tests
185
+ de integración fallaban por el entorno. Como los tests son condición para
186
+ publicar, eso bloqueaba el release. Los describe unitarios de esos mismos
187
+ archivos —`resolveBackendKind`, detección de motor, `normalizeCookies`,
188
+ `sessionPersistenceEnabled`— siguen corriendo siempre: son los que cubren el
189
+ contrato del backend.
190
+
191
+ - **Se quitó un `mock.module` que se filtraba entre archivos de test.** El test
192
+ de aislamiento multi-tenant sustituía el módulo `storage/crypto` para no
193
+ escribir en el keychain del SO. `mock.module` es global al proceso, no al
194
+ archivo: mientras estuviera activo, cualquier otro test que importara ese
195
+ módulo recibía el doble, y `loadProviderApiKey` devolvía la key del mock. Que
196
+ mordiera dependía del orden de ejecución — pasaba en local y fallaba en CI.
197
+ Ahora el test usa un id de proveedor propio (`test-tenant-isolation`) y limpia
198
+ sus secretos, sin tocar el módulo ni la credencial de nadie.
199
+
200
+ - **El caché de disponibilidad del keychain se envenenaba para todo el proceso.**
201
+ `_keychainOk` recuerda si `Bun.secrets` respondió, para no reintentar en cada
202
+ lectura en un servidor sin libsecret. El problema es que ese resultado valía
203
+ para siempre: una vez marcado como no disponible, sustituir `Bun.secrets` por
204
+ otro backend —o por un doble de test— no servía de nada, porque la lectura
205
+ cortaba antes de tocarlo. Ahora se detecta que el objeto cambió de identidad y
206
+ el sondeo se invalida solo. Era la causa de que el test de compatibilidad con
207
+ keychain fallara en CI headless (y sólo ahí).
208
+
209
+ - **`resetKeychainProbe()`** en `storage/crypto.ts`. Si el keychain del SO no
210
+ responde, el resultado se cachea a nivel de módulo para no reintentar en cada
211
+ lectura — correcto en producción, pero significa que el primer sondeo vale
212
+ para todo el proceso. Un test que sustituya `Bun.secrets` por un doble queda
213
+ cortocircuitado si algo ya sondeó y falló antes, que es lo que pasa en CI
214
+ headless.
215
+
216
+
217
+ - **Automatización web: un solo backend, `Bun.WebView`.** Se retiró
218
+ `AgentBrowserBackend`, que hablaba con el CLI de agent-browser por
219
+ subproceso. El motivo no es de estilo: medido en Bun 1.4 el WebView **sí**
220
+ corre headless (Bun lanza Chromium con `--headless`), que era la única razón
221
+ por la que agent-browser seguía siendo el default. Lo que quedaba era su
222
+ costo — ~40 ms de `Bun.spawn` por operación contra ~0,3 ms, y ~88 MB con su
223
+ propia copia de Chrome.
224
+
225
+ Lo importante para quien consume el paquete: el backend viejo ejecutaba
226
+ **`bun add agent-browser@latest` en el entorno del consumidor**, al primer uso
227
+ de una browser tool. Una versión flotante bajada de npm en runtime, en
228
+ producción. Eso ya no existe.
229
+
230
+ Requisitos ahora: un Chromium instalado (o `BUN_CHROME_PATH`) y **Bun ≥ 1.4**,
231
+ declarado en `engines`. La clave de config `tools.browser.backend` sobrevive:
232
+ `"agent-browser"` se acepta, avisa una vez y usa el WebView, así que las
233
+ configuraciones viejas no se rompen.
234
+
235
+ - **Sesión de navegador persistente** (`tools/web/browser-session.ts`). El
236
+ perfil de Chrome que abre Bun es efímero —su ruta lleva un hash que cambia
237
+ entre procesos— así que las cookies se guardan y restauran a mano. Sin esto
238
+ cada reinicio empezaba sin logins. Se controla con `tools.browser.persistSession`
239
+ (activo por defecto).
240
+
241
+ - **Nueva tool `computer_use_task`**: operar el navegador mirando la pantalla
242
+ —clic por coordenadas, escribir, navegar— cuando no hay un selector CSS
243
+ estable (canvas, UIs generadas, visores embebidos).
244
+
245
+ - CI actualizado a **Bun 1.4.0**, alineado con `hive`.
246
+
247
+ ### Quitado
248
+
249
+ - **`AgentRunner`** (`agent/providers/index.ts`). Era una capa de compatibilidad
250
+ con la firma de LangGraph anterior a que el runtime pasara a `agent-loop.ts`, y
251
+ **nunca llegó a instanciarse**: los cuatro puntos de entrada reales —el
252
+ gateway, `createAgent`, el worker y los ejecutores del harness— llaman
253
+ `runAgent()` directo. 158 líneas de código muerto. El subpath
254
+ `@johpaz/hive-sdk/agent/providers` sigue existiendo con sus tipos (`Provider`,
255
+ `ModelResponse`), que sí son parte del contrato público.
256
+
257
+ ### Añadido
258
+
259
+ - **Streaming por token en la API pública.** `chat(mensaje, { stream: true })`
260
+ emite eventos `token` con los deltas del proveedor a medida que llegan. El
261
+ mecanismo ya existía —los proveedores llamaban `onToken` por cada delta— pero
262
+ **ningún punto de entrada lo pasaba**, así que nunca llegaba a nadie: la
263
+ respuesta aparecía de golpe al terminar el turno.
264
+
265
+ - **`@johpaz/hive-sdk/services/images`** — imágenes como servicio para el usuario
266
+ final, no para el agente: entra y sale por bytes, se persiste por id. Incluye
267
+ galería (`listImages`), presets y control de retención.
268
+
269
+ - **`@johpaz/hive-sdk/services` — la superficie que maneja una interfaz.** El SDK
270
+ estaba construido para que lo condujera el modelo: casi todo el CRUD vivía
271
+ dentro de las tools (`cronCreateTool`, `memoryWriteTool`, `agentCreateTool`),
272
+ con argumentos con forma de LLM y respuestas escritas para un prompt. Montar
273
+ una UI encima obligaba a llamar `tool.execute({...})` y parsear prosa, o a
274
+ escribir consultas crudas contra HiveDB conociendo un esquema privado.
275
+
276
+ Ahora la implementación vive en `services/` y las tools la envuelven — una
277
+ implementación, dos consumidores. Diez dominios: `agents`, `swarms`, `skills`,
278
+ `tools`, `providers`, `models`, `mcp`, `cron`, `memory`, `ethics`. Es
279
+ deliberadamente agnóstico del framework (funciones, no rutas HTTP): una app
280
+ móvil o de escritorio que embeba el runtime no quiere un servidor.
281
+
282
+ Añade tres cosas que hive no hace: **valida que las referencias existan** al
283
+ asignar tools/skills/MCP a un agente (hive las guarda sin comprobar, y el
284
+ error aparece cuando el agente intenta usarlas); **`testMcpServer()`**, que
285
+ allí es "guardá y esperá a que el hot-reload conecte"; y el **rename de modelo
286
+ transaccional**, que re-apunta a cada agente en el mismo `batch()`.
287
+
288
+ - **`SwarmDoc` — los enjambres se pueden guardar.** Hasta acá un enjambre existía
289
+ sólo mientras corría: `runRoleSwarm()` recibe los agentes en la llamada y no
290
+ persiste nada, así que quien armara uno desde una interfaz lo perdía al cerrar
291
+ la ventana. Era el bloqueador real para poner una UI encima del SDK, y explica
292
+ por qué hive-cloud creó sus propias tablas en Postgres.
293
+
294
+ La validación ocurre **al guardar, no al correr**: un enjambre jerárquico sin
295
+ orquestador, o con un agente que ya no existe, es un error de configuración —
296
+ descubrirlo semanas después, cuando alguien lo ejecuta, es descubrirlo tarde.
297
+
298
+ - **El harness trae ejecutores listos** (`initHarnessExecutors()`). La cola
299
+ durable sabía encolar, reintentar y recuperar tras un crash, pero no ejecutar:
300
+ registrar los ejecutores quedaba en manos de quien usara el SDK, y eso son
301
+ ~420 líneas de cableado —epoch, proof packets, criterios de aceptación,
302
+ fan-in de delegaciones— antes de correr un solo enjambre durable. Ahora vienen
303
+ `worker_task` (worker delegado en contexto aislado, con verificación de sus
304
+ criterios) y `goal_run` (varios turnos contra un objetivo hasta verificarlo o
305
+ agotar el presupuesto).
306
+
307
+ `chat_turn` no está a propósito: qué es un canal y cómo se transmite un token
308
+ lo define la aplicación. Se registra desde fuera con `registerExecutor()`.
309
+ Registrar sigue siendo opt-in — `initHarnessExecutors()` no se llama sola.
310
+
311
+ - **`getRegisteredExecutorTypes()`** — el registro era privado, así que no había
312
+ forma de comprobar si un tipo quedó cableado. Un job encolado sin ejecutor no
313
+ falla al encolarse sino al tomarse, lejos de donde está el error.
314
+
315
+ - **Superficie pública completa**: 33 subpaths (antes 28). `events/` y
316
+ `resilience/` no tenían barril, `canvas/` no exportaba su emitter, `artifacts/`
317
+ no existía como módulo, y `./events` apuntaba a un solo archivo — el
318
+ **agent-bus**, que es la mensajería entre workers de un enjambre, era
319
+ inalcanzable desde fuera. También se exponen `./tool-runtime`, `./channels`,
320
+ `./voice`, y `initializeBrowserService`/`activateBrowserTools`, sin los cuales
321
+ las browser tools estaban en el catálogo pero nadie podía arrancarlas.
322
+
323
+ - **`@johpaz/hive-sdk/sessions`** — la conversación de un usuario como una sola
324
+ cosa. Hasta acá "sesión" estaba repartida entre `thread-store` (identidad),
325
+ `conversation-store` (mensajes), `run-store` (ejecución) y un `Map` en memoria
326
+ que moría con el proceso; no existía la consulta "qué sesiones tiene este
327
+ usuario". `Session` es una vista compuesta sobre las colecciones que ya
328
+ existían — no agrega una tercera persistencia — y `Session.id` ES el
329
+ `threadId`. Incluye `createSession`, `listSessions`, `appendMessage`,
330
+ `resumeSession`, `closeSession`/`reopenSession` y `deleteSession`.
331
+
332
+ - **`@johpaz/hive-sdk/models`** — el seed de modelos con nombre propio. El
333
+ catálogo (18 proveedores, 110 modelos), las claves de modelo y el cálculo de
334
+ costo seguían viviendo bajo `storage/`; esto les da un punto de entrada sin
335
+ mover la implementación.
336
+
337
+ - **Enjambre por roles** (`runRoleSwarm` en `@johpaz/hive-sdk/swarm`) —
338
+ orquestador/trabajadores con estrategias `sequential`, `parallel` y
339
+ `hierarchical`. Es la tercera forma de armar un enjambre, junto a la
340
+ delegación por catálogo y al DAG de tareas, y la única que expresa un enjambre
341
+ como *configuración persistida* en vez de un grafo conocido de antemano. No
342
+ persiste nada: `onMessage` es el punto de enganche del consumidor.
343
+
344
+ - **`bun run drift`** (`scripts/check-drift.ts`) — compara los módulos del
345
+ cerebro contra `hive` y reporta qué falta y qué difiere, indicando de qué lado
346
+ está el avance. El SDK es la fuente de verdad pero nada lo garantizaba
347
+ estructuralmente: la última vez la divergencia llegó a compartir sólo 87 de
348
+ 224 nombres de archivo.
349
+
350
+ - **`test/exports-contract.test.ts`** — importa de verdad cada subpath declarado
351
+ en `exports`. Los deep-imports se han roto entre versiones sin aviso, y el
352
+ consumidor se defendía pineando la versión exacta.
353
+
13
354
  ### Corregido
14
355
 
356
+ - **Las notificaciones no llegaban a ningún lado.** `notifyChannel` era un stub
357
+ que sólo hacía `console.log`, y está en el camino real: la tool `notify`, los
358
+ reportes de progreso, el aviso de que una tarea programada terminó, el de un
359
+ turno interrumpido por un crash. Un agente sobre el SDK **no podía hablarle al
360
+ usuario por ningún canal**, mientras `channels/manager.ts` tenía adaptadores
361
+ funcionales de Slack, Discord, Telegram y WhatsApp sin nada que los conectara.
362
+ Ahora la app registra el suyo con `setChannelManager()`; sin registro se
363
+ conserva el comportamiento anterior, pero avisando.
364
+
365
+ - **Las imágenes se reenviaban al modelo en cada turno.** `content_multimodal`
366
+ guardaba el base64 completo y `toAPIMessages` lo restauraba una y otra vez:
367
+ cinco fotos en una conversación eran cinco fotos viajando en cada turno
368
+ siguiente. Ahora se guardan como artefacto y en el historial queda una
369
+ referencia; las de los últimos mensajes se vuelven a poner en línea, porque un
370
+ modelo de visión no ve una foto desde un id. Mismo criterio que
371
+ `clearOldToolResults`.
372
+
373
+ - **`token_count` no contaba las imágenes**, así que la compactación creía que un
374
+ hilo lleno de fotos ocupaba lo que ocupa su texto y no se disparaba hasta que
375
+ el proveedor rechazaba el turno. Ahora se estiman por área, como cobran los
376
+ proveedores.
377
+
378
+ - **`agent.context.compactionThreshold` no lo leía nadie.** Estaba en el esquema
379
+ de configuración y ajustarlo no hacía nada. Una opción que no hace nada es
380
+ peor que no tenerla, porque el usuario cree que cambió algo.
381
+
382
+ - **`search_knowledge` filtraba en el lugar equivocado.** Mostraba tools fuera de
383
+ la lista blanca del agente. La ejecución sí estaba protegida, pero además de
384
+ contarle qué existe fuera de su alcance, ofrecerle algo que no puede ejecutar
385
+ es hacerle perder un turno.
386
+
387
+ - **El seed selectivo no habría sobrevivido a un reinicio.** `reseedToolsAndSkills()`
388
+ escribía `active: true` para todas las tools y skills en cada arranque, así que
389
+ la elección del usuario sobre qué capacidades quiere en su colmena duraba hasta
390
+ el próximo reinicio: apagaba lo que no usaba y volvía todo. Ahora el reseed
391
+ preserva `active` —la descripción y la categoría siguen viniendo del código,
392
+ que es su fuente de verdad—, igual que ya hacía con los modelos.
393
+
394
+ - **La memoria era global al proceso.** El id de `MemoryDoc` era sólo el título y
395
+ no había `user_id`: dos usuarios no podían tener una memoria con el mismo
396
+ nombre —la segunda pisaba la primera— y cualquiera veía la del otro. Coherente
397
+ con hive, que es mono-usuario; inservible para un runtime donde cada quien arma
398
+ su colmena. El id pasa a ser `${userId}:${title}` y toda lectura filtra por
399
+ dueño. Las filas anteriores se migran al arrancar.
400
+
401
+ - **Los ids no manejaban acentos.** "Efímero" quedaba como `ef_mero` y "Diseño"
402
+ como `dise_o`, porque la í y la ñ no son `[a-z0-9]`. Para un producto en
403
+ español eso no es cosmético. `slugify()` normaliza los diacríticos antes de
404
+ filtrar, y se aplica también a skills y servidores MCP.
405
+
406
+ - **Documentación que describía un backend retirado.** `API-TOOLS-SKILLS-CHANNELS.md`
407
+ seguía explicando cómo `agent-browser` se instalaba solo en `~/.hive/` al
408
+ primer uso — un backend que ya no existe. Reescrita para `Bun.WebView`, con la
409
+ nota de por qué se retiró. También se corrigieron los conteos (58→60 tools,
410
+ 106→110 modelos) y los pies de página congelados en `v0.0.17`.
411
+
412
+
413
+ - **Un job que moría por expiración de lease no disparaba su terminal hook.** La
414
+ ruta normal de fallo sí lo hacía; la de recuperación tras un crash, no. El
415
+ aviso al usuario y el fan-in de delegaciones se perdían en silencio justo
416
+ cuando más importaban.
417
+
418
+ - **Los artefactos de imagen no llegaban al consumidor.** El agent loop ya los
419
+ emitía (`chunk.artifacts.images`, vía mcp-result-normalizer), pero el wrapper
420
+ `AgentRunner` no los propagaba, así que una imagen producida por una tool MCP
421
+ se perdía antes de salir del SDK.
422
+
423
+ - **NVIDIA no emitía razonamiento.** NIM lo mantiene apagado por defecto y el
424
+ interruptor no es `reasoning_effort` sino `chat_template_kwargs`, con una
425
+ clave distinta por familia de modelo. Se añade el reintento sin esos extras
426
+ cuando el proveedor responde 400/422: perder el razonamiento es mejor que
427
+ perder el turno.
428
+
429
+ - **Un turno con más de una tool call podía morir por un hueco de empaquetado.**
430
+ `resolveWorkerEntry()` lanzaba si no encontraba el worker; ahora devuelve null
431
+ y degrada a hilo principal.
432
+
433
+ - **`touchThread` perdía mensajes en el contador.** El incremento se calculaba
434
+ fuera del reintento de `updateDoc`, así que ante un conflicto de versión el
435
+ reintento volvía a escribir el valor viejo. Como `addMessage` la llama sin
436
+ esperarla, dos mensajes seguidos del mismo hilo bastaban para que el conteo se
437
+ quedara corto de forma permanente. Ahora el valor se recalcula dentro del
438
+ bucle.
439
+
440
+ - **El paquete publicaba su propia suite de tests.** Sin campo `files`, el
441
+ tarball llevaba 329 archivos y 2.3 MB, incluidos `test/`, `docs/`, `scripts/`
442
+ y los `*.test.ts` que conviven con el código. Ahora son 260 archivos y 448 kB.
443
+
444
+ - **`prepublish` no verificaba nada** (era un `echo`), y además es el hook
445
+ deprecado. Se reemplazó por `prepublishOnly` con typecheck + tests.
446
+
447
+ - **Sintaxis TypeScript que ningún runtime salvo Bun puede procesar.** Las 5
448
+ *parameter properties* (`constructor(private x)`) rompían incluso el
449
+ type-stripping nativo de Node, y como las clases se re-exportan desde el barrel
450
+ raíz tumbaban cualquier import del paquete. Se reescribieron a mano, sin
451
+ cambiar la API, y se normalizaron 355 imports relativos a extensión `.ts`
452
+ explícita. El paquete sigue requiriendo Bun por el uso de `Bun.*` en 18
453
+ archivos del core — ahora documentado en el README.
454
+
455
+
15
456
  - Se fijaron las 8 dependencias que estaban en `latest` (`zod`, `discord.js`,
16
457
  `grammy`, `@slack/bolt`, `@whiskeysockets/baileys`, `@modelcontextprotocol/sdk`,
17
458
  `qrcode-terminal`, `@sapphire/snowflake`). Como `bun.lock` no se publica, cada
package/README.md CHANGED
@@ -1,3 +1,7 @@
1
+ <p align="center">
2
+ <img src="docs/assets/logoblack.png" alt="Hive SDK" width="180" />
3
+ </p>
4
+
1
5
  # @johpaz/hive-sdk
2
6
 
3
7
  > **Hive Agent Harness SDK** — construí, desplegá y escalá aplicaciones de agentes de IA, con soporte multi-canal, Bun Workers y orquestación en swarm.
@@ -13,19 +17,33 @@ bun add @johpaz/hive-sdk
13
17
  **Hive SDK es un Agent Harness**: un marco de trabajo completo para construir, desplegar y escalar aplicaciones de agentes de IA. A diferencia de un simple wrapper de LLM, un *harness* provee todo lo necesario para que un agente opere en producción:
14
18
 
15
19
  - **Agentes**: ciclo ReAct nativo con checkpoint durable, 16 providers LLM y descubrimiento de tools/skills por búsqueda BM25.
16
- - **Catálogo**: 18 providers y 106 modelos sembrados, cada uno con su precio por millón de tokens — una sola fuente de verdad para el costo.
17
- - **Tools**: 58 tools incluidas — filesystem, web search, browser automation (`agent-browser`), APIs (`api_request`), a2ui, office, cron, delegación.
20
+ - **Catálogo**: 18 providers y 110 modelos sembrados, cada uno con su precio por millón de tokens — una sola fuente de verdad para el costo.
21
+ - **Tools**: 60 tools incluidas — filesystem, web search, browser automation (`Bun.WebView`), APIs (`api_request`), a2ui, office, cron, delegación.
18
22
  - **Skills**: 23 workflows bundled, más los tuyos con `defineSkill` y `SkillLoader`.
19
23
  - **Canales**: Telegram, Discord, WhatsApp, Slack y WebChat con `ChannelManager`.
20
24
  - **Swarm**: orquestación multi-agente con `DAGScheduler`, `TaskGraph` y `WorkerPool`.
21
25
  - **Runtime**: ejecución paralela de tools vía Bun Workers.
22
26
  - **Gateway**: servidor HTTP/WebSocket para exponer agentes como API.
23
27
  - **Memoria y estado**: HiveDB (colecciones + índice BM25), scratchpad, context compiler con compactación.
28
+ - **Servicios**: CRUD tipado de agentes, enjambres, skills, modelos, MCP y cron para montarle **la interfaz que quieras** — móvil, web o escritorio. Ver [API-SERVICES.md](./docs/API-SERVICES.md).
29
+ - **Sesiones**: un hilo por canal y por contacto, con historial, resumen y reanudación tras un corte.
30
+ - **Imágenes**: redimensionar y convertir con `Bun.Image`, sin dependencias nativas. Las imágenes entrantes se normalizan antes de llegar al modelo — una foto de cámara pasa de 217 KB a 4 KB.
31
+ - **Harness**: cola durable con leases y recuperación tras crash, y ejecutores listos (`initHarnessExecutors`).
24
32
 
25
33
  Con Hive SDK no montas un agente desde cero: **enganchas tu lógica de negocio en un harness ya armado**.
26
34
 
35
+ Y si además querés ponerle interfaz, no tenés que hablarle a la base de datos ni
36
+ imitar el formato que espera el modelo: `@johpaz/hive-sdk/services` expone el
37
+ mismo CRUD que usan las tools, en funciones tipadas.
38
+
27
39
  ## Instalación
28
40
 
41
+ > **Requiere Bun.** El paquete se publica como TypeScript y usa APIs de Bun
42
+ > (`Bun.secrets`, `Bun.spawn`, Workers) en 18 archivos del core, así que no
43
+ > corre sobre Node aunque se le apliquen los flags de type-stripping. Si tu
44
+ > backend es Node, hoy la vía es un proceso Bun aparte; el build a JS que
45
+ > levantaría esa restricción todavía no existe.
46
+
29
47
  ```bash
30
48
  # Instalar globalmente para el CLI
31
49
  bun install -g @johpaz/hive-sdk
@@ -212,4 +230,4 @@ npm view @johpaz/hive-sdk dist-tags # verificar después del release
212
230
 
213
231
  ---
214
232
 
215
- *Hive SDK v0.1.6 — MIT*
233
+ *Hive SDK v0.3.0 — MIT*
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@johpaz/hive-sdk",
3
- "version": "0.1.6",
3
+ "version": "0.3.0",
4
4
  "private": false,
5
5
  "description": "Hive SDK — The Agent Harness SDK. Build, deploy, and scale AI agent applications with multi-channel support, context engineering, and swarm orchestration.",
6
6
  "license": "MIT",
@@ -35,12 +35,22 @@
35
35
  "./tools": "./packages/core/src/tools/index.ts",
36
36
  "./skills": "./packages/core/src/skills/index.ts",
37
37
  "./storage": "./packages/core/src/storage/index.ts",
38
+ "./services": "./packages/core/src/services/index.ts",
39
+ "./hooks": "./packages/core/src/hooks/index.ts",
40
+ "./images": "./packages/core/src/images/index.ts",
41
+ "./sessions": "./packages/core/src/sessions/index.ts",
42
+ "./models": "./packages/core/src/models/index.ts",
38
43
  "./swarm": "./packages/core/src/swarm/index.ts",
39
44
  "./swarm/strategies": "./packages/core/src/swarm/strategies/index.ts",
40
45
  "./swarm/presets": "./packages/core/src/swarm/presets/index.ts",
41
46
  "./scheduler": "./packages/core/src/scheduler/index.ts",
42
47
  "./workers": "./packages/core/src/workers/index.ts",
43
- "./events": "./packages/core/src/events/event-bus.ts",
48
+ "./events": "./packages/core/src/events/index.ts",
49
+ "./resilience": "./packages/core/src/resilience/index.ts",
50
+ "./tool-runtime": "./packages/core/src/tool-runtime/index.ts",
51
+ "./channels": "./packages/core/src/channels/index.ts",
52
+ "./voice": "./packages/core/src/voice/index.ts",
53
+ "./artifacts": "./packages/core/src/artifacts/index.ts",
44
54
  "./ethics": "./packages/core/src/ethics/index.ts",
45
55
  "./canvas": "./packages/core/src/canvas/index.ts",
46
56
  "./config": "./packages/core/src/config/index.ts",
@@ -59,6 +69,19 @@
59
69
  "bin": {
60
70
  "hives": "./packages/cli/bin/hives"
61
71
  },
72
+ "files": [
73
+ "packages/core/src",
74
+ "packages/cli/bin",
75
+ "packages/cli/src",
76
+ "packages/cli/templates",
77
+ "!packages/**/*.test.ts",
78
+ "README.md",
79
+ "CHANGELOG.md",
80
+ "LICENSE"
81
+ ],
82
+ "engines": {
83
+ "bun": ">=1.4.0"
84
+ },
62
85
  "workspaces": [
63
86
  "packages/core",
64
87
  "packages/cli"
@@ -70,7 +93,8 @@
70
93
  "skills:bundle": "bun scripts/generate-skill-bundle.ts",
71
94
  "version:set": "bun scripts/bump-version.ts",
72
95
  "release": "bun scripts/bump-version.ts --push",
73
- "prepublish": "echo 'No build needed - Bun runs TypeScript directly'"
96
+ "prepublishOnly": "bun run typecheck && bun test",
97
+ "drift": "bun scripts/check-drift.ts"
74
98
  },
75
99
  "dependencies": {
76
100
  "@johpaz/hive-db": "^0.4.0",
@@ -81,8 +105,6 @@
81
105
  "@slack/bolt": "^4.7.2",
82
106
  "@whiskeysockets/baileys": "7.0.0-rc11",
83
107
  "async-mutex": "^0.5.0",
84
- "cron-parser": "^5.5.0",
85
- "croner": "^10.0.1",
86
108
  "discord.js": "^14.26.4",
87
109
  "docx": "^9.6.1",
88
110
  "grammy": "^1.42.0",
@@ -13,13 +13,13 @@
13
13
  * to judge using this checks result plus the raw evidence.
14
14
  */
15
15
 
16
- import { col } from "../storage/hive";
17
- import type { AgentDoc } from "../storage/collections";
18
- import type { AcceptanceCriterion } from "./run-store";
19
- import { interpretCheckResult } from "./goal-runner";
20
- import { inspectArtifact } from "../artifacts/store";
21
- import { loadConfig } from "../config/loader";
22
- import { logger } from "../utils/logger";
16
+ import { col } from "../storage/hive.ts";
17
+ import type { AgentDoc } from "../storage/collections.ts";
18
+ import type { AcceptanceCriterion } from "./run-store.ts";
19
+ import { interpretCheckResult } from "./goal-runner.ts";
20
+ import { inspectArtifact } from "../artifacts/store.ts";
21
+ import { loadConfig } from "../config/loader.ts";
22
+ import { logger } from "../utils/logger.ts";
23
23
 
24
24
  const log = logger.child("acceptance-checks");
25
25
 
@@ -55,8 +55,8 @@ export function sanitizeDiagnostic(value: string, limit = 1000): string {
55
55
  async function runCheckTool(criterion: AcceptanceCriterion, objective: string): Promise<AcceptanceCheckResult | null> {
56
56
  if (!criterion.checkTool) return null;
57
57
  try {
58
- const { executeToolBatch } = await import("../tool-runtime");
59
- const { createAllTools } = await import("../tools/index");
58
+ const { executeToolBatch } = await import("../tool-runtime/index.ts");
59
+ const { createAllTools } = await import("../tools/index.ts");
60
60
  const allTools = createAllTools(loadConfig());
61
61
  const toolDef = allTools.find((t) => t.name === criterion.checkTool);
62
62
  if (!toolDef) {