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
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
2
|
+
import type { Registry } from './registry';
|
|
3
|
+
import type { Router } from './router';
|
|
4
|
+
/** MCP server connection config */
|
|
5
|
+
export interface McpServerConfig {
|
|
6
|
+
/** Unique name for this server */
|
|
7
|
+
name: string;
|
|
8
|
+
/** Command to launch the server (e.g., 'node', 'python') */
|
|
9
|
+
command: string;
|
|
10
|
+
/** Arguments for the command */
|
|
11
|
+
args: string[];
|
|
12
|
+
/** Environment variables */
|
|
13
|
+
env?: Record<string, string>;
|
|
14
|
+
/** Working directory */
|
|
15
|
+
cwd?: string;
|
|
16
|
+
}
|
|
17
|
+
/** Discovery result for a single server */
|
|
18
|
+
export interface DiscoveryResult {
|
|
19
|
+
server: string;
|
|
20
|
+
status: 'success' | 'failed' | 'timeout';
|
|
21
|
+
toolCount: number;
|
|
22
|
+
tools: string[];
|
|
23
|
+
error?: string;
|
|
24
|
+
elapsed: number;
|
|
25
|
+
}
|
|
26
|
+
/** Full auto-discovery result */
|
|
27
|
+
export interface AutoDiscoveryResult {
|
|
28
|
+
total: number;
|
|
29
|
+
registered: number;
|
|
30
|
+
servers: DiscoveryResult[];
|
|
31
|
+
elapsed: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* MCP Auto-Discovery engine.
|
|
35
|
+
*
|
|
36
|
+
* Connects to external MCP servers, lists their tools,
|
|
37
|
+
* and registers them in the QLN index for semantic routing.
|
|
38
|
+
*
|
|
39
|
+
* Usage:
|
|
40
|
+
* const discovery = new McpDiscovery(registry, router);
|
|
41
|
+
* const result = await discovery.discoverAll(serverConfigs);
|
|
42
|
+
*/
|
|
43
|
+
export declare class McpDiscovery {
|
|
44
|
+
private _registry;
|
|
45
|
+
private _router;
|
|
46
|
+
private _timeout;
|
|
47
|
+
/** Active MCP client connections (for live proxy execution) */
|
|
48
|
+
private _clients;
|
|
49
|
+
constructor(registry: Registry, router: Router, timeout?: number);
|
|
50
|
+
/**
|
|
51
|
+
* Discover tools from all configured MCP servers.
|
|
52
|
+
* Connects to each server, lists tools, registers in QLN.
|
|
53
|
+
*/
|
|
54
|
+
discoverAll(servers: McpServerConfig[]): Promise<AutoDiscoveryResult>;
|
|
55
|
+
/**
|
|
56
|
+
* Discover tools from a single MCP server.
|
|
57
|
+
*/
|
|
58
|
+
discoverServer(config: McpServerConfig): Promise<DiscoveryResult>;
|
|
59
|
+
/**
|
|
60
|
+
* Get active client connection for live tool execution.
|
|
61
|
+
*/
|
|
62
|
+
getClient(serverName: string): Client | null;
|
|
63
|
+
/**
|
|
64
|
+
* Disconnect all active clients.
|
|
65
|
+
*/
|
|
66
|
+
disconnectAll(): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* Disconnect a single server.
|
|
69
|
+
*/
|
|
70
|
+
disconnect(serverName: string): Promise<boolean>;
|
|
71
|
+
/** @internal Connect to a single MCP server and list its tools. */
|
|
72
|
+
private _discoverServer;
|
|
73
|
+
/** @internal Create transport + client, connect with timeout. */
|
|
74
|
+
private _connectServer;
|
|
75
|
+
/** @internal Purge old entries + register discovered tools. */
|
|
76
|
+
private _indexTools;
|
|
77
|
+
/**
|
|
78
|
+
* Generate boost keywords from tool name and description.
|
|
79
|
+
* Extracts action verbs and key nouns for BM25 boosting.
|
|
80
|
+
*/
|
|
81
|
+
private _generateBoostKeywords;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=mcp-discovery.d.ts.map
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.McpDiscovery = void 0;
|
|
4
|
+
// QLN — MCP Auto-Discovery: scan connected MCP servers and auto-index their tools
|
|
5
|
+
// Killer feature: QLN becomes the universal MCP hub
|
|
6
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/client/index.js");
|
|
7
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/client/stdio.js");
|
|
8
|
+
const schema_1 = require("./schema");
|
|
9
|
+
/**
|
|
10
|
+
* MCP Auto-Discovery engine.
|
|
11
|
+
*
|
|
12
|
+
* Connects to external MCP servers, lists their tools,
|
|
13
|
+
* and registers them in the QLN index for semantic routing.
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* const discovery = new McpDiscovery(registry, router);
|
|
17
|
+
* const result = await discovery.discoverAll(serverConfigs);
|
|
18
|
+
*/
|
|
19
|
+
class McpDiscovery {
|
|
20
|
+
_registry;
|
|
21
|
+
_router;
|
|
22
|
+
_timeout;
|
|
23
|
+
/** Active MCP client connections (for live proxy execution) */
|
|
24
|
+
_clients;
|
|
25
|
+
constructor(registry, router, timeout = 15000) {
|
|
26
|
+
this._registry = registry;
|
|
27
|
+
this._router = router;
|
|
28
|
+
this._timeout = timeout;
|
|
29
|
+
this._clients = new Map();
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Discover tools from all configured MCP servers.
|
|
33
|
+
* Connects to each server, lists tools, registers in QLN.
|
|
34
|
+
*/
|
|
35
|
+
async discoverAll(servers) {
|
|
36
|
+
const t0 = Date.now();
|
|
37
|
+
const results = [];
|
|
38
|
+
let totalRegistered = 0;
|
|
39
|
+
for (const server of servers) {
|
|
40
|
+
const result = await this._discoverServer(server);
|
|
41
|
+
results.push(result);
|
|
42
|
+
totalRegistered += result.toolCount;
|
|
43
|
+
}
|
|
44
|
+
// Rebuild index after all servers discovered
|
|
45
|
+
if (totalRegistered > 0) {
|
|
46
|
+
this._router.buildIndex();
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
total: results.reduce((sum, r) => sum + r.toolCount, 0),
|
|
50
|
+
registered: totalRegistered,
|
|
51
|
+
servers: results,
|
|
52
|
+
elapsed: Date.now() - t0,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Discover tools from a single MCP server.
|
|
57
|
+
*/
|
|
58
|
+
async discoverServer(config) {
|
|
59
|
+
const result = await this._discoverServer(config);
|
|
60
|
+
if (result.toolCount > 0) {
|
|
61
|
+
this._router.buildIndex();
|
|
62
|
+
}
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get active client connection for live tool execution.
|
|
67
|
+
*/
|
|
68
|
+
getClient(serverName) {
|
|
69
|
+
return this._clients.get(serverName) || null;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Disconnect all active clients.
|
|
73
|
+
*/
|
|
74
|
+
async disconnectAll() {
|
|
75
|
+
for (const [name, client] of this._clients) {
|
|
76
|
+
try {
|
|
77
|
+
await client.close();
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
console.error(`[QLN] Discovery: failed to disconnect ${name}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
this._clients.clear();
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Disconnect a single server.
|
|
87
|
+
*/
|
|
88
|
+
async disconnect(serverName) {
|
|
89
|
+
const client = this._clients.get(serverName);
|
|
90
|
+
if (!client)
|
|
91
|
+
return false;
|
|
92
|
+
try {
|
|
93
|
+
await client.close();
|
|
94
|
+
}
|
|
95
|
+
catch { /* ignore */ }
|
|
96
|
+
this._clients.delete(serverName);
|
|
97
|
+
// Purge tools from this server
|
|
98
|
+
this._registry.purgeBySource(`mcp:${serverName}`);
|
|
99
|
+
this._router.buildIndex();
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
/** @internal Connect to a single MCP server and list its tools. */
|
|
103
|
+
async _discoverServer(config) {
|
|
104
|
+
const t0 = Date.now();
|
|
105
|
+
const result = {
|
|
106
|
+
server: config.name, status: 'failed', toolCount: 0, tools: [], elapsed: 0,
|
|
107
|
+
};
|
|
108
|
+
let transport = null;
|
|
109
|
+
let timeoutId = null;
|
|
110
|
+
try {
|
|
111
|
+
const { client, transport: t, timer } = await this._connectServer(config);
|
|
112
|
+
transport = t;
|
|
113
|
+
timeoutId = timer;
|
|
114
|
+
const toolsResult = await client.listTools();
|
|
115
|
+
const tools = toolsResult.tools || [];
|
|
116
|
+
if (tools.length === 0) {
|
|
117
|
+
result.status = 'success';
|
|
118
|
+
result.elapsed = Date.now() - t0;
|
|
119
|
+
await client.close();
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
result.toolCount = this._indexTools(config.name, tools);
|
|
123
|
+
this._clients.set(config.name, client);
|
|
124
|
+
result.status = 'success';
|
|
125
|
+
result.tools = tools.map(t => t.name);
|
|
126
|
+
result.elapsed = Date.now() - t0;
|
|
127
|
+
console.error(`[QLN] Discovery: ${config.name} → ${result.toolCount} tools (${result.elapsed}ms)`);
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
if (timeoutId)
|
|
131
|
+
clearTimeout(timeoutId);
|
|
132
|
+
try {
|
|
133
|
+
if (transport)
|
|
134
|
+
await transport.close();
|
|
135
|
+
}
|
|
136
|
+
catch { /* ignore */ }
|
|
137
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
138
|
+
result.status = msg.includes('timeout') ? 'timeout' : 'failed';
|
|
139
|
+
result.error = msg;
|
|
140
|
+
result.elapsed = Date.now() - t0;
|
|
141
|
+
console.error(`[QLN] Discovery: ${config.name} failed — ${msg}`);
|
|
142
|
+
}
|
|
143
|
+
return result;
|
|
144
|
+
}
|
|
145
|
+
/** @internal Create transport + client, connect with timeout. */
|
|
146
|
+
async _connectServer(config) {
|
|
147
|
+
const transport = new stdio_js_1.StdioClientTransport({
|
|
148
|
+
command: config.command, args: config.args,
|
|
149
|
+
env: config.env
|
|
150
|
+
? Object.fromEntries(Object.entries({ ...process.env, ...config.env })
|
|
151
|
+
.filter((pair) => pair[1] !== undefined))
|
|
152
|
+
: undefined,
|
|
153
|
+
cwd: config.cwd,
|
|
154
|
+
});
|
|
155
|
+
const client = new index_js_1.Client({ name: `qln-discovery-${config.name}`, version: '1.0.0' }, { capabilities: {} });
|
|
156
|
+
let timeoutId = null;
|
|
157
|
+
const connectPromise = client.connect(transport);
|
|
158
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
159
|
+
timeoutId = setTimeout(() => reject(new Error(`Connection timeout (${this._timeout}ms)`)), this._timeout);
|
|
160
|
+
});
|
|
161
|
+
await Promise.race([connectPromise, timeoutPromise]);
|
|
162
|
+
if (timeoutId)
|
|
163
|
+
clearTimeout(timeoutId);
|
|
164
|
+
return { client, transport, timer: timeoutId };
|
|
165
|
+
}
|
|
166
|
+
/** @internal Purge old entries + register discovered tools. */
|
|
167
|
+
_indexTools(serverName, tools) {
|
|
168
|
+
this._registry.purgeBySource(`mcp:${serverName}`);
|
|
169
|
+
const rawTools = tools.map(tool => ({
|
|
170
|
+
name: `mcp__${serverName}__${tool.name}`,
|
|
171
|
+
description: tool.description || '',
|
|
172
|
+
source: `mcp:${serverName}`,
|
|
173
|
+
category: (0, schema_1.inferCategory)(tool.name, 'mcp'),
|
|
174
|
+
provider: serverName,
|
|
175
|
+
inputSchema: tool.inputSchema ?? null,
|
|
176
|
+
tags: [`mcp`, serverName, tool.name],
|
|
177
|
+
boostKeywords: this._generateBoostKeywords(tool.name, tool.description || ''),
|
|
178
|
+
}));
|
|
179
|
+
return this._registry.registerBatch(rawTools);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Generate boost keywords from tool name and description.
|
|
183
|
+
* Extracts action verbs and key nouns for BM25 boosting.
|
|
184
|
+
*/
|
|
185
|
+
_generateBoostKeywords(name, description) {
|
|
186
|
+
// Split camelCase/snake_case tool name into words
|
|
187
|
+
const nameWords = name
|
|
188
|
+
.replace(/([a-z])([A-Z])/g, '$1 $2')
|
|
189
|
+
.replace(/[_\-.]/g, ' ')
|
|
190
|
+
.toLowerCase()
|
|
191
|
+
.split(/\s+/)
|
|
192
|
+
.filter(w => w.length > 2);
|
|
193
|
+
// Extract first sentence of description
|
|
194
|
+
const firstSentence = description.split(/[.!?]/)[0] || '';
|
|
195
|
+
const descWords = firstSentence
|
|
196
|
+
.toLowerCase()
|
|
197
|
+
.split(/\s+/)
|
|
198
|
+
.filter(w => w.length > 3)
|
|
199
|
+
.slice(0, 5);
|
|
200
|
+
// Combine unique words (max 10)
|
|
201
|
+
const combined = [...new Set([...nameWords, ...descWords])].slice(0, 10);
|
|
202
|
+
return combined.join(' ');
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
exports.McpDiscovery = McpDiscovery;
|
|
206
|
+
//# sourceMappingURL=mcp-discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-discovery.js","sourceRoot":"","sources":["../../src/lib/mcp-discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Registry } from './registry';
|
|
2
|
+
import type { ProviderLoadResult } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Load all provider manifests from a directory and register their tools.
|
|
5
|
+
*/
|
|
6
|
+
export declare function loadProviders(providersDir: string, registry: Registry): ProviderLoadResult;
|
|
7
|
+
/**
|
|
8
|
+
* Watch providers directory for changes and auto-reload.
|
|
9
|
+
* Debounces to avoid rapid-fire reloads.
|
|
10
|
+
* @returns cleanup function to stop watching
|
|
11
|
+
*/
|
|
12
|
+
export declare function watchProviders(providersDir: string, registry: Registry, onReload?: (result: ProviderLoadResult) => void): () => void;
|
|
13
|
+
//# sourceMappingURL=provider-loader.d.ts.map
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.loadProviders = loadProviders;
|
|
7
|
+
exports.watchProviders = watchProviders;
|
|
8
|
+
// QLN — Provider manifest loader (providers/*.json → registry auto-registration)
|
|
9
|
+
// Includes hot reload via fs.watch for development
|
|
10
|
+
const fs_1 = __importDefault(require("fs"));
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
const schema_1 = require("./schema");
|
|
13
|
+
/** Required fields for a valid provider manifest. */
|
|
14
|
+
const REQUIRED_MANIFEST_FIELDS = ['provider', 'tools'];
|
|
15
|
+
/**
|
|
16
|
+
* Load all provider manifests from a directory and register their tools.
|
|
17
|
+
*/
|
|
18
|
+
function loadProviders(providersDir, registry) {
|
|
19
|
+
const result = { loaded: 0, skipped: 0, failed: 0, details: [] };
|
|
20
|
+
if (!fs_1.default.existsSync(providersDir))
|
|
21
|
+
return result;
|
|
22
|
+
const files = fs_1.default.readdirSync(providersDir)
|
|
23
|
+
.filter((f) => f.endsWith('.json'));
|
|
24
|
+
if (files.length === 0)
|
|
25
|
+
return result;
|
|
26
|
+
for (const file of files) {
|
|
27
|
+
const filePath = path_1.default.join(providersDir, file);
|
|
28
|
+
try {
|
|
29
|
+
const manifest = _parseManifest(filePath);
|
|
30
|
+
if (!manifest) {
|
|
31
|
+
result.skipped++;
|
|
32
|
+
result.details.push({ file, status: 'skipped', reason: 'invalid manifest' });
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
const tools = _normalizeTools(manifest);
|
|
36
|
+
if (tools.length === 0) {
|
|
37
|
+
result.skipped++;
|
|
38
|
+
result.details.push({ file, status: 'skipped', reason: 'no valid tools' });
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
// Idempotent: purge old entries from this provider before re-registering
|
|
42
|
+
registry.purgeBySource(`provider:${manifest.provider}`);
|
|
43
|
+
const count = registry.registerBatch(tools);
|
|
44
|
+
result.loaded += count;
|
|
45
|
+
result.details.push({
|
|
46
|
+
file,
|
|
47
|
+
status: 'loaded',
|
|
48
|
+
provider: manifest.provider,
|
|
49
|
+
toolCount: count,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
result.failed++;
|
|
54
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
55
|
+
result.details.push({ file, status: 'failed', reason: msg });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Parse and validate a manifest JSON file.
|
|
62
|
+
*/
|
|
63
|
+
function _parseManifest(filePath) {
|
|
64
|
+
const raw = fs_1.default.readFileSync(filePath, 'utf-8');
|
|
65
|
+
const manifest = JSON.parse(raw);
|
|
66
|
+
// Validate required fields
|
|
67
|
+
for (const field of REQUIRED_MANIFEST_FIELDS) {
|
|
68
|
+
if (!manifest[field])
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
// tools must be a non-empty array
|
|
72
|
+
if (!Array.isArray(manifest.tools))
|
|
73
|
+
return null;
|
|
74
|
+
return manifest;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Normalize tool entries from a manifest for registry registration.
|
|
78
|
+
* Injects provider metadata and assigns source = "provider:{name}".
|
|
79
|
+
*/
|
|
80
|
+
function _normalizeTools(manifest) {
|
|
81
|
+
const providerName = manifest.provider;
|
|
82
|
+
const tools = [];
|
|
83
|
+
for (const raw of manifest.tools) {
|
|
84
|
+
// Skip tools missing required fields
|
|
85
|
+
if (!raw.name || !raw.description)
|
|
86
|
+
continue;
|
|
87
|
+
tools.push({
|
|
88
|
+
name: raw.name,
|
|
89
|
+
description: raw.description,
|
|
90
|
+
source: `provider:${providerName}`,
|
|
91
|
+
category: raw.category || (0, schema_1.inferCategory)(raw.name, 'provider'),
|
|
92
|
+
provider: providerName,
|
|
93
|
+
inputSchema: raw.inputSchema || null,
|
|
94
|
+
triggers: raw.triggers || undefined,
|
|
95
|
+
tags: raw.tags || [],
|
|
96
|
+
examples: raw.examples || [],
|
|
97
|
+
endpoint: raw.endpoint || '',
|
|
98
|
+
boostKeywords: raw.boostKeywords || undefined,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
return tools;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Watch providers directory for changes and auto-reload.
|
|
105
|
+
* Debounces to avoid rapid-fire reloads.
|
|
106
|
+
* @returns cleanup function to stop watching
|
|
107
|
+
*/
|
|
108
|
+
function watchProviders(providersDir, registry, onReload) {
|
|
109
|
+
if (!fs_1.default.existsSync(providersDir)) {
|
|
110
|
+
console.error(`[QLN] Hot Reload: providers dir not found: ${providersDir}`);
|
|
111
|
+
return () => { };
|
|
112
|
+
}
|
|
113
|
+
let debounceTimer = null;
|
|
114
|
+
const DEBOUNCE_MS = 500;
|
|
115
|
+
const watcher = fs_1.default.watch(providersDir, (eventType, filename) => {
|
|
116
|
+
// Only react to .json file changes
|
|
117
|
+
if (!filename || !filename.endsWith('.json'))
|
|
118
|
+
return;
|
|
119
|
+
// Debounce: collapse rapid changes into one reload
|
|
120
|
+
if (debounceTimer)
|
|
121
|
+
clearTimeout(debounceTimer);
|
|
122
|
+
debounceTimer = setTimeout(() => {
|
|
123
|
+
console.error(`[QLN] Hot Reload: ${eventType} ${filename} → reloading providers...`);
|
|
124
|
+
try {
|
|
125
|
+
const result = loadProviders(providersDir, registry);
|
|
126
|
+
console.error(`[QLN] Hot Reload: ${result.loaded} tools reloaded`);
|
|
127
|
+
if (onReload)
|
|
128
|
+
onReload(result);
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
132
|
+
console.error(`[QLN] Hot Reload error: ${msg}`);
|
|
133
|
+
}
|
|
134
|
+
}, DEBOUNCE_MS);
|
|
135
|
+
});
|
|
136
|
+
console.error(`[QLN] Hot Reload: watching ${providersDir}`);
|
|
137
|
+
return () => {
|
|
138
|
+
if (debounceTimer)
|
|
139
|
+
clearTimeout(debounceTimer);
|
|
140
|
+
watcher.close();
|
|
141
|
+
console.error('[QLN] Hot Reload: stopped');
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=provider-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-loader.js","sourceRoot":"","sources":["../../src/lib/provider-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Store } from './store';
|
|
2
|
+
import type { Embedding } from './embedding';
|
|
3
|
+
import type { ToolEntry, RawToolEntry, RegistryStats, EmbeddingPrecomputeResult } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* Tool registry — in-memory cache (Map) + SQLite persistence.
|
|
6
|
+
* Designed for up to 1000 tools.
|
|
7
|
+
*/
|
|
8
|
+
export declare class Registry {
|
|
9
|
+
private _store;
|
|
10
|
+
private _embedding;
|
|
11
|
+
private _cache;
|
|
12
|
+
constructor(store: Store, embedding?: Embedding | null);
|
|
13
|
+
/** Load all entries from SQLite into memory cache */
|
|
14
|
+
load(): void;
|
|
15
|
+
/**
|
|
16
|
+
* Register a tool (update if exists, preserve existing stats).
|
|
17
|
+
*/
|
|
18
|
+
register(raw: RawToolEntry): ToolEntry;
|
|
19
|
+
/** Batch register tools (single disk write at the end). */
|
|
20
|
+
registerBatch(tools: RawToolEntry[]): number;
|
|
21
|
+
/** Remove a tool. */
|
|
22
|
+
remove(name: string): boolean;
|
|
23
|
+
/** Purge all tools by source (for re-sync). */
|
|
24
|
+
purgeBySource(source: string): number;
|
|
25
|
+
get(name: string): ToolEntry | null;
|
|
26
|
+
getAll(): ToolEntry[];
|
|
27
|
+
get size(): number;
|
|
28
|
+
/** Remove all tools by provider name. */
|
|
29
|
+
removeByProvider(providerName: string): number;
|
|
30
|
+
/** Precompute embeddings for tools without one (single disk write). */
|
|
31
|
+
precomputeEmbeddings(): Promise<EmbeddingPrecomputeResult>;
|
|
32
|
+
/** Record tool usage + circuit breaker state. */
|
|
33
|
+
recordUsage(name: string, success?: boolean): void;
|
|
34
|
+
stats(): RegistryStats;
|
|
35
|
+
/** Convert SQLite row to tool entry */
|
|
36
|
+
private _rowToEntry;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=registry.d.ts.map
|