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.
- 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 +28 -0
- package/{lib → dist/lib}/embedding.js +45 -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 +206 -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 +144 -0
- package/dist/lib/provider-loader.js.map +1 -0
- package/dist/lib/registry.d.ts +38 -0
- package/{lib → dist/lib}/registry.js +103 -101
- 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 +48 -0
- package/dist/lib/store.js +234 -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/package.json +11 -4
- package/.github/FUNDING.yml +0 -3
- package/docs/README.md +0 -2
- package/docs/architecture.png +0 -0
- package/index.js +0 -80
- 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,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
|
|
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
|
-
|
|
12
|
-
|
|
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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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)
|
|
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
|
-
|
|
75
|
+
const toDelete = [];
|
|
86
76
|
for (const [name, entry] of this._cache) {
|
|
87
|
-
if (entry.source === source)
|
|
88
|
-
|
|
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
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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)
|
|
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)
|
|
109
|
+
if (!this._embedding)
|
|
110
|
+
return { embedded: 0, skipped: 0, failed: 0 };
|
|
129
111
|
const available = await this._embedding.isAvailable();
|
|
130
|
-
if (!available)
|
|
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
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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)
|
|
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)
|
|
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 === '')
|
|
216
|
-
|
|
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":"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"}
|
|
@@ -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
|