@vurb/core 3.7.12 → 3.8.0
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 +63 -0
- package/dist/cli/commands/deploy.js +1 -1
- package/dist/cli/commands/deploy.js.map +1 -1
- package/dist/cli/commands/dev.js +1 -1
- package/dist/cli/commands/dev.js.map +1 -1
- package/dist/client/VurbClient.js +2 -2
- package/dist/client/VurbClient.js.map +1 -1
- package/dist/core/StandardSchema.js +1 -1
- package/dist/core/StandardSchema.js.map +1 -1
- package/dist/core/builder/BuildPipeline.d.ts.map +1 -1
- package/dist/core/builder/BuildPipeline.js +11 -15
- package/dist/core/builder/BuildPipeline.js.map +1 -1
- package/dist/core/builder/FluentToolBuilder.d.ts +1 -1
- package/dist/core/builder/FluentToolBuilder.js +3 -3
- package/dist/core/builder/FluentToolBuilder.js.map +1 -1
- package/dist/core/builder/GroupedToolBuilder.js +2 -2
- package/dist/core/builder/GroupedToolBuilder.js.map +1 -1
- package/dist/core/execution/ExecutionPipeline.js +3 -3
- package/dist/core/execution/ExecutionPipeline.js.map +1 -1
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/initVurb.js +2 -2
- package/dist/core/initVurb.js.map +1 -1
- package/dist/core/middleware/AuditTrail.js +1 -1
- package/dist/core/middleware/AuditTrail.js.map +1 -1
- package/dist/core/middleware/ContextDerivation.js +1 -1
- package/dist/core/middleware/ContextDerivation.js.map +1 -1
- package/dist/core/middleware/InputFirewall.js +1 -1
- package/dist/core/middleware/InputFirewall.js.map +1 -1
- package/dist/core/middleware/RateLimiter.js +1 -1
- package/dist/core/middleware/RateLimiter.js.map +1 -1
- package/dist/core/registry/ToolRegistry.js +1 -1
- package/dist/core/registry/ToolRegistry.js.map +1 -1
- package/dist/core/response.d.ts +53 -2
- package/dist/core/response.d.ts.map +1 -1
- package/dist/core/response.js +42 -1
- package/dist/core/response.js.map +1 -1
- package/dist/domain/Group.js +2 -2
- package/dist/domain/Group.js.map +1 -1
- package/dist/exposition/ExpositionCompiler.d.ts +1 -1
- package/dist/exposition/ExpositionCompiler.js +2 -2
- package/dist/exposition/ExpositionCompiler.js.map +1 -1
- package/dist/fsm/StateMachineGate.d.ts.map +1 -1
- package/dist/fsm/StateMachineGate.js +9 -4
- package/dist/fsm/StateMachineGate.js.map +1 -1
- package/dist/handoff/DelegationToken.d.ts +58 -0
- package/dist/handoff/DelegationToken.d.ts.map +1 -0
- package/dist/handoff/DelegationToken.js +186 -0
- package/dist/handoff/DelegationToken.js.map +1 -0
- package/dist/handoff/HandoffStateStore.d.ts +52 -0
- package/dist/handoff/HandoffStateStore.d.ts.map +1 -0
- package/dist/handoff/HandoffStateStore.js +73 -0
- package/dist/handoff/HandoffStateStore.js.map +1 -0
- package/dist/handoff/index.d.ts +32 -0
- package/dist/handoff/index.d.ts.map +1 -0
- package/dist/handoff/index.js +19 -0
- package/dist/handoff/index.js.map +1 -0
- package/dist/handoff/middleware.d.ts +36 -0
- package/dist/handoff/middleware.d.ts.map +1 -0
- package/dist/handoff/middleware.js +118 -0
- package/dist/handoff/middleware.js.map +1 -0
- package/dist/handoff/types.d.ts +51 -0
- package/dist/handoff/types.d.ts.map +1 -0
- package/dist/handoff/types.js +9 -0
- package/dist/handoff/types.js.map +1 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/introspection/CryptoAttestation.js +1 -1
- package/dist/introspection/CryptoAttestation.js.map +1 -1
- package/dist/introspection/GovernanceObserver.js +1 -1
- package/dist/introspection/GovernanceObserver.js.map +1 -1
- package/dist/introspection/TokenEconomics.js +1 -1
- package/dist/introspection/TokenEconomics.js.map +1 -1
- package/dist/introspection/ToolContract.js +2 -2
- package/dist/introspection/ToolContract.js.map +1 -1
- package/dist/observability/TelemetryBus.js +3 -3
- package/dist/observability/TelemetryBus.js.map +1 -1
- package/dist/presenter/JudgeChain.js +2 -2
- package/dist/presenter/JudgeChain.js.map +1 -1
- package/dist/presenter/PromptFirewall.js +2 -2
- package/dist/presenter/PromptFirewall.js.map +1 -1
- package/dist/presenter/RedactEngine.js +3 -3
- package/dist/presenter/RedactEngine.js.map +1 -1
- package/dist/prompt/FluentPromptBuilder.js +1 -1
- package/dist/prompt/FluentPromptBuilder.js.map +1 -1
- package/dist/resource/ResourceRegistry.d.ts +1 -1
- package/dist/resource/ResourceRegistry.js +1 -1
- package/dist/sandbox/SandboxEngine.d.ts +1 -1
- package/dist/sandbox/SandboxEngine.d.ts.map +1 -1
- package/dist/sandbox/SandboxEngine.js +16 -7
- package/dist/sandbox/SandboxEngine.js.map +1 -1
- package/dist/sandbox/SandboxGuard.js +5 -5
- package/dist/sandbox/SandboxGuard.js.map +1 -1
- package/dist/server/DevServer.js +2 -2
- package/dist/server/DevServer.js.map +1 -1
- package/dist/server/ServerAttachment.d.ts +41 -1
- package/dist/server/ServerAttachment.d.ts.map +1 -1
- package/dist/server/ServerAttachment.js +102 -37
- package/dist/server/ServerAttachment.js.map +1 -1
- package/dist/server/ServerResolver.d.ts.map +1 -1
- package/dist/server/ServerResolver.js +15 -2
- package/dist/server/ServerResolver.js.map +1 -1
- package/dist/server/autoDiscover.js +2 -2
- package/dist/server/autoDiscover.js.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/startServer.js +2 -2
- package/dist/server/startServer.js.map +1 -1
- package/dist/state-sync/StateSyncBuilder.d.ts +1 -1
- package/dist/state-sync/StateSyncBuilder.js +2 -2
- package/dist/state-sync/StateSyncBuilder.js.map +1 -1
- package/package.json +151 -151
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SandboxEngine.d.ts","sourceRoot":"","sources":["../../src/sandbox/SandboxEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAGH,OAAO,EAAyB,KAAK,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAK/F;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,aAAa;IAC1B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,gBAAgB,GACtB,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,kBAAkB,GAClB,cAAc,GACd,cAAc,GACd,aAAa,GACb,SAAS,CAAC;AAEhB;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,GAAG,OAAO,IAC/B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACtE;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAkCtF;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,aAAa;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IAEzC,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAC,CAAgB;IACnC,+DAA+D;IAC/D,OAAO,CAAC,iBAAiB,CAAK;gBAElB,MAAM,CAAC,EAAE,aAAa;IAgBlC;;;;OAIG;IACH,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI;IAKpC;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACG,OAAO,CAAC,CAAC,GAAG,OAAO,EACrB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,OAAO,EACb,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GACnC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"SandboxEngine.d.ts","sourceRoot":"","sources":["../../src/sandbox/SandboxEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAGH,OAAO,EAAyB,KAAK,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAK/F;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,aAAa;IAC1B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,gBAAgB,GACtB,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,kBAAkB,GAClB,cAAc,GACd,cAAc,GACd,aAAa,GACb,SAAS,CAAC;AAEhB;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,GAAG,OAAO,IAC/B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACtE;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAkCtF;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,aAAa;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IAEzC,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAC,CAAgB;IACnC,+DAA+D;IAC/D,OAAO,CAAC,iBAAiB,CAAK;gBAElB,MAAM,CAAC,EAAE,aAAa;IAgBlC;;;;OAIG;IACH,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI;IAKpC;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACG,OAAO,CAAC,CAAC,GAAG,OAAO,EACrB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,OAAO,EACb,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GACnC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IA8K5B;;;;;OAKG;IACH,OAAO,IAAI,IAAI;IAUf;;OAEG;IACH,IAAI,UAAU,IAAI,OAAO,CAExB;IAED;;;OAGG;IACH,OAAO,CAAC,cAAc;IActB;;;OAGG;IACH,OAAO,CAAC,cAAc;IAatB;;;OAGG;IACH,OAAO,CAAC,cAAc;CA6CzB"}
|
|
@@ -52,7 +52,7 @@ const DEFAULT_TIMEOUT_MS = 5_000;
|
|
|
52
52
|
const DEFAULT_MEMORY_LIMIT_MB = 128;
|
|
53
53
|
const DEFAULT_MAX_OUTPUT_BYTES = 1_048_576; // 1MB
|
|
54
54
|
const MAX_CODE_LENGTH = 65_536; // 64KB — generous for any legitimate sandbox function
|
|
55
|
-
const TEXT_ENCODER = new TextEncoder(); //
|
|
55
|
+
const TEXT_ENCODER = new TextEncoder(); // reuse stateless encoder
|
|
56
56
|
// ── Lazy Require ─────────────────────────────────────────
|
|
57
57
|
/**
|
|
58
58
|
* Lazy-load isolated-vm to avoid hard dependency.
|
|
@@ -79,7 +79,7 @@ function getIvm() {
|
|
|
79
79
|
/**
|
|
80
80
|
* Reset the cached isolated-vm module reference.
|
|
81
81
|
* Exported exclusively for testing — allows mock/unmock cycles
|
|
82
|
-
* without process restart (
|
|
82
|
+
* without process restart ().
|
|
83
83
|
* @internal
|
|
84
84
|
*/
|
|
85
85
|
export function resetIvmCache() {
|
|
@@ -208,14 +208,21 @@ export class SandboxEngine {
|
|
|
208
208
|
// When the signal fires and this is the ONLY execution in
|
|
209
209
|
// progress, we call isolate.dispose() to kill V8 instantly.
|
|
210
210
|
//
|
|
211
|
-
// Bug
|
|
211
|
+
// Bug fix: `context` is assigned later via `await isolate.createContext()`,
|
|
212
|
+
// so a plain closure over `let context` would capture `undefined` if the abort
|
|
213
|
+
// fires before that line. We use a mutable reference object (`ctxRef`) so the
|
|
214
|
+
// closure always sees the latest assigned value.
|
|
215
|
+
//
|
|
216
|
+
// When other executions share the same isolate
|
|
212
217
|
// (activeExecutions > 1), we cannot dispose the isolate
|
|
213
|
-
// without killing all concurrent work (
|
|
218
|
+
// without killing all concurrent work ( fix). Instead
|
|
214
219
|
// we set the `aborted` flag AND release the per-request
|
|
215
220
|
// context (if already created) to interrupt the running
|
|
216
221
|
// script without collateral damage. If context is not yet
|
|
217
222
|
// created, the script will terminate at its timeout boundary.
|
|
218
223
|
let aborted = false;
|
|
224
|
+
// Mutable wrapper so the abort closure always reads the latest context ref.
|
|
225
|
+
const ctxRef = { current: undefined };
|
|
219
226
|
const onAbort = signal ? () => {
|
|
220
227
|
aborted = true;
|
|
221
228
|
if (this._activeExecutions <= 1) {
|
|
@@ -226,9 +233,9 @@ export class SandboxEngine {
|
|
|
226
233
|
}
|
|
227
234
|
else {
|
|
228
235
|
// Release this request's context to interrupt execution
|
|
229
|
-
// without killing the shared isolate (
|
|
236
|
+
// without killing the shared isolate ().
|
|
230
237
|
try {
|
|
231
|
-
|
|
238
|
+
ctxRef.current?.release();
|
|
232
239
|
}
|
|
233
240
|
catch { /* may already be released */ }
|
|
234
241
|
}
|
|
@@ -247,8 +254,10 @@ export class SandboxEngine {
|
|
|
247
254
|
try {
|
|
248
255
|
// Create pristine context (NO globals injected — this IS the security)
|
|
249
256
|
context = await isolate.createContext();
|
|
257
|
+
// Keep ctxRef in sync so the abort handler can release it if needed.
|
|
258
|
+
ctxRef.current = context;
|
|
250
259
|
// Deep-copy data into isolated heap (no references!)
|
|
251
|
-
//
|
|
260
|
+
// catch serialization errors from ExternalCopy separately
|
|
252
261
|
try {
|
|
253
262
|
inputCopy = new ivm.ExternalCopy(data);
|
|
254
263
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SandboxEngine.js","sourceRoot":"","sources":["../../src/sandbox/SandboxEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAA6C,MAAM,oCAAoC,CAAC;AAC/F,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAoFvD,4DAA4D;AAE5D,MAAM,kBAAkB,GAAG,KAAK,CAAC;AACjC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AACpC,MAAM,wBAAwB,GAAG,SAAS,CAAC,CAAC,MAAM;AAClD,MAAM,eAAe,GAAG,MAAM,CAAC,CAAC,sDAAsD;AACtF,MAAM,YAAY,GAAG,IAAI,WAAW,EAAE,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"SandboxEngine.js","sourceRoot":"","sources":["../../src/sandbox/SandboxEngine.ts"],"names":[],"mappings":"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"}
|
|
@@ -42,7 +42,7 @@ const SUSPICIOUS_PATTERNS = [
|
|
|
42
42
|
{ pattern: /\bimport\s*\(/, reason: 'Dynamic import() is not available in the sandbox.' },
|
|
43
43
|
{ pattern: /\bimport\s+/, reason: 'ES module imports are not available in the sandbox.' },
|
|
44
44
|
{ pattern: /\brequire\s*\(/, reason: 'require() is not available in the sandbox.' },
|
|
45
|
-
//
|
|
45
|
+
// fail-fast for eval()/Function() — no security risk (empty Context),
|
|
46
46
|
// but provides immediate, actionable feedback to the LLM.
|
|
47
47
|
{ pattern: /\beval\s*\(/, reason: 'eval() has no effect in the sandbox — use direct expressions instead.' },
|
|
48
48
|
{ pattern: /\bnew\s+Function\s*\(/, reason: 'new Function() has no effect in the sandbox — use direct expressions instead.' },
|
|
@@ -57,7 +57,7 @@ const FUNCTION_PATTERNS = [
|
|
|
57
57
|
/^\s*function\s*\(/, // function(x) { ... }
|
|
58
58
|
/^\s*function\s+\w+\s*\(/, // function name(x) { ... }
|
|
59
59
|
// Async patterns kept for shape recognition — SUSPICIOUS_PATTERNS
|
|
60
|
-
// will reject them before they reach execution (
|
|
60
|
+
// will reject them before they reach execution ()
|
|
61
61
|
/^\s*async\s+\(.*\)\s*=>/s, // async (x) => ...
|
|
62
62
|
/^\s*async\s+function\s*\(/, // async function(x) { ... }
|
|
63
63
|
/^\s*async\s+[a-zA-Z_$]\w*\s*=>/, // async x => ...
|
|
@@ -105,7 +105,7 @@ export function validateSandboxCode(code) {
|
|
|
105
105
|
return { ok: false, violation: reason };
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
|
-
//
|
|
108
|
+
// detect `async` anywhere in the code (not just at the start).
|
|
109
109
|
// Strip string literals first to avoid false positives on e.g. "async".
|
|
110
110
|
if (containsAsyncKeyword(trimmed)) {
|
|
111
111
|
return {
|
|
@@ -133,11 +133,11 @@ function stripStringLiterals(code) {
|
|
|
133
133
|
}
|
|
134
134
|
/**
|
|
135
135
|
* Check if `async` appears as a keyword anywhere in the code,
|
|
136
|
-
* ignoring occurrences inside string literals (
|
|
136
|
+
* ignoring occurrences inside string literals ().
|
|
137
137
|
* @internal
|
|
138
138
|
*/
|
|
139
139
|
function containsAsyncKeyword(code) {
|
|
140
|
-
//
|
|
140
|
+
// negative lookbehind excludes property access (d.async)
|
|
141
141
|
// Only matches `async` as a keyword (not preceded by a dot)
|
|
142
142
|
return /(?<!\.)\basync\b/.test(stripStringLiterals(code));
|
|
143
143
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SandboxGuard.js","sourceRoot":"","sources":["../../src/sandbox/SandboxGuard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAWH,4DAA4D;AAE5D;;;;GAIG;AACH,MAAM,mBAAmB,GAAuD;IAC5E,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,mDAAmD,EAAE;IACzF,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,qDAAqD,EAAE;IACzF,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,4CAA4C,EAAE;IACnF,
|
|
1
|
+
{"version":3,"file":"SandboxGuard.js","sourceRoot":"","sources":["../../src/sandbox/SandboxGuard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAWH,4DAA4D;AAE5D;;;;GAIG;AACH,MAAM,mBAAmB,GAAuD;IAC5E,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,mDAAmD,EAAE;IACzF,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,qDAAqD,EAAE;IACzF,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,4CAA4C,EAAE;IACnF,sEAAsE;IACtE,0DAA0D;IAC1D,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,uEAAuE,EAAE;IAC3G,EAAE,OAAO,EAAE,uBAAuB,EAAE,MAAM,EAAE,+EAA+E,EAAE;CAChI,CAAC;AAEF;;;GAGG;AACH,MAAM,iBAAiB,GAA0B;IAC7C,kBAAkB,EAAe,aAAa;IAC9C,wBAAwB,EAAQ,WAAW;IAC3C,mBAAmB,EAAc,sBAAsB;IACvD,yBAAyB,EAAQ,2BAA2B;IAC5D,kEAAkE;IAClE,kDAAkD;IAClD,0BAA0B,EAAO,mBAAmB;IACpD,2BAA2B,EAAM,4BAA4B;IAC7D,gCAAgC,EAAE,iBAAiB;CACtD,CAAC;AAEF,4DAA4D;AAE5D;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC5C,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,kCAAkC,EAAE,CAAC;IACxE,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAE5B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,kCAAkC,EAAE,CAAC;IACxE,CAAC;IAED,yCAAyC;IACzC,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IACvE,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACrB,OAAO;YACH,EAAE,EAAE,KAAK;YACT,SAAS,EACL,wDAAwD;gBACxD,mDAAmD;SAC1D,CAAC;IACN,CAAC;IAED,2DAA2D;IAC3D,KAAK,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,mBAAmB,EAAE,CAAC;QACpD,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACxB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;QAC5C,CAAC;IACL,CAAC;IAED,+DAA+D;IAC/D,wEAAwE;IACxE,IAAI,oBAAoB,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,OAAO;YACH,EAAE,EAAE,KAAK;YACT,SAAS,EACL,oDAAoD;gBACpD,2DAA2D;gBAC3D,+CAA+C;gBAC/C,qCAAqC;SAC5C,CAAC;IACN,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACxB,CAAC;AAED,4DAA4D;AAE5D;;;;;GAKG;AACH,SAAS,mBAAmB,CAAC,IAAY;IACrC,oEAAoE;IACpE,2DAA2D;IAC3D,yEAAyE;IACzE,OAAO,IAAI,CAAC,OAAO,CACf,wFAAwF,EACxF,EAAE,CACL,CAAC;AACN,CAAC;AAED;;;;GAIG;AACH,SAAS,oBAAoB,CAAC,IAAY;IACtC,yDAAyD;IACzD,4DAA4D;IAC5D,OAAO,kBAAkB,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC;AAC9D,CAAC"}
|
package/dist/server/DevServer.js
CHANGED
|
@@ -205,7 +205,7 @@ export function createDevServer(config) {
|
|
|
205
205
|
esmWarningEmitted = true;
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
|
-
// Transfer collected builders to the real registry (
|
|
208
|
+
// Transfer collected builders to the real registry ( fix)
|
|
209
209
|
if (builders.length > 0 && config.registry) {
|
|
210
210
|
if (typeof config.registry.clear === 'function') {
|
|
211
211
|
config.registry.clear();
|
|
@@ -238,7 +238,7 @@ export function createDevServer(config) {
|
|
|
238
238
|
await performReload('(initial)');
|
|
239
239
|
// Start watching
|
|
240
240
|
const watchOptions = { recursive: true };
|
|
241
|
-
//
|
|
241
|
+
// warn on Linux with Node.js < 20 where recursive watch is unsupported
|
|
242
242
|
if (process.platform === 'linux' && parseInt(process.versions.node, 10) < 20) {
|
|
243
243
|
// eslint-disable-next-line no-console
|
|
244
244
|
console.warn('[vurb dev] Warning: recursive fs.watch() is not fully supported on Linux with Node.js < 20. ' +
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DevServer.js","sourceRoot":"","sources":["../../src/server/DevServer.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"DevServer.js","sourceRoot":"","sources":["../../src/server/DevServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Tool as McpTool } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
-
import { type ToolResponse } from '../core/response.js';
|
|
2
|
+
import { type ToolResponse, type HandoffPayload } from '../core/response.js';
|
|
3
3
|
import { type ToolBuilder } from '../core/types.js';
|
|
4
4
|
import { type ProgressSink } from '../core/execution/ProgressHelper.js';
|
|
5
5
|
import { type DebugObserverFn } from '../observability/DebugObserver.js';
|
|
@@ -331,6 +331,44 @@ export interface AttachOptions<TContext> {
|
|
|
331
331
|
* @see {@link defineResource} for creating resources
|
|
332
332
|
*/
|
|
333
333
|
resources?: ResourceRegistry<TContext>;
|
|
334
|
+
/**
|
|
335
|
+
* SwarmGateway for federated multi-agent handoffs (Federated Handoff Protocol).
|
|
336
|
+
*
|
|
337
|
+
* When provided, the framework detects `HandoffResponse` from tool handlers
|
|
338
|
+
* and activates the B2BUA tunnel to the upstream MCP micro-server.
|
|
339
|
+
* Zero overhead when omitted — no FHP code runs.
|
|
340
|
+
*
|
|
341
|
+
* Import from `@vurb/swarm`:
|
|
342
|
+
* ```typescript
|
|
343
|
+
* import { SwarmGateway } from '@vurb/swarm';
|
|
344
|
+
*
|
|
345
|
+
* registry.attachToServer(server, {
|
|
346
|
+
* swarmGateway: new SwarmGateway({
|
|
347
|
+
* registry: { finance: 'http://finance-agent:8081' },
|
|
348
|
+
* delegationSecret: process.env.VURB_DELEGATION_SECRET!,
|
|
349
|
+
* }),
|
|
350
|
+
* });
|
|
351
|
+
* ```
|
|
352
|
+
*/
|
|
353
|
+
swarmGateway?: ISwarmGateway;
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Minimal duck-typed interface for the SwarmGateway.
|
|
357
|
+
* Defined here to avoid a hard dependency on `@vurb/swarm` from `@vurb/core`.
|
|
358
|
+
* The real `SwarmGateway` from `@vurb/swarm` satisfies this interface automatically.
|
|
359
|
+
*
|
|
360
|
+
* @internal
|
|
361
|
+
*/
|
|
362
|
+
export interface ISwarmGateway {
|
|
363
|
+
activateHandoff(payload: HandoffPayload, sessionId: string, signal: AbortSignal): Promise<void>;
|
|
364
|
+
proxyToolsList(sessionId: string): Promise<Array<{
|
|
365
|
+
name: string;
|
|
366
|
+
description?: string;
|
|
367
|
+
inputSchema?: unknown;
|
|
368
|
+
}> | null>;
|
|
369
|
+
proxyToolsCall(sessionId: string, name: string, args: Record<string, unknown>, signal: AbortSignal): Promise<ToolResponse | null>;
|
|
370
|
+
returnToGateway(sessionId: string): Promise<void>;
|
|
371
|
+
hasActiveHandoff(sessionId: string): boolean;
|
|
334
372
|
}
|
|
335
373
|
/** Function to detach the registry from the server */
|
|
336
374
|
export type DetachFn = () => void;
|
|
@@ -351,6 +389,8 @@ export interface RegistryDelegate<TContext> {
|
|
|
351
389
|
enableTelemetry?(sink: TelemetrySink): void;
|
|
352
390
|
/** Get an iterable of all registered builders (for introspection and exposition) */
|
|
353
391
|
getBuilders(): Iterable<ToolBuilder<TContext>>;
|
|
392
|
+
/** O(1) count of registered builders — used by recompile() cache safety net. */
|
|
393
|
+
readonly size: number;
|
|
354
394
|
}
|
|
355
395
|
/**
|
|
356
396
|
* Proxy sentinel used when `contextFactory` is not provided.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServerAttachment.d.ts","sourceRoot":"","sources":["../../src/server/ServerAttachment.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,KAAK,IAAI,IAAI,OAAO,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,KAAK,YAAY,
|
|
1
|
+
{"version":3,"file":"ServerAttachment.d.ts","sourceRoot":"","sources":["../../src/server/ServerAttachment.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { ListToolsRequestSchema, CallToolRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, SubscribeRequestSchema, UnsubscribeRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
12
12
|
import {} from '@modelcontextprotocol/sdk/types.js';
|
|
13
|
-
import { error, toolError } from '../core/response.js';
|
|
13
|
+
import { error, toolError, isHandoffResponse } from '../core/response.js';
|
|
14
14
|
import {} from '../core/types.js';
|
|
15
15
|
import {} from '../core/execution/ProgressHelper.js';
|
|
16
16
|
import { resolveServer } from './ServerResolver.js';
|
|
@@ -88,7 +88,7 @@ function resolveSessionId(extra, hCtx) {
|
|
|
88
88
|
* Clone the FSM and restore the session-specific snapshot.
|
|
89
89
|
*
|
|
90
90
|
* Shared by both `tools/list` and `tools/call` handlers.
|
|
91
|
-
* Eliminates the duplicated clone+restore logic (
|
|
91
|
+
* Eliminates the duplicated clone+restore logic ( + ).
|
|
92
92
|
*/
|
|
93
93
|
async function cloneAndRestoreFsm(hCtx, extra) {
|
|
94
94
|
let fsm = hCtx.fsm;
|
|
@@ -117,8 +117,17 @@ async function cloneAndRestoreFsm(hCtx, extra) {
|
|
|
117
117
|
*/
|
|
118
118
|
function createToolListHandler(hCtx) {
|
|
119
119
|
return async (_request, extra) => {
|
|
120
|
-
// Per-request FSM clone for serverless isolation (
|
|
120
|
+
// Per-request FSM clone for serverless isolation ( + fix).
|
|
121
121
|
const fsm = await cloneAndRestoreFsm(hCtx, extra);
|
|
122
|
+
// FHP: if a handoff tunnel is active, proxy the upstream's tools list
|
|
123
|
+
if (hCtx.swarmGateway) {
|
|
124
|
+
const sessionId = resolveSessionId(extra, hCtx);
|
|
125
|
+
const proxied = await hCtx.swarmGateway.proxyToolsList(sessionId);
|
|
126
|
+
if (proxied !== null && proxied !== undefined) {
|
|
127
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- McpTool shape
|
|
128
|
+
return { tools: proxied };
|
|
129
|
+
}
|
|
130
|
+
}
|
|
122
131
|
let tools;
|
|
123
132
|
if (hCtx.isFlat) {
|
|
124
133
|
const exposition = hCtx.recompile();
|
|
@@ -157,15 +166,27 @@ function createToolCallHandler(hCtx) {
|
|
|
157
166
|
// Resolve group/action from the routing map instead of naive
|
|
158
167
|
// split('_') — avoids misattributing tools with underscores
|
|
159
168
|
// in their names (e.g. 'user_accounts_list' → group='user_accounts', action='list').
|
|
160
|
-
|
|
169
|
+
//
|
|
170
|
+
// Bug fix: recompile() was called unconditionally in flat mode, even when
|
|
171
|
+
// neither telemetry nor FSM were active. We now lazily compute it once
|
|
172
|
+
// and reuse the same ExpositionResult for telemetry, FSM gate, and routing.
|
|
173
|
+
let _cachedExposition;
|
|
174
|
+
const getExposition = () => {
|
|
175
|
+
if (!hCtx.isFlat)
|
|
176
|
+
return undefined;
|
|
177
|
+
if (!_cachedExposition)
|
|
178
|
+
_cachedExposition = hCtx.recompile();
|
|
179
|
+
return _cachedExposition;
|
|
180
|
+
};
|
|
181
|
+
const exposition = getExposition();
|
|
161
182
|
const flatRoute = exposition?.routingMap.get(name);
|
|
162
183
|
const toolGroup = flatRoute ? flatRoute.builder.getName() : name;
|
|
163
184
|
const action = flatRoute ? flatRoute.actionKey : name;
|
|
164
185
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- TelemetrySink accepts extensible event shapes
|
|
165
186
|
emit?.({ type: 'route', tool: toolGroup, action, args, timestamp: Date.now() });
|
|
166
|
-
// Per-request FSM clone for serverless isolation (
|
|
187
|
+
// Per-request FSM clone for serverless isolation ( + fix).
|
|
167
188
|
const fsm = await cloneAndRestoreFsm(hCtx, extra);
|
|
168
|
-
//
|
|
189
|
+
// enforce FSM gate on tools/call — not just tools/list.
|
|
169
190
|
// Without this, a client that knows a tool's name can bypass the gate.
|
|
170
191
|
if (fsm && fsm.hasBindings && !fsm.isToolAllowed(name)) {
|
|
171
192
|
return toolError('FORBIDDEN', {
|
|
@@ -176,6 +197,29 @@ function createToolCallHandler(hCtx) {
|
|
|
176
197
|
details: { currentState: fsm.currentState, blockedTool: name },
|
|
177
198
|
});
|
|
178
199
|
}
|
|
200
|
+
// ── FHP: proxy tools/call when handoff tunnel is active ──────────────────
|
|
201
|
+
// This check MUST happen before the local tool execution block below.
|
|
202
|
+
// When a session has an active handoff, the LLM will call upstream tools
|
|
203
|
+
// (e.g. 'finance.refund') that do not exist in the gateway registry.
|
|
204
|
+
// Checking for an active handoff FIRST short-circuits the local execution
|
|
205
|
+
// entirely, giving clean telemetry and avoiding the unnecessary registry lookup.
|
|
206
|
+
if (hCtx.swarmGateway) {
|
|
207
|
+
const sessionId = resolveSessionId(extra, hCtx);
|
|
208
|
+
if (hCtx.swarmGateway.hasActiveHandoff(sessionId)) {
|
|
209
|
+
// Handle return_to_triage
|
|
210
|
+
if (name.endsWith('.return_to_triage')) {
|
|
211
|
+
await hCtx.swarmGateway.returnToGateway(sessionId);
|
|
212
|
+
hCtx.notifyToolListChanged?.();
|
|
213
|
+
return { content: [{ type: 'text', text: '[RETURN] Specialised session ended. Gateway tools restored.' }] };
|
|
214
|
+
}
|
|
215
|
+
const callSignal = extractSignal(extra) ?? new AbortController().signal;
|
|
216
|
+
const proxied = await hCtx.swarmGateway.proxyToolsCall(sessionId, name, args, callSignal);
|
|
217
|
+
if (proxied !== null)
|
|
218
|
+
return proxied;
|
|
219
|
+
// proxied === null means the gateway deferred (e.g. unknown tool in upstream);
|
|
220
|
+
// fall through to local execution so gateway-native tools still work.
|
|
221
|
+
}
|
|
222
|
+
}
|
|
179
223
|
let result;
|
|
180
224
|
const t0 = Date.now();
|
|
181
225
|
try {
|
|
@@ -201,7 +245,7 @@ function createToolCallHandler(hCtx) {
|
|
|
201
245
|
emit?.({ type: 'error', tool: toolGroup, action, error: String(err), timestamp: Date.now() });
|
|
202
246
|
throw err;
|
|
203
247
|
}
|
|
204
|
-
// ── Self-Healing: enrich validation errors with contract deltas (
|
|
248
|
+
// ── Self-Healing: enrich validation errors with contract deltas ( fix) ──
|
|
205
249
|
if (result.isError && hCtx.selfHealing) {
|
|
206
250
|
const text = result.content?.[0]?.type === 'text' ? result.content[0].text : '';
|
|
207
251
|
if (text) {
|
|
@@ -211,6 +255,25 @@ function createToolCallHandler(hCtx) {
|
|
|
211
255
|
}
|
|
212
256
|
}
|
|
213
257
|
}
|
|
258
|
+
// ── FHP: detect HandoffResponse and activate SwarmGateway tunnel ──────────
|
|
259
|
+
if (isHandoffResponse(result) && hCtx.swarmGateway) {
|
|
260
|
+
const sessionId = resolveSessionId(extra, hCtx);
|
|
261
|
+
const signal = extractSignal(extra) ?? new AbortController().signal;
|
|
262
|
+
const gateway = hCtx.swarmGateway;
|
|
263
|
+
const payload = result.payload;
|
|
264
|
+
// Activate tunnel asynchronously — ACK is returned immediately to the LLM
|
|
265
|
+
void gateway.activateHandoff(payload, sessionId, signal)
|
|
266
|
+
.then(() => hCtx.notifyToolListChanged?.())
|
|
267
|
+
.catch(() => hCtx.notifyToolListChanged?.());
|
|
268
|
+
// Cognitive anchor: visible ACK prevents LLM anxiety loop while tools reload.
|
|
269
|
+
// Uses HANDOFF_CONNECTING (not HANDOFF_UPSTREAM_UNAVAILABLE): the latter
|
|
270
|
+
// signals a failure to the LLM, whereas here the upstream is actively connecting.
|
|
271
|
+
return toolError('HANDOFF_CONNECTING', {
|
|
272
|
+
message: `[HANDOFF] ${payload.reason ?? 'Specialist selected'}. Your tools are being updated — please wait.`,
|
|
273
|
+
suggestion: 'Wait for the tools list to refresh, then proceed with the specialised tools.',
|
|
274
|
+
severity: 'warning',
|
|
275
|
+
});
|
|
276
|
+
}
|
|
214
277
|
// ── Telemetry: execute event ─────────────────────────
|
|
215
278
|
emit?.({
|
|
216
279
|
type: 'execute', tool: toolGroup, action,
|
|
@@ -240,13 +303,13 @@ function createToolCallHandler(hCtx) {
|
|
|
240
303
|
});
|
|
241
304
|
}
|
|
242
305
|
// Persist new state to external store (serverless/edge)
|
|
243
|
-
// Use fallback session ID for transports without sessions (e.g., stdio) (
|
|
306
|
+
// Use fallback session ID for transports without sessions (e.g., stdio) ( fix)
|
|
244
307
|
const sessionId = resolveSessionId(extra, hCtx);
|
|
245
308
|
if (hCtx.fsmStore) {
|
|
246
309
|
await hCtx.fsmStore.save(sessionId, fsm.snapshot());
|
|
247
310
|
}
|
|
248
311
|
else if (hCtx.fsmMemorySnapshots) {
|
|
249
|
-
//
|
|
312
|
+
// persist to in-memory session map
|
|
250
313
|
hCtx.fsmMemorySnapshots.set(sessionId, fsm.snapshot());
|
|
251
314
|
}
|
|
252
315
|
// Notify client to re-fetch tools/list
|
|
@@ -343,7 +406,7 @@ function injectLoopbackDispatcher(ctx, registry, signal) {
|
|
|
343
406
|
*/
|
|
344
407
|
function registerResourceHandlers(resolved, server, resources, contextFactory, introspection) {
|
|
345
408
|
const resourceServer = resolved;
|
|
346
|
-
//
|
|
409
|
+
// Pre-compute introspection manifest URI for merge.
|
|
347
410
|
const manifestUri = introspection?.config.uri ?? 'vurb://manifest.json';
|
|
348
411
|
// Wire notification sink for `notifications/resources/updated`
|
|
349
412
|
const serverAny = server;
|
|
@@ -367,7 +430,7 @@ function registerResourceHandlers(resolved, server, resources, contextFactory, i
|
|
|
367
430
|
if (typeof sendListChanged === 'function') {
|
|
368
431
|
resources.setListChangedSink(() => { sendListChanged.call(server); });
|
|
369
432
|
}
|
|
370
|
-
// resources/list — merge with introspection resources if present (
|
|
433
|
+
// resources/list — merge with introspection resources if present ( fix)
|
|
371
434
|
resourceServer.setRequestHandler(ListResourcesRequestSchema, (() => {
|
|
372
435
|
const list = resources.listResources();
|
|
373
436
|
if (introspection) {
|
|
@@ -380,9 +443,9 @@ function registerResourceHandlers(resolved, server, resources, contextFactory, i
|
|
|
380
443
|
}
|
|
381
444
|
return { resources: list };
|
|
382
445
|
}));
|
|
383
|
-
// resources/read — with introspection manifest delegation (
|
|
446
|
+
// resources/read — with introspection manifest delegation ( fix)
|
|
384
447
|
resourceServer.setRequestHandler(ReadResourceRequestSchema, (async (request, extra) => {
|
|
385
|
-
//
|
|
448
|
+
// Handle introspection manifest URI before ResourceRegistry
|
|
386
449
|
if (introspection && request.params.uri === manifestUri) {
|
|
387
450
|
const fullManifest = compileManifest(introspection.serverName, introspection.builders.values());
|
|
388
451
|
let manifest = fullManifest;
|
|
@@ -448,7 +511,7 @@ function createDetachFn(resolved, hasPrompts) {
|
|
|
448
511
|
*/
|
|
449
512
|
export async function attachToServer(server, registry, options = {}) {
|
|
450
513
|
const resolved = resolveServer(server);
|
|
451
|
-
const { filter, contextFactory, debug, tracing, stateSync, introspection, serverName, toolExposition = 'flat', actionSeparator = '_', prompts, zeroTrust, selfHealing, } = options;
|
|
514
|
+
const { filter, contextFactory, debug, tracing, stateSync, introspection, serverName, toolExposition = 'flat', actionSeparator = '_', prompts, zeroTrust, selfHealing, swarmGateway, } = options;
|
|
452
515
|
// 1. Propagate observability to all registered builders
|
|
453
516
|
propagateObservability(registry, debug, tracing, options.telemetry);
|
|
454
517
|
// 2. Create State Sync layer (zero overhead when not configured)
|
|
@@ -456,7 +519,7 @@ export async function attachToServer(server, registry, options = {}) {
|
|
|
456
519
|
const mergedSyncConfig = mergeStateSyncConfig(stateSync, registry.getBuilders());
|
|
457
520
|
const syncLayer = mergedSyncConfig ? new StateSyncLayer(mergedSyncConfig) : undefined;
|
|
458
521
|
// 3. Register introspection resource (zero overhead when disabled)
|
|
459
|
-
//
|
|
522
|
+
// When `resources` is also configured, introspection is merged
|
|
460
523
|
// into registerResourceHandlers to avoid setRequestHandler overwrite.
|
|
461
524
|
if (introspection?.enabled && !options.resources) {
|
|
462
525
|
registerIntrospectionResource(resolved, introspection, serverName ?? 'vurb-server', { values: () => registry.getBuilders() }, contextFactory);
|
|
@@ -487,9 +550,9 @@ export async function attachToServer(server, registry, options = {}) {
|
|
|
487
550
|
if (fsm) {
|
|
488
551
|
autoBindFsmFromBuilders(fsm, registry.getBuilders(), toolExposition, actionSeparator);
|
|
489
552
|
}
|
|
490
|
-
// Wire the notification sink for list_changed (FSM transitions)
|
|
553
|
+
// Wire the notification sink for list_changed (FSM transitions + FHP swarm)
|
|
491
554
|
let notifyToolListChanged;
|
|
492
|
-
if (fsm) {
|
|
555
|
+
if (fsm || swarmGateway) {
|
|
493
556
|
const serverAny = server;
|
|
494
557
|
const sendFn = serverAny['sendToolListChanged'] ?? serverAny['notification'];
|
|
495
558
|
if (typeof sendFn === 'function') {
|
|
@@ -503,7 +566,7 @@ export async function attachToServer(server, registry, options = {}) {
|
|
|
503
566
|
};
|
|
504
567
|
}
|
|
505
568
|
}
|
|
506
|
-
//
|
|
569
|
+
// exposition dirty flag — O(1) cache validation
|
|
507
570
|
// Starts dirty to force initial compile, then stays clean until invalidated.
|
|
508
571
|
let _expositionDirty = true;
|
|
509
572
|
const hCtx = {
|
|
@@ -513,26 +576,27 @@ export async function attachToServer(server, registry, options = {}) {
|
|
|
513
576
|
...(syncLayer ? { syncLayer } : {}),
|
|
514
577
|
toolExposition, actionSeparator,
|
|
515
578
|
isFlat: toolExposition === 'flat',
|
|
516
|
-
//
|
|
517
|
-
//
|
|
518
|
-
//
|
|
519
|
-
//
|
|
579
|
+
// O(1) exposition cache with dirty flag + builder-count safety net.
|
|
580
|
+
// The dirty flag provides O(1) fast-path invalidation (set whenever a builder
|
|
581
|
+
// registers or the filter changes). The builder-count safety net catches
|
|
582
|
+
// late-registered builders that might have been missed by the dirty flag.
|
|
583
|
+
//
|
|
584
|
+
// (Performance) fix: previous safety net iterated `registry.getBuilders()`
|
|
585
|
+
// with a for...of loop (O(n)) on every tools/call request even on the cache hit path.
|
|
586
|
+
// `ToolRegistry.size` is a Map.size getter — always O(1). No loop needed.
|
|
520
587
|
recompile: (() => {
|
|
521
588
|
let cachedResult;
|
|
522
589
|
let cachedBuilderCount = -1;
|
|
523
590
|
return () => {
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
count++;
|
|
529
|
-
if (count === cachedBuilderCount)
|
|
530
|
-
return cachedResult;
|
|
591
|
+
// O(1) size check: detect late-registered builders without iterating.
|
|
592
|
+
const currentCount = registry.size;
|
|
593
|
+
if (!_expositionDirty && cachedResult && currentCount === cachedBuilderCount) {
|
|
594
|
+
return cachedResult;
|
|
531
595
|
}
|
|
532
596
|
_expositionDirty = false;
|
|
597
|
+
cachedBuilderCount = currentCount;
|
|
533
598
|
const builders = [...registry.getBuilders()];
|
|
534
|
-
|
|
535
|
-
// Bug #131: route diagnostic warnings through debug observer
|
|
599
|
+
// route diagnostic warnings through debug observer
|
|
536
600
|
const warnFn = debug
|
|
537
601
|
? (msg) => debug({ type: 'error', tool: '', action: '', error: msg, step: 'route', timestamp: Date.now() })
|
|
538
602
|
: undefined;
|
|
@@ -542,14 +606,15 @@ export async function attachToServer(server, registry, options = {}) {
|
|
|
542
606
|
})(),
|
|
543
607
|
...(fsm ? { fsm } : {}),
|
|
544
608
|
...(fsmStore ? { fsmStore } : {}),
|
|
545
|
-
//
|
|
546
|
-
//
|
|
609
|
+
// in-memory FSM snapshot store when no external fsmStore
|
|
610
|
+
// bounded LRU eviction (max 10,000 entries) to prevent
|
|
547
611
|
// unbounded memory growth proportional to unique session count.
|
|
548
612
|
...(fsm && !fsmStore ? { fsmMemorySnapshots: createBoundedSnapshotMap(10_000) } : {}),
|
|
549
613
|
...(notifyToolListChanged ? { notifyToolListChanged } : {}),
|
|
550
614
|
...(options.telemetry ? { telemetry: options.telemetry } : {}),
|
|
551
615
|
...(selfHealing ? { selfHealing } : {}),
|
|
552
|
-
|
|
616
|
+
...(swarmGateway ? { swarmGateway } : {}),
|
|
617
|
+
// per-attachment UUID — never use static key for session-scoped mutable state
|
|
553
618
|
fallbackSessionId: randomUUID(),
|
|
554
619
|
};
|
|
555
620
|
// 5. Register tool handlers
|
|
@@ -562,7 +627,7 @@ export async function attachToServer(server, registry, options = {}) {
|
|
|
562
627
|
// 7. Register resource handlers (zero overhead when omitted)
|
|
563
628
|
const { resources } = options;
|
|
564
629
|
if (resources) {
|
|
565
|
-
//
|
|
630
|
+
// pass introspection config so manifest resource is merged
|
|
566
631
|
// into ResourceRegistry handlers instead of being overwritten.
|
|
567
632
|
registerResourceHandlers(resolved, server, resources, contextFactory, introspection?.enabled ? {
|
|
568
633
|
config: introspection,
|
|
@@ -727,7 +792,7 @@ function collectHintPolicies(builders) {
|
|
|
727
792
|
* Uses native `Map` iteration order guarantee (insertion order) as the LRU proxy.
|
|
728
793
|
* On `get()`, the accessed entry is re-inserted to refresh its position.
|
|
729
794
|
*
|
|
730
|
-
*
|
|
795
|
+
* prevents unbounded memory growth proportional to unique sessions.
|
|
731
796
|
*/
|
|
732
797
|
function createBoundedSnapshotMap(maxSize) {
|
|
733
798
|
const map = new Map();
|
|
@@ -816,7 +881,7 @@ function autoBindFsmFromBuilders(gate, builders, exposition, separator) {
|
|
|
816
881
|
const actionList = actions.call(builder);
|
|
817
882
|
const isSingleAction = actionList.length === 1;
|
|
818
883
|
for (const action of actionList) {
|
|
819
|
-
//
|
|
884
|
+
// single-action default tools use bare name
|
|
820
885
|
// (matching ExpositionCompiler.compileFlat behavior)
|
|
821
886
|
const flatName = (isSingleAction && action.key === 'default')
|
|
822
887
|
? toolName
|