n2-qln 3.4.2 → 4.1.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/README.ko.md +459 -470
- package/README.md +459 -490
- package/dist/index.d.ts +3 -0
- package/dist/index.js +87 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/config.d.ts +9 -0
- package/{lib → dist/lib}/config.js +23 -27
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/embedding.d.ts +27 -0
- package/{lib → dist/lib}/embedding.js +39 -47
- package/dist/lib/embedding.js.map +1 -0
- package/dist/lib/executor.d.ts +57 -0
- package/dist/lib/executor.js +175 -0
- package/dist/lib/executor.js.map +1 -0
- package/dist/lib/mcp-discovery.d.ts +83 -0
- package/dist/lib/mcp-discovery.js +203 -0
- package/dist/lib/mcp-discovery.js.map +1 -0
- package/dist/lib/provider-loader.d.ts +13 -0
- package/dist/lib/provider-loader.js +146 -0
- package/dist/lib/provider-loader.js.map +1 -0
- package/dist/lib/registry.d.ts +38 -0
- package/{lib → dist/lib}/registry.js +82 -92
- package/dist/lib/registry.js.map +1 -0
- package/dist/lib/router.d.ts +63 -0
- package/{lib → dist/lib}/router.js +75 -117
- package/dist/lib/router.js.map +1 -0
- package/dist/lib/schema.d.ts +20 -0
- package/{lib → dist/lib}/schema.js +38 -30
- package/dist/lib/schema.js.map +1 -0
- package/dist/lib/store.d.ts +37 -0
- package/dist/lib/store.js +207 -0
- package/dist/lib/store.js.map +1 -0
- package/dist/lib/validator.d.ts +37 -0
- package/dist/lib/validator.js +114 -0
- package/dist/lib/validator.js.map +1 -0
- package/dist/lib/vector-index.d.ts +37 -0
- package/{lib → dist/lib}/vector-index.js +19 -36
- package/dist/lib/vector-index.js.map +1 -0
- package/dist/tools/qln-call.d.ts +41 -0
- package/dist/tools/qln-call.js +353 -0
- package/dist/tools/qln-call.js.map +1 -0
- package/dist/tools/qln-helpers.d.ts +55 -0
- package/dist/tools/qln-helpers.js +88 -0
- package/dist/tools/qln-helpers.js.map +1 -0
- package/dist/types.d.ts +243 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/index.js +3 -79
- package/package.json +11 -4
- package/.github/FUNDING.yml +0 -3
- package/docs/README.md +0 -2
- package/docs/architecture.png +0 -0
- package/lib/executor.js +0 -104
- package/lib/provider-loader.js +0 -126
- package/lib/store.js +0 -217
- package/lib/validator.js +0 -171
- package/tools/qln-call.js +0 -257
|
@@ -1,40 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Router = void 0;
|
|
1
4
|
// QLN — L1 Router (3-Stage parallel search engine)
|
|
2
5
|
// Query → Stage1(Trigger) + Stage2(BM25 Keyword) + Stage3(Semantic) → Merge → Top-K
|
|
3
|
-
const
|
|
4
|
-
|
|
6
|
+
const schema_1 = require("./schema");
|
|
5
7
|
/**
|
|
6
8
|
* 3-Stage search engine.
|
|
7
9
|
*
|
|
8
10
|
* Score formula:
|
|
9
|
-
* final = trigger×3.0 + bm25_keyword×1.0 + semantic×2.0
|
|
10
|
-
* + log2(usageCount+1)×0.5 + successRate×1.0
|
|
11
|
+
* final = (trigger×3.0 + bm25_keyword×1.0 + semantic×2.0
|
|
12
|
+
* + log2(usageCount+1)×0.5 + successRate×1.0) × sourceWeight
|
|
11
13
|
*/
|
|
12
14
|
class Router {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
_registry;
|
|
16
|
+
_vectorIndex;
|
|
17
|
+
_embedding;
|
|
18
|
+
// BM25 parameters (standard Okapi BM25 defaults)
|
|
19
|
+
_k1 = 1.2;
|
|
20
|
+
_b = 0.75;
|
|
21
|
+
// IDF cache (rebuilt when tools change)
|
|
22
|
+
_idfCache = new Map();
|
|
23
|
+
_avgDocLen = 0;
|
|
24
|
+
_idfDirty = true;
|
|
25
|
+
// Source weights (per-source score multiplier)
|
|
26
|
+
_sourceWeights;
|
|
27
|
+
constructor(registry, vectorIndex, embedding = null, sourceWeights = {}) {
|
|
19
28
|
this._registry = registry;
|
|
20
29
|
this._vectorIndex = vectorIndex;
|
|
21
30
|
this._embedding = embedding;
|
|
22
|
-
|
|
23
|
-
// BM25 parameters (standard Okapi BM25 defaults)
|
|
24
|
-
this._k1 = 1.2; // Term frequency saturation
|
|
25
|
-
this._b = 0.75; // Document length normalization
|
|
26
|
-
|
|
27
|
-
// IDF cache (rebuilt when tools change)
|
|
28
|
-
this._idfCache = new Map();
|
|
29
|
-
this._avgDocLen = 0;
|
|
30
|
-
this._idfDirty = true;
|
|
31
|
+
this._sourceWeights = sourceWeights;
|
|
31
32
|
}
|
|
32
|
-
|
|
33
33
|
/**
|
|
34
34
|
* Route natural language query to tools.
|
|
35
|
-
* @param {string} query - Natural language (e.g. "take a screenshot")
|
|
36
|
-
* @param {{topK?: number, threshold?: number}} [options]
|
|
37
|
-
* @returns {Promise<{results: object[], timing: object}>}
|
|
38
35
|
*/
|
|
39
36
|
async route(query, options = {}) {
|
|
40
37
|
const topK = options.topK || 5;
|
|
@@ -42,34 +39,28 @@ class Router {
|
|
|
42
39
|
const scores = new Map();
|
|
43
40
|
const timing = { stage1: 0, stage2: 0, stage3: 0, merge: 0, total: 0 };
|
|
44
41
|
const t0 = Date.now();
|
|
45
|
-
|
|
46
42
|
// Rebuild IDF if registry changed
|
|
47
|
-
if (this._idfDirty)
|
|
48
|
-
|
|
43
|
+
if (this._idfDirty)
|
|
44
|
+
this._buildIDF();
|
|
49
45
|
// Stage 1: Trigger exact match (fastest)
|
|
50
46
|
const t1 = Date.now();
|
|
51
47
|
this._stage1TriggerMatch(query, scores);
|
|
52
48
|
timing.stage1 = Date.now() - t1;
|
|
53
|
-
|
|
54
49
|
// Stage 2: BM25 keyword search
|
|
55
50
|
const t2 = Date.now();
|
|
56
51
|
this._stage2BM25(query, scores);
|
|
57
52
|
timing.stage2 = Date.now() - t2;
|
|
58
|
-
|
|
59
53
|
// Stage 3: Semantic vector search (when embedding available)
|
|
60
54
|
const t3 = Date.now();
|
|
61
55
|
await this._stage3SemanticSearch(query, scores);
|
|
62
56
|
timing.stage3 = Date.now() - t3;
|
|
63
|
-
|
|
64
57
|
// Merge: Calculate final scores
|
|
65
58
|
const t4 = Date.now();
|
|
66
59
|
const results = this._mergeAndRank(scores, topK, threshold);
|
|
67
60
|
timing.merge = Date.now() - t4;
|
|
68
61
|
timing.total = Date.now() - t0;
|
|
69
|
-
|
|
70
62
|
return { results, timing };
|
|
71
63
|
}
|
|
72
|
-
|
|
73
64
|
/** Stage 1: Trigger word exact match. Weight: 3.0 */
|
|
74
65
|
_stage1TriggerMatch(query, scores) {
|
|
75
66
|
const queryWords = query.toLowerCase().split(/\s+/).filter(w => w.length > 1);
|
|
@@ -77,64 +68,54 @@ class Router {
|
|
|
77
68
|
const triggers = tool.triggers || [];
|
|
78
69
|
let hits = 0;
|
|
79
70
|
for (const word of queryWords) {
|
|
80
|
-
if (triggers.some(t => t === word || t.includes(word)))
|
|
71
|
+
if (triggers.some(t => t === word || t.includes(word)))
|
|
72
|
+
hits++;
|
|
81
73
|
}
|
|
82
74
|
if (hits > 0) {
|
|
83
75
|
this._getOrCreate(scores, tool.name).stage1 = hits * 3.0;
|
|
84
76
|
}
|
|
85
77
|
}
|
|
86
78
|
}
|
|
87
|
-
|
|
88
79
|
/** Stage 2: BM25 keyword search. Weight: 1.0 */
|
|
89
80
|
_stage2BM25(query, scores) {
|
|
90
81
|
const queryTerms = this._tokenize(query);
|
|
91
|
-
if (queryTerms.length === 0)
|
|
92
|
-
|
|
82
|
+
if (queryTerms.length === 0)
|
|
83
|
+
return;
|
|
93
84
|
for (const tool of this._registry.getAll()) {
|
|
94
|
-
const text = (tool.searchText || buildSearchText(tool)).toLowerCase();
|
|
85
|
+
const text = (tool.searchText || (0, schema_1.buildSearchText)(tool)).toLowerCase();
|
|
95
86
|
const bm25 = this._bm25Score(queryTerms, text);
|
|
96
87
|
if (bm25 > 0) {
|
|
97
88
|
this._getOrCreate(scores, tool.name).stage2 = bm25 * 1.0;
|
|
98
89
|
}
|
|
99
90
|
}
|
|
100
91
|
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Calculate BM25 score for a query against a document.
|
|
104
|
-
* @param {string[]} queryTerms - Tokenized query terms
|
|
105
|
-
* @param {string} docText - Document text (lowercased)
|
|
106
|
-
* @returns {number} BM25 score
|
|
107
|
-
*/
|
|
92
|
+
/** Calculate BM25 score for a query against a document. */
|
|
108
93
|
_bm25Score(queryTerms, docText) {
|
|
109
94
|
const docTerms = docText.split(/[\s_\-./]+/).filter(w => w.length > 1);
|
|
110
95
|
const docLen = docTerms.length;
|
|
111
|
-
if (docLen === 0)
|
|
112
|
-
|
|
96
|
+
if (docLen === 0)
|
|
97
|
+
return 0;
|
|
113
98
|
// Build term frequency map for this document
|
|
114
99
|
const tf = new Map();
|
|
115
100
|
for (const term of docTerms) {
|
|
116
101
|
tf.set(term, (tf.get(term) || 0) + 1);
|
|
117
102
|
}
|
|
118
|
-
|
|
119
103
|
let score = 0;
|
|
120
104
|
for (const term of queryTerms) {
|
|
121
105
|
const idf = this._idfCache.get(term) || 0;
|
|
122
106
|
const freq = tf.get(term) || 0;
|
|
123
|
-
if (freq === 0)
|
|
124
|
-
|
|
107
|
+
if (freq === 0)
|
|
108
|
+
continue;
|
|
125
109
|
// BM25 formula: IDF × (f × (k1+1)) / (f + k1 × (1 - b + b × |d|/avgDL))
|
|
126
110
|
const numerator = freq * (this._k1 + 1);
|
|
127
111
|
const denominator = freq + this._k1 * (1 - this._b + this._b * (docLen / this._avgDocLen));
|
|
128
112
|
score += idf * (numerator / denominator);
|
|
129
113
|
}
|
|
130
|
-
|
|
131
114
|
return score;
|
|
132
115
|
}
|
|
133
|
-
|
|
134
116
|
/**
|
|
135
117
|
* Build IDF cache from all registered tools.
|
|
136
118
|
* IDF(term) = ln((N - n(t) + 0.5) / (n(t) + 0.5) + 1)
|
|
137
|
-
* where N = total docs, n(t) = docs containing term
|
|
138
119
|
*/
|
|
139
120
|
_buildIDF() {
|
|
140
121
|
const tools = this._registry.getAll();
|
|
@@ -143,141 +124,119 @@ class Router {
|
|
|
143
124
|
this._idfDirty = false;
|
|
144
125
|
return;
|
|
145
126
|
}
|
|
146
|
-
|
|
147
|
-
// Tokenize all documents and count document frequencies
|
|
148
127
|
const docFreq = new Map();
|
|
149
128
|
let totalLen = 0;
|
|
150
|
-
|
|
151
129
|
for (const tool of tools) {
|
|
152
|
-
const text = (tool.searchText || buildSearchText(tool)).toLowerCase();
|
|
130
|
+
const text = (tool.searchText || (0, schema_1.buildSearchText)(tool)).toLowerCase();
|
|
153
131
|
const terms = text.split(/[\s_\-./]+/).filter(w => w.length > 1);
|
|
154
132
|
totalLen += terms.length;
|
|
155
|
-
|
|
156
|
-
// Unique terms per document
|
|
157
133
|
const uniqueTerms = new Set(terms);
|
|
158
134
|
for (const term of uniqueTerms) {
|
|
159
135
|
docFreq.set(term, (docFreq.get(term) || 0) + 1);
|
|
160
136
|
}
|
|
161
137
|
}
|
|
162
|
-
|
|
163
138
|
this._avgDocLen = totalLen / N;
|
|
164
|
-
|
|
165
|
-
// Calculate IDF for each term
|
|
166
139
|
this._idfCache.clear();
|
|
167
140
|
for (const [term, df] of docFreq) {
|
|
168
|
-
// BM25 IDF: ln((N - df + 0.5) / (df + 0.5) + 1)
|
|
169
141
|
const idf = Math.log((N - df + 0.5) / (df + 0.5) + 1);
|
|
170
142
|
this._idfCache.set(term, idf);
|
|
171
143
|
}
|
|
172
|
-
|
|
173
144
|
this._idfDirty = false;
|
|
174
145
|
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Tokenize query string into search terms.
|
|
178
|
-
* @param {string} query
|
|
179
|
-
* @returns {string[]}
|
|
180
|
-
*/
|
|
146
|
+
/** Tokenize query string into search terms. */
|
|
181
147
|
_tokenize(query) {
|
|
182
148
|
return query.toLowerCase().split(/[\s_\-./]+/).filter(w => w.length > 2);
|
|
183
149
|
}
|
|
184
|
-
|
|
185
150
|
/** Stage 3: Semantic vector search. Weight: 2.0 */
|
|
186
151
|
async _stage3SemanticSearch(query, scores) {
|
|
187
|
-
if (!this._embedding || !this._vectorIndex)
|
|
152
|
+
if (!this._embedding || !this._vectorIndex)
|
|
153
|
+
return;
|
|
188
154
|
try {
|
|
189
155
|
const available = await this._embedding.isAvailable();
|
|
190
|
-
if (!available)
|
|
156
|
+
if (!available)
|
|
157
|
+
return;
|
|
191
158
|
const queryVec = await this._embedding.embed(query);
|
|
192
|
-
if (!queryVec || queryVec.length === 0)
|
|
159
|
+
if (!queryVec || queryVec.length === 0)
|
|
160
|
+
return;
|
|
193
161
|
const semanticResults = this._vectorIndex.search(queryVec, 20);
|
|
194
162
|
for (const r of semanticResults) {
|
|
195
163
|
this._getOrCreate(scores, r.name).stage3 = r.score * 2.0;
|
|
196
164
|
}
|
|
197
|
-
}
|
|
165
|
+
}
|
|
166
|
+
catch { /* graceful degradation */ }
|
|
198
167
|
}
|
|
199
|
-
|
|
200
168
|
/** Merge all stage results + usage/success bonus + recency decay → ranking */
|
|
201
169
|
_mergeAndRank(scores, topK, threshold) {
|
|
202
170
|
const results = [];
|
|
203
171
|
for (const [name, s] of scores) {
|
|
204
172
|
const tool = this._registry.get(name);
|
|
205
|
-
if (!tool)
|
|
206
|
-
|
|
173
|
+
if (!tool)
|
|
174
|
+
continue;
|
|
207
175
|
// Recency Decay: usage bonus fades over 30-day half-life
|
|
208
176
|
const daysSinceUse = tool.lastUsedAt
|
|
209
177
|
? (Date.now() - new Date(tool.lastUsedAt).getTime()) / 86400000
|
|
210
178
|
: 0;
|
|
211
179
|
const recencyFactor = tool.lastUsedAt ? Math.exp(-daysSinceUse / 30) : 1.0;
|
|
212
180
|
const usageBonus = Math.log2((tool.usageCount || 0) + 1) * 0.5 * recencyFactor;
|
|
213
|
-
|
|
214
181
|
const successBonus = (tool.successRate ?? 1.0) * 1.0;
|
|
215
|
-
const
|
|
182
|
+
const rawScore = (s.stage1 || 0) + (s.stage2 || 0) + (s.stage3 || 0)
|
|
216
183
|
+ usageBonus + successBonus;
|
|
184
|
+
// Apply source weight multiplier (default: 1.0)
|
|
185
|
+
const sourceWeight = this._sourceWeights[tool.source] ?? 1.0;
|
|
186
|
+
const finalScore = rawScore * sourceWeight;
|
|
217
187
|
if (finalScore >= threshold) {
|
|
218
188
|
results.push({
|
|
219
189
|
name,
|
|
220
190
|
score: Math.round(finalScore * 100) / 100,
|
|
221
191
|
stages: {
|
|
222
|
-
trigger: s.stage1 || 0,
|
|
223
|
-
keyword: s.stage2 || 0,
|
|
224
|
-
semantic: s.stage3 || 0,
|
|
192
|
+
trigger: s.stage1 || 0, keyword: s.stage2 || 0, semantic: s.stage3 || 0,
|
|
225
193
|
usage: Math.round(usageBonus * 100) / 100,
|
|
226
194
|
success: Math.round(successBonus * 100) / 100,
|
|
227
195
|
recencyFactor: Math.round(recencyFactor * 1000) / 1000,
|
|
228
196
|
},
|
|
229
|
-
description: tool.description,
|
|
230
|
-
|
|
231
|
-
category: tool.category,
|
|
232
|
-
inputSchema: tool.inputSchema,
|
|
197
|
+
description: tool.description, source: tool.source,
|
|
198
|
+
category: tool.category, inputSchema: tool.inputSchema,
|
|
233
199
|
});
|
|
234
200
|
}
|
|
235
201
|
}
|
|
236
202
|
results.sort((a, b) => b.score - a.score);
|
|
237
203
|
const ranked = results.slice(0, topK);
|
|
238
|
-
|
|
239
|
-
// 5% Explorer: inject least-used tool into last slot
|
|
240
|
-
if (ranked.length >= topK && topK >= 2) {
|
|
241
|
-
const resultNames = new Set(ranked.map(r => r.name));
|
|
242
|
-
const allTools = this._registry.getAll()
|
|
243
|
-
.filter(t => !resultNames.has(t.name))
|
|
244
|
-
.sort((a, b) => (a.usageCount || 0) - (b.usageCount || 0));
|
|
245
|
-
if (allTools.length > 0) {
|
|
246
|
-
const explorer = allTools[0];
|
|
247
|
-
ranked[ranked.length - 1] = {
|
|
248
|
-
name: explorer.name,
|
|
249
|
-
score: 0,
|
|
250
|
-
stages: { trigger: 0, keyword: 0, semantic: 0, usage: 0, success: 0, recencyFactor: 0 },
|
|
251
|
-
description: explorer.description,
|
|
252
|
-
source: explorer.source,
|
|
253
|
-
category: explorer.category,
|
|
254
|
-
inputSchema: explorer.inputSchema,
|
|
255
|
-
explorer: true,
|
|
256
|
-
};
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
204
|
+
this._injectExplorer(ranked);
|
|
260
205
|
return ranked;
|
|
261
206
|
}
|
|
262
|
-
|
|
207
|
+
/** 5% Explorer: append least-used tool as bonus slot (never replaces regular results) */
|
|
208
|
+
_injectExplorer(ranked) {
|
|
209
|
+
if (ranked.length < 2 || Math.random() >= 0.05)
|
|
210
|
+
return;
|
|
211
|
+
const resultNames = new Set(ranked.map(r => r.name));
|
|
212
|
+
const allTools = this._registry.getAll()
|
|
213
|
+
.filter(t => !resultNames.has(t.name))
|
|
214
|
+
.sort((a, b) => (a.usageCount || 0) - (b.usageCount || 0));
|
|
215
|
+
if (allTools.length > 0) {
|
|
216
|
+
const explorer = allTools[0];
|
|
217
|
+
ranked.push({
|
|
218
|
+
name: explorer.name, score: 0,
|
|
219
|
+
stages: { trigger: 0, keyword: 0, semantic: 0, usage: 0, success: 0, recencyFactor: 0 },
|
|
220
|
+
description: explorer.description, source: explorer.source,
|
|
221
|
+
category: explorer.category, inputSchema: explorer.inputSchema,
|
|
222
|
+
explorer: true,
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
}
|
|
263
226
|
/** Build vector index and refresh IDF cache */
|
|
264
227
|
buildIndex() {
|
|
265
228
|
this._idfDirty = true;
|
|
266
229
|
return this._vectorIndex.build(this._registry.getAll());
|
|
267
230
|
}
|
|
268
|
-
|
|
269
231
|
/** Mark IDF cache as dirty (call after tool registration changes) */
|
|
270
232
|
invalidateIDF() {
|
|
271
233
|
this._idfDirty = true;
|
|
272
234
|
}
|
|
273
|
-
|
|
274
|
-
/** @private */
|
|
275
235
|
_getOrCreate(scores, name) {
|
|
276
|
-
if (!scores.has(name))
|
|
236
|
+
if (!scores.has(name))
|
|
237
|
+
scores.set(name, { stage1: 0, stage2: 0, stage3: 0 });
|
|
277
238
|
return scores.get(name);
|
|
278
239
|
}
|
|
279
|
-
|
|
280
|
-
/** @returns {object} */
|
|
281
240
|
stats() {
|
|
282
241
|
return {
|
|
283
242
|
registrySize: this._registry.size,
|
|
@@ -292,6 +251,5 @@ class Router {
|
|
|
292
251
|
};
|
|
293
252
|
}
|
|
294
253
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
254
|
+
exports.Router = Router;
|
|
255
|
+
//# sourceMappingURL=router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/lib/router.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ToolEntry, RawToolEntry } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Convert raw tool data to a normalized entry.
|
|
4
|
+
*/
|
|
5
|
+
export declare function createToolEntry(raw: RawToolEntry): ToolEntry;
|
|
6
|
+
/**
|
|
7
|
+
* Build searchable text from tool entry.
|
|
8
|
+
* Used by Stage 2 (keyword matching) and Stage 3 (embedding generation).
|
|
9
|
+
*/
|
|
10
|
+
export declare function buildSearchText(entry: ToolEntry): string;
|
|
11
|
+
/**
|
|
12
|
+
* Auto-extract trigger words from tool name/description.
|
|
13
|
+
* Used by Stage 1 (exact matching).
|
|
14
|
+
*/
|
|
15
|
+
export declare function extractTriggers(name: string, description?: string, tags?: string[]): string[];
|
|
16
|
+
/**
|
|
17
|
+
* Infer category from tool name/source.
|
|
18
|
+
*/
|
|
19
|
+
export declare function inferCategory(name: string, source?: string): string;
|
|
20
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createToolEntry = createToolEntry;
|
|
4
|
+
exports.buildSearchText = buildSearchText;
|
|
5
|
+
exports.extractTriggers = extractTriggers;
|
|
6
|
+
exports.inferCategory = inferCategory;
|
|
4
7
|
/**
|
|
5
8
|
* Convert raw tool data to a normalized entry.
|
|
6
|
-
* @param {object} raw - Raw tool data
|
|
7
|
-
* @returns {object} Normalized tool entry
|
|
8
9
|
*/
|
|
9
10
|
function createToolEntry(raw) {
|
|
10
11
|
return {
|
|
@@ -19,20 +20,19 @@ function createToolEntry(raw) {
|
|
|
19
20
|
examples: raw.examples || [],
|
|
20
21
|
endpoint: raw.endpoint || '',
|
|
21
22
|
searchText: '',
|
|
23
|
+
boostKeywords: raw.boostKeywords || '',
|
|
22
24
|
usageCount: raw.usageCount || 0,
|
|
23
25
|
successRate: typeof raw.successRate === 'number' ? raw.successRate : 1.0,
|
|
26
|
+
consecutiveFailures: 0,
|
|
24
27
|
lastUsedAt: raw.lastUsedAt || null,
|
|
25
28
|
embedding: raw.embedding || null,
|
|
26
29
|
registeredAt: raw.registeredAt || new Date().toISOString(),
|
|
27
30
|
updatedAt: new Date().toISOString(),
|
|
28
31
|
};
|
|
29
32
|
}
|
|
30
|
-
|
|
31
33
|
/**
|
|
32
34
|
* Build searchable text from tool entry.
|
|
33
35
|
* Used by Stage 2 (keyword matching) and Stage 3 (embedding generation).
|
|
34
|
-
* @param {object} entry - Normalized tool entry
|
|
35
|
-
* @returns {string}
|
|
36
36
|
*/
|
|
37
37
|
function buildSearchText(entry) {
|
|
38
38
|
const parts = [
|
|
@@ -41,25 +41,30 @@ function buildSearchText(entry) {
|
|
|
41
41
|
entry.category,
|
|
42
42
|
entry.provider,
|
|
43
43
|
];
|
|
44
|
-
|
|
45
|
-
if (entry.
|
|
46
|
-
|
|
44
|
+
// boostKeywords gets double weight — it's a curated capability phrase
|
|
45
|
+
if (entry.boostKeywords) {
|
|
46
|
+
parts.push(entry.boostKeywords);
|
|
47
|
+
parts.push(entry.boostKeywords); // intentional duplication for BM25 term frequency boost
|
|
48
|
+
}
|
|
49
|
+
if (entry.triggers?.length > 0)
|
|
50
|
+
parts.push(entry.triggers.join(' '));
|
|
51
|
+
if (entry.tags?.length > 0)
|
|
52
|
+
parts.push(entry.tags.join(' '));
|
|
53
|
+
if (entry.examples?.length > 0)
|
|
54
|
+
parts.push(entry.examples.join(' '));
|
|
47
55
|
return parts.filter(Boolean).join(' ').toLowerCase();
|
|
48
56
|
}
|
|
49
|
-
|
|
50
57
|
/**
|
|
51
58
|
* Auto-extract trigger words from tool name/description.
|
|
52
59
|
* Used by Stage 1 (exact matching).
|
|
53
|
-
* @param {string} name - Tool name (e.g. 'read_page')
|
|
54
|
-
* @param {string} description - Tool description
|
|
55
|
-
* @returns {string[]} Trigger word array
|
|
56
60
|
*/
|
|
57
61
|
function extractTriggers(name, description = '', tags = []) {
|
|
58
62
|
const triggers = [];
|
|
59
63
|
if (name) {
|
|
60
64
|
triggers.push(name);
|
|
61
65
|
const parts = name.split(/[_\-\.]/);
|
|
62
|
-
if (parts.length > 1)
|
|
66
|
+
if (parts.length > 1)
|
|
67
|
+
triggers.push(...parts);
|
|
63
68
|
}
|
|
64
69
|
if (description) {
|
|
65
70
|
const firstWord = description.trim().split(/\s+/)[0]?.toLowerCase();
|
|
@@ -69,28 +74,31 @@ function extractTriggers(name, description = '', tags = []) {
|
|
|
69
74
|
}
|
|
70
75
|
if (tags && tags.length > 0) {
|
|
71
76
|
for (const tag of tags) {
|
|
72
|
-
if (tag.length > 2 && !triggers.includes(tag))
|
|
77
|
+
if (tag.length > 2 && !triggers.includes(tag))
|
|
78
|
+
triggers.push(tag);
|
|
73
79
|
}
|
|
74
80
|
}
|
|
75
81
|
return [...new Set(triggers.filter(t => t.length > 1))];
|
|
76
82
|
}
|
|
77
|
-
|
|
78
83
|
/**
|
|
79
84
|
* Infer category from tool name/source.
|
|
80
|
-
* @param {string} name - Tool name
|
|
81
|
-
* @param {string} source - Source ('mcp', 'plugin', 'local')
|
|
82
|
-
* @returns {string} Category
|
|
83
85
|
*/
|
|
84
86
|
function inferCategory(name, source = 'unknown') {
|
|
85
87
|
const lower = (name || '').toLowerCase();
|
|
86
|
-
if (lower.includes('screenshot') || lower.includes('capture') || lower.includes('record'))
|
|
87
|
-
|
|
88
|
-
if (lower.includes('
|
|
89
|
-
|
|
90
|
-
if (lower.includes('
|
|
91
|
-
|
|
92
|
-
if (
|
|
88
|
+
if (lower.includes('screenshot') || lower.includes('capture') || lower.includes('record'))
|
|
89
|
+
return 'capture';
|
|
90
|
+
if (lower.includes('scroll') || lower.includes('tab') || lower.includes('read_page') || lower.includes('navigate'))
|
|
91
|
+
return 'web';
|
|
92
|
+
if (lower.includes('extract') || lower.includes('scrape') || lower.includes('parse'))
|
|
93
|
+
return 'data';
|
|
94
|
+
if (lower.includes('search') || lower.includes('ai') || lower.includes('query'))
|
|
95
|
+
return 'ai';
|
|
96
|
+
if (lower.includes('file') || lower.includes('write') || lower.includes('read'))
|
|
97
|
+
return 'file';
|
|
98
|
+
if (lower.includes('code') || lower.includes('compile') || lower.includes('lint'))
|
|
99
|
+
return 'dev';
|
|
100
|
+
if (source === 'mcp')
|
|
101
|
+
return 'mcp';
|
|
93
102
|
return 'misc';
|
|
94
103
|
}
|
|
95
|
-
|
|
96
|
-
module.exports = { createToolEntry, buildSearchText, extractTriggers, inferCategory };
|
|
104
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/lib/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { ToolEntry, SqlJsStatic } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Initialize sql.js WASM module (once per process).
|
|
4
|
+
*/
|
|
5
|
+
declare function initSqlJs(): Promise<SqlJsStatic>;
|
|
6
|
+
/**
|
|
7
|
+
* QLN SQLite store.
|
|
8
|
+
* Dedicated tool index DB — separated from Soul KV-Cache.
|
|
9
|
+
*
|
|
10
|
+
* File: {dataDir}/qln-tools.sqlite
|
|
11
|
+
*/
|
|
12
|
+
export declare class Store {
|
|
13
|
+
private _dataDir;
|
|
14
|
+
private _db;
|
|
15
|
+
private _dbPath;
|
|
16
|
+
constructor(dataDir: string);
|
|
17
|
+
/** Async init — load sql.js + open DB + create schema */
|
|
18
|
+
init(): Promise<void>;
|
|
19
|
+
/** Create tools + providers table schema */
|
|
20
|
+
private _createSchema;
|
|
21
|
+
/** Schema migration — safe ADD COLUMN (ignores if already exists) */
|
|
22
|
+
private _migrateSchema;
|
|
23
|
+
/** Upsert a tool entry. */
|
|
24
|
+
upsert(entry: ToolEntry): void;
|
|
25
|
+
/** Remove a tool by name. */
|
|
26
|
+
remove(name: string): boolean;
|
|
27
|
+
/** Purge all tools by source (for re-sync). */
|
|
28
|
+
purgeBySource(source: string): void;
|
|
29
|
+
/** Load all tools from DB. */
|
|
30
|
+
loadAll(): Record<string, unknown>[];
|
|
31
|
+
/** Persist DB to disk */
|
|
32
|
+
private _persist;
|
|
33
|
+
/** Close connection */
|
|
34
|
+
dispose(): void;
|
|
35
|
+
}
|
|
36
|
+
export { initSqlJs };
|
|
37
|
+
//# sourceMappingURL=store.d.ts.map
|