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
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js ADDED
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ // QLN — Query Layer Network MCP server entry point
8
+ // Semantic tool dispatcher: route 1000 tools through 1 router
9
+ const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
10
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
11
+ const zod_1 = require("zod");
12
+ const path_1 = __importDefault(require("path"));
13
+ // Core modules
14
+ const config_1 = require("./lib/config");
15
+ const store_1 = require("./lib/store");
16
+ const embedding_1 = require("./lib/embedding");
17
+ const registry_1 = require("./lib/registry");
18
+ const vector_index_1 = require("./lib/vector-index");
19
+ const router_1 = require("./lib/router");
20
+ const executor_1 = require("./lib/executor");
21
+ const provider_loader_1 = require("./lib/provider-loader");
22
+ const mcp_discovery_1 = require("./lib/mcp-discovery");
23
+ // MCP Tool (unified)
24
+ const qln_call_1 = require("./tools/qln-call");
25
+ /** Load provider manifests into registry */
26
+ function initProviders(config, registry) {
27
+ if (config.providers?.enabled === false)
28
+ return;
29
+ const provDir = config.providers?.dir || path_1.default.join(__dirname, '..', 'providers');
30
+ const provResult = (0, provider_loader_1.loadProviders)(provDir, registry);
31
+ if (provResult.loaded > 0) {
32
+ console.error(`[QLN] Providers: ${provResult.loaded} tools from ${provResult.details.filter(d => d.status === 'loaded').length} files`);
33
+ }
34
+ if (provResult.failed > 0) {
35
+ console.error(`[QLN] Provider warnings: ${provResult.failed} files failed to load`);
36
+ }
37
+ }
38
+ /** Schedule async embedding precompute (non-blocking) */
39
+ function scheduleEmbeddings(embedding, registry, router) {
40
+ if (!embedding)
41
+ return;
42
+ setImmediate(async () => {
43
+ try {
44
+ await registry.precomputeEmbeddings();
45
+ router.buildIndex();
46
+ }
47
+ catch { /* Ollama not available — Stage 1+2 still work */ }
48
+ });
49
+ }
50
+ async function main() {
51
+ const config = (0, config_1.loadConfig)();
52
+ // 1. Core engine initialization
53
+ const store = new store_1.Store(config.dataDir);
54
+ await store.init();
55
+ const embedding = config.embedding?.enabled
56
+ ? new embedding_1.Embedding(config.embedding)
57
+ : null;
58
+ const registry = new registry_1.Registry(store, embedding);
59
+ registry.load();
60
+ // 1.5. Provider auto-indexing
61
+ initProviders(config, registry);
62
+ const vectorIndex = new vector_index_1.VectorIndex();
63
+ const router = new router_1.Router(registry, vectorIndex, embedding, config.search?.sourceWeights || {});
64
+ const executor = new executor_1.Executor(config.executor || {});
65
+ const discovery = new mcp_discovery_1.McpDiscovery(registry, router);
66
+ // 2. Precompute embeddings (async, non-blocking)
67
+ scheduleEmbeddings(embedding, registry, router);
68
+ // 3. Create MCP server + register tool
69
+ const pkg = require('../package.json');
70
+ const server = new mcp_js_1.McpServer({ name: 'n2-qln', version: pkg.version });
71
+ (0, qln_call_1.registerQlnCall)(server, zod_1.z, router, executor, registry, discovery);
72
+ // 4. Connect stdio transport
73
+ const transport = new stdio_js_1.StdioServerTransport();
74
+ await server.connect(transport);
75
+ // 5. Hot Reload: watch providers dir for changes
76
+ if (config.providers?.enabled !== false) {
77
+ const provDir = config.providers?.dir || path_1.default.join(__dirname, '..', 'providers');
78
+ (0, provider_loader_1.watchProviders)(provDir, registry, () => {
79
+ router.buildIndex();
80
+ });
81
+ }
82
+ }
83
+ main().catch((err) => {
84
+ console.error(`[QLN] Fatal: ${err.message}`);
85
+ process.exit(1);
86
+ });
87
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { QLNConfig } from '../types';
2
+ /** Default configuration */
3
+ declare const defaults: QLNConfig;
4
+ /**
5
+ * Load config — apply config.local.js overrides on top of defaults.
6
+ */
7
+ export declare function loadConfig(): QLNConfig;
8
+ export { defaults };
9
+ //# sourceMappingURL=config.d.ts.map
@@ -1,71 +1,67 @@
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.defaults = void 0;
7
+ exports.loadConfig = loadConfig;
1
8
  // QLN — Config loader (default + local deep merge)
