nodebench-mcp 2.14.1 → 2.15.0
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/NODEBENCH_AGENTS.md +19 -9
- package/README.md +42 -19
- package/dist/__tests__/critterCalibrationEval.d.ts +8 -0
- package/dist/__tests__/critterCalibrationEval.js +370 -0
- package/dist/__tests__/critterCalibrationEval.js.map +1 -0
- package/dist/__tests__/embeddingProvider.test.d.ts +1 -0
- package/dist/__tests__/embeddingProvider.test.js +86 -0
- package/dist/__tests__/embeddingProvider.test.js.map +1 -0
- package/dist/__tests__/gaiaCapabilityAudioEval.test.js +1 -1
- package/dist/__tests__/gaiaCapabilityAudioEval.test.js.map +1 -1
- package/dist/__tests__/gaiaCapabilityEval.test.js +541 -27
- package/dist/__tests__/gaiaCapabilityEval.test.js.map +1 -1
- package/dist/__tests__/gaiaCapabilityFilesEval.test.js +1 -1
- package/dist/__tests__/gaiaCapabilityFilesEval.test.js.map +1 -1
- package/dist/__tests__/gaiaCapabilityMediaEval.test.js +473 -4
- package/dist/__tests__/gaiaCapabilityMediaEval.test.js.map +1 -1
- package/dist/__tests__/tools.test.js +1010 -8
- package/dist/__tests__/tools.test.js.map +1 -1
- package/dist/db.js +64 -0
- package/dist/db.js.map +1 -1
- package/dist/index.js +70 -9
- package/dist/index.js.map +1 -1
- package/dist/tools/critterTools.d.ts +21 -0
- package/dist/tools/critterTools.js +230 -0
- package/dist/tools/critterTools.js.map +1 -0
- package/dist/tools/embeddingProvider.d.ts +67 -0
- package/dist/tools/embeddingProvider.js +299 -0
- package/dist/tools/embeddingProvider.js.map +1 -0
- package/dist/tools/progressiveDiscoveryTools.js +24 -7
- package/dist/tools/progressiveDiscoveryTools.js.map +1 -1
- package/dist/tools/reconTools.js +83 -33
- package/dist/tools/reconTools.js.map +1 -1
- package/dist/tools/toolRegistry.d.ts +30 -2
- package/dist/tools/toolRegistry.js +253 -25
- package/dist/tools/toolRegistry.js.map +1 -1
- package/package.json +13 -3
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embedding Provider — True semantic search via neural embeddings.
|
|
3
|
+
*
|
|
4
|
+
* Provider fallback order:
|
|
5
|
+
* 1. Local: @huggingface/transformers + Xenova/all-MiniLM-L6-v2 (384-dim, 23MB INT8, zero API keys)
|
|
6
|
+
* 2. Google: text-embedding-004 (768-dim, free API, needs GEMINI_API_KEY)
|
|
7
|
+
* 3. OpenAI: text-embedding-3-small (1536-dim, $0.02/1M tokens, needs OPENAI_API_KEY)
|
|
8
|
+
*
|
|
9
|
+
* Graceful degradation: if no provider is available, all exports return null/false
|
|
10
|
+
* and search works exactly as before.
|
|
11
|
+
*/
|
|
12
|
+
export interface EmbeddingProvider {
|
|
13
|
+
name: string;
|
|
14
|
+
dimensions: number;
|
|
15
|
+
embed(texts: string[]): Promise<Float32Array[]>;
|
|
16
|
+
}
|
|
17
|
+
/** Node type in the bipartite graph: tool nodes vs domain (agent) nodes */
|
|
18
|
+
export type GraphNodeType = "tool" | "domain";
|
|
19
|
+
interface EmbeddingIndexEntry {
|
|
20
|
+
name: string;
|
|
21
|
+
vector: Float32Array;
|
|
22
|
+
/** Node type for Agent-as-a-Graph bipartite scoring */
|
|
23
|
+
nodeType: GraphNodeType;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Returns the best available embedding provider, or null if none is available.
|
|
27
|
+
* Tries: local HuggingFace → Google → OpenAI (in that order).
|
|
28
|
+
*/
|
|
29
|
+
export declare function getEmbeddingProvider(): Promise<EmbeddingProvider | null>;
|
|
30
|
+
/**
|
|
31
|
+
* Pre-embed all tools at startup. Reads from cache if valid, otherwise embeds fresh.
|
|
32
|
+
* Call this once after tool assembly with a corpus of { name, text, nodeType? } entries.
|
|
33
|
+
* nodeType defaults to "tool" for backwards compatibility.
|
|
34
|
+
*/
|
|
35
|
+
export declare function initEmbeddingIndex(corpus: Array<{
|
|
36
|
+
name: string;
|
|
37
|
+
text: string;
|
|
38
|
+
nodeType?: GraphNodeType;
|
|
39
|
+
}>): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Embed a single query string. Returns null if no provider is available.
|
|
42
|
+
*/
|
|
43
|
+
export declare function embedQuery(text: string): Promise<Float32Array | null>;
|
|
44
|
+
/**
|
|
45
|
+
* Brute-force cosine KNN over the pre-computed embedding index.
|
|
46
|
+
* Returns ranked results with similarity scores and node types.
|
|
47
|
+
*/
|
|
48
|
+
export declare function embeddingSearch(queryVec: Float32Array, limit?: number): Array<{
|
|
49
|
+
name: string;
|
|
50
|
+
similarity: number;
|
|
51
|
+
nodeType: GraphNodeType;
|
|
52
|
+
}>;
|
|
53
|
+
/**
|
|
54
|
+
* Returns true when the embedding index is loaded and ready for search.
|
|
55
|
+
*/
|
|
56
|
+
export declare function isEmbeddingReady(): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Returns the name of the active embedding provider, or null.
|
|
59
|
+
*/
|
|
60
|
+
export declare function getProviderName(): string | null;
|
|
61
|
+
/** Reset all state — for testing only. */
|
|
62
|
+
export declare function _resetForTesting(): void;
|
|
63
|
+
/** Inject a mock provider — for testing only. */
|
|
64
|
+
export declare function _setProviderForTesting(provider: EmbeddingProvider | null): void;
|
|
65
|
+
/** Inject a pre-built index — for testing only. */
|
|
66
|
+
export declare function _setIndexForTesting(index: EmbeddingIndexEntry[]): void;
|
|
67
|
+
export {};
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embedding Provider — True semantic search via neural embeddings.
|
|
3
|
+
*
|
|
4
|
+
* Provider fallback order:
|
|
5
|
+
* 1. Local: @huggingface/transformers + Xenova/all-MiniLM-L6-v2 (384-dim, 23MB INT8, zero API keys)
|
|
6
|
+
* 2. Google: text-embedding-004 (768-dim, free API, needs GEMINI_API_KEY)
|
|
7
|
+
* 3. OpenAI: text-embedding-3-small (1536-dim, $0.02/1M tokens, needs OPENAI_API_KEY)
|
|
8
|
+
*
|
|
9
|
+
* Graceful degradation: if no provider is available, all exports return null/false
|
|
10
|
+
* and search works exactly as before.
|
|
11
|
+
*/
|
|
12
|
+
import { homedir } from "node:os";
|
|
13
|
+
import { join } from "node:path";
|
|
14
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
|
|
15
|
+
// ── State ────────────────────────────────────────────────────────────────────
|
|
16
|
+
let _provider = null;
|
|
17
|
+
let _providerChecked = false;
|
|
18
|
+
let _embeddingIndex = null;
|
|
19
|
+
let _initPromise = null;
|
|
20
|
+
const CACHE_VERSION = 1;
|
|
21
|
+
const CACHE_DIR = join(homedir(), ".nodebench");
|
|
22
|
+
const CACHE_FILE = join(CACHE_DIR, "embedding_cache.json");
|
|
23
|
+
// ── Provider creation ────────────────────────────────────────────────────────
|
|
24
|
+
async function createLocalProvider() {
|
|
25
|
+
try {
|
|
26
|
+
// Non-literal import to avoid TypeScript bundling issues with optional deps
|
|
27
|
+
const pkg = "@huggingface/transformers";
|
|
28
|
+
const mod = await import(/* @vite-ignore */ pkg);
|
|
29
|
+
const { pipeline, env } = mod;
|
|
30
|
+
// Disable remote model loading attempts in restricted environments
|
|
31
|
+
env.allowRemoteModels = true;
|
|
32
|
+
env.useBrowserCache = false;
|
|
33
|
+
const extractor = await pipeline("feature-extraction", "Xenova/all-MiniLM-L6-v2", {
|
|
34
|
+
quantized: true, // INT8 — 23MB vs 90MB FP32
|
|
35
|
+
});
|
|
36
|
+
return {
|
|
37
|
+
name: "local-minilm",
|
|
38
|
+
dimensions: 384,
|
|
39
|
+
embed: async (texts) => {
|
|
40
|
+
const results = [];
|
|
41
|
+
// Batch in chunks of 32 to avoid OOM on large corpora
|
|
42
|
+
for (let i = 0; i < texts.length; i += 32) {
|
|
43
|
+
const batch = texts.slice(i, i + 32);
|
|
44
|
+
const output = await extractor(batch, { pooling: "mean", normalize: true });
|
|
45
|
+
for (let j = 0; j < batch.length; j++) {
|
|
46
|
+
results.push(new Float32Array(output[j].data));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return results;
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async function createGoogleProvider() {
|
|
58
|
+
const apiKey = process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY;
|
|
59
|
+
if (!apiKey)
|
|
60
|
+
return null;
|
|
61
|
+
try {
|
|
62
|
+
const { GoogleGenAI } = await import("@google/genai");
|
|
63
|
+
const ai = new GoogleGenAI({ apiKey });
|
|
64
|
+
return {
|
|
65
|
+
name: "google",
|
|
66
|
+
dimensions: 768,
|
|
67
|
+
embed: async (texts) => {
|
|
68
|
+
const results = [];
|
|
69
|
+
// Google API supports batching up to 100 texts
|
|
70
|
+
for (let i = 0; i < texts.length; i += 100) {
|
|
71
|
+
const batch = texts.slice(i, i + 100);
|
|
72
|
+
const response = await ai.models.embedContent({
|
|
73
|
+
model: "text-embedding-004",
|
|
74
|
+
contents: batch.map((t) => ({ parts: [{ text: t }] })),
|
|
75
|
+
});
|
|
76
|
+
const embeddings = response.embeddings ?? [];
|
|
77
|
+
for (const emb of embeddings) {
|
|
78
|
+
results.push(new Float32Array(emb.values));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return results;
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async function createOpenAIProvider() {
|
|
90
|
+
if (!process.env.OPENAI_API_KEY)
|
|
91
|
+
return null;
|
|
92
|
+
try {
|
|
93
|
+
const OpenAI = (await import("openai")).default;
|
|
94
|
+
const client = new OpenAI();
|
|
95
|
+
return {
|
|
96
|
+
name: "openai",
|
|
97
|
+
dimensions: 1536,
|
|
98
|
+
embed: async (texts) => {
|
|
99
|
+
const results = [];
|
|
100
|
+
// OpenAI supports up to 2048 inputs per request
|
|
101
|
+
for (let i = 0; i < texts.length; i += 2048) {
|
|
102
|
+
const batch = texts.slice(i, i + 2048);
|
|
103
|
+
const response = await client.embeddings.create({
|
|
104
|
+
model: "text-embedding-3-small",
|
|
105
|
+
input: batch,
|
|
106
|
+
});
|
|
107
|
+
for (const item of response.data) {
|
|
108
|
+
results.push(new Float32Array(item.embedding));
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return results;
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// ── Public API ───────────────────────────────────────────────────────────────
|
|
120
|
+
/**
|
|
121
|
+
* Returns the best available embedding provider, or null if none is available.
|
|
122
|
+
* Tries: local HuggingFace → Google → OpenAI (in that order).
|
|
123
|
+
*/
|
|
124
|
+
export async function getEmbeddingProvider() {
|
|
125
|
+
if (_providerChecked)
|
|
126
|
+
return _provider;
|
|
127
|
+
_providerChecked = true;
|
|
128
|
+
_provider = await createLocalProvider();
|
|
129
|
+
if (_provider)
|
|
130
|
+
return _provider;
|
|
131
|
+
_provider = await createGoogleProvider();
|
|
132
|
+
if (_provider)
|
|
133
|
+
return _provider;
|
|
134
|
+
_provider = await createOpenAIProvider();
|
|
135
|
+
return _provider;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Pre-embed all tools at startup. Reads from cache if valid, otherwise embeds fresh.
|
|
139
|
+
* Call this once after tool assembly with a corpus of { name, text, nodeType? } entries.
|
|
140
|
+
* nodeType defaults to "tool" for backwards compatibility.
|
|
141
|
+
*/
|
|
142
|
+
export async function initEmbeddingIndex(corpus) {
|
|
143
|
+
// Prevent duplicate init
|
|
144
|
+
if (_initPromise)
|
|
145
|
+
return _initPromise;
|
|
146
|
+
_initPromise = _doInit(corpus);
|
|
147
|
+
return _initPromise;
|
|
148
|
+
}
|
|
149
|
+
async function _doInit(corpus) {
|
|
150
|
+
const provider = await getEmbeddingProvider();
|
|
151
|
+
if (!provider)
|
|
152
|
+
return; // No provider — semantic search stays disabled
|
|
153
|
+
const hash = fnv1aHash(corpus.map((c) => c.text).join("\n"));
|
|
154
|
+
// Try loading from cache
|
|
155
|
+
const cached = loadCache();
|
|
156
|
+
if (cached &&
|
|
157
|
+
cached.providerName === provider.name &&
|
|
158
|
+
cached.dimensions === provider.dimensions &&
|
|
159
|
+
cached.version === CACHE_VERSION &&
|
|
160
|
+
cached.toolCount === corpus.length &&
|
|
161
|
+
cached.corpusHash === hash &&
|
|
162
|
+
corpus.every((c) => c.name in cached.entries)) {
|
|
163
|
+
_embeddingIndex = corpus.map((c) => ({
|
|
164
|
+
name: c.name,
|
|
165
|
+
vector: new Float32Array(cached.entries[c.name]),
|
|
166
|
+
nodeType: c.nodeType ?? "tool",
|
|
167
|
+
}));
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
// Embed all tools
|
|
171
|
+
try {
|
|
172
|
+
const texts = corpus.map((c) => c.text);
|
|
173
|
+
const vectors = await provider.embed(texts);
|
|
174
|
+
_embeddingIndex = corpus.map((c, i) => ({
|
|
175
|
+
name: c.name,
|
|
176
|
+
vector: vectors[i],
|
|
177
|
+
nodeType: c.nodeType ?? "tool",
|
|
178
|
+
}));
|
|
179
|
+
// Save to cache
|
|
180
|
+
const cacheData = {
|
|
181
|
+
providerName: provider.name,
|
|
182
|
+
dimensions: provider.dimensions,
|
|
183
|
+
version: CACHE_VERSION,
|
|
184
|
+
toolCount: corpus.length,
|
|
185
|
+
corpusHash: hash,
|
|
186
|
+
entries: {},
|
|
187
|
+
};
|
|
188
|
+
for (let i = 0; i < corpus.length; i++) {
|
|
189
|
+
cacheData.entries[corpus[i].name] = Array.from(vectors[i]);
|
|
190
|
+
}
|
|
191
|
+
saveCache(cacheData);
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
// Embedding failed — graceful degradation, search works without embeddings
|
|
195
|
+
_embeddingIndex = null;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Embed a single query string. Returns null if no provider is available.
|
|
200
|
+
*/
|
|
201
|
+
export async function embedQuery(text) {
|
|
202
|
+
const provider = await getEmbeddingProvider();
|
|
203
|
+
if (!provider)
|
|
204
|
+
return null;
|
|
205
|
+
try {
|
|
206
|
+
const [vec] = await provider.embed([text]);
|
|
207
|
+
return vec;
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Brute-force cosine KNN over the pre-computed embedding index.
|
|
215
|
+
* Returns ranked results with similarity scores and node types.
|
|
216
|
+
*/
|
|
217
|
+
export function embeddingSearch(queryVec, limit = 30) {
|
|
218
|
+
if (!_embeddingIndex)
|
|
219
|
+
return [];
|
|
220
|
+
const scored = _embeddingIndex.map((entry) => ({
|
|
221
|
+
name: entry.name,
|
|
222
|
+
similarity: cosineSim(queryVec, entry.vector),
|
|
223
|
+
nodeType: entry.nodeType,
|
|
224
|
+
}));
|
|
225
|
+
scored.sort((a, b) => b.similarity - a.similarity);
|
|
226
|
+
return scored.slice(0, limit);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Returns true when the embedding index is loaded and ready for search.
|
|
230
|
+
*/
|
|
231
|
+
export function isEmbeddingReady() {
|
|
232
|
+
return _embeddingIndex !== null && _embeddingIndex.length > 0;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Returns the name of the active embedding provider, or null.
|
|
236
|
+
*/
|
|
237
|
+
export function getProviderName() {
|
|
238
|
+
return _provider?.name ?? null;
|
|
239
|
+
}
|
|
240
|
+
// ── Internals ────────────────────────────────────────────────────────────────
|
|
241
|
+
/** FNV-1a hash — fast, deterministic, good distribution for cache invalidation */
|
|
242
|
+
function fnv1aHash(str) {
|
|
243
|
+
let hash = 0x811c9dc5;
|
|
244
|
+
for (let i = 0; i < str.length; i++) {
|
|
245
|
+
hash ^= str.charCodeAt(i);
|
|
246
|
+
hash = (hash * 0x01000193) >>> 0;
|
|
247
|
+
}
|
|
248
|
+
return hash.toString(36);
|
|
249
|
+
}
|
|
250
|
+
function cosineSim(a, b) {
|
|
251
|
+
if (a.length !== b.length)
|
|
252
|
+
return 0;
|
|
253
|
+
let dot = 0, normA = 0, normB = 0;
|
|
254
|
+
for (let i = 0; i < a.length; i++) {
|
|
255
|
+
dot += a[i] * b[i];
|
|
256
|
+
normA += a[i] * a[i];
|
|
257
|
+
normB += b[i] * b[i];
|
|
258
|
+
}
|
|
259
|
+
const denom = Math.sqrt(normA) * Math.sqrt(normB);
|
|
260
|
+
return denom === 0 ? 0 : dot / denom;
|
|
261
|
+
}
|
|
262
|
+
function loadCache() {
|
|
263
|
+
try {
|
|
264
|
+
if (!existsSync(CACHE_FILE))
|
|
265
|
+
return null;
|
|
266
|
+
const raw = readFileSync(CACHE_FILE, "utf-8");
|
|
267
|
+
return JSON.parse(raw);
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
function saveCache(data) {
|
|
274
|
+
try {
|
|
275
|
+
mkdirSync(CACHE_DIR, { recursive: true });
|
|
276
|
+
writeFileSync(CACHE_FILE, JSON.stringify(data));
|
|
277
|
+
}
|
|
278
|
+
catch {
|
|
279
|
+
// Non-critical — next startup will just re-embed
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
// ── Testing helpers ──────────────────────────────────────────────────────────
|
|
283
|
+
/** Reset all state — for testing only. */
|
|
284
|
+
export function _resetForTesting() {
|
|
285
|
+
_provider = null;
|
|
286
|
+
_providerChecked = false;
|
|
287
|
+
_embeddingIndex = null;
|
|
288
|
+
_initPromise = null;
|
|
289
|
+
}
|
|
290
|
+
/** Inject a mock provider — for testing only. */
|
|
291
|
+
export function _setProviderForTesting(provider) {
|
|
292
|
+
_provider = provider;
|
|
293
|
+
_providerChecked = true;
|
|
294
|
+
}
|
|
295
|
+
/** Inject a pre-built index — for testing only. */
|
|
296
|
+
export function _setIndexForTesting(index) {
|
|
297
|
+
_embeddingIndex = index;
|
|
298
|
+
}
|
|
299
|
+
//# sourceMappingURL=embeddingProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embeddingProvider.js","sourceRoot":"","sources":["../../src/tools/embeddingProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,12 +8,13 @@
|
|
|
8
8
|
* - get_workflow_chain: Get a recommended tool sequence for a common workflow
|
|
9
9
|
*/
|
|
10
10
|
import { hybridSearch, TOOL_REGISTRY, ALL_REGISTRY_ENTRIES, WORKFLOW_CHAINS, SEARCH_MODES, } from "./toolRegistry.js";
|
|
11
|
+
import { embedQuery, isEmbeddingReady } from "./embeddingProvider.js";
|
|
11
12
|
export function createProgressiveDiscoveryTools(allRegisteredTools) {
|
|
12
13
|
return [
|
|
13
14
|
// ── discover_tools ─────────────────────────────────────────────────
|
|
14
15
|
{
|
|
15
16
|
name: "discover_tools",
|
|
16
|
-
description: "Multi-modal tool search engine with
|
|
17
|
+
description: "Multi-modal tool search engine with 14 scoring strategies: keyword, fuzzy (typo-tolerant), n-gram (partial words), prefix, semantic (synonym expansion), TF-IDF (rare tags score higher), regex, bigram (phrase matching), domain cluster boosting, dense (TF-IDF cosine), neural embedding tool RRF, domain RRF (Agent-as-a-Graph bipartite graph), upward traversal (tool→domain→siblings), and execution trace edges (co-occurrence mining). Returns ranked results with quick refs. Use mode='hybrid' (default) for best results, or 'regex'/'fuzzy'/'prefix'/'semantic'/'exact'/'dense'/'embedding' for targeted search.",
|
|
17
18
|
inputSchema: {
|
|
18
19
|
type: "object",
|
|
19
20
|
properties: {
|
|
@@ -29,7 +30,9 @@ export function createProgressiveDiscoveryTools(allRegisteredTools) {
|
|
|
29
30
|
"github", "documentation", "bootstrap", "self_eval",
|
|
30
31
|
"parallel_agents", "llm", "security", "platform",
|
|
31
32
|
"research_writing", "flicker_detection", "figma_flow",
|
|
32
|
-
"boilerplate", "benchmark", "
|
|
33
|
+
"boilerplate", "benchmark", "session_memory", "gaia_solvers",
|
|
34
|
+
"toon", "pattern", "git_workflow", "seo", "voice_bridge",
|
|
35
|
+
"critter", "progressive_discovery", "meta",
|
|
33
36
|
],
|
|
34
37
|
description: "Filter by tool category (optional)",
|
|
35
38
|
},
|
|
@@ -48,8 +51,8 @@ export function createProgressiveDiscoveryTools(allRegisteredTools) {
|
|
|
48
51
|
},
|
|
49
52
|
mode: {
|
|
50
53
|
type: "string",
|
|
51
|
-
enum: ["hybrid", "fuzzy", "regex", "prefix", "semantic", "exact", "dense"],
|
|
52
|
-
description: "Search mode. 'hybrid' (default) runs all strategies. 'fuzzy' tolerates typos. 'regex' accepts patterns. 'prefix' matches tool name starts. 'semantic' expands synonyms. 'exact' requires exact match. 'dense' uses TF-IDF cosine similarity
|
|
54
|
+
enum: ["hybrid", "fuzzy", "regex", "prefix", "semantic", "exact", "dense", "embedding"],
|
|
55
|
+
description: "Search mode. 'hybrid' (default) runs all strategies including neural embeddings when available. 'fuzzy' tolerates typos. 'regex' accepts patterns. 'prefix' matches tool name starts. 'semantic' expands synonyms. 'exact' requires exact match. 'dense' uses TF-IDF cosine similarity. 'embedding' uses neural embedding similarity only.",
|
|
53
56
|
},
|
|
54
57
|
explain: {
|
|
55
58
|
type: "boolean",
|
|
@@ -64,6 +67,13 @@ export function createProgressiveDiscoveryTools(allRegisteredTools) {
|
|
|
64
67
|
const includeChains = args.includeChains !== false;
|
|
65
68
|
const mode = args.mode ?? "hybrid";
|
|
66
69
|
const explain = args.explain === true;
|
|
70
|
+
// Pre-compute query embedding (async) before passing to sync hybridSearch
|
|
71
|
+
let embeddingQueryVec;
|
|
72
|
+
if ((mode === "hybrid" || mode === "embedding") && isEmbeddingReady()) {
|
|
73
|
+
const vec = await embedQuery(query);
|
|
74
|
+
if (vec)
|
|
75
|
+
embeddingQueryVec = vec;
|
|
76
|
+
}
|
|
67
77
|
// Multi-modal search with scoring
|
|
68
78
|
const results = hybridSearch(query, allRegisteredTools, {
|
|
69
79
|
category: args.category,
|
|
@@ -71,6 +81,7 @@ export function createProgressiveDiscoveryTools(allRegisteredTools) {
|
|
|
71
81
|
limit,
|
|
72
82
|
mode,
|
|
73
83
|
explain,
|
|
84
|
+
embeddingQueryVec,
|
|
74
85
|
});
|
|
75
86
|
// Find matching workflow chains
|
|
76
87
|
let matchingChains = [];
|
|
@@ -177,7 +188,7 @@ export function createProgressiveDiscoveryTools(allRegisteredTools) {
|
|
|
177
188
|
// ── get_workflow_chain ──────────────────────────────────────────────
|
|
178
189
|
{
|
|
179
190
|
name: "get_workflow_chain",
|
|
180
|
-
description: 'Get a recommended tool sequence for a common workflow. Returns step-by-step tool chain with actions for each step.
|
|
191
|
+
description: 'Get a recommended tool sequence for a common workflow. Returns step-by-step tool chain with actions for each step. 25 chains available covering feature dev, debugging, security, deployment, research, academic writing, CI/CD, multi-agent coordination, and more. Call with chain="list" to see all.',
|
|
181
192
|
inputSchema: {
|
|
182
193
|
type: "object",
|
|
183
194
|
properties: {
|
|
@@ -185,9 +196,15 @@ export function createProgressiveDiscoveryTools(allRegisteredTools) {
|
|
|
185
196
|
type: "string",
|
|
186
197
|
enum: [
|
|
187
198
|
"new_feature", "fix_bug", "ui_change", "parallel_project",
|
|
188
|
-
"research_phase", "academic_paper", "c_compiler_benchmark",
|
|
199
|
+
"research_phase", "academic_paper", "c_compiler_benchmark",
|
|
200
|
+
"security_audit", "code_review", "deployment", "migration",
|
|
201
|
+
"coordinator_spawn", "self_setup", "flicker_detection",
|
|
202
|
+
"figma_flow_analysis", "agent_eval", "contract_compliance",
|
|
203
|
+
"ablation_eval", "session_recovery", "attention_refresh",
|
|
204
|
+
"task_bank_setup", "pr_review", "seo_audit", "voice_pipeline",
|
|
205
|
+
"intentionality_check", "list",
|
|
189
206
|
],
|
|
190
|
-
description: 'Which workflow chain to retrieve. Use "list" to see all available chains.',
|
|
207
|
+
description: 'Which workflow chain to retrieve. Use "list" to see all available chains with descriptions.',
|
|
191
208
|
},
|
|
192
209
|
},
|
|
193
210
|
required: ["chain"],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progressiveDiscoveryTools.js","sourceRoot":"","sources":["../../src/tools/progressiveDiscoveryTools.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EACL,YAAY,EACZ,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,YAAY,GAGb,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"progressiveDiscoveryTools.js","sourceRoot":"","sources":["../../src/tools/progressiveDiscoveryTools.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/reconTools.js
CHANGED
|
@@ -465,45 +465,95 @@ export const reconTools = [
|
|
|
465
465
|
if (categories && categories.length > 0) {
|
|
466
466
|
learnings = learnings.filter((l) => categories.includes(l.category));
|
|
467
467
|
}
|
|
468
|
-
// 2. Search recon findings across ALL sessions
|
|
468
|
+
// 2. Search recon findings across ALL sessions via FTS5+BM25 (LIKE fallback)
|
|
469
469
|
let reconFindings;
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
470
|
+
try {
|
|
471
|
+
if (categories && categories.length > 0) {
|
|
472
|
+
const placeholders = categories.map(() => "?").join(", ");
|
|
473
|
+
reconFindings = db
|
|
474
|
+
.prepare(`SELECT f.id, f.session_id, f.source_url, f.category, f.summary,
|
|
475
|
+
f.relevance, f.action_items, f.created_at,
|
|
476
|
+
s.target as session_target
|
|
477
|
+
FROM recon_findings_fts fts
|
|
478
|
+
JOIN recon_findings f ON f.rowid = fts.rowid
|
|
479
|
+
JOIN recon_sessions s ON s.id = f.session_id
|
|
480
|
+
WHERE recon_findings_fts MATCH ?
|
|
481
|
+
AND f.category IN (${placeholders})
|
|
482
|
+
ORDER BY rank
|
|
483
|
+
LIMIT ?`)
|
|
484
|
+
.all(query, ...categories, limit);
|
|
485
|
+
}
|
|
486
|
+
else {
|
|
487
|
+
reconFindings = db
|
|
488
|
+
.prepare(`SELECT f.id, f.session_id, f.source_url, f.category, f.summary,
|
|
489
|
+
f.relevance, f.action_items, f.created_at,
|
|
490
|
+
s.target as session_target
|
|
491
|
+
FROM recon_findings_fts fts
|
|
492
|
+
JOIN recon_findings f ON f.rowid = fts.rowid
|
|
493
|
+
JOIN recon_sessions s ON s.id = f.session_id
|
|
494
|
+
WHERE recon_findings_fts MATCH ?
|
|
495
|
+
ORDER BY rank
|
|
496
|
+
LIMIT ?`)
|
|
497
|
+
.all(query, limit);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
catch {
|
|
501
|
+
// FTS5 syntax error — fall back to LIKE
|
|
502
|
+
if (categories && categories.length > 0) {
|
|
503
|
+
const placeholders = categories.map(() => "?").join(", ");
|
|
504
|
+
reconFindings = db
|
|
505
|
+
.prepare(`SELECT f.id, f.session_id, f.source_url, f.category, f.summary,
|
|
506
|
+
f.relevance, f.action_items, f.created_at,
|
|
507
|
+
s.target as session_target
|
|
508
|
+
FROM recon_findings f
|
|
509
|
+
JOIN recon_sessions s ON s.id = f.session_id
|
|
510
|
+
WHERE (f.summary LIKE ? OR f.relevance LIKE ? OR f.action_items LIKE ?)
|
|
511
|
+
AND f.category IN (${placeholders})
|
|
512
|
+
ORDER BY f.created_at DESC
|
|
513
|
+
LIMIT ?`)
|
|
514
|
+
.all(`%${query}%`, `%${query}%`, `%${query}%`, ...categories, limit);
|
|
515
|
+
}
|
|
516
|
+
else {
|
|
517
|
+
reconFindings = db
|
|
518
|
+
.prepare(`SELECT f.id, f.session_id, f.source_url, f.category, f.summary,
|
|
519
|
+
f.relevance, f.action_items, f.created_at,
|
|
520
|
+
s.target as session_target
|
|
521
|
+
FROM recon_findings f
|
|
522
|
+
JOIN recon_sessions s ON s.id = f.session_id
|
|
523
|
+
WHERE f.summary LIKE ? OR f.relevance LIKE ? OR f.action_items LIKE ?
|
|
524
|
+
ORDER BY f.created_at DESC
|
|
525
|
+
LIMIT ?`)
|
|
526
|
+
.all(`%${query}%`, `%${query}%`, `%${query}%`, limit);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
// 3. Search ALL gaps from past verification cycles via FTS5+BM25 (LIKE fallback)
|
|
530
|
+
let matchedGaps;
|
|
531
|
+
try {
|
|
532
|
+
matchedGaps = db
|
|
533
|
+
.prepare(`SELECT g.id, g.cycle_id, g.title, g.description, g.severity,
|
|
534
|
+
g.status, g.fix_strategy as resolution, g.resolved_at,
|
|
535
|
+
c.title as cycle_target
|
|
536
|
+
FROM gaps_fts fts
|
|
537
|
+
JOIN gaps g ON g.rowid = fts.rowid
|
|
538
|
+
JOIN verification_cycles c ON c.id = g.cycle_id
|
|
539
|
+
WHERE gaps_fts MATCH ?
|
|
540
|
+
ORDER BY rank
|
|
481
541
|
LIMIT ?`)
|
|
482
|
-
.all(
|
|
542
|
+
.all(query, limit);
|
|
483
543
|
}
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
544
|
+
catch {
|
|
545
|
+
// FTS5 syntax error — fall back to LIKE
|
|
546
|
+
matchedGaps = db
|
|
547
|
+
.prepare(`SELECT g.id, g.cycle_id, g.title, g.description, g.severity,
|
|
548
|
+
g.status, g.fix_strategy as resolution, g.resolved_at,
|
|
549
|
+
c.title as cycle_target
|
|
550
|
+
FROM gaps g
|
|
551
|
+
JOIN verification_cycles c ON c.id = g.cycle_id
|
|
552
|
+
WHERE (g.description LIKE ? OR g.fix_strategy LIKE ? OR g.title LIKE ?)
|
|
553
|
+
ORDER BY g.created_at DESC
|
|
493
554
|
LIMIT ?`)
|
|
494
555
|
.all(`%${query}%`, `%${query}%`, `%${query}%`, limit);
|
|
495
556
|
}
|
|
496
|
-
// 3. Search ALL gaps from past verification cycles (resolved + open)
|
|
497
|
-
const matchedGaps = db
|
|
498
|
-
.prepare(`SELECT g.id, g.cycle_id, g.title, g.description, g.severity,
|
|
499
|
-
g.status, g.fix_strategy as resolution, g.resolved_at,
|
|
500
|
-
c.title as cycle_target
|
|
501
|
-
FROM gaps g
|
|
502
|
-
JOIN verification_cycles c ON c.id = g.cycle_id
|
|
503
|
-
WHERE (g.description LIKE ? OR g.fix_strategy LIKE ? OR g.title LIKE ?)
|
|
504
|
-
ORDER BY g.created_at DESC
|
|
505
|
-
LIMIT ?`)
|
|
506
|
-
.all(`%${query}%`, `%${query}%`, `%${query}%`, limit);
|
|
507
557
|
const totalResults = learnings.length + reconFindings.length + matchedGaps.length;
|
|
508
558
|
return {
|
|
509
559
|
query,
|