@johpaz/hive-sdk 0.1.5 → 0.2.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.
- package/CHANGELOG.md +167 -0
- package/README.md +11 -1
- package/package.json +26 -10
- package/packages/core/src/agent/acceptance-checks.ts +16 -10
- package/packages/core/src/agent/agent-catalog.ts +3 -3
- package/packages/core/src/agent/agent-loop.ts +115 -26
- package/packages/core/src/agent/capability-search.ts +2 -2
- package/packages/core/src/agent/catalog-selector.ts +4 -4
- package/packages/core/src/agent/compaction.ts +10 -9
- package/packages/core/src/agent/context-compiler.ts +58 -34
- package/packages/core/src/agent/conversation-store.ts +31 -7
- package/packages/core/src/agent/curator.ts +4 -4
- package/packages/core/src/agent/delegation-runtime.ts +5 -5
- package/packages/core/src/agent/goal-runner.ts +9 -9
- package/packages/core/src/agent/index.ts +1 -0
- package/packages/core/src/agent/llm-client.ts +98 -37
- package/packages/core/src/agent/llm-providers/anthropic.ts +4 -4
- package/packages/core/src/agent/llm-providers/deepseek.ts +1 -1
- package/packages/core/src/agent/llm-providers/gemini.ts +4 -4
- package/packages/core/src/agent/llm-providers/groq.ts +1 -1
- package/packages/core/src/agent/llm-providers/hiveagents.ts +3 -3
- package/packages/core/src/agent/llm-providers/interface.ts +2 -2
- package/packages/core/src/agent/llm-providers/kimi.ts +1 -1
- package/packages/core/src/agent/llm-providers/minimax.ts +1 -1
- package/packages/core/src/agent/llm-providers/mistral.ts +1 -1
- package/packages/core/src/agent/llm-providers/modelscope.ts +1 -1
- package/packages/core/src/agent/llm-providers/nvidia.ts +1 -1
- package/packages/core/src/agent/llm-providers/ollama.ts +4 -4
- package/packages/core/src/agent/llm-providers/openai-compat-base.ts +9 -5
- package/packages/core/src/agent/llm-providers/openai.ts +1 -1
- package/packages/core/src/agent/llm-providers/opencode-go.ts +1 -1
- package/packages/core/src/agent/llm-providers/openrouter.ts +1 -1
- package/packages/core/src/agent/llm-providers/qwen.ts +1 -1
- package/packages/core/src/agent/llm-providers/z-ai.ts +1 -1
- package/packages/core/src/agent/mcp-result-normalizer.ts +192 -0
- package/packages/core/src/agent/playbook-selector.ts +4 -4
- package/packages/core/src/agent/prompt-builder.ts +5 -5
- package/packages/core/src/agent/proof-packet.ts +5 -5
- package/packages/core/src/agent/providers/index.ts +4 -4
- package/packages/core/src/agent/realtime-providers/gemini-live.ts +238 -0
- package/packages/core/src/agent/realtime-providers/index.ts +29 -0
- package/packages/core/src/agent/realtime-providers/interface.ts +108 -0
- package/packages/core/src/agent/reflector.ts +6 -6
- package/packages/core/src/agent/run-store.ts +8 -8
- package/packages/core/src/agent/service.ts +10 -10
- package/packages/core/src/agent/skill-selector.ts +6 -6
- package/packages/core/src/agent/thread-id.ts +71 -0
- package/packages/core/src/agent/thread-store.ts +250 -0
- package/packages/core/src/agent/tool-selector.ts +7 -5
- package/packages/core/src/agent/tracer.ts +5 -5
- package/packages/core/src/api/createAgent.ts +1 -1
- package/packages/core/src/artifacts/store.ts +84 -3
- package/packages/core/src/canvas/emitter.ts +2 -2
- package/packages/core/src/channels/telegram.ts +1 -1
- package/packages/core/src/channels/webchat.ts +1 -1
- package/packages/core/src/config/loader.ts +15 -1
- package/packages/core/src/events/agent-bus.ts +3 -3
- package/packages/core/src/events/channel-narration.ts +3 -3
- package/packages/core/src/events/event-bus.ts +1 -1
- package/packages/core/src/events/narration.ts +3 -3
- package/packages/core/src/gateway/delegation-groups.ts +4 -4
- package/packages/core/src/gateway/durable-queue.ts +5 -5
- package/packages/core/src/gateway/job-store.ts +5 -5
- package/packages/core/src/gateway/notification-inbox.ts +2 -2
- package/packages/core/src/gateway/server.ts +2 -2
- package/packages/core/src/mcp/MCPClient.ts +3 -3
- package/packages/core/src/mcp/hot-reload.ts +5 -5
- package/packages/core/src/mcp/tool-sync.ts +5 -5
- package/packages/core/src/mcp/transports/index.ts +2 -2
- package/packages/core/src/mcp/transports/sse.ts +1 -1
- package/packages/core/src/models/index.ts +36 -0
- package/packages/core/src/multimodal/index.ts +2 -2
- package/packages/core/src/multimodal/vision-service.ts +6 -6
- package/packages/core/src/plugins/loader.ts +4 -1
- package/packages/core/src/resilience/circuit-breaker.ts +16 -5
- package/packages/core/src/resilience/retry.ts +1 -1
- package/packages/core/src/scheduler/CronScheduler.ts +6 -6
- package/packages/core/src/scheduler/integration.ts +9 -9
- package/packages/core/src/sessions/index.ts +266 -0
- package/packages/core/src/storage/bootstrap.ts +34 -8
- package/packages/core/src/storage/causal-events.ts +1 -1
- package/packages/core/src/storage/collections.ts +32 -1
- package/packages/core/src/storage/crypto.ts +16 -2
- package/packages/core/src/storage/hive.ts +1 -1
- package/packages/core/src/storage/hivedb.ts +10 -1
- package/packages/core/src/storage/onboarding.ts +6 -6
- package/packages/core/src/storage/reconcile.ts +5 -5
- package/packages/core/src/storage/seed.ts +103 -13
- package/packages/core/src/storage/usage.ts +3 -3
- package/packages/core/src/swarm/AgentExecutor.ts +2 -2
- package/packages/core/src/swarm/Coordinator.ts +8 -8
- package/packages/core/src/swarm/EventBridge.ts +2 -2
- package/packages/core/src/swarm/RoleSwarm.ts +234 -0
- package/packages/core/src/swarm/TaskGraph.ts +2 -2
- package/packages/core/src/swarm/index.ts +7 -0
- package/packages/core/src/swarm/presets/HiveLearnPreset.ts +2 -2
- package/packages/core/src/swarm/presets/ResearchPreset.ts +2 -2
- package/packages/core/src/swarm/strategies/ParallelStrategy.ts +1 -1
- package/packages/core/src/swarm/strategies/PriorityStrategy.ts +3 -3
- package/packages/core/src/tools/ToolExecutor.ts +7 -3
- package/packages/core/src/tools/core/index.ts +2 -2
- package/packages/core/src/tools/cron/index.ts +4 -4
- package/packages/core/src/tools/web/artifact-inspect.ts +2 -2
- package/packages/core/src/tools/web/artifact-read.ts +162 -0
- package/packages/core/src/tools/web/browser-backend.ts +226 -0
- package/packages/core/src/tools/web/browser-click.ts +2 -2
- package/packages/core/src/tools/web/browser-extract.ts +2 -2
- package/packages/core/src/tools/web/browser-navigate.ts +2 -2
- package/packages/core/src/tools/web/browser-screenshot.ts +12 -5
- package/packages/core/src/tools/web/browser-script.ts +2 -2
- package/packages/core/src/tools/web/browser-service.ts +85 -366
- package/packages/core/src/tools/web/browser-session.ts +125 -0
- package/packages/core/src/tools/web/browser-type.ts +2 -2
- package/packages/core/src/tools/web/browser-wait.ts +2 -2
- package/packages/core/src/tools/web/computer-use.ts +553 -0
- package/packages/core/src/tools/web/index.ts +8 -1
- package/packages/core/src/tools/web/webview-backend.ts +851 -0
- package/packages/core/src/utils/index.ts +1 -0
- package/packages/core/src/utils/logger.ts +12 -4
- package/packages/core/src/utils/redact-binary.ts +17 -0
- package/packages/core/src/utils/toon.ts +1 -1
- package/packages/core/src/voice/index.ts +6 -6
- package/bun.lock +0 -833
- package/bunfig.toml +0 -9
- package/docs/API-AGENTS.md +0 -367
- package/docs/API-CONTEXT-COMPILER.md +0 -249
- package/docs/API-DAG-SCHEDULER.md +0 -273
- package/docs/API-TOOLS-SKILLS-CHANNELS.md +0 -446
- package/docs/API-WORKERS-EVENTS.md +0 -299
- package/docs/HIVE-HARNESS.md +0 -113
- package/docs/INDEX.md +0 -190
- package/docs/TEMPLATE-HIVE-APP.md +0 -360
- package/packages/cli/package.json +0 -17
- package/packages/cli/src/commands/create-app.test.ts +0 -180
- package/packages/core/package.json +0 -70
- package/packages/core/src/api/createAgent.test.ts +0 -160
- package/packages/core/src/canvas/canvas.test.ts +0 -36
- package/packages/core/src/channels/channels.test.ts +0 -18
- package/packages/core/src/ethics/EthicsGuard.test.ts +0 -108
- package/packages/core/src/gateway/gateway.test.ts +0 -38
- package/packages/core/src/memory/Scratchpad.test.ts +0 -68
- package/packages/core/src/scheduler/scheduler.test.ts +0 -15
- package/packages/core/src/skills/skills.test.ts +0 -62
- package/packages/core/src/swarm/swarm.test.ts +0 -24
- package/packages/core/src/tool-runtime/tool-runtime.test.ts +0 -99
- package/packages/core/src/tools/ToolRegistry.test.ts +0 -98
- package/packages/core/src/tools/api/api-request.test.ts +0 -164
- package/packages/core/src/tools/web/browser-service.test.ts +0 -83
- package/packages/core/src/workers/workers.test.ts +0 -41
- package/scripts/bump-version.ts +0 -248
- package/scripts/generate-skill-bundle.ts +0 -108
- package/test/agent-loop-terminal-synthesis.test.ts +0 -32
- package/test/catalog-agents-stay-enabled.test.ts +0 -117
- package/test/causal-events.test.ts +0 -117
- package/test/compaction.test.ts +0 -105
- package/test/context-compiler.test.ts +0 -269
- package/test/curator.test.ts +0 -130
- package/test/durable-queue.test.ts +0 -114
- package/test/harness-barrel.test.ts +0 -64
- package/test/hive-helpers.test.ts +0 -130
- package/test/hivedb-search.test.ts +0 -189
- package/test/internal-turns.test.ts +0 -166
- package/test/job-idempotency.test.ts +0 -68
- package/test/job-retry-backoff.test.ts +0 -184
- package/test/job-store.test.ts +0 -381
- package/test/llm-retry.test.ts +0 -97
- package/test/memory-perf.test.ts +0 -774
- package/test/minimal-loadout.test.ts +0 -78
- package/test/model-catalog.test.ts +0 -105
- package/test/preload.ts +0 -12
- package/test/reflector.test.ts +0 -320
- package/test/retention-cap.test.ts +0 -91
- package/test/retired-capabilities-pruned.test.ts +0 -192
- package/test/run-store.test.ts +0 -355
- package/test/scratchpad.test.ts +0 -74
- package/test/secrets-durability.test.ts +0 -119
- package/test/seed-model-reseed.test.ts +0 -155
- package/test/setup-agent-seed.test.ts +0 -264
- package/test/tool-inventory.test.ts +0 -65
- package/test/tool-runtime.test.ts +0 -258
- package/test/toon.test.ts +0 -429
- package/tsconfig.json +0 -42
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,172 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Sin publicar
|
|
4
|
+
|
|
5
|
+
### Seguridad
|
|
6
|
+
|
|
7
|
+
- **La lista blanca de tools no se aplicaba al descubrimiento dinámico.**
|
|
8
|
+
`compileContext` sólo recortaba `allTools` cuando el agente era de catálogo
|
|
9
|
+
(`source === "catalog"`). Un agente creado por el usuario veía su loadout
|
|
10
|
+
inicial restringido, pero `search_knowledge` busca contra el índice completo y
|
|
11
|
+
el agent loop inyecta lo que encuentre resolviéndolo contra `allTools`: la
|
|
12
|
+
tool excluida terminaba siendo llamable igual. Ahora la restricción depende de
|
|
13
|
+
que el agente declare una lista, no de su origen. Cubierto por
|
|
14
|
+
`test/tool-allowlist-discovery.test.ts`.
|
|
15
|
+
|
|
16
|
+
- **Aislamiento de credenciales entre inquilinos.** `AgentLoopOptions` no tenía
|
|
17
|
+
forma de recibir la key del proveedor, así que la única fuente era el secret
|
|
18
|
+
store de HiveDB o `process.env[PROVIDER_API_KEY]`, ambos globales al proceso.
|
|
19
|
+
Un host multi-tenant que corriera dos workspaces en el mismo proceso les daba
|
|
20
|
+
la misma credencial. Se agregó `credentials` en `AgentLoopOptions`,
|
|
21
|
+
`IsolatedAgentOptions` y `resolveProviderConfig`; la credencial de la llamada
|
|
22
|
+
gana y corta ahí, sin consultar las fuentes globales ni mutar `process.env`.
|
|
23
|
+
Retrocompatible: sin `credentials` el comportamiento es el de siempre.
|
|
24
|
+
Cubierto por `test/tenant-isolation.test.ts`.
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
- **`sanitizeDiagnostic` dejaba el token en claro detrás del esquema de auth.**
|
|
28
|
+
La regex consumía sólo la palabra `Bearer`, así que un diagnóstico con
|
|
29
|
+
`authorization: Bearer <token>` quedaba como `authorization: [REDACTED] <token>`
|
|
30
|
+
y la credencial viajaba al prompt del coordinador. Afecta a **0.1.5 y
|
|
31
|
+
anteriores**: el archivo viaja en el tarball publicado.
|
|
32
|
+
|
|
33
|
+
### Cambiado
|
|
34
|
+
|
|
35
|
+
- **Los tests que manejan un navegador real son opt-in (`BROWSER_TESTS=1`).**
|
|
36
|
+
Su guarda era `isWebViewSupported()`, que sólo comprueba que exista un binario
|
|
37
|
+
de Chromium — no que arranque. En un runner de CI (contenedor, a menudo root)
|
|
38
|
+
el binario está y Chromium muere igual sin `--no-sandbox`, así que ~90 tests
|
|
39
|
+
de integración fallaban por el entorno. Como los tests son condición para
|
|
40
|
+
publicar, eso bloqueaba el release. Los describe unitarios de esos mismos
|
|
41
|
+
archivos —`resolveBackendKind`, detección de motor, `normalizeCookies`,
|
|
42
|
+
`sessionPersistenceEnabled`— siguen corriendo siempre: son los que cubren el
|
|
43
|
+
contrato del backend.
|
|
44
|
+
|
|
45
|
+
- **Se quitó un `mock.module` que se filtraba entre archivos de test.** El test
|
|
46
|
+
de aislamiento multi-tenant sustituía el módulo `storage/crypto` para no
|
|
47
|
+
escribir en el keychain del SO. `mock.module` es global al proceso, no al
|
|
48
|
+
archivo: mientras estuviera activo, cualquier otro test que importara ese
|
|
49
|
+
módulo recibía el doble, y `loadProviderApiKey` devolvía la key del mock. Que
|
|
50
|
+
mordiera dependía del orden de ejecución — pasaba en local y fallaba en CI.
|
|
51
|
+
Ahora el test usa un id de proveedor propio (`test-tenant-isolation`) y limpia
|
|
52
|
+
sus secretos, sin tocar el módulo ni la credencial de nadie.
|
|
53
|
+
|
|
54
|
+
- **`resetKeychainProbe()`** en `storage/crypto.ts`. Si el keychain del SO no
|
|
55
|
+
responde, el resultado se cachea a nivel de módulo para no reintentar en cada
|
|
56
|
+
lectura — correcto en producción, pero significa que el primer sondeo vale
|
|
57
|
+
para todo el proceso. Un test que sustituya `Bun.secrets` por un doble queda
|
|
58
|
+
cortocircuitado si algo ya sondeó y falló antes, que es lo que pasa en CI
|
|
59
|
+
headless.
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
- **Automatización web: un solo backend, `Bun.WebView`.** Se retiró
|
|
63
|
+
`AgentBrowserBackend`, que hablaba con el CLI de agent-browser por
|
|
64
|
+
subproceso. El motivo no es de estilo: medido en Bun 1.4 el WebView **sí**
|
|
65
|
+
corre headless (Bun lanza Chromium con `--headless`), que era la única razón
|
|
66
|
+
por la que agent-browser seguía siendo el default. Lo que quedaba era su
|
|
67
|
+
costo — ~40 ms de `Bun.spawn` por operación contra ~0,3 ms, y ~88 MB con su
|
|
68
|
+
propia copia de Chrome.
|
|
69
|
+
|
|
70
|
+
Lo importante para quien consume el paquete: el backend viejo ejecutaba
|
|
71
|
+
**`bun add agent-browser@latest` en el entorno del consumidor**, al primer uso
|
|
72
|
+
de una browser tool. Una versión flotante bajada de npm en runtime, en
|
|
73
|
+
producción. Eso ya no existe.
|
|
74
|
+
|
|
75
|
+
Requisitos ahora: un Chromium instalado (o `BUN_CHROME_PATH`) y **Bun ≥ 1.4**,
|
|
76
|
+
declarado en `engines`. La clave de config `tools.browser.backend` sobrevive:
|
|
77
|
+
`"agent-browser"` se acepta, avisa una vez y usa el WebView, así que las
|
|
78
|
+
configuraciones viejas no se rompen.
|
|
79
|
+
|
|
80
|
+
- **Sesión de navegador persistente** (`tools/web/browser-session.ts`). El
|
|
81
|
+
perfil de Chrome que abre Bun es efímero —su ruta lleva un hash que cambia
|
|
82
|
+
entre procesos— así que las cookies se guardan y restauran a mano. Sin esto
|
|
83
|
+
cada reinicio empezaba sin logins. Se controla con `tools.browser.persistSession`
|
|
84
|
+
(activo por defecto).
|
|
85
|
+
|
|
86
|
+
- **Nueva tool `computer_use_task`**: operar el navegador mirando la pantalla
|
|
87
|
+
—clic por coordenadas, escribir, navegar— cuando no hay un selector CSS
|
|
88
|
+
estable (canvas, UIs generadas, visores embebidos).
|
|
89
|
+
|
|
90
|
+
- CI actualizado a **Bun 1.4.0**, alineado con `hive`.
|
|
91
|
+
|
|
92
|
+
### Añadido
|
|
93
|
+
|
|
94
|
+
- **`@johpaz/hive-sdk/sessions`** — la conversación de un usuario como una sola
|
|
95
|
+
cosa. Hasta acá "sesión" estaba repartida entre `thread-store` (identidad),
|
|
96
|
+
`conversation-store` (mensajes), `run-store` (ejecución) y un `Map` en memoria
|
|
97
|
+
que moría con el proceso; no existía la consulta "qué sesiones tiene este
|
|
98
|
+
usuario". `Session` es una vista compuesta sobre las colecciones que ya
|
|
99
|
+
existían — no agrega una tercera persistencia — y `Session.id` ES el
|
|
100
|
+
`threadId`. Incluye `createSession`, `listSessions`, `appendMessage`,
|
|
101
|
+
`resumeSession`, `closeSession`/`reopenSession` y `deleteSession`.
|
|
102
|
+
|
|
103
|
+
- **`@johpaz/hive-sdk/models`** — el seed de modelos con nombre propio. El
|
|
104
|
+
catálogo (18 proveedores, 110 modelos), las claves de modelo y el cálculo de
|
|
105
|
+
costo seguían viviendo bajo `storage/`; esto les da un punto de entrada sin
|
|
106
|
+
mover la implementación.
|
|
107
|
+
|
|
108
|
+
- **Enjambre por roles** (`runRoleSwarm` en `@johpaz/hive-sdk/swarm`) —
|
|
109
|
+
orquestador/trabajadores con estrategias `sequential`, `parallel` y
|
|
110
|
+
`hierarchical`. Es la tercera forma de armar un enjambre, junto a la
|
|
111
|
+
delegación por catálogo y al DAG de tareas, y la única que expresa un enjambre
|
|
112
|
+
como *configuración persistida* en vez de un grafo conocido de antemano. No
|
|
113
|
+
persiste nada: `onMessage` es el punto de enganche del consumidor.
|
|
114
|
+
|
|
115
|
+
- **`bun run drift`** (`scripts/check-drift.ts`) — compara los módulos del
|
|
116
|
+
cerebro contra `hive` y reporta qué falta y qué difiere, indicando de qué lado
|
|
117
|
+
está el avance. El SDK es la fuente de verdad pero nada lo garantizaba
|
|
118
|
+
estructuralmente: la última vez la divergencia llegó a compartir sólo 87 de
|
|
119
|
+
224 nombres de archivo.
|
|
120
|
+
|
|
121
|
+
- **`test/exports-contract.test.ts`** — importa de verdad cada subpath declarado
|
|
122
|
+
en `exports`. Los deep-imports se han roto entre versiones sin aviso, y el
|
|
123
|
+
consumidor se defendía pineando la versión exacta.
|
|
124
|
+
|
|
125
|
+
### Corregido
|
|
126
|
+
|
|
127
|
+
- **`touchThread` perdía mensajes en el contador.** El incremento se calculaba
|
|
128
|
+
fuera del reintento de `updateDoc`, así que ante un conflicto de versión el
|
|
129
|
+
reintento volvía a escribir el valor viejo. Como `addMessage` la llama sin
|
|
130
|
+
esperarla, dos mensajes seguidos del mismo hilo bastaban para que el conteo se
|
|
131
|
+
quedara corto de forma permanente. Ahora el valor se recalcula dentro del
|
|
132
|
+
bucle.
|
|
133
|
+
|
|
134
|
+
- **El paquete publicaba su propia suite de tests.** Sin campo `files`, el
|
|
135
|
+
tarball llevaba 329 archivos y 2.3 MB, incluidos `test/`, `docs/`, `scripts/`
|
|
136
|
+
y los `*.test.ts` que conviven con el código. Ahora son 260 archivos y 448 kB.
|
|
137
|
+
|
|
138
|
+
- **`prepublish` no verificaba nada** (era un `echo`), y además es el hook
|
|
139
|
+
deprecado. Se reemplazó por `prepublishOnly` con typecheck + tests.
|
|
140
|
+
|
|
141
|
+
- **Sintaxis TypeScript que ningún runtime salvo Bun puede procesar.** Las 5
|
|
142
|
+
*parameter properties* (`constructor(private x)`) rompían incluso el
|
|
143
|
+
type-stripping nativo de Node, y como las clases se re-exportan desde el barrel
|
|
144
|
+
raíz tumbaban cualquier import del paquete. Se reescribieron a mano, sin
|
|
145
|
+
cambiar la API, y se normalizaron 355 imports relativos a extensión `.ts`
|
|
146
|
+
explícita. El paquete sigue requiriendo Bun por el uso de `Bun.*` en 18
|
|
147
|
+
archivos del core — ahora documentado en el README.
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
- Se fijaron las 8 dependencias que estaban en `latest` (`zod`, `discord.js`,
|
|
151
|
+
`grammy`, `@slack/bolt`, `@whiskeysockets/baileys`, `@modelcontextprotocol/sdk`,
|
|
152
|
+
`qrcode-terminal`, `@sapphire/snowflake`). Como `bun.lock` no se publica, cada
|
|
153
|
+
instalación resolvía `latest` de nuevo: el SDK ya estaba corriendo
|
|
154
|
+
`@slack/bolt` **5.0.0** mientras hive, con el mismo código de canales, corría
|
|
155
|
+
**4.7.x**. Ahora quedan alineados.
|
|
156
|
+
|
|
157
|
+
### Añadido
|
|
158
|
+
|
|
159
|
+
- **Backend de navegador intercambiable.** Las tools hablan con la interfaz
|
|
160
|
+
`BrowserBackend`; además del `agent-browser` de siempre (default, sin cambios)
|
|
161
|
+
hay un `WebViewBackend` sobre `Bun.WebView`, in-process, sin instalación de
|
|
162
|
+
~75 MB ni descarga de Chrome. Se elige con `tools.browser.backend`
|
|
163
|
+
(`"agent-browser" | "webview" | "auto"`) o `HIVE_BROWSER_BACKEND`.
|
|
164
|
+
- Cobertura de `acceptance-checks` (27 tests), del backend de navegador (27) y
|
|
165
|
+
del selector con tools registradas en runtime (6).
|
|
166
|
+
- Workflow de CI: typecheck, tests, verificación de aislamiento de la base, y un
|
|
167
|
+
job que genera un scaffold con `create-app` y lo typechequea contra el SDK de
|
|
168
|
+
ese commit.
|
|
169
|
+
|
|
3
170
|
## 0.1.5
|
|
4
171
|
|
|
5
172
|
Sincronización del SDK con el runtime de agentes de `hive`. **Trae rupturas de
|
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.
|
|
@@ -26,6 +30,12 @@ Con Hive SDK no montas un agente desde cero: **enganchas tu lógica de negocio e
|
|
|
26
30
|
|
|
27
31
|
## Instalación
|
|
28
32
|
|
|
33
|
+
> **Requiere Bun.** El paquete se publica como TypeScript y usa APIs de Bun
|
|
34
|
+
> (`Bun.secrets`, `Bun.spawn`, Workers) en 18 archivos del core, así que no
|
|
35
|
+
> corre sobre Node aunque se le apliquen los flags de type-stripping. Si tu
|
|
36
|
+
> backend es Node, hoy la vía es un proceso Bun aparte; el build a JS que
|
|
37
|
+
> levantaría esa restricción todavía no existe.
|
|
38
|
+
|
|
29
39
|
```bash
|
|
30
40
|
# Instalar globalmente para el CLI
|
|
31
41
|
bun install -g @johpaz/hive-sdk
|
|
@@ -212,4 +222,4 @@ npm view @johpaz/hive-sdk dist-tags # verificar después del release
|
|
|
212
222
|
|
|
213
223
|
---
|
|
214
224
|
|
|
215
|
-
*Hive SDK v0.
|
|
225
|
+
*Hive SDK v0.2.0 — MIT*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@johpaz/hive-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.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,6 +35,8 @@
|
|
|
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
|
+
"./sessions": "./packages/core/src/sessions/index.ts",
|
|
39
|
+
"./models": "./packages/core/src/models/index.ts",
|
|
38
40
|
"./swarm": "./packages/core/src/swarm/index.ts",
|
|
39
41
|
"./swarm/strategies": "./packages/core/src/swarm/strategies/index.ts",
|
|
40
42
|
"./swarm/presets": "./packages/core/src/swarm/presets/index.ts",
|
|
@@ -59,6 +61,19 @@
|
|
|
59
61
|
"bin": {
|
|
60
62
|
"hives": "./packages/cli/bin/hives"
|
|
61
63
|
},
|
|
64
|
+
"files": [
|
|
65
|
+
"packages/core/src",
|
|
66
|
+
"packages/cli/bin",
|
|
67
|
+
"packages/cli/src",
|
|
68
|
+
"packages/cli/templates",
|
|
69
|
+
"!packages/**/*.test.ts",
|
|
70
|
+
"README.md",
|
|
71
|
+
"CHANGELOG.md",
|
|
72
|
+
"LICENSE"
|
|
73
|
+
],
|
|
74
|
+
"engines": {
|
|
75
|
+
"bun": ">=1.4.0"
|
|
76
|
+
},
|
|
62
77
|
"workspaces": [
|
|
63
78
|
"packages/core",
|
|
64
79
|
"packages/cli"
|
|
@@ -70,22 +85,23 @@
|
|
|
70
85
|
"skills:bundle": "bun scripts/generate-skill-bundle.ts",
|
|
71
86
|
"version:set": "bun scripts/bump-version.ts",
|
|
72
87
|
"release": "bun scripts/bump-version.ts --push",
|
|
73
|
-
"
|
|
88
|
+
"prepublishOnly": "bun run typecheck && bun test",
|
|
89
|
+
"drift": "bun scripts/check-drift.ts"
|
|
74
90
|
},
|
|
75
91
|
"dependencies": {
|
|
76
92
|
"@johpaz/hive-db": "^0.4.0",
|
|
77
93
|
"@anthropic-ai/sdk": "^0.74.0",
|
|
78
94
|
"@google/genai": "^1.43.0",
|
|
79
|
-
"@modelcontextprotocol/sdk": "
|
|
80
|
-
"@sapphire/snowflake": "
|
|
81
|
-
"@slack/bolt": "
|
|
82
|
-
"@whiskeysockets/baileys": "
|
|
95
|
+
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
96
|
+
"@sapphire/snowflake": "^3.5.5",
|
|
97
|
+
"@slack/bolt": "^4.7.2",
|
|
98
|
+
"@whiskeysockets/baileys": "7.0.0-rc11",
|
|
83
99
|
"async-mutex": "^0.5.0",
|
|
84
100
|
"cron-parser": "^5.5.0",
|
|
85
101
|
"croner": "^10.0.1",
|
|
86
|
-
"discord.js": "
|
|
102
|
+
"discord.js": "^14.26.4",
|
|
87
103
|
"docx": "^9.6.1",
|
|
88
|
-
"grammy": "
|
|
104
|
+
"grammy": "^1.42.0",
|
|
89
105
|
"groq-sdk": "^0.37.0",
|
|
90
106
|
"jsonwebtoken": "^9.0.3",
|
|
91
107
|
"jszip": "^3.10.1",
|
|
@@ -95,10 +111,10 @@
|
|
|
95
111
|
"openai": "^6.18.0",
|
|
96
112
|
"pdfjs-dist": "^5.6.205",
|
|
97
113
|
"pptxgenjs": "^4.0.1",
|
|
98
|
-
"qrcode-terminal": "
|
|
114
|
+
"qrcode-terminal": "^0.12.0",
|
|
99
115
|
"toon-format-parser": "^1.1.0",
|
|
100
116
|
"xlsx": "^0.18.5",
|
|
101
|
-
"zod": "
|
|
117
|
+
"zod": "^4.4.3"
|
|
102
118
|
},
|
|
103
119
|
"devDependencies": {
|
|
104
120
|
"@types/bun": "^1.3.13",
|
|
@@ -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
|
|
|
@@ -42,15 +42,21 @@ export interface AcceptanceChecks {
|
|
|
42
42
|
|
|
43
43
|
export function sanitizeDiagnostic(value: string, limit = 1000): string {
|
|
44
44
|
return value
|
|
45
|
-
.replace(
|
|
45
|
+
.replace(
|
|
46
|
+
// El esquema de auth va aparte: sin el grupo opcional, "authorization:
|
|
47
|
+
// Bearer <token>" consumía sólo "Bearer" y dejaba el token en claro.
|
|
48
|
+
/(api[_-]?key|token|authorization|secret)(["'=:\s]+)(?:(bearer|basic)\s+)?[^\s,}"']+/gi,
|
|
49
|
+
(_match, key: string, separator: string, scheme?: string) =>
|
|
50
|
+
`${key}${separator}${scheme ? `${scheme} ` : ""}[REDACTED]`,
|
|
51
|
+
)
|
|
46
52
|
.slice(0, limit);
|
|
47
53
|
}
|
|
48
54
|
|
|
49
55
|
async function runCheckTool(criterion: AcceptanceCriterion, objective: string): Promise<AcceptanceCheckResult | null> {
|
|
50
56
|
if (!criterion.checkTool) return null;
|
|
51
57
|
try {
|
|
52
|
-
const { executeToolBatch } = await import("../tool-runtime");
|
|
53
|
-
const { createAllTools } = await import("../tools/index");
|
|
58
|
+
const { executeToolBatch } = await import("../tool-runtime/index.ts");
|
|
59
|
+
const { createAllTools } = await import("../tools/index.ts");
|
|
54
60
|
const allTools = createAllTools(loadConfig());
|
|
55
61
|
const toolDef = allTools.find((t) => t.name === criterion.checkTool);
|
|
56
62
|
if (!toolDef) {
|
|
@@ -3,9 +3,9 @@ import type {
|
|
|
3
3
|
AgentAcceptanceCriterion,
|
|
4
4
|
AgentModelOverride,
|
|
5
5
|
AgentWorkspaceScope,
|
|
6
|
-
} from "../storage/collections";
|
|
7
|
-
import { col, toIndexable, fromIndexable } from "../storage/hive";
|
|
8
|
-
import { expandToolAllowlist } from "./delegation-runtime";
|
|
6
|
+
} from "../storage/collections.ts";
|
|
7
|
+
import { col, toIndexable, fromIndexable } from "../storage/hive.ts";
|
|
8
|
+
import { expandToolAllowlist } from "./delegation-runtime.ts";
|
|
9
9
|
|
|
10
10
|
interface CatalogPersona {
|
|
11
11
|
id: string;
|
|
@@ -13,24 +13,25 @@
|
|
|
13
13
|
* Also used directly by runAgentIsolated() for worker tasks.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
import { logger } from "../utils/logger"
|
|
17
|
-
import { col, fromIndexable } from "../storage/hive"
|
|
18
|
-
import { getHiveDb } from "../storage/hivedb"
|
|
16
|
+
import { logger } from "../utils/logger.ts"
|
|
17
|
+
import { col, fromIndexable } from "../storage/hive.ts"
|
|
18
|
+
import { getHiveDb } from "../storage/hivedb.ts"
|
|
19
19
|
import type { HiveDB, EventInput } from "@johpaz/hive-db"
|
|
20
|
-
import type { AgentDoc, TurnSource } from "../storage/collections"
|
|
21
|
-
import { callLLM, resolveProviderConfig, getDefaultLLM, type LLMMessage } from "./llm-client"
|
|
22
|
-
import { addMessage } from "./conversation-store"
|
|
23
|
-
import { saveTrace, recordLLMUsage } from "./tracer"
|
|
24
|
-
import { maybeCompact, clearOldToolResults } from "./compaction"
|
|
25
|
-
import { emitCanvas } from "../canvas/emitter"
|
|
20
|
+
import type { AgentDoc, TurnSource } from "../storage/collections.ts"
|
|
21
|
+
import { callLLM, resolveProviderConfig, getDefaultLLM, type LLMMessage, type ProviderCredentials } from "./llm-client.ts"
|
|
22
|
+
import { addMessage } from "./conversation-store.ts"
|
|
23
|
+
import { saveTrace, recordLLMUsage } from "./tracer.ts"
|
|
24
|
+
import { maybeCompact, clearOldToolResults } from "./compaction.ts"
|
|
25
|
+
import { emitCanvas } from "../canvas/emitter.ts"
|
|
26
26
|
import type { MCPClientManager } from "../mcp/index.ts"
|
|
27
|
-
import { compileContext } from "./context-compiler"
|
|
28
|
-
import { formatToolResult } from "../utils/toon"
|
|
29
|
-
import {
|
|
30
|
-
import
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
27
|
+
import { compileContext } from "./context-compiler.ts"
|
|
28
|
+
import { formatToolResult } from "../utils/toon.ts"
|
|
29
|
+
import { redactBinaryStrings } from "../utils/redact-binary.ts"
|
|
30
|
+
import { resolveUserId, resolveAgentId } from "../storage/onboarding.ts"
|
|
31
|
+
import type { ContentPart } from "../multimodal/types.ts"
|
|
32
|
+
import { loadConfig } from "../config/loader.ts"
|
|
33
|
+
import { executeToolBatch } from "../tool-runtime/index.ts"
|
|
34
|
+
import { createStuckLoopDetector, getInterventionMessage, type StuckLoopState } from "./stuck-loop.ts"
|
|
34
35
|
import {
|
|
35
36
|
createRun as createAgentRun,
|
|
36
37
|
checkpoint as checkpointRun,
|
|
@@ -44,9 +45,9 @@ import {
|
|
|
44
45
|
startLeaseRenewal,
|
|
45
46
|
stopLeaseRenewal,
|
|
46
47
|
type RunCheckpointState,
|
|
47
|
-
} from "./run-store"
|
|
48
|
-
import { publishNarration } from "../events/narration"
|
|
49
|
-
import { getNarration } from "../events/tool-narration"
|
|
48
|
+
} from "./run-store.ts"
|
|
49
|
+
import { publishNarration } from "../events/narration.ts"
|
|
50
|
+
import { getNarration } from "../events/tool-narration.ts"
|
|
50
51
|
|
|
51
52
|
const log = logger.child("agent-loop")
|
|
52
53
|
|
|
@@ -94,6 +95,50 @@ export async function synthesizeFinalResponse(
|
|
|
94
95
|
)
|
|
95
96
|
}
|
|
96
97
|
|
|
98
|
+
type LoadoutContext = {
|
|
99
|
+
tools: Array<{ type: string; function?: { name?: string } }>
|
|
100
|
+
allTools: Array<{ name: string }>
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Adds artifact_read to the loadout the moment a tool result hands the model an
|
|
105
|
+
* `artifact_ref` it will need to open.
|
|
106
|
+
*
|
|
107
|
+
* mcp-result-normalizer.ts moves oversized MCP text results out of the context
|
|
108
|
+
* window and leaves a reference behind. Discovery (search_knowledge) can find
|
|
109
|
+
* the reader, but that costs an iteration and assumes the model thinks to look:
|
|
110
|
+
* in the incident this comes from, it reached for artifact_inspect instead, got
|
|
111
|
+
* metadata, and burned the rest of its budget on `find` and `env` before the
|
|
112
|
+
* turn died on an empty synthesis. Image refs are excluded — those are carried
|
|
113
|
+
* to the UI, not read back by the model.
|
|
114
|
+
*
|
|
115
|
+
* Returns true when the loadout changed.
|
|
116
|
+
*/
|
|
117
|
+
export function injectArtifactReadIfNeeded(toolResult: unknown, ctx: LoadoutContext): boolean {
|
|
118
|
+
if (!Array.isArray(toolResult)) return false
|
|
119
|
+
|
|
120
|
+
const needsReader = toolResult.some((block) =>
|
|
121
|
+
!!block && typeof block === "object" &&
|
|
122
|
+
(block as { type?: unknown }).type === "artifact_ref" &&
|
|
123
|
+
!String((block as { mime_type?: unknown }).mime_type ?? "").startsWith("image/")
|
|
124
|
+
)
|
|
125
|
+
if (!needsReader) return false
|
|
126
|
+
if (ctx.tools.some((t) => t.function?.name === "artifact_read")) return false
|
|
127
|
+
|
|
128
|
+
const reader = ctx.allTools.find((t) => t.name === "artifact_read")
|
|
129
|
+
if (!reader) return false
|
|
130
|
+
|
|
131
|
+
ctx.tools.push({
|
|
132
|
+
type: "function",
|
|
133
|
+
function: {
|
|
134
|
+
name: reader.name,
|
|
135
|
+
description: (reader as any).description ?? "",
|
|
136
|
+
parameters: (reader as any).parameters ?? { type: "object", properties: {} },
|
|
137
|
+
},
|
|
138
|
+
} as LoadoutContext["tools"][number])
|
|
139
|
+
return true
|
|
140
|
+
}
|
|
141
|
+
|
|
97
142
|
/** Bounds a single async operation to its own timeout window, independent of any caller. */
|
|
98
143
|
export async function withTimeout<T>(op: () => Promise<T>, timeoutMs: number): Promise<T> {
|
|
99
144
|
let timer: ReturnType<typeof setTimeout>
|
|
@@ -171,6 +216,14 @@ export interface AgentLoopOptions {
|
|
|
171
216
|
taskId?: string
|
|
172
217
|
/** External routing/session id for progress delivery. */
|
|
173
218
|
sessionId?: string
|
|
219
|
+
/**
|
|
220
|
+
* Credenciales del proveedor para ESTA llamada, en vez de las del proceso.
|
|
221
|
+
*
|
|
222
|
+
* Un host multi-tenant resuelve la key de su inquilino y la pasa acá. Sin esto
|
|
223
|
+
* la única fuente era el secret store de HiveDB o `process.env`, ambos globales:
|
|
224
|
+
* dos inquilinos concurrentes en el mismo proceso compartían credencial.
|
|
225
|
+
*/
|
|
226
|
+
credentials?: ProviderCredentials
|
|
174
227
|
/** Whether to resume from a previously saved checkpoint */
|
|
175
228
|
resume?: boolean
|
|
176
229
|
/** Run budget — overrides agent.max_iterations when set */
|
|
@@ -215,6 +268,8 @@ export interface StreamChunk {
|
|
|
215
268
|
agent?: { messages: any[]; streamed?: boolean }
|
|
216
269
|
tools?: { messages: any[] }
|
|
217
270
|
usage?: { input_tokens: number; output_tokens: number }
|
|
271
|
+
/** Image artifacts (mcp-result-normalizer.ts) produced by tools this turn. */
|
|
272
|
+
artifacts?: { images: Array<{ artifactId: string; mimeType: string }> }
|
|
218
273
|
}
|
|
219
274
|
|
|
220
275
|
// ─── Main agent loop ──────────────────────────────────────────────────────────
|
|
@@ -280,7 +335,7 @@ export async function* runAgent(
|
|
|
280
335
|
agentProvider = agentProvider || defaultLLM.provider
|
|
281
336
|
agentModel = agentModel || defaultLLM.model
|
|
282
337
|
}
|
|
283
|
-
const providerCfg = await resolveProviderConfig(agentProvider, agentModel)
|
|
338
|
+
const providerCfg = await resolveProviderConfig(agentProvider, agentModel, opts.credentials)
|
|
284
339
|
|
|
285
340
|
const cleanModel = providerCfg.model.replace(new RegExp(`^${providerCfg.provider}\\/`), "")
|
|
286
341
|
log.info(`[agent-loop] Starting: agent=${agentName} thread=${opts.threadId} provider=${providerCfg.provider}/${cleanModel}`)
|
|
@@ -360,6 +415,10 @@ export async function* runAgent(
|
|
|
360
415
|
let iterations = 0
|
|
361
416
|
let totalInputTokens = 0
|
|
362
417
|
let totalOutputTokens = 0
|
|
418
|
+
// Image artifacts produced by tool results this turn (post mcp-result-normalizer.ts) —
|
|
419
|
+
// surfaced in the final chunk so callers (webchat-turn.ts) can attach them to the
|
|
420
|
+
// outbound message instead of the model having to describe them in text.
|
|
421
|
+
const turnImageArtifacts: Array<{ artifactId: string; mimeType: string }> = []
|
|
363
422
|
let lastToolSignature = ""
|
|
364
423
|
let consecutiveRepeat = 0
|
|
365
424
|
let idleIterations = 0
|
|
@@ -452,7 +511,7 @@ export async function* runAgent(
|
|
|
452
511
|
iterations++
|
|
453
512
|
|
|
454
513
|
const delegationGroupAtCall = opts.turnId && !opts.isolated
|
|
455
|
-
? await import("../gateway/delegation-groups").then((mod) => mod.getDelegationGroup(opts.turnId!))
|
|
514
|
+
? await import("../gateway/delegation-groups.ts").then((mod) => mod.getDelegationGroup(opts.turnId!))
|
|
456
515
|
: null
|
|
457
516
|
let streamedThisCall = false
|
|
458
517
|
let response: Awaited<ReturnType<typeof callLLM>>
|
|
@@ -648,6 +707,27 @@ export async function* runAgent(
|
|
|
648
707
|
const toolResultJS = batchResult.result
|
|
649
708
|
const toolMs = batchResult.durationMs
|
|
650
709
|
|
|
710
|
+
// Surface image artifacts (see mcp-result-normalizer.ts) so the final
|
|
711
|
+
// response can carry them to the UI/channel — before TOON-encoding,
|
|
712
|
+
// while toolResultJS is still structured.
|
|
713
|
+
if (Array.isArray(toolResultJS)) {
|
|
714
|
+
for (const block of toolResultJS) {
|
|
715
|
+
if (
|
|
716
|
+
block && typeof block === "object" &&
|
|
717
|
+
(block as { type?: unknown }).type === "artifact_ref" &&
|
|
718
|
+
typeof (block as { mime_type?: unknown }).mime_type === "string" &&
|
|
719
|
+
(block as { mime_type: string }).mime_type.startsWith("image/")
|
|
720
|
+
) {
|
|
721
|
+
const ref = block as { artifact_id: string; mime_type: string }
|
|
722
|
+
turnImageArtifacts.push({ artifactId: ref.artifact_id, mimeType: ref.mime_type })
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
if (injectArtifactReadIfNeeded(toolResultJS, ctx)) {
|
|
728
|
+
log.info("[agent-loop] Tool result carries an artifact_ref — injected artifact_read into loadout")
|
|
729
|
+
}
|
|
730
|
+
|
|
651
731
|
// Encode TOON only for LLM consumption (with cost calculation)
|
|
652
732
|
const toolResultLLM = formatToolResult(toolResultJS, cleanModel)
|
|
653
733
|
|
|
@@ -812,7 +892,7 @@ export async function* runAgent(
|
|
|
812
892
|
// Inject skills associated with the injected tools
|
|
813
893
|
if (injectedTools.length > 0) {
|
|
814
894
|
try {
|
|
815
|
-
const skillsCol = await col<import("../storage/collections").SkillDoc>("skills")
|
|
895
|
+
const skillsCol = await col<import("../storage/collections.ts").SkillDoc>("skills")
|
|
816
896
|
// Find skills that use any of the injected tools
|
|
817
897
|
const activeSkills = (await skillsCol.scan({})).filter(e => e.doc.active)
|
|
818
898
|
const skillsWithTools = activeSkills
|
|
@@ -1032,7 +1112,7 @@ export async function* runAgent(
|
|
|
1032
1112
|
// Make one extra call without tools so it summarizes what it did.
|
|
1033
1113
|
if (!finalContent) {
|
|
1034
1114
|
const pendingDelegation = opts.turnId && !opts.isolated
|
|
1035
|
-
? await import("../gateway/delegation-groups").then((mod) => mod.getDelegationGroup(opts.turnId!))
|
|
1115
|
+
? await import("../gateway/delegation-groups.ts").then((mod) => mod.getDelegationGroup(opts.turnId!))
|
|
1036
1116
|
: null
|
|
1037
1117
|
if (pendingDelegation) {
|
|
1038
1118
|
log.info(`[agent-loop] Suppressing terminal synthesis while delegation group ${opts.turnId} is pending`)
|
|
@@ -1085,6 +1165,10 @@ export async function* runAgent(
|
|
|
1085
1165
|
yield { usage: { input_tokens: totalInputTokens, output_tokens: totalOutputTokens } }
|
|
1086
1166
|
}
|
|
1087
1167
|
|
|
1168
|
+
if (turnImageArtifacts.length > 0) {
|
|
1169
|
+
yield { artifacts: { images: turnImageArtifacts } }
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1088
1172
|
// ── Post-loop ────────────────────────────────────────────────────────────
|
|
1089
1173
|
const durationMs = Math.round(performance.now() - t0)
|
|
1090
1174
|
|
|
@@ -1203,6 +1287,12 @@ export interface IsolatedAgentOptions {
|
|
|
1203
1287
|
userId?: string
|
|
1204
1288
|
channel?: string
|
|
1205
1289
|
sessionId?: string
|
|
1290
|
+
/**
|
|
1291
|
+
* Se hereda del turno que delegó. Sin propagarla, un worker delegado volvía a
|
|
1292
|
+
* caer en la credencial global del proceso y la fuga entre inquilinos se
|
|
1293
|
+
* reabría justo en el camino de delegación.
|
|
1294
|
+
*/
|
|
1295
|
+
credentials?: ProviderCredentials
|
|
1206
1296
|
}
|
|
1207
1297
|
|
|
1208
1298
|
export async function runAgentIsolatedDetailed(
|
|
@@ -1226,15 +1316,14 @@ export async function runAgentIsolatedDetailed(
|
|
|
1226
1316
|
userId: opts.userId,
|
|
1227
1317
|
channel: opts.channel,
|
|
1228
1318
|
sessionId: opts.sessionId,
|
|
1319
|
+
credentials: opts.credentials,
|
|
1229
1320
|
})) {
|
|
1230
1321
|
if (chunk.agent?.messages?.[0]?.content) {
|
|
1231
1322
|
lastContent = chunk.agent.messages[0].content
|
|
1232
1323
|
}
|
|
1233
1324
|
for (const message of chunk.tools?.messages ?? []) {
|
|
1234
1325
|
const raw = typeof message.content === "string" ? message.content : JSON.stringify(message.content)
|
|
1235
|
-
const safe = raw
|
|
1236
|
-
.replace(/data:[a-z0-9.+-]+\/[a-z0-9.+-]+;base64,[a-z0-9+/=\s]+/gi, "[REDACTED_BINARY]")
|
|
1237
|
-
.replace(/[A-Za-z0-9+/]{1000,}={0,2}/g, "[REDACTED_BINARY]")
|
|
1326
|
+
const safe = redactBinaryStrings(raw)
|
|
1238
1327
|
toolEvidence.push(`${message.name ?? "tool"}: ${safe.slice(0, 4000)}`)
|
|
1239
1328
|
if (toolEvidence.length > 8) toolEvidence.shift()
|
|
1240
1329
|
}
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
import type { IndexDoc } from "@johpaz/hive-db";
|
|
22
|
-
import { getHiveDb } from "../storage/hivedb";
|
|
23
|
-
import { logger } from "../utils/logger";
|
|
22
|
+
import { getHiveDb } from "../storage/hivedb.ts";
|
|
23
|
+
import { logger } from "../utils/logger.ts";
|
|
24
24
|
|
|
25
25
|
const log = logger.child("capability-search");
|
|
26
26
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { col } from "../storage/hive";
|
|
2
|
-
import type { AgentDoc } from "../storage/collections";
|
|
1
|
+
import { col } from "../storage/hive.ts";
|
|
2
|
+
import type { AgentDoc } from "../storage/collections.ts";
|
|
3
3
|
import {
|
|
4
4
|
applyRelativeCutoff,
|
|
5
5
|
replaceCapabilityDocs,
|
|
6
6
|
searchCapabilities,
|
|
7
7
|
type CapabilityDoc,
|
|
8
|
-
} from "./capability-search";
|
|
9
|
-
import { logger } from "../utils/logger";
|
|
8
|
+
} from "./capability-search.ts";
|
|
9
|
+
import { logger } from "../utils/logger.ts";
|
|
10
10
|
|
|
11
11
|
const log = logger.child("catalog-selector");
|
|
12
12
|
const RELEVANCE_RATIO = 0.35;
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* short summaries in the in-memory message array before model calls.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
import { logger } from "../utils/logger"
|
|
18
|
+
import { logger } from "../utils/logger.ts"
|
|
19
19
|
import {
|
|
20
20
|
getTotalTokens,
|
|
21
21
|
getHistory,
|
|
@@ -24,11 +24,11 @@ import {
|
|
|
24
24
|
getMessageCount,
|
|
25
25
|
isInternalSource,
|
|
26
26
|
type StoredMessage,
|
|
27
|
-
} from "./conversation-store"
|
|
28
|
-
import { estimateTokens } from "../utils/toon"
|
|
29
|
-
import { callLLM, resolveProviderConfig, getDefaultLLM, type ContentPart } from "./llm-client"
|
|
30
|
-
import { col, fromIndexable } from "../storage/hive"
|
|
31
|
-
import type { AgentDoc, ModelDoc } from "../storage/collections"
|
|
27
|
+
} from "./conversation-store.ts"
|
|
28
|
+
import { estimateTokens } from "../utils/toon.ts"
|
|
29
|
+
import { callLLM, resolveProviderConfig, getDefaultLLM, type ContentPart } from "./llm-client.ts"
|
|
30
|
+
import { col, fromIndexable } from "../storage/hive.ts"
|
|
31
|
+
import type { AgentDoc, ModelDoc } from "../storage/collections.ts"
|
|
32
32
|
|
|
33
33
|
const log = logger.child("compaction")
|
|
34
34
|
|
|
@@ -118,7 +118,7 @@ export function renderTranscript(rows: StoredMessage[], maxMsgChars = MAX_MSG_CH
|
|
|
118
118
|
/**
|
|
119
119
|
* Compress a thread's history into a summary.
|
|
120
120
|
*/
|
|
121
|
-
async function compactThread(
|
|
121
|
+
export async function compactThread(
|
|
122
122
|
threadId: string,
|
|
123
123
|
notify?: { channel: string; userId: string }
|
|
124
124
|
): Promise<void> {
|
|
@@ -187,11 +187,12 @@ async function compactThread(
|
|
|
187
187
|
// Notify user in their active channel (non-critical)
|
|
188
188
|
if (notify?.channel && notify?.userId) {
|
|
189
189
|
try {
|
|
190
|
-
const { sendToUserChannel } = await import("../gateway/channel-notify")
|
|
190
|
+
const { sendToUserChannel } = await import("../gateway/channel-notify.ts")
|
|
191
191
|
await sendToUserChannel(
|
|
192
192
|
notify.channel,
|
|
193
193
|
notify.userId,
|
|
194
|
-
`🗜️ Resumí ${toSummarize.length} mensajes anteriores para mantener el contexto limpio
|
|
194
|
+
`🗜️ Resumí ${toSummarize.length} mensajes anteriores para mantener el contexto limpio.`,
|
|
195
|
+
{ threadId }
|
|
195
196
|
)
|
|
196
197
|
} catch {
|
|
197
198
|
// Non-critical — don't break the flow if notification fails
|