2
- const path = require('path');
3
- const fs = require('fs');
4
-
9
+ const path_1 = __importDefault(require("path"));
10
+ const fs_1 = __importDefault(require("fs"));
5
11
  /** Default configuration */
6
12
  const defaults = {
7
- /** Data directory (SQLite, indices, etc.) */
8
- dataDir: path.join(__dirname, '..', 'data'),
9
-
10
- /** Embedding configuration */
13
+ dataDir: path_1.default.join(__dirname, '..', '..', 'data'),
11
14
  embedding: {
12
15
  enabled: true,
13
16
  model: 'nomic-embed-text',
14
17
  endpoint: 'http://127.0.0.1:11434',
15
18
  },
16
-
17
- /** Tool execution configuration */
18
19
  executor: {
19
20
  httpEndpoint: null,
20
21
  timeout: 20000,
21
22
  },
22
-
23
- /** Provider manifest auto-indexing */
24
23
  providers: {
25
24
  enabled: true,
26
- dir: path.join(__dirname, '..', 'providers'),
25
+ dir: path_1.default.join(__dirname, '..', '..', 'providers'),
27
26
  },
28
-
29
- /** Search configuration */
30
27
  search: {
31
28
  defaultTopK: 5,
32
29
  threshold: 0.1,
30
+ sourceWeights: { mcp: 1.2, plugin: 1.0, local: 0.8 },
33
31
  },
34
32
  };
35
-
33
+ exports.defaults = defaults;
36
34
  /**
37
35
  * Load config — apply config.local.js overrides on top of defaults.
38
- * @returns {object} Merged config
39
36
  */
40
37
  function loadConfig() {
41
38
  const config = JSON.parse(JSON.stringify(defaults));
42
- const localPath = path.join(__dirname, '..', 'config.local.js');
43
-
44
- if (fs.existsSync(localPath)) {
39
+ const localPath = path_1.default.join(__dirname, '..', '..', 'config.local.js');
40
+ if (fs_1.default.existsSync(localPath)) {
45
41
  try {
42
+ // config.local.js is a CJS module — require is intentional
46
43
  const local = require(localPath);
47
44
  deepMerge(config, local);
48
- } catch (e) {
49
- console.warn(`[QLN] config.local.js load failed: ${e.message}`);
45
+ }
46
+ catch (e) {
47
+ const msg = e instanceof Error ? e.message : String(e);
48
+ console.warn(`[QLN] config.local.js load failed: ${msg}`);
50
49
  }
51
50
  }
52
51
  return config;
53
52
  }
54
-
55
53
  /**
56
54
  * Deep merge (merge source into target).
57
- * @param {object} target
58
- * @param {object} source
59
55
  */
60
56
  function deepMerge(target, source) {
61
57
  for (const key of Object.keys(source)) {
62
58
  if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])
63
59
  && target[key] && typeof target[key] === 'object') {
64
60
  deepMerge(target[key], source[key]);
65
- } else {
61
+ }
62
+ else {
66
63
  target[key] = source[key];
67
64
  }
68
65
  }
69
66
  }
