@johpaz/hive-sdk 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +129 -0
- package/README.md +78 -23
- package/bun.lock +55 -29
- package/bunfig.toml +4 -2
- package/docs/API-AGENTS.md +78 -27
- package/docs/API-CONTEXT-COMPILER.md +31 -34
- package/docs/API-TOOLS-SKILLS-CHANNELS.md +58 -22
- package/docs/HIVE-HARNESS.md +1 -1
- package/docs/INDEX.md +4 -4
- package/docs/TEMPLATE-HIVE-APP.md +10 -10
- package/package.json +17 -12
- package/packages/cli/package.json +2 -2
- package/packages/cli/src/commands/create-app.test.ts +36 -7
- package/packages/cli/src/commands/init.ts +3 -3
- package/packages/cli/src/commands/run.ts +1 -1
- package/packages/cli/src/commands/test.ts +37 -25
- package/packages/cli/src/commands/trace.ts +30 -28
- package/packages/cli/templates/hive-app/.env.example +10 -2
- package/packages/cli/templates/hive-app/README.md +103 -0
- package/packages/cli/templates/hive-app/hive.config.ts +9 -3
- package/packages/cli/templates/hive-app/src/agents/coordinator.ts +8 -1
- package/packages/cli/templates/hive-app/src/main.ts +12 -19
- package/packages/core/package.json +13 -12
- package/packages/core/src/agent/acceptance-checks.ts +172 -0
- package/packages/core/src/agent/agent-catalog.ts +348 -0
- package/packages/core/src/agent/agent-loop.ts +1373 -0
- package/packages/core/src/agent/capability-search.ts +186 -0
- package/packages/core/src/agent/catalog-selector.ts +103 -0
- package/packages/core/src/agent/{Compaction.ts → compaction.ts} +86 -63
- package/packages/core/src/agent/context-compiler.ts +689 -0
- package/packages/core/src/agent/conversation-store.ts +381 -0
- package/packages/core/src/agent/curator.ts +276 -0
- package/packages/core/src/agent/delegation-runtime.ts +241 -0
- package/packages/core/src/agent/goal-runner.ts +323 -0
- package/packages/core/src/agent/index.ts +17 -12
- package/packages/core/src/agent/llm-client.ts +266 -0
- package/packages/core/src/agent/llm-providers/anthropic.ts +264 -0
- package/packages/core/src/agent/llm-providers/deepseek.ts +8 -0
- package/packages/core/src/agent/{providers → llm-providers}/gemini.ts +98 -60
- package/packages/core/src/agent/llm-providers/groq.ts +5 -0
- package/packages/core/src/agent/llm-providers/hiveagents.ts +253 -0
- package/packages/core/src/agent/{providers → llm-providers}/interface.ts +73 -13
- package/packages/core/src/agent/llm-providers/kimi.ts +8 -0
- package/packages/core/src/agent/llm-providers/minimax.ts +13 -0
- package/packages/core/src/agent/llm-providers/mistral.ts +5 -0
- package/packages/core/src/agent/llm-providers/modelscope.ts +5 -0
- package/packages/core/src/agent/llm-providers/nvidia.ts +5 -0
- package/packages/core/src/agent/{providers → llm-providers}/ollama.ts +31 -5
- package/packages/core/src/agent/llm-providers/openai-compat-base.ts +418 -0
- package/packages/core/src/agent/llm-providers/openai.ts +5 -0
- package/packages/core/src/agent/llm-providers/opencode-go.ts +9 -0
- package/packages/core/src/agent/llm-providers/openrouter.ts +5 -0
- package/packages/core/src/agent/llm-providers/qwen.ts +5 -0
- package/packages/core/src/agent/llm-providers/z-ai.ts +5 -0
- package/packages/core/src/agent/minimal-loadout.ts +47 -0
- package/packages/core/src/agent/playbook-selector.ts +119 -0
- package/packages/core/src/agent/{PromptBuilder.ts → prompt-builder.ts} +21 -22
- package/packages/core/src/{harness → agent}/proof-packet.ts +16 -21
- package/packages/core/src/agent/providers/index.ts +35 -16
- package/packages/core/src/agent/reflector.ts +320 -0
- package/packages/core/src/agent/routing-intent.ts +22 -0
- package/packages/core/src/{harness → agent}/run-epoch.ts +4 -3
- package/packages/core/src/{harness → agent}/run-store.ts +142 -81
- package/packages/core/src/agent/{Service.ts → service.ts} +37 -26
- package/packages/core/src/agent/skill-selector.ts +374 -0
- package/packages/core/src/agent/stuck-loop.ts +209 -0
- package/packages/core/src/agent/{selectors/ToolSelector.ts → tool-selector.ts} +188 -178
- package/packages/core/src/{ace/Tracer.ts → agent/tracer.ts} +37 -27
- package/packages/core/src/api/createAgent.test.ts +139 -27
- package/packages/core/src/api/createAgent.ts +232 -44
- package/packages/core/src/artifacts/store.ts +162 -0
- package/packages/core/src/canvas/canvas-manager.ts +161 -0
- package/packages/core/src/canvas/canvas.test.ts +8 -4
- package/packages/core/src/canvas/emitter.ts +131 -80
- package/packages/core/src/canvas/index.ts +1 -3
- package/packages/core/src/channels/base.ts +9 -1
- package/packages/core/src/channels/discord.ts +5 -4
- package/packages/core/src/channels/manager.ts +122 -30
- package/packages/core/src/channels/slack.ts +5 -4
- package/packages/core/src/channels/telegram.ts +36 -6
- package/packages/core/src/channels/webchat.ts +11 -10
- package/packages/core/src/channels/whatsapp.ts +23 -7
- package/packages/core/src/config/index.ts +13 -2
- package/packages/core/src/config/loader.ts +76 -29
- package/packages/core/src/ethics/EthicsGuard.test.ts +90 -36
- package/packages/core/src/ethics/EthicsGuard.ts +51 -47
- package/packages/core/src/events/agent-bus.ts +44 -68
- package/packages/core/src/events/channel-narration.ts +150 -0
- package/packages/core/src/events/narration.ts +82 -0
- package/packages/core/src/events/tool-narration.ts +62 -0
- package/packages/core/src/gateway/delegation-groups.ts +258 -0
- package/packages/core/src/{harness → gateway}/durable-queue.ts +102 -42
- package/packages/core/src/{harness → gateway}/job-store.ts +85 -48
- package/packages/core/src/gateway/lane-queue.ts +173 -0
- package/packages/core/src/gateway/notification-inbox.ts +57 -0
- package/packages/core/src/gateway/server.ts +1 -1
- package/packages/core/src/harness/index.ts +46 -27
- package/packages/core/src/index.ts +33 -27
- package/packages/core/src/mcp/hot-reload.ts +32 -23
- package/packages/core/src/mcp/index.ts +6 -3
- package/packages/core/src/mcp/singleton.ts +1 -4
- package/packages/core/src/mcp/tool-sync.ts +138 -0
- package/packages/core/src/memory/Scratchpad.test.ts +39 -20
- package/packages/core/src/memory/Scratchpad.ts +27 -34
- package/packages/core/src/multimodal/vision-service.ts +44 -38
- package/packages/core/src/resilience/retry.ts +95 -0
- package/packages/core/src/scheduler/CronScheduler.ts +334 -287
- package/packages/core/src/scheduler/index.ts +9 -7
- package/packages/core/src/scheduler/integration.ts +46 -26
- package/packages/core/src/scheduler/scheduler.test.ts +9 -13
- package/packages/core/src/scheduler/types.ts +7 -2
- package/packages/core/src/security/Pairing.ts +1 -1
- package/packages/core/src/skills/bundled/a2ui/a2ui_dashboard/SKILL.md +176 -0
- package/packages/core/src/skills/bundled/a2ui/a2ui_form/SKILL.md +202 -0
- package/packages/core/src/skills/bundled/a2ui/a2ui_interactive/SKILL.md +206 -0
- package/packages/core/src/skills/bundled/agents/agent_spawner/SKILL.md +173 -0
- package/packages/core/src/skills/bundled/agents/memory_manager/SKILL.md +143 -0
- package/packages/core/src/skills/bundled/agents/research_and_remember/SKILL.md +139 -0
- package/packages/core/src/skills/bundled/agents/task_orchestrator/SKILL.md +98 -0
- package/packages/core/src/skills/bundled/api/api_client/SKILL.md +132 -0
- package/packages/core/src/skills/bundled/cli/cli_pipeline/SKILL.md +135 -0
- package/packages/core/src/skills/bundled/cli/cli_safe_exec/SKILL.md +125 -0
- package/packages/core/src/skills/bundled/cli/software_engineering/SKILL.md +23 -0
- package/packages/core/src/skills/bundled/cron_manager/SKILL.md +188 -0
- package/packages/core/src/skills/bundled/cron_reminder/SKILL.md +112 -0
- package/packages/core/src/skills/bundled/filesystem/file_manager/SKILL.md +118 -0
- package/packages/core/src/skills/bundled/filesystem/file_read_and_summarize/SKILL.md +109 -0
- package/packages/core/src/skills/bundled/filesystem/file_writer/SKILL.md +129 -0
- package/packages/core/src/skills/bundled/filesystem/workspace_file_operator/SKILL.md +22 -0
- package/packages/core/src/skills/bundled/office/office_document_manager/SKILL.md +262 -0
- package/packages/core/src/skills/bundled/search_knowledge/capability_discovery/SKILL.md +75 -0
- package/packages/core/src/skills/bundled/web/browser_automate/SKILL.md +120 -0
- package/packages/core/src/skills/bundled/web/browser_scrape/SKILL.md +109 -0
- package/packages/core/src/skills/bundled/web/web_monitor/SKILL.md +127 -0
- package/packages/core/src/skills/bundled/web/web_research/SKILL.md +119 -0
- package/packages/core/src/skills/bundled-data.generated.ts +731 -2678
- package/packages/core/src/skills/skills.test.ts +52 -11
- package/packages/core/src/{harness → storage}/boot-id.ts +5 -2
- package/packages/core/src/storage/bootstrap.ts +151 -0
- package/packages/core/src/storage/causal-events.ts +84 -0
- package/packages/core/src/storage/collections.ts +680 -0
- package/packages/core/src/storage/crypto.ts +205 -74
- package/packages/core/src/{harness/db-helpers.ts → storage/hive.ts} +63 -7
- package/packages/core/src/storage/hivedb.ts +61 -0
- package/packages/core/src/storage/index.ts +111 -18
- package/packages/core/src/storage/model-id.ts +53 -0
- package/packages/core/src/storage/onboarding.ts +540 -972
- package/packages/core/src/storage/reconcile.ts +238 -0
- package/packages/core/src/storage/seed.ts +572 -406
- package/packages/core/src/storage/usage.ts +285 -225
- package/packages/core/src/storage/user-email.ts +11 -0
- package/packages/core/src/swarm/AgentExecutor.ts +1 -1
- package/packages/core/src/swarm/EventBridge.ts +1 -1
- package/packages/core/src/swarm/index.ts +12 -9
- package/packages/core/src/tool-runtime/index.ts +146 -23
- package/packages/core/src/tool-runtime/tool-worker.ts +2 -2
- package/packages/core/src/tool-runtime/worker-tools.ts +27 -0
- package/packages/core/src/{canvas/a2ui-tools.ts → tools/a2ui/index.ts} +17 -8
- package/packages/core/src/tools/agents/get-available-models.ts +36 -54
- package/packages/core/src/tools/agents/index.ts +784 -292
- package/packages/core/src/tools/api/api-request.test.ts +164 -0
- package/packages/core/src/tools/api/api-request.ts +174 -0
- package/packages/core/src/tools/api/index.ts +16 -0
- package/packages/core/src/tools/cli/index.ts +4 -0
- package/packages/core/src/tools/core/index.ts +281 -112
- package/packages/core/src/tools/cron/index.ts +121 -124
- package/packages/core/src/tools/index.ts +63 -78
- package/packages/core/src/tools/office/office-escribir-xlsx.ts +3 -1
- package/packages/core/src/tools/types.ts +3 -1
- package/packages/core/src/tools/web/artifact-inspect.ts +23 -0
- package/packages/core/src/tools/web/browser-backend.ts +129 -0
- package/packages/core/src/tools/web/browser-screenshot.ts +26 -5
- package/packages/core/src/tools/web/browser-service.ts +80 -35
- package/packages/core/src/tools/web/browser-type.ts +3 -8
- package/packages/core/src/tools/web/index.ts +4 -4
- package/packages/core/src/tools/web/webview-backend.ts +412 -0
- package/packages/core/src/voice/index.ts +89 -63
- package/packages/core/src/workers/agent.worker.ts +2 -2
- package/packages/core/src/workers/workers.test.ts +3 -10
- package/scripts/bump-version.ts +248 -0
- package/scripts/generate-skill-bundle.ts +108 -0
- package/test/acceptance-checks.test.ts +403 -0
- package/test/agent-loop-terminal-synthesis.test.ts +32 -0
- package/test/browser-backend.test.ts +308 -0
- package/test/catalog-agents-stay-enabled.test.ts +117 -0
- package/test/causal-events.test.ts +117 -0
- package/test/compaction.test.ts +105 -0
- package/test/context-compiler.test.ts +269 -0
- package/test/curator.test.ts +130 -0
- package/test/durable-queue.test.ts +114 -0
- package/test/harness-barrel.test.ts +64 -0
- package/test/hive-helpers.test.ts +130 -0
- package/test/hivedb-search.test.ts +189 -0
- package/test/internal-turns.test.ts +166 -0
- package/test/job-idempotency.test.ts +68 -0
- package/test/job-retry-backoff.test.ts +184 -0
- package/test/job-store.test.ts +381 -0
- package/test/llm-retry.test.ts +97 -0
- package/test/memory-perf.test.ts +774 -0
- package/test/minimal-loadout.test.ts +78 -0
- package/test/model-catalog.test.ts +105 -0
- package/test/preload.ts +12 -0
- package/test/reflector.test.ts +320 -0
- package/test/retention-cap.test.ts +91 -0
- package/test/retired-capabilities-pruned.test.ts +192 -0
- package/test/run-store.test.ts +355 -0
- package/test/scratchpad.test.ts +74 -0
- package/test/secrets-durability.test.ts +119 -0
- package/test/seed-model-reseed.test.ts +155 -0
- package/test/setup-agent-seed.test.ts +264 -0
- package/test/tool-inventory.test.ts +65 -0
- package/test/tool-runtime.test.ts +258 -0
- package/test/tool-selector-runtime-tools.test.ts +117 -0
- package/test/toon.test.ts +429 -0
- package/tsconfig.json +2 -0
- package/packages/core/src/ace/Curator.ts +0 -158
- package/packages/core/src/ace/Reflector.ts +0 -200
- package/packages/core/src/ace/index.ts +0 -4
- package/packages/core/src/agent/AgentRunner.ts +0 -711
- package/packages/core/src/agent/ContextCompiler.ts +0 -567
- package/packages/core/src/agent/ContextGuard.ts +0 -91
- package/packages/core/src/agent/ConversationStore.ts +0 -254
- package/packages/core/src/agent/Hooks.ts +0 -166
- package/packages/core/src/agent/StuckLoop.ts +0 -133
- package/packages/core/src/agent/providers/LLMClient.ts +0 -149
- package/packages/core/src/agent/providers/anthropic.ts +0 -212
- package/packages/core/src/agent/providers/openai-compat.ts +0 -231
- package/packages/core/src/agent/selectors/PlaybookSelector.ts +0 -121
- package/packages/core/src/agent/selectors/SkillSelector.ts +0 -322
- package/packages/core/src/agent/selectors/index.ts +0 -6
- package/packages/core/src/auth/auth.ts +0 -121
- package/packages/core/src/auth/index.ts +0 -1
- package/packages/core/src/canvas/CanvasManager.ts +0 -390
- package/packages/core/src/canvas/canvas-tools.ts +0 -448
- package/packages/core/src/harness/collections.ts +0 -98
- package/packages/core/src/harness/goal-verifier.ts +0 -141
- package/packages/core/src/harness/harness.test.ts +0 -236
- package/packages/core/src/harness/reconcile.ts +0 -149
- package/packages/core/src/mcp/MCPToolAdapter.ts +0 -176
- package/packages/core/src/multimodal/VisionService.ts +0 -293
- package/packages/core/src/scheduler/dag/AgentExecutor.ts +0 -53
- package/packages/core/src/scheduler/dag/DAGScheduler.ts +0 -250
- package/packages/core/src/scheduler/dag/EventBridge.ts +0 -122
- package/packages/core/src/scheduler/dag/TaskGraph.ts +0 -192
- package/packages/core/src/scheduler/dag/TaskNode.ts +0 -97
- package/packages/core/src/scheduler/dag/TaskResult.ts +0 -22
- package/packages/core/src/scheduler/dag/errors.ts +0 -37
- package/packages/core/src/scheduler/dag/index.ts +0 -26
- package/packages/core/src/scheduler/dag/presets/ResearchPreset.ts +0 -97
- package/packages/core/src/scheduler/dag/strategies/ParallelStrategy.ts +0 -21
- package/packages/core/src/scheduler/dag/strategies/PriorityStrategy.ts +0 -46
- package/packages/core/src/storage/HiveDBStorage.ts +0 -64
- package/packages/core/src/storage/SQLiteStorage.ts +0 -414
- package/packages/core/src/storage/hiveSeed.ts +0 -308
- package/packages/core/src/storage/hiveStorage.test.ts +0 -38
- package/packages/core/src/storage/schema.ts +0 -689
- package/packages/core/src/storage/storage.test.ts +0 -37
- package/packages/core/src/swarm/AgentBus.ts +0 -460
- package/packages/core/src/swarm/EventBus.ts +0 -169
- package/packages/core/src/swarm/WorkerPool.ts +0 -236
- package/packages/core/src/tools/bridge-events.ts +0 -26
- package/packages/core/src/tools/canvas/index.ts +0 -375
- package/packages/core/src/tools/codebridge/index.ts +0 -342
- package/packages/core/src/tools/meeting/index.ts +0 -353
- package/packages/core/src/tools/projects/index.ts +0 -37
- package/packages/core/src/tools/projects/project-create.ts +0 -94
- package/packages/core/src/tools/projects/project-done.ts +0 -66
- package/packages/core/src/tools/projects/project-fail.ts +0 -66
- package/packages/core/src/tools/projects/project-list.ts +0 -96
- package/packages/core/src/tools/projects/project-update.ts +0 -72
- package/packages/core/src/tools/projects/task-create.ts +0 -68
- package/packages/core/src/tools/projects/task-evaluate.ts +0 -93
- package/packages/core/src/tools/projects/task-update.ts +0 -93
- package/packages/core/src/tools/voice/index.ts +0 -104
- package/packages/core/src/tools/web/api-request.test.ts +0 -170
- package/packages/core/src/tools/web/api-request.ts +0 -239
- package/test/setup-db.ts +0 -216
- /package/packages/core/src/agent/{NativeTools.ts → native-tools.ts} +0 -0
|
@@ -1,21 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* El catálogo de skills bundled se genera desde los SKILL.md de `skills/bundled/`
|
|
3
|
+
* con `bun run skills:bundle`. Hasta 0.1.5 el SDK traía 44 skills copiadas a
|
|
4
|
+
* mano, 21 de las cuales invocaban tools que ya no existen (`voice_*`,
|
|
5
|
+
* `meeting_transcription`, `canvas_*`, `code_*`, `project_*`): el selector se
|
|
6
|
+
* las podía ofrecer al modelo y la ejecución moría sin ejecutor.
|
|
7
|
+
*/
|
|
8
|
+
|
|
1
9
|
import { describe, it, expect } from "bun:test";
|
|
2
10
|
import { BUNDLED_SKILLS_DATA } from "./bundled-data.generated.ts";
|
|
11
|
+
import { createAllTools } from "../tools/index.ts";
|
|
12
|
+
import { loadConfig } from "../config/loader.ts";
|
|
3
13
|
|
|
4
14
|
describe("Bundled skills", () => {
|
|
5
|
-
it("
|
|
6
|
-
const skill = BUNDLED_SKILLS_DATA.find((s) => s.name === "web_browser_research");
|
|
7
|
-
expect(skill).toBeDefined();
|
|
8
|
-
expect(skill?.category).toBe("web");
|
|
9
|
-
expect(skill?.tools).toContain("web_search");
|
|
10
|
-
expect(skill?.tools).toContain("browser_navigate");
|
|
11
|
-
expect(skill?.tools).toContain("browser_extract");
|
|
12
|
-
expect(skill?.triggers.length).toBeGreaterThan(0);
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it("includes existing web and browser skills", () => {
|
|
15
|
+
it("incluye las skills web y de browser", () => {
|
|
16
16
|
const names = BUNDLED_SKILLS_DATA.map((s) => s.name);
|
|
17
17
|
expect(names).toContain("web_research");
|
|
18
18
|
expect(names).toContain("browser_scrape");
|
|
19
19
|
expect(names).toContain("browser_automate");
|
|
20
20
|
});
|
|
21
|
+
|
|
22
|
+
it("no arrastra las skills retiradas", () => {
|
|
23
|
+
const names = BUNDLED_SKILLS_DATA.map((s) => s.name);
|
|
24
|
+
for (const retired of [
|
|
25
|
+
"web_browser_research",
|
|
26
|
+
"voice_input",
|
|
27
|
+
"voice_output",
|
|
28
|
+
"voice_assistant",
|
|
29
|
+
"meeting_transcription",
|
|
30
|
+
"canvas_report",
|
|
31
|
+
"canvas_dashboard",
|
|
32
|
+
"code_review",
|
|
33
|
+
"code_generate",
|
|
34
|
+
"project_planner",
|
|
35
|
+
"busqueda_fts5",
|
|
36
|
+
"ai_coder",
|
|
37
|
+
"data_analyst",
|
|
38
|
+
]) {
|
|
39
|
+
expect(names, `la skill retirada "${retired}" volvió al bundle`).not.toContain(retired);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("cada skill declara sólo tools que existen en el registry", async () => {
|
|
44
|
+
const available = new Set(createAllTools(await loadConfig()).map((t) => t.name));
|
|
45
|
+
|
|
46
|
+
const dangling = BUNDLED_SKILLS_DATA.flatMap((skill) =>
|
|
47
|
+
(skill.tools ?? [])
|
|
48
|
+
.filter((tool) => !available.has(tool))
|
|
49
|
+
.map((tool) => `${skill.name} → ${tool}`)
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
expect(dangling, `skills apuntando a tools inexistentes:\n${dangling.join("\n")}`).toEqual([]);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("toda skill tiene nombre, descripción y categoría", () => {
|
|
56
|
+
for (const skill of BUNDLED_SKILLS_DATA) {
|
|
57
|
+
expect(skill.name, "skill sin nombre").toBeTruthy();
|
|
58
|
+
expect(skill.description, `${skill.name} sin descripción`).toBeTruthy();
|
|
59
|
+
expect(skill.category, `${skill.name} sin categoría`).toBeTruthy();
|
|
60
|
+
}
|
|
61
|
+
});
|
|
21
62
|
});
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* boot-id — a unique id generated on every process start so that durable
|
|
3
|
-
* leases (
|
|
3
|
+
* leases (agentRuns / jobQueue) can detect which rows belong to a dead
|
|
4
4
|
* process after a crash/restart.
|
|
5
|
+
*
|
|
6
|
+
* The id is a short hex string; it is stable for the lifetime of the
|
|
7
|
+
* process and can be passed to {@link reconcileOnBoot}.
|
|
5
8
|
*/
|
|
6
9
|
|
|
7
10
|
import { randomBytes } from "node:crypto";
|
|
@@ -17,4 +20,4 @@ export function getBootId(): string {
|
|
|
17
20
|
|
|
18
21
|
export function resetBootId(): void {
|
|
19
22
|
currentBootId = null;
|
|
20
|
-
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HiveDB bootstrap — replaces initializeDatabase() + seedAllData() +
|
|
3
|
+
* runStartupMigrations().
|
|
4
|
+
*
|
|
5
|
+
* A brand-new install never has legacy SQLite data to migrate, so there is
|
|
6
|
+
* no version-gated migration list: ensureHiveDb() just makes sure every
|
|
7
|
+
* collection's secondary indexes exist (idempotent, safe every boot) and
|
|
8
|
+
* that the static catalogs are (re)seeded from their canonical source
|
|
9
|
+
* (SEED_DATA / SkillLoader) — same "reseed every boot so code changes
|
|
10
|
+
* always take effect" behavior `seedAllData()` had, just via `put()`
|
|
11
|
+
* instead of `DELETE`+`INSERT`.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { getHiveDb } from "./hivedb";
|
|
15
|
+
import { col } from "./hive";
|
|
16
|
+
import { seedAllData } from "./seed";
|
|
17
|
+
import { ensureSecretsBackend } from "./crypto";
|
|
18
|
+
|
|
19
|
+
interface IndexSpec {
|
|
20
|
+
collection: string;
|
|
21
|
+
field: string;
|
|
22
|
+
unique?: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Every equality index used by `findBy()` across the codebase. Grouped by
|
|
27
|
+
* the migration stage that introduces the collection; kept in one place so
|
|
28
|
+
* a missing index is a loud error (`findBy` throws) rather than a silent
|
|
29
|
+
* empty result.
|
|
30
|
+
*/
|
|
31
|
+
const INDEXES: IndexSpec[] = [
|
|
32
|
+
// Stage 1 — identity/config core
|
|
33
|
+
{ collection: "models", field: "provider_id" },
|
|
34
|
+
{ collection: "models", field: "model_type" },
|
|
35
|
+
{ collection: "agents", field: "user_id" },
|
|
36
|
+
{ collection: "agents", field: "model_id" },
|
|
37
|
+
{ collection: "agents", field: "parent_id" },
|
|
38
|
+
{ collection: "agents", field: "role" },
|
|
39
|
+
{ collection: "agents", field: "status" },
|
|
40
|
+
{ collection: "agents", field: "source" },
|
|
41
|
+
// Stage 2 — catalog
|
|
42
|
+
{ collection: "channels", field: "user_id" },
|
|
43
|
+
{ collection: "channels", field: "type" },
|
|
44
|
+
{ collection: "skills", field: "category" },
|
|
45
|
+
{ collection: "skills", field: "active" },
|
|
46
|
+
{ collection: "tools", field: "category" },
|
|
47
|
+
{ collection: "tools", field: "active" },
|
|
48
|
+
{ collection: "ethics", field: "active" },
|
|
49
|
+
{ collection: "mcpTools", field: "server_id" },
|
|
50
|
+
{ collection: "mcpTools", field: "active" },
|
|
51
|
+
// Stage 3 — auth/identity
|
|
52
|
+
{ collection: "userChannels", field: "channel" },
|
|
53
|
+
{ collection: "refreshTokens", field: "token_hash", unique: true },
|
|
54
|
+
{ collection: "refreshTokens", field: "user_id" },
|
|
55
|
+
{ collection: "notifications", field: "user_id" },
|
|
56
|
+
{ collection: "notifications", field: "channel" },
|
|
57
|
+
// Stage 4 — chat/ACE
|
|
58
|
+
{ collection: "traces", field: "thread_id" },
|
|
59
|
+
{ collection: "traces", field: "agent_id" },
|
|
60
|
+
{ collection: "traces", field: "success" },
|
|
61
|
+
{ collection: "playbook", field: "active" },
|
|
62
|
+
{ collection: "playbook", field: "category" },
|
|
63
|
+
// Stage 5 — scheduler
|
|
64
|
+
{ collection: "cronJobs", field: "status" },
|
|
65
|
+
{ collection: "cronJobs", field: "task_type" },
|
|
66
|
+
{ collection: "cronJobs", field: "agent_id" },
|
|
67
|
+
{ collection: "agentRuns", field: "status" },
|
|
68
|
+
{ collection: "agentRuns", field: "thread_id" },
|
|
69
|
+
{ collection: "agentRuns", field: "agent_id" },
|
|
70
|
+
{ collection: "agentRuns", field: "kind" },
|
|
71
|
+
{ collection: "agentRuns", field: "catalog_agent_id" },
|
|
72
|
+
{ collection: "jobQueue", field: "status" },
|
|
73
|
+
{ collection: "jobQueue", field: "lane" },
|
|
74
|
+
{ collection: "jobQueue", field: "type" },
|
|
75
|
+
{ collection: "jobQueue", field: "run_id" },
|
|
76
|
+
{ collection: "jobQueue", field: "idempotency_key" },
|
|
77
|
+
{ collection: "proofPackets", field: "run_id" },
|
|
78
|
+
{ collection: "proofPackets", field: "agent_id" },
|
|
79
|
+
{ collection: "proofPackets", field: "catalog_agent_id" },
|
|
80
|
+
{ collection: "artifacts", field: "run_id" },
|
|
81
|
+
{ collection: "artifacts", field: "task_id" },
|
|
82
|
+
{ collection: "artifacts", field: "user_id" },
|
|
83
|
+
{ collection: "artifacts", field: "status" },
|
|
84
|
+
{ collection: "agentProposals", field: "agent_id" },
|
|
85
|
+
{ collection: "agentProposals", field: "status" },
|
|
86
|
+
{ collection: "agentProposals", field: "type" },
|
|
87
|
+
// Stage 6 — orchestration
|
|
88
|
+
{ collection: "tasks", field: "agent_id" },
|
|
89
|
+
{ collection: "tasks", field: "status" },
|
|
90
|
+
{ collection: "tasks", field: "catalog_agent_id" },
|
|
91
|
+
{ collection: "tasks", field: "delegation_group_id" },
|
|
92
|
+
{ collection: "delegationGroups", field: "turn_id", unique: true },
|
|
93
|
+
{ collection: "delegationGroups", field: "thread_id" },
|
|
94
|
+
{ collection: "delegationGroups", field: "status" },
|
|
95
|
+
{ collection: "agentBusMessages", field: "to_worker_id" },
|
|
96
|
+
{ collection: "agentBusMessages", field: "from_worker_id" },
|
|
97
|
+
{ collection: "agentBusMessages", field: "event_type" },
|
|
98
|
+
{ collection: "narrationEvents", field: "turn_id" },
|
|
99
|
+
{ collection: "narrationEvents", field: "thread_id" },
|
|
100
|
+
{ collection: "narrationEvents", field: "user_id" },
|
|
101
|
+
{ collection: "narrationEvents", field: "kind" },
|
|
102
|
+
// Stage 7 — meeting
|
|
103
|
+
{ collection: "meetingSessions", field: "user_id" },
|
|
104
|
+
{ collection: "meetingSessions", field: "status" },
|
|
105
|
+
];
|
|
106
|
+
|
|
107
|
+
async function ensureIndexes(): Promise<void> {
|
|
108
|
+
for (const spec of INDEXES) {
|
|
109
|
+
const c = await col(spec.collection);
|
|
110
|
+
await c.createIndex(spec.field, { unique: spec.unique });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Seeds the static catalogs (tools, skills, providers, models, mcp servers,
|
|
116
|
+
* channels, ethics, ACE playbook) from their canonical source every boot —
|
|
117
|
+
* same "reseed every boot so code changes always take effect" behavior the
|
|
118
|
+
* old SQLite seedAllData() had. Fully idempotent: uses putIfAbsent for
|
|
119
|
+
* user-toggleable fields (enabled/active) and doesn't touch `users`, so it's
|
|
120
|
+
* safe to call unconditionally before any onboarding has happened.
|
|
121
|
+
*/
|
|
122
|
+
async function ensureSeedData(): Promise<void> {
|
|
123
|
+
await seedAllData();
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
let bootstrapped = false;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Idempotent entry point: opens the database, ensures indexes, reseeds the
|
|
130
|
+
* static catalogs, and records the schema version. Safe to call on every
|
|
131
|
+
* gateway boot.
|
|
132
|
+
*/
|
|
133
|
+
export async function ensureHiveDb(): Promise<void> {
|
|
134
|
+
await getHiveDb();
|
|
135
|
+
await ensureIndexes();
|
|
136
|
+
// Mint the master key before anything can save an API key, so a fresh
|
|
137
|
+
// install is durable from the first keystroke rather than after a restart
|
|
138
|
+
// has already dropped the secret.
|
|
139
|
+
ensureSecretsBackend();
|
|
140
|
+
await ensureSeedData();
|
|
141
|
+
|
|
142
|
+
const meta = await col<{ value: number }>("meta");
|
|
143
|
+
const existing = await meta.get("schemaVersion");
|
|
144
|
+
if (!existing) await meta.put("schemaVersion", { value: 1 }, { expectedVersion: 0 });
|
|
145
|
+
|
|
146
|
+
bootstrapped = true;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export function isBootstrapped(): boolean {
|
|
150
|
+
return bootstrapped;
|
|
151
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live-tail wrapper over HiveDB's G9 causal event log (subscribe()/events()).
|
|
3
|
+
*
|
|
4
|
+
* Read-side, separate from agent-loop.ts's write-side appendCausalEvent()
|
|
5
|
+
* (module-private there, write-only). This is the read/watch counterpart,
|
|
6
|
+
* co-located with the DB singleton accessor.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { getHiveDb } from "./hivedb"
|
|
10
|
+
import type { Event, EventPattern } from "@johpaz/hive-db"
|
|
11
|
+
|
|
12
|
+
export type { Event as CausalEvent, EventPattern as CausalEventPattern }
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Live-tail causal events matching `pattern`. Forward-only: only events
|
|
16
|
+
* appended AFTER this call resolves are delivered. hive-db's subscribe()/
|
|
17
|
+
* events() are a pure in-process pub/sub (see hiveBD's reactive.rs — a
|
|
18
|
+
* DashMap of subscribers, dispatched right after the durable write, with no
|
|
19
|
+
* backing read of the log on subscribe) — there is no historical replay.
|
|
20
|
+
* Combine with causalThread()/read(seq) if backfill is ever needed.
|
|
21
|
+
*
|
|
22
|
+
* Note: `pattern.kind` matches exactly one kind at a time, not an OR of
|
|
23
|
+
* several — call watchCausalEvents() once per kind if you need more than one.
|
|
24
|
+
*
|
|
25
|
+
* Process constraint (confirmed by testing): getHiveDb() opens the database
|
|
26
|
+
* exclusively — there is no shared/read-only mode, so this can only be
|
|
27
|
+
* called from within the SAME process as whatever else has the DB open
|
|
28
|
+
* (e.g. embedded inside the gateway). A separate process (like the `hive
|
|
29
|
+
* causal watch` CLI) calling this while a `hive` gateway is already running
|
|
30
|
+
* against the same DB fails fast with an "already open" error.
|
|
31
|
+
*/
|
|
32
|
+
export async function watchCausalEvents(
|
|
33
|
+
pattern: EventPattern
|
|
34
|
+
): Promise<AsyncIterable<Event> & { close(): void }> {
|
|
35
|
+
const db = await getHiveDb()
|
|
36
|
+
return db.events(pattern)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** One-line human-readable summary of a causal event, keyed by its kindTag. */
|
|
40
|
+
export function formatCausalEvent(event: Event): string {
|
|
41
|
+
let payload: Record<string, unknown> = {}
|
|
42
|
+
try {
|
|
43
|
+
payload = JSON.parse(event.payload)
|
|
44
|
+
} catch {
|
|
45
|
+
// Malformed payload — still print seq/kind/agent/stream below.
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const streamShort = event.streamId.slice(0, 8)
|
|
49
|
+
const header = `[${event.seq}] ${kindIcon(event.kindTag)} ${event.kindTag.padEnd(16)} agent=${event.agentId} stream=${streamShort}…`
|
|
50
|
+
|
|
51
|
+
switch (event.kindTag) {
|
|
52
|
+
case "IntentLogged":
|
|
53
|
+
return `${header} "${truncate(String(payload.intent ?? ""), 120)}"`
|
|
54
|
+
case "StateTransition":
|
|
55
|
+
return `${header} "${truncate(String(payload.description ?? ""), 120)}"`
|
|
56
|
+
case "ToolCall": {
|
|
57
|
+
const outcome = payload.outcome
|
|
58
|
+
const outcomeStr =
|
|
59
|
+
outcome === "Ok" ? "ok"
|
|
60
|
+
: outcome === "Timeout" ? "TIMEOUT"
|
|
61
|
+
: (outcome && typeof outcome === "object" && "Err" in (outcome as object))
|
|
62
|
+
? `ERR: ${(outcome as { Err: string }).Err}`
|
|
63
|
+
: String(outcome)
|
|
64
|
+
const latency = payload.latency_ms !== undefined ? `${payload.latency_ms}ms` : "?ms"
|
|
65
|
+
return `${header} tool=${payload.tool} ${latency} ${outcomeStr}`
|
|
66
|
+
}
|
|
67
|
+
default:
|
|
68
|
+
return `${header} ${truncate(JSON.stringify(payload), 120)}`
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function kindIcon(kindTag: string): string {
|
|
73
|
+
switch (kindTag) {
|
|
74
|
+
case "IntentLogged": return "🎯"
|
|
75
|
+
case "StateTransition": return "🔀"
|
|
76
|
+
case "ToolCall": return "🔧"
|
|
77
|
+
case "LearningProposal": return "📄"
|
|
78
|
+
default: return "•"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function truncate(s: string, max: number): string {
|
|
83
|
+
return s.length > max ? s.slice(0, max) + "…" : s
|
|
84
|
+
}
|