@darkiceinteractive/mcp-conductor 2.0.0-alpha.1 → 3.0.0-beta.2
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.md +35 -5
- package/dist/bin/cli.d.ts +20 -0
- package/dist/bin/cli.d.ts.map +1 -0
- package/dist/bin/cli.js +260 -0
- package/dist/bin/cli.js.map +1 -0
- package/dist/bridge/http-server.d.ts +35 -0
- package/dist/bridge/http-server.d.ts.map +1 -1
- package/dist/bridge/http-server.js +51 -2
- package/dist/bridge/http-server.js.map +1 -1
- package/dist/bridge/index.d.ts +1 -0
- package/dist/bridge/index.d.ts.map +1 -1
- package/dist/bridge/index.js +1 -0
- package/dist/bridge/index.js.map +1 -1
- package/dist/bridge/pool.d.ts +95 -0
- package/dist/bridge/pool.d.ts.map +1 -0
- package/dist/bridge/pool.js +384 -0
- package/dist/bridge/pool.js.map +1 -0
- package/dist/cache/cache.d.ts +64 -0
- package/dist/cache/cache.d.ts.map +1 -0
- package/dist/cache/cache.js +209 -0
- package/dist/cache/cache.js.map +1 -0
- package/dist/cache/delta.d.ts +32 -0
- package/dist/cache/delta.d.ts.map +1 -0
- package/dist/cache/delta.js +131 -0
- package/dist/cache/delta.js.map +1 -0
- package/dist/cache/disk.d.ts +65 -0
- package/dist/cache/disk.d.ts.map +1 -0
- package/dist/cache/disk.js +238 -0
- package/dist/cache/disk.js.map +1 -0
- package/dist/cache/index.d.ts +53 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +12 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/key.d.ts +44 -0
- package/dist/cache/key.d.ts.map +1 -0
- package/dist/cache/key.js +83 -0
- package/dist/cache/key.js.map +1 -0
- package/dist/cache/lru.d.ts +57 -0
- package/dist/cache/lru.d.ts.map +1 -0
- package/dist/cache/lru.js +112 -0
- package/dist/cache/lru.js.map +1 -0
- package/dist/cache/policy.d.ts +34 -0
- package/dist/cache/policy.d.ts.map +1 -0
- package/dist/cache/policy.js +95 -0
- package/dist/cache/policy.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +33 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +135 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/export-servers.d.ts +22 -0
- package/dist/cli/commands/export-servers.d.ts.map +1 -0
- package/dist/cli/commands/export-servers.js +45 -0
- package/dist/cli/commands/export-servers.js.map +1 -0
- package/dist/cli/commands/import-servers.d.ts +57 -0
- package/dist/cli/commands/import-servers.d.ts.map +1 -0
- package/dist/cli/commands/import-servers.js +137 -0
- package/dist/cli/commands/import-servers.js.map +1 -0
- package/dist/cli/commands/routing.d.ts +34 -0
- package/dist/cli/commands/routing.d.ts.map +1 -0
- package/dist/cli/commands/routing.js +60 -0
- package/dist/cli/commands/routing.js.map +1 -0
- package/dist/cli/commands/test-server.d.ts +34 -0
- package/dist/cli/commands/test-server.d.ts.map +1 -0
- package/dist/cli/commands/test-server.js +86 -0
- package/dist/cli/commands/test-server.js.map +1 -0
- package/dist/cli/daemon.d.ts +60 -0
- package/dist/cli/daemon.d.ts.map +1 -0
- package/dist/cli/daemon.js +244 -0
- package/dist/cli/daemon.js.map +1 -0
- package/dist/cli/replay.d.ts +16 -0
- package/dist/cli/replay.d.ts.map +1 -0
- package/dist/cli/replay.js +89 -0
- package/dist/cli/replay.js.map +1 -0
- package/dist/cli/wizard/setup.d.ts +12 -0
- package/dist/cli/wizard/setup.d.ts.map +1 -0
- package/dist/cli/wizard/setup.js +71 -0
- package/dist/cli/wizard/setup.js.map +1 -0
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +4 -1
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/schema.d.ts +34 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/daemon/client.d.ts +99 -0
- package/dist/daemon/client.d.ts.map +1 -0
- package/dist/daemon/client.js +292 -0
- package/dist/daemon/client.js.map +1 -0
- package/dist/daemon/discovery.d.ts +50 -0
- package/dist/daemon/discovery.d.ts.map +1 -0
- package/dist/daemon/discovery.js +104 -0
- package/dist/daemon/discovery.js.map +1 -0
- package/dist/daemon/index.d.ts +16 -0
- package/dist/daemon/index.d.ts.map +1 -0
- package/dist/daemon/index.js +11 -0
- package/dist/daemon/index.js.map +1 -0
- package/dist/daemon/sandbox-api.d.ts +45 -0
- package/dist/daemon/sandbox-api.d.ts.map +1 -0
- package/dist/daemon/sandbox-api.js +74 -0
- package/dist/daemon/sandbox-api.js.map +1 -0
- package/dist/daemon/server.d.ts +65 -0
- package/dist/daemon/server.d.ts.map +1 -0
- package/dist/daemon/server.js +373 -0
- package/dist/daemon/server.js.map +1 -0
- package/dist/daemon/shared-kv.d.ts +81 -0
- package/dist/daemon/shared-kv.d.ts.map +1 -0
- package/dist/daemon/shared-kv.js +215 -0
- package/dist/daemon/shared-kv.js.map +1 -0
- package/dist/daemon/shared-lock.d.ts +71 -0
- package/dist/daemon/shared-lock.d.ts.map +1 -0
- package/dist/daemon/shared-lock.js +119 -0
- package/dist/daemon/shared-lock.js.map +1 -0
- package/dist/hub/mcp-hub.d.ts +23 -0
- package/dist/hub/mcp-hub.d.ts.map +1 -1
- package/dist/hub/mcp-hub.js +34 -1
- package/dist/hub/mcp-hub.js.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/observability/anomaly.d.ts +67 -0
- package/dist/observability/anomaly.d.ts.map +1 -0
- package/dist/observability/anomaly.js +141 -0
- package/dist/observability/anomaly.js.map +1 -0
- package/dist/observability/cost-predictor.d.ts +49 -0
- package/dist/observability/cost-predictor.d.ts.map +1 -0
- package/dist/observability/cost-predictor.js +145 -0
- package/dist/observability/cost-predictor.js.map +1 -0
- package/dist/observability/hot-path.d.ts +49 -0
- package/dist/observability/hot-path.d.ts.map +1 -0
- package/dist/observability/hot-path.js +125 -0
- package/dist/observability/hot-path.js.map +1 -0
- package/dist/observability/index.d.ts +10 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +10 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/replay.d.ts +104 -0
- package/dist/observability/replay.d.ts.map +1 -0
- package/dist/observability/replay.js +239 -0
- package/dist/observability/replay.js.map +1 -0
- package/dist/registry/built-in-recommendations.d.ts +54 -0
- package/dist/registry/built-in-recommendations.d.ts.map +1 -0
- package/dist/registry/built-in-recommendations.js +65 -0
- package/dist/registry/built-in-recommendations.js.map +1 -0
- package/dist/registry/events.d.ts +26 -0
- package/dist/registry/events.d.ts.map +1 -0
- package/dist/registry/events.js +22 -0
- package/dist/registry/events.js.map +1 -0
- package/dist/registry/index.d.ts +159 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +12 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/registry.d.ts +87 -0
- package/dist/registry/registry.d.ts.map +1 -0
- package/dist/registry/registry.js +294 -0
- package/dist/registry/registry.js.map +1 -0
- package/dist/registry/snapshot.d.ts +42 -0
- package/dist/registry/snapshot.d.ts.map +1 -0
- package/dist/registry/snapshot.js +71 -0
- package/dist/registry/snapshot.js.map +1 -0
- package/dist/registry/typegen.d.ts +48 -0
- package/dist/registry/typegen.d.ts.map +1 -0
- package/dist/registry/typegen.js +200 -0
- package/dist/registry/typegen.js.map +1 -0
- package/dist/registry/validator.d.ts +23 -0
- package/dist/registry/validator.d.ts.map +1 -0
- package/dist/registry/validator.js +50 -0
- package/dist/registry/validator.js.map +1 -0
- package/dist/reliability/breaker.d.ts +57 -0
- package/dist/reliability/breaker.d.ts.map +1 -0
- package/dist/reliability/breaker.js +130 -0
- package/dist/reliability/breaker.js.map +1 -0
- package/dist/reliability/errors.d.ts +78 -0
- package/dist/reliability/errors.d.ts.map +1 -0
- package/dist/reliability/errors.js +160 -0
- package/dist/reliability/errors.js.map +1 -0
- package/dist/reliability/gateway.d.ts +88 -0
- package/dist/reliability/gateway.d.ts.map +1 -0
- package/dist/reliability/gateway.js +180 -0
- package/dist/reliability/gateway.js.map +1 -0
- package/dist/reliability/index.d.ts +20 -0
- package/dist/reliability/index.d.ts.map +1 -0
- package/dist/reliability/index.js +16 -0
- package/dist/reliability/index.js.map +1 -0
- package/dist/reliability/profile.d.ts +49 -0
- package/dist/reliability/profile.d.ts.map +1 -0
- package/dist/reliability/profile.js +58 -0
- package/dist/reliability/profile.js.map +1 -0
- package/dist/reliability/retry.d.ts +39 -0
- package/dist/reliability/retry.d.ts.map +1 -0
- package/dist/reliability/retry.js +51 -0
- package/dist/reliability/retry.js.map +1 -0
- package/dist/reliability/timeout.d.ts +34 -0
- package/dist/reliability/timeout.d.ts.map +1 -0
- package/dist/reliability/timeout.js +53 -0
- package/dist/reliability/timeout.js.map +1 -0
- package/dist/runtime/executor.d.ts.map +1 -1
- package/dist/runtime/executor.js +122 -14
- package/dist/runtime/executor.js.map +1 -1
- package/dist/runtime/findtool/embed.d.ts +28 -0
- package/dist/runtime/findtool/embed.d.ts.map +1 -0
- package/dist/runtime/findtool/embed.js +85 -0
- package/dist/runtime/findtool/embed.js.map +1 -0
- package/dist/runtime/findtool/index.d.ts +52 -0
- package/dist/runtime/findtool/index.d.ts.map +1 -0
- package/dist/runtime/findtool/index.js +78 -0
- package/dist/runtime/findtool/index.js.map +1 -0
- package/dist/runtime/findtool/vector-index.d.ts +53 -0
- package/dist/runtime/findtool/vector-index.d.ts.map +1 -0
- package/dist/runtime/findtool/vector-index.js +71 -0
- package/dist/runtime/findtool/vector-index.js.map +1 -0
- package/dist/runtime/helpers/budget.d.ts +27 -0
- package/dist/runtime/helpers/budget.d.ts.map +1 -0
- package/dist/runtime/helpers/budget.js +103 -0
- package/dist/runtime/helpers/budget.js.map +1 -0
- package/dist/runtime/helpers/compact.d.ts +32 -0
- package/dist/runtime/helpers/compact.d.ts.map +1 -0
- package/dist/runtime/helpers/compact.js +93 -0
- package/dist/runtime/helpers/compact.js.map +1 -0
- package/dist/runtime/helpers/delta.d.ts +45 -0
- package/dist/runtime/helpers/delta.d.ts.map +1 -0
- package/dist/runtime/helpers/delta.js +116 -0
- package/dist/runtime/helpers/delta.js.map +1 -0
- package/dist/runtime/helpers/index.d.ts +16 -0
- package/dist/runtime/helpers/index.d.ts.map +1 -0
- package/dist/runtime/helpers/index.js +13 -0
- package/dist/runtime/helpers/index.js.map +1 -0
- package/dist/runtime/helpers/summarize.d.ts +24 -0
- package/dist/runtime/helpers/summarize.d.ts.map +1 -0
- package/dist/runtime/helpers/summarize.js +124 -0
- package/dist/runtime/helpers/summarize.js.map +1 -0
- package/dist/runtime/helpers/worker-preload.d.ts +25 -0
- package/dist/runtime/helpers/worker-preload.d.ts.map +1 -0
- package/dist/runtime/helpers/worker-preload.js +223 -0
- package/dist/runtime/helpers/worker-preload.js.map +1 -0
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/pool/index.d.ts +11 -0
- package/dist/runtime/pool/index.d.ts.map +1 -0
- package/dist/runtime/pool/index.js +8 -0
- package/dist/runtime/pool/index.js.map +1 -0
- package/dist/runtime/pool/recycle.d.ts +44 -0
- package/dist/runtime/pool/recycle.d.ts.map +1 -0
- package/dist/runtime/pool/recycle.js +50 -0
- package/dist/runtime/pool/recycle.js.map +1 -0
- package/dist/runtime/pool/worker-pool.d.ts +77 -0
- package/dist/runtime/pool/worker-pool.d.ts.map +1 -0
- package/dist/runtime/pool/worker-pool.js +216 -0
- package/dist/runtime/pool/worker-pool.js.map +1 -0
- package/dist/runtime/pool/worker.d.ts +80 -0
- package/dist/runtime/pool/worker.d.ts.map +1 -0
- package/dist/runtime/pool/worker.js +324 -0
- package/dist/runtime/pool/worker.js.map +1 -0
- package/dist/server/mcp-server.d.ts +3 -0
- package/dist/server/mcp-server.d.ts.map +1 -1
- package/dist/server/mcp-server.js +457 -3
- package/dist/server/mcp-server.js.map +1 -1
- package/dist/server/passthrough-registrar.d.ts +123 -0
- package/dist/server/passthrough-registrar.d.ts.map +1 -0
- package/dist/server/passthrough-registrar.js +199 -0
- package/dist/server/passthrough-registrar.js.map +1 -0
- package/dist/skills/skills-engine.d.ts +9 -1
- package/dist/skills/skills-engine.d.ts.map +1 -1
- package/dist/skills/skills-engine.js +20 -3
- package/dist/skills/skills-engine.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/tokenize.d.ts +55 -0
- package/dist/utils/tokenize.d.ts.map +1 -0
- package/dist/utils/tokenize.js +205 -0
- package/dist/utils/tokenize.js.map +1 -0
- package/dist/version.d.ts +3 -3
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +3 -3
- package/dist/version.js.map +1 -1
- package/package.json +13 -3
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight embedding for findTool
|
|
3
|
+
*
|
|
4
|
+
* Uses a character-level TF-IDF-style embedding that runs entirely in-process
|
|
5
|
+
* with no ONNX runtime dependency. This keeps the package lightweight while
|
|
6
|
+
* providing meaningful semantic similarity for MCP tool search.
|
|
7
|
+
*
|
|
8
|
+
* The embedding is a fixed-dimensional Float32Array built from:
|
|
9
|
+
* 1. Unigram token frequencies (normalised)
|
|
10
|
+
* 2. Bigram token frequencies (normalised)
|
|
11
|
+
*
|
|
12
|
+
* This is sufficient for the findTool use case where queries are short phrases
|
|
13
|
+
* and tool descriptions are relatively short, structured text.
|
|
14
|
+
*
|
|
15
|
+
* If $MCP_CONDUCTOR_EMBED_MODEL=onnx is set and @xenova/transformers is
|
|
16
|
+
* installed, we will delegate to MiniLM-L6 at runtime. Otherwise we fall
|
|
17
|
+
* back to the in-process TF-IDF embedder.
|
|
18
|
+
*
|
|
19
|
+
* @module runtime/findtool/embed
|
|
20
|
+
*/
|
|
21
|
+
// Embedding dimension for the in-process embedder
|
|
22
|
+
export const EMBED_DIM = 256;
|
|
23
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
24
|
+
// Tokeniser
|
|
25
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
26
|
+
function tokenise(text) {
|
|
27
|
+
return text
|
|
28
|
+
.toLowerCase()
|
|
29
|
+
.replace(/[^a-z0-9_\-. ]/g, ' ')
|
|
30
|
+
.split(/\s+/)
|
|
31
|
+
.filter(Boolean);
|
|
32
|
+
}
|
|
33
|
+
// Deterministic hash of a string to [0, EMBED_DIM)
|
|
34
|
+
function hashBucket(s) {
|
|
35
|
+
let h = 5381;
|
|
36
|
+
for (let i = 0; i < s.length; i++) {
|
|
37
|
+
h = ((h << 5) + h) ^ s.charCodeAt(i);
|
|
38
|
+
h = h >>> 0; // keep unsigned 32-bit
|
|
39
|
+
}
|
|
40
|
+
return h % EMBED_DIM;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Build a Float32Array embedding for a text string.
|
|
44
|
+
* The vector is L2-normalised for cosine similarity computation.
|
|
45
|
+
*/
|
|
46
|
+
export function embed(text) {
|
|
47
|
+
const vec = new Float32Array(EMBED_DIM);
|
|
48
|
+
const tokens = tokenise(text);
|
|
49
|
+
if (tokens.length === 0)
|
|
50
|
+
return vec;
|
|
51
|
+
// Unigram features
|
|
52
|
+
for (const token of tokens) {
|
|
53
|
+
vec[hashBucket(token)] = (vec[hashBucket(token)] ?? 0) + 1;
|
|
54
|
+
}
|
|
55
|
+
// Bigram features
|
|
56
|
+
for (let i = 0; i < tokens.length - 1; i++) {
|
|
57
|
+
const ti = tokens[i] ?? '';
|
|
58
|
+
const ti1 = tokens[i + 1] ?? '';
|
|
59
|
+
const bigram = ti + '_' + ti1;
|
|
60
|
+
vec[hashBucket(bigram)] = (vec[hashBucket(bigram)] ?? 0) + 0.5;
|
|
61
|
+
}
|
|
62
|
+
// L2 normalise
|
|
63
|
+
let norm = 0;
|
|
64
|
+
for (let i = 0; i < EMBED_DIM; i++)
|
|
65
|
+
norm += (vec[i] ?? 0) * (vec[i] ?? 0);
|
|
66
|
+
norm = Math.sqrt(norm);
|
|
67
|
+
if (norm > 0) {
|
|
68
|
+
for (let i = 0; i < EMBED_DIM; i++) {
|
|
69
|
+
const v = vec[i] ?? 0;
|
|
70
|
+
vec[i] = v / norm;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return vec;
|
|
74
|
+
}
|
|
75
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
76
|
+
// Cosine similarity
|
|
77
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
78
|
+
export function cosineSimilarity(a, b) {
|
|
79
|
+
let dot = 0;
|
|
80
|
+
for (let i = 0; i < a.length; i++)
|
|
81
|
+
dot += (a[i] ?? 0) * (b[i] ?? 0);
|
|
82
|
+
// Vectors are already L2-normalised so dot product == cosine similarity
|
|
83
|
+
return dot;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=embed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embed.js","sourceRoot":"","sources":["../../../src/runtime/findtool/embed.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* findTool — semantic tool discovery
|
|
3
|
+
*
|
|
4
|
+
* Provides `findTool(query, options)` for sandbox code. Lazily initialises
|
|
5
|
+
* the vector index on first call and re-indexes whenever the registry
|
|
6
|
+
* publishes a hot-reload event.
|
|
7
|
+
*
|
|
8
|
+
* @module runtime/findtool
|
|
9
|
+
*/
|
|
10
|
+
export type { SearchResult } from './vector-index.js';
|
|
11
|
+
export { embed, cosineSimilarity, EMBED_DIM } from './embed.js';
|
|
12
|
+
export interface FindToolOptions {
|
|
13
|
+
/** Number of results to return (default: 5) */
|
|
14
|
+
topK?: number;
|
|
15
|
+
/** Restrict search to these servers */
|
|
16
|
+
serverFilter?: string[];
|
|
17
|
+
}
|
|
18
|
+
export interface ToolEntry {
|
|
19
|
+
server: string;
|
|
20
|
+
tool: string;
|
|
21
|
+
description: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Register a tool loader callback. Called during system startup so the
|
|
25
|
+
* findTool module can lazily pull tool definitions from the registry.
|
|
26
|
+
*/
|
|
27
|
+
export declare function registerToolLoader(loader: () => Promise<ToolEntry[]>): void;
|
|
28
|
+
/**
|
|
29
|
+
* Immediately re-index all tools. Call this when the registry hot-reloads.
|
|
30
|
+
*/
|
|
31
|
+
export declare function reindex(): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Find MCP tools semantically similar to `query`.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* const tools = await findTool('list github issues', { topK: 3 });
|
|
37
|
+
*/
|
|
38
|
+
export declare function findTool(query: string, options?: FindToolOptions): Promise<Array<{
|
|
39
|
+
server: string;
|
|
40
|
+
tool: string;
|
|
41
|
+
description: string;
|
|
42
|
+
score: number;
|
|
43
|
+
}>>;
|
|
44
|
+
/**
|
|
45
|
+
* Seed the index directly (used in tests and worker bootstrap).
|
|
46
|
+
*/
|
|
47
|
+
export declare function seedIndex(tools: ToolEntry[]): void;
|
|
48
|
+
/**
|
|
49
|
+
* Reset state (tests only).
|
|
50
|
+
*/
|
|
51
|
+
export declare function resetFindTool(): void;
|
|
52
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/runtime/findtool/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAMhE,MAAM,WAAW,eAAe;IAC9B,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAiBD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC,GAAG,IAAI,CAG3E;AAED;;GAEG;AACH,wBAAsB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAK7C;AAcD;;;;;GAKG;AACH,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAGtF;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,CAGlD;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAIpC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* findTool — semantic tool discovery
|
|
3
|
+
*
|
|
4
|
+
* Provides `findTool(query, options)` for sandbox code. Lazily initialises
|
|
5
|
+
* the vector index on first call and re-indexes whenever the registry
|
|
6
|
+
* publishes a hot-reload event.
|
|
7
|
+
*
|
|
8
|
+
* @module runtime/findtool
|
|
9
|
+
*/
|
|
10
|
+
import { VectorIndex } from './vector-index.js';
|
|
11
|
+
export { embed, cosineSimilarity, EMBED_DIM } from './embed.js';
|
|
12
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
13
|
+
// Singleton index
|
|
14
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
15
|
+
let _index = null;
|
|
16
|
+
let _initialised = false;
|
|
17
|
+
let _toolLoader = null;
|
|
18
|
+
function getIndex() {
|
|
19
|
+
if (!_index) {
|
|
20
|
+
_index = new VectorIndex();
|
|
21
|
+
}
|
|
22
|
+
return _index;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Register a tool loader callback. Called during system startup so the
|
|
26
|
+
* findTool module can lazily pull tool definitions from the registry.
|
|
27
|
+
*/
|
|
28
|
+
export function registerToolLoader(loader) {
|
|
29
|
+
_toolLoader = loader;
|
|
30
|
+
_initialised = false; // force re-init on next search
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Immediately re-index all tools. Call this when the registry hot-reloads.
|
|
34
|
+
*/
|
|
35
|
+
export async function reindex() {
|
|
36
|
+
if (!_toolLoader)
|
|
37
|
+
return;
|
|
38
|
+
const tools = await _toolLoader();
|
|
39
|
+
getIndex().rebuild(tools);
|
|
40
|
+
_initialised = true;
|
|
41
|
+
}
|
|
42
|
+
async function ensureInitialised() {
|
|
43
|
+
if (_initialised)
|
|
44
|
+
return;
|
|
45
|
+
if (_toolLoader) {
|
|
46
|
+
await reindex();
|
|
47
|
+
}
|
|
48
|
+
_initialised = true;
|
|
49
|
+
}
|
|
50
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
51
|
+
// Public API
|
|
52
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
53
|
+
/**
|
|
54
|
+
* Find MCP tools semantically similar to `query`.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* const tools = await findTool('list github issues', { topK: 3 });
|
|
58
|
+
*/
|
|
59
|
+
export async function findTool(query, options = {}) {
|
|
60
|
+
await ensureInitialised();
|
|
61
|
+
return getIndex().search(query, options.topK ?? 5, options.serverFilter);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Seed the index directly (used in tests and worker bootstrap).
|
|
65
|
+
*/
|
|
66
|
+
export function seedIndex(tools) {
|
|
67
|
+
getIndex().rebuild(tools);
|
|
68
|
+
_initialised = true;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Reset state (tests only).
|
|
72
|
+
*/
|
|
73
|
+
export function resetFindTool() {
|
|
74
|
+
_index = null;
|
|
75
|
+
_initialised = false;
|
|
76
|
+
_toolLoader = null;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/runtime/findtool/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAmBhE,gFAAgF;AAChF,kBAAkB;AAClB,gFAAgF;AAEhF,IAAI,MAAM,GAAuB,IAAI,CAAC;AACtC,IAAI,YAAY,GAAG,KAAK,CAAC;AACzB,IAAI,WAAW,GAAwC,IAAI,CAAC;AAE5D,SAAS,QAAQ;IACf,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;IAC7B,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAkC;IACnE,WAAW,GAAG,MAAM,CAAC;IACrB,YAAY,GAAG,KAAK,CAAC,CAAC,+BAA+B;AACvD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO;IAC3B,IAAI,CAAC,WAAW;QAAE,OAAO;IACzB,MAAM,KAAK,GAAG,MAAM,WAAW,EAAE,CAAC;IAClC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC1B,YAAY,GAAG,IAAI,CAAC;AACtB,CAAC;AAED,KAAK,UAAU,iBAAiB;IAC9B,IAAI,YAAY;QAAE,OAAO;IACzB,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,OAAO,EAAE,CAAC;IAClB,CAAC;IACD,YAAY,GAAG,IAAI,CAAC;AACtB,CAAC;AAED,gFAAgF;AAChF,aAAa;AACb,gFAAgF;AAEhF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,KAAa,EACb,UAA2B,EAAE;IAE7B,MAAM,iBAAiB,EAAE,CAAC;IAC1B,OAAO,QAAQ,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;AAC3E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,KAAkB;IAC1C,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC1B,YAAY,GAAG,IAAI,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,GAAG,IAAI,CAAC;IACd,YAAY,GAAG,KAAK,CAAC;IACrB,WAAW,GAAG,IAAI,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory vector index for tool embeddings
|
|
3
|
+
*
|
|
4
|
+
* Stores Float32Array embeddings for each registered MCP tool and provides
|
|
5
|
+
* cosine-similarity nearest-neighbour search. Re-indexes on registry hot-reload.
|
|
6
|
+
*
|
|
7
|
+
* For large deployments (>10k tools) consider replacing with hnswlib-node or
|
|
8
|
+
* LanceDB (set $LANCEDB_URL to enable the remote backend).
|
|
9
|
+
*
|
|
10
|
+
* @module runtime/findtool/vector-index
|
|
11
|
+
*/
|
|
12
|
+
export interface IndexedTool {
|
|
13
|
+
server: string;
|
|
14
|
+
tool: string;
|
|
15
|
+
description: string;
|
|
16
|
+
vector: Float32Array;
|
|
17
|
+
}
|
|
18
|
+
export interface SearchResult {
|
|
19
|
+
server: string;
|
|
20
|
+
tool: string;
|
|
21
|
+
description: string;
|
|
22
|
+
score: number;
|
|
23
|
+
}
|
|
24
|
+
export declare class VectorIndex {
|
|
25
|
+
private entries;
|
|
26
|
+
/**
|
|
27
|
+
* Add or replace all tools for a server. Existing entries for that
|
|
28
|
+
* server are removed first.
|
|
29
|
+
*/
|
|
30
|
+
upsertServer(server: string, tools: Array<{
|
|
31
|
+
tool: string;
|
|
32
|
+
description: string;
|
|
33
|
+
}>): void;
|
|
34
|
+
/**
|
|
35
|
+
* Remove all entries for a server.
|
|
36
|
+
*/
|
|
37
|
+
removeServer(server: string): void;
|
|
38
|
+
/**
|
|
39
|
+
* Rebuild the entire index from a flat list of tools.
|
|
40
|
+
*/
|
|
41
|
+
rebuild(tools: Array<{
|
|
42
|
+
server: string;
|
|
43
|
+
tool: string;
|
|
44
|
+
description: string;
|
|
45
|
+
}>): void;
|
|
46
|
+
/**
|
|
47
|
+
* Search for tools similar to `query`.
|
|
48
|
+
*/
|
|
49
|
+
search(query: string, topK?: number, serverFilter?: string[]): SearchResult[];
|
|
50
|
+
get size(): number;
|
|
51
|
+
clear(): void;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=vector-index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vector-index.d.ts","sourceRoot":"","sources":["../../../src/runtime/findtool/vector-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAqB;IAEpC;;;OAGG;IACH,YAAY,CACV,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,GAClD,IAAI;IAWP;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAIlC;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI;IASlF;;OAEG;IACH,MAAM,CACJ,KAAK,EAAE,MAAM,EACb,IAAI,SAAI,EACR,YAAY,CAAC,EAAE,MAAM,EAAE,GACtB,YAAY,EAAE;IAmBjB,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory vector index for tool embeddings
|
|
3
|
+
*
|
|
4
|
+
* Stores Float32Array embeddings for each registered MCP tool and provides
|
|
5
|
+
* cosine-similarity nearest-neighbour search. Re-indexes on registry hot-reload.
|
|
6
|
+
*
|
|
7
|
+
* For large deployments (>10k tools) consider replacing with hnswlib-node or
|
|
8
|
+
* LanceDB (set $LANCEDB_URL to enable the remote backend).
|
|
9
|
+
*
|
|
10
|
+
* @module runtime/findtool/vector-index
|
|
11
|
+
*/
|
|
12
|
+
import { embed, cosineSimilarity } from './embed.js';
|
|
13
|
+
export class VectorIndex {
|
|
14
|
+
entries = [];
|
|
15
|
+
/**
|
|
16
|
+
* Add or replace all tools for a server. Existing entries for that
|
|
17
|
+
* server are removed first.
|
|
18
|
+
*/
|
|
19
|
+
upsertServer(server, tools) {
|
|
20
|
+
// Remove existing entries for this server
|
|
21
|
+
this.entries = this.entries.filter((e) => e.server !== server);
|
|
22
|
+
for (const { tool, description } of tools) {
|
|
23
|
+
const text = `${tool}\n${description}`;
|
|
24
|
+
const vector = embed(text);
|
|
25
|
+
this.entries.push({ server, tool, description, vector });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Remove all entries for a server.
|
|
30
|
+
*/
|
|
31
|
+
removeServer(server) {
|
|
32
|
+
this.entries = this.entries.filter((e) => e.server !== server);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Rebuild the entire index from a flat list of tools.
|
|
36
|
+
*/
|
|
37
|
+
rebuild(tools) {
|
|
38
|
+
this.entries = tools.map(({ server, tool, description }) => ({
|
|
39
|
+
server,
|
|
40
|
+
tool,
|
|
41
|
+
description,
|
|
42
|
+
vector: embed(`${tool}\n${description}`),
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Search for tools similar to `query`.
|
|
47
|
+
*/
|
|
48
|
+
search(query, topK = 5, serverFilter) {
|
|
49
|
+
if (this.entries.length === 0)
|
|
50
|
+
return [];
|
|
51
|
+
const queryVec = embed(query);
|
|
52
|
+
const candidates = serverFilter
|
|
53
|
+
? this.entries.filter((e) => serverFilter.includes(e.server))
|
|
54
|
+
: this.entries;
|
|
55
|
+
const scored = candidates.map((e) => ({
|
|
56
|
+
server: e.server,
|
|
57
|
+
tool: e.tool,
|
|
58
|
+
description: e.description,
|
|
59
|
+
score: cosineSimilarity(queryVec, e.vector),
|
|
60
|
+
}));
|
|
61
|
+
scored.sort((a, b) => b.score - a.score);
|
|
62
|
+
return scored.slice(0, topK);
|
|
63
|
+
}
|
|
64
|
+
get size() {
|
|
65
|
+
return this.entries.length;
|
|
66
|
+
}
|
|
67
|
+
clear() {
|
|
68
|
+
this.entries = [];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=vector-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vector-index.js","sourceRoot":"","sources":["../../../src/runtime/findtool/vector-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAgBrD,MAAM,OAAO,WAAW;IACd,OAAO,GAAkB,EAAE,CAAC;IAEpC;;;OAGG;IACH,YAAY,CACV,MAAc,EACd,KAAmD;QAEnD,0CAA0C;QAC1C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;QAE/D,KAAK,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,KAAK,EAAE,CAAC;YAC1C,MAAM,IAAI,GAAG,GAAG,IAAI,KAAK,WAAW,EAAE,CAAC;YACvC,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;YAC3B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,MAAc;QACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;IACjE,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,KAAmE;QACzE,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC;YAC3D,MAAM;YACN,IAAI;YACJ,WAAW;YACX,MAAM,EAAE,KAAK,CAAC,GAAG,IAAI,KAAK,WAAW,EAAE,CAAC;SACzC,CAAC,CAAC,CAAC;IACN,CAAC;IAED;;OAEG;IACH,MAAM,CACJ,KAAa,EACb,IAAI,GAAG,CAAC,EACR,YAAuB;QAEvB,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAEzC,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QAC9B,MAAM,UAAU,GAAG,YAAY;YAC7B,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAC7D,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;QAEjB,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACpC,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,KAAK,EAAE,gBAAgB,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC;SAC5C,CAAC,CAAC,CAAC;QAEJ,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QACzC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;IACpB,CAAC;CACF"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mcp.budget — Token budget enforcement helper
|
|
3
|
+
*
|
|
4
|
+
* Wraps an async function call and automatically trims the result to fit
|
|
5
|
+
* within a token budget. If the result cannot be trimmed below the budget,
|
|
6
|
+
* throws BudgetExceededError.
|
|
7
|
+
*
|
|
8
|
+
* Token estimation: 1 token ≈ 4 characters (conservative heuristic,
|
|
9
|
+
* same as summarize.ts).
|
|
10
|
+
*
|
|
11
|
+
* @module runtime/helpers/budget
|
|
12
|
+
*/
|
|
13
|
+
export declare class BudgetExceededError extends Error {
|
|
14
|
+
readonly estimatedTokens: number;
|
|
15
|
+
readonly maxTokens: number;
|
|
16
|
+
constructor(estimatedTokens: number, maxTokens: number);
|
|
17
|
+
}
|
|
18
|
+
export declare function estimateTokens(data: unknown): number;
|
|
19
|
+
/**
|
|
20
|
+
* Execute `fn` and auto-trim its return value to fit within `maxTokens`.
|
|
21
|
+
* Throws `BudgetExceededError` if the result cannot be trimmed.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* const result = await budget(500, async () => mcp.github.list_issues({ repo: 'foo' }));
|
|
25
|
+
*/
|
|
26
|
+
export declare function budget<T>(maxTokens: number, fn: () => T | Promise<T>): Promise<T>;
|
|
27
|
+
//# sourceMappingURL=budget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../../../src/runtime/helpers/budget.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AASH,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAEf,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAQvD;AAQD,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAOpD;AAqDD;;;;;;GAMG;AACH,wBAAsB,MAAM,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CASvF"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mcp.budget — Token budget enforcement helper
|
|
3
|
+
*
|
|
4
|
+
* Wraps an async function call and automatically trims the result to fit
|
|
5
|
+
* within a token budget. If the result cannot be trimmed below the budget,
|
|
6
|
+
* throws BudgetExceededError.
|
|
7
|
+
*
|
|
8
|
+
* Token estimation: 1 token ≈ 4 characters (conservative heuristic,
|
|
9
|
+
* same as summarize.ts).
|
|
10
|
+
*
|
|
11
|
+
* @module runtime/helpers/budget
|
|
12
|
+
*/
|
|
13
|
+
import { compact } from './compact.js';
|
|
14
|
+
import { summarize } from './summarize.js';
|
|
15
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
16
|
+
// Error type
|
|
17
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
18
|
+
export class BudgetExceededError extends Error {
|
|
19
|
+
estimatedTokens;
|
|
20
|
+
maxTokens;
|
|
21
|
+
constructor(estimatedTokens, maxTokens) {
|
|
22
|
+
super(`Result exceeds token budget after trimming: estimated ${estimatedTokens} tokens, budget ${maxTokens} tokens`);
|
|
23
|
+
this.name = 'BudgetExceededError';
|
|
24
|
+
this.estimatedTokens = estimatedTokens;
|
|
25
|
+
this.maxTokens = maxTokens;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
29
|
+
// Token estimation
|
|
30
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
31
|
+
const CHARS_PER_TOKEN = 4;
|
|
32
|
+
export function estimateTokens(data) {
|
|
33
|
+
try {
|
|
34
|
+
const serialized = JSON.stringify(data) ?? String(data);
|
|
35
|
+
return Math.ceil(serialized.length / CHARS_PER_TOKEN);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return Math.ceil(String(data).length / CHARS_PER_TOKEN);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
42
|
+
// Trimming strategy
|
|
43
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
44
|
+
/**
|
|
45
|
+
* Attempt to trim `data` to fit within `maxTokens`.
|
|
46
|
+
* Strategy:
|
|
47
|
+
* 1. Try compact with progressive maxItems reduction (100 → 50 → 20 → 5)
|
|
48
|
+
* 2. Try summarize (list → paragraph)
|
|
49
|
+
* 3. If still over budget, throw BudgetExceededError
|
|
50
|
+
*/
|
|
51
|
+
function tryTrim(data, maxTokens) {
|
|
52
|
+
const maxChars = maxTokens * CHARS_PER_TOKEN;
|
|
53
|
+
// Step 1: progressive compact on arrays
|
|
54
|
+
if (Array.isArray(data)) {
|
|
55
|
+
for (const maxItems of [100, 50, 20, 10, 5, 1]) {
|
|
56
|
+
const trimmed = compact(data, { maxItems, maxStringLength: 200 });
|
|
57
|
+
if (estimateTokens(trimmed) <= maxTokens)
|
|
58
|
+
return trimmed;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Step 2: compact objects with depth restriction
|
|
62
|
+
if (typeof data === 'object' && data !== null) {
|
|
63
|
+
for (const maxDepth of [5, 3, 2, 1]) {
|
|
64
|
+
const trimmed = compact(data, { maxDepth, maxItems: 20, maxStringLength: 200 });
|
|
65
|
+
if (estimateTokens(trimmed) <= maxTokens)
|
|
66
|
+
return trimmed;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Step 3: summarize as list
|
|
70
|
+
const listSummary = summarize(data, { maxTokens, style: 'list' });
|
|
71
|
+
if (estimateTokens(listSummary) <= maxTokens)
|
|
72
|
+
return listSummary;
|
|
73
|
+
// Step 4: summarize as paragraph (more aggressive)
|
|
74
|
+
const paraSummary = summarize(data, { maxTokens, style: 'paragraph' });
|
|
75
|
+
if (estimateTokens(paraSummary) <= maxTokens)
|
|
76
|
+
return paraSummary;
|
|
77
|
+
// Step 5: raw string clip
|
|
78
|
+
const raw = typeof data === 'string' ? data : JSON.stringify(data) ?? String(data);
|
|
79
|
+
const clipped = raw.slice(0, maxChars - 1) + '…';
|
|
80
|
+
if (estimateTokens(clipped) <= maxTokens)
|
|
81
|
+
return clipped;
|
|
82
|
+
// Untrimmable
|
|
83
|
+
throw new BudgetExceededError(estimateTokens(data), maxTokens);
|
|
84
|
+
}
|
|
85
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
86
|
+
// Public API
|
|
87
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
88
|
+
/**
|
|
89
|
+
* Execute `fn` and auto-trim its return value to fit within `maxTokens`.
|
|
90
|
+
* Throws `BudgetExceededError` if the result cannot be trimmed.
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* const result = await budget(500, async () => mcp.github.list_issues({ repo: 'foo' }));
|
|
94
|
+
*/
|
|
95
|
+
export async function budget(maxTokens, fn) {
|
|
96
|
+
const result = await fn();
|
|
97
|
+
const estimated = estimateTokens(result);
|
|
98
|
+
if (estimated <= maxTokens) {
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
return tryTrim(result, maxTokens);
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=budget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget.js","sourceRoot":"","sources":["../../../src/runtime/helpers/budget.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mcp.compact — Field selection and data trimming helper
|
|
3
|
+
*
|
|
4
|
+
* Zero-roundtrip sandbox helper. Reduces large data objects to only the
|
|
5
|
+
* fields the caller cares about, truncates arrays, clips strings, and
|
|
6
|
+
* limits nesting depth. All operations are synchronous and in-process.
|
|
7
|
+
*
|
|
8
|
+
* @module runtime/helpers/compact
|
|
9
|
+
*/
|
|
10
|
+
export interface CompactOptions {
|
|
11
|
+
/**
|
|
12
|
+
* Dot-path field selectors to retain. Supports nested paths like
|
|
13
|
+
* 'labels.name'. If omitted, all fields are retained (only structural
|
|
14
|
+
* limits apply).
|
|
15
|
+
*/
|
|
16
|
+
fields?: string[];
|
|
17
|
+
/** Maximum number of items to retain in any array. */
|
|
18
|
+
maxItems?: number;
|
|
19
|
+
/** Maximum object nesting depth (root = depth 0). */
|
|
20
|
+
maxDepth?: number;
|
|
21
|
+
/** Maximum character length for any string value. */
|
|
22
|
+
maxStringLength?: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Compact a data value by selecting fields, truncating arrays, clipping
|
|
26
|
+
* strings, and limiting nesting depth.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* const lean = compact(issues, { fields: ['id', 'title', 'labels.name'], maxItems: 20 });
|
|
30
|
+
*/
|
|
31
|
+
export declare function compact<T>(data: T, options?: CompactOptions): T;
|
|
32
|
+
//# sourceMappingURL=compact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compact.d.ts","sourceRoot":"","sources":["../../../src/runtime/helpers/compact.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qDAAqD;IACrD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAuFD;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,GAAE,cAAmB,GAAG,CAAC,CAOnE"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mcp.compact — Field selection and data trimming helper
|
|
3
|
+
*
|
|
4
|
+
* Zero-roundtrip sandbox helper. Reduces large data objects to only the
|
|
5
|
+
* fields the caller cares about, truncates arrays, clips strings, and
|
|
6
|
+
* limits nesting depth. All operations are synchronous and in-process.
|
|
7
|
+
*
|
|
8
|
+
* @module runtime/helpers/compact
|
|
9
|
+
*/
|
|
10
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
11
|
+
// Internal helpers
|
|
12
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
13
|
+
/**
|
|
14
|
+
* Parse a dot-path like "labels.name" into a nested selector tree.
|
|
15
|
+
* { labels: { name: true }, id: true }
|
|
16
|
+
*/
|
|
17
|
+
function buildSelectorTree(fields) {
|
|
18
|
+
const tree = {};
|
|
19
|
+
for (const field of fields) {
|
|
20
|
+
const parts = field.split('.');
|
|
21
|
+
let node = tree;
|
|
22
|
+
for (let i = 0; i < parts.length; i++) {
|
|
23
|
+
const part = parts[i] ?? '';
|
|
24
|
+
if (i === parts.length - 1) {
|
|
25
|
+
node[part] = true;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
if (typeof node[part] !== 'object' || node[part] === null) {
|
|
29
|
+
node[part] = {};
|
|
30
|
+
}
|
|
31
|
+
node = node[part];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return tree;
|
|
36
|
+
}
|
|
37
|
+
function trimValue(value, selector, opts, depth) {
|
|
38
|
+
const maxDepth = opts.maxDepth ?? Infinity;
|
|
39
|
+
if (depth > maxDepth) {
|
|
40
|
+
return typeof value === 'object' && value !== null ? '[truncated]' : value;
|
|
41
|
+
}
|
|
42
|
+
if (typeof value === 'string') {
|
|
43
|
+
const max = opts.maxStringLength;
|
|
44
|
+
if (max !== undefined && value.length > max) {
|
|
45
|
+
return value.slice(0, max) + '…';
|
|
46
|
+
}
|
|
47
|
+
return value;
|
|
48
|
+
}
|
|
49
|
+
if (Array.isArray(value)) {
|
|
50
|
+
const maxItems = opts.maxItems;
|
|
51
|
+
const arr = maxItems !== undefined ? value.slice(0, maxItems) : value;
|
|
52
|
+
return arr.map((item) => trimValue(item, selector, opts, depth + 1));
|
|
53
|
+
}
|
|
54
|
+
if (typeof value === 'object' && value !== null) {
|
|
55
|
+
const obj = value;
|
|
56
|
+
const result = {};
|
|
57
|
+
if (selector && Object.keys(selector).length > 0) {
|
|
58
|
+
// Only keep selected keys
|
|
59
|
+
for (const key of Object.keys(selector)) {
|
|
60
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
61
|
+
const childSelector = selector[key];
|
|
62
|
+
const nextSelector = childSelector === true ? null : childSelector;
|
|
63
|
+
result[key] = trimValue(obj[key], nextSelector, opts, depth + 1);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
// No field filter — apply structural limits only
|
|
69
|
+
for (const key of Object.keys(obj)) {
|
|
70
|
+
result[key] = trimValue(obj[key], null, opts, depth + 1);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
return value;
|
|
76
|
+
}
|
|
77
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
78
|
+
// Public API
|
|
79
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
80
|
+
/**
|
|
81
|
+
* Compact a data value by selecting fields, truncating arrays, clipping
|
|
82
|
+
* strings, and limiting nesting depth.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* const lean = compact(issues, { fields: ['id', 'title', 'labels.name'], maxItems: 20 });
|
|
86
|
+
*/
|
|
87
|
+
export function compact(data, options = {}) {
|
|
88
|
+
const selector = options.fields && options.fields.length > 0
|
|
89
|
+
? buildSelectorTree(options.fields)
|
|
90
|
+
: null;
|
|
91
|
+
return trimValue(data, selector, options, 0);
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=compact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compact.js","sourceRoot":"","sources":["../../../src/runtime/helpers/compact.ts"],"names":[],"mappings":"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"}
|