@mcpmesh/sdk 1.3.4 → 2.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/a2a/a2a-bearer.spec.d.ts +2 -0
- package/dist/__tests__/a2a/a2a-bearer.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/a2a-bearer.spec.js +58 -0
- package/dist/__tests__/a2a/a2a-bearer.spec.js.map +1 -0
- package/dist/__tests__/a2a/a2a-client.spec.d.ts +2 -0
- package/dist/__tests__/a2a/a2a-client.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/a2a-client.spec.js +334 -0
- package/dist/__tests__/a2a/a2a-client.spec.js.map +1 -0
- package/dist/__tests__/a2a/a2a-job.spec.d.ts +2 -0
- package/dist/__tests__/a2a/a2a-job.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/a2a-job.spec.js +255 -0
- package/dist/__tests__/a2a/a2a-job.spec.js.map +1 -0
- package/dist/__tests__/a2a/a2a-stream.spec.d.ts +2 -0
- package/dist/__tests__/a2a/a2a-stream.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/a2a-stream.spec.js +278 -0
- package/dist/__tests__/a2a/a2a-stream.spec.js.map +1 -0
- package/dist/__tests__/a2a/agent-a2a-config.spec.d.ts +2 -0
- package/dist/__tests__/a2a/agent-a2a-config.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/agent-a2a-config.spec.js +262 -0
- package/dist/__tests__/a2a/agent-a2a-config.spec.js.map +1 -0
- package/dist/__tests__/a2a/producer/auth-filter.spec.d.ts +2 -0
- package/dist/__tests__/a2a/producer/auth-filter.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/producer/auth-filter.spec.js +127 -0
- package/dist/__tests__/a2a/producer/auth-filter.spec.js.map +1 -0
- package/dist/__tests__/a2a/producer/card-builder.spec.d.ts +2 -0
- package/dist/__tests__/a2a/producer/card-builder.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/producer/card-builder.spec.js +113 -0
- package/dist/__tests__/a2a/producer/card-builder.spec.js.map +1 -0
- package/dist/__tests__/a2a/producer/dispatcher.spec.d.ts +2 -0
- package/dist/__tests__/a2a/producer/dispatcher.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/producer/dispatcher.spec.js +850 -0
- package/dist/__tests__/a2a/producer/dispatcher.spec.js.map +1 -0
- package/dist/__tests__/a2a/producer/mount-surface-push.spec.d.ts +2 -0
- package/dist/__tests__/a2a/producer/mount-surface-push.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/producer/mount-surface-push.spec.js +164 -0
- package/dist/__tests__/a2a/producer/mount-surface-push.spec.js.map +1 -0
- package/dist/__tests__/a2a/producer/mount.spec.d.ts +2 -0
- package/dist/__tests__/a2a/producer/mount.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/producer/mount.spec.js +433 -0
- package/dist/__tests__/a2a/producer/mount.spec.js.map +1 -0
- package/dist/__tests__/a2a/producer/public-url-cache.spec.d.ts +2 -0
- package/dist/__tests__/a2a/producer/public-url-cache.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/producer/public-url-cache.spec.js +116 -0
- package/dist/__tests__/a2a/producer/public-url-cache.spec.js.map +1 -0
- package/dist/__tests__/a2a/producer/sse-emitter.spec.d.ts +2 -0
- package/dist/__tests__/a2a/producer/sse-emitter.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/producer/sse-emitter.spec.js +754 -0
- package/dist/__tests__/a2a/producer/sse-emitter.spec.js.map +1 -0
- package/dist/__tests__/a2a/producer/state-translator.spec.d.ts +2 -0
- package/dist/__tests__/a2a/producer/state-translator.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/producer/state-translator.spec.js +124 -0
- package/dist/__tests__/a2a/producer/state-translator.spec.js.map +1 -0
- package/dist/__tests__/a2a/producer/task-store.spec.d.ts +2 -0
- package/dist/__tests__/a2a/producer/task-store.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/producer/task-store.spec.js +180 -0
- package/dist/__tests__/a2a/producer/task-store.spec.js.map +1 -0
- package/dist/__tests__/agent-add-tool.spec.d.ts +2 -0
- package/dist/__tests__/agent-add-tool.spec.d.ts.map +1 -0
- package/dist/__tests__/agent-add-tool.spec.js +483 -0
- package/dist/__tests__/agent-add-tool.spec.js.map +1 -0
- package/dist/__tests__/api-runtime-race.spec.d.ts +2 -0
- package/dist/__tests__/api-runtime-race.spec.d.ts.map +1 -0
- package/dist/__tests__/api-runtime-race.spec.js +193 -0
- package/dist/__tests__/api-runtime-race.spec.js.map +1 -0
- package/dist/__tests__/claim-dispatcher.spec.d.ts +2 -0
- package/dist/__tests__/claim-dispatcher.spec.d.ts.map +1 -0
- package/dist/__tests__/claim-dispatcher.spec.js +408 -0
- package/dist/__tests__/claim-dispatcher.spec.js.map +1 -0
- package/dist/__tests__/inbound-job-dispatch.spec.d.ts +2 -0
- package/dist/__tests__/inbound-job-dispatch.spec.d.ts.map +1 -0
- package/dist/__tests__/inbound-job-dispatch.spec.js +185 -0
- package/dist/__tests__/inbound-job-dispatch.spec.js.map +1 -0
- package/dist/__tests__/job-controller-progress.spec.d.ts +2 -0
- package/dist/__tests__/job-controller-progress.spec.d.ts.map +1 -0
- package/dist/__tests__/job-controller-progress.spec.js +85 -0
- package/dist/__tests__/job-controller-progress.spec.js.map +1 -0
- package/dist/__tests__/jobs-cancel-route.spec.d.ts +2 -0
- package/dist/__tests__/jobs-cancel-route.spec.d.ts.map +1 -0
- package/dist/__tests__/jobs-cancel-route.spec.js +88 -0
- package/dist/__tests__/jobs-cancel-route.spec.js.map +1 -0
- package/dist/__tests__/llm-agent-stream.test.d.ts +14 -0
- package/dist/__tests__/llm-agent-stream.test.d.ts.map +1 -0
- package/dist/__tests__/llm-agent-stream.test.js +341 -0
- package/dist/__tests__/llm-agent-stream.test.js.map +1 -0
- package/dist/__tests__/llm-provider.test.js +22 -1
- package/dist/__tests__/llm-provider.test.js.map +1 -1
- package/dist/__tests__/media-resolver.test.js +40 -0
- package/dist/__tests__/media-resolver.test.js.map +1 -1
- package/dist/__tests__/mesh-job-submitter.spec.d.ts +2 -0
- package/dist/__tests__/mesh-job-submitter.spec.d.ts.map +1 -0
- package/dist/__tests__/mesh-job-submitter.spec.js +110 -0
- package/dist/__tests__/mesh-job-submitter.spec.js.map +1 -0
- package/dist/__tests__/proxy-stream.test.d.ts +9 -0
- package/dist/__tests__/proxy-stream.test.d.ts.map +1 -0
- package/dist/__tests__/proxy-stream.test.js +347 -0
- package/dist/__tests__/proxy-stream.test.js.map +1 -0
- package/dist/__tests__/resolver-meshjob.spec.d.ts +26 -0
- package/dist/__tests__/resolver-meshjob.spec.d.ts.map +1 -0
- package/dist/__tests__/resolver-meshjob.spec.js +201 -0
- package/dist/__tests__/resolver-meshjob.spec.js.map +1 -0
- package/dist/__tests__/schema-verdict-policy.test.d.ts +6 -0
- package/dist/__tests__/schema-verdict-policy.test.d.ts.map +1 -0
- package/dist/__tests__/schema-verdict-policy.test.js +126 -0
- package/dist/__tests__/schema-verdict-policy.test.js.map +1 -0
- package/dist/__tests__/sse-stream.test.d.ts +12 -0
- package/dist/__tests__/sse-stream.test.d.ts.map +1 -0
- package/dist/__tests__/sse-stream.test.js +170 -0
- package/dist/__tests__/sse-stream.test.js.map +1 -0
- package/dist/a2a/a2a-bearer.d.ts +27 -0
- package/dist/a2a/a2a-bearer.d.ts.map +1 -0
- package/dist/a2a/a2a-bearer.js +63 -0
- package/dist/a2a/a2a-bearer.js.map +1 -0
- package/dist/a2a/a2a-client.d.ts +114 -0
- package/dist/a2a/a2a-client.d.ts.map +1 -0
- package/dist/a2a/a2a-client.js +405 -0
- package/dist/a2a/a2a-client.js.map +1 -0
- package/dist/a2a/a2a-event.d.ts +25 -0
- package/dist/a2a/a2a-event.d.ts.map +1 -0
- package/dist/a2a/a2a-event.js +9 -0
- package/dist/a2a/a2a-event.js.map +1 -0
- package/dist/a2a/a2a-job.d.ts +58 -0
- package/dist/a2a/a2a-job.d.ts.map +1 -0
- package/dist/a2a/a2a-job.js +264 -0
- package/dist/a2a/a2a-job.js.map +1 -0
- package/dist/a2a/a2a-stream.d.ts +39 -0
- package/dist/a2a/a2a-stream.d.ts.map +1 -0
- package/dist/a2a/a2a-stream.js +290 -0
- package/dist/a2a/a2a-stream.js.map +1 -0
- package/dist/a2a/errors.d.ts +29 -0
- package/dist/a2a/errors.d.ts.map +1 -0
- package/dist/a2a/errors.js +48 -0
- package/dist/a2a/errors.js.map +1 -0
- package/dist/a2a/index.d.ts +12 -0
- package/dist/a2a/index.d.ts.map +1 -0
- package/dist/a2a/index.js +11 -0
- package/dist/a2a/index.js.map +1 -0
- package/dist/a2a/producer/auth-filter.d.ts +34 -0
- package/dist/a2a/producer/auth-filter.d.ts.map +1 -0
- package/dist/a2a/producer/auth-filter.js +39 -0
- package/dist/a2a/producer/auth-filter.js.map +1 -0
- package/dist/a2a/producer/card-builder.d.ts +59 -0
- package/dist/a2a/producer/card-builder.d.ts.map +1 -0
- package/dist/a2a/producer/card-builder.js +59 -0
- package/dist/a2a/producer/card-builder.js.map +1 -0
- package/dist/a2a/producer/dispatcher.d.ts +276 -0
- package/dist/a2a/producer/dispatcher.d.ts.map +1 -0
- package/dist/a2a/producer/dispatcher.js +896 -0
- package/dist/a2a/producer/dispatcher.js.map +1 -0
- package/dist/a2a/producer/index.d.ts +26 -0
- package/dist/a2a/producer/index.d.ts.map +1 -0
- package/dist/a2a/producer/index.js +23 -0
- package/dist/a2a/producer/index.js.map +1 -0
- package/dist/a2a/producer/mount.d.ts +75 -0
- package/dist/a2a/producer/mount.d.ts.map +1 -0
- package/dist/a2a/producer/mount.js +422 -0
- package/dist/a2a/producer/mount.js.map +1 -0
- package/dist/a2a/producer/public-url-cache.d.ts +73 -0
- package/dist/a2a/producer/public-url-cache.d.ts.map +1 -0
- package/dist/a2a/producer/public-url-cache.js +0 -0
- package/dist/a2a/producer/public-url-cache.js.map +1 -0
- package/dist/a2a/producer/registry.d.ts +138 -0
- package/dist/a2a/producer/registry.d.ts.map +1 -0
- package/dist/a2a/producer/registry.js +117 -0
- package/dist/a2a/producer/registry.js.map +1 -0
- package/dist/a2a/producer/sse-emitter.d.ts +85 -0
- package/dist/a2a/producer/sse-emitter.d.ts.map +1 -0
- package/dist/a2a/producer/sse-emitter.js +405 -0
- package/dist/a2a/producer/sse-emitter.js.map +1 -0
- package/dist/a2a/producer/state-translator.d.ts +63 -0
- package/dist/a2a/producer/state-translator.d.ts.map +1 -0
- package/dist/a2a/producer/state-translator.js +108 -0
- package/dist/a2a/producer/state-translator.js.map +1 -0
- package/dist/a2a/producer/task-store.d.ts +128 -0
- package/dist/a2a/producer/task-store.d.ts.map +1 -0
- package/dist/a2a/producer/task-store.js +128 -0
- package/dist/a2a/producer/task-store.js.map +1 -0
- package/dist/agent.d.ts +99 -0
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +754 -19
- package/dist/agent.js.map +1 -1
- package/dist/api-runtime.d.ts +25 -0
- package/dist/api-runtime.d.ts.map +1 -1
- package/dist/api-runtime.js +75 -2
- package/dist/api-runtime.js.map +1 -1
- package/dist/claim-dispatcher.d.ts +126 -0
- package/dist/claim-dispatcher.d.ts.map +1 -0
- package/dist/claim-dispatcher.js +478 -0
- package/dist/claim-dispatcher.js.map +1 -0
- package/dist/express.d.ts.map +1 -1
- package/dist/express.js +33 -6
- package/dist/express.js.map +1 -1
- package/dist/inbound-job-dispatch.d.ts +105 -0
- package/dist/inbound-job-dispatch.d.ts.map +1 -0
- package/dist/inbound-job-dispatch.js +335 -0
- package/dist/inbound-job-dispatch.js.map +1 -0
- package/dist/index.d.ts +40 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +40 -3
- package/dist/index.js.map +1 -1
- package/dist/job-context.d.ts +107 -0
- package/dist/job-context.d.ts.map +1 -0
- package/dist/job-context.js +95 -0
- package/dist/job-context.js.map +1 -0
- package/dist/jobs-cancel-route.d.ts +36 -0
- package/dist/jobs-cancel-route.d.ts.map +1 -0
- package/dist/jobs-cancel-route.js +60 -0
- package/dist/jobs-cancel-route.js.map +1 -0
- package/dist/jobs-helper-tools.d.ts +48 -0
- package/dist/jobs-helper-tools.d.ts.map +1 -0
- package/dist/jobs-helper-tools.js +133 -0
- package/dist/jobs-helper-tools.js.map +1 -0
- package/dist/llm-agent.d.ts +62 -53
- package/dist/llm-agent.d.ts.map +1 -1
- package/dist/llm-agent.js +211 -292
- package/dist/llm-agent.js.map +1 -1
- package/dist/llm-provider.d.ts +11 -4
- package/dist/llm-provider.d.ts.map +1 -1
- package/dist/llm-provider.js +57 -4
- package/dist/llm-provider.js.map +1 -1
- package/dist/llm.d.ts +4 -1
- package/dist/llm.d.ts.map +1 -1
- package/dist/llm.js +7 -17
- package/dist/llm.js.map +1 -1
- package/dist/media/resolver.d.ts.map +1 -1
- package/dist/media/resolver.js +3 -2
- package/dist/media/resolver.js.map +1 -1
- package/dist/mesh-job-submitter.d.ts +83 -0
- package/dist/mesh-job-submitter.d.ts.map +1 -0
- package/dist/mesh-job-submitter.js +143 -0
- package/dist/mesh-job-submitter.js.map +1 -0
- package/dist/provider-handlers/gemini-handler.js +5 -0
- package/dist/provider-handlers/gemini-handler.js.map +1 -1
- package/dist/proxy.d.ts +40 -0
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +375 -2
- package/dist/proxy.js.map +1 -1
- package/dist/resolver-meshjob.d.ts +170 -0
- package/dist/resolver-meshjob.d.ts.map +1 -0
- package/dist/resolver-meshjob.js +159 -0
- package/dist/resolver-meshjob.js.map +1 -0
- package/dist/route.d.ts +4 -0
- package/dist/route.d.ts.map +1 -1
- package/dist/route.js.map +1 -1
- package/dist/schema-normalize.d.ts +62 -0
- package/dist/schema-normalize.d.ts.map +1 -0
- package/dist/schema-normalize.js +128 -0
- package/dist/schema-normalize.js.map +1 -0
- package/dist/sse-stream.d.ts +44 -0
- package/dist/sse-stream.d.ts.map +1 -0
- package/dist/sse-stream.js +173 -0
- package/dist/sse-stream.js.map +1 -0
- package/dist/tool-worker-entry.d.ts +21 -0
- package/dist/tool-worker-entry.d.ts.map +1 -0
- package/dist/tool-worker-entry.js +162 -0
- package/dist/tool-worker-entry.js.map +1 -0
- package/dist/tool-worker-pool.d.ts +49 -0
- package/dist/tool-worker-pool.d.ts.map +1 -0
- package/dist/tool-worker-pool.js +272 -0
- package/dist/tool-worker-pool.js.map +1 -0
- package/dist/types.d.ts +351 -9
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -3
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSE streaming helper for Express route handlers.
|
|
3
|
+
*
|
|
4
|
+
* Pipes any ``AsyncIterable<string>`` to an Express ``Response`` as
|
|
5
|
+
* ``text/event-stream``. Designed to be called from inside a ``mesh.route``
|
|
6
|
+
* handler — for example, to forward chunks from a remote streaming tool to
|
|
7
|
+
* a browser client via SSE.
|
|
8
|
+
*
|
|
9
|
+
* Wire format mirrors the Python ``mesh.route`` SSE adapter:
|
|
10
|
+
* - ``data: <chunk>\n\n`` per item
|
|
11
|
+
* - ``data: [DONE]\n\n`` terminator on normal completion
|
|
12
|
+
* - ``event: error\ndata: <json>\n\n`` on per-chunk error
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import { mesh } from "@mcpmesh/sdk";
|
|
17
|
+
*
|
|
18
|
+
* app.post("/plan", mesh.route(["trip_planner"], async (req, res, { trip_planner }) => {
|
|
19
|
+
* if (!trip_planner) return res.status(503).end();
|
|
20
|
+
* await mesh.sseStream(res, trip_planner.stream(req.body));
|
|
21
|
+
* }));
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
const SSE_HEADERS = {
|
|
25
|
+
"Content-Type": "text/event-stream",
|
|
26
|
+
"Cache-Control": "no-cache",
|
|
27
|
+
Connection: "keep-alive",
|
|
28
|
+
// Disable nginx response buffering so chunks reach the browser immediately
|
|
29
|
+
"X-Accel-Buffering": "no",
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Format a single chunk as SSE ``data:`` lines per spec.
|
|
33
|
+
*
|
|
34
|
+
* Each newline in the chunk becomes its own ``data:`` line; the record is
|
|
35
|
+
* terminated by a blank line. Empty chunks still emit a single ``data:``
|
|
36
|
+
* line so consumers see a heartbeat-style event (matches Python behavior).
|
|
37
|
+
*/
|
|
38
|
+
function frameChunkAsSSE(chunk) {
|
|
39
|
+
// splitlines() in Python splits on any line boundary; in JS we normalize
|
|
40
|
+
// CRLF to LF first then split on \n. An empty chunk still emits one frame.
|
|
41
|
+
const normalized = chunk.replace(/\r\n/g, "\n");
|
|
42
|
+
const lines = normalized === "" ? [""] : normalized.split("\n");
|
|
43
|
+
return lines.map((l) => `data: ${l}\n`).join("") + "\n";
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Pipe an ``AsyncIterable<string>`` to an Express ``Response`` as SSE.
|
|
47
|
+
*
|
|
48
|
+
* Sets the standard SSE headers, writes one ``data: <chunk>\n\n`` frame per
|
|
49
|
+
* item from the iterable, and terminates with ``data: [DONE]\n\n``. On
|
|
50
|
+
* per-chunk error (e.g. the upstream stream throws), writes
|
|
51
|
+
* ``event: error\ndata: <json>\n\n`` and ends the response.
|
|
52
|
+
*
|
|
53
|
+
* Resolves when the response has been fully written. Callers do not need to
|
|
54
|
+
* call ``res.end()`` themselves.
|
|
55
|
+
*
|
|
56
|
+
* If the consumer disconnects mid-stream (``res.writableEnded``), iteration
|
|
57
|
+
* stops cleanly via the iterable's ``return()`` method (so the upstream
|
|
58
|
+
* proxy stream's ``finally`` block can release its underlying reader).
|
|
59
|
+
*
|
|
60
|
+
* @param res - Express response object
|
|
61
|
+
* @param source - Async iterable yielding strings
|
|
62
|
+
*/
|
|
63
|
+
export async function sseStream(res, source) {
|
|
64
|
+
// Set headers if not already sent. Use writeHead for a single atomic flush
|
|
65
|
+
// so the browser sees the full set immediately (some proxies buffer until
|
|
66
|
+
// headers arrive). If the caller already wrote headers we just continue.
|
|
67
|
+
if (!res.headersSent) {
|
|
68
|
+
for (const [k, v] of Object.entries(SSE_HEADERS)) {
|
|
69
|
+
res.setHeader(k, v);
|
|
70
|
+
}
|
|
71
|
+
// Some Express versions need an explicit flushHeaders() to commit before
|
|
72
|
+
// the first data frame; call it if available.
|
|
73
|
+
if (typeof res.flushHeaders === "function") {
|
|
74
|
+
res.flushHeaders();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Track whether end() has been called so we never double-end (which would
|
|
78
|
+
// throw "ERR_STREAM_WRITE_AFTER_END" on Node). ``writable`` flips to false
|
|
79
|
+
// when further writes will fail (e.g. socket closed) but we still want to
|
|
80
|
+
// call res.end() exactly once for cleanup.
|
|
81
|
+
let endCalled = false;
|
|
82
|
+
let writable = true;
|
|
83
|
+
const safeEnd = () => {
|
|
84
|
+
if (endCalled)
|
|
85
|
+
return;
|
|
86
|
+
endCalled = true;
|
|
87
|
+
try {
|
|
88
|
+
res.end();
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
// ignore — response may already be torn down
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
const safeWrite = (data) => {
|
|
95
|
+
if (!writable)
|
|
96
|
+
return false;
|
|
97
|
+
if (res.writableEnded || res.destroyed) {
|
|
98
|
+
writable = false;
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
try {
|
|
102
|
+
return res.write(data);
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
writable = false;
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
110
|
+
try {
|
|
111
|
+
while (true) {
|
|
112
|
+
const { value, done } = await iterator.next();
|
|
113
|
+
if (done)
|
|
114
|
+
break;
|
|
115
|
+
if (typeof value !== "string") {
|
|
116
|
+
// v1 supports str only — surface a structured error and stop
|
|
117
|
+
const errPayload = JSON.stringify({
|
|
118
|
+
error: `sseStream: expected string chunk, got ${typeof value}`,
|
|
119
|
+
type: "TypeError",
|
|
120
|
+
});
|
|
121
|
+
safeWrite(`event: error\ndata: ${errPayload}\n\n`);
|
|
122
|
+
safeEnd();
|
|
123
|
+
// best-effort cleanup of upstream
|
|
124
|
+
if (typeof iterator.return === "function") {
|
|
125
|
+
try {
|
|
126
|
+
await iterator.return();
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
// ignore
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const wroteOk = safeWrite(frameChunkAsSSE(value));
|
|
135
|
+
if (!wroteOk) {
|
|
136
|
+
// Consumer disconnected (or write threw) — clean up upstream and end.
|
|
137
|
+
if (typeof iterator.return === "function") {
|
|
138
|
+
try {
|
|
139
|
+
await iterator.return();
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
// ignore
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
safeEnd();
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
safeWrite("data: [DONE]\n\n");
|
|
150
|
+
safeEnd();
|
|
151
|
+
}
|
|
152
|
+
catch (err) {
|
|
153
|
+
const errPayload = JSON.stringify({
|
|
154
|
+
error: err instanceof Error ? err.message : String(err),
|
|
155
|
+
type: err instanceof Error ? err.constructor.name : "Error",
|
|
156
|
+
});
|
|
157
|
+
safeWrite(`event: error\ndata: ${errPayload}\n\n`);
|
|
158
|
+
safeEnd();
|
|
159
|
+
// Release the upstream iterator if the failure originated outside the
|
|
160
|
+
// iterator itself (e.g. safeWrite threw). Without this, an upstream
|
|
161
|
+
// proxy.stream() generator's finally block — which cancels the
|
|
162
|
+
// OkHttp/fetch reader — never runs until GC, leaking the connection.
|
|
163
|
+
if (typeof iterator.return === "function") {
|
|
164
|
+
try {
|
|
165
|
+
await iterator.return();
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
/* upstream cleanup is best-effort */
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=sse-stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse-stream.js","sourceRoot":"","sources":["../src/sse-stream.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker entry for the mesh tool worker pool.
|
|
3
|
+
*
|
|
4
|
+
* Launched as a `worker_threads.Worker` from `tool-worker-pool.ts`. Each
|
|
5
|
+
* worker:
|
|
6
|
+
*
|
|
7
|
+
* 1. Resolves the user's `tsx` loader from THEIR node_modules (the Worker
|
|
8
|
+
* `execArgv` does not propagate the parent process's tsx loader, so .ts
|
|
9
|
+
* imports would otherwise throw `ERR_UNKNOWN_FILE_EXTENSION`).
|
|
10
|
+
* 2. Sets a worker-mode symbol on `globalThis` so the SDK skips main-thread
|
|
11
|
+
* init (HTTP server, registry heartbeat, Rust core agent start) when the
|
|
12
|
+
* user module imports `mesh()`.
|
|
13
|
+
* 3. Dynamic-imports the user module — this triggers `agent.addTool(...)` calls
|
|
14
|
+
* which the SDK redirects into a worker-local tool map.
|
|
15
|
+
* 4. Reports `ready` to the parent.
|
|
16
|
+
* 5. Listens for `{kind: "call"}` messages, executes the tool with
|
|
17
|
+
* reconstructed DI proxies + restored ALS scope, and replies with
|
|
18
|
+
* `{kind: "result"}` or `{kind: "error"}`.
|
|
19
|
+
*/
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=tool-worker-entry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-worker-entry.d.ts","sourceRoot":"","sources":["../src/tool-worker-entry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker entry for the mesh tool worker pool.
|
|
3
|
+
*
|
|
4
|
+
* Launched as a `worker_threads.Worker` from `tool-worker-pool.ts`. Each
|
|
5
|
+
* worker:
|
|
6
|
+
*
|
|
7
|
+
* 1. Resolves the user's `tsx` loader from THEIR node_modules (the Worker
|
|
8
|
+
* `execArgv` does not propagate the parent process's tsx loader, so .ts
|
|
9
|
+
* imports would otherwise throw `ERR_UNKNOWN_FILE_EXTENSION`).
|
|
10
|
+
* 2. Sets a worker-mode symbol on `globalThis` so the SDK skips main-thread
|
|
11
|
+
* init (HTTP server, registry heartbeat, Rust core agent start) when the
|
|
12
|
+
* user module imports `mesh()`.
|
|
13
|
+
* 3. Dynamic-imports the user module — this triggers `agent.addTool(...)` calls
|
|
14
|
+
* which the SDK redirects into a worker-local tool map.
|
|
15
|
+
* 4. Reports `ready` to the parent.
|
|
16
|
+
* 5. Listens for `{kind: "call"}` messages, executes the tool with
|
|
17
|
+
* reconstructed DI proxies + restored ALS scope, and replies with
|
|
18
|
+
* `{kind: "result"}` or `{kind: "error"}`.
|
|
19
|
+
*/
|
|
20
|
+
import { parentPort, workerData, isMainThread } from "node:worker_threads";
|
|
21
|
+
import { createRequire } from "node:module";
|
|
22
|
+
import { pathToFileURL } from "node:url";
|
|
23
|
+
if (isMainThread) {
|
|
24
|
+
throw new Error("tool-worker-entry.js must be loaded inside a worker thread");
|
|
25
|
+
}
|
|
26
|
+
if (!parentPort) {
|
|
27
|
+
throw new Error("tool-worker-entry.js requires a parent port");
|
|
28
|
+
}
|
|
29
|
+
const data = workerData;
|
|
30
|
+
const userModulePath = data.userModulePath;
|
|
31
|
+
const sdkEntryPath = data.sdkEntryPath;
|
|
32
|
+
// Mark worker mode BEFORE importing the user module. The SDK checks this
|
|
33
|
+
// symbol in MeshAgent.constructor / addTool to short-circuit main-thread
|
|
34
|
+
// init and stash tool functions in a worker-local map instead.
|
|
35
|
+
const WORKER_MODE_SYMBOL = Symbol.for("@mcpmesh/sdk/worker-mode");
|
|
36
|
+
globalThis[WORKER_MODE_SYMBOL] = true;
|
|
37
|
+
// User-facing in-worker flag. Distinct from the SDK-internal worker-mode flag
|
|
38
|
+
// above. User code can check this to guard their own top-level side effects
|
|
39
|
+
// (custom HTTP servers, OTel init, prometheus registries) that should not
|
|
40
|
+
// run in worker threads. Exported as IN_WORKER_SYMBOL from the SDK index.
|
|
41
|
+
globalThis[Symbol.for("@mcpmesh/sdk/in-worker")] = true;
|
|
42
|
+
async function bootstrap() {
|
|
43
|
+
// 1. Register tsx loader for the worker if user runs .ts directly.
|
|
44
|
+
const isTs = userModulePath.endsWith(".ts") ||
|
|
45
|
+
userModulePath.endsWith(".mts") ||
|
|
46
|
+
userModulePath.endsWith(".cts") ||
|
|
47
|
+
userModulePath.endsWith(".tsx");
|
|
48
|
+
if (isTs) {
|
|
49
|
+
try {
|
|
50
|
+
const userRequire = createRequire(userModulePath);
|
|
51
|
+
const tsxApiPath = userRequire.resolve("tsx/esm/api");
|
|
52
|
+
const tsxApi = await import(pathToFileURL(tsxApiPath).href);
|
|
53
|
+
if (typeof tsxApi.register === "function") {
|
|
54
|
+
tsxApi.register();
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
throw new Error("tsx/esm/api does not export register()");
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
const msg = "MCP_MESH_TOOL_ISOLATION requires `tsx` in your dependencies when " +
|
|
62
|
+
"running .ts directly. Add `tsx` to package.json or set " +
|
|
63
|
+
"MCP_MESH_TOOL_ISOLATION=false to disable isolation.";
|
|
64
|
+
parentPort.postMessage({
|
|
65
|
+
kind: "fatal",
|
|
66
|
+
error: {
|
|
67
|
+
name: "TsxResolutionError",
|
|
68
|
+
message: msg,
|
|
69
|
+
cause: String(e),
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
process.exit(1);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// 2. Import the SDK first so the worker-mode flag takes effect before the
|
|
77
|
+
// user's import of mesh() touches MeshAgent.constructor.
|
|
78
|
+
const sdk = await import(pathToFileURL(sdkEntryPath).href);
|
|
79
|
+
// 3. Import the user's module — fires addTool() calls.
|
|
80
|
+
await import(pathToFileURL(userModulePath).href);
|
|
81
|
+
// 4. Pull the tool map populated during user module init.
|
|
82
|
+
const tools = typeof sdk.__getWorkerToolMap === "function"
|
|
83
|
+
? sdk.__getWorkerToolMap()
|
|
84
|
+
: new Map();
|
|
85
|
+
// 5. Get ALS helpers + proxy factory for per-call setup.
|
|
86
|
+
const { createProxy, runWithTraceContext, runWithPropagatedHeaders } = sdk;
|
|
87
|
+
parentPort.on("message", (msg) => {
|
|
88
|
+
handleMessage(msg, tools, createProxy, runWithTraceContext, runWithPropagatedHeaders);
|
|
89
|
+
});
|
|
90
|
+
parentPort.postMessage({ kind: "ready" });
|
|
91
|
+
}
|
|
92
|
+
function serializeError(err) {
|
|
93
|
+
if (!(err instanceof Error)) {
|
|
94
|
+
return { name: "Error", message: String(err) };
|
|
95
|
+
}
|
|
96
|
+
const out = { name: err.name, message: err.message, stack: err.stack };
|
|
97
|
+
const errAny = err;
|
|
98
|
+
if (errAny.code !== undefined)
|
|
99
|
+
out.code = errAny.code;
|
|
100
|
+
if (errAny.cause !== undefined)
|
|
101
|
+
out.cause = serializeError(errAny.cause);
|
|
102
|
+
return out;
|
|
103
|
+
}
|
|
104
|
+
function handleMessage(msg, tools, createProxy, runWithTraceContext, runWithPropagatedHeaders) {
|
|
105
|
+
if (!msg || typeof msg !== "object")
|
|
106
|
+
return;
|
|
107
|
+
const m = msg;
|
|
108
|
+
if (m.kind !== "call" || typeof m.id !== "number")
|
|
109
|
+
return;
|
|
110
|
+
const respond = (payload) => {
|
|
111
|
+
parentPort.postMessage({ id: m.id, ...payload });
|
|
112
|
+
};
|
|
113
|
+
const tool = tools.get(m.toolName);
|
|
114
|
+
if (!tool) {
|
|
115
|
+
respond({
|
|
116
|
+
kind: "error",
|
|
117
|
+
error: {
|
|
118
|
+
name: "ToolNotFound",
|
|
119
|
+
message: `Tool '${m.toolName}' not registered in worker`,
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
// Reconstruct DI proxies — workers can't share the main-thread proxies, so
|
|
125
|
+
// each worker builds its own with its own undici Agent (Python parity).
|
|
126
|
+
const deps = m.depsConfig.map((cfg) => cfg === null
|
|
127
|
+
? null
|
|
128
|
+
: createProxy(cfg.endpoint, cfg.capability, cfg.functionName, cfg.kwargs));
|
|
129
|
+
// Restore ALS scopes so user code sees the same trace context + headers as
|
|
130
|
+
// the main-thread caller, then invoke the tool. When traceContext is null,
|
|
131
|
+
// skip runWithTraceContext entirely so user's getCurrentTraceContext()
|
|
132
|
+
// returns null — matching the MCP_MESH_TOOL_ISOLATION=false legacy path.
|
|
133
|
+
const headers = m.propagatedHeaders ?? {};
|
|
134
|
+
const invokeUser = () => runWithPropagatedHeaders(headers, () => tool(m.cleanArgs, ...deps));
|
|
135
|
+
const wrapWithTrace = () => m.traceContext === null
|
|
136
|
+
? invokeUser()
|
|
137
|
+
: runWithTraceContext(m.traceContext, invokeUser);
|
|
138
|
+
Promise.resolve()
|
|
139
|
+
.then(wrapWithTrace)
|
|
140
|
+
.then((value) => respond({ kind: "result", value }))
|
|
141
|
+
.catch((err) => {
|
|
142
|
+
respond({ kind: "error", error: serializeError(err) });
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
bootstrap().catch((e) => {
|
|
146
|
+
const err = e;
|
|
147
|
+
try {
|
|
148
|
+
parentPort.postMessage({
|
|
149
|
+
kind: "fatal",
|
|
150
|
+
error: {
|
|
151
|
+
name: err?.name ?? "Error",
|
|
152
|
+
message: err?.message ?? String(e),
|
|
153
|
+
stack: err?.stack,
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
// ignore
|
|
159
|
+
}
|
|
160
|
+
process.exit(1);
|
|
161
|
+
});
|
|
162
|
+
//# sourceMappingURL=tool-worker-entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-worker-entry.js","sourceRoot":"","sources":["../src/tool-worker-entry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool worker pool for isolating user tool execution from the main event loop.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the Python `_mcp_mesh.shared.tool_executor` design: spawn N worker
|
|
5
|
+
* threads (V8 isolates here, since Node has no GIL/asyncio split), each with
|
|
6
|
+
* its own event loop and undici connection pool, and dispatch tool calls
|
|
7
|
+
* round-robin across them. A user's blocking call (`execFileSync`, CPU spin,
|
|
8
|
+
* etc.) blocks one worker thread, NOT the main thread that serves
|
|
9
|
+
* /health, /ready, FastMCP HTTP, and registry heartbeats.
|
|
10
|
+
*
|
|
11
|
+
* Pool size:
|
|
12
|
+
* Default `min(8, max(2, os.availableParallelism() ?? 2))`.
|
|
13
|
+
* Override via `MCP_MESH_TOOL_WORKERS=<N>`.
|
|
14
|
+
*
|
|
15
|
+
* The pool is created lazily on first dispatch (matches Python parity) and
|
|
16
|
+
* cached for the process lifetime. Workers that crash are respawned on the
|
|
17
|
+
* next dispatch.
|
|
18
|
+
*/
|
|
19
|
+
export interface DepConfig {
|
|
20
|
+
endpoint: string;
|
|
21
|
+
capability: string;
|
|
22
|
+
functionName: string;
|
|
23
|
+
kwargs: Record<string, unknown>;
|
|
24
|
+
}
|
|
25
|
+
export interface DispatchPayload {
|
|
26
|
+
toolName: string;
|
|
27
|
+
cleanArgs: unknown;
|
|
28
|
+
depsConfig: (DepConfig | null)[];
|
|
29
|
+
traceContext: unknown;
|
|
30
|
+
propagatedHeaders: Record<string, string>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Dispatch a tool call to a worker.
|
|
34
|
+
*
|
|
35
|
+
* Round-robin selects a worker, awaits its readiness (first call only),
|
|
36
|
+
* sends the payload, and resolves with the worker's `{result}` or rejects
|
|
37
|
+
* with its `{error}`. Worker crashes propagate as a rejection.
|
|
38
|
+
*/
|
|
39
|
+
export declare function dispatch(payload: DispatchPayload): Promise<unknown>;
|
|
40
|
+
/**
|
|
41
|
+
* Drain in-flight calls (up to deadlineMs), then forcefully terminate all
|
|
42
|
+
* workers. Calls still pending after the deadline are rejected with a
|
|
43
|
+
* descriptive error.
|
|
44
|
+
*
|
|
45
|
+
* Called automatically on `process.exit`; can be invoked explicitly during
|
|
46
|
+
* shutdown if you want to await completion.
|
|
47
|
+
*/
|
|
48
|
+
export declare function closePool(deadlineMs?: number): Promise<void>;
|
|
49
|
+
//# sourceMappingURL=tool-worker-pool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-worker-pool.d.ts","sourceRoot":"","sources":["../src/tool-worker-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAQH,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,CAAC,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC;IACjC,YAAY,EAAE,OAAO,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C;AA4MD;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAiCzE;AAED;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAAC,UAAU,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BhE"}
|