@johpaz/hive-sdk 0.0.18 → 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.
- package/bun.lock +291 -1
- package/docs/HIVE-HARNESS.md +113 -0
- package/package.json +36 -2
- package/packages/cli/package.json +1 -1
- package/packages/core/package.json +13 -2
- package/packages/core/src/ace/Tracer.ts +1 -1
- package/packages/core/src/agent/AgentRunner.ts +12 -0
- package/packages/core/src/agent/ContextCompiler.ts +4 -4
- package/packages/core/src/agent/ConversationStore.ts +30 -20
- package/packages/core/src/agent/selectors/PlaybookSelector.ts +50 -76
- package/packages/core/src/agent/selectors/SkillSelector.ts +106 -262
- package/packages/core/src/agent/selectors/ToolSelector.ts +53 -89
- package/packages/core/src/auth/auth.ts +36 -23
- package/packages/core/src/harness/boot-id.ts +20 -0
- package/packages/core/src/harness/collections.ts +98 -0
- package/packages/core/src/harness/db-helpers.ts +87 -0
- package/packages/core/src/harness/durable-queue.ts +337 -0
- package/packages/core/src/harness/goal-verifier.ts +141 -0
- package/packages/core/src/harness/harness.test.ts +236 -0
- package/packages/core/src/harness/index.ts +34 -0
- package/packages/core/src/harness/job-store.ts +399 -0
- package/packages/core/src/harness/proof-packet.ts +69 -0
- package/packages/core/src/harness/reconcile.ts +149 -0
- package/packages/core/src/harness/run-epoch.ts +32 -0
- package/packages/core/src/harness/run-store.ts +334 -0
- package/packages/core/src/index.ts +6 -0
- package/packages/core/src/memory/Scratchpad.test.ts +23 -21
- package/packages/core/src/memory/Scratchpad.ts +41 -24
- package/packages/core/src/storage/HiveDBStorage.ts +64 -0
- package/packages/core/src/storage/SQLiteStorage.ts +7 -0
- package/packages/core/src/storage/hiveSeed.ts +308 -0
- package/packages/core/src/storage/hiveStorage.test.ts +38 -0
- package/packages/core/src/storage/index.ts +10 -0
- package/packages/core/src/storage/seed.ts +5 -1
- package/packages/core/src/storage/usage.ts +106 -167
- package/packages/core/src/tool-runtime/tool-runtime.test.ts +11 -3
- package/packages/core/src/tools/agents/get-available-models.ts +52 -56
- package/packages/core/src/tools/agents/index.ts +77 -60
- package/packages/core/src/tools/core/index.ts +106 -291
- package/packages/core/src/tools/meeting/index.ts +83 -93
- package/packages/core/src/utils/toon.ts +4 -4
|
@@ -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 =
|
|
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.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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 =
|
|
61
|
+
const db = await getHiveDB();
|
|
60
62
|
const title = params.title as string;
|
|
61
63
|
|
|
62
64
|
try {
|
|
63
|
-
const
|
|
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
|
|
74
|
-
updatedAt: new Date(note.updatedAt
|
|
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 =
|
|
96
|
+
const db = await getHiveDB();
|
|
93
97
|
|
|
94
98
|
try {
|
|
95
|
-
const
|
|
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
|
|
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 =
|
|
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
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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 =
|
|
167
|
+
const db = await getHiveDB();
|
|
159
168
|
const title = params.title as string;
|
|
160
169
|
|
|
161
170
|
try {
|
|
162
|
-
const
|
|
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 (
|
|
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 =
|
|
207
|
+
const db = await getHiveDB();
|
|
196
208
|
const userId = config?.configurable?.user_id;
|
|
197
|
-
const parentId = config?.configurable?.agent_id ??
|
|
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) :
|
|
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 ??
|
|
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
|
-
|
|
217
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
258
|
-
|
|
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 =
|
|
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
|
-
|
|
310
|
-
const
|
|
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
|
-
|
|
314
|
-
|
|
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
|
-
|
|
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 =
|
|
369
|
+
const db = await getHiveDB();
|
|
355
370
|
const agentId = params.agentId as string;
|
|
356
371
|
|
|
357
372
|
try {
|
|
358
|
-
const
|
|
373
|
+
const agentsCol = db.collection<HiveAgentDoc>("agents");
|
|
374
|
+
const entry = await agentsCol.get(agentId);
|
|
359
375
|
|
|
360
|
-
if (
|
|
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}` };
|