n2-qln 3.4.2 → 4.1.1

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 +28 -0
  10. package/{lib → dist/lib}/embedding.js +45 -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 +206 -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 +144 -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 +103 -101
  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 +48 -0
  31. package/dist/lib/store.js +234 -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/package.json +11 -4
  49. package/.github/FUNDING.yml +0 -3
  50. package/docs/README.md +0 -2
  51. package/docs/architecture.png +0 -0
  52. package/index.js +0 -80
  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,23 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Registry = void 0;
1
4
  // QLN — L2 tool index (memory cache + SQLite persistence)
2
5
  // Tool CRUD, batch registration, embedding precomputation, usage tracking
3
- const { createToolEntry, buildSearchText } = require('./schema');
4
-
6
+ const schema_1 = require("./schema");
5
7
  /**
6
8
  * Tool registry — in-memory cache (Map) + SQLite persistence.
7
9
  * Designed for up to 1000 tools.
8
10
  */
9
11
  class Registry {
10
- /**
11
- * @param {import('./store').Store} store - SQLite store
12
- * @param {import('./embedding').Embedding} [embedding] - Embedding engine (optional)
13
- */
12
+ _store;
13
+ _embedding;
14
+ _cache;
14
15
  constructor(store, embedding = null) {
15
16
  this._store = store;
16
17
  this._embedding = embedding;
17
- /** @type {Map<string, object>} name → tool entry */
18
18
  this._cache = new Map();
19
19
  }
20
-
21
20
  /** Load all entries from SQLite into memory cache */
22
21
  load() {
23
22
  this._cache.clear();
@@ -26,16 +25,12 @@ class Registry {
26
25
  this._cache.set(row.name, this._rowToEntry(row));
27
26
  }
28
27
  }
29
-
30
28
  // ── CRUD ──
31
-
32
29
  /**
33
30
  * Register a tool (update if exists, preserve existing stats).
34
- * @param {object} raw - Raw tool data
35
- * @returns {object} Normalized tool entry
36
31
  */
37
32
  register(raw) {
38
- const entry = createToolEntry(raw);
33
+ const entry = (0, schema_1.createToolEntry)(raw);
39
34
  const existing = this._cache.get(entry.name);
40
35
  if (existing) {
41
36
  entry.usageCount = existing.usageCount || entry.usageCount;
@@ -44,128 +39,129 @@ class Registry {
44
39
  entry.embedding = existing.embedding;
45
40
  }
46
41
  }
47
- entry.searchText = buildSearchText(entry);
42
+ entry.searchText = (0, schema_1.buildSearchText)(entry);
48
43
  this._cache.set(entry.name, entry);
49
44
  this._store.upsert(entry);
50
45
  return entry;
51
46
  }
52
-
53
- /**
54
- * Batch register tools.
55
- * @param {object[]} tools
56
- * @returns {number} Number of registered tools
57
- */
47
+ /** Batch register tools (single disk write at the end). */
58
48
  registerBatch(tools) {
49
+ this._store.beginBatch();
59
50
  let count = 0;
60
- for (const raw of tools) {
61
- try { this.register(raw); count++; }
62
- catch { /* skip invalid */ }
51
+ try {
52
+ for (const raw of tools) {
53
+ try {
54
+ this.register(raw);
55
+ count++;
56
+ }
57
+ catch { /* skip invalid */ }
58
+ }
59
+ }
60
+ finally {
61
+ this._store.endBatch();
63
62
  }
64
63
  return count;
65
64
  }
66
-
67
- /**
68
- * Remove a tool.
69
- * @param {string} name
70
- * @returns {boolean}
71
- */
65
+ /** Remove a tool. */
72
66
  remove(name) {
73
67
  const had = this._cache.has(name);
74
68
  this._cache.delete(name);
75
- if (had) this._store.remove(name);
69
+ if (had)
70
+ this._store.remove(name);
76
71
  return had;
77
72
  }
78
-
79
- /**
80
- * Purge all tools by source (for re-sync).
81
- * @param {string} source
82
- * @returns {number} Number deleted
83
- */
73
+ /** Purge all tools by source (for re-sync). */
84
74
  purgeBySource(source) {
85
- let deleted = 0;
75
+ const toDelete = [];
86
76
  for (const [name, entry] of this._cache) {
87
- if (entry.source === source) {
88
- this._cache.delete(name);
89
- deleted++;
90
- }
77
+ if (entry.source === source)
78
+ toDelete.push(name);
91
79
  }
80
+ for (const name of toDelete)
81
+ this._cache.delete(name);
92
82
  this._store.purgeBySource(source);
93
- return deleted;
94
- }
95
-
96
- /** @param {string} name @returns {object|null} */
97
- get(name) { return this._cache.get(name) || null; }
98
-
99
- /** @returns {object[]} */
100
- getAll() { return Array.from(this._cache.values()); }
101
-
102
- /** @returns {number} */
103
- get size() { return this._cache.size; }
104
-
105
- /**
106
- * Remove all tools by provider name.
107
- * @param {string} providerName
108
- * @returns {number} Number of tools removed
109
- */
83
+ return toDelete.length;
84
+ }
85
+ get(name) {
86
+ return this._cache.get(name) || null;
87
+ }
88
+ getAll() {
89
+ return Array.from(this._cache.values());
90
+ }
91
+ get size() {
92
+ return this._cache.size;
93
+ }
94
+ /** Remove all tools by provider name. */
110
95
  removeByProvider(providerName) {
111
96
  const toRemove = [];
112
97
  for (const [name, entry] of this._cache) {
113
- if (entry.provider === providerName) toRemove.push(name);
98
+ if (entry.provider === providerName)
99
+ toRemove.push(name);
114
100
  }
115
101
  for (const name of toRemove) {
116
102
  this.remove(name);
117
103
  }
118
104
  return toRemove.length;
119
105
  }
120
-
121
106
  // ── Embeddings ──
122
-
123
- /**
124
- * Precompute embeddings for tools without one.
125
- * @returns {Promise<{embedded: number, skipped: number, failed: number}>}
126
- */
107
+ /** Precompute embeddings for tools without one (single disk write). */
127
108
  async precomputeEmbeddings() {
128
- if (!this._embedding) return { embedded: 0, skipped: 0, failed: 0 };
109
+ if (!this._embedding)
110
+ return { embedded: 0, skipped: 0, failed: 0 };
129
111
  const available = await this._embedding.isAvailable();
130
- if (!available) return { embedded: 0, skipped: 0, failed: 0 };
131
-
112
+ if (!available)
113
+ return { embedded: 0, skipped: 0, failed: 0 };
114
+ this._store.beginBatch();
132
115
  let embedded = 0, skipped = 0, failed = 0;
133
- for (const [, entry] of this._cache) {
134
- if (entry.embedding) { skipped++; continue; }
135
- try {
136
- const text = entry.searchText || buildSearchText(entry);
137
- const vec = await this._embedding.embed(text);
138
- if (vec.length > 0) {
139
- entry.embedding = vec;
140
- this._store.upsert(entry);
141
- embedded++;
142
- } else { failed++; }
143
- } catch { failed++; }
116
+ try {
117
+ for (const [, entry] of this._cache) {
118
+ if (entry.embedding) {
119
+ skipped++;
120
+ continue;
121
+ }
122
+ try {
123
+ const text = entry.searchText || (0, schema_1.buildSearchText)(entry);
124
+ const vec = await this._embedding.embed(text);
125
+ if (vec.length > 0) {
126
+ entry.embedding = vec;
127
+ this._store.upsert(entry);
128
+ embedded++;
129
+ }
130
+ else {
131
+ failed++;
132
+ }
133
+ }
134
+ catch {
135
+ failed++;
136
+ }
137
+ }
138
+ }
139
+ finally {
140
+ this._store.endBatch();
144
141
  }
145
142
  return { embedded, skipped, failed };
146
143
  }
147
-
148
144
  // ── Usage tracking ──
149
-
150
- /**
151
- * Record tool usage.
152
- * @param {string} name
153
- * @param {boolean} success
154
- */
145
+ /** Record tool usage + circuit breaker state. */
155
146
  recordUsage(name, success = true) {
156
147
  const entry = this._cache.get(name);
157
- if (!entry) return;
148
+ if (!entry)
149
+ return;
158
150
  entry.usageCount++;
159
151
  entry.lastUsedAt = new Date().toISOString();
160
152
  const alpha = 0.1;
161
153
  entry.successRate = entry.successRate * (1 - alpha) + (success ? 1 : 0) * alpha;
154
+ // Circuit breaker tracking
155
+ if (success) {
156
+ entry.consecutiveFailures = 0;
157
+ }
158
+ else {
159
+ entry.consecutiveFailures = (entry.consecutiveFailures || 0) + 1;
160
+ }
162
161
  entry.updatedAt = new Date().toISOString();
163
162
  this._store.upsert(entry);
164
163
  }
165
-
166
164
  // ── Stats ──
167
-
168
- /** @returns {object} */
169
165
  stats() {
170
166
  const bySource = {};
171
167
  const byCategory = {};
@@ -173,7 +169,8 @@ class Registry {
173
169
  for (const entry of this._cache.values()) {
174
170
  bySource[entry.source] = (bySource[entry.source] || 0) + 1;
175
171
  byCategory[entry.category] = (byCategory[entry.category] || 0) + 1;
176
- if (entry.embedding) withEmbedding++;
172
+ if (entry.embedding)
173
+ withEmbedding++;
177
174
  }
178
175
  return {
179
176
  total: this._cache.size,
@@ -184,13 +181,11 @@ class Registry {
184
181
  ? Math.round((withEmbedding / this._cache.size) * 100) + '%' : '0%',
185
182
  };
186
183
  }
187
-
188
184
  // ── Internal ──
189
-
190
185
  /** Convert SQLite row to tool entry */
191
186
  _rowToEntry(row) {
192
187
  return {
193
- name: row.name,
188
+ name: row.name || '',
194
189
  description: row.description || '',
195
190
  source: row.source || 'unknown',
196
191
  category: row.category || 'misc',
@@ -201,19 +196,26 @@ class Registry {
201
196
  examples: _parseJson(row.examples, []),
202
197
  endpoint: row.endpoint || '',
203
198
  searchText: row.search_text || '',
199
+ boostKeywords: row.boost_keywords || '',
204
200
  embedding: _parseJson(row.embedding, null),
205
201
  usageCount: row.usage_count || 0,
206
202
  successRate: row.success_rate ?? 1.0,
203
+ consecutiveFailures: row.consecutive_failures || 0,
207
204
  lastUsedAt: row.last_used_at || null,
208
- registeredAt: row.registered_at,
209
- updatedAt: row.updated_at,
205
+ registeredAt: row.registered_at || '',
206
+ updatedAt: row.updated_at || '',
210
207
  };
211
208
  }
212
209
  }
213
-
210
+ exports.Registry = Registry;
214
211
  function _parseJson(str, fallback) {
215
- if (!str || str === '') return fallback;
216
- try { return JSON.parse(str); } catch { return fallback; }
212
+ if (!str || str === '')
213
+ return fallback;
214
+ try {
215
+ return JSON.parse(str);
216
+ }
217
+ catch {
218
+ return fallback;
219
+ }
217
220
  }
218
-
219
- module.exports = { Registry };
221
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/lib/registry.ts"],"names":[],"mappings":";;;AAAA,0DAA0D;AAC1D,0EAA0E;AAC1E,qCAA4D;AAK5D;;;GAGG;AACH,MAAa,QAAQ;IACX,MAAM,CAAQ;IACd,UAAU,CAAmB;IAC7B,MAAM,CAAyB;IAEvC,YAAY,KAAY,EAAE,YAA8B,IAAI;QAC1D,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;IAC1B,CAAC;IAED,qDAAqD;IACrD,IAAI;QACF,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACpB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACnC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAc,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,aAAa;IAEb;;OAEG;IACH,QAAQ,CAAC,GAAiB;QACxB,MAAM,KAAK,GAAG,IAAA,wBAAe,EAAC,GAAG,CAAC,CAAC;QACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,QAAQ,EAAE,CAAC;YACb,KAAK,CAAC,UAAU,GAAG,QAAQ,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,CAAC;YAC3D,KAAK,CAAC,WAAW,GAAG,QAAQ,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW,CAAC;YAC9D,IAAI,QAAQ,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;gBAC3C,KAAK,CAAC,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC;YACvC,CAAC;QACH,CAAC;QACD,KAAK,CAAC,UAAU,GAAG,IAAA,wBAAe,EAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,2DAA2D;IAC3D,aAAa,CAAC,KAAqB;QACjC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;QACzB,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,CAAC;YACH,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;gBACxB,IAAI,CAAC;oBAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;oBAAC,KAAK,EAAE,CAAC;gBAAC,CAAC;gBACpC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QACzB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,qBAAqB;IACrB,MAAM,CAAC,IAAY;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACzB,IAAI,GAAG;YAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAClC,OAAO,GAAG,CAAC;IACb,CAAC;IAED,+CAA+C;IAC/C,aAAa,CAAC,MAAc;QAC1B,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACxC,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM;gBAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnD,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,QAAQ;YAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAClC,OAAO,QAAQ,CAAC,MAAM,CAAC;IACzB,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;IACvC,CAAC;IAED,MAAM;QACJ,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IAC1B,CAAC;IAED,yCAAyC;IACzC,gBAAgB,CAAC,YAAoB;QACnC,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACxC,IAAI,KAAK,CAAC,QAAQ,KAAK,YAAY;gBAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3D,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC5B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;QACD,OAAO,QAAQ,CAAC,MAAM,CAAC;IACzB,CAAC;IAED,mBAAmB;IAEnB,uEAAuE;IACvE,KAAK,CAAC,oBAAoB;QACxB,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QACpE,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC;QACtD,IAAI,CAAC,SAAS;YAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QAE9D,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;QACzB,IAAI,QAAQ,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC;QAC1C,IAAI,CAAC;YACH,KAAK,MAAM,CAAC,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBACpC,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;oBAAC,OAAO,EAAE,CAAC;oBAAC,SAAS;gBAAC,CAAC;gBAC7C,IAAI,CAAC;oBACH,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,IAAI,IAAA,wBAAe,EAAC,KAAK,CAAC,CAAC;oBACxD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC9C,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACnB,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC;wBACtB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;wBAC1B,QAAQ,EAAE,CAAC;oBACb,CAAC;yBAAM,CAAC;wBAAC,MAAM,EAAE,CAAC;oBAAC,CAAC;gBACtB,CAAC;gBAAC,MAAM,CAAC;oBAAC,MAAM,EAAE,CAAC;gBAAC,CAAC;YACvB,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QACzB,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IACvC,CAAC;IAED,uBAAuB;IAEvB,iDAAiD;IACjD,WAAW,CAAC,IAAY,EAAE,UAAmB,IAAI;QAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,KAAK,CAAC,UAAU,EAAE,CAAC;QACnB,KAAK,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC5C,MAAM,KAAK,GAAG,GAAG,CAAC;QAClB,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;QAChF,2BAA2B;QAC3B,IAAI,OAAO,EAAE,CAAC;YACZ,KAAK,CAAC,mBAAmB,GAAG,CAAC,CAAC;QAChC,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,mBAAmB,GAAG,CAAC,KAAK,CAAC,mBAAmB,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACnE,CAAC;QACD,KAAK,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAED,cAAc;IAEd,KAAK;QACH,MAAM,QAAQ,GAA2B,EAAE,CAAC;QAC5C,MAAM,UAAU,GAA2B,EAAE,CAAC;QAC9C,IAAI,aAAa,GAAG,CAAC,CAAC;QACtB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACzC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YAC3D,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACnE,IAAI,KAAK,CAAC,SAAS;gBAAE,aAAa,EAAE,CAAC;QACvC,CAAC;QACD,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;YACvB,QAAQ;YACR,UAAU;YACV,aAAa;YACb,iBAAiB,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC;gBACrC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI;SACtE,CAAC;IACJ,CAAC;IAED,iBAAiB;IAEjB,uCAAuC;IAC/B,WAAW,CAAC,GAA4B;QAC9C,OAAO;YACL,IAAI,EAAG,GAAG,CAAC,IAAe,IAAI,EAAE;YAChC,WAAW,EAAG,GAAG,CAAC,WAAsB,IAAI,EAAE;YAC9C,MAAM,EAAG,GAAG,CAAC,MAAiB,IAAI,SAAS;YAC3C,QAAQ,EAAG,GAAG,CAAC,QAAmB,IAAI,MAAM;YAC5C,QAAQ,EAAG,GAAG,CAAC,QAAmB,IAAK,GAAG,CAAC,WAAsB,IAAI,EAAE;YACvE,WAAW,EAAE,UAAU,CAAC,GAAG,CAAC,YAAsB,EAAE,IAAI,CAAC;YACzD,QAAQ,EAAE,UAAU,CAAC,GAAG,CAAC,QAAkB,EAAE,EAAE,CAAC;YAChD,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC,IAAc,EAAE,EAAE,CAAC;YACxC,QAAQ,EAAE,UAAU,CAAC,GAAG,CAAC,QAAkB,EAAE,EAAE,CAAC;YAChD,QAAQ,EAAG,GAAG,CAAC,QAAmB,IAAI,EAAE;YACxC,UAAU,EAAG,GAAG,CAAC,WAAsB,IAAI,EAAE;YAC7C,aAAa,EAAG,GAAG,CAAC,cAAyB,IAAI,EAAE;YACnD,SAAS,EAAE,UAAU,CAAC,GAAG,CAAC,SAAmB,EAAE,IAAI,CAAC;YACpD,UAAU,EAAG,GAAG,CAAC,WAAsB,IAAI,CAAC;YAC5C,WAAW,EAAG,GAAG,CAAC,YAAuB,IAAI,GAAG;YAChD,mBAAmB,EAAG,GAAG,CAAC,oBAA+B,IAAI,CAAC;YAC9D,UAAU,EAAG,GAAG,CAAC,YAAuB,IAAI,IAAI;YAChD,YAAY,EAAG,GAAG,CAAC,aAAwB,IAAI,EAAE;YACjD,SAAS,EAAG,GAAG,CAAC,UAAqB,IAAI,EAAE;SAC5C,CAAC;IACJ,CAAC;CACF;AAnMD,4BAmMC;AAED,SAAS,UAAU,CAAI,GAA8B,EAAE,QAAW;IAChE,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,EAAE;QAAE,OAAO,QAAQ,CAAC;IACxC,IAAI,CAAC;QAAC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAM,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,QAAQ,CAAC;IAAC,CAAC;AACjE,CAAC"}
@@ -0,0 +1,63 @@
1
+ import type { Registry } from './registry';
2
+ import type { VectorIndex } from './vector-index';
3
+ import type { Embedding } from './embedding';
4
+ import type { SearchResult, SearchTiming, RouterStats } from '../types';
5
+ /**
6
+ * 3-Stage search engine.
7
+ *
8
+ * Score formula:
9
+ * final = (trigger×3.0 + bm25_keyword×1.0 + semantic×2.0
10
+ * + log2(usageCount+1)×0.5 + successRate×1.0) × sourceWeight
11
+ */
12
+ export declare class Router {
13
+ private _registry;
14
+ private _vectorIndex;
15
+ private _embedding;
16
+ private _k1;
17
+ private _b;
18
+ private _idfCache;
19
+ private _avgDocLen;
20
+ private _idfDirty;
21
+ private _sourceWeights;
22
+ constructor(registry: Registry, vectorIndex: VectorIndex, embedding?: Embedding | null, sourceWeights?: Record<string, number>);
23
+ /**
24
+ * Route natural language query to tools.
25
+ */
26
+ route(query: string, options?: {
27
+ topK?: number;
28
+ threshold?: number;
29
+ }): Promise<{
30
+ results: SearchResult[];
31
+ timing: SearchTiming;
32
+ }>;
33
+ /** Stage 1: Trigger word exact match. Weight: 3.0 */
34
+ private _stage1TriggerMatch;
35
+ /** Stage 2: BM25 keyword search. Weight: 1.0 */
36
+ private _stage2BM25;
37
+ /** Calculate BM25 score for a query against a document. */
38
+ private _bm25Score;
39
+ /**
40
+ * Build IDF cache from all registered tools.
41
+ * IDF(term) = ln((N - n(t) + 0.5) / (n(t) + 0.5) + 1)
42
+ */
43
+ private _buildIDF;
44
+ /** Tokenize query string into search terms. */
45
+ private _tokenize;
46
+ /** Stage 3: Semantic vector search. Weight: 2.0 */
47
+ private _stage3SemanticSearch;
48
+ /** Merge all stage results + usage/success bonus + recency decay → ranking */
49
+ private _mergeAndRank;
50
+ /** 5% Explorer: append least-used tool as bonus slot (never replaces regular results) */
51
+ private _injectExplorer;
52
+ /** Build vector index and refresh IDF cache */
53
+ buildIndex(): {
54
+ indexed: number;
55
+ categories: number;
56
+ dimension: number;
57
+ };
58
+ /** Mark IDF cache as dirty (call after tool registration changes) */
59
+ invalidateIDF(): void;
60
+ private _getOrCreate;
61
+ stats(): RouterStats;
62
+ }
63
+ //# sourceMappingURL=router.d.ts.map