70
-
71
- module.exports = { loadConfig, defaults };
67
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":";;;;;;AA+BA,gCAeC;AA9CD,mDAAmD;AACnD,gDAAwB;AACxB,4CAAoB;AAGpB,4BAA4B;AAC5B,MAAM,QAAQ,GAAc;IAC1B,OAAO,EAAE,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC;IACjD,SAAS,EAAE;QACT,OAAO,EAAE,IAAI;QACb,KAAK,EAAE,kBAAkB;QACzB,QAAQ,EAAE,wBAAwB;KACnC;IACD,QAAQ,EAAE;QACR,YAAY,EAAE,IAAI;QAClB,OAAO,EAAE,KAAK;KACf;IACD,SAAS,EAAE;QACT,OAAO,EAAE,IAAI;QACb,GAAG,EAAE,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC;KACnD;IACD,MAAM,EAAE;QACN,WAAW,EAAE,CAAC;QACd,SAAS,EAAE,GAAG;QACd,aAAa,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE;KACrD;CACF,CAAC;AAoCO,4BAAQ;AAlCjB;;GAEG;AACH,SAAgB,UAAU;IACxB,MAAM,MAAM,GAAc,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC/D,MAAM,SAAS,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC;IAEtE,IAAI,YAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,2DAA2D;YAC3D,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAuB,CAAC;YACvD,SAAS,CAAC,MAA4C,EAAE,KAA2C,CAAC,CAAC;QACvG,CAAC;QAAC,OAAO,CAAU,EAAE,CAAC;YACpB,MAAM,GAAG,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACvD,OAAO,CAAC,IAAI,CAAC,sCAAsC,GAAG,EAAE,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,SAAS,CAAC,MAA+B,EAAE,MAA+B;IACjF,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACtC,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;eAC1E,MAAM,CAAC,GAAG,CAAC,IAAI,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,QAAQ,EAAE,CAAC;YACtD,SAAS,CAAC,MAAM,CAAC,GAAG,CAA4B,EAAE,MAAM,CAAC,GAAG,CAA4B,CAAC,CAAC;QAC5F,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,28 @@
1
+ interface EmbeddingConfig {
2
+ model?: string;
3
+ endpoint?: string;
4
+ }
5
+ /**
6
+ * Ollama-based local embedding engine.
7
+ * Graceful degradation when unavailable — Stage 1+2 still work.
8
+ */
9
+ export declare class Embedding {
10
+ private model;
11
+ private endpoint;
12
+ dimensions: number | null;
13
+ private _available;
14
+ private _availableCheckedAt;
15
+ constructor(config?: EmbeddingConfig);
16
+ /** Check Ollama availability (TTL cached — re-checks every 5 minutes). */
17
+ isAvailable(): Promise<boolean>;
18
+ /** Generate vector embedding from text. */
19
+ embed(text: string): Promise<number[]>;
20
+ /** Batch embedding generation. */
21
+ embedBatch(texts: string[]): Promise<number[][]>;
22
+ /** Cosine similarity between two vectors. */
23
+ cosineSimilarity(a: number[], b: number[]): number;
24
+ /** @internal HTTP POST to Ollama API */
25
+ private _post;
26
+ }
27
+ export {};
28
+ //# sourceMappingURL=embedding.d.ts.map
@@ -1,57 +1,59 @@
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.Embedding = void 0;
1
7
  // QLN — Embedding engine (Ollama nomic-embed-text)
2
8
  // Vector embedding generation for semantic search (Stage 3)
3
- const http = require('http');
4
-
9
+ const http_1 = __importDefault(require("http"));
5
10
  /**
6
11
  * Ollama-based local embedding engine.
7
12
  * Graceful degradation when unavailable — Stage 1+2 still work.
8
13
  */
