@automatalabs/acp-agents 2.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -17
- package/dist/acp-client.d.ts +10 -4
- package/dist/acp-client.d.ts.map +1 -1
- package/dist/acp-client.js +11 -8
- package/dist/agent/acp-agent.d.ts +84 -26
- package/dist/agent/acp-agent.d.ts.map +1 -1
- package/dist/agent/acp-agent.js +458 -170
- package/dist/agent/errors.d.ts +12 -2
- package/dist/agent/errors.d.ts.map +1 -1
- package/dist/agent/errors.js +38 -9
- package/dist/agent/fork.d.ts +7 -5
- package/dist/agent/fork.d.ts.map +1 -1
- package/dist/agent/fork.js +7 -5
- package/dist/agent/messages.d.ts +42 -0
- package/dist/agent/messages.d.ts.map +1 -0
- package/dist/agent/messages.js +225 -0
- package/dist/agent/probe.d.ts +1 -1
- package/dist/agent/probe.d.ts.map +1 -1
- package/dist/agent/probe.js +5 -1
- package/dist/agent/queue.js +2 -2
- package/dist/agent/routing.d.ts +19 -1
- package/dist/agent/routing.d.ts.map +1 -1
- package/dist/agent/routing.js +41 -4
- package/dist/agent/stream.d.ts +21 -0
- package/dist/agent/stream.d.ts.map +1 -0
- package/dist/agent/stream.js +93 -0
- package/dist/agent/structured.d.ts +7 -3
- package/dist/agent/structured.d.ts.map +1 -1
- package/dist/agent/structured.js +24 -14
- package/dist/agent/tool-host.d.ts +34 -0
- package/dist/agent/tool-host.d.ts.map +1 -0
- package/dist/agent/tool-host.js +138 -0
- package/dist/agent/tools.d.ts +26 -0
- package/dist/agent/tools.d.ts.map +1 -0
- package/dist/agent/tools.js +62 -0
- package/dist/agent/turn.d.ts +6 -3
- package/dist/agent/turn.d.ts.map +1 -1
- package/dist/agent/turn.js +15 -67
- package/dist/agent/types.d.ts +174 -25
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/backend.d.ts +4 -3
- package/dist/backend.d.ts.map +1 -1
- package/dist/backends/codex.d.ts +2 -1
- package/dist/backends/codex.d.ts.map +1 -1
- package/dist/backends/codex.js +3 -2
- package/dist/config-catalog.d.ts +4 -0
- package/dist/config-catalog.d.ts.map +1 -1
- package/dist/config-catalog.js +1 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/local-mcp-host.d.ts +30 -0
- package/dist/local-mcp-host.d.ts.map +1 -0
- package/dist/local-mcp-host.js +151 -0
- package/dist/protocol-coverage.d.ts +8 -6
- package/dist/protocol-coverage.d.ts.map +1 -1
- package/dist/protocol-coverage.js +3 -2
- package/dist/registry.d.ts +3 -3
- package/dist/registry.d.ts.map +1 -1
- package/dist/runner.d.ts +5 -0
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +7 -4
- package/dist/structured-output.d.ts +18 -0
- package/dist/structured-output.d.ts.map +1 -1
- package/dist/structured-output.js +19 -1
- package/dist/structured-tool.d.ts +7 -9
- package/dist/structured-tool.d.ts.map +1 -1
- package/dist/structured-tool.js +14 -102
- package/dist/traits.d.ts +51 -0
- package/dist/traits.d.ts.map +1 -0
- package/dist/traits.js +88 -0
- package/package.json +4 -4
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
// The in-process Streamable HTTP MCP host both client-hosted tool servers share: bound to
|
|
2
|
+
// 127.0.0.1 on an ephemeral port, lazily (the first registration binds), serving one MCP server
|
|
3
|
+
// per unguessable token path. A request that names no live token is a 404; a request on a live
|
|
4
|
+
// token gets a fresh stateless transport + MCP `Server` pair for its lifetime (the SDK's stateless
|
|
5
|
+
// pattern, so concurrent calls never share protocol state). Subclasses own the token → server
|
|
6
|
+
// mapping (`StructuredOutputToolHost`: one slot per registered schema; `AgentToolHost`: one token
|
|
7
|
+
// for the agent's function tools) and the tool handlers.
|
|
8
|
+
import http from "node:http";
|
|
9
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
10
|
+
export const LOCAL_MCP_HOST = "127.0.0.1";
|
|
11
|
+
/** How long `closeServer()` lets requests that were mid-answer finish writing before every
|
|
12
|
+
* remaining connection is torn down (a tool run that ignores its abort signal must not keep the
|
|
13
|
+
* agent's `close()` hanging). */
|
|
14
|
+
const CLOSE_DRAIN_GRACE_MS = 1000;
|
|
15
|
+
export class LocalMcpHttpHost {
|
|
16
|
+
server;
|
|
17
|
+
/** The pending or settled bind of `server`, resolving with its port. */
|
|
18
|
+
listenPromise;
|
|
19
|
+
port;
|
|
20
|
+
inFlightRequests = 0;
|
|
21
|
+
drained;
|
|
22
|
+
isListening() {
|
|
23
|
+
return this.server?.listening === true;
|
|
24
|
+
}
|
|
25
|
+
listeningPort() {
|
|
26
|
+
return this.port;
|
|
27
|
+
}
|
|
28
|
+
/** Stop listening. Idempotent; resolves once the HTTP server closed (immediately when it never
|
|
29
|
+
* bound). A close that lands while `ensureListening()` is still binding waits for that bind to
|
|
30
|
+
* settle and then closes the socket it produced — returning early would leave the socket to
|
|
31
|
+
* come up after the close with nothing left to close it (the racing `ensureListening()` sees
|
|
32
|
+
* the host closed and rejects). A peer's keep-alive socket never holds the close open: idle
|
|
33
|
+
* connections are closed at once, requests still being answered get a bounded grace to flush,
|
|
34
|
+
* then everything left is destroyed — the peer is the agent process, which is gone or going. */
|
|
35
|
+
async closeServer() {
|
|
36
|
+
const server = this.server;
|
|
37
|
+
const binding = this.listenPromise;
|
|
38
|
+
this.server = undefined;
|
|
39
|
+
this.listenPromise = undefined;
|
|
40
|
+
this.port = undefined;
|
|
41
|
+
if (!server)
|
|
42
|
+
return;
|
|
43
|
+
if (binding)
|
|
44
|
+
await binding.then(noop, noop);
|
|
45
|
+
if (!server.listening)
|
|
46
|
+
return;
|
|
47
|
+
const closed = new Promise((resolve, reject) => {
|
|
48
|
+
server.close((error) => (error ? reject(error) : resolve()));
|
|
49
|
+
});
|
|
50
|
+
server.closeIdleConnections();
|
|
51
|
+
if (this.inFlightRequests > 0) {
|
|
52
|
+
await Promise.race([
|
|
53
|
+
new Promise((resolve) => (this.drained = resolve)),
|
|
54
|
+
new Promise((resolve) => setTimeout(resolve, CLOSE_DRAIN_GRACE_MS).unref()),
|
|
55
|
+
]);
|
|
56
|
+
this.drained = undefined;
|
|
57
|
+
}
|
|
58
|
+
server.closeIdleConnections();
|
|
59
|
+
if (this.inFlightRequests > 0)
|
|
60
|
+
server.closeAllConnections();
|
|
61
|
+
await closed;
|
|
62
|
+
}
|
|
63
|
+
urlFor(token, port) {
|
|
64
|
+
return `http://${LOCAL_MCP_HOST}:${port}/${token}`;
|
|
65
|
+
}
|
|
66
|
+
async ensureListening() {
|
|
67
|
+
if (!this.server) {
|
|
68
|
+
this.server = http.createServer((req, res) => {
|
|
69
|
+
void this.handleRequest(req, res);
|
|
70
|
+
});
|
|
71
|
+
this.server.unref();
|
|
72
|
+
}
|
|
73
|
+
const server = this.server;
|
|
74
|
+
if (!this.listenPromise) {
|
|
75
|
+
this.listenPromise = new Promise((resolve, reject) => {
|
|
76
|
+
const onError = (error) => {
|
|
77
|
+
server.off("listening", onListening);
|
|
78
|
+
reject(error);
|
|
79
|
+
};
|
|
80
|
+
const onListening = () => {
|
|
81
|
+
server.off("error", onError);
|
|
82
|
+
const address = server.address();
|
|
83
|
+
if (!address || typeof address === "string") {
|
|
84
|
+
reject(new Error(`${this.hostName} MCP server did not bind to a TCP port`));
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
resolve(address.port);
|
|
88
|
+
};
|
|
89
|
+
server.once("error", onError);
|
|
90
|
+
server.once("listening", onListening);
|
|
91
|
+
server.listen(0, LOCAL_MCP_HOST);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
const port = await this.listenPromise;
|
|
95
|
+
// `closeServer()` ran while the bind was pending: it waited for this bind and closed the
|
|
96
|
+
// server, so the port must not be handed out.
|
|
97
|
+
if (this.server !== server) {
|
|
98
|
+
throw new Error(`${this.hostName} MCP server was closed while it was binding`);
|
|
99
|
+
}
|
|
100
|
+
this.port = port;
|
|
101
|
+
return port;
|
|
102
|
+
}
|
|
103
|
+
async handleRequest(req, res) {
|
|
104
|
+
const token = tokenOf(req);
|
|
105
|
+
const server = token === undefined ? undefined : this.mcpServerFor(token, req, res);
|
|
106
|
+
if (!server) {
|
|
107
|
+
res.writeHead(404, { "content-type": "text/plain; charset=utf-8" });
|
|
108
|
+
res.end("not found");
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
|
|
112
|
+
this.inFlightRequests += 1;
|
|
113
|
+
try {
|
|
114
|
+
await server.connect(transport);
|
|
115
|
+
// Resolves once the response body has been written in full (the SDK's Node listener awaits
|
|
116
|
+
// the streamed body), so an async tool handler's result is on the wire before the teardown.
|
|
117
|
+
await transport.handleRequest(req, res);
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
if (!res.headersSent) {
|
|
121
|
+
res.writeHead(500, { "content-type": "text/plain; charset=utf-8" });
|
|
122
|
+
res.end(error instanceof Error ? error.message : String(error));
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
res.destroy(error instanceof Error ? error : undefined);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
finally {
|
|
129
|
+
await Promise.allSettled([server.close(), transport.close()]);
|
|
130
|
+
this.inFlightRequests -= 1;
|
|
131
|
+
if (this.inFlightRequests === 0)
|
|
132
|
+
this.drained?.();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function noop() { }
|
|
137
|
+
/** The single path segment of the request URL, or undefined when the path is not exactly `/<token>`. */
|
|
138
|
+
function tokenOf(req) {
|
|
139
|
+
const rawUrl = req.url ?? "/";
|
|
140
|
+
let pathname;
|
|
141
|
+
try {
|
|
142
|
+
pathname = new URL(rawUrl, `http://${LOCAL_MCP_HOST}`).pathname;
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
if (!pathname.startsWith("/") || pathname.slice(1).includes("/"))
|
|
148
|
+
return undefined;
|
|
149
|
+
const token = pathname.slice(1);
|
|
150
|
+
return token === "" ? undefined : token;
|
|
151
|
+
}
|
|
@@ -125,12 +125,14 @@ export declare const ACP_EXTENSION_SUPPORT_MATRIX: readonly AcpExtensionSupportM
|
|
|
125
125
|
/** How each installed agent answers `session/fork`, read from its adapter source, and what the
|
|
126
126
|
* AcpAgent SDK must do with the response. `id-only`: the response names a persisted copy that
|
|
127
127
|
* is not live — claude-agent-acp returns `{ sessionId }` from `dist/fork-session.js` and `prompt`
|
|
128
|
-
* on it throws "Session not found"
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
128
|
+
* on it throws "Session not found". `live`: the fork handle is the session — @automatalabs/codex-acp
|
|
129
|
+
* forks the thread through `thread/fork`, which subscribes the connection to the new thread
|
|
130
|
+
* exactly like `thread/resume` does, keeps that subscription (no `threadUnsubscribe`), and
|
|
131
|
+
* publishes the forked session's available commands and MCP startup status like a resumed one;
|
|
132
|
+
* pi constructs the fork in-process; OpenCode by live verification only. `reattach` names the
|
|
133
|
+
* reopen an `id-only` fork needs before its first turn. `cwd`: whether the fork may re-home —
|
|
134
|
+
* claude's transcript store is keyed by the source cwd. Data for the SDK's fork choreography;
|
|
135
|
+
* the runner's `forkSession()` returns the raw fork handle and never consults it. */
|
|
134
136
|
export interface ForkSessionTraitRow {
|
|
135
137
|
readonly agent: string;
|
|
136
138
|
readonly disposition: "id-only" | "live";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol-coverage.d.ts","sourceRoot":"","sources":["../src/protocol-coverage.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"protocol-coverage.d.ts","sourceRoot":"","sources":["../src/protocol-coverage.ts"],"names":[],"mappings":"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"}
|
|
@@ -186,7 +186,7 @@ const ACP_EXTENSION_SUPPORT_MATRIX_ROWS = [
|
|
|
186
186
|
export const ACP_EXTENSION_SUPPORT_MATRIX = Object.freeze(ACP_EXTENSION_SUPPORT_MATRIX_ROWS.map((row) => Object.freeze(row)));
|
|
187
187
|
const FORK_SESSION_TRAIT_ROWS = [
|
|
188
188
|
{ agent: "claude", disposition: "id-only", reattach: "resume-or-load", cwd: "source-only", distProbe: "claude" },
|
|
189
|
-
{ agent: "codex", disposition: "
|
|
189
|
+
{ agent: "codex", disposition: "live", reattach: "none", cwd: "free", distProbe: "codex" },
|
|
190
190
|
{ agent: "opencode", disposition: "live", reattach: "none", cwd: "free" },
|
|
191
191
|
{ agent: "pi", disposition: "live", reattach: "none", cwd: "free", distProbe: "pi" },
|
|
192
192
|
];
|
|
@@ -220,7 +220,8 @@ const SYSTEM_PROMPT_SUPPORT_ROWS = [
|
|
|
220
220
|
// merged into the `claude_code` preset with type/preset locked (`{ append }` extends it).
|
|
221
221
|
{ agent: "claude", replace: true, append: true, metaKeys: ["systemPrompt"], distProbe: "claude" },
|
|
222
222
|
// @automatalabs/codex-acp: bare `_meta.baseInstructions` (base prompt replacement) and
|
|
223
|
-
// `_meta.developerInstructions` (developer-role instructions) => thread/{start,resume} params
|
|
223
|
+
// `_meta.developerInstructions` (developer-role instructions) => thread/{start,resume,fork} params
|
|
224
|
+
// (a Codex fork is live, so session/fork's own `_meta` is where a fork's instructions travel).
|
|
224
225
|
{ agent: "codex", replace: true, append: true, metaKeys: ["baseInstructions", "developerInstructions"], distProbe: "codex" },
|
|
225
226
|
{ agent: "opencode", replace: false, append: false, metaKeys: [] },
|
|
226
227
|
// @automatalabs/pi-acp: `_meta.systemPrompt` `{ replace?, append? }` (or a string = replace) =>
|
package/dist/registry.d.ts
CHANGED
|
@@ -14,9 +14,9 @@ export interface CustomBackendConfig {
|
|
|
14
14
|
* Default true; set false for custom agents that should use only the generic prompt/_meta path. */
|
|
15
15
|
structuredOutputTool?: boolean;
|
|
16
16
|
/** How the custom agent answers `session/fork` (see `FORK_SESSION_TRAITS`). Omitted = `live` /
|
|
17
|
-
* `free`: the plain ACP contract. Entries wrapping claude-agent-acp or codex-acp
|
|
18
|
-
* `{ disposition: "id-only" }` — a registered name is a
|
|
19
|
-
* may shadow and never inherits the built-in's row. */
|
|
17
|
+
* `free`: the plain ACP contract. Entries wrapping claude-agent-acp (or upstream codex-acp, which
|
|
18
|
+
* unsubscribes its forks) MUST declare `{ disposition: "id-only" }` — a registered name is a
|
|
19
|
+
* different program from the built-in it may shadow and never inherits the built-in's row. */
|
|
20
20
|
fork?: CustomBackendForkConfig;
|
|
21
21
|
}
|
|
22
22
|
/** A custom backend's declared `session/fork` disposition — data, never probed. `id-only`: the fork
|
package/dist/registry.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,YAAY,wBAAwB,CAAC;AAIlD,0EAA0E;AAC1E,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,mFAAmF;IACnF,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B;2FACuF;IACvF,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC;wGACoG;IACpG,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,YAAY,wBAAwB,CAAC;AAIlD,0EAA0E;AAC1E,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,mFAAmF;IACnF,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B;2FACuF;IACvF,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC;wGACoG;IACpG,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;mGAG+F;IAC/F,IAAI,CAAC,EAAE,uBAAuB,CAAC;CAChC;AAED;;wGAEwG;AACxG,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,SAAS,GAAG,MAAM,CAAC;IAChC,GAAG,CAAC,EAAE,aAAa,GAAG,MAAM,CAAC;CAC9B;AAED,yEAAyE;AACzE,MAAM,WAAW,iBAAkB,SAAQ,mBAAmB;IAC5D,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;AAErE;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,EAC5C,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,eAAe,CAwBjB;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,eAAe,EACrB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,GACxC,eAAe,CAQjB"}
|
package/dist/runner.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { type AcpEventListener, type AcpEventName } from "./events.js";
|
|
|
6
6
|
import type { Backend } from "./backend.js";
|
|
7
7
|
import { InteractiveSession, type InteractiveSessionOptions } from "./interactive.js";
|
|
8
8
|
import { type BackendRegistry, type CustomBackendConfig } from "./registry.js";
|
|
9
|
+
import { type AcpAgentTraits } from "./traits.js";
|
|
9
10
|
import { type AuthMethodDescriptor, type AuthResolution, type AuthResolver } from "./auth/auth-types.js";
|
|
10
11
|
import { type AuthMethodType, type BackendAuthState } from "./auth/auth-store.js";
|
|
11
12
|
import type { ElicitationResolver, PermissionResolver } from "./permissions.js";
|
|
@@ -17,6 +18,10 @@ export interface ProbedConfigOptions {
|
|
|
17
18
|
options: SessionConfigOption[];
|
|
18
19
|
/** Effective ACP mode catalog after normalizing the mode config-option fallback; null means unsupported. AcpAgentRunner always returns this field. */
|
|
19
20
|
modes?: SessionModeState | null;
|
|
21
|
+
/** The backend's traits refined by the probe connection's initialize advertisements
|
|
22
|
+
* (`describeBackendTraits`): pi and the Codex fork report their system-prompt channel as
|
|
23
|
+
* `advertised`, Claude reports the table. AcpAgentRunner and the SDK probe always return it. */
|
|
24
|
+
traits?: AcpAgentTraits;
|
|
20
25
|
}
|
|
21
26
|
export interface ProbeConfigOptionsOptions {
|
|
22
27
|
cwd?: string;
|
package/dist/runner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAkBA,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,WAAW,EAEhB,KAAK,UAAU,EAEhB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EACpB,UAAU,EAEV,sBAAsB,EACtB,uBAAuB,EAEvB,qBAAqB,EAErB,oBAAoB,EAEpB,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAEjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAQvC,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,YAAY,EAGlB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAEtF,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACzB,MAAM,eAAe,CAAC;AAKvB,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,YAAY,EAClB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACtB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAc,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
|
package/dist/runner.js
CHANGED
|
@@ -27,13 +27,13 @@ import { mapThrownError } from "./errors-map.js";
|
|
|
27
27
|
import { assertNoModelConfigOption, resolveModelRoute } from "./routing.js";
|
|
28
28
|
import { assertSystemPromptSupported } from "./system-prompt.js";
|
|
29
29
|
import { sessionRefFor } from "./session-ref.js";
|
|
30
|
+
import { describeBackendTraits } from "./traits.js";
|
|
30
31
|
import { buildAuthDescriptor, } from "./auth/auth-types.js";
|
|
31
32
|
import { AuthStore, classifyCredential, } from "./auth/auth-store.js";
|
|
32
33
|
import { ProviderStore, providerVertexMeta } from "./provider-store.js";
|
|
33
|
-
import { resolveStructuredOutput } from "./structured-output.js";
|
|
34
|
+
import { repairPromptText, resolveStructuredOutput } from "./structured-output.js";
|
|
34
35
|
import { STRUCTURED_OUTPUT_SERVER_NAME, StructuredOutputToolHost, } from "./structured-tool.js";
|
|
35
36
|
import { buildRunPrompt, mergeTurnMeta, promptWithImages, validatePromptImages, } from "./prompt.js";
|
|
36
|
-
const STRUCTURED_TOOL_REPROMPT_TEXT = "You did not call the StructuredOutput tool. Call the StructuredOutput tool now, exactly once, with your final answer as its arguments conforming to its parameter schema. Do not reply with plain text.";
|
|
37
37
|
const CONTINUATION_INSTRUCTION = "Your previous turn was interrupted before it finished — the provider paused it for a usage " +
|
|
38
38
|
"limit or expired credentials, not because the task was complete. The full task and all prior " +
|
|
39
39
|
"context are already in this session's history; do not restart or repeat work you already did. " +
|
|
@@ -174,10 +174,11 @@ export class AcpAgentRunner {
|
|
|
174
174
|
throw new Error("ACP agent runner is disposed");
|
|
175
175
|
opts.signal?.throwIfAborted();
|
|
176
176
|
const cwd = opts.cwd ?? process.cwd();
|
|
177
|
+
const registry = registryWithRunBackends(this.backends, opts.backends);
|
|
177
178
|
const prepared = this.prepareSession({ model: spec }, {
|
|
178
179
|
cwd,
|
|
179
180
|
schema: undefined,
|
|
180
|
-
registry
|
|
181
|
+
registry,
|
|
181
182
|
signal: opts.signal,
|
|
182
183
|
});
|
|
183
184
|
let session;
|
|
@@ -192,6 +193,7 @@ export class AcpAgentRunner {
|
|
|
192
193
|
...(prepared.backend.defaultModeId === undefined ? {} : { defaultModeId: prepared.backend.defaultModeId }),
|
|
193
194
|
options: session.advertisedConfigOptions,
|
|
194
195
|
modes: session.modes ?? null,
|
|
196
|
+
traits: describeBackendTraits(prepared.backend, registry, session.capabilities),
|
|
195
197
|
};
|
|
196
198
|
}
|
|
197
199
|
finally {
|
|
@@ -686,7 +688,8 @@ export class AcpAgentRunner {
|
|
|
686
688
|
maxSchemaRetries: opts.maxSchemaRetries,
|
|
687
689
|
signal: opts.signal,
|
|
688
690
|
label: opts.label,
|
|
689
|
-
|
|
691
|
+
// The same selection AcpAgent's ladder makes (tool variant vs JSON variant), bare text.
|
|
692
|
+
repromptText: repairPromptText({ toolActive: structuredToolActive }),
|
|
690
693
|
});
|
|
691
694
|
return result;
|
|
692
695
|
}
|
|
@@ -39,6 +39,24 @@ export interface ResolveOptions {
|
|
|
39
39
|
label?: string;
|
|
40
40
|
repromptText?: string;
|
|
41
41
|
}
|
|
42
|
+
/** The repair prompt for a schema turn that produced no valid JSON (native channels, prose
|
|
43
|
+
* extraction). Sent bare — text only, no re-embedded contract; the schema is in the session's
|
|
44
|
+
* context from the first turn — by the runner's ladder and by `AcpAgent`'s opt-in one. */
|
|
45
|
+
export declare const REPROMPT_TEXT: string;
|
|
46
|
+
/** The repair prompt when the client-hosted StructuredOutput tool is active on the session and
|
|
47
|
+
* the turn did not call it. */
|
|
48
|
+
export declare const STRUCTURED_TOOL_REPROMPT_TEXT = "You did not call the StructuredOutput tool. Call the StructuredOutput tool now, exactly once, with your final answer as its arguments conforming to its parameter schema. Do not reply with plain text.";
|
|
49
|
+
/**
|
|
50
|
+
* The one repair prompt both ladders send (package-internal; the runner and `AcpAgent` are its
|
|
51
|
+
* only callers): `STRUCTURED_TOOL_REPROMPT_TEXT` when the injected StructuredOutput tool is active
|
|
52
|
+
* for the session, else `REPROMPT_TEXT`; with `reason` (the previous turn's validation failure —
|
|
53
|
+
* `AcpAgentTurn.structuredError`) appended on its own line so the agent corrects against the actual
|
|
54
|
+
* miss, not a guess. The runner passes no reason and sends the bare text.
|
|
55
|
+
*/
|
|
56
|
+
export declare function repairPromptText(options: {
|
|
57
|
+
toolActive: boolean;
|
|
58
|
+
reason?: string;
|
|
59
|
+
}): string;
|
|
42
60
|
/**
|
|
43
61
|
* Resolve a schema agent's result via the ladder above. Returns the validated value (typed
|
|
44
62
|
* unknown at this layer; the caller casts to the seam's AgentResult<S>). Throws
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"structured-output.d.ts","sourceRoot":"","sources":["../src/structured-output.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAIvC;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAa9D;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAiBpD;AAED,gGAAgG;AAChG,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAQtE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAUvE;AAED,sGAAsG;AACtG,MAAM,WAAW,iBAAiB;IAChC,mDAAmD;IACnD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,+DAA+D;IAC/D,QAAQ,IAAI,MAAM,CAAC;IACnB,8FAA8F;IAC9F,SAAS,CAAC,IAAI,OAAO,CAAC;IACtB,4FAA4F;IAC5F,WAAW,CAAC,IAAI,OAAO,GAAG,SAAS,CAAC;CACrC;AAED,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;
|
|
1
|
+
{"version":3,"file":"structured-output.d.ts","sourceRoot":"","sources":["../src/structured-output.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAIvC;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAa9D;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAiBpD;AAED,gGAAgG;AAChG,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAQtE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAUvE;AAED,sGAAsG;AACtG,MAAM,WAAW,iBAAiB;IAChC,mDAAmD;IACnD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,+DAA+D;IAC/D,QAAQ,IAAI,MAAM,CAAC;IACnB,8FAA8F;IAC9F,SAAS,CAAC,IAAI,OAAO,CAAC;IACtB,4FAA4F;IAC5F,WAAW,CAAC,IAAI,OAAO,GAAG,SAAS,CAAC;CACrC;AAED,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;2FAE2F;AAC3F,eAAO,MAAM,aAAa,QAIf,CAAC;AAEZ;gCACgC;AAChC,eAAO,MAAM,6BAA6B,4MACiK,CAAC;AAE5M;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IAAE,UAAU,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAI1F;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,iBAAiB,EAC1B,MAAM,EAAE,OAAO,EACf,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,OAAO,CAAC,CAgClB"}
|
|
@@ -81,11 +81,29 @@ export function extractValidated(text, schema) {
|
|
|
81
81
|
}
|
|
82
82
|
return validateValue(parsed, schema);
|
|
83
83
|
}
|
|
84
|
-
|
|
84
|
+
/** The repair prompt for a schema turn that produced no valid JSON (native channels, prose
|
|
85
|
+
* extraction). Sent bare — text only, no re-embedded contract; the schema is in the session's
|
|
86
|
+
* context from the first turn — by the runner's ladder and by `AcpAgent`'s opt-in one. */
|
|
87
|
+
export const REPROMPT_TEXT = [
|
|
85
88
|
"Your previous reply did not return valid JSON matching the required output schema.",
|
|
86
89
|
"Reply now with ONLY a single JSON object that conforms to the schema —",
|
|
87
90
|
"no prose, no explanation, and no markdown code fences.",
|
|
88
91
|
].join(" ");
|
|
92
|
+
/** The repair prompt when the client-hosted StructuredOutput tool is active on the session and
|
|
93
|
+
* the turn did not call it. */
|
|
94
|
+
export const STRUCTURED_TOOL_REPROMPT_TEXT = "You did not call the StructuredOutput tool. Call the StructuredOutput tool now, exactly once, with your final answer as its arguments conforming to its parameter schema. Do not reply with plain text.";
|
|
95
|
+
/**
|
|
96
|
+
* The one repair prompt both ladders send (package-internal; the runner and `AcpAgent` are its
|
|
97
|
+
* only callers): `STRUCTURED_TOOL_REPROMPT_TEXT` when the injected StructuredOutput tool is active
|
|
98
|
+
* for the session, else `REPROMPT_TEXT`; with `reason` (the previous turn's validation failure —
|
|
99
|
+
* `AcpAgentTurn.structuredError`) appended on its own line so the agent corrects against the actual
|
|
100
|
+
* miss, not a guess. The runner passes no reason and sends the bare text.
|
|
101
|
+
*/
|
|
102
|
+
export function repairPromptText(options) {
|
|
103
|
+
const base = options.toolActive ? STRUCTURED_TOOL_REPROMPT_TEXT : REPROMPT_TEXT;
|
|
104
|
+
const reason = options.reason?.trim();
|
|
105
|
+
return reason ? `${base}\n\nValidation error: ${reason}` : base;
|
|
106
|
+
}
|
|
89
107
|
/**
|
|
90
108
|
* Resolve a schema agent's result via the ladder above. Returns the validated value (typed
|
|
91
109
|
* unknown at this layer; the caller casts to the seam's AgentResult<S>). Throws
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
1
2
|
import { type Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
2
3
|
import type { TSchema } from "typebox";
|
|
4
|
+
import { LocalMcpHttpHost } from "./local-mcp-host.js";
|
|
3
5
|
export declare const STRUCTURED_OUTPUT_TOOL_NAME = "StructuredOutput";
|
|
4
6
|
export declare const STRUCTURED_OUTPUT_SERVER_NAME = "structured_output";
|
|
5
7
|
export declare const STRUCTURED_OUTPUT_TOOL_DESCRIPTION: string;
|
|
@@ -13,18 +15,14 @@ export interface StructuredOutputToolRegistration {
|
|
|
13
15
|
release(): void;
|
|
14
16
|
}
|
|
15
17
|
/** Runner-scoped localhost MCP host. It binds only once a schema run actually needs injection. */
|
|
16
|
-
export declare class StructuredOutputToolHost {
|
|
18
|
+
export declare class StructuredOutputToolHost extends LocalMcpHttpHost {
|
|
19
|
+
protected readonly hostName = "StructuredOutput";
|
|
17
20
|
private readonly slots;
|
|
18
|
-
private server;
|
|
19
|
-
private listenPromise;
|
|
20
|
-
private port;
|
|
21
|
-
isListening(): boolean;
|
|
22
|
-
listeningPort(): number | undefined;
|
|
23
21
|
register(schema: TSchema): Promise<StructuredOutputToolRegistration>;
|
|
24
22
|
dispose(): Promise<void>;
|
|
25
|
-
|
|
26
|
-
private handleRequest;
|
|
27
|
-
private slotFor;
|
|
23
|
+
protected mcpServerFor(token: string): Server | undefined;
|
|
28
24
|
}
|
|
29
25
|
export declare function structuredToolInputSchema(schema: TSchema): Tool["inputSchema"];
|
|
26
|
+
/** The first three typebox validation errors of `value` against `schema`, one line. */
|
|
27
|
+
export declare function describeSchemaErrors(schema: TSchema, value: unknown): string;
|
|
30
28
|
//# sourceMappingURL=structured-tool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"structured-tool.d.ts","sourceRoot":"","sources":["../src/structured-tool.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"structured-tool.d.ts","sourceRoot":"","sources":["../src/structured-tool.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAOL,KAAK,IAAI,EACV,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAIvD,eAAO,MAAM,2BAA2B,qBAAqB,CAAC;AAC9D,eAAO,MAAM,6BAA6B,sBAAsB,CAAC;AAEjE,eAAO,MAAM,kCAAkC,QAM2C,CAAC;AAS3F,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,2FAA2F;IAC3F,WAAW,IAAI,OAAO,GAAG,SAAS,CAAC;IACnC;2EACuE;IACvE,YAAY,IAAI,OAAO,GAAG,SAAS,CAAC;IACpC,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,kGAAkG;AAClG,qBAAa,wBAAyB,SAAQ,gBAAgB;IAC5D,SAAS,CAAC,QAAQ,CAAC,QAAQ,sBAAsB;IACjD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2B;IAE3C,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,gCAAgC,CAAC;IA6BpE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAK9B,SAAS,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;CAI1D;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,CAI9E;AAyCD,uFAAuF;AACvF,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAW5E"}
|
package/dist/structured-tool.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { randomBytes } from "node:crypto";
|
|
2
|
-
import http from "node:http";
|
|
3
2
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
4
|
-
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
5
3
|
import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, } from "@modelcontextprotocol/sdk/types.js";
|
|
6
4
|
import { Convert, Errors } from "typebox/value";
|
|
5
|
+
import { LocalMcpHttpHost } from "./local-mcp-host.js";
|
|
7
6
|
import { toJsonSchema } from "./schema-strict.js";
|
|
8
7
|
import { validateValue } from "./structured-output.js";
|
|
9
8
|
export const STRUCTURED_OUTPUT_TOOL_NAME = "StructuredOutput";
|
|
@@ -14,19 +13,10 @@ export const STRUCTURED_OUTPUT_TOOL_DESCRIPTION = "Use this tool to return your
|
|
|
14
13
|
"- The input must be valid JSON matching the required schema\n" +
|
|
15
14
|
"- Complete all necessary research and tool calls BEFORE calling this tool\n" +
|
|
16
15
|
"- This tool provides your final answer - no further actions are taken after calling it";
|
|
17
|
-
const HOST = "127.0.0.1";
|
|
18
16
|
/** Runner-scoped localhost MCP host. It binds only once a schema run actually needs injection. */
|
|
19
|
-
export class StructuredOutputToolHost {
|
|
17
|
+
export class StructuredOutputToolHost extends LocalMcpHttpHost {
|
|
18
|
+
hostName = "StructuredOutput";
|
|
20
19
|
slots = new Map();
|
|
21
|
-
server;
|
|
22
|
-
listenPromise;
|
|
23
|
-
port;
|
|
24
|
-
isListening() {
|
|
25
|
-
return this.server?.listening === true;
|
|
26
|
-
}
|
|
27
|
-
listeningPort() {
|
|
28
|
-
return this.port;
|
|
29
|
-
}
|
|
30
20
|
async register(schema) {
|
|
31
21
|
const token = randomBytes(16).toString("hex");
|
|
32
22
|
const slot = {
|
|
@@ -39,7 +29,7 @@ export class StructuredOutputToolHost {
|
|
|
39
29
|
try {
|
|
40
30
|
const port = await this.ensureListening();
|
|
41
31
|
return {
|
|
42
|
-
url:
|
|
32
|
+
url: this.urlFor(token, port),
|
|
43
33
|
tryCaptured: () => slot.captured,
|
|
44
34
|
takeCaptured: () => {
|
|
45
35
|
const captured = slot.captured;
|
|
@@ -58,92 +48,11 @@ export class StructuredOutputToolHost {
|
|
|
58
48
|
}
|
|
59
49
|
async dispose() {
|
|
60
50
|
this.slots.clear();
|
|
61
|
-
|
|
62
|
-
this.server = undefined;
|
|
63
|
-
this.listenPromise = undefined;
|
|
64
|
-
this.port = undefined;
|
|
65
|
-
if (!server || !server.listening)
|
|
66
|
-
return;
|
|
67
|
-
await new Promise((resolve, reject) => {
|
|
68
|
-
server.close((error) => (error ? reject(error) : resolve()));
|
|
69
|
-
});
|
|
51
|
+
await this.closeServer();
|
|
70
52
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
void this.handleRequest(req, res);
|
|
75
|
-
});
|
|
76
|
-
this.server.unref();
|
|
77
|
-
}
|
|
78
|
-
if (!this.listenPromise) {
|
|
79
|
-
this.listenPromise = new Promise((resolve, reject) => {
|
|
80
|
-
const server = this.server;
|
|
81
|
-
const onError = (error) => {
|
|
82
|
-
server.off("listening", onListening);
|
|
83
|
-
reject(error);
|
|
84
|
-
};
|
|
85
|
-
const onListening = () => {
|
|
86
|
-
server.off("error", onError);
|
|
87
|
-
const address = server.address();
|
|
88
|
-
if (!address || typeof address === "string") {
|
|
89
|
-
reject(new Error("StructuredOutput MCP server did not bind to a TCP port"));
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
this.port = address.port;
|
|
93
|
-
resolve();
|
|
94
|
-
};
|
|
95
|
-
server.once("error", onError);
|
|
96
|
-
server.once("listening", onListening);
|
|
97
|
-
server.listen(0, HOST);
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
await this.listenPromise;
|
|
101
|
-
if (this.port === undefined) {
|
|
102
|
-
throw new Error("StructuredOutput MCP server has no listening port");
|
|
103
|
-
}
|
|
104
|
-
return this.port;
|
|
105
|
-
}
|
|
106
|
-
async handleRequest(req, res) {
|
|
107
|
-
const slot = this.slotFor(req);
|
|
108
|
-
if (!slot) {
|
|
109
|
-
res.writeHead(404, { "content-type": "text/plain; charset=utf-8" });
|
|
110
|
-
res.end("not found");
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
|
|
114
|
-
const server = createMcpServer(slot);
|
|
115
|
-
try {
|
|
116
|
-
await server.connect(transport);
|
|
117
|
-
await transport.handleRequest(req, res);
|
|
118
|
-
}
|
|
119
|
-
catch (error) {
|
|
120
|
-
if (!res.headersSent) {
|
|
121
|
-
res.writeHead(500, { "content-type": "text/plain; charset=utf-8" });
|
|
122
|
-
res.end(error instanceof Error ? error.message : String(error));
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
res.destroy(error instanceof Error ? error : undefined);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
finally {
|
|
129
|
-
await Promise.allSettled([server.close(), transport.close()]);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
slotFor(req) {
|
|
133
|
-
const rawUrl = req.url ?? "/";
|
|
134
|
-
let pathname;
|
|
135
|
-
try {
|
|
136
|
-
pathname = new URL(rawUrl, `http://${HOST}`).pathname;
|
|
137
|
-
}
|
|
138
|
-
catch {
|
|
139
|
-
return undefined;
|
|
140
|
-
}
|
|
141
|
-
if (!pathname.startsWith("/") || pathname.slice(1).includes("/"))
|
|
142
|
-
return undefined;
|
|
143
|
-
const token = pathname.slice(1);
|
|
144
|
-
if (!token)
|
|
145
|
-
return undefined;
|
|
146
|
-
return this.slots.get(token);
|
|
53
|
+
mcpServerFor(token) {
|
|
54
|
+
const slot = this.slots.get(token);
|
|
55
|
+
return slot ? createMcpServer(slot) : undefined;
|
|
147
56
|
}
|
|
148
57
|
}
|
|
149
58
|
export function structuredToolInputSchema(schema) {
|
|
@@ -182,7 +91,8 @@ function textResult(text, isError) {
|
|
|
182
91
|
...(isError ? { isError: true } : {}),
|
|
183
92
|
};
|
|
184
93
|
}
|
|
185
|
-
|
|
94
|
+
/** The first three typebox validation errors of `value` against `schema`, one line. */
|
|
95
|
+
export function describeSchemaErrors(schema, value) {
|
|
186
96
|
let converted;
|
|
187
97
|
try {
|
|
188
98
|
converted = Convert(schema, value);
|
|
@@ -190,13 +100,15 @@ function rejectionText(value, schema) {
|
|
|
190
100
|
catch {
|
|
191
101
|
converted = value;
|
|
192
102
|
}
|
|
193
|
-
|
|
103
|
+
return Errors(schema, converted)
|
|
194
104
|
.slice(0, 3)
|
|
195
105
|
.map((error) => `${error.instancePath || "/"} ${error.message}`)
|
|
196
106
|
.join("; ");
|
|
107
|
+
}
|
|
108
|
+
function rejectionText(value, schema) {
|
|
197
109
|
return [
|
|
198
110
|
"Structured output rejected: arguments do not match the required schema.",
|
|
199
|
-
|
|
111
|
+
describeSchemaErrors(schema, value),
|
|
200
112
|
"Fix the arguments and call StructuredOutput again.",
|
|
201
113
|
]
|
|
202
114
|
.filter(Boolean)
|