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.
Files changed (57) hide show
  1. package/README.ko.md +459 -470
  2. package/README.md +459 -490
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.js +87 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/lib/config.d.ts +9 -0
  7. package/{lib → dist/lib}/config.js +23 -27
  8. package/dist/lib/config.js.map +1 -0
  9. package/dist/lib/embedding.d.ts +27 -0
  10. package/{lib → dist/lib}/embedding.js +39 -47
  11. package/dist/lib/embedding.js.map +1 -0
  12. package/dist/lib/executor.d.ts +57 -0
  13. package/dist/lib/executor.js +175 -0
  14. package/dist/lib/executor.js.map +1 -0
  15. package/dist/lib/mcp-discovery.d.ts +83 -0
  16. package/dist/lib/mcp-discovery.js +203 -0
  17. package/dist/lib/mcp-discovery.js.map +1 -0
  18. package/dist/lib/provider-loader.d.ts +13 -0
  19. package/dist/lib/provider-loader.js +146 -0
  20. package/dist/lib/provider-loader.js.map +1 -0
  21. package/dist/lib/registry.d.ts +38 -0
  22. package/{lib → dist/lib}/registry.js +82 -92
  23. package/dist/lib/registry.js.map +1 -0
  24. package/dist/lib/router.d.ts +63 -0
  25. package/{lib → dist/lib}/router.js +75 -117
  26. package/dist/lib/router.js.map +1 -0
  27. package/dist/lib/schema.d.ts +20 -0
  28. package/{lib → dist/lib}/schema.js +38 -30
  29. package/dist/lib/schema.js.map +1 -0
  30. package/dist/lib/store.d.ts +37 -0
  31. package/dist/lib/store.js +207 -0
  32. package/dist/lib/store.js.map +1 -0
  33. package/dist/lib/validator.d.ts +37 -0
  34. package/dist/lib/validator.js +114 -0
  35. package/dist/lib/validator.js.map +1 -0
  36. package/dist/lib/vector-index.d.ts +37 -0
  37. package/{lib → dist/lib}/vector-index.js +19 -36
  38. package/dist/lib/vector-index.js.map +1 -0
  39. package/dist/tools/qln-call.d.ts +41 -0
  40. package/dist/tools/qln-call.js +353 -0
  41. package/dist/tools/qln-call.js.map +1 -0
  42. package/dist/tools/qln-helpers.d.ts +55 -0
  43. package/dist/tools/qln-helpers.js +88 -0
  44. package/dist/tools/qln-helpers.js.map +1 -0
  45. package/dist/types.d.ts +243 -0
  46. package/dist/types.js +4 -0
  47. package/dist/types.js.map +1 -0
  48. package/index.js +3 -79
  49. package/package.json +11 -4
  50. package/.github/FUNDING.yml +0 -3
  51. package/docs/README.md +0 -2
  52. package/docs/architecture.png +0 -0
  53. package/lib/executor.js +0 -104
  54. package/lib/provider-loader.js +0 -126
  55. package/lib/store.js +0 -217
  56. package/lib/validator.js +0 -171
  57. 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 { buildSearchText } = require('./schema');
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
- * @param {import('./registry').Registry} registry
15
- * @param {import('./vector-index').VectorIndex} vectorIndex
16
- * @param {import('./embedding').Embedding} [embedding]
17
- */
18
- constructor(registry, vectorIndex, embedding = null) {
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) this._buildIDF();
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))) hits++;
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) return;
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) return 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) continue;
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) return;
152
+ if (!this._embedding || !this._vectorIndex)
153
+ return;
188
154
  try {
189
155
  const available = await this._embedding.isAvailable();
190
- if (!available) return;
156
+ if (!available)
157
+ return;
191
158
  const queryVec = await this._embedding.embed(query);
192
- if (!queryVec || queryVec.length === 0) return;
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
- } catch { /* graceful degradation */ }
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) continue;
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 finalScore = (s.stage1 || 0) + (s.stage2 || 0) + (s.stage3 || 0)
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
- source: tool.source,
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)) scores.set(name, { stage1: 0, stage2: 0, stage3: 0 });
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
- module.exports = { Router };
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
- // QLN — Tool schema normalization + trigger extraction
2
- // Converts tools from various sources (MCP, plugins, local) into a standard format
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
- if (entry.triggers?.length > 0) parts.push(entry.triggers.join(' '));
45
- if (entry.tags?.length > 0) parts.push(entry.tags.join(' '));
46
- if (entry.examples?.length > 0) parts.push(entry.examples.join(' '));
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) triggers.push(...parts);
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)) triggers.push(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')) return 'capture';
87
- if (lower.includes('scroll') || lower.includes('tab') || lower.includes('read_page') || lower.includes('navigate')) return 'web';
88
- if (lower.includes('extract') || lower.includes('scrape') || lower.includes('parse')) return 'data';
89
- if (lower.includes('search') || lower.includes('ai') || lower.includes('query')) return 'ai';
90
- if (lower.includes('file') || lower.includes('write') || lower.includes('read')) return 'file';
91
- if (lower.includes('code') || lower.includes('compile') || lower.includes('lint')) return 'dev';
92
- if (source === 'mcp') return 'mcp';
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