@mcpmesh/sdk 2.8.0 → 2.8.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/dist/__tests__/calling-job.test.d.ts +2 -0
- package/dist/__tests__/calling-job.test.d.ts.map +1 -0
- package/dist/__tests__/calling-job.test.js +154 -0
- package/dist/__tests__/calling-job.test.js.map +1 -0
- package/dist/__tests__/claim-dispatcher-required-gate.test.d.ts +2 -0
- package/dist/__tests__/claim-dispatcher-required-gate.test.d.ts.map +1 -0
- package/dist/__tests__/claim-dispatcher-required-gate.test.js +101 -0
- package/dist/__tests__/claim-dispatcher-required-gate.test.js.map +1 -0
- package/dist/__tests__/direct-invoke-required.spec.d.ts +2 -0
- package/dist/__tests__/direct-invoke-required.spec.d.ts.map +1 -0
- package/dist/__tests__/direct-invoke-required.spec.js +209 -0
- package/dist/__tests__/direct-invoke-required.spec.js.map +1 -0
- package/dist/agent.d.ts +7 -0
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +112 -4
- package/dist/agent.js.map +1 -1
- package/dist/claim-dispatcher.d.ts +18 -1
- package/dist/claim-dispatcher.d.ts.map +1 -1
- package/dist/claim-dispatcher.js +70 -1
- package/dist/claim-dispatcher.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/proxy.d.ts +30 -0
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +61 -0
- package/dist/proxy.js.map +1 -1
- package/dist/tracing.d.ts.map +1 -1
- package/dist/tracing.js +13 -0
- package/dist/tracing.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calling-job.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/calling-job.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Issue #1263: propagate the CALLING job's identity on outbound tool calls via
|
|
3
|
+
* a dedicated header pair, and expose a provider-side accessor.
|
|
4
|
+
*
|
|
5
|
+
* Carrier: `x-mesh-calling-job-id` / `x-mesh-calling-claim-epoch` — distinct
|
|
6
|
+
* from the push-mode dispatch protocol's `x-mesh-job-id` / `x-mesh-claim-epoch`
|
|
7
|
+
* (x-mesh-job-id doubles as the dispatch discriminator and cannot carry calling
|
|
8
|
+
* identity).
|
|
9
|
+
*/
|
|
10
|
+
import { describe, it, expect, vi, afterEach } from "vitest";
|
|
11
|
+
// Keep the REAL core (real matchesPropagateHeader / injectTraceContext); only
|
|
12
|
+
// silence the span publisher and the never-resolving cancel await.
|
|
13
|
+
vi.mock("@mcpmesh/core", async (importOriginal) => {
|
|
14
|
+
const actual = await importOriginal();
|
|
15
|
+
return {
|
|
16
|
+
...actual,
|
|
17
|
+
publishSpan: vi.fn(async () => false),
|
|
18
|
+
awaitJobCancel: vi.fn(() => new Promise(() => { })),
|
|
19
|
+
};
|
|
20
|
+
});
|
|
21
|
+
vi.mock("../http-pool.js", () => ({ getDispatcher: () => undefined }));
|
|
22
|
+
import { callingJob, callMcpTool, DEFAULT_CALL_OPTIONS, runWithPropagatedHeaders, } from "../proxy.js";
|
|
23
|
+
import { matchesPropagateHeader } from "../tracing.js";
|
|
24
|
+
import { CURRENT_JOB } from "../job-context.js";
|
|
25
|
+
describe("allowlist (issue #1263)", () => {
|
|
26
|
+
it("always propagates the calling-* pair", () => {
|
|
27
|
+
expect(matchesPropagateHeader("x-mesh-calling-job-id")).toBe(true);
|
|
28
|
+
expect(matchesPropagateHeader("x-mesh-calling-claim-epoch")).toBe(true);
|
|
29
|
+
});
|
|
30
|
+
it("does NOT allowlist the dispatch pair (reverted)", () => {
|
|
31
|
+
expect(matchesPropagateHeader("x-mesh-job-id")).toBe(false);
|
|
32
|
+
expect(matchesPropagateHeader("x-mesh-claim-epoch")).toBe(false);
|
|
33
|
+
});
|
|
34
|
+
it("is case-insensitive", () => {
|
|
35
|
+
expect(matchesPropagateHeader("X-Mesh-Calling-Job-Id")).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
describe("callingJob() accessor (issue #1263)", () => {
|
|
39
|
+
it("returns null outside a job", () => {
|
|
40
|
+
expect(callingJob()).toBeNull();
|
|
41
|
+
});
|
|
42
|
+
it("returns null when no calling job id", () => {
|
|
43
|
+
runWithPropagatedHeaders({ "x-mesh-calling-claim-epoch": "7" }, () => {
|
|
44
|
+
expect(callingJob()).toBeNull();
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
it("does NOT read the dispatch pair", () => {
|
|
48
|
+
runWithPropagatedHeaders({ "x-mesh-job-id": "job-self", "x-mesh-claim-epoch": "3" }, () => {
|
|
49
|
+
expect(callingJob()).toBeNull();
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
it("returns jobId + claimEpoch from the calling-* pair", () => {
|
|
53
|
+
runWithPropagatedHeaders({
|
|
54
|
+
"x-mesh-calling-job-id": "job-abc",
|
|
55
|
+
"x-mesh-calling-claim-epoch": "5",
|
|
56
|
+
}, () => {
|
|
57
|
+
expect(callingJob()).toEqual({ jobId: "job-abc", claimEpoch: 5 });
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
it("claimEpoch is null when only calling job id present", () => {
|
|
61
|
+
runWithPropagatedHeaders({ "x-mesh-calling-job-id": "job-xyz" }, () => {
|
|
62
|
+
expect(callingJob()).toEqual({ jobId: "job-xyz", claimEpoch: null });
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
it("malformed epoch degrades to null", () => {
|
|
66
|
+
runWithPropagatedHeaders({ "x-mesh-calling-job-id": "job-1", "x-mesh-calling-claim-epoch": "5.5" }, () => {
|
|
67
|
+
expect(callingJob()?.claimEpoch).toBeNull();
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
describe("outbound overlay (issue #1263)", () => {
|
|
72
|
+
let captured;
|
|
73
|
+
function mockFetch() {
|
|
74
|
+
captured = undefined;
|
|
75
|
+
globalThis.fetch = vi.fn(async (_url, init) => {
|
|
76
|
+
captured = init;
|
|
77
|
+
const body = JSON.stringify({
|
|
78
|
+
jsonrpc: "2.0",
|
|
79
|
+
id: "x",
|
|
80
|
+
result: { content: [{ type: "text", text: "{}" }] },
|
|
81
|
+
});
|
|
82
|
+
return {
|
|
83
|
+
ok: true,
|
|
84
|
+
status: 200,
|
|
85
|
+
statusText: "OK",
|
|
86
|
+
text: async () => body,
|
|
87
|
+
headers: {
|
|
88
|
+
get: (n) => n.toLowerCase() === "content-type" ? "application/json" : null,
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
function capturedHeaders() {
|
|
94
|
+
return (captured?.headers ?? {});
|
|
95
|
+
}
|
|
96
|
+
function capturedMeshHeaders() {
|
|
97
|
+
const body = JSON.parse(captured?.body ?? "{}");
|
|
98
|
+
return (body?.params?.arguments?._mesh_headers ?? {});
|
|
99
|
+
}
|
|
100
|
+
function snap(jobId, claimEpoch) {
|
|
101
|
+
return { jobId, deadlineSecsRemaining: null, claimEpoch };
|
|
102
|
+
}
|
|
103
|
+
afterEach(() => {
|
|
104
|
+
vi.restoreAllMocks();
|
|
105
|
+
});
|
|
106
|
+
it("no active job → no calling-* seeded", async () => {
|
|
107
|
+
mockFetch();
|
|
108
|
+
await callMcpTool("http://d:9000", "t", { a: 1 }, DEFAULT_CALL_OPTIONS, "cap");
|
|
109
|
+
expect(capturedHeaders()["x-mesh-calling-job-id"]).toBeUndefined();
|
|
110
|
+
});
|
|
111
|
+
it("seeds both from the active job snapshot", async () => {
|
|
112
|
+
mockFetch();
|
|
113
|
+
await CURRENT_JOB.run(snap("job-A", 4), async () => {
|
|
114
|
+
await callMcpTool("http://d:9000", "t", {}, DEFAULT_CALL_OPTIONS, "cap");
|
|
115
|
+
});
|
|
116
|
+
expect(capturedHeaders()["x-mesh-calling-job-id"]).toBe("job-A");
|
|
117
|
+
expect(capturedHeaders()["x-mesh-calling-claim-epoch"]).toBe("4");
|
|
118
|
+
// Also carried in the _mesh_headers args (FastMCP-visible path).
|
|
119
|
+
expect(capturedMeshHeaders()["x-mesh-calling-job-id"]).toBe("job-A");
|
|
120
|
+
});
|
|
121
|
+
it("seeds id only when the snapshot has no epoch", async () => {
|
|
122
|
+
mockFetch();
|
|
123
|
+
await CURRENT_JOB.run(snap("job-A", null), async () => {
|
|
124
|
+
await callMcpTool("http://d:9000", "t", {}, DEFAULT_CALL_OPTIONS, "cap");
|
|
125
|
+
});
|
|
126
|
+
expect(capturedHeaders()["x-mesh-calling-job-id"]).toBe("job-A");
|
|
127
|
+
expect(capturedHeaders()["x-mesh-calling-claim-epoch"]).toBeUndefined();
|
|
128
|
+
});
|
|
129
|
+
it("replaces an inherited pair entirely — no stale epoch rides along", async () => {
|
|
130
|
+
mockFetch();
|
|
131
|
+
await runWithPropagatedHeaders({
|
|
132
|
+
"x-mesh-calling-job-id": "job-OLD",
|
|
133
|
+
"x-mesh-calling-claim-epoch": "99",
|
|
134
|
+
}, async () => {
|
|
135
|
+
await CURRENT_JOB.run(snap("job-NEW", null), async () => {
|
|
136
|
+
await callMcpTool("http://d:9000", "t", {}, DEFAULT_CALL_OPTIONS, "cap");
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
expect(capturedHeaders()["x-mesh-calling-job-id"]).toBe("job-NEW");
|
|
140
|
+
expect(capturedHeaders()["x-mesh-calling-claim-epoch"]).toBeUndefined();
|
|
141
|
+
});
|
|
142
|
+
it("passes an inherited pair through when there is no active job", async () => {
|
|
143
|
+
mockFetch();
|
|
144
|
+
await runWithPropagatedHeaders({
|
|
145
|
+
"x-mesh-calling-job-id": "job-UP",
|
|
146
|
+
"x-mesh-calling-claim-epoch": "2",
|
|
147
|
+
}, async () => {
|
|
148
|
+
await callMcpTool("http://d:9000", "t", {}, DEFAULT_CALL_OPTIONS, "cap");
|
|
149
|
+
});
|
|
150
|
+
expect(capturedHeaders()["x-mesh-calling-job-id"]).toBe("job-UP");
|
|
151
|
+
expect(capturedHeaders()["x-mesh-calling-claim-epoch"]).toBe("2");
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
//# sourceMappingURL=calling-job.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calling-job.test.js","sourceRoot":"","sources":["../../src/__tests__/calling-job.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claim-dispatcher-required-gate.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/claim-dispatcher-required-gate.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Issue #1268: claim dispatch must gate on locally-resolved required deps.
|
|
3
|
+
*
|
|
4
|
+
* - Pre-claim skip: the dispatcher must NOT POST /jobs/claim while a required
|
|
5
|
+
* dependency slot is unresolved locally.
|
|
6
|
+
* - Pre-invoke guard: a still-unresolved required slot at invoke time must
|
|
7
|
+
* release the lease (retryable), never terminal-fail, and must NOT run the
|
|
8
|
+
* handler.
|
|
9
|
+
* - Optional deps (no probe) run as before.
|
|
10
|
+
*/
|
|
11
|
+
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
12
|
+
// Fake JobController captured per-test so assertions can inspect it.
|
|
13
|
+
let lastController = null;
|
|
14
|
+
vi.mock("../inbound-job-dispatch.js", () => ({
|
|
15
|
+
makeJobController: vi.fn(() => {
|
|
16
|
+
lastController = {
|
|
17
|
+
releaseLease: vi.fn(async () => { }),
|
|
18
|
+
fail: vi.fn(async () => { }),
|
|
19
|
+
};
|
|
20
|
+
return lastController;
|
|
21
|
+
}),
|
|
22
|
+
// Pass-through: invoke the thunk so the handler runs when the guard allows.
|
|
23
|
+
runWithJobContext: vi.fn(async (_jobId, _dl, _controller, invoke) => invoke()),
|
|
24
|
+
}));
|
|
25
|
+
vi.mock("../proxy.js", () => ({
|
|
26
|
+
runWithPropagatedHeaders: (_headers, fn) => fn(),
|
|
27
|
+
}));
|
|
28
|
+
import { ClaimDispatcher } from "../claim-dispatcher.js";
|
|
29
|
+
function makeDispatcher(handler, requiredProbe) {
|
|
30
|
+
return new ClaimDispatcher("test_cap", "test-instance", "http://registry:8000", handler, undefined, requiredProbe);
|
|
31
|
+
}
|
|
32
|
+
beforeEach(() => {
|
|
33
|
+
lastController = null;
|
|
34
|
+
vi.clearAllMocks();
|
|
35
|
+
});
|
|
36
|
+
describe("pre-invoke guard (issue #1268)", () => {
|
|
37
|
+
it("unresolved required dep → releaseLease, no handler, no fail", async () => {
|
|
38
|
+
const handlerCalls = [];
|
|
39
|
+
const handler = async (payload) => {
|
|
40
|
+
handlerCalls.push(payload);
|
|
41
|
+
};
|
|
42
|
+
const d = makeDispatcher(handler, () => "cap_a");
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
44
|
+
await d._dispatch({ id: "job-1", submitted_payload: {} });
|
|
45
|
+
expect(handlerCalls).toEqual([]);
|
|
46
|
+
expect(lastController).not.toBeNull();
|
|
47
|
+
expect(lastController.releaseLease).toHaveBeenCalledTimes(1);
|
|
48
|
+
expect(lastController.fail).not.toHaveBeenCalled();
|
|
49
|
+
});
|
|
50
|
+
it("resolved required dep → handler runs, no release", async () => {
|
|
51
|
+
const handlerCalls = [];
|
|
52
|
+
const handler = async (payload) => {
|
|
53
|
+
handlerCalls.push(payload);
|
|
54
|
+
};
|
|
55
|
+
const d = makeDispatcher(handler, () => null);
|
|
56
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
57
|
+
await d._dispatch({ id: "job-2", submitted_payload: { x: 1 } });
|
|
58
|
+
expect(handlerCalls).toEqual([{ x: 1 }]);
|
|
59
|
+
expect(lastController.releaseLease).not.toHaveBeenCalled();
|
|
60
|
+
expect(lastController.fail).not.toHaveBeenCalled();
|
|
61
|
+
});
|
|
62
|
+
it("optional deps (no probe) → handler runs (regression)", async () => {
|
|
63
|
+
const handlerCalls = [];
|
|
64
|
+
const handler = async (payload) => {
|
|
65
|
+
handlerCalls.push(payload);
|
|
66
|
+
};
|
|
67
|
+
const d = makeDispatcher(handler); // no requiredProbe
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
69
|
+
await d._dispatch({ id: "job-3", submitted_payload: {} });
|
|
70
|
+
expect(handlerCalls).toEqual([{}]);
|
|
71
|
+
expect(lastController.releaseLease).not.toHaveBeenCalled();
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
describe("pre-claim skip (issue #1268)", () => {
|
|
75
|
+
it("does not claim while a required dep is unresolved", async () => {
|
|
76
|
+
const d = makeDispatcher(async () => { }, () => "cap_a");
|
|
77
|
+
const claimSpy = vi.fn(async () => []);
|
|
78
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
79
|
+
d._claimOnce = claimSpy;
|
|
80
|
+
d.start();
|
|
81
|
+
await new Promise((r) => setTimeout(r, 60));
|
|
82
|
+
await d.stop(0);
|
|
83
|
+
expect(claimSpy).not.toHaveBeenCalled();
|
|
84
|
+
});
|
|
85
|
+
it("claims once the required dep is resolved", async () => {
|
|
86
|
+
let resolved = false;
|
|
87
|
+
const d = makeDispatcher(async () => { }, () => (resolved ? null : "cap_a"));
|
|
88
|
+
const claimSpy = vi.fn(async () => []);
|
|
89
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
90
|
+
d._claimOnce = claimSpy;
|
|
91
|
+
d.start();
|
|
92
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
93
|
+
resolved = true;
|
|
94
|
+
// Wait past one base poll interval (500ms) so the loop wakes, re-probes
|
|
95
|
+
// (now resolved), and issues a claim.
|
|
96
|
+
await new Promise((r) => setTimeout(r, 650));
|
|
97
|
+
await d.stop(0);
|
|
98
|
+
expect(claimSpy).toHaveBeenCalled();
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
//# sourceMappingURL=claim-dispatcher-required-gate.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claim-dispatcher-required-gate.test.js","sourceRoot":"","sources":["../../src/__tests__/claim-dispatcher-required-gate.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"direct-invoke-required.spec.d.ts","sourceRoot":"","sources":["../../src/__tests__/direct-invoke-required.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Issue #1273: direct `tools/call` dispatch must refuse when a `required=true`
|
|
3
|
+
* dependency slot is unresolved at invocation time.
|
|
4
|
+
*
|
|
5
|
+
* The claim path (#1268, requiredProbe) and the @mesh.route perimeter (#1249,
|
|
6
|
+
* 503) already refuse before a handler can observe a null required dependency;
|
|
7
|
+
* this closes the same DOWN→UP flap window on the plain tool-dispatch path.
|
|
8
|
+
* The guard is FLAVOR-AWARE (review follow-up):
|
|
9
|
+
* - plain tools/call → structured `dependency_unavailable` refusal (a
|
|
10
|
+
* `UserError` whose message carries the JSON envelope → FastMCP `isError`
|
|
11
|
+
* result, the SAME semantic class as the route perimeter's 503), so the
|
|
12
|
+
* caller classifies it as retryable topology.
|
|
13
|
+
* - inbound JOB dispatch (task tool + X-Mesh-Job-Id) → RELEASE the lease so
|
|
14
|
+
* the claimed row re-queues, mirroring the claim path — never a bare throw
|
|
15
|
+
* (which would strand the row `working` until lease expiry).
|
|
16
|
+
* Optional deps keep their null-passthrough. The guard runs AFTER the settle
|
|
17
|
+
* wait (deps are built post-settle).
|
|
18
|
+
*/
|
|
19
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
|
20
|
+
import { z } from "zod";
|
|
21
|
+
import { UserError } from "fastmcp";
|
|
22
|
+
// Only `makeJobController` is mocked (it wraps a napi JobController handle that
|
|
23
|
+
// hits the registry). The REAL `readJobHeaders` runs against the raw inbound
|
|
24
|
+
// `_mesh_headers` the test passes through `execute(...)` — so the job-header
|
|
25
|
+
// extraction path (item 1's fix: raw headers, not the allowlist-filtered map)
|
|
26
|
+
// is exercised end-to-end. Declared via vi.hoisted so the hoisted vi.mock
|
|
27
|
+
// factory below can reference them (TDZ otherwise).
|
|
28
|
+
const h = vi.hoisted(() => {
|
|
29
|
+
const releaseLeaseMock = vi.fn(async () => { });
|
|
30
|
+
const makeJobControllerMock = vi.fn(() => ({ releaseLease: releaseLeaseMock }));
|
|
31
|
+
return { releaseLeaseMock, makeJobControllerMock };
|
|
32
|
+
});
|
|
33
|
+
vi.mock("../inbound-job-dispatch.js", async (importActual) => {
|
|
34
|
+
const actual = await importActual();
|
|
35
|
+
return {
|
|
36
|
+
...actual,
|
|
37
|
+
makeJobController: h.makeJobControllerMock,
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
import { MeshAgent } from "../agent.js";
|
|
41
|
+
import { RouteRegistry } from "../route.js";
|
|
42
|
+
import { resetSettleStateForTests } from "../settle.js";
|
|
43
|
+
function makeFastMCPStub() {
|
|
44
|
+
return {
|
|
45
|
+
addTool: vi.fn(),
|
|
46
|
+
start: vi.fn(),
|
|
47
|
+
getApp: vi.fn(),
|
|
48
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
let autoStartSpy = null;
|
|
52
|
+
let warnSpy = null;
|
|
53
|
+
const savedEnv = {};
|
|
54
|
+
beforeEach(() => {
|
|
55
|
+
h.releaseLeaseMock.mockClear();
|
|
56
|
+
h.makeJobControllerMock.mockClear();
|
|
57
|
+
autoStartSpy = vi
|
|
58
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
59
|
+
.spyOn(MeshAgent.prototype, "_autoStart")
|
|
60
|
+
.mockImplementation(async () => {
|
|
61
|
+
/* no-op */
|
|
62
|
+
});
|
|
63
|
+
warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {
|
|
64
|
+
/* swallow */
|
|
65
|
+
});
|
|
66
|
+
savedEnv.MCP_MESH_SETTLE_TIMEOUT = process.env.MCP_MESH_SETTLE_TIMEOUT;
|
|
67
|
+
savedEnv.MCP_MESH_TOOL_ISOLATION = process.env.MCP_MESH_TOOL_ISOLATION;
|
|
68
|
+
process.env.MCP_MESH_TOOL_ISOLATION = "false";
|
|
69
|
+
// Settle immediately so an unresolved required slot is genuinely unresolved,
|
|
70
|
+
// not merely still-settling.
|
|
71
|
+
process.env.MCP_MESH_SETTLE_TIMEOUT = "0";
|
|
72
|
+
resetSettleStateForTests();
|
|
73
|
+
RouteRegistry.reset();
|
|
74
|
+
});
|
|
75
|
+
afterEach(() => {
|
|
76
|
+
autoStartSpy?.mockRestore();
|
|
77
|
+
autoStartSpy = null;
|
|
78
|
+
warnSpy?.mockRestore();
|
|
79
|
+
warnSpy = null;
|
|
80
|
+
for (const [key, value] of Object.entries(savedEnv)) {
|
|
81
|
+
if (value === undefined)
|
|
82
|
+
delete process.env[key];
|
|
83
|
+
else
|
|
84
|
+
process.env[key] = value;
|
|
85
|
+
}
|
|
86
|
+
resetSettleStateForTests();
|
|
87
|
+
RouteRegistry.reset();
|
|
88
|
+
});
|
|
89
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
90
|
+
function captureExecute(fastmcp) {
|
|
91
|
+
return fastmcp.addTool.mock.calls[0][0].execute;
|
|
92
|
+
}
|
|
93
|
+
describe("direct-invoke required-dep guard (#1273)", () => {
|
|
94
|
+
it("refuses with dependency_unavailable when a required slot is unresolved", async () => {
|
|
95
|
+
const fastmcp = makeFastMCPStub();
|
|
96
|
+
const agent = new MeshAgent(fastmcp, { name: "guard-agent", httpPort: 0 });
|
|
97
|
+
const calls = [];
|
|
98
|
+
agent.addTool({
|
|
99
|
+
name: "enrich",
|
|
100
|
+
parameters: z.object({}),
|
|
101
|
+
dependencies: [{ capability: "lookup", required: true }],
|
|
102
|
+
execute: async (_args, dep) => {
|
|
103
|
+
calls.push(dep);
|
|
104
|
+
return "ran";
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
const execute = captureExecute(fastmcp);
|
|
108
|
+
let thrown;
|
|
109
|
+
try {
|
|
110
|
+
await execute({});
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
thrown = err;
|
|
114
|
+
}
|
|
115
|
+
expect(thrown).toBeInstanceOf(UserError);
|
|
116
|
+
const body = JSON.parse(thrown.message);
|
|
117
|
+
expect(body).toEqual({
|
|
118
|
+
error: "dependency_unavailable",
|
|
119
|
+
capability: "lookup",
|
|
120
|
+
});
|
|
121
|
+
expect(calls).toHaveLength(0); // handler must NOT run
|
|
122
|
+
expect(h.releaseLeaseMock).not.toHaveBeenCalled(); // not a job flavor
|
|
123
|
+
});
|
|
124
|
+
it("invokes the handler once the required dep resolves", async () => {
|
|
125
|
+
const fastmcp = makeFastMCPStub();
|
|
126
|
+
const agent = new MeshAgent(fastmcp, { name: "resolved-agent", httpPort: 0 });
|
|
127
|
+
const calls = [];
|
|
128
|
+
agent.addTool({
|
|
129
|
+
name: "enrich",
|
|
130
|
+
parameters: z.object({}),
|
|
131
|
+
dependencies: [{ capability: "lookup", required: true }],
|
|
132
|
+
execute: async (_args, dep) => {
|
|
133
|
+
calls.push(dep);
|
|
134
|
+
return "ran";
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
// Resolve the required dependency so a real proxy lands in the slot.
|
|
138
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
139
|
+
agent.handleDependencyAvailable("lookup", "http://localhost:19999", "remote_fn", "provider-agent", "enrich", 0);
|
|
140
|
+
const execute = captureExecute(fastmcp);
|
|
141
|
+
expect(await execute({})).toBe("ran");
|
|
142
|
+
expect(calls).toHaveLength(1);
|
|
143
|
+
expect(calls[0]).not.toBeNull(); // ran with the live proxy
|
|
144
|
+
});
|
|
145
|
+
it("passes null through for an unresolved OPTIONAL dep (regression)", async () => {
|
|
146
|
+
const fastmcp = makeFastMCPStub();
|
|
147
|
+
const agent = new MeshAgent(fastmcp, { name: "optional-agent", httpPort: 0 });
|
|
148
|
+
const calls = [];
|
|
149
|
+
agent.addTool({
|
|
150
|
+
name: "enrich",
|
|
151
|
+
parameters: z.object({}),
|
|
152
|
+
// No `required` → optional; null passthrough preserved.
|
|
153
|
+
dependencies: [{ capability: "lookup" }],
|
|
154
|
+
execute: async (_args, dep) => {
|
|
155
|
+
calls.push(dep);
|
|
156
|
+
return dep ? "wired" : "unwired";
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
const execute = captureExecute(fastmcp);
|
|
160
|
+
expect(await execute({})).toBe("unwired");
|
|
161
|
+
expect(calls).toEqual([null]); // handler ran with null, no refusal
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
describe("job-header path releases the lease, never throws (#1273)", () => {
|
|
165
|
+
it("releases the lease (not a throw) when an inbound JOB dispatch hits an unresolved required dep", async () => {
|
|
166
|
+
// registryUrl defaults from env (MCP_MESH_REGISTRY_URL →
|
|
167
|
+
// http://localhost:8000), so this.config.registryUrl is non-empty.
|
|
168
|
+
const fastmcp = makeFastMCPStub();
|
|
169
|
+
const agent = new MeshAgent(fastmcp, {
|
|
170
|
+
name: "job-guard-agent",
|
|
171
|
+
httpPort: 0,
|
|
172
|
+
});
|
|
173
|
+
const calls = [];
|
|
174
|
+
agent.addTool({
|
|
175
|
+
name: "render",
|
|
176
|
+
task: true,
|
|
177
|
+
parameters: z.object({}),
|
|
178
|
+
dependencies: [{ capability: "lookup", required: true }],
|
|
179
|
+
execute: async (_args, dep) => {
|
|
180
|
+
calls.push(dep);
|
|
181
|
+
return "ran";
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
const execute = captureExecute(fastmcp);
|
|
185
|
+
// Present an inbound JOB dispatch by passing the job headers through the
|
|
186
|
+
// REAL extraction path in _mesh_headers. x-mesh-job-id is NOT in the
|
|
187
|
+
// propagate allowlist, so this only works because the guard reads the RAW
|
|
188
|
+
// inbound headers (item 1's fix), not the allowlist-filtered map.
|
|
189
|
+
const result = await execute({
|
|
190
|
+
_mesh_headers: {
|
|
191
|
+
"x-mesh-job-id": "job-77",
|
|
192
|
+
"x-mesh-claim-epoch": "3",
|
|
193
|
+
},
|
|
194
|
+
});
|
|
195
|
+
// Must NOT throw — the job-flavored path releases the lease instead.
|
|
196
|
+
expect(result).toBe("");
|
|
197
|
+
expect(calls).toHaveLength(0); // handler MUST NOT run
|
|
198
|
+
expect(h.makeJobControllerMock).toHaveBeenCalledTimes(1);
|
|
199
|
+
// makeJobController(jobId, agentId, registryUrl, claimEpoch)
|
|
200
|
+
const ctorArgs = h.makeJobControllerMock.mock
|
|
201
|
+
.calls[0];
|
|
202
|
+
expect(ctorArgs[0]).toBe("job-77");
|
|
203
|
+
expect(ctorArgs[3]).toBe(3);
|
|
204
|
+
expect(h.releaseLeaseMock).toHaveBeenCalledTimes(1);
|
|
205
|
+
const releaseArgs = h.releaseLeaseMock.mock.calls[0];
|
|
206
|
+
expect(String(releaseArgs[0])).toContain("lookup");
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
//# sourceMappingURL=direct-invoke-required.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"direct-invoke-required.spec.js","sourceRoot":"","sources":["../../src/__tests__/direct-invoke-required.spec.ts"],"names":[],"mappings":"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"}
|
package/dist/agent.d.ts
CHANGED
|
@@ -109,6 +109,13 @@ export declare class MeshAgent {
|
|
|
109
109
|
* Issue #894: also carries the per-tool retryOn whitelist so the
|
|
110
110
|
* dispatcher can pass it into `runWithJobContext` for the
|
|
111
111
|
* release-lease-on-retry-eligible-throw path.
|
|
112
|
+
*
|
|
113
|
+
* Issue #1268: also carries a `requiredProbe` closure that reports the
|
|
114
|
+
* first `required=true` dependency slot that is still unresolved locally
|
|
115
|
+
* (its proxy is null/absent in `resolvedDeps`), or null when all required
|
|
116
|
+
* deps are live. The dispatcher consults it BEFORE claiming (pre-claim
|
|
117
|
+
* skip) and BEFORE invoking (pre-invoke guard) so the claim gate and the
|
|
118
|
+
* handler's injection read one clock.
|
|
112
119
|
*/
|
|
113
120
|
private _taskHandlers;
|
|
114
121
|
/**
|
package/dist/agent.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAG7B,OAAO,EAGL,KAAK,aAAa,EAInB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EACV,WAAW,EACX,mBAAmB,EACnB,WAAW,EAEX,WAAW,EAEX,iBAAiB,EAClB,MAAM,YAAY,CAAC;AA6DpB;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,gBAAgB,eAAuC,CAAC;AAiBrE;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAEjF;AA0BD,4EAA4E;AAC5E,wBAAgB,gCAAgC,IAAI,IAAI,CAEvD;AAuBD;;;;;;;;GAQG;AACH,qBAAa,SAAS;IACpB;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,0BAA0B,CAAU;IAE5D,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAoC;IACjD;;;;OAIG;IACH,OAAO,CAAC,kBAAkB,CAAkC;IAC5D,OAAO,CAAC,MAAM,CAA8B;IAC5C,OAAO,CAAC,UAAU,CAAC,CAA8B;IACjD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,iBAAiB,CAAS;IAClC;;;;;;OAMG;IACH,OAAO,CAAC,eAAe,CAA8B;IACrD;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc,CAGN;IAEhB;;;;;;;OAOG;IACH,OAAO,CAAC,YAAY,CAAuC;IAK3D,OAAO,CAAC,WAAW,CAAS;IAE5B;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,aAAa,CAOP;IACd;;;;OAIG;IACH,OAAO,CAAC,iBAAiB,CAAyB;IAElD;;;;;OAKG;IACH,OAAO,CAAC,WAAW,CAAqC;IAExD;;;;;;;OAOG;IACH,OAAO,CAAC,UAAU,CAA6C;IAC/D,OAAO,CAAC,aAAa,CAAK;gBAEd,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW;IAsDhD;;;;;;OAMG;IACH,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI;IAowBvD;;;;;;;;;;;;;;;;;OAiBG;IACH,cAAc,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAyC/C;;;;;;;;;;OAUG;IACH,OAAO,CAAC,sBAAsB;IAQ9B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,eAAe;IAkBvB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,cAAc;IAsCtB,OAAO,CAAC,oBAAoB;IAgB5B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAS9B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAkKjC;;;;OAIG;IACH,OAAO,CAAC,uBAAuB;IA4B/B;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAiB7B;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAoBxB;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,qBAAqB;IAoD7B;;OAEG;YACW,cAAc;IAmN5B;;;;;;;;;;;OAWG;YACW,YAAY;IAgK1B;;;;;;;OAOG;IACH,OAAO,CAAC,yBAAyB;IAkDjC;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IAiCnC;;;;;OAKG;IACH,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAYrD;;;;;;OAMG;IACH,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAI1E;;OAEG;IACH,kBAAkB,IAAI,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC;IAI9C;;;;;;;;OAQG;IACH,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI;IAe9D;;OAEG;IACH,SAAS,IAAI,aAAa,GAAG,IAAI;IAIjC;;OAEG;IACH,SAAS,IAAI,mBAAmB;IAIhC;;OAEG;IACH,UAAU,IAAI,MAAM;IAIpB;;;;;;;;;OASG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE;QACd,mEAAmE;QACnE,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,uEAAuE;QACvE,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,GAAG,OAAO,CAAC,IAAI,CAAC;CAwElB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,GAAG,SAAS,CAEpE"}
|