@johpaz/hive-sdk 0.0.18 → 0.1.4

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 (41) hide show
  1. package/bun.lock +291 -1
  2. package/docs/HIVE-HARNESS.md +113 -0
  3. package/package.json +36 -2
  4. package/packages/cli/package.json +1 -1
  5. package/packages/core/package.json +13 -2
  6. package/packages/core/src/ace/Tracer.ts +1 -1
  7. package/packages/core/src/agent/AgentRunner.ts +12 -0
  8. package/packages/core/src/agent/ContextCompiler.ts +4 -4
  9. package/packages/core/src/agent/ConversationStore.ts +30 -20
  10. package/packages/core/src/agent/selectors/PlaybookSelector.ts +50 -76
  11. package/packages/core/src/agent/selectors/SkillSelector.ts +106 -262
  12. package/packages/core/src/agent/selectors/ToolSelector.ts +53 -89
  13. package/packages/core/src/auth/auth.ts +36 -23
  14. package/packages/core/src/harness/boot-id.ts +20 -0
  15. package/packages/core/src/harness/collections.ts +98 -0
  16. package/packages/core/src/harness/db-helpers.ts +87 -0
  17. package/packages/core/src/harness/durable-queue.ts +337 -0
  18. package/packages/core/src/harness/goal-verifier.ts +141 -0
  19. package/packages/core/src/harness/harness.test.ts +236 -0
  20. package/packages/core/src/harness/index.ts +34 -0
  21. package/packages/core/src/harness/job-store.ts +399 -0
  22. package/packages/core/src/harness/proof-packet.ts +69 -0
  23. package/packages/core/src/harness/reconcile.ts +149 -0
  24. package/packages/core/src/harness/run-epoch.ts +32 -0
  25. package/packages/core/src/harness/run-store.ts +334 -0
  26. package/packages/core/src/index.ts +13 -0
  27. package/packages/core/src/memory/Scratchpad.test.ts +23 -21
  28. package/packages/core/src/memory/Scratchpad.ts +41 -24
  29. package/packages/core/src/storage/HiveDBStorage.ts +64 -0
  30. package/packages/core/src/storage/SQLiteStorage.ts +7 -0
  31. package/packages/core/src/storage/hiveSeed.ts +308 -0
  32. package/packages/core/src/storage/hiveStorage.test.ts +38 -0
  33. package/packages/core/src/storage/index.ts +11 -0
  34. package/packages/core/src/storage/seed.ts +5 -1
  35. package/packages/core/src/storage/usage.ts +106 -167
  36. package/packages/core/src/tool-runtime/tool-runtime.test.ts +11 -3
  37. package/packages/core/src/tools/agents/get-available-models.ts +52 -56
  38. package/packages/core/src/tools/agents/index.ts +77 -60
  39. package/packages/core/src/tools/core/index.ts +106 -291
  40. package/packages/core/src/tools/meeting/index.ts +83 -93
  41. package/packages/core/src/utils/toon.ts +4 -4
@@ -1,37 +1,54 @@
1
- import type { Database } from "bun:sqlite";
1
+ import { getHiveDB } from "../storage/HiveDBStorage.ts";
2
+
3
+ interface ScratchpadDoc {
4
+ threadId: string;
5
+ key: string;
6
+ value: string;
7
+ updatedAt: number;
8
+ }
2
9
 
3
10
  export class Scratchpad {
4
- constructor(private db: Database) {}
11
+ async write(threadId: string, key: string, value: string): Promise<void> {
12
+ const db = await getHiveDB();
13
+ const col = db.collection<ScratchpadDoc>("scratchpad");
14
+ await col.put(this.docId(threadId, key), { threadId, key, value, updatedAt: Date.now() });
15
+ }
5
16
 
6
- write(threadId: string, key: string, value: string): void {
7
- this.db.run(
8
- `INSERT OR REPLACE INTO scratchpad (thread_id, key, value, updated_at) VALUES (?, ?, ?, datetime('now'))`,
9
- [threadId, key, value]
10
- );
17
+ async read(threadId: string, key: string): Promise<string | undefined> {
18
+ const db = await getHiveDB();
19
+ const col = db.collection<ScratchpadDoc>("scratchpad");
20
+ const entry = await col.get(this.docId(threadId, key));
21
+ return entry?.doc.value;
11
22
  }
12
23
 
13
- read(threadId: string, key: string): string | null {
14
- const row = this.db
15
- .query(`SELECT value FROM scratchpad WHERE thread_id = ? AND key = ?`)
16
- .get(threadId, key) as any;
17
- return row?.value ?? null;
24
+ async list(threadId: string): Promise<Record<string, string>> {
25
+ const db = await getHiveDB();
26
+ const col = db.collection<ScratchpadDoc>("scratchpad");
27
+ const entries = await col.scan();
28
+ const result: Record<string, string> = {};
29
+ for (const e of entries) {
30
+ if (e.doc.threadId === threadId) {
31
+ result[e.doc.key] = e.doc.value;
32
+ }
33
+ }
34
+ return result;
18
35
  }
19
36
 
20
- list(threadId: string): Record<string, string> {
21
- const rows = this.db
22
- .query(`SELECT key, value FROM scratchpad WHERE thread_id = ?`)
23
- .all(threadId) as any[];
24
- return Object.fromEntries(rows.map(r => [r.key, r.value]));
37
+ async delete(threadId: string, key: string): Promise<void> {
38
+ const db = await getHiveDB();
39
+ const col = db.collection<ScratchpadDoc>("scratchpad");
40
+ await col.delete(this.docId(threadId, key));
25
41
  }
26
42
 
27
- delete(threadId: string, key: string): void {
28
- this.db.run(
29
- `DELETE FROM scratchpad WHERE thread_id = ? AND key = ?`,
30
- [threadId, key]
31
- );
43
+ async clear(threadId: string): Promise<void> {
44
+ const db = await getHiveDB();
45
+ const col = db.collection<ScratchpadDoc>("scratchpad");
46
+ const entries = await col.scan();
47
+ const ids = entries.filter(e => e.doc.threadId === threadId).map(e => e.id);
48
+ await db.batch(ids.map(id => ({ op: "delete" as const, collection: "scratchpad", id })));
32
49
  }
33
50
 
34
- clear(threadId: string): void {
35
- this.db.run(`DELETE FROM scratchpad WHERE thread_id = ?`, [threadId]);
51
+ private docId(threadId: string, key: string): string {
52
+ return `${threadId}:${key}`;
36
53
  }
37
54
  }
@@ -0,0 +1,64 @@
1
+ import { HiveDB, type Collection, type EventInput, type Event } from "@johpaz/hive-db";
2
+ import * as path from "node:path";
3
+ import { existsSync, mkdirSync } from "node:fs";
4
+ import { getHiveDir } from "../config/loader.ts";
5
+ import { logger } from "../utils/logger.ts";
6
+
7
+ const log = logger.child("hivedb-storage");
8
+
9
+ let _db: HiveDB | null = null;
10
+ let _opening: Promise<HiveDB> | null = null;
11
+
12
+ export function getHiveDbPath(): string {
13
+ return path.join(getHiveDir(), "data", "hive");
14
+ }
15
+
16
+ export function openHiveDB(): Promise<HiveDB> {
17
+ if (_db) return Promise.resolve(_db);
18
+ if (_opening) return _opening;
19
+
20
+ const hiveDir = getHiveDir();
21
+ const dir = path.join(hiveDir, "data");
22
+ if (!existsSync(dir)) {
23
+ mkdirSync(dir, { recursive: true });
24
+ }
25
+
26
+ const dbPath = getHiveDbPath();
27
+ log.info(`[hivedb] Opening HiveDB at ${dbPath}`);
28
+ _opening = HiveDB.open(dbPath, { vector: { dimension: 384, spaceId: "hive-sdk-v1" } }).then((db) => {
29
+ _db = db;
30
+ _opening = null;
31
+ return db;
32
+ });
33
+ return _opening;
34
+ }
35
+
36
+ export async function getHiveDB(): Promise<HiveDB> {
37
+ if (_db) return _db;
38
+ if (_opening) return _opening;
39
+ return openHiveDB();
40
+ }
41
+
42
+ export async function closeHiveDB(): Promise<void> {
43
+ if (_db) {
44
+ _db.close();
45
+ _db = null;
46
+ }
47
+ _opening = null;
48
+ }
49
+
50
+ export async function hiveCollection<T = unknown>(name: string): Promise<Collection<T>> {
51
+ return (await getHiveDB()).collection<T>(name);
52
+ }
53
+
54
+ export async function hiveAppend(input: EventInput): Promise<number> {
55
+ return (await getHiveDB()).append(input);
56
+ }
57
+
58
+ export async function hiveRead(seq: number): Promise<Event> {
59
+ return (await getHiveDB()).read(seq);
60
+ }
61
+
62
+ export function isHiveDBInitialized(): boolean {
63
+ return _db !== null;
64
+ }
@@ -4,6 +4,7 @@ import * as path from "node:path";
4
4
  import { existsSync, mkdirSync } from "node:fs";
5
5
  import { getHiveDir } from "../config/loader.ts";
6
6
  import { SCHEMA, PROJECTS_SCHEMA, CONTEXT_ENGINE_SCHEMA, MEETING_SCHEMA } from "./schema.ts";
7
+ import { openHiveDB, closeHiveDB } from "./HiveDBStorage.ts";
7
8
 
8
9
  function getDbPath(): string {
9
10
  return path.join(getHiveDir(), "data", "hive.db");
@@ -84,6 +85,12 @@ export function initializeDatabase(): Database {
84
85
 
85
86
  ensureSchemaSync();
86
87
 
88
+ // Open HiveDB as the new source-of-truth engine alongside SQLite
89
+ // during the migration; SQLite will be removed once all tables are migrated.
90
+ openHiveDB().catch((err) => {
91
+ logger.error("❌ Failed to initialize HiveDB:", err);
92
+ });
93
+
87
94
  return _db;
88
95
  }
89
96
 
@@ -0,0 +1,308 @@
1
+ import { getHiveDB, hiveCollection } from "./HiveDBStorage.ts";
2
+ import { logger } from "../utils/logger.ts";
3
+ import { SEED_DATA, INITIAL_PLAYBOOK_RULES } from "./seed.ts";
4
+ import { SkillLoader } from "../skills/index.ts";
5
+ import { enrichToolDescription } from "../agent/selectors/ToolSelector.ts";
6
+ import type { ToolDescriptor } from "../agent/selectors/ToolSelector.ts";
7
+ import type { IndexDoc, HiveDB } from "@johpaz/hive-db";
8
+
9
+ const log = logger.child("hive-seed");
10
+
11
+ export interface HiveToolDoc {
12
+ name: string;
13
+ description: string;
14
+ category: string;
15
+ enabled: boolean;
16
+ active: boolean;
17
+ }
18
+
19
+ export interface HiveProviderDoc {
20
+ id: string;
21
+ name: string;
22
+ baseUrl?: string;
23
+ category: string;
24
+ enabled: boolean;
25
+ active: boolean;
26
+ }
27
+
28
+ export interface HiveModelDoc {
29
+ id: string;
30
+ providerId: string;
31
+ name: string;
32
+ modelType: string;
33
+ contextWindow?: number;
34
+ capabilities?: string[];
35
+ enabled: boolean;
36
+ active: boolean;
37
+ }
38
+
39
+ export interface HiveSkillDoc {
40
+ id: string;
41
+ name: string;
42
+ description: string;
43
+ version: string;
44
+ author: string;
45
+ icon: string;
46
+ category: string;
47
+ permissions: string[];
48
+ dependencies: string[];
49
+ tools: string[];
50
+ triggers: string[];
51
+ preferredAgents: string[];
52
+ body: string;
53
+ versionNum: number;
54
+ active: boolean;
55
+ }
56
+
57
+ export interface HiveAgentDoc {
58
+ id: string;
59
+ userId?: string;
60
+ name: string;
61
+ description: string;
62
+ systemPrompt: string;
63
+ toolsJson?: string;
64
+ role: string;
65
+ status: string;
66
+ parentId?: string;
67
+ providerId: string;
68
+ modelId: string;
69
+ tone?: string;
70
+ maxIterations: number;
71
+ workspace?: string;
72
+ enabled: boolean;
73
+ active: boolean;
74
+ createdAt: number;
75
+ updatedAt: number;
76
+ }
77
+
78
+ export interface HiveChannelDoc {
79
+ id: string;
80
+ type: string;
81
+ enabled: boolean;
82
+ active: boolean;
83
+ status: string;
84
+ }
85
+
86
+ export interface HiveEthicsDoc {
87
+ id: string;
88
+ name: string;
89
+ description: string;
90
+ content: string;
91
+ isDefault: boolean;
92
+ enabled: boolean;
93
+ active: boolean;
94
+ }
95
+
96
+ export interface HiveCodeBridgeDoc {
97
+ id: string;
98
+ name: string;
99
+ cliCommand: string;
100
+ port: number;
101
+ enabled: boolean;
102
+ active: boolean;
103
+ }
104
+
105
+ export interface HiveCodeBridgeConfigDoc {
106
+ id: string;
107
+ key: string;
108
+ value: string;
109
+ }
110
+
111
+ export interface HivePlaybookDoc {
112
+ rule: string;
113
+ category: string;
114
+ applicableTo?: string[];
115
+ helpfulCount: number;
116
+ harmfulCount: number;
117
+ active: boolean;
118
+ }
119
+
120
+ export async function seedHiveDB(db?: HiveDB): Promise<void> {
121
+ db ??= await getHiveDB();
122
+
123
+ log.info("[hive-seed] 🌱 Iniciando seed de HiveDB");
124
+
125
+ // 1️⃣ Tools
126
+ const toolsCol = db.collection<HiveToolDoc>("tools");
127
+ await toolsCol.createIndex("name", { unique: true });
128
+ for (const tool of SEED_DATA.tools) {
129
+ await toolsCol.put(tool.id, {
130
+ name: tool.name,
131
+ description: tool.description,
132
+ category: tool.category,
133
+ enabled: tool.enabled ?? true,
134
+ active: true,
135
+ });
136
+ }
137
+ log.info(`[hive-seed] ✅ ${SEED_DATA.tools.length} tools seeded`);
138
+
139
+ // 2️⃣ Index tools for hybrid search
140
+ const toolDocs: IndexDoc[] = SEED_DATA.tools.map(tool => ({
141
+ id: tool.name,
142
+ name: tool.name,
143
+ body: enrichToolDescription({ name: tool.name, description: tool.description, category: tool.category } as ToolDescriptor),
144
+ tags: tool.category,
145
+ filters: [{ field: "type", value: "tool" }],
146
+ }));
147
+ await db.upsertBatch(toolDocs);
148
+ log.info(`[hive-seed] ✅ ${toolDocs.length} tools indexed`);
149
+
150
+ // 3️⃣ Providers
151
+ const providersCol = db.collection<HiveProviderDoc>("providers");
152
+ await providersCol.createIndex("id", { unique: true });
153
+ for (const provider of SEED_DATA.providers) {
154
+ await providersCol.put(provider.id, {
155
+ id: provider.id,
156
+ name: provider.name,
157
+ baseUrl: provider.baseUrl,
158
+ category: provider.category ?? "llm",
159
+ enabled: true,
160
+ active: false,
161
+ });
162
+ }
163
+ const ollamaHost = process.env.OLLAMA_HOST;
164
+ if (ollamaHost) {
165
+ const entry = await providersCol.get("ollama");
166
+ if (entry) {
167
+ await providersCol.put("ollama", { ...entry.doc, baseUrl: ollamaHost });
168
+ }
169
+ }
170
+ log.info(`[hive-seed] ✅ ${SEED_DATA.providers.length} providers seeded`);
171
+
172
+ // 4️⃣ Models
173
+ const modelsCol = db.collection<HiveModelDoc>("models");
174
+ await modelsCol.createIndex("id", { unique: true });
175
+ await modelsCol.createIndex("providerId");
176
+ for (const model of SEED_DATA.models) {
177
+ await modelsCol.put(model.id, {
178
+ id: model.id,
179
+ providerId: model.providerId,
180
+ name: model.name,
181
+ modelType: model.modelType,
182
+ contextWindow: model.contextWindow,
183
+ capabilities: model.capabilities ? JSON.parse(model.capabilities) : undefined,
184
+ enabled: true,
185
+ active: false,
186
+ });
187
+ }
188
+ log.info(`[hive-seed] ✅ ${SEED_DATA.models.length} models seeded`);
189
+
190
+ // 5️⃣ MCP servers
191
+ const mcpCol = db.collection("mcp_servers");
192
+ await mcpCol.createIndex("id", { unique: true });
193
+ for (const mcp of SEED_DATA.mcpServers) {
194
+ await mcpCol.put(mcp.id, { ...mcp, enabled: true, active: false, builtin: mcp.builtin, toolsCount: 0 });
195
+ }
196
+ log.info(`[hive-seed] ✅ ${SEED_DATA.mcpServers.length} MCP servers seeded`);
197
+
198
+ // 6️⃣ Channels
199
+ const channelsCol = db.collection<HiveChannelDoc>("channels");
200
+ await channelsCol.createIndex("id", { unique: true });
201
+ for (const channel of SEED_DATA.channels) {
202
+ const isWebChat = channel.id === "webchat";
203
+ await channelsCol.put(channel.id, {
204
+ id: channel.id,
205
+ type: channel.type,
206
+ enabled: true,
207
+ active: isWebChat,
208
+ status: isWebChat ? "connected" : "disconnected",
209
+ });
210
+ }
211
+ log.info(`[hive-seed] ✅ ${SEED_DATA.channels.length} channels seeded`);
212
+
213
+ // 7️⃣ Ethics
214
+ const ethicsCol = db.collection<HiveEthicsDoc>("ethics");
215
+ await ethicsCol.createIndex("id", { unique: true });
216
+ for (const ethics of SEED_DATA.ethics) {
217
+ await ethicsCol.put(ethics.id, {
218
+ id: ethics.id,
219
+ name: ethics.name,
220
+ description: ethics.description,
221
+ content: ethics.content,
222
+ isDefault: ethics.isDefault,
223
+ enabled: true,
224
+ active: ethics.isDefault,
225
+ });
226
+ }
227
+ log.info(`[hive-seed] ✅ ${SEED_DATA.ethics.length} ethics templates seeded`);
228
+
229
+ // 8️⃣ Code Bridge
230
+ const cbCol = db.collection<HiveCodeBridgeDoc>("code_bridge");
231
+ await cbCol.createIndex("id", { unique: true });
232
+ for (const cb of SEED_DATA.codeBridge) {
233
+ await cbCol.put(cb.id, { ...cb, enabled: false, active: false });
234
+ }
235
+ log.info(`[hive-seed] ✅ ${SEED_DATA.codeBridge.length} Code Bridge entries seeded`);
236
+
237
+ // 9️⃣ Code Bridge Config
238
+ const cbConfigCol = db.collection<HiveCodeBridgeConfigDoc>("code_bridge_config");
239
+ await cbConfigCol.createIndex("id", { unique: true });
240
+ for (const config of SEED_DATA.codeBridgeConfig) {
241
+ await cbConfigCol.put(config.id, config);
242
+ }
243
+ log.info(`[hive-seed] ✅ ${SEED_DATA.codeBridgeConfig.length} Code Bridge Config entries seeded`);
244
+
245
+ // 🔟 Skills
246
+ const skillLoader = new SkillLoader({ workspacePath: process.env.HIVE_HOME || process.cwd() });
247
+ const realSkills = skillLoader.loadBundledSkills();
248
+ const skillsCol = db.collection("skills");
249
+ await skillsCol.createIndex("id", { unique: true });
250
+ const skillDocs: IndexDoc[] = [];
251
+ for (const s of realSkills) {
252
+ const doc = {
253
+ id: s.name,
254
+ name: s.name,
255
+ description: s.description || "",
256
+ version: typeof s.version === "string" ? s.version : String(s.version || "0.0.1"),
257
+ author: s.author || "Anonymous",
258
+ icon: s.icon || "🧩",
259
+ category: s.category || "general",
260
+ permissions: s.permissions || [],
261
+ dependencies: s.dependencies || [],
262
+ tools: s.tools || [],
263
+ triggers: s.triggers || [],
264
+ preferredAgents: s.preferred_agents || [],
265
+ body: s.content || "",
266
+ versionNum: parseInt(String(s.version || "0.0.1").split(".")[0]) || 1,
267
+ active: true,
268
+ };
269
+ await skillsCol.put(s.name, doc);
270
+ skillDocs.push({
271
+ id: s.name,
272
+ name: s.name,
273
+ body: `${s.description || ""} ${s.content || ""}`,
274
+ tags: [s.category || "general", ...(s.tools || []), ...(s.triggers || [])].join(" "),
275
+ filters: [{ field: "type", value: "skill" }],
276
+ });
277
+ }
278
+ await db.upsertBatch(skillDocs);
279
+ log.info(`[hive-seed] ✅ ${realSkills.length} skills seeded and indexed`);
280
+
281
+ // 11. ACE Playbook
282
+ const playbookCol = db.collection<HivePlaybookDoc>("playbook");
283
+ await playbookCol.createIndex("id", { unique: true });
284
+ const playbookDocs: IndexDoc[] = [];
285
+ for (const rule of INITIAL_PLAYBOOK_RULES) {
286
+ const doc = {
287
+ rule: rule.rule,
288
+ category: rule.category,
289
+ applicableTo: rule.applicable_to ? JSON.parse(rule.applicable_to) : undefined,
290
+ helpfulCount: 1,
291
+ harmfulCount: 0,
292
+ active: true,
293
+ };
294
+ const id = `${rule.category}-${rule.rule.slice(0, 32).replace(/\s+/g, "-")}`;
295
+ await playbookCol.put(id, doc);
296
+ playbookDocs.push({
297
+ id,
298
+ name: rule.category,
299
+ body: rule.rule,
300
+ tags: rule.applicable_to || "",
301
+ filters: [{ field: "type", value: "playbook" }],
302
+ });
303
+ }
304
+ await db.upsertBatch(playbookDocs);
305
+ log.info(`[hive-seed] ✅ ${INITIAL_PLAYBOOK_RULES.length} playbook rules seeded and indexed`);
306
+
307
+ log.info("[hive-seed] ✨ HiveDB seed completado");
308
+ }
@@ -0,0 +1,38 @@
1
+ import { describe, it, expect, beforeAll, afterAll } from "bun:test";
2
+ import { HiveDB } from "@johpaz/hive-db";
3
+ import { seedHiveDB } from "./hiveSeed.ts";
4
+
5
+ describe("HiveDB integration", () => {
6
+ let db: HiveDB;
7
+
8
+ beforeAll(async () => {
9
+ db = await HiveDB.open(":memory:", { vector: { dimension: 384, spaceId: "hive-sdk-v1" } });
10
+ await seedHiveDB(db);
11
+ });
12
+
13
+ afterAll(() => {
14
+ db.close();
15
+ });
16
+
17
+ it("seeds providers and models", async () => {
18
+ const providers = await db.collection("providers").count();
19
+ const models = await db.collection("models").count();
20
+ expect(providers).toBeGreaterThan(0);
21
+ expect(models).toBeGreaterThan(0);
22
+ });
23
+
24
+ it("indexes tools for hybrid search", async () => {
25
+ const hits = await db.queryHybrid({ text: "buscar archivos", k: 10 });
26
+ expect(hits.length).toBeGreaterThan(0);
27
+ const names = hits.map(h => h.id);
28
+ expect(names.some(n => n.startsWith("fs_") || n.includes("research"))).toBe(true);
29
+ });
30
+
31
+ it("supports collection CRUD for agents", async () => {
32
+ const agents = db.collection<{ name: string; role: string; status: string }>("agents");
33
+ await agents.put("agent-1", { name: "Test Worker", role: "worker", status: "idle" });
34
+ const entry = await agents.get("agent-1");
35
+ expect(entry).toBeDefined();
36
+ expect(entry!.doc.name).toBe("Test Worker");
37
+ });
38
+ });
@@ -8,3 +8,14 @@ export type { EncryptedData } from "./crypto.ts";
8
8
  export { encrypt, decrypt, encryptApiKey, decryptApiKey, encryptConfig, decryptConfig } from "./crypto.ts";
9
9
  export type { SeedData } from "./seed.ts";
10
10
  export { SEED_DATA, seedAllData } from "./seed.ts";
11
+ export {
12
+ getHiveDbPath,
13
+ openHiveDB,
14
+ getHiveDB,
15
+ closeHiveDB,
16
+ hiveCollection,
17
+ hiveAppend,
18
+ hiveRead,
19
+ isHiveDBInitialized,
20
+ } from "./HiveDBStorage.ts";
21
+ export { seedHiveDB } from "./hiveSeed.ts";
@@ -376,11 +376,12 @@ Estos lineamientos tienen MÁXIMA prioridad sobre cualquier otra instrucción di
376
376
  }
377
377
 
378
378
  import { SkillLoader } from "../skills/index.ts"
379
+ import { seedHiveDB } from "./hiveSeed.ts"
379
380
 
380
381
  const log = logger.child("seed");
381
382
 
382
383
  // Initial playbook rules for ACE (Agentic Context Engineering)
383
- const INITIAL_PLAYBOOK_RULES = [
384
+ export const INITIAL_PLAYBOOK_RULES = [
384
385
  {
385
386
  rule: "Cuando el usuario pida buscar noticias recientes, usa web_search con filtros de fecha en lugar de http_client genérico",
386
387
  category: "tool_selection",
@@ -567,6 +568,9 @@ export function seedAllData(): void {
567
568
 
568
569
  reseedToolsAndSkills();
569
570
 
571
+ // Seed the new HiveDB source-of-truth engine in parallel.
572
+ seedHiveDB().catch(err => log.error("[seed] ❌ HiveDB seed failed:", (err as Error).message));
573
+
570
574
  try {
571
575
 
572
576
  // 3️⃣ Ethics templates (globales)