@sema-agent/core 7.5.2 → 7.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/CHANGELOG.md +41 -0
- package/dist/agents/cascade.d.ts +2 -2
- package/dist/agents/cascade.js +12 -10
- package/dist/agents/repair-loop.d.ts +5 -3
- package/dist/agents/repair-loop.js +13 -15
- package/dist/agents/subagent.d.ts +24 -42
- package/dist/agents/subagent.js +119 -105
- package/dist/agents/suspend-guard.d.ts +31 -19
- package/dist/agents/suspend-guard.js +14 -8
- package/dist/agents/teacher.js +9 -9
- package/dist/agents/team.d.ts +4 -3
- package/dist/agents/team.js +10 -8
- package/dist/agents/verify.d.ts +3 -3
- package/dist/agents/verify.js +17 -17
- package/dist/core/a2a.js +2 -1
- package/dist/core/ask-origin.d.ts +60 -7
- package/dist/core/ask-origin.js +26 -1
- package/dist/core/checkpoint-store.d.ts +78 -76
- package/dist/core/checkpoint-store.js +17 -1
- package/dist/core/gate-outcome.d.ts +189 -0
- package/dist/core/gate-outcome.js +70 -0
- package/dist/core/hooks.d.ts +18 -92
- package/dist/core/hooks.js +88 -85
- package/dist/core/mcp-failure.d.ts +104 -0
- package/dist/core/mcp-failure.js +128 -0
- package/dist/core/mcp.d.ts +21 -77
- package/dist/core/mcp.js +76 -150
- package/dist/core/pause-registry.d.ts +131 -0
- package/dist/core/pause-registry.js +27 -0
- package/dist/core/runner/assemble-result.d.ts +32 -41
- package/dist/core/runner/assemble-result.js +55 -74
- package/dist/core/runner/contracts.d.ts +46 -64
- package/dist/core/runner/denial-limit-arms.d.ts +1 -1
- package/dist/core/runner/denial-limit-arms.js +3 -3
- package/dist/core/runner/gate-exit.d.ts +74 -0
- package/dist/core/runner/gate-exit.js +55 -0
- package/dist/core/runner/park-commit.d.ts +17 -23
- package/dist/core/runner/park-commit.js +14 -15
- package/dist/core/runner/prepare-ask-lane.d.ts +0 -3
- package/dist/core/runner/prepare-ask-lane.js +3 -5
- package/dist/core/runner/prepare-boundary-parks.d.ts +3 -6
- package/dist/core/runner/prepare-boundary-parks.js +3 -3
- package/dist/core/runner/prepare-caps-and-workflow.js +1 -1
- package/dist/core/runner/prepare-gate-stations.d.ts +4 -7
- package/dist/core/runner/prepare-gate-stations.js +29 -54
- package/dist/core/runner/prepare-inherited-gate.js +1 -1
- package/dist/core/runner/prepare-memory.d.ts +44 -26
- package/dist/core/runner/prepare-park-ask.d.ts +2 -4
- package/dist/core/runner/prepare-park-ask.js +5 -5
- package/dist/core/runner/prepare-task.js +8 -9
- package/dist/core/runner/prepare-wiring-manifest.d.ts +7 -15
- package/dist/core/runner/prepare-wiring-manifest.js +9 -10
- package/dist/core/runner/runtask.d.ts +16 -31
- package/dist/core/runner/runtask.js +109 -120
- package/dist/core/runner/terminal-projection.d.ts +22 -0
- package/dist/core/runner/terminal-projection.js +28 -0
- package/dist/core/store-contracts/checkpoint-store-contract.d.ts +4 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +8 -2
- package/dist/core/terminal-cause.d.ts +137 -0
- package/dist/core/terminal-cause.js +9 -0
- package/dist/core/tool-policy.d.ts +43 -139
- package/dist/core/tool-policy.js +79 -112
- package/dist/core/types.d.ts +67 -164
- package/dist/core/wiring-manifest.d.ts +6 -3
- package/dist/core/workflow-journal-store.js +3 -4
- package/dist/engine/harness/agent-harness.d.ts +1 -1
- package/dist/index.d.ts +10 -7
- package/dist/index.js +8 -5
- package/dist/orchestration/builtin-workflows.d.ts +2 -2
- package/dist/orchestration/builtin-workflows.js +1 -1
- package/dist/orchestration/goal.js +8 -7
- package/dist/orchestration/run-spec.js +5 -3
- package/dist/orchestration/run-workflow-tool.d.ts +1 -1
- package/dist/orchestration/run-workflow-tool.js +4 -4
- package/dist/orchestration/workflow-governance.d.ts +4 -4
- package/dist/orchestration/workflow-governance.js +4 -2
- package/dist/orchestration/workflow-primitives.d.ts +1 -1
- package/dist/orchestration/workflow-primitives.js +1 -1
- package/dist/orchestration/workflow.d.ts +11 -0
- package/dist/orchestration/workflow.js +64 -39
- package/dist/prompts/supervisor.d.ts +1 -1
- package/dist/prompts/supervisor.js +3 -3
- package/dist/scenarios/scenario-registry.js +1 -1
- package/package.json +3 -1
- package/test/export-surface.snapshot.json +74 -22
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The closed set of failure classes ({@link McpFailure.kind}):
|
|
3
|
+
* · `connect_refused` — a connect-phase errno (ECONNREFUSED / ENOTFOUND / EAI_AGAIN / EHOSTUNREACH /
|
|
4
|
+
* ENETUNREACH / UND_ERR_CONNECT_TIMEOUT): the request provably never left;
|
|
5
|
+
* · `connection_failed` — any other errno / undici code on the cause chain (a reset or a timeout
|
|
6
|
+
* mid-exchange): the request may have run;
|
|
7
|
+
* · `connection_closed` — the SDK reported the transport closed (`McpError` `ConnectionClosed`): in
|
|
8
|
+
* flight the fate is unknowable, and for a server already known dead the
|
|
9
|
+
* request was never attempted — the two are told apart by `delivered`;
|
|
10
|
+
* · `http_status` — the HTTP endpoint answered with a status instead of an MCP response
|
|
11
|
+
* (`httpStatus` carries the number: 401/403 = re-authorize, 5xx = down);
|
|
12
|
+
* · `not_mcp_response` — the HTTP endpoint answered something that is not an MCP payload and no status;
|
|
13
|
+
* · `spawn_failed` — a stdio server process could not be started (a missing/unexecutable command);
|
|
14
|
+
* · `timeout` — the request timed out (the SDK's per-call timer, the total ceiling, or the
|
|
15
|
+
* idle watchdog — `details` names which);
|
|
16
|
+
* · `protocol` — the server ANSWERED with an MCP/JSON-RPC error (a version mismatch, a rejected
|
|
17
|
+
* capability, an ordinary `-32603`): the exchange happened;
|
|
18
|
+
* · `invalid_config` — the declaration itself could not be dialed (a malformed `url`): a fault to
|
|
19
|
+
* fix in the spec, never an outage to wait out;
|
|
20
|
+
* · `unknown` — the thrown value carried no structure this table reads.
|
|
21
|
+
*/
|
|
22
|
+
export declare const MCP_FAILURE_KINDS: readonly ["connect_refused", "connection_failed", "connection_closed", "http_status", "not_mcp_response", "spawn_failed", "timeout", "protocol", "invalid_config", "unknown"];
|
|
23
|
+
export type McpFailureKind = (typeof MCP_FAILURE_KINDS)[number];
|
|
24
|
+
/** The closed set of delivery verdicts ({@link McpFailure.delivered}). */
|
|
25
|
+
export declare const MCP_DELIVERY_VERDICTS: readonly ["yes", "no", "unknown"];
|
|
26
|
+
export type McpDelivered = (typeof MCP_DELIVERY_VERDICTS)[number];
|
|
27
|
+
/** Where the failure was judged: at the dial (connect + initial listing), where an errno on a stdio
|
|
28
|
+
* transport is the child process failing to spawn, or on a request over an established connection. */
|
|
29
|
+
export type McpFailureSite = {
|
|
30
|
+
phase: "connect";
|
|
31
|
+
transport: "stdio" | "http" | undefined;
|
|
32
|
+
} | {
|
|
33
|
+
phase: "request";
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* The one MCP failure record. Both fields are always present; `httpStatus` rides only with
|
|
37
|
+
* `kind === "http_status"`.
|
|
38
|
+
*/
|
|
39
|
+
export interface McpFailure {
|
|
40
|
+
/**
|
|
41
|
+
* @contract mcp.failure.kind — the failure's CLASS, one of {@link MCP_FAILURE_KINDS}, decided by
|
|
42
|
+
* {@link classifyMcpFailure} from the thrown value's structure alone (never from its message). It is
|
|
43
|
+
* the SAME word on every face: the per-server status's and the wiring manifest's `errorCode`, the
|
|
44
|
+
* thrown request error's `details.code`, and the `tool_end` frame's `errorCode`. Closed: a consumer
|
|
45
|
+
* switching on it is complete; a new class is a new word for consumers, never a re-meaning of one.
|
|
46
|
+
*/
|
|
47
|
+
kind: McpFailureKind;
|
|
48
|
+
/**
|
|
49
|
+
* @contract mcp.failure.delivered — whether the request REACHED the server, as a first-class fact
|
|
50
|
+
* beside the class: `"yes"` = the server answered (a `protocol` rejection proves the exchange
|
|
51
|
+
* happened); `"no"` = provably never sent (a connect-phase errno, a spawn failure, a malformed
|
|
52
|
+
* declaration, a server already known dead — safe to retry or abandon, nothing executed); `"unknown"`
|
|
53
|
+
* = the client stopped waiting or lost the pipe mid-exchange (a timeout, an in-flight close, a reset,
|
|
54
|
+
* an HTTP status from a gateway in front of the server) — the request MAY have executed, so a
|
|
55
|
+
* write-capable tool's side effects must be verified before a retry. Two failures with the same
|
|
56
|
+
* `kind` can differ here (`connection_closed` in flight vs. against a dead server), which is why the
|
|
57
|
+
* verdict is its own field and not folded into the class.
|
|
58
|
+
*/
|
|
59
|
+
delivered: McpDelivered;
|
|
60
|
+
/** The HTTP status the endpoint answered with; present iff `kind === "http_status"`. */
|
|
61
|
+
httpStatus?: number;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The first errno-shaped / undici-shaped `code` on an error's cause chain (`E[A-Z_]+`, `UND_ERR_*`,
|
|
65
|
+
* Node's `ERR_*`). `fetch` reports every network failure as a bare `TypeError: fetch failed` with the
|
|
66
|
+
* real cause nested underneath (and an AggregateError when a host resolved to several addresses), so
|
|
67
|
+
* the code is never on the thrown error itself. The E-prefixed alternative allows `_`: Node's
|
|
68
|
+
* DNS-temporary-failure errno is literally `EAI_AGAIN`.
|
|
69
|
+
*/
|
|
70
|
+
export declare function networkErrorCode(err: unknown, depth?: number): string | undefined;
|
|
71
|
+
/** One row of the classifier: `when` reads structure only; `failure` mints the record. */
|
|
72
|
+
export interface McpFailureRule {
|
|
73
|
+
/** The row's name, for the discrimination pins (one pin per row) and for a reader of a verdict. */
|
|
74
|
+
readonly name: string;
|
|
75
|
+
readonly when: (err: unknown, at: McpFailureSite) => boolean;
|
|
76
|
+
readonly failure: (err: unknown, at: McpFailureSite) => McpFailure;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The ORDERED classifier. First match wins; the final row matches everything. The order is part of
|
|
80
|
+
* the contract — the SDK's typed errors go first because they are an answer FROM the exchange (an
|
|
81
|
+
* McpError is never a transport failure, whatever its text says), then the HTTP transport's typed
|
|
82
|
+
* error, then the cause-chain codes from most specific (a configuration fault, a spawn) to least
|
|
83
|
+
* (a connect-phase errno, any other network code).
|
|
84
|
+
*/
|
|
85
|
+
export declare const FAILURE_CLASSIFIER: ReadonlyArray<McpFailureRule>;
|
|
86
|
+
/**
|
|
87
|
+
* Classify one MCP failure into {@link McpFailure} by the first matching row of
|
|
88
|
+
* {@link FAILURE_CLASSIFIER}. Total: every input maps to a record.
|
|
89
|
+
*/
|
|
90
|
+
export declare function classifyMcpFailure(err: unknown, at: McpFailureSite): McpFailure;
|
|
91
|
+
/**
|
|
92
|
+
* What a transport-level HTTP failure can be said to be, in words for a model-facing line: the
|
|
93
|
+
* condition to name, and the delivery verdict. `undefined` for every failure that is NOT of the HTTP
|
|
94
|
+
* transport family (an McpError is an answer FROM the server; a bare error with no structure is
|
|
95
|
+
* `unknown` and gets no transport story). Shared with the A2A client leg, which faces the SAME `fetch`
|
|
96
|
+
* layer and owes the same outcome contract — one classifier, so the two protocols cannot drift on what
|
|
97
|
+
* "the request never reached them" means.
|
|
98
|
+
*/
|
|
99
|
+
export interface HttpTransportFailure {
|
|
100
|
+
condition: string;
|
|
101
|
+
delivered: McpDelivered;
|
|
102
|
+
httpStatus?: number;
|
|
103
|
+
}
|
|
104
|
+
export declare function describeHttpTransportFailure(err: unknown): HttpTransportFailure | undefined;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
import { StreamableHTTPError } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
3
|
+
export const MCP_FAILURE_KINDS = [
|
|
4
|
+
"connect_refused",
|
|
5
|
+
"connection_failed",
|
|
6
|
+
"connection_closed",
|
|
7
|
+
"http_status",
|
|
8
|
+
"not_mcp_response",
|
|
9
|
+
"spawn_failed",
|
|
10
|
+
"timeout",
|
|
11
|
+
"protocol",
|
|
12
|
+
"invalid_config",
|
|
13
|
+
"unknown",
|
|
14
|
+
];
|
|
15
|
+
export const MCP_DELIVERY_VERDICTS = ["yes", "no", "unknown"];
|
|
16
|
+
const NETWORK_CODES_NEVER_DELIVERED = new Set([
|
|
17
|
+
"ECONNREFUSED",
|
|
18
|
+
"ENOTFOUND",
|
|
19
|
+
"EAI_AGAIN",
|
|
20
|
+
"EHOSTUNREACH",
|
|
21
|
+
"ENETUNREACH",
|
|
22
|
+
"UND_ERR_CONNECT_TIMEOUT",
|
|
23
|
+
]);
|
|
24
|
+
export function networkErrorCode(err, depth = 0) {
|
|
25
|
+
if (depth > 5 || !(err instanceof Error))
|
|
26
|
+
return undefined;
|
|
27
|
+
const code = err.code;
|
|
28
|
+
if (typeof code === "string" && /^(?:E[A-Z_]+|UND_ERR_[A-Z_]+)$/.test(code))
|
|
29
|
+
return code;
|
|
30
|
+
if (err instanceof AggregateError) {
|
|
31
|
+
for (const inner of err.errors) {
|
|
32
|
+
const found = networkErrorCode(inner, depth + 1);
|
|
33
|
+
if (found !== undefined)
|
|
34
|
+
return found;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return networkErrorCode(err.cause, depth + 1);
|
|
38
|
+
}
|
|
39
|
+
const isNodeErrCode = (code) => code.startsWith("ERR_");
|
|
40
|
+
export const FAILURE_CLASSIFIER = [
|
|
41
|
+
{
|
|
42
|
+
name: "sdk connection closed",
|
|
43
|
+
when: (err) => err instanceof McpError && err.code === ErrorCode.ConnectionClosed,
|
|
44
|
+
failure: () => ({ kind: "connection_closed", delivered: "unknown" }),
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: "sdk request timeout",
|
|
48
|
+
when: (err) => err instanceof McpError && err.code === ErrorCode.RequestTimeout,
|
|
49
|
+
failure: () => ({ kind: "timeout", delivered: "unknown" }),
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: "server answered with a protocol error",
|
|
53
|
+
when: (err) => err instanceof McpError,
|
|
54
|
+
failure: () => ({ kind: "protocol", delivered: "yes" }),
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: "http endpoint answered a status",
|
|
58
|
+
when: (err) => err instanceof StreamableHTTPError && typeof err.code === "number" && err.code > 0,
|
|
59
|
+
failure: (err) => ({ kind: "http_status", delivered: "unknown", httpStatus: err.code }),
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: "http endpoint answered a non-mcp payload",
|
|
63
|
+
when: (err) => err instanceof StreamableHTTPError,
|
|
64
|
+
failure: () => ({ kind: "not_mcp_response", delivered: "unknown" }),
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: "malformed declaration",
|
|
68
|
+
when: (err, at) => at.phase === "connect" && err instanceof Error && err.code === "ERR_INVALID_URL",
|
|
69
|
+
failure: () => ({ kind: "invalid_config", delivered: "no" }),
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: "node error code, not a network errno",
|
|
73
|
+
when: (err) => {
|
|
74
|
+
const code = networkErrorCode(err);
|
|
75
|
+
return code !== undefined && isNodeErrCode(code);
|
|
76
|
+
},
|
|
77
|
+
failure: () => ({ kind: "unknown", delivered: "unknown" }),
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: "stdio spawn failed",
|
|
81
|
+
when: (err, at) => at.phase === "connect" && at.transport === "stdio" && networkErrorCode(err) !== undefined,
|
|
82
|
+
failure: () => ({ kind: "spawn_failed", delivered: "no" }),
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: "connect-phase errno",
|
|
86
|
+
when: (err) => {
|
|
87
|
+
const code = networkErrorCode(err);
|
|
88
|
+
return code !== undefined && NETWORK_CODES_NEVER_DELIVERED.has(code);
|
|
89
|
+
},
|
|
90
|
+
failure: () => ({ kind: "connect_refused", delivered: "no" }),
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: "network errno past the connect phase",
|
|
94
|
+
when: (err) => networkErrorCode(err) !== undefined,
|
|
95
|
+
failure: () => ({ kind: "connection_failed", delivered: "unknown" }),
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
name: "no structure",
|
|
99
|
+
when: () => true,
|
|
100
|
+
failure: () => ({ kind: "unknown", delivered: "unknown" }),
|
|
101
|
+
},
|
|
102
|
+
];
|
|
103
|
+
export function classifyMcpFailure(err, at) {
|
|
104
|
+
for (const rule of FAILURE_CLASSIFIER)
|
|
105
|
+
if (rule.when(err, at))
|
|
106
|
+
return rule.failure(err, at);
|
|
107
|
+
return { kind: "unknown", delivered: "unknown" };
|
|
108
|
+
}
|
|
109
|
+
export function describeHttpTransportFailure(err) {
|
|
110
|
+
const f = classifyMcpFailure(err, { phase: "request" });
|
|
111
|
+
switch (f.kind) {
|
|
112
|
+
case "http_status":
|
|
113
|
+
return { condition: `its HTTP endpoint answered ${f.httpStatus} instead of an MCP response`, delivered: f.delivered, httpStatus: f.httpStatus };
|
|
114
|
+
case "not_mcp_response":
|
|
115
|
+
return { condition: "its HTTP endpoint answered something that is not an MCP response", delivered: f.delivered };
|
|
116
|
+
case "connect_refused":
|
|
117
|
+
return { condition: `its HTTP endpoint could not be reached (${networkErrorCode(err)})`, delivered: f.delivered };
|
|
118
|
+
case "connection_failed":
|
|
119
|
+
return { condition: `the connection to its HTTP endpoint failed (${networkErrorCode(err)})`, delivered: f.delivered };
|
|
120
|
+
case "connection_closed":
|
|
121
|
+
case "spawn_failed":
|
|
122
|
+
case "timeout":
|
|
123
|
+
case "protocol":
|
|
124
|
+
case "invalid_config":
|
|
125
|
+
case "unknown":
|
|
126
|
+
return undefined;
|
|
127
|
+
}
|
|
128
|
+
}
|
package/dist/core/mcp.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ProtocolId } from "./protocol-table.js";
|
|
2
|
+
import { type McpDelivered, type McpFailureKind } from "./mcp-failure.js";
|
|
2
3
|
import type { AgentTool } from "../internal/harness-types.js";
|
|
3
4
|
import type { ImageContent, TextContent } from "../internal/llm.js";
|
|
4
5
|
import { type McpImageResizer } from "./image-downsample.js";
|
|
@@ -258,11 +259,13 @@ export interface McpServerStatus {
|
|
|
258
259
|
};
|
|
259
260
|
toolNames?: string[];
|
|
260
261
|
error?: string;
|
|
261
|
-
/** Present iff `status === "failed"` — the failure
|
|
262
|
-
*
|
|
263
|
-
* `
|
|
264
|
-
*
|
|
265
|
-
errorCode?:
|
|
262
|
+
/** Present iff `status === "failed"` — the connect-time failure record, spread flat: {@link McpFailure.kind}
|
|
263
|
+
* as `errorCode`, {@link McpFailure.delivered} as `delivered`, and `httpStatus` when the kind is
|
|
264
|
+
* `http_status`. A consumer keys an action off THESE (a `http_status` 401 is a re-authorization door,
|
|
265
|
+
* a `spawn_failed` is a missing binary) instead of parsing the neutralized `error` text. */
|
|
266
|
+
errorCode?: McpFailureKind;
|
|
267
|
+
delivered?: McpDelivered;
|
|
268
|
+
httpStatus?: number;
|
|
266
269
|
/**
|
|
267
270
|
* RB-437-a — set to `true` once core OBSERVES this server's transport close during the task; absent
|
|
268
271
|
* otherwise (never `false`: absence means "no close was observed", which is not the same as "alive").
|
|
@@ -380,78 +383,6 @@ export declare function describeMcpSpecErrorCode(code: unknown): string | undefi
|
|
|
380
383
|
* ours, and is left alone). Exported for unit testing; not part of the package index.
|
|
381
384
|
*/
|
|
382
385
|
export declare function collapseMcpErrorPrefix(message: string): string;
|
|
383
|
-
/** The first errno-shaped `code` on an error's cause chain. `fetch` reports every network failure as a
|
|
384
|
-
* bare `TypeError: fetch failed` with the real cause nested underneath (and an AggregateError when a
|
|
385
|
-
* host resolved to several addresses), so the code is never on the thrown error itself.
|
|
386
|
-
* Exported for unit testing (RB-449 mcp-1); not part of the package index (src/index.ts re-exports are
|
|
387
|
-
* explicit and do not name it — see the sibling `collapseMcpErrorPrefix`/`classifyDirReadInvalidParams`
|
|
388
|
-
* comments for the same "exported for tests only" convention). */
|
|
389
|
-
export declare function networkErrorCode(err: unknown, depth?: number): string | undefined;
|
|
390
|
-
/** What {@link describeHttpTransportFailure} could establish about a transport-level HTTP failure:
|
|
391
|
-
* the condition to name in the model-facing copy, whether the request can be said NOT to have reached
|
|
392
|
-
* the remote, and the HTTP status when the endpoint answered with one. */
|
|
393
|
-
export interface HttpTransportFailure {
|
|
394
|
-
condition: string;
|
|
395
|
-
/** `"no"` = provably never delivered (a connect-phase errno); `"unknown"` = the request may have run. */
|
|
396
|
-
delivered: "no" | "unknown";
|
|
397
|
-
httpStatus?: number;
|
|
398
|
-
}
|
|
399
|
-
/**
|
|
400
|
-
* RB-437-b — a streamable-HTTP failure that never became an MCP exchange at all: the POST failed at the
|
|
401
|
-
* network layer (endpoint gone / unresolvable), or the endpoint answered with something that is not an
|
|
402
|
-
* MCP response. The SDK surfaces the first as `fetch`'s bare `TypeError: fetch failed` and the second as
|
|
403
|
-
* a `StreamableHTTPError`; NEITHER carries the server name, the MCP context or an outcome — while the
|
|
404
|
-
* stdio path for the same event (the server went away) has all three. Returns the condition to name and
|
|
405
|
-
* whether the request can be said not to have reached the server, or `undefined` when the failure is not
|
|
406
|
-
* of this class (an McpError is an answer FROM the server: the exchange happened, so it is never one).
|
|
407
|
-
*
|
|
408
|
-
* Exported (not on the package index) for the A2A client leg, which faces the SAME `fetch` layer and owes
|
|
409
|
-
* the same outcome contract — one classifier, so the two protocols cannot drift on what "the request never
|
|
410
|
-
* reached them" means.
|
|
411
|
-
*/
|
|
412
|
-
export declare function describeHttpTransportFailure(err: unknown): HttpTransportFailure | undefined;
|
|
413
|
-
/**
|
|
414
|
-
* The closed vocabulary of MCP connect-failure classes a per-server status record may carry
|
|
415
|
-
* ({@link McpServerStatus.errorCode}, relayed onto the wiring manifest's `mcp[]` read face). The
|
|
416
|
-
* transport family is named by the failure's SHAPE wherever the SDK exposes one (error class, JSON-RPC
|
|
417
|
-
* code, errno on the cause chain, HTTP status), so a consumer can map a class to an action without
|
|
418
|
-
* parsing the neutralized error string. Two words are the exception and are text-derived, because
|
|
419
|
-
* undici and the SDK surface those two conditions as bare messages with no code: `network` (a
|
|
420
|
-
* `TypeError` whose message matches `fetch failed|terminated|network` and carries no errno) and the
|
|
421
|
-
* non-`McpError` arm of `connection_closed` (a message matching `not connected|connection closed`).
|
|
422
|
-
* A wording change in those libraries moves such a failure to `unknown`, never to a wrong word; the
|
|
423
|
-
* classifier table pins both regexes. An HTTP endpoint that answered with a status is
|
|
424
|
-
* reported in the `http_<status>` form (`http_401` = the endpoint wants (re-)authorization, `http_5xx` =
|
|
425
|
-
* the endpoint is down) — a template member of the type beside these fixed words. Additive-only: a new
|
|
426
|
-
* word here is a new arm for consumers, never a re-meaning of an existing one.
|
|
427
|
-
* · `connect_refused` — a connect-phase errno (ECONNREFUSED / ENOTFOUND / …): the request provably never left;
|
|
428
|
-
* · `connection_failed` — a network errno past the connect phase (reset / timed out mid-exchange);
|
|
429
|
-
* · `network` — the HTTP request failed at the network layer with no errno on the cause chain;
|
|
430
|
-
* · `not_mcp_response` — the HTTP endpoint answered something that is not an MCP payload (no status to name);
|
|
431
|
-
* · `spawn_failed` — a stdio server process could not be started (a missing/unexecutable command);
|
|
432
|
-
* · `connection_closed` — the transport closed during the handshake (the server process exited, the stream ended);
|
|
433
|
-
* · `timeout` — the handshake's request timed out;
|
|
434
|
-
* · `protocol` — the server answered the handshake with an MCP/JSON-RPC error (a version mismatch, a
|
|
435
|
-
* rejected capability, …) — `error` carries the named condition;
|
|
436
|
-
* · `invalid_config` — the declaration itself could not be dialed (a malformed `url`): a configuration
|
|
437
|
-
* fault to fix in the spec, never an outage to wait out;
|
|
438
|
-
* · `unknown` — none of the above could be established from the thrown value.
|
|
439
|
-
*/
|
|
440
|
-
export declare const MCP_FAILURE_CODES: readonly ["connect_refused", "connection_failed", "network", "not_mcp_response", "spawn_failed", "connection_closed", "timeout", "protocol", "invalid_config", "unknown"];
|
|
441
|
-
export type McpFailureCode = (typeof MCP_FAILURE_CODES)[number] | `http_${number}`;
|
|
442
|
-
/**
|
|
443
|
-
* Classify one connect-time failure into {@link McpFailureCode}. Reads the thrown value's SHAPE
|
|
444
|
-
* (error class, JSON-RPC code, errno on the cause chain, HTTP status) first; only the two
|
|
445
|
-
* message-shaped conditions named on {@link MCP_FAILURE_CODES} (`network`, the non-`McpError`
|
|
446
|
-
* `connection_closed`) are decided by a fixed regex over the message, and no other word can be chosen
|
|
447
|
-
* by message text — a remote's own wording can at most leave a failure at `unknown`.
|
|
448
|
-
* `transport` disambiguates the errno family: on a stdio server an errno is the child
|
|
449
|
-
* process failing to spawn, on an HTTP server it is the socket; a caller that could not establish the
|
|
450
|
-
* kind passes `undefined` and the errno family reads as the transport-neutral `connection_failed`.
|
|
451
|
-
* Total: every input maps to a word, and `unknown` is the honest word for a value this table cannot
|
|
452
|
-
* read (a caller must not receive a guess).
|
|
453
|
-
*/
|
|
454
|
-
export declare function mcpFailureCodeOf(err: unknown, transport: "stdio" | "http" | undefined): McpFailureCode;
|
|
455
386
|
export { normalizeNameSegment as normalizeMcpName, clampNameSegment } from "./protocol-naming.js";
|
|
456
387
|
export * from "./image-downsample.js";
|
|
457
388
|
/**
|
|
@@ -483,6 +414,19 @@ export interface ProtocolHttpAuth {
|
|
|
483
414
|
* turns it into a skipped peer instead of a failed task.
|
|
484
415
|
*/
|
|
485
416
|
export declare function resolveProtocolHttpHeaders(protocol: ProtocolId, t: ProtocolHttpAuth, principal?: string): Record<string, string> | undefined;
|
|
417
|
+
/** `kind` is the dial's ONE read of `spec.transport.kind` (taken by the caller beside the dial and threaded
|
|
418
|
+
* here, to the idle bucket and to the failure classifier alike): a nested `transport` object is the
|
|
419
|
+
* caller's, and a getter that answered differently to two readers would otherwise connect over one
|
|
420
|
+
* transport and be judged under another. An unknown kind takes the non-stdio branch, as it always did. */
|
|
421
|
+
/**
|
|
422
|
+
* The MCP HTTP transport's `fetch`: every request the transport makes — the POST, the SSE GET (initial and
|
|
423
|
+
* resumed), the DELETE, the auth flows — goes to the endpoint the declaration NAMED and follows no redirect.
|
|
424
|
+
* `fetch`'s default follows a 3xx silently and then reports only the last hop, which is the one shape under
|
|
425
|
+
* which the delivery verdict would lie (a connect refusal on the redirect target reading "never sent" while
|
|
426
|
+
* the declared endpoint had received the POST); a 3xx now surfaces as the SDK's HTTP-status error, and a
|
|
427
|
+
* body or a credential never travels to a host the declaration did not name. Exported for its pin only.
|
|
428
|
+
*/
|
|
429
|
+
export declare const declaredEndpointFetch: typeof fetch;
|
|
486
430
|
interface McpContentItem {
|
|
487
431
|
type: string;
|
|
488
432
|
text?: string;
|