@johpaz/hive-sdk 0.0.17 → 0.1.3

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 (63) hide show
  1. package/README.md +83 -203
  2. package/bun.lock +833 -0
  3. package/bunfig.toml +7 -0
  4. package/docs/API-TOOLS-SKILLS-CHANNELS.md +60 -0
  5. package/docs/HIVE-HARNESS.md +113 -0
  6. package/package.json +36 -2
  7. package/packages/cli/package.json +1 -1
  8. package/packages/core/package.json +13 -2
  9. package/packages/core/src/ace/Tracer.ts +1 -1
  10. package/packages/core/src/agent/AgentRunner.ts +12 -0
  11. package/packages/core/src/agent/ContextCompiler.ts +4 -4
  12. package/packages/core/src/agent/ConversationStore.ts +30 -20
  13. package/packages/core/src/agent/selectors/PlaybookSelector.ts +50 -76
  14. package/packages/core/src/agent/selectors/SkillSelector.ts +106 -262
  15. package/packages/core/src/agent/selectors/ToolSelector.ts +54 -89
  16. package/packages/core/src/api/createAgent.ts +10 -0
  17. package/packages/core/src/auth/auth.ts +36 -23
  18. package/packages/core/src/config/loader.ts +2 -2
  19. package/packages/core/src/harness/boot-id.ts +20 -0
  20. package/packages/core/src/harness/collections.ts +98 -0
  21. package/packages/core/src/harness/db-helpers.ts +87 -0
  22. package/packages/core/src/harness/durable-queue.ts +337 -0
  23. package/packages/core/src/harness/goal-verifier.ts +141 -0
  24. package/packages/core/src/harness/harness.test.ts +236 -0
  25. package/packages/core/src/harness/index.ts +34 -0
  26. package/packages/core/src/harness/job-store.ts +399 -0
  27. package/packages/core/src/harness/proof-packet.ts +69 -0
  28. package/packages/core/src/harness/reconcile.ts +149 -0
  29. package/packages/core/src/harness/run-epoch.ts +32 -0
  30. package/packages/core/src/harness/run-store.ts +334 -0
  31. package/packages/core/src/index.ts +19 -0
  32. package/packages/core/src/memory/Scratchpad.test.ts +23 -21
  33. package/packages/core/src/memory/Scratchpad.ts +41 -24
  34. package/packages/core/src/skills/bundled-data.generated.ts +50 -0
  35. package/packages/core/src/skills/skills.test.ts +21 -0
  36. package/packages/core/src/storage/HiveDBStorage.ts +64 -0
  37. package/packages/core/src/storage/SQLiteStorage.ts +7 -0
  38. package/packages/core/src/storage/hiveSeed.ts +308 -0
  39. package/packages/core/src/storage/hiveStorage.test.ts +38 -0
  40. package/packages/core/src/storage/index.ts +10 -0
  41. package/packages/core/src/storage/seed.ts +5 -1
  42. package/packages/core/src/storage/usage.ts +106 -167
  43. package/packages/core/src/tool-runtime/tool-runtime.test.ts +11 -3
  44. package/packages/core/src/tools/agents/get-available-models.ts +52 -56
  45. package/packages/core/src/tools/agents/index.ts +77 -60
  46. package/packages/core/src/tools/core/index.ts +106 -291
  47. package/packages/core/src/tools/index.ts +1 -0
  48. package/packages/core/src/tools/meeting/index.ts +83 -93
  49. package/packages/core/src/tools/web/api-request.test.ts +170 -0
  50. package/packages/core/src/tools/web/api-request.ts +239 -0
  51. package/packages/core/src/tools/web/browser-click.ts +2 -2
  52. package/packages/core/src/tools/web/browser-extract.ts +22 -6
  53. package/packages/core/src/tools/web/browser-navigate.ts +34 -18
  54. package/packages/core/src/tools/web/browser-screenshot.ts +40 -8
  55. package/packages/core/src/tools/web/browser-script.ts +2 -2
  56. package/packages/core/src/tools/web/browser-service.test.ts +83 -0
  57. package/packages/core/src/tools/web/browser-service.ts +290 -341
  58. package/packages/core/src/tools/web/browser-type.ts +2 -2
  59. package/packages/core/src/tools/web/browser-wait.ts +2 -2
  60. package/packages/core/src/tools/web/index.ts +3 -0
  61. package/packages/core/src/utils/toon.ts +4 -4
  62. package/CHANGELOG.md +0 -72
  63. package/docs/README.md +0 -161
@@ -6,6 +6,8 @@
6
6
 
7
7
  import type { Tool } from "../types.ts";
8
8
  import { getDb } from "../../storage/SQLiteStorage.ts";
9
+ import { getHiveDB } from "../../storage/HiveDBStorage.ts";
10
+ import type { HiveModelDoc, HiveProviderDoc, HiveAgentDoc } from "../../storage/hiveSeed.ts";
9
11
  import { logger } from "../../utils/logger.ts";
10
12
  import { agentBus } from "../../swarm/AgentBus.ts";
11
13
  import { emitCanvas } from "../../canvas/emitter.ts";
@@ -26,15 +28,15 @@ export const memoryWriteTool: Tool = {
26
28
  required: ["title", "content"],
27
29
  },
28
30
  execute: async (params: Record<string, unknown>) => {
29
- const db = getDb();
31
+ const db = await getHiveDB();
30
32
  const title = params.title as string;
31
33
  const content = params.content as string;
32
34
 
33
35
  try {
34
- db.query(`
35
- INSERT OR REPLACE INTO notes (id, title, content, createdAt, updatedAt)
36
- VALUES (lower(hex(randomblob(16))), ?, ?, unixepoch(), unixepoch())
37
- `).run(title, content);
36
+ const notesCol = db.collection<{ title: string; content: string; createdAt: number; updatedAt: number }>("notes");
37
+ const id = crypto.randomUUID();
38
+ const now = Date.now();
39
+ await notesCol.put(id, { title, content, createdAt: now, updatedAt: now });
38
40
 
39
41
  return { ok: true, title, message: "Memory saved." };
40
42
  } catch (error) {
@@ -56,11 +58,13 @@ export const memoryReadTool: Tool = {
56
58
  required: ["title"],
57
59
  },
58
60
  execute: async (params: Record<string, unknown>) => {
59
- const db = getDb();
61
+ const db = await getHiveDB();
60
62
  const title = params.title as string;
61
63
 
62
64
  try {
63
- const note = db.query<any, [string]>("SELECT * FROM notes WHERE title = ?").get(title);
65
+ const notesCol = db.collection<{ title: string; content: string; createdAt: number; updatedAt: number }>("notes");
66
+ const entries = await notesCol.scan();
67
+ const note = entries.find(e => e.doc.title === title)?.doc;
64
68
 
65
69
  if (!note) {
66
70
  return { ok: false, error: `Memory not found: ${title}` };
@@ -70,8 +74,8 @@ export const memoryReadTool: Tool = {
70
74
  ok: true,
71
75
  title: note.title,
72
76
  content: note.content,
73
- createdAt: new Date(note.createdAt * 1000).toISOString(),
74
- updatedAt: new Date(note.updatedAt * 1000).toISOString(),
77
+ createdAt: new Date(note.createdAt).toISOString(),
78
+ updatedAt: new Date(note.updatedAt).toISOString(),
75
79
  };
76
80
  } catch (error) {
77
81
  return { ok: false, error: `Failed to read memory: ${(error as Error).message}` };
@@ -89,15 +93,19 @@ export const memoryListTool: Tool = {
89
93
  properties: {},
90
94
  },
91
95
  execute: async () => {
92
- const db = getDb();
96
+ const db = await getHiveDB();
93
97
 
94
98
  try {
95
- const notes = db.query("SELECT id, title, createdAt FROM notes ORDER BY updatedAt DESC").all() as any[];
99
+ const notesCol = db.collection<{ title: string; content: string; createdAt: number; updatedAt: number }>("notes");
100
+ const entries = await notesCol.scan();
101
+ const notes = entries
102
+ .map(e => e.doc)
103
+ .sort((a, b) => b.updatedAt - a.updatedAt);
96
104
 
97
105
  return {
98
106
  ok: true,
99
107
  count: notes.length,
100
- entries: notes.map((n) => ({ title: n.title, createdAt: new Date(n.createdAt * 1000).toISOString() })),
108
+ entries: notes.map((n) => ({ title: n.title, createdAt: new Date(n.createdAt).toISOString() })),
101
109
  };
102
110
  } catch (error) {
103
111
  return { ok: false, error: `Failed to list memories: ${(error as Error).message}` };
@@ -118,14 +126,15 @@ export const memorySearchTool: Tool = {
118
126
  required: ["query"],
119
127
  },
120
128
  execute: async (params: Record<string, unknown>) => {
121
- const db = getDb();
122
- const query = params.query as string;
129
+ const db = await getHiveDB();
130
+ const query = (params.query as string).toLowerCase();
123
131
 
124
132
  try {
125
- const stmt = db.query<any, [string, string]>(
126
- "SELECT id, title, content FROM notes WHERE content LIKE ? OR title LIKE ?"
127
- );
128
- const notes = stmt.all(`%${query}%`, `%${query}%`) as any[];
133
+ const notesCol = db.collection<{ title: string; content: string; createdAt: number; updatedAt: number }>("notes");
134
+ const entries = await notesCol.scan();
135
+ const notes = entries
136
+ .map(e => e.doc)
137
+ .filter(n => n.title.toLowerCase().includes(query) || n.content.toLowerCase().includes(query));
129
138
 
130
139
  return {
131
140
  ok: true,
@@ -155,16 +164,19 @@ export const memoryDeleteTool: Tool = {
155
164
  required: ["title"],
156
165
  },
157
166
  execute: async (params: Record<string, unknown>) => {
158
- const db = getDb();
167
+ const db = await getHiveDB();
159
168
  const title = params.title as string;
160
169
 
161
170
  try {
162
- const result = db.query("DELETE FROM notes WHERE title = ?").run(title);
171
+ const notesCol = db.collection<{ title: string; content: string; createdAt: number; updatedAt: number }>("notes");
172
+ const entries = await notesCol.scan();
173
+ const target = entries.find(e => e.doc.title === title);
163
174
 
164
- if (result.changes === 0) {
175
+ if (!target) {
165
176
  return { ok: false, error: `Memory not found: ${title}` };
166
177
  }
167
178
 
179
+ await notesCol.delete(target.id);
168
180
  return { ok: true, title, message: "Memory deleted." };
169
181
  } catch (error) {
170
182
  return { ok: false, error: `Failed to delete memory: ${(error as Error).message}` };
@@ -192,20 +204,19 @@ export const agentCreateTool: Tool = {
192
204
  required: ["name", "providerId", "modelId"],
193
205
  },
194
206
  execute: async (params: Record<string, unknown>, config?: any) => {
195
- const db = getDb();
207
+ const db = await getHiveDB();
196
208
  const userId = config?.configurable?.user_id;
197
- const parentId = config?.configurable?.agent_id ?? null;
209
+ const parentId = config?.configurable?.agent_id ?? undefined;
198
210
  const name = params.name as string;
199
211
  const description = (params.description as string) ?? "";
200
212
  const systemPrompt = (params.system_prompt as string) ?? "";
201
- const toolsJson = params.tools_json ? JSON.stringify(params.tools_json) : null;
213
+ const toolsJson = params.tools_json ? JSON.stringify(params.tools_json) : undefined;
202
214
  const providerId = params.providerId as string;
203
215
  const modelId = params.modelId as string;
204
216
  const tone = (params.tone as string) ?? "friendly";
205
217
  const maxIterations = (params.max_iterations as number) ?? 10;
206
- const parentWorkspace = config?.configurable?.workspace ?? null;
218
+ const parentWorkspace = config?.configurable?.workspace ?? undefined;
207
219
 
208
- // Validar que providerId y modelId sean obligatorios
209
220
  if (!providerId || !modelId) {
210
221
  return {
211
222
  ok: false,
@@ -213,38 +224,34 @@ export const agentCreateTool: Tool = {
213
224
  };
214
225
  }
215
226
 
216
- // Validar que el provider existe y está activo
217
- const provider = db.query<any, [string]>(
218
- "SELECT id, name, enabled, active FROM providers WHERE id = ?"
219
- ).get(providerId);
227
+ const providersCol = db.collection<HiveProviderDoc>("providers");
228
+ const modelsCol = db.collection<HiveModelDoc>("models");
220
229
 
221
- if (!provider) {
230
+ const [providerEntry, modelEntry] = await Promise.all([
231
+ providersCol.get(providerId),
232
+ modelsCol.get(modelId),
233
+ ]);
234
+
235
+ if (!providerEntry) {
222
236
  return {
223
237
  ok: false,
224
238
  error: `Provider '${providerId}' no existe. Usá get_available_models para ver providers disponibles.`
225
239
  };
226
240
  }
227
-
228
- if (!provider.enabled || !provider.active) {
241
+ if (!providerEntry.doc.enabled || !providerEntry.doc.active) {
229
242
  return {
230
243
  ok: false,
231
244
  error: `Provider '${providerId}' no está activo. Usá get_available_models para ver providers activos.`
232
245
  };
233
246
  }
234
247
 
235
- // Validar que el modelo existe y está activo
236
- const model = db.query<any, [string]>(
237
- "SELECT id, name, enabled, active FROM models WHERE id = ?"
238
- ).get(modelId);
239
-
240
- if (!model) {
248
+ if (!modelEntry) {
241
249
  return {
242
250
  ok: false,
243
251
  error: `Modelo '${modelId}' no existe. Usá get_available_models para ver modelos disponibles.`
244
252
  };
245
253
  }
246
-
247
- if (!model.enabled || !model.active) {
254
+ if (!modelEntry.doc.enabled || !modelEntry.doc.active) {
248
255
  return {
249
256
  ok: false,
250
257
  error: `Modelo '${modelId}' no está activo. Usá get_available_models para ver modelos activos.`
@@ -253,24 +260,29 @@ export const agentCreateTool: Tool = {
253
260
 
254
261
  try {
255
262
  const agentId = crypto.randomUUID().replace(/-/g, "").slice(0, 16);
263
+ const agentsCol = db.collection<HiveAgentDoc>("agents");
264
+ const now = Date.now();
256
265
 
257
- db.query(`
258
- INSERT INTO agents (id, user_id, name, description, system_prompt, tools_json, role, status, parent_id, provider_id, model_id, tone, max_iterations, workspace)
259
- VALUES (?, ?, ?, ?, ?, ?, 'worker', 'idle', ?, ?, ?, ?, ?, ?)
260
- `).run(
261
- agentId,
266
+ await agentsCol.put(agentId, {
267
+ id: agentId,
262
268
  userId,
263
269
  name,
264
270
  description,
265
271
  systemPrompt,
266
272
  toolsJson,
273
+ role: "worker",
274
+ status: "idle",
267
275
  parentId,
268
276
  providerId,
269
277
  modelId,
270
278
  tone,
271
279
  maxIterations,
272
- parentWorkspace
273
- );
280
+ workspace: parentWorkspace,
281
+ enabled: true,
282
+ active: true,
283
+ createdAt: now,
284
+ updatedAt: now,
285
+ });
274
286
 
275
287
  return {
276
288
  ok: true,
@@ -300,27 +312,30 @@ export const agentFindTool: Tool = {
300
312
  },
301
313
  },
302
314
  execute: async (params: Record<string, unknown>, config?: any) => {
303
- const db = getDb();
315
+ const db = await getHiveDB();
304
316
  const userId = config?.configurable?.user_id;
305
317
  const search = params.search as string | undefined;
306
318
  const status = params.status as string | undefined;
307
319
 
308
320
  try {
309
- let query = "SELECT id, name, description, role, status FROM agents WHERE user_id = ? AND role = 'worker'";
310
- const args: any[] = [userId];
321
+ const agentsCol = db.collection<HiveAgentDoc>("agents");
322
+ const entries = await agentsCol.scan();
323
+
324
+ let agents = entries
325
+ .map(e => e.doc)
326
+ .filter(a => a.userId === userId && a.role === "worker");
311
327
 
312
328
  if (search) {
313
- query += " AND (name LIKE ? OR description LIKE ?)";
314
- args.push(`%${search}%`, `%${search}%`);
329
+ const s = search.toLowerCase();
330
+ agents = agents.filter(a =>
331
+ a.name.toLowerCase().includes(s) || a.description.toLowerCase().includes(s)
332
+ );
315
333
  }
316
334
 
317
335
  if (status && status !== "any") {
318
- query += " AND status = ?";
319
- args.push(status);
336
+ agents = agents.filter(a => a.status === status);
320
337
  }
321
338
 
322
- const agents = db.query(query).all(...args) as any[];
323
-
324
339
  return {
325
340
  ok: true,
326
341
  count: agents.length,
@@ -351,16 +366,18 @@ export const agentArchiveTool: Tool = {
351
366
  required: ["agentId"],
352
367
  },
353
368
  execute: async (params: Record<string, unknown>) => {
354
- const db = getDb();
369
+ const db = await getHiveDB();
355
370
  const agentId = params.agentId as string;
356
371
 
357
372
  try {
358
- const result = db.query(`UPDATE agents SET enabled = 0, updated_at = unixepoch() WHERE id = ?`).run(agentId);
373
+ const agentsCol = db.collection<HiveAgentDoc>("agents");
374
+ const entry = await agentsCol.get(agentId);
359
375
 
360
- if (result.changes === 0) {
376
+ if (!entry) {
361
377
  return { ok: false, error: `Agent not found: ${agentId}` };
362
378
  }
363
379
 
380
+ await agentsCol.put(agentId, { ...entry.doc, enabled: false, updatedAt: Date.now() });
364
381
  return { ok: true, agentId, message: "Agent archived." };
365
382
  } catch (error) {
366
383
  return { ok: false, error: `Failed to archive agent: ${(error as Error).message}` };