9
14
  class Embedding {
10
- /**
11
- * @param {object} config
12
- * @param {string} [config.model='nomic-embed-text'] - Ollama model
13
- * @param {string} [config.endpoint='http://127.0.0.1:11434'] - Ollama endpoint
14
- */
15
+ model;
16
+ endpoint;
17
+ dimensions;
18
+ _available;
19
+ _availableCheckedAt;
15
20
  constructor(config = {}) {
16
21
  this.model = config.model || 'nomic-embed-text';
17
22
  this.endpoint = config.endpoint || 'http://127.0.0.1:11434';
18
23
  this.dimensions = null;
19
24
  this._available = null;
25
+ this._availableCheckedAt = 0;
20
26
  }
21
-
22
- /**
23
- * Check Ollama availability (cached).
24
- * @returns {Promise<boolean>}
25
- */
27
+ /** Check Ollama availability (TTL cached — re-checks every 5 minutes). */
26
28
  async isAvailable() {
27
- if (this._available !== null) return this._available;
29
+ const TTL_MS = 5 * 60 * 1000;
30
+ if (this._available !== null && (Date.now() - this._availableCheckedAt) < TTL_MS) {
31
+ return this._available;
32
+ }
28
33
  try {
29
34
  const vec = await this.embed('test');
30
35
  this._available = vec.length > 0;
31
36
  this.dimensions = vec.length;
37
+ this._availableCheckedAt = Date.now();
32
38
  return this._available;
33
- } catch {
39
+ }
40
+ catch {
34
41
  this._available = false;
42
+ this._availableCheckedAt = Date.now();
35
43
  return false;
36
44
  }
37
45
  }
38
-
39
- /**
40
- * Generate vector embedding from text.
41
- * @param {string} text
42
- * @returns {Promise<number[]>}
43
- */
46
+ /** Generate vector embedding from text. */
44
47
  async embed(text) {
45
- if (!text || text.trim().length === 0) return [];
48
+ if (!text || text.trim().length === 0)
49
+ return [];
46
50
  const input = text.length > 2000 ? text.slice(0, 2000) : text;
47
-
48
51
  for (const apiPath of ['/api/embeddings', '/api/embed']) {
49
52
  try {
50
53
  const body = apiPath === '/api/embeddings'
51
54
  ? { model: this.model, prompt: input }
52
55
  : { model: this.model, input: input };
53
56
  const result = await this._post(apiPath, body);
54
-
55
57
  if (result.embedding && Array.isArray(result.embedding)) {
56
58
  this.dimensions = result.embedding.length;
57
59
  return result.embedding;
@@ -60,16 +62,14 @@ class Embedding {
60
62
  this.dimensions = result.embeddings[0].length;
61
63
  return result.embeddings[0];
62
64
  }
63
- } catch { continue; }
65
+ }
66
+ catch {
67
+ continue;
68
+ }
64
69
  }
65
70
  return [];
66
71
  }
67
-
68
- /**
69
- * Batch embedding generation.
70
- * @param {string[]} texts
71
- * @returns {Promise<number[][]>}
72
- */
72
+ /** Batch embedding generation. */
73
73
  async embedBatch(texts) {
74
74
  const results = [];
75
75
  for (const text of texts) {
@@ -77,15 +77,10 @@ class Embedding {
77
77
  }
78
78
  return results;
79
79
  }
80
-
81
- /**
82
- * Cosine similarity between two vectors.
83
- * @param {number[]} a
84
- * @param {number[]} b
85
- * @returns {number} 0~1
86
- */
80
+ /** Cosine similarity between two vectors. */
87
81
  cosineSimilarity(a, b) {
88
- if (!a || !b || a.length === 0 || a.length !== b.length) return 0;
82
+ if (!a || !b || a.length === 0 || a.length !== b.length)
83
+ return 0;
89
84
  let dot = 0, normA = 0, normB = 0;
90
85
  for (let i = 0; i < a.length; i++) {
91
86
  dot += a[i] * b[i];
@@ -95,8 +90,7 @@ class Embedding {
95
90
  const denom = Math.sqrt(normA) * Math.sqrt(normB);
96
91
  return denom === 0 ? 0 : dot / denom;
97
92
  }
98
-
99
- /** @private HTTP POST to Ollama API */
93
+ /** @internal HTTP POST to Ollama API */
100
94
  _post(apiPath, body) {
101
95
  return new Promise((resolve, reject) => {
102
96
  const url = new URL(this.endpoint);
@@ -108,16 +102,20 @@ class Embedding {
108
102
  headers: { 'Content-Type': 'application/json' },
109
103
  timeout: 30000,
110
104
  };
111
- const req = http.request(options, res => {
105
+ const req = http_1.default.request(options, (res) => {
112
106
  let data = '';
113
- res.on('data', chunk => { data += chunk; });
107
+ res.on('data', (chunk) => { data += chunk; });
114
108
  res.on('end', () => {
115
- if (res.statusCode >= 400) {
109
+ if (res.statusCode && res.statusCode >= 400) {
116
110
  reject(new Error(`Ollama ${res.statusCode}: ${data.slice(0, 200)}`));
117
111
  return;
118
112
  }
119
- try { resolve(JSON.parse(data)); }
120
- catch { reject(new Error(`Invalid JSON: ${data.slice(0, 100)}`)); }
113
+ try {
114
+ resolve(JSON.parse(data));
115
+ }
116
+ catch {
117
+ reject(new Error(`Invalid JSON: ${data.slice(0, 100)}`));
118
+ }
121
119
  });
122
120
  });
123
121
  req.on('error', reject);
@@ -127,5 +125,5 @@ class Embedding {
127
125
  });
128
126
  }
129
127
  }
130
-
131
- module.exports = { Embedding };
128
+ exports.Embedding = Embedding;
129
+ //# sourceMappingURL=embedding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedding.js","sourceRoot":"","sources":["../../src/lib/embedding.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ import type { ExecResult, ToolHandler, CircuitBreakerConfig, CircuitState } from '../types';
2
+ interface ExecutorConfig {
3
+ httpEndpoint?: string | null;
4
+ timeout?: number;
5
+ circuitBreaker?: Partial<CircuitBreakerConfig>;
6
+ }
7
+ /**
8
+ * Tool executor — HTTP proxy + local function calls + Circuit Breaker.
9
+ *
10
+ * Execution priority:
11
+ * 1. Circuit breaker check (reject if open)
12
+ * 2. Local registered handler (via addHandler)
13
+ * 3. HTTP proxy (when endpoint configured)
14
+ *
15
+ * Circuit Breaker states:
16
+ * closed → normal, requests pass through
17
+ * open → tool disabled, fast-fail (after N consecutive failures)
18
+ * half-open → recovery attempt (after recovery timeout)
19
+ */
20
+ export declare class Executor {
21
+ private _httpEndpoint;
22
+ private _timeout;
23
+ private _handlers;
24
+ private _circuits;
25
+ private _cbConfig;
26
+ constructor(config?: ExecutorConfig);
27
+ /** Register a local tool handler. */
28
+ addHandler(name: string, handler: ToolHandler): void;
29
+ /** Execute a tool (with circuit breaker protection). */
30
+ exec(name: string, args?: Record<string, unknown>): Promise<ExecResult>;
31
+ /** @internal Route to handler or HTTP proxy. */
32
+ private _dispatch;
33
+ /** @internal Circuit breaker gate — throws if tool is disabled. */
34
+ private _checkCircuit;
35
+ /** Get circuit breaker state for a tool. */
36
+ getCircuitState(name: string): {
37
+ state: CircuitState;
38
+ failures: number;
39
+ };
40
+ /** Manually reset circuit breaker for a tool. */
41
+ resetCircuit(name: string): void;
42
+ /** Get all tripped circuits (for stats). */
43
+ getTrippedCircuits(): Array<{
44
+ name: string;
45
+ failures: number;
46
+ state: CircuitState;
47
+ }>;
48
+ /** Dynamically set HTTP endpoint. */
49
+ setHttpEndpoint(endpoint: string): void;
50
+ private _getCircuit;
51
+ private _recordSuccess;
52
+ private _recordFailure;
53
+ /** @internal HTTP POST /call → tool execution */
54
+ private _execHttp;
55
+ }
56
+ export {};
57
+ //# sourceMappingURL=executor.d.ts.map
@@ -0,0 +1,175 @@
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.Executor = void 0;
7
+ // QLN — L3 tool executor with Circuit Breaker
8
+ // Execute tools via HTTP (localhost) or registered local handlers
9
+ // Circuit Breaker: auto-disable tools after consecutive failures
10
+ const http_1 = __importDefault(require("http"));
11
+ /**
12
+ * Tool executor — HTTP proxy + local function calls + Circuit Breaker.
13
+ *
14
+ * Execution priority:
15
+ * 1. Circuit breaker check (reject if open)
16
+ * 2. Local registered handler (via addHandler)
17
+ * 3. HTTP proxy (when endpoint configured)
18
+ *
19
+ * Circuit Breaker states:
20
+ * closed → normal, requests pass through
21
+ * open → tool disabled, fast-fail (after N consecutive failures)
22
+ * half-open → recovery attempt (after recovery timeout)
23
+ */
24
+ class Executor {
25
+ _httpEndpoint;
26
+ _timeout;
27
+ _handlers;
28
+ _circuits;
29
+ _cbConfig;
30
+ constructor(config = {}) {
31
+ this._httpEndpoint = config.httpEndpoint || null;
32
+ this._timeout = config.timeout || 20000;
33
+ this._handlers = new Map();
34
+ this._circuits = new Map();
35
+ this._cbConfig = {
36
+ failureThreshold: config.circuitBreaker?.failureThreshold ?? 3,
37
+ recoveryTimeout: config.circuitBreaker?.recoveryTimeout ?? 60000,
38
+ };
39
+ }
40
+ /** Register a local tool handler. */
41
+ addHandler(name, handler) {
42
+ this._handlers.set(name, handler);
43
+ }
44
+ /** Execute a tool (with circuit breaker protection). */
45
+ async exec(name, args = {}) {
46
+ const circuit = this._checkCircuit(name);
47
+ const t0 = Date.now();
48
+ circuit.lastAttempt = t0;
49
+ try {
50
+ const result = await this._dispatch(name, args, t0);
51
+ this._recordSuccess(name);
52
+ return result;
53
+ }
54
+ catch (err) {
55
+ if (!err.__qlnConfigError) {
56
+ this._recordFailure(name);
57
+ }
58
+ throw err;
59
+ }
60
+ }
61
+ /** @internal Route to handler or HTTP proxy. */
62
+ async _dispatch(name, args, t0) {
63
+ if (this._handlers.has(name)) {
64
+ const output = await this._handlers.get(name)(args);
65
+ return { result: output, source: 'local', elapsed: Date.now() - t0 };
66
+ }
67
+ if (this._httpEndpoint) {
68
+ const output = await this._execHttp(name, args);
69
+ return { result: output, source: 'http', elapsed: Date.now() - t0 };
70
+ }
71
+ throw Object.assign(new Error(`No handler found for tool: ${name}. Register with addHandler() or set httpEndpoint.`), { __qlnConfigError: true });
72
+ }
73
+ /** @internal Circuit breaker gate — throws if tool is disabled. */
74
+ _checkCircuit(name) {
75
+ const circuit = this._getCircuit(name);
76
+ if (circuit.state === 'open') {
77
+ const elapsed = Date.now() - circuit.lastFailure;
78
+ if (elapsed < this._cbConfig.recoveryTimeout) {
79
+ throw new Error(`[Circuit Breaker] ${name} is disabled (${circuit.failures} failures). ` +
80
+ `Recovery in ${Math.ceil((this._cbConfig.recoveryTimeout - elapsed) / 1000)}s.`);
81
+ }
82
+ circuit.state = 'half-open';
83
+ }
84
+ return circuit;
85
+ }
86
+ /** Get circuit breaker state for a tool. */
87
+ getCircuitState(name) {
88
+ const c = this._circuits.get(name);
89
+ if (!c)
90
+ return { state: 'closed', failures: 0 };
91
+ // Check for auto-recovery
92
+ if (c.state === 'open' && (Date.now() - c.lastFailure) >= this._cbConfig.recoveryTimeout) {
93
+ return { state: 'half-open', failures: c.failures };
94
+ }
95
+ return { state: c.state, failures: c.failures };
96
+ }
97
+ /** Manually reset circuit breaker for a tool. */
98
+ resetCircuit(name) {
99
+ this._circuits.delete(name);
100
+ }
101
+ /** Get all tripped circuits (for stats). */
102
+ getTrippedCircuits() {
103
+ const tripped = [];
104
+ for (const [name, entry] of this._circuits) {
105
+ if (entry.state !== 'closed') {
106
+ tripped.push({ name, failures: entry.failures, state: entry.state });
107
+ }
108
+ }
109
+ return tripped;
110
+ }
111
+ /** Dynamically set HTTP endpoint. */
112
+ setHttpEndpoint(endpoint) {
113
+ this._httpEndpoint = endpoint;
114
+ }
115
+ // ── Circuit Breaker internals ──
116
+ _getCircuit(name) {
117
+ if (!this._circuits.has(name)) {
118
+ this._circuits.set(name, { state: 'closed', failures: 0, lastFailure: 0, lastAttempt: 0 });
119
+ }
120
+ return this._circuits.get(name);
121
+ }
122
+ _recordSuccess(name) {
123
+ const circuit = this._getCircuit(name);
124
+ circuit.state = 'closed';
125
+ circuit.failures = 0;
126
+ }
127
+ _recordFailure(name) {
128
+ const circuit = this._getCircuit(name);
129
+ circuit.failures++;
130
+ circuit.lastFailure = Date.now();
131
+ if (circuit.failures >= this._cbConfig.failureThreshold) {
132
+ circuit.state = 'open';
133
+ console.error(`[QLN] Circuit Breaker: ${name} tripped (${circuit.failures} failures)`);
134
+ }
135
+ }
136
+ /** @internal HTTP POST /call → tool execution */
137
+ _execHttp(name, args) {
138
+ return new Promise((resolve, reject) => {
139
+ const url = new URL(this._httpEndpoint);
140
+ const bodyStr = JSON.stringify({ tool: name, args });
141
+ const timer = setTimeout(() => reject(new Error(`timeout (${this._timeout}ms)`)), this._timeout);
142
+ const req = http_1.default.request({
143
+ hostname: url.hostname,
144
+ port: url.port,
145
+ path: '/call',
146
+ method: 'POST',
147
+ headers: {
148
+ 'Content-Type': 'application/json',
149
+ 'Content-Length': Buffer.byteLength(bodyStr),
150
+ },
151
+ }, (res) => {
152
+ let body = '';
153
+ res.on('data', (c) => body += c);
154
+ res.on('end', () => {
155
+ clearTimeout(timer);
156
+ try {
157
+ const parsed = JSON.parse(body);
158
+ if (parsed.error)
159
+ reject(new Error(parsed.error));
160
+ else
161
+ resolve(parsed.result);
162
+ }
163
+ catch {
164
+ reject(new Error(`Invalid response: ${body.slice(0, 200)}`));
165
+ }
166
+ });
167
+ });
168
+ req.on('error', (e) => { clearTimeout(timer); reject(e); });
169
+ req.write(bodyStr);
170
+ req.end();
171
+ });
172
+ }
173
+ }
174
+ exports.Executor = Executor;
175
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/lib/executor.ts"],"names":[],"mappings":"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"}