@mcpmesh/sdk 2.4.0 → 2.6.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/dist/__tests__/agent-single-instance.spec.d.ts +2 -0
- package/dist/__tests__/agent-single-instance.spec.d.ts.map +1 -0
- package/dist/__tests__/agent-single-instance.spec.js +80 -0
- package/dist/__tests__/agent-single-instance.spec.js.map +1 -0
- package/dist/__tests__/event-loop-resilience.spec.d.ts +2 -0
- package/dist/__tests__/event-loop-resilience.spec.d.ts.map +1 -0
- package/dist/__tests__/event-loop-resilience.spec.js +321 -0
- package/dist/__tests__/event-loop-resilience.spec.js.map +1 -0
- package/dist/__tests__/llm-max-iterations.test.js +10 -8
- package/dist/__tests__/llm-max-iterations.test.js.map +1 -1
- package/dist/__tests__/llm-provider-multistep.test.d.ts +20 -0
- package/dist/__tests__/llm-provider-multistep.test.d.ts.map +1 -0
- package/dist/__tests__/llm-provider-multistep.test.js +138 -0
- package/dist/__tests__/llm-provider-multistep.test.js.map +1 -0
- package/dist/__tests__/llm-provider-output-mode.test.js +1 -0
- package/dist/__tests__/llm-provider-output-mode.test.js.map +1 -1
- package/dist/__tests__/llm-provider-stopwhen.test.d.ts +22 -0
- package/dist/__tests__/llm-provider-stopwhen.test.d.ts.map +1 -0
- package/dist/__tests__/llm-provider-stopwhen.test.js +127 -0
- package/dist/__tests__/llm-provider-stopwhen.test.js.map +1 -0
- package/dist/__tests__/llm-provider-system-synthesis.test.js +1 -0
- package/dist/__tests__/llm-provider-system-synthesis.test.js.map +1 -1
- package/dist/__tests__/llm-provider-vertex-settings.test.d.ts +18 -0
- package/dist/__tests__/llm-provider-vertex-settings.test.d.ts.map +1 -0
- package/dist/__tests__/llm-provider-vertex-settings.test.js +128 -0
- package/dist/__tests__/llm-provider-vertex-settings.test.js.map +1 -0
- package/dist/__tests__/port-conflict-fallback.spec.d.ts +2 -0
- package/dist/__tests__/port-conflict-fallback.spec.d.ts.map +1 -0
- package/dist/__tests__/port-conflict-fallback.spec.js +123 -0
- package/dist/__tests__/port-conflict-fallback.spec.js.map +1 -0
- package/dist/__tests__/port-probe-errors.spec.d.ts +2 -0
- package/dist/__tests__/port-probe-errors.spec.d.ts.map +1 -0
- package/dist/__tests__/port-probe-errors.spec.js +100 -0
- package/dist/__tests__/port-probe-errors.spec.js.map +1 -0
- package/dist/__tests__/provider-handler-registry.test.d.ts +0 -1
- package/dist/__tests__/provider-handler-registry.test.d.ts.map +1 -1
- package/dist/__tests__/provider-handler-registry.test.js +23 -1
- package/dist/__tests__/provider-handler-registry.test.js.map +1 -1
- package/dist/__tests__/proxy-sse-no-data.test.d.ts +13 -0
- package/dist/__tests__/proxy-sse-no-data.test.d.ts.map +1 -0
- package/dist/__tests__/proxy-sse-no-data.test.js +147 -0
- package/dist/__tests__/proxy-sse-no-data.test.js.map +1 -0
- package/dist/__tests__/proxy-stream.test.js +26 -0
- package/dist/__tests__/proxy-stream.test.js.map +1 -1
- package/dist/__tests__/proxy-timer-leak.test.d.ts +16 -0
- package/dist/__tests__/proxy-timer-leak.test.d.ts.map +1 -0
- package/dist/__tests__/proxy-timer-leak.test.js +97 -0
- package/dist/__tests__/proxy-timer-leak.test.js.map +1 -0
- package/dist/__tests__/proxy-tool-error.test.d.ts +13 -0
- package/dist/__tests__/proxy-tool-error.test.d.ts.map +1 -0
- package/dist/__tests__/proxy-tool-error.test.js +313 -0
- package/dist/__tests__/proxy-tool-error.test.js.map +1 -0
- package/dist/__tests__/route.test.js +21 -1
- package/dist/__tests__/route.test.js.map +1 -1
- package/dist/__tests__/settle-window.spec.d.ts +2 -0
- package/dist/__tests__/settle-window.spec.d.ts.map +1 -0
- package/dist/__tests__/settle-window.spec.js +324 -0
- package/dist/__tests__/settle-window.spec.js.map +1 -0
- package/dist/__tests__/sse.test.js +12 -0
- package/dist/__tests__/sse.test.js.map +1 -1
- package/dist/__tests__/stop-dispatchers.spec.d.ts +2 -0
- package/dist/__tests__/stop-dispatchers.spec.d.ts.map +1 -0
- package/dist/__tests__/stop-dispatchers.spec.js +227 -0
- package/dist/__tests__/stop-dispatchers.spec.js.map +1 -0
- package/dist/agent.d.ts +65 -5
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +313 -78
- package/dist/agent.js.map +1 -1
- package/dist/api-runtime.d.ts +33 -3
- package/dist/api-runtime.d.ts.map +1 -1
- package/dist/api-runtime.js +125 -32
- package/dist/api-runtime.js.map +1 -1
- package/dist/claim-dispatcher.d.ts +25 -0
- package/dist/claim-dispatcher.d.ts.map +1 -1
- package/dist/claim-dispatcher.js +59 -1
- package/dist/claim-dispatcher.js.map +1 -1
- package/dist/config.d.ts +73 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +108 -2
- package/dist/config.js.map +1 -1
- package/dist/debug.d.ts +1 -1
- package/dist/debug.d.ts.map +1 -1
- package/dist/express.d.ts +33 -0
- package/dist/express.d.ts.map +1 -1
- package/dist/express.js +149 -31
- package/dist/express.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/llm-provider.d.ts +18 -0
- package/dist/llm-provider.d.ts.map +1 -1
- package/dist/llm-provider.js +86 -34
- package/dist/llm-provider.js.map +1 -1
- package/dist/provider-handlers/gemini-handler.js +6 -0
- package/dist/provider-handlers/gemini-handler.js.map +1 -1
- package/dist/provider-handlers/provider-handler-registry.d.ts +10 -1
- package/dist/provider-handlers/provider-handler-registry.d.ts.map +1 -1
- package/dist/provider-handlers/provider-handler-registry.js +4 -1
- package/dist/provider-handlers/provider-handler-registry.js.map +1 -1
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +178 -40
- package/dist/proxy.js.map +1 -1
- package/dist/route.d.ts.map +1 -1
- package/dist/route.js +38 -0
- package/dist/route.js.map +1 -1
- package/dist/settle.d.ts +129 -0
- package/dist/settle.d.ts.map +1 -0
- package/dist/settle.js +284 -0
- package/dist/settle.js.map +1 -0
- package/dist/sse.d.ts.map +1 -1
- package/dist/sse.js +5 -2
- package/dist/sse.js.map +1 -1
- package/dist/tracing.d.ts +1 -0
- package/dist/tracing.d.ts.map +1 -1
- package/dist/tracing.js +3 -0
- package/dist/tracing.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-single-instance.spec.d.ts","sourceRoot":"","sources":["../../src/__tests__/agent-single-instance.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression tests for #1163 LOW-6 — a second MeshAgent constructed in
|
|
3
|
+
* the same synchronous chunk as another used to silently overwrite the
|
|
4
|
+
* module-level pending-auto-start slot: `scheduleAutoStart` only ever
|
|
5
|
+
* ran once per tick, so the first agent never started and nobody
|
|
6
|
+
* noticed.
|
|
7
|
+
*
|
|
8
|
+
* Fixed behavior:
|
|
9
|
+
* - constructing a second agent in the same synchronous chunk (i.e.
|
|
10
|
+
* while the first is still pending its auto-start tick — in real
|
|
11
|
+
* Node the nextTick drains before any microtask continuation, so
|
|
12
|
+
* the guard window covers the whole danger zone) throws a clear
|
|
13
|
+
* "one MeshAgent per process" error;
|
|
14
|
+
* - sequential constructions across async boundaries (e.g. one agent
|
|
15
|
+
* per test in a harness) remain allowed: the guard auto-releases on
|
|
16
|
+
* the first microtask.
|
|
17
|
+
*/
|
|
18
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
|
19
|
+
import { MeshAgent } from "../agent.js";
|
|
20
|
+
function makeFastMCPStub() {
|
|
21
|
+
return {
|
|
22
|
+
addTool: vi.fn(),
|
|
23
|
+
start: vi.fn(),
|
|
24
|
+
getApp: vi.fn(),
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
let autoStartSpy = null;
|
|
29
|
+
beforeEach(() => {
|
|
30
|
+
autoStartSpy = vi
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
32
|
+
.spyOn(MeshAgent.prototype, "_autoStart")
|
|
33
|
+
.mockImplementation(async () => {
|
|
34
|
+
/* no-op */
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
afterEach(async () => {
|
|
38
|
+
// Drain the next-tick queue BEFORE restoring the spy: the constructor
|
|
39
|
+
// schedules the auto-start callback via process.nextTick, and vitest
|
|
40
|
+
// runs afterEach before that tick fires for sync test bodies. Restoring
|
|
41
|
+
// first would let the REAL _autoStart run against the FastMCP stub.
|
|
42
|
+
await new Promise(process.nextTick);
|
|
43
|
+
if (autoStartSpy) {
|
|
44
|
+
autoStartSpy.mockRestore();
|
|
45
|
+
autoStartSpy = null;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
describe("one MeshAgent per process (#1163 LOW-6)", () => {
|
|
49
|
+
it("throws when a second agent is constructed in the same synchronous chunk", () => {
|
|
50
|
+
const first = new MeshAgent(makeFastMCPStub(), {
|
|
51
|
+
name: "first-agent",
|
|
52
|
+
httpPort: 0,
|
|
53
|
+
});
|
|
54
|
+
expect(first).toBeDefined();
|
|
55
|
+
expect(() => new MeshAgent(makeFastMCPStub(), {
|
|
56
|
+
name: "second-agent",
|
|
57
|
+
httpPort: 0,
|
|
58
|
+
})).toThrow(/Only one MeshAgent may be constructed per process/);
|
|
59
|
+
expect(() => new MeshAgent(makeFastMCPStub(), {
|
|
60
|
+
name: "second-agent",
|
|
61
|
+
httpPort: 0,
|
|
62
|
+
})).toThrow(/'first-agent' is already pending auto-start/);
|
|
63
|
+
});
|
|
64
|
+
it("allows constructing a new agent after the guard releases", async () => {
|
|
65
|
+
const first = new MeshAgent(makeFastMCPStub(), {
|
|
66
|
+
name: "first-agent",
|
|
67
|
+
httpPort: 0,
|
|
68
|
+
});
|
|
69
|
+
expect(first).toBeDefined();
|
|
70
|
+
// Cross the async boundary: the construction guard releases on the
|
|
71
|
+
// first microtask (and in real Node the auto-start tick has already
|
|
72
|
+
// consumed the pending slot by then).
|
|
73
|
+
await Promise.resolve();
|
|
74
|
+
expect(() => new MeshAgent(makeFastMCPStub(), {
|
|
75
|
+
name: "later-agent",
|
|
76
|
+
httpPort: 0,
|
|
77
|
+
})).not.toThrow();
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
//# sourceMappingURL=agent-single-instance.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-single-instance.spec.js","sourceRoot":"","sources":["../../src/__tests__/agent-single-instance.spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,SAAS,eAAe;IACtB,OAAO;QACL,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE;QAChB,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;QACd,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE;QACf,8DAA8D;KACxD,CAAC;AACX,CAAC;AAED,IAAI,YAAY,GAAuC,IAAI,CAAC;AAE5D,UAAU,CAAC,GAAG,EAAE;IACd,YAAY,GAAG,EAAE;QACf,8DAA8D;SAC7D,KAAK,CAAC,SAAS,CAAC,SAAgB,EAAE,YAAY,CAAC;SAC/C,kBAAkB,CAAC,KAAK,IAAI,EAAE;QAC7B,WAAW;IACb,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,sEAAsE;IACtE,qEAAqE;IACrE,wEAAwE;IACxE,oEAAoE;IACpE,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpC,IAAI,YAAY,EAAE,CAAC;QACjB,YAAY,CAAC,WAAW,EAAE,CAAC;QAC3B,YAAY,GAAG,IAAI,CAAC;IACtB,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,yCAAyC,EAAE,GAAG,EAAE;IACvD,EAAE,CAAC,yEAAyE,EAAE,GAAG,EAAE;QACjF,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,eAAe,EAAE,EAAE;YAC7C,IAAI,EAAE,aAAa;YACnB,QAAQ,EAAE,CAAC;SACZ,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QAE5B,MAAM,CACJ,GAAG,EAAE,CACH,IAAI,SAAS,CAAC,eAAe,EAAE,EAAE;YAC/B,IAAI,EAAE,cAAc;YACpB,QAAQ,EAAE,CAAC;SACZ,CAAC,CACL,CAAC,OAAO,CAAC,mDAAmD,CAAC,CAAC;QAC/D,MAAM,CACJ,GAAG,EAAE,CACH,IAAI,SAAS,CAAC,eAAe,EAAE,EAAE;YAC/B,IAAI,EAAE,cAAc;YACpB,QAAQ,EAAE,CAAC;SACZ,CAAC,CACL,CAAC,OAAO,CAAC,6CAA6C,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,eAAe,EAAE,EAAE;YAC7C,IAAI,EAAE,aAAa;YACnB,QAAQ,EAAE,CAAC;SACZ,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QAE5B,mEAAmE;QACnE,oEAAoE;QACpE,sCAAsC;QACtC,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QAExB,MAAM,CACJ,GAAG,EAAE,CACH,IAAI,SAAS,CAAC,eAAe,EAAE,EAAE;YAC/B,IAAI,EAAE,aAAa;YACnB,QAAQ,EAAE,CAAC;SACZ,CAAC,CACL,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-loop-resilience.spec.d.ts","sourceRoot":"","sources":["../../src/__tests__/event-loop-resilience.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression tests for #1163 MED-1 — the mesh event loop must outlive
|
|
3
|
+
* individual failures.
|
|
4
|
+
*
|
|
5
|
+
* Previously all three event loops (MeshAgent, ApiRuntime, MeshExpress)
|
|
6
|
+
* wrapped the entire `nextEvent()` + switch in one try/catch whose catch
|
|
7
|
+
* did `console.error(...); break;` — a single throw (transient napi
|
|
8
|
+
* rejection from nextEvent(), malformed event hitting a non-null
|
|
9
|
+
* assertion inside a handler) killed dependency-event processing for the
|
|
10
|
+
* process lifetime while the agent kept serving: frozen topology.
|
|
11
|
+
*
|
|
12
|
+
* The fixed loops:
|
|
13
|
+
* - isolate each event: a handler throw is logged and the loop keeps
|
|
14
|
+
* consuming events;
|
|
15
|
+
* - retry `nextEvent()` rejections with a bounded exponential backoff
|
|
16
|
+
* (100ms doubling, capped at 5s, reset on success);
|
|
17
|
+
* - exit only on the "shutdown" event or a torn-down handle.
|
|
18
|
+
*
|
|
19
|
+
* Pattern mirrors registry-disconnect-retains-deps.spec.ts: drive the
|
|
20
|
+
* REAL private `runEventLoop` against a stub `this`.
|
|
21
|
+
*/
|
|
22
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
|
23
|
+
import { MeshAgent } from "../agent.js";
|
|
24
|
+
import { ApiRuntime } from "../api-runtime.js";
|
|
25
|
+
import { MeshExpress } from "../express.js";
|
|
26
|
+
import { RouteRegistry } from "../route.js";
|
|
27
|
+
import { MAX_CONSECUTIVE_NEXT_EVENT_FAILURES } from "../config.js";
|
|
28
|
+
/** Replays the given event sequence once, then parks forever. */
|
|
29
|
+
function stubHandle(events) {
|
|
30
|
+
let i = 0;
|
|
31
|
+
return {
|
|
32
|
+
nextEvent: async () => {
|
|
33
|
+
if (i < events.length)
|
|
34
|
+
return events[i++];
|
|
35
|
+
return new Promise(() => { });
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function depEvent(capability) {
|
|
40
|
+
return {
|
|
41
|
+
eventType: "dependency_available",
|
|
42
|
+
capability,
|
|
43
|
+
endpoint: "http://peer:9000",
|
|
44
|
+
functionName: "fn",
|
|
45
|
+
agentId: "peer-1",
|
|
46
|
+
requestingFunction: "tool",
|
|
47
|
+
depIndex: 0,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
const THROW_THEN_PROCESS_THEN_SHUTDOWN = [
|
|
51
|
+
depEvent("first"), // handler throws on this one
|
|
52
|
+
depEvent("second"), // must still be processed
|
|
53
|
+
{ eventType: "shutdown" },
|
|
54
|
+
];
|
|
55
|
+
describe("event loop survives a throwing event handler (#1163 MED-1)", () => {
|
|
56
|
+
let errorSpy;
|
|
57
|
+
beforeEach(() => {
|
|
58
|
+
RouteRegistry.reset();
|
|
59
|
+
errorSpy = vi.spyOn(console, "error").mockImplementation(() => { });
|
|
60
|
+
vi.spyOn(console, "log").mockImplementation(() => { });
|
|
61
|
+
vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
62
|
+
});
|
|
63
|
+
afterEach(() => {
|
|
64
|
+
vi.restoreAllMocks();
|
|
65
|
+
});
|
|
66
|
+
function throwingThenRecordingHandler() {
|
|
67
|
+
return vi
|
|
68
|
+
.fn()
|
|
69
|
+
.mockImplementationOnce(() => {
|
|
70
|
+
throw new Error("malformed event boom");
|
|
71
|
+
})
|
|
72
|
+
.mockImplementation(() => {
|
|
73
|
+
/* subsequent events processed fine */
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
it("MeshAgent keeps processing events after a handler throw", async () => {
|
|
77
|
+
const handler = throwingThenRecordingHandler();
|
|
78
|
+
const stubThis = {
|
|
79
|
+
handle: stubHandle(THROW_THEN_PROCESS_THEN_SHUTDOWN),
|
|
80
|
+
handleDependencyAvailable: handler,
|
|
81
|
+
};
|
|
82
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
83
|
+
const runEventLoop = MeshAgent.prototype.runEventLoop;
|
|
84
|
+
await runEventLoop.call(stubThis);
|
|
85
|
+
// Both dependency events reached the handler; the throw on the first
|
|
86
|
+
// one was logged and did NOT kill the loop, and shutdown still exits.
|
|
87
|
+
expect(handler).toHaveBeenCalledTimes(2);
|
|
88
|
+
expect(errorSpy).toHaveBeenCalledWith(expect.stringContaining("error handling event 'dependency_available'"), expect.any(Error));
|
|
89
|
+
});
|
|
90
|
+
it("ApiRuntime keeps processing events after a handler throw", async () => {
|
|
91
|
+
const handler = throwingThenRecordingHandler();
|
|
92
|
+
const stubThis = {
|
|
93
|
+
handle: stubHandle(THROW_THEN_PROCESS_THEN_SHUTDOWN),
|
|
94
|
+
handleDependencyAvailable: handler,
|
|
95
|
+
};
|
|
96
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
97
|
+
const runEventLoop = ApiRuntime.prototype.runEventLoop;
|
|
98
|
+
await runEventLoop.call(stubThis);
|
|
99
|
+
expect(handler).toHaveBeenCalledTimes(2);
|
|
100
|
+
expect(errorSpy).toHaveBeenCalledWith(expect.stringContaining("error handling event 'dependency_available'"), expect.any(Error));
|
|
101
|
+
});
|
|
102
|
+
it("MeshExpress keeps processing events after a handler throw", async () => {
|
|
103
|
+
const handler = throwingThenRecordingHandler();
|
|
104
|
+
const stubThis = {
|
|
105
|
+
handle: stubHandle(THROW_THEN_PROCESS_THEN_SHUTDOWN),
|
|
106
|
+
handleDependencyAvailable: handler,
|
|
107
|
+
};
|
|
108
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
109
|
+
const runEventLoop = MeshExpress.prototype.runEventLoop;
|
|
110
|
+
await runEventLoop.call(stubThis);
|
|
111
|
+
expect(handler).toHaveBeenCalledTimes(2);
|
|
112
|
+
expect(errorSpy).toHaveBeenCalledWith(expect.stringContaining("error handling event 'dependency_available'"), expect.any(Error));
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
describe("event loop retries nextEvent() rejections with bounded backoff (#1163 MED-1)", () => {
|
|
116
|
+
let errorSpy;
|
|
117
|
+
beforeEach(() => {
|
|
118
|
+
RouteRegistry.reset();
|
|
119
|
+
errorSpy = vi.spyOn(console, "error").mockImplementation(() => { });
|
|
120
|
+
vi.spyOn(console, "log").mockImplementation(() => { });
|
|
121
|
+
vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
122
|
+
});
|
|
123
|
+
afterEach(() => {
|
|
124
|
+
vi.restoreAllMocks();
|
|
125
|
+
vi.useRealTimers();
|
|
126
|
+
});
|
|
127
|
+
/**
|
|
128
|
+
* Extract the backoff delays from the loop's "retrying in Xms" log
|
|
129
|
+
* lines. Deliberately NOT a setTimeout spy: a spy on the (fake)
|
|
130
|
+
* global setTimeout survives `vi.restoreAllMocks()` re-runs in later
|
|
131
|
+
* tests' afterEach hooks and re-installs the stale fake clock,
|
|
132
|
+
* hanging unrelated real-timer tests.
|
|
133
|
+
*/
|
|
134
|
+
function loggedBackoffs() {
|
|
135
|
+
return errorSpy.mock.calls
|
|
136
|
+
.map((c) => /retrying in (\d+)ms/.exec(String(c[0]))?.[1])
|
|
137
|
+
.filter((m) => m !== undefined)
|
|
138
|
+
.map(Number);
|
|
139
|
+
}
|
|
140
|
+
it("MeshAgent survives repeated nextEvent failures and still exits on shutdown", async () => {
|
|
141
|
+
vi.useFakeTimers();
|
|
142
|
+
const failures = 8;
|
|
143
|
+
let attempts = 0;
|
|
144
|
+
const stubThis = {
|
|
145
|
+
handle: {
|
|
146
|
+
nextEvent: async () => {
|
|
147
|
+
if (attempts < failures) {
|
|
148
|
+
attempts++;
|
|
149
|
+
throw new Error(`transient napi failure ${attempts}`);
|
|
150
|
+
}
|
|
151
|
+
return { eventType: "shutdown" };
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
156
|
+
const runEventLoop = MeshAgent.prototype.runEventLoop;
|
|
157
|
+
const loop = runEventLoop.call(stubThis);
|
|
158
|
+
// Each rejection schedules one backoff sleep; advancing by the cap
|
|
159
|
+
// flushes whichever delay is pending.
|
|
160
|
+
for (let i = 0; i < failures + 1; i++) {
|
|
161
|
+
await vi.advanceTimersByTimeAsync(5000);
|
|
162
|
+
}
|
|
163
|
+
await loop; // resolves — the loop survived and exited on shutdown
|
|
164
|
+
expect(attempts).toBe(failures);
|
|
165
|
+
// Backoff delays: exponential from 100ms, hard-capped at 5000ms.
|
|
166
|
+
expect(loggedBackoffs()).toEqual([100, 200, 400, 800, 1600, 3200, 5000, 5000]);
|
|
167
|
+
});
|
|
168
|
+
it("MeshAgent resets the backoff after a successful nextEvent", async () => {
|
|
169
|
+
vi.useFakeTimers();
|
|
170
|
+
// fail, fail, succeed (benign event), fail, shutdown
|
|
171
|
+
const script = [
|
|
172
|
+
"fail",
|
|
173
|
+
"fail",
|
|
174
|
+
{ eventType: "registry_connected" },
|
|
175
|
+
"fail",
|
|
176
|
+
{ eventType: "shutdown" },
|
|
177
|
+
];
|
|
178
|
+
let i = 0;
|
|
179
|
+
const stubThis = {
|
|
180
|
+
handle: {
|
|
181
|
+
nextEvent: async () => {
|
|
182
|
+
const step = script[i++];
|
|
183
|
+
if (step === "fail")
|
|
184
|
+
throw new Error("transient");
|
|
185
|
+
return step;
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
};
|
|
189
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
190
|
+
const runEventLoop = MeshAgent.prototype.runEventLoop;
|
|
191
|
+
const loop = runEventLoop.call(stubThis);
|
|
192
|
+
for (let n = 0; n < script.length; n++) {
|
|
193
|
+
await vi.advanceTimersByTimeAsync(5000);
|
|
194
|
+
}
|
|
195
|
+
await loop;
|
|
196
|
+
// 100, 200 (two consecutive failures), then reset to 100 after the
|
|
197
|
+
// successful event.
|
|
198
|
+
expect(loggedBackoffs()).toEqual([100, 200, 100]);
|
|
199
|
+
});
|
|
200
|
+
it("ApiRuntime survives a nextEvent rejection and still exits on shutdown", async () => {
|
|
201
|
+
let attempts = 0;
|
|
202
|
+
const stubThis = {
|
|
203
|
+
handle: {
|
|
204
|
+
nextEvent: async () => {
|
|
205
|
+
if (attempts === 0) {
|
|
206
|
+
attempts++;
|
|
207
|
+
throw new Error("transient");
|
|
208
|
+
}
|
|
209
|
+
return { eventType: "shutdown" };
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
214
|
+
const runEventLoop = ApiRuntime.prototype.runEventLoop;
|
|
215
|
+
await runEventLoop.call(stubThis); // real timers: single 100ms backoff
|
|
216
|
+
expect(attempts).toBe(1);
|
|
217
|
+
});
|
|
218
|
+
it("MeshExpress survives a nextEvent rejection and still exits on shutdown", async () => {
|
|
219
|
+
let attempts = 0;
|
|
220
|
+
const stubThis = {
|
|
221
|
+
handle: {
|
|
222
|
+
nextEvent: async () => {
|
|
223
|
+
if (attempts === 0) {
|
|
224
|
+
attempts++;
|
|
225
|
+
throw new Error("transient");
|
|
226
|
+
}
|
|
227
|
+
return { eventType: "shutdown" };
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
};
|
|
231
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
232
|
+
const runEventLoop = MeshExpress.prototype.runEventLoop;
|
|
233
|
+
await runEventLoop.call(stubThis);
|
|
234
|
+
expect(attempts).toBe(1);
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
describe("event loop terminates at the consecutive-failure ceiling instead of retrying forever", () => {
|
|
238
|
+
let errorSpy;
|
|
239
|
+
beforeEach(() => {
|
|
240
|
+
RouteRegistry.reset();
|
|
241
|
+
errorSpy = vi.spyOn(console, "error").mockImplementation(() => { });
|
|
242
|
+
vi.spyOn(console, "log").mockImplementation(() => { });
|
|
243
|
+
vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
244
|
+
});
|
|
245
|
+
afterEach(() => {
|
|
246
|
+
vi.restoreAllMocks();
|
|
247
|
+
vi.useRealTimers();
|
|
248
|
+
});
|
|
249
|
+
/**
|
|
250
|
+
* Drive a permanently-failing nextEvent() against the given class's
|
|
251
|
+
* REAL private runEventLoop. Returns the number of nextEvent()
|
|
252
|
+
* attempts before the loop gave up (the loop resolving at all IS the
|
|
253
|
+
* regression assertion — before the ceiling it retried forever, and
|
|
254
|
+
* its ref'd backoff timer kept the process alive).
|
|
255
|
+
*/
|
|
256
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
257
|
+
async function runUntilCeiling(proto) {
|
|
258
|
+
vi.useFakeTimers();
|
|
259
|
+
let attempts = 0;
|
|
260
|
+
const stubThis = {
|
|
261
|
+
handle: {
|
|
262
|
+
nextEvent: async () => {
|
|
263
|
+
attempts++;
|
|
264
|
+
throw new Error("permanent napi failure");
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
};
|
|
268
|
+
const loop = proto.runEventLoop.call(stubThis);
|
|
269
|
+
// Failures 1..N-1 each schedule one backoff sleep (≤ the 5s cap);
|
|
270
|
+
// the Nth failure terminates without sleeping. Each advance
|
|
271
|
+
// flushes at most one pending sleep.
|
|
272
|
+
for (let i = 0; i < MAX_CONSECUTIVE_NEXT_EVENT_FAILURES; i++) {
|
|
273
|
+
await vi.advanceTimersByTimeAsync(5000);
|
|
274
|
+
}
|
|
275
|
+
await loop;
|
|
276
|
+
return attempts;
|
|
277
|
+
}
|
|
278
|
+
function expectTerminationLogged() {
|
|
279
|
+
expect(errorSpy).toHaveBeenCalledWith(expect.stringContaining(`terminating after ${MAX_CONSECUTIVE_NEXT_EVENT_FAILURES} consecutive nextEvent() failures`), expect.any(Error));
|
|
280
|
+
}
|
|
281
|
+
it("MeshAgent stops retrying after the documented failure count", async () => {
|
|
282
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
283
|
+
const attempts = await runUntilCeiling(MeshAgent.prototype);
|
|
284
|
+
expect(attempts).toBe(MAX_CONSECUTIVE_NEXT_EVENT_FAILURES);
|
|
285
|
+
expectTerminationLogged();
|
|
286
|
+
});
|
|
287
|
+
it("ApiRuntime stops retrying after the documented failure count", async () => {
|
|
288
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
289
|
+
const attempts = await runUntilCeiling(ApiRuntime.prototype);
|
|
290
|
+
expect(attempts).toBe(MAX_CONSECUTIVE_NEXT_EVENT_FAILURES);
|
|
291
|
+
expectTerminationLogged();
|
|
292
|
+
});
|
|
293
|
+
it("MeshExpress stops retrying after the documented failure count", async () => {
|
|
294
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
295
|
+
const attempts = await runUntilCeiling(MeshExpress.prototype);
|
|
296
|
+
expect(attempts).toBe(MAX_CONSECUTIVE_NEXT_EVENT_FAILURES);
|
|
297
|
+
expectTerminationLogged();
|
|
298
|
+
});
|
|
299
|
+
it("a failing loop exits promptly once shutdown() is requested (well before the ceiling)", async () => {
|
|
300
|
+
vi.useFakeTimers();
|
|
301
|
+
let attempts = 0;
|
|
302
|
+
const stubThis = {
|
|
303
|
+
shutdownRequested: false,
|
|
304
|
+
handle: {
|
|
305
|
+
nextEvent: async () => {
|
|
306
|
+
attempts++;
|
|
307
|
+
throw new Error("still broken");
|
|
308
|
+
},
|
|
309
|
+
},
|
|
310
|
+
};
|
|
311
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
312
|
+
const runEventLoop = MeshAgent.prototype.runEventLoop;
|
|
313
|
+
const loop = runEventLoop.call(stubThis);
|
|
314
|
+
await vi.advanceTimersByTimeAsync(100); // flush the first backoff
|
|
315
|
+
stubThis.shutdownRequested = true; // shutdown() sets this flag
|
|
316
|
+
await vi.advanceTimersByTimeAsync(5000); // flush the pending backoff
|
|
317
|
+
await loop; // exits via the failure-branch shutdown check
|
|
318
|
+
expect(attempts).toBeLessThan(MAX_CONSECUTIVE_NEXT_EVENT_FAILURES);
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
//# sourceMappingURL=event-loop-resilience.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-loop-resilience.spec.js","sourceRoot":"","sources":["../../src/__tests__/event-loop-resilience.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -90,17 +90,19 @@ describe("resolveMaxIterations — provider loop cap resolution", () => {
|
|
|
90
90
|
process.env.MESH_LLM_MAX_ITERATIONS = "not-a-number";
|
|
91
91
|
expect(resolveMaxIterations(undefined)).toBe(10);
|
|
92
92
|
});
|
|
93
|
-
// Parity (#1116): the Gemini AI-SDK-managed loop
|
|
94
|
-
// `
|
|
95
|
-
//
|
|
96
|
-
//
|
|
97
|
-
//
|
|
98
|
-
//
|
|
99
|
-
|
|
93
|
+
// Parity (#1116/#1160): the Gemini AI-SDK-managed loop wires
|
|
94
|
+
// `stopWhen: stepCountIs(resolvedMaxIterations)` — AI SDK v6 removed
|
|
95
|
+
// `maxSteps`, whose default-stepCountIs(1) replacement caused the empty
|
|
96
|
+
// assistant message regression (#1160). The actual generateText option
|
|
97
|
+
// wiring is asserted in llm-provider-stopwhen.test.ts, and the multi-step
|
|
98
|
+
// loop behavior (tool call → follow-up text) in
|
|
99
|
+
// llm-provider-multistep.test.ts. Here we only assert the resolution the
|
|
100
|
+
// Gemini path consumes.
|
|
101
|
+
it("Gemini stopWhen path consumes the forwarded resolved cap", () => {
|
|
100
102
|
delete process.env.MESH_LLM_MAX_ITERATIONS;
|
|
101
103
|
expect(resolveMaxIterations(25)).toBe(25);
|
|
102
104
|
});
|
|
103
|
-
it("Gemini
|
|
105
|
+
it("Gemini stopWhen path falls back to 10 when the cap is absent", () => {
|
|
104
106
|
delete process.env.MESH_LLM_MAX_ITERATIONS;
|
|
105
107
|
expect(resolveMaxIterations(undefined)).toBe(10);
|
|
106
108
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm-max-iterations.test.js","sourceRoot":"","sources":["../../src/__tests__/llm-max-iterations.test.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"llm-max-iterations.test.js","sourceRoot":"","sources":["../../src/__tests__/llm-max-iterations.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gemini SDK-managed multi-step loop — end-to-end regression test for #1160.
|
|
3
|
+
*
|
|
4
|
+
* Uses the REAL `ai` module (generateText + stopWhen + tool execution) with a
|
|
5
|
+
* `MockLanguageModelV3` (from `ai/test`) injected via a mocked
|
|
6
|
+
* `@ai-sdk/google` provider. The model emits a tool call on step 1 and text
|
|
7
|
+
* on step 2.
|
|
8
|
+
*
|
|
9
|
+
* With the broken `maxSteps` wiring (removed in AI SDK v6), generateText
|
|
10
|
+
* defaulted to `stopWhen: stepCountIs(1)`: the loop stopped right after the
|
|
11
|
+
* tool-call step, `result.text` was empty, and since the tools carried
|
|
12
|
+
* `_mesh_endpoint` the provider also stripped tool_calls — consumers received
|
|
13
|
+
* an empty assistant message. With `stopWhen: stepCountIs(n)` the loop does
|
|
14
|
+
* the follow-up generation and the final text is non-empty.
|
|
15
|
+
*
|
|
16
|
+
* Tool execution goes through the provider's execute functions →
|
|
17
|
+
* `callMcpTool`, which is mocked here to return a canned tool result.
|
|
18
|
+
*/
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=llm-provider-multistep.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-provider-multistep.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/llm-provider-multistep.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG"}
|