@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,148 +6,32 @@
|
|
|
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";
|
|
9
10
|
import { logger } from "../../utils/logger.ts";
|
|
10
11
|
|
|
11
12
|
const log = logger.child("core");
|
|
12
13
|
|
|
13
|
-
// ───
|
|
14
|
-
|
|
15
|
-
const ES_EN_DICT: Record<string, string[]> = {
|
|
16
|
-
// Acciones
|
|
17
|
-
"buscar": ["search", "find", "list", "get", "query"],
|
|
18
|
-
"listar": ["list", "get", "fetch", "retrieve"],
|
|
19
|
-
"crear": ["create", "add", "insert", "new", "make"],
|
|
20
|
-
"actualizar": ["update", "edit", "modify", "change"],
|
|
21
|
-
"eliminar": ["delete", "remove", "destroy"],
|
|
22
|
-
"obtener": ["get", "fetch", "retrieve", "read"],
|
|
23
|
-
"enviar": ["send", "post", "submit", "push"],
|
|
24
|
-
"leer": ["read", "get", "fetch"],
|
|
25
|
-
"escribir": ["write", "create", "save"],
|
|
26
|
-
"modificar": ["update", "modify", "edit", "change"],
|
|
27
|
-
"ejecutar": ["execute", "run", "invoke"],
|
|
28
|
-
"conectar": ["connect", "link"],
|
|
29
|
-
"desconectar": ["disconnect", "remove"],
|
|
30
|
-
"descargar": ["download", "export", "fetch"],
|
|
31
|
-
"subir": ["upload", "import", "create"],
|
|
32
|
-
"analizar": ["analyze", "review", "examine"],
|
|
33
|
-
"generar": ["generate", "create", "produce"],
|
|
34
|
-
"convertir": ["convert", "transform", "translate"],
|
|
35
|
-
"validar": ["validate", "verify", "check"],
|
|
36
|
-
"importar": ["import", "load", "ingest"],
|
|
37
|
-
"exportar": ["export", "download", "extract"],
|
|
38
|
-
"comprimir": ["compress", "zip", "archive"],
|
|
39
|
-
"extraer": ["extract", "get", "retrieve", "parse"],
|
|
40
|
-
"reemplazar": ["replace", "update", "swap"],
|
|
41
|
-
"cargar": ["load", "import", "upload"],
|
|
42
|
-
"guardar": ["save", "store", "create"],
|
|
43
|
-
"consultar": ["query", "search", "get", "list"],
|
|
44
|
-
"registrar": ["register", "create", "log", "record"],
|
|
45
|
-
"programar": ["schedule", "plan", "cron"],
|
|
46
|
-
"notificar": ["notify", "alert", "send"],
|
|
47
|
-
"reiniciar": ["restart", "reset", "reboot"],
|
|
48
|
-
"configurar": ["configure", "setup", "set"],
|
|
49
|
-
"autenticar": ["authenticate", "login", "auth"],
|
|
50
|
-
"publicar": ["publish", "deploy", "release"],
|
|
51
|
-
"desplegar": ["deploy", "publish", "release"],
|
|
52
|
-
"copiar": ["copy", "clone", "duplicate"],
|
|
53
|
-
"mover": ["move", "transfer", "migrate"],
|
|
54
|
-
"comparar": ["compare", "diff", "match"],
|
|
55
|
-
"fusionar": ["merge", "combine", "join"],
|
|
56
|
-
"dividir": ["split", "divide", "partition"],
|
|
57
|
-
"filtrar": ["filter", "search", "query"],
|
|
58
|
-
"ordenar": ["sort", "order", "arrange"],
|
|
59
|
-
"traducir": ["translate", "convert"],
|
|
60
|
-
|
|
61
|
-
// Entidades
|
|
62
|
-
"base": ["base", "database", "db"],
|
|
63
|
-
"bases": ["bases", "databases"],
|
|
64
|
-
"datos": ["data", "records", "rows", "entries"],
|
|
65
|
-
"registro": ["record", "entry", "row", "item"],
|
|
66
|
-
"registros": ["records", "entries", "rows", "items"],
|
|
67
|
-
"tabla": ["table", "schema", "collection"],
|
|
68
|
-
"tablas": ["tables", "schemas"],
|
|
69
|
-
"campo": ["field", "column", "property"],
|
|
70
|
-
"campos": ["fields", "columns", "properties"],
|
|
71
|
-
"usuario": ["user", "account"],
|
|
72
|
-
"usuarios": ["users", "accounts"],
|
|
73
|
-
"proyecto": ["project", "repo", "workspace"],
|
|
74
|
-
"proyectos": ["projects", "repos", "workspaces"],
|
|
75
|
-
"archivo": ["file", "document"],
|
|
76
|
-
"archivos": ["files", "documents"],
|
|
77
|
-
"correo": ["email", "mail", "message"],
|
|
78
|
-
"correos": ["emails", "mails", "messages"],
|
|
79
|
-
"noticia": ["news", "article", "post"],
|
|
80
|
-
"noticias": ["news", "articles", "posts"],
|
|
81
|
-
"contenido": ["content", "data", "text"],
|
|
82
|
-
"tarea": ["task", "job", "issue", "ticket"],
|
|
83
|
-
"tareas": ["tasks", "jobs", "issues", "tickets"],
|
|
84
|
-
"pagina": ["page", "site", "web"],
|
|
85
|
-
"enlace": ["link", "url", "reference"],
|
|
86
|
-
"imagen": ["image", "picture", "photo"],
|
|
87
|
-
"video": ["video", "media"],
|
|
88
|
-
"audio": ["audio", "sound", "media"],
|
|
89
|
-
"categoria": ["category", "tag", "label"],
|
|
90
|
-
"estado": ["status", "state", "condition"],
|
|
91
|
-
"error": ["error", "exception", "fault"],
|
|
92
|
-
"fuente": ["source", "origin", "reference"],
|
|
93
|
-
"esquema": ["schema", "structure", "model"],
|
|
94
|
-
"respuesta": ["response", "reply", "answer"],
|
|
95
|
-
"solicitud": ["request", "query", "call"],
|
|
96
|
-
"repositorio": ["repository", "repo"],
|
|
97
|
-
"seguridad": ["security", "auth", "permission"],
|
|
98
|
-
"permiso": ["permission", "role", "access"],
|
|
99
|
-
"acceso": ["access", "login", "entry"],
|
|
100
|
-
"servidor": ["server", "host", "service"],
|
|
101
|
-
"conexion": ["connection", "link", "integration"],
|
|
102
|
-
"integracion": ["integration", "connector", "plugin"],
|
|
103
|
-
"herramienta": ["tool", "utility", "function"],
|
|
104
|
-
"informacion": ["info", "information", "details"],
|
|
105
|
-
"lista": ["list", "collection", "array"],
|
|
106
|
-
"reporte": ["report", "summary", "analytics"],
|
|
107
|
-
"metrica": ["metric", "stat", "analytics"],
|
|
108
|
-
"contacto": ["contact", "lead", "person"],
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Translate a Spanish query to English equivalents for FTS5 fallback.
|
|
113
|
-
* Returns an array of English keyword tokens.
|
|
114
|
-
*/
|
|
115
|
-
function translateQueryToEnglish(query: string): string {
|
|
116
|
-
const words = query.toLowerCase().replace(/_/g, " ").split(/\s+/).filter(w => w.length > 1);
|
|
117
|
-
const translated: string[] = [];
|
|
118
|
-
|
|
119
|
-
for (const word of words) {
|
|
120
|
-
const equivalents = ES_EN_DICT[word];
|
|
121
|
-
if (equivalents) {
|
|
122
|
-
translated.push(...equivalents);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return [...new Set(translated)].join(" ");
|
|
127
|
-
}
|
|
14
|
+
// ─── search_knowledge ────────────────────────────────────────────────────────
|
|
128
15
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
return `"${words.join(' ')}" OR ${words[0]}*`;
|
|
16
|
+
function buildSearchQuery(query: string): string {
|
|
17
|
+
return query
|
|
18
|
+
.toLowerCase()
|
|
19
|
+
.replace(/[^\p{L}\p{N}\s]/gu, " ")
|
|
20
|
+
.split(/\s+/)
|
|
21
|
+
.filter(w => w.length > 2)
|
|
22
|
+
.slice(0, 8)
|
|
23
|
+
.join(" ");
|
|
138
24
|
}
|
|
139
25
|
|
|
140
|
-
// ─── search_knowledge ────────────────────────────────────────────────────────
|
|
141
|
-
|
|
142
26
|
export const searchKnowledgeTool: Tool = {
|
|
143
27
|
name: "search_knowledge",
|
|
144
|
-
description: "Busca herramientas NATIVAS (tools), MCP (tools externas), habilidades (skills) o reglas del playbook en la base de conocimientos. Usa búsqueda
|
|
28
|
+
description: "Busca herramientas NATIVAS (tools), MCP (tools externas), habilidades (skills) o reglas del playbook en la base de conocimientos. Usa búsqueda híbrida (BM25 + vector). type='mcp' para herramientas MCP, type='all' para buscar en todo.",
|
|
145
29
|
parameters: {
|
|
146
30
|
type: "object",
|
|
147
31
|
properties: {
|
|
148
32
|
query: {
|
|
149
33
|
type: "string",
|
|
150
|
-
description: "Término de búsqueda (nombre, descripción, categoría).
|
|
34
|
+
description: "Término de búsqueda (nombre, descripción, categoría).",
|
|
151
35
|
},
|
|
152
36
|
type: {
|
|
153
37
|
type: "string",
|
|
@@ -162,179 +46,105 @@ export const searchKnowledgeTool: Tool = {
|
|
|
162
46
|
required: ["query"],
|
|
163
47
|
},
|
|
164
48
|
execute: async (params: Record<string, unknown>) => {
|
|
165
|
-
const db =
|
|
49
|
+
const db = await getHiveDB();
|
|
166
50
|
const query = params.query as string;
|
|
167
51
|
const type = (params.type as string) ?? "all";
|
|
168
52
|
const limit = (params.limit as number) ?? 10;
|
|
169
|
-
const MIN_RESULTS_FOR_BILINGUAL = 2;
|
|
170
53
|
|
|
171
54
|
try {
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
55
|
+
const searchQuery = buildSearchQuery(query);
|
|
56
|
+
if (!searchQuery) {
|
|
57
|
+
return { ok: true, query, type, tools: [], skills: [], playbook: [], toolsmcp: [], totalResults: 0 };
|
|
58
|
+
}
|
|
176
59
|
|
|
177
60
|
const result: any = { query, type, tools: [], skills: [], playbook: [], toolsmcp: [] };
|
|
178
61
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
COALESCE(t.id, tools_fts.tool_name) as id,
|
|
187
|
-
COALESCE(t.name, tools_fts.tool_name) as name,
|
|
188
|
-
COALESCE(t.description, tools_fts.description) as description,
|
|
189
|
-
COALESCE(t.category, tools_fts.category) as category,
|
|
190
|
-
COALESCE(t.enabled, 1) as enabled,
|
|
191
|
-
COALESCE(t.active, 1) as active,
|
|
192
|
-
bm25(tools_fts) as rank
|
|
193
|
-
FROM tools_fts
|
|
194
|
-
LEFT JOIN tools t ON t.name = tools_fts.tool_name
|
|
195
|
-
WHERE tools_fts MATCH ?
|
|
196
|
-
ORDER BY rank
|
|
197
|
-
LIMIT ?
|
|
198
|
-
`).all(matchExpr, limit) as any[];
|
|
199
|
-
} catch { return []; }
|
|
62
|
+
async function searchByType(docType: string) {
|
|
63
|
+
return db.queryHybrid({
|
|
64
|
+
text: searchQuery,
|
|
65
|
+
k: limit,
|
|
66
|
+
filters: [{ field: "type", value: docType }],
|
|
67
|
+
boosts: { name: 5.0, body: 3.0, tags: 2.0 },
|
|
68
|
+
});
|
|
200
69
|
}
|
|
201
70
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
71
|
+
if (type === "all" || type === "tools") {
|
|
72
|
+
const hits = await searchByType("tool");
|
|
73
|
+
const toolsCol = db.collection<{ name: string; description: string; category: string; enabled: boolean; active: boolean }>("tools");
|
|
74
|
+
for (const hit of hits) {
|
|
75
|
+
const entry = await toolsCol.get(hit.id);
|
|
76
|
+
const doc = entry?.doc;
|
|
77
|
+
result.tools.push({
|
|
78
|
+
id: hit.id,
|
|
79
|
+
name: doc?.name ?? hit.id,
|
|
80
|
+
description: doc?.description ?? "",
|
|
81
|
+
category: doc?.category ?? "core",
|
|
82
|
+
enabled: doc?.enabled ?? true,
|
|
83
|
+
active: doc?.active ?? true,
|
|
84
|
+
rank: hit.score,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
214
87
|
}
|
|
215
88
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
89
|
+
if (type === "all" || type === "skills") {
|
|
90
|
+
const hits = await searchByType("skill");
|
|
91
|
+
const skillsCol = db.collection<{ name: string; description: string; category: string; body: string; tools: string[]; triggers: string[]; active: boolean }>("skills");
|
|
92
|
+
for (const hit of hits) {
|
|
93
|
+
const entry = await skillsCol.get(hit.id);
|
|
94
|
+
const doc = entry?.doc;
|
|
95
|
+
result.skills.push({
|
|
96
|
+
id: hit.id,
|
|
97
|
+
name: doc?.name ?? hit.id,
|
|
98
|
+
description: doc?.description ?? "",
|
|
99
|
+
category: doc?.category ?? "general",
|
|
100
|
+
tools: doc?.tools ?? [],
|
|
101
|
+
triggers: doc?.triggers ?? [],
|
|
102
|
+
body: doc?.body ? (doc.body.length > 400 ? doc.body.substring(0, 400) + "…" : doc.body) : undefined,
|
|
103
|
+
active: doc?.active ?? true,
|
|
104
|
+
rank: hit.score,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
228
107
|
}
|
|
229
108
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
109
|
+
if (type === "all" || type === "playbook") {
|
|
110
|
+
const hits = await searchByType("playbook");
|
|
111
|
+
const playbookCol = db.collection<{ rule: string; category: string; applicableTo?: string[]; active: boolean }>("playbook");
|
|
112
|
+
for (const hit of hits) {
|
|
113
|
+
const entry = await playbookCol.get(hit.id);
|
|
114
|
+
const doc = entry?.doc;
|
|
115
|
+
result.playbook.push({
|
|
116
|
+
id: hit.id,
|
|
117
|
+
rule: doc?.rule ?? "",
|
|
118
|
+
category: doc?.category ?? "",
|
|
119
|
+
applicable_to: doc?.applicableTo ?? null,
|
|
120
|
+
active: doc?.active ?? true,
|
|
121
|
+
rank: hit.score,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
242
124
|
}
|
|
243
125
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
id: p.id, rule: p.rule, category: p.category,
|
|
267
|
-
applicable_to: p.applicable_to ? JSON.parse(p.applicable_to) : null,
|
|
268
|
-
helpful_count: p.helpful_count, harmful_count: p.harmful_count,
|
|
269
|
-
active: p.active === 1, rank: p.rank,
|
|
270
|
-
}));
|
|
271
|
-
result.toolsmcp = mcp1.map((t: any) => ({
|
|
272
|
-
id: t.id, full_name: t.id, server_name: t.server_name, tool_name: t.tool_name,
|
|
273
|
-
description: t.description, category: t.category,
|
|
274
|
-
active: t.active === 1, rank: t.rank,
|
|
275
|
-
}));
|
|
276
|
-
|
|
277
|
-
// ─── Pass 2: Bilingual fallback (ES → EN) ──────────────────────
|
|
278
|
-
|
|
279
|
-
if (totalFirst < MIN_RESULTS_FOR_BILINGUAL) {
|
|
280
|
-
const englishQuery = translateQueryToEnglish(normalizedQuery);
|
|
281
|
-
if (englishQuery.length > 0) {
|
|
282
|
-
const enWords = englishQuery.split(/\s+/).filter(w => w.length > 0);
|
|
283
|
-
const enMatch = buildFtsMatch(enWords);
|
|
284
|
-
|
|
285
|
-
log.info(`[search_knowledge] Bilingual fallback: "${normalizedQuery}" → "${englishQuery}" (first pass: ${totalFirst} results)`);
|
|
286
|
-
|
|
287
|
-
const existingIds = new Set([
|
|
288
|
-
...result.tools.map((t: any) => t.name),
|
|
289
|
-
...result.skills.map((s: any) => s.id),
|
|
290
|
-
...result.playbook.map((p: any) => p.id),
|
|
291
|
-
...result.toolsmcp.map((t: any) => t.id),
|
|
292
|
-
]);
|
|
293
|
-
|
|
294
|
-
// Merge English results (dedup by id)
|
|
295
|
-
for (const t of searchTools(enMatch)) {
|
|
296
|
-
if (!existingIds.has(t.name || t.id)) {
|
|
297
|
-
result.tools.push({
|
|
298
|
-
id: t.id, name: t.name, description: t.description, category: t.category,
|
|
299
|
-
enabled: t.enabled === 1, active: t.active === 1, rank: t.rank,
|
|
300
|
-
});
|
|
301
|
-
existingIds.add(t.name || t.id);
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
for (const s of searchSkills(enMatch)) {
|
|
305
|
-
if (!existingIds.has(s.id)) {
|
|
306
|
-
result.skills.push({
|
|
307
|
-
id: s.id, name: s.name, description: s.description, category: s.category,
|
|
308
|
-
tools: s.tools, triggers: s.triggers,
|
|
309
|
-
preferred_agents: s.preferred_agents ? JSON.parse(s.preferred_agents) : [],
|
|
310
|
-
body: s.body ? (s.body.length > 400 ? s.body.substring(0, 400) + "…" : s.body) : undefined,
|
|
311
|
-
active: s.active === 1, rank: s.rank,
|
|
312
|
-
});
|
|
313
|
-
existingIds.add(s.id);
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
for (const p of searchPlaybook(enMatch)) {
|
|
317
|
-
if (!existingIds.has(p.id)) {
|
|
318
|
-
result.playbook.push({
|
|
319
|
-
id: p.id, rule: p.rule, category: p.category,
|
|
320
|
-
applicable_to: p.applicable_to ? JSON.parse(p.applicable_to) : null,
|
|
321
|
-
helpful_count: p.helpful_count, harmful_count: p.harmful_count,
|
|
322
|
-
active: p.active === 1, rank: p.rank,
|
|
323
|
-
});
|
|
324
|
-
existingIds.add(p.id);
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
for (const t of searchMcpTools(enMatch)) {
|
|
328
|
-
if (!existingIds.has(t.id)) {
|
|
329
|
-
result.toolsmcp.push({
|
|
330
|
-
id: t.id, full_name: t.id, server_name: t.server_name, tool_name: t.tool_name,
|
|
331
|
-
description: t.description, category: t.category,
|
|
332
|
-
active: t.active === 1, rank: t.rank,
|
|
333
|
-
});
|
|
334
|
-
existingIds.add(t.id);
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
}
|
|
126
|
+
if (type === "all" || type === "mcp") {
|
|
127
|
+
const mcpCol = db.collection<{ serverName: string; toolName: string; description: string; category: string; active: boolean }>("mcp_tools");
|
|
128
|
+
const entries = await mcpCol.scan();
|
|
129
|
+
const q = searchQuery.toLowerCase();
|
|
130
|
+
const matches = entries
|
|
131
|
+
.map(e => e.doc)
|
|
132
|
+
.filter(m => m.active && (
|
|
133
|
+
m.toolName.toLowerCase().includes(q) ||
|
|
134
|
+
m.description.toLowerCase().includes(q) ||
|
|
135
|
+
m.category.toLowerCase().includes(q)
|
|
136
|
+
))
|
|
137
|
+
.slice(0, limit);
|
|
138
|
+
result.toolsmcp = matches.map(m => ({
|
|
139
|
+
id: `${m.serverName}__${m.toolName}`,
|
|
140
|
+
full_name: `${m.serverName}__${m.toolName}`,
|
|
141
|
+
server_name: m.serverName,
|
|
142
|
+
tool_name: m.toolName,
|
|
143
|
+
description: m.description,
|
|
144
|
+
category: m.category,
|
|
145
|
+
active: true,
|
|
146
|
+
rank: 0,
|
|
147
|
+
}));
|
|
338
148
|
}
|
|
339
149
|
|
|
340
150
|
result.totalResults = result.tools.length + result.skills.length + result.playbook.length + result.toolsmcp.length;
|
|
@@ -380,6 +190,13 @@ export const notifyTool: Tool = {
|
|
|
380
190
|
|
|
381
191
|
// ─── save_note (scratchpad) ──────────────────────────────────────────────────
|
|
382
192
|
|
|
193
|
+
interface ScratchpadDoc {
|
|
194
|
+
threadId: string;
|
|
195
|
+
key: string;
|
|
196
|
+
value: string;
|
|
197
|
+
updatedAt: number;
|
|
198
|
+
}
|
|
199
|
+
|
|
383
200
|
export const saveNoteTool: Tool = {
|
|
384
201
|
name: "save_note",
|
|
385
202
|
description: "Save a note to the scratchpad (survives context compression).",
|
|
@@ -402,16 +219,14 @@ export const saveNoteTool: Tool = {
|
|
|
402
219
|
required: ["key", "value"],
|
|
403
220
|
},
|
|
404
221
|
execute: async (params: Record<string, unknown>, config?: any) => {
|
|
405
|
-
const db =
|
|
222
|
+
const db = await getHiveDB();
|
|
406
223
|
const key = params.key as string;
|
|
407
224
|
const value = params.value as string;
|
|
408
225
|
const threadId = (params.thread_id as string) ?? config?.configurable?.thread_id ?? "default";
|
|
409
226
|
|
|
410
227
|
try {
|
|
411
|
-
db.
|
|
412
|
-
|
|
413
|
-
VALUES (?, ?, ?, 'agent', unixepoch())
|
|
414
|
-
`).run(threadId, key, value);
|
|
228
|
+
const col = db.collection<ScratchpadDoc>("scratchpad");
|
|
229
|
+
await col.put(`${threadId}:${key}`, { threadId, key, value, updatedAt: Date.now() });
|
|
415
230
|
|
|
416
231
|
return { ok: true, key, message: "Note saved." };
|
|
417
232
|
} catch (error) {
|
|
@@ -473,4 +288,4 @@ export const reportProgressTool: Tool = {
|
|
|
473
288
|
|
|
474
289
|
export function createTools(): Tool[] {
|
|
475
290
|
return [searchKnowledgeTool, notifyTool, saveNoteTool, reportProgressTool];
|
|
476
|
-
}
|
|
291
|
+
}
|