@nextclaw/nextclaw-ncp-runtime-stdio-client 0.2.13 → 0.2.14-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/stdio-runtime-config.utils.d.ts +1 -0
- package/dist/stdio-runtime-config.utils.d.ts.map +1 -1
- package/dist/stdio-runtime-config.utils.js +2 -0
- package/dist/stdio-runtime-config.utils.js.map +1 -1
- package/dist/stdio-runtime-probe.utils.d.ts.map +1 -1
- package/dist/stdio-runtime-probe.utils.js +6 -4
- package/dist/stdio-runtime-probe.utils.js.map +1 -1
- package/dist/stdio-runtime.service.d.ts +0 -1
- package/dist/stdio-runtime.service.d.ts.map +1 -1
- package/dist/stdio-runtime.service.js +41 -28
- package/dist/stdio-runtime.service.js.map +1 -1
- package/dist/utils/stdio-runtime-input.utils.js +18 -0
- package/dist/utils/stdio-runtime-input.utils.js.map +1 -0
- package/dist/utils/stdio-runtime-recovery.utils.js +27 -0
- package/dist/utils/stdio-runtime-recovery.utils.js.map +1 -0
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stdio-runtime-config.utils.d.ts","names":[],"sources":["../src/stdio-runtime-config.utils.ts"],"mappings":";;;cAGa,0BAAA;AAAA,KAWD,eAAA,GAAkB,MAAA;AAAA,KAClB,uBAAA;AAAA,KACA,wBAAA;AAAA,KAEA,mBAAA;EACV,aAAA;EACA,aAAA,GAAgB,uBAAA;EAChB,eAAA,GAAkB,MAAA;EAClB,KAAA,GAAQ,aAAA,CAAc,UAAA;AAAA;AAAA,KAGZ,0BAAA;EACV,WAAA,EAAa,uBAAA;EACb,YAAA,EAAc,wBAAA;EACd,OAAA;EACA,IAAA;EACA,GAAA;EACA,GAAA,GAAM,eAAA;EACN,gBAAA;EACA,cAAA;EACA,gBAAA;AAAA;AAAA,cAkGW,0BAAA;EAAA,iBACkB,MAAA;cAAA,MAAA,GAAQ,MAAA;EAErC,OAAA,QAAc,0BAAA;EAAA,
|
|
1
|
+
{"version":3,"file":"stdio-runtime-config.utils.d.ts","names":[],"sources":["../src/stdio-runtime-config.utils.ts"],"mappings":";;;cAGa,0BAAA;AAAA,KAWD,eAAA,GAAkB,MAAA;AAAA,KAClB,uBAAA;AAAA,KACA,wBAAA;AAAA,KAEA,mBAAA;EACV,aAAA;EACA,aAAA,GAAgB,uBAAA;EAChB,eAAA,GAAkB,MAAA;EAClB,KAAA,GAAQ,aAAA,CAAc,UAAA;AAAA;AAAA,KAGZ,0BAAA;EACV,WAAA,EAAa,uBAAA;EACb,YAAA,EAAc,wBAAA;EACd,OAAA;EACA,IAAA;EACA,GAAA;EACA,GAAA,GAAM,eAAA;EACN,mCAAA;EACA,gBAAA;EACA,cAAA;EACA,gBAAA;AAAA;AAAA,cAkGW,0BAAA;EAAA,iBACkB,MAAA;cAAA,MAAA,GAAQ,MAAA;EAErC,OAAA,QAAc,0BAAA;EAAA,QAmDN,kBAAA;EAAA,QAQA,mBAAA;AAAA;AAAA,iBASM,0BAAA,CAA2B,MAAA;EACzC,aAAA,GAAgB,uBAAA;AAAA,IACd,MAAA;AAAA,iBAaY,0BAAA,CAA2B,MAAA;EACzC,OAAA,GAAU,MAAA;EACV,SAAA,GAAY,eAAA;EACZ,aAAA,GAAgB,uBAAA;AAAA,IACd,MAAA"}
|
|
@@ -78,6 +78,7 @@ var StdioRuntimeConfigResolver = class {
|
|
|
78
78
|
const args = override?.args ?? readStringArray(this.source.args) ?? readStringArray(parseJsonArray(process.env.NEXTCLAW_NARP_STDIO_ARGS)) ?? [];
|
|
79
79
|
const cwd = override?.cwd ?? readString(this.source.cwd) ?? readString(process.env.NEXTCLAW_NARP_STDIO_CWD);
|
|
80
80
|
const env = override?.env ?? readStringRecord(this.source.env) ?? readStringRecord(parseJsonObject(process.env.NEXTCLAW_NARP_STDIO_ENV));
|
|
81
|
+
const resetSessionMetadataOnPromptTimeout = readStringArray(this.source.resetSessionMetadataOnPromptTimeout);
|
|
81
82
|
return {
|
|
82
83
|
wireDialect,
|
|
83
84
|
processScope,
|
|
@@ -85,6 +86,7 @@ var StdioRuntimeConfigResolver = class {
|
|
|
85
86
|
args,
|
|
86
87
|
...cwd ? { cwd } : {},
|
|
87
88
|
...env ? { env } : {},
|
|
89
|
+
...resetSessionMetadataOnPromptTimeout ? { resetSessionMetadataOnPromptTimeout } : {},
|
|
88
90
|
startupTimeoutMs: readPositiveInteger(this.source.startupTimeoutMs) ?? readPositiveInteger(process.env.NEXTCLAW_NARP_STDIO_STARTUP_TIMEOUT_MS) ?? DEFAULT_STARTUP_TIMEOUT_MS,
|
|
89
91
|
probeTimeoutMs: readPositiveInteger(this.source.probeTimeoutMs) ?? DEFAULT_PROBE_TIMEOUT_MS,
|
|
90
92
|
requestTimeoutMs: readPositiveInteger(this.source.requestTimeoutMs) ?? DEFAULT_REQUEST_TIMEOUT_MS
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stdio-runtime-config.utils.js","names":[],"sources":["../src/stdio-runtime-config.utils.ts"],"sourcesContent":["import type { OpenAITool, NcpProviderRuntimeRoute } from \"@nextclaw/ncp\";\nimport { createRuntimeChildEnv } from \"@nextclaw/core\";\n\nexport const NARP_STDIO_PROMPT_META_KEY = \"nextclaw_narp\";\nconst DEFAULT_STARTUP_TIMEOUT_MS = 10_000;\nconst DEFAULT_PROBE_TIMEOUT_MS = 3_000;\nconst DEFAULT_REQUEST_TIMEOUT_MS = 120_000;\nconst DEFAULT_RUNTIME_ROUTE_BRIDGE_FIELDS = {\n model: \"NEXTCLAW_MODEL\",\n apiBase: \"NEXTCLAW_API_BASE\",\n apiKey: \"NEXTCLAW_API_KEY\",\n headers: \"NEXTCLAW_HEADERS_JSON\",\n} as const;\n\nexport type StdioRuntimeEnv = Record<string, string>;\nexport type StdioRuntimeWireDialect = \"acp\";\nexport type StdioRuntimeProcessScope = \"per-session\";\n\nexport type NarpStdioPromptMeta = {\n correlationId?: string;\n providerRoute?: NcpProviderRuntimeRoute;\n sessionMetadata?: Record<string, unknown>;\n tools?: ReadonlyArray<OpenAITool>;\n};\n\nexport type StdioRuntimeResolvedConfig = {\n wireDialect: StdioRuntimeWireDialect;\n processScope: StdioRuntimeProcessScope;\n command: string;\n args: string[];\n cwd?: string;\n env?: StdioRuntimeEnv;\n startupTimeoutMs: number;\n probeTimeoutMs: number;\n requestTimeoutMs: number;\n};\n\ntype StdioRuntimeCommandOverride = {\n command?: string;\n args?: string[];\n cwd?: string;\n env?: StdioRuntimeEnv;\n};\n\nexport function readString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nexport function readPositiveInteger(value: unknown): number | undefined {\n const parsed =\n typeof value === \"number\"\n ? value\n : typeof value === \"string\"\n ? Number.parseInt(value, 10)\n : Number.NaN;\n if (!Number.isFinite(parsed)) {\n return undefined;\n }\n const normalized = Math.trunc(parsed);\n return normalized > 0 ? normalized : undefined;\n}\n\nexport function readStringArray(value: unknown): string[] | undefined {\n if (!Array.isArray(value)) {\n return undefined;\n }\n\n const output: string[] = [];\n for (const entry of value) {\n const normalized = readString(entry);\n if (!normalized) {\n continue;\n }\n output.push(normalized);\n }\n return output.length > 0 ? output : undefined;\n}\n\nexport function readStringRecord(value: unknown): Record<string, string> | undefined {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return undefined;\n }\n\n const output: Record<string, string> = {};\n for (const [entryKey, entryValue] of Object.entries(value)) {\n const normalizedValue = readString(entryValue);\n if (!normalizedValue) {\n continue;\n }\n output[entryKey] = normalizedValue;\n }\n return Object.keys(output).length > 0 ? output : undefined;\n}\n\nfunction readCommandOverrides(value: unknown): Record<string, StdioRuntimeCommandOverride> {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return {};\n }\n\n const overrides: Record<string, StdioRuntimeCommandOverride> = {};\n for (const [rawCommand, rawOverride] of Object.entries(value)) {\n const commandKey = readString(rawCommand);\n if (!commandKey || !rawOverride || typeof rawOverride !== \"object\" || Array.isArray(rawOverride)) {\n continue;\n }\n const overrideRecord = rawOverride as Record<string, unknown>;\n const command = readString(overrideRecord.command);\n const args = readStringArray(overrideRecord.args);\n const cwd = readString(overrideRecord.cwd);\n const env = readStringRecord(overrideRecord.env);\n if (!command && !args && !cwd && !env) {\n continue;\n }\n overrides[commandKey] = {\n ...(command ? { command } : {}),\n ...(args ? { args } : {}),\n ...(cwd ? { cwd } : {}),\n ...(env ? { env } : {}),\n };\n }\n return overrides;\n}\n\nfunction readCommandOverride(command: string): StdioRuntimeCommandOverride | undefined {\n const rawOverrides = parseJsonObject(process.env.NEXTCLAW_NARP_STDIO_COMMAND_OVERRIDES);\n return readCommandOverrides(rawOverrides)[command];\n}\n\nexport class StdioRuntimeConfigResolver {\n constructor(private readonly source: Record<string, unknown> = {}) {}\n\n resolve = (): StdioRuntimeResolvedConfig => {\n const wireDialect = this.resolveWireDialect();\n const processScope = this.resolveProcessScope();\n const command =\n readString(this.source.command) ??\n readString(process.env.NEXTCLAW_NARP_STDIO_COMMAND);\n if (!command) {\n throw new Error(\"[narp-stdio] missing stdio command\");\n }\n\n const override = readCommandOverride(command);\n const args =\n override?.args ??\n readStringArray(this.source.args) ??\n readStringArray(parseJsonArray(process.env.NEXTCLAW_NARP_STDIO_ARGS)) ??\n [];\n const cwd =\n override?.cwd ??\n readString(this.source.cwd) ??\n readString(process.env.NEXTCLAW_NARP_STDIO_CWD);\n const env =\n override?.env ??\n readStringRecord(this.source.env) ??\n readStringRecord(parseJsonObject(process.env.NEXTCLAW_NARP_STDIO_ENV));\n\n return {\n wireDialect,\n processScope,\n command: override?.command ?? command,\n args,\n ...(cwd ? { cwd } : {}),\n ...(env ? { env } : {}),\n startupTimeoutMs:\n readPositiveInteger(this.source.startupTimeoutMs) ??\n readPositiveInteger(process.env.NEXTCLAW_NARP_STDIO_STARTUP_TIMEOUT_MS) ??\n DEFAULT_STARTUP_TIMEOUT_MS,\n probeTimeoutMs:\n readPositiveInteger(this.source.probeTimeoutMs) ??\n DEFAULT_PROBE_TIMEOUT_MS,\n requestTimeoutMs:\n readPositiveInteger(this.source.requestTimeoutMs) ??\n DEFAULT_REQUEST_TIMEOUT_MS,\n };\n };\n\n private resolveWireDialect = (): StdioRuntimeWireDialect => {\n const wireDialect = readString(this.source.wireDialect) ?? \"acp\";\n if (wireDialect !== \"acp\") {\n throw new Error(`[narp-stdio] unsupported wireDialect \"${wireDialect}\"`);\n }\n return \"acp\";\n };\n\n private resolveProcessScope = (): StdioRuntimeProcessScope => {\n const processScope = readString(this.source.processScope) ?? \"per-session\";\n if (processScope !== \"per-session\") {\n throw new Error(`[narp-stdio] unsupported processScope \"${processScope}\"`);\n }\n return \"per-session\";\n };\n}\n\nexport function buildRuntimeRouteBridgeEnv(params: {\n providerRoute?: NcpProviderRuntimeRoute;\n}): Record<string, string> {\n const { providerRoute } = params;\n if (!providerRoute) {\n return {};\n }\n return {\n [DEFAULT_RUNTIME_ROUTE_BRIDGE_FIELDS.model]: providerRoute.model,\n [DEFAULT_RUNTIME_ROUTE_BRIDGE_FIELDS.apiBase]: providerRoute.apiBase ?? \"\",\n [DEFAULT_RUNTIME_ROUTE_BRIDGE_FIELDS.apiKey]: providerRoute.apiKey ?? \"\",\n [DEFAULT_RUNTIME_ROUTE_BRIDGE_FIELDS.headers]: JSON.stringify(providerRoute.headers ?? {}),\n };\n}\n\nexport function buildStdioRuntimeLaunchEnv(params: {\n baseEnv?: Record<string, string | undefined>;\n configEnv?: StdioRuntimeEnv;\n providerRoute?: NcpProviderRuntimeRoute;\n}): Record<string, string> {\n return {\n ...createRuntimeChildEnv(params.baseEnv ?? process.env, params.configEnv, {\n inheritBaseEnv: true,\n }),\n ...buildRuntimeRouteBridgeEnv({\n providerRoute: params.providerRoute,\n }),\n };\n}\n\nfunction parseJsonArray(value: unknown): unknown {\n if (typeof value !== \"string\" || !value.trim()) {\n return undefined;\n }\n try {\n return JSON.parse(value);\n } catch {\n return undefined;\n }\n}\n\nfunction parseJsonObject(value: unknown): unknown {\n if (typeof value !== \"string\" || !value.trim()) {\n return undefined;\n }\n try {\n return JSON.parse(value);\n } catch {\n return undefined;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"stdio-runtime-config.utils.js","names":[],"sources":["../src/stdio-runtime-config.utils.ts"],"sourcesContent":["import type { OpenAITool, NcpProviderRuntimeRoute } from \"@nextclaw/ncp\";\nimport { createRuntimeChildEnv } from \"@nextclaw/core\";\n\nexport const NARP_STDIO_PROMPT_META_KEY = \"nextclaw_narp\";\nconst DEFAULT_STARTUP_TIMEOUT_MS = 10_000;\nconst DEFAULT_PROBE_TIMEOUT_MS = 3_000;\nconst DEFAULT_REQUEST_TIMEOUT_MS = 120_000;\nconst DEFAULT_RUNTIME_ROUTE_BRIDGE_FIELDS = {\n model: \"NEXTCLAW_MODEL\",\n apiBase: \"NEXTCLAW_API_BASE\",\n apiKey: \"NEXTCLAW_API_KEY\",\n headers: \"NEXTCLAW_HEADERS_JSON\",\n} as const;\n\nexport type StdioRuntimeEnv = Record<string, string>;\nexport type StdioRuntimeWireDialect = \"acp\";\nexport type StdioRuntimeProcessScope = \"per-session\";\n\nexport type NarpStdioPromptMeta = {\n correlationId?: string;\n providerRoute?: NcpProviderRuntimeRoute;\n sessionMetadata?: Record<string, unknown>;\n tools?: ReadonlyArray<OpenAITool>;\n};\n\nexport type StdioRuntimeResolvedConfig = {\n wireDialect: StdioRuntimeWireDialect;\n processScope: StdioRuntimeProcessScope;\n command: string;\n args: string[];\n cwd?: string;\n env?: StdioRuntimeEnv;\n resetSessionMetadataOnPromptTimeout?: string[];\n startupTimeoutMs: number;\n probeTimeoutMs: number;\n requestTimeoutMs: number;\n};\n\ntype StdioRuntimeCommandOverride = {\n command?: string;\n args?: string[];\n cwd?: string;\n env?: StdioRuntimeEnv;\n};\n\nexport function readString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nexport function readPositiveInteger(value: unknown): number | undefined {\n const parsed =\n typeof value === \"number\"\n ? value\n : typeof value === \"string\"\n ? Number.parseInt(value, 10)\n : Number.NaN;\n if (!Number.isFinite(parsed)) {\n return undefined;\n }\n const normalized = Math.trunc(parsed);\n return normalized > 0 ? normalized : undefined;\n}\n\nexport function readStringArray(value: unknown): string[] | undefined {\n if (!Array.isArray(value)) {\n return undefined;\n }\n\n const output: string[] = [];\n for (const entry of value) {\n const normalized = readString(entry);\n if (!normalized) {\n continue;\n }\n output.push(normalized);\n }\n return output.length > 0 ? output : undefined;\n}\n\nexport function readStringRecord(value: unknown): Record<string, string> | undefined {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return undefined;\n }\n\n const output: Record<string, string> = {};\n for (const [entryKey, entryValue] of Object.entries(value)) {\n const normalizedValue = readString(entryValue);\n if (!normalizedValue) {\n continue;\n }\n output[entryKey] = normalizedValue;\n }\n return Object.keys(output).length > 0 ? output : undefined;\n}\n\nfunction readCommandOverrides(value: unknown): Record<string, StdioRuntimeCommandOverride> {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return {};\n }\n\n const overrides: Record<string, StdioRuntimeCommandOverride> = {};\n for (const [rawCommand, rawOverride] of Object.entries(value)) {\n const commandKey = readString(rawCommand);\n if (!commandKey || !rawOverride || typeof rawOverride !== \"object\" || Array.isArray(rawOverride)) {\n continue;\n }\n const overrideRecord = rawOverride as Record<string, unknown>;\n const command = readString(overrideRecord.command);\n const args = readStringArray(overrideRecord.args);\n const cwd = readString(overrideRecord.cwd);\n const env = readStringRecord(overrideRecord.env);\n if (!command && !args && !cwd && !env) {\n continue;\n }\n overrides[commandKey] = {\n ...(command ? { command } : {}),\n ...(args ? { args } : {}),\n ...(cwd ? { cwd } : {}),\n ...(env ? { env } : {}),\n };\n }\n return overrides;\n}\n\nfunction readCommandOverride(command: string): StdioRuntimeCommandOverride | undefined {\n const rawOverrides = parseJsonObject(process.env.NEXTCLAW_NARP_STDIO_COMMAND_OVERRIDES);\n return readCommandOverrides(rawOverrides)[command];\n}\n\nexport class StdioRuntimeConfigResolver {\n constructor(private readonly source: Record<string, unknown> = {}) {}\n\n resolve = (): StdioRuntimeResolvedConfig => {\n const wireDialect = this.resolveWireDialect();\n const processScope = this.resolveProcessScope();\n const command =\n readString(this.source.command) ??\n readString(process.env.NEXTCLAW_NARP_STDIO_COMMAND);\n if (!command) {\n throw new Error(\"[narp-stdio] missing stdio command\");\n }\n\n const override = readCommandOverride(command);\n const args =\n override?.args ??\n readStringArray(this.source.args) ??\n readStringArray(parseJsonArray(process.env.NEXTCLAW_NARP_STDIO_ARGS)) ??\n [];\n const cwd =\n override?.cwd ??\n readString(this.source.cwd) ??\n readString(process.env.NEXTCLAW_NARP_STDIO_CWD);\n const env =\n override?.env ??\n readStringRecord(this.source.env) ??\n readStringRecord(parseJsonObject(process.env.NEXTCLAW_NARP_STDIO_ENV));\n const resetSessionMetadataOnPromptTimeout = readStringArray(\n this.source.resetSessionMetadataOnPromptTimeout,\n );\n\n return {\n wireDialect,\n processScope,\n command: override?.command ?? command,\n args,\n ...(cwd ? { cwd } : {}),\n ...(env ? { env } : {}),\n ...(resetSessionMetadataOnPromptTimeout\n ? { resetSessionMetadataOnPromptTimeout }\n : {}),\n startupTimeoutMs:\n readPositiveInteger(this.source.startupTimeoutMs) ??\n readPositiveInteger(process.env.NEXTCLAW_NARP_STDIO_STARTUP_TIMEOUT_MS) ??\n DEFAULT_STARTUP_TIMEOUT_MS,\n probeTimeoutMs:\n readPositiveInteger(this.source.probeTimeoutMs) ??\n DEFAULT_PROBE_TIMEOUT_MS,\n requestTimeoutMs:\n readPositiveInteger(this.source.requestTimeoutMs) ??\n DEFAULT_REQUEST_TIMEOUT_MS,\n };\n };\n\n private resolveWireDialect = (): StdioRuntimeWireDialect => {\n const wireDialect = readString(this.source.wireDialect) ?? \"acp\";\n if (wireDialect !== \"acp\") {\n throw new Error(`[narp-stdio] unsupported wireDialect \"${wireDialect}\"`);\n }\n return \"acp\";\n };\n\n private resolveProcessScope = (): StdioRuntimeProcessScope => {\n const processScope = readString(this.source.processScope) ?? \"per-session\";\n if (processScope !== \"per-session\") {\n throw new Error(`[narp-stdio] unsupported processScope \"${processScope}\"`);\n }\n return \"per-session\";\n };\n}\n\nexport function buildRuntimeRouteBridgeEnv(params: {\n providerRoute?: NcpProviderRuntimeRoute;\n}): Record<string, string> {\n const { providerRoute } = params;\n if (!providerRoute) {\n return {};\n }\n return {\n [DEFAULT_RUNTIME_ROUTE_BRIDGE_FIELDS.model]: providerRoute.model,\n [DEFAULT_RUNTIME_ROUTE_BRIDGE_FIELDS.apiBase]: providerRoute.apiBase ?? \"\",\n [DEFAULT_RUNTIME_ROUTE_BRIDGE_FIELDS.apiKey]: providerRoute.apiKey ?? \"\",\n [DEFAULT_RUNTIME_ROUTE_BRIDGE_FIELDS.headers]: JSON.stringify(providerRoute.headers ?? {}),\n };\n}\n\nexport function buildStdioRuntimeLaunchEnv(params: {\n baseEnv?: Record<string, string | undefined>;\n configEnv?: StdioRuntimeEnv;\n providerRoute?: NcpProviderRuntimeRoute;\n}): Record<string, string> {\n return {\n ...createRuntimeChildEnv(params.baseEnv ?? process.env, params.configEnv, {\n inheritBaseEnv: true,\n }),\n ...buildRuntimeRouteBridgeEnv({\n providerRoute: params.providerRoute,\n }),\n };\n}\n\nfunction parseJsonArray(value: unknown): unknown {\n if (typeof value !== \"string\" || !value.trim()) {\n return undefined;\n }\n try {\n return JSON.parse(value);\n } catch {\n return undefined;\n }\n}\n\nfunction parseJsonObject(value: unknown): unknown {\n if (typeof value !== \"string\" || !value.trim()) {\n return undefined;\n }\n try {\n return JSON.parse(value);\n } catch {\n return undefined;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stdio-runtime-probe.utils.d.ts","names":[],"sources":["../src/stdio-runtime-probe.utils.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"stdio-runtime-probe.utils.d.ts","names":[],"sources":["../src/stdio-runtime-probe.utils.ts"],"mappings":";;;iBAwBsB,iBAAA,CAAkB,MAAA,EAAQ,0BAAA,GAA6B,OAAA"}
|
|
@@ -3,6 +3,7 @@ import { buildSpawnFailureMessage } from "./stdio-runtime-error.utils.js";
|
|
|
3
3
|
import { spawn } from "node:child_process";
|
|
4
4
|
import { Readable, Writable } from "node:stream";
|
|
5
5
|
import * as acp from "@agentclientprotocol/sdk";
|
|
6
|
+
import { tmpdir } from "node:os";
|
|
6
7
|
//#region src/stdio-runtime-probe.utils.ts
|
|
7
8
|
const createProbeClientBridge = () => ({
|
|
8
9
|
sessionUpdate: async () => void 0,
|
|
@@ -37,16 +38,17 @@ async function probeStdioRuntime(config) {
|
|
|
37
38
|
});
|
|
38
39
|
const stream = acp.ndJsonStream(Writable.toWeb(child.stdin), Readable.toWeb(child.stdout));
|
|
39
40
|
const connection = new acp.ClientSideConnection(() => createProbeClientBridge(), stream);
|
|
41
|
+
const newSessionParams = {
|
|
42
|
+
cwd: config.cwd ?? tmpdir(),
|
|
43
|
+
mcpServers: []
|
|
44
|
+
};
|
|
40
45
|
try {
|
|
41
46
|
const session = await Promise.race([(async () => {
|
|
42
47
|
await withTimeout(connection.initialize({
|
|
43
48
|
protocolVersion: acp.PROTOCOL_VERSION,
|
|
44
49
|
clientCapabilities: {}
|
|
45
50
|
}), config.probeTimeoutMs, `[narp-stdio] probe timed out initializing stdio runtime`);
|
|
46
|
-
return withTimeout(connection.newSession(
|
|
47
|
-
cwd: config.cwd ?? process.cwd(),
|
|
48
|
-
mcpServers: []
|
|
49
|
-
}), config.probeTimeoutMs, `[narp-stdio] probe timed out creating remote session`);
|
|
51
|
+
return withTimeout(connection.newSession(newSessionParams), config.probeTimeoutMs, `[narp-stdio] probe timed out creating remote session`);
|
|
50
52
|
})(), spawnErrorPromise]);
|
|
51
53
|
await connection.cancel({ sessionId: session.sessionId }).catch(() => void 0);
|
|
52
54
|
} catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stdio-runtime-probe.utils.js","names":[],"sources":["../src/stdio-runtime-probe.utils.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport { Readable, Writable } from \"node:stream\";\nimport * as acp from \"@agentclientprotocol/sdk\";\nimport {\n buildStdioRuntimeLaunchEnv,\n type StdioRuntimeResolvedConfig,\n} from \"./stdio-runtime-config.utils.js\";\nimport { buildSpawnFailureMessage } from \"./stdio-runtime-error.utils.js\";\n\ntype ProbeClientBridge = {\n sessionUpdate: (params: { sessionId: string; update: unknown }) => Promise<void>;\n requestPermission: () => Promise<{ outcome: { outcome: \"cancelled\" } }>;\n readTextFile: () => Promise<{ content: string }>;\n writeTextFile: () => Promise<Record<string, never>>;\n};\n\nconst createProbeClientBridge = (): ProbeClientBridge => ({\n sessionUpdate: async () => undefined,\n requestPermission: async () => ({ outcome: { outcome: \"cancelled\" } }),\n readTextFile: async () => ({ content: \"\" }),\n writeTextFile: async () => ({}),\n});\n\nexport async function probeStdioRuntime(config: StdioRuntimeResolvedConfig): Promise<void> {\n const child = spawn(config.command, config.args, {\n cwd: config.cwd,\n env: buildStdioRuntimeLaunchEnv({\n configEnv: config.env,\n }),\n stdio: [\"pipe\", \"pipe\", \"pipe\"], windowsHide: true,\n });\n const spawnErrorPromise = new Promise<never>((_, reject) => {\n child.once(\"error\", (error) => {\n reject(new Error(buildSpawnFailureMessage({ command: config.command, cwd: config.cwd, error })));\n });\n });\n\n let stderr = \"\";\n child.stderr.setEncoding(\"utf8\");\n child.stderr.on(\"data\", (chunk: string) => {\n stderr = `${stderr}${chunk}`.slice(-4000);\n });\n\n const stream = acp.ndJsonStream(\n Writable.toWeb(child.stdin),\n Readable.toWeb(child.stdout),\n );\n const connection = new acp.ClientSideConnection(\n () => createProbeClientBridge(),\n stream,\n );\n\n try {\n const session = await Promise.race([\n (async () => {\n await withTimeout(\n connection.initialize({\n protocolVersion: acp.PROTOCOL_VERSION,\n clientCapabilities: {},\n }),\n config.probeTimeoutMs,\n `[narp-stdio] probe timed out initializing stdio runtime`,\n );\n return withTimeout(\n connection.newSession(
|
|
1
|
+
{"version":3,"file":"stdio-runtime-probe.utils.js","names":[],"sources":["../src/stdio-runtime-probe.utils.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport { tmpdir } from \"node:os\";\nimport { Readable, Writable } from \"node:stream\";\nimport * as acp from \"@agentclientprotocol/sdk\";\nimport {\n buildStdioRuntimeLaunchEnv,\n type StdioRuntimeResolvedConfig,\n} from \"./stdio-runtime-config.utils.js\";\nimport { buildSpawnFailureMessage } from \"./stdio-runtime-error.utils.js\";\n\ntype ProbeClientBridge = {\n sessionUpdate: (params: { sessionId: string; update: unknown }) => Promise<void>;\n requestPermission: () => Promise<{ outcome: { outcome: \"cancelled\" } }>;\n readTextFile: () => Promise<{ content: string }>;\n writeTextFile: () => Promise<Record<string, never>>;\n};\n\nconst createProbeClientBridge = (): ProbeClientBridge => ({\n sessionUpdate: async () => undefined,\n requestPermission: async () => ({ outcome: { outcome: \"cancelled\" } }),\n readTextFile: async () => ({ content: \"\" }),\n writeTextFile: async () => ({}),\n});\n\nexport async function probeStdioRuntime(config: StdioRuntimeResolvedConfig): Promise<void> {\n const child = spawn(config.command, config.args, {\n cwd: config.cwd,\n env: buildStdioRuntimeLaunchEnv({\n configEnv: config.env,\n }),\n stdio: [\"pipe\", \"pipe\", \"pipe\"], windowsHide: true,\n });\n const spawnErrorPromise = new Promise<never>((_, reject) => {\n child.once(\"error\", (error) => {\n reject(new Error(buildSpawnFailureMessage({ command: config.command, cwd: config.cwd, error })));\n });\n });\n\n let stderr = \"\";\n child.stderr.setEncoding(\"utf8\");\n child.stderr.on(\"data\", (chunk: string) => {\n stderr = `${stderr}${chunk}`.slice(-4000);\n });\n\n const stream = acp.ndJsonStream(\n Writable.toWeb(child.stdin),\n Readable.toWeb(child.stdout),\n );\n const connection = new acp.ClientSideConnection(\n () => createProbeClientBridge(),\n stream,\n );\n const newSessionParams = {\n cwd: config.cwd ?? tmpdir(),\n mcpServers: [],\n };\n\n try {\n const session = await Promise.race([\n (async () => {\n await withTimeout(\n connection.initialize({\n protocolVersion: acp.PROTOCOL_VERSION,\n clientCapabilities: {},\n }),\n config.probeTimeoutMs,\n `[narp-stdio] probe timed out initializing stdio runtime`,\n );\n return withTimeout(\n connection.newSession(newSessionParams),\n config.probeTimeoutMs,\n `[narp-stdio] probe timed out creating remote session`,\n );\n })(),\n spawnErrorPromise,\n ]);\n await connection.cancel({ sessionId: session.sessionId }).catch(() => undefined);\n } catch (error) {\n const message =\n error instanceof Error ? error.message : \"[narp-stdio] stdio runtime probe failed\";\n throw new Error(`${message}. stderr=${stderr}`.trim());\n } finally {\n child.kill(\"SIGTERM\");\n }\n}\n\nasync function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n message: string,\n): Promise<T> {\n let timeoutHandle: NodeJS.Timeout | undefined;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutHandle = setTimeout(() => reject(new Error(message)), timeoutMs);\n });\n try {\n return await Promise.race([promise, timeoutPromise]);\n } finally {\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n }\n}\n"],"mappings":";;;;;;;AAiBA,MAAM,iCAAoD;CACxD,eAAe,YAAY,KAAA;CAC3B,mBAAmB,aAAa,EAAE,SAAS,EAAE,SAAS,aAAa,EAAE;CACrE,cAAc,aAAa,EAAE,SAAS,IAAI;CAC1C,eAAe,aAAa,EAAE;CAC/B;AAED,eAAsB,kBAAkB,QAAmD;CACzF,MAAM,QAAQ,MAAM,OAAO,SAAS,OAAO,MAAM;EAC/C,KAAK,OAAO;EACZ,KAAK,2BAA2B,EAC9B,WAAW,OAAO,KACnB,CAAC;EACF,OAAO;GAAC;GAAQ;GAAQ;GAAO;EAAE,aAAa;EAC/C,CAAC;CACF,MAAM,oBAAoB,IAAI,SAAgB,GAAG,WAAW;AAC1D,QAAM,KAAK,UAAU,UAAU;AAC7B,UAAO,IAAI,MAAM,yBAAyB;IAAE,SAAS,OAAO;IAAS,KAAK,OAAO;IAAK;IAAO,CAAC,CAAC,CAAC;IAChG;GACF;CAEF,IAAI,SAAS;AACb,OAAM,OAAO,YAAY,OAAO;AAChC,OAAM,OAAO,GAAG,SAAS,UAAkB;AACzC,WAAS,GAAG,SAAS,QAAQ,MAAM,KAAM;GACzC;CAEF,MAAM,SAAS,IAAI,aACjB,SAAS,MAAM,MAAM,MAAM,EAC3B,SAAS,MAAM,MAAM,OAAO,CAC7B;CACD,MAAM,aAAa,IAAI,IAAI,2BACnB,yBAAyB,EAC/B,OACD;CACD,MAAM,mBAAmB;EACvB,KAAK,OAAO,OAAO,QAAQ;EAC3B,YAAY,EAAE;EACf;AAED,KAAI;EACF,MAAM,UAAU,MAAM,QAAQ,KAAK,EAChC,YAAY;AACX,SAAM,YACJ,WAAW,WAAW;IACpB,iBAAiB,IAAI;IACrB,oBAAoB,EAAE;IACvB,CAAC,EACF,OAAO,gBACP,0DACD;AACD,UAAO,YACL,WAAW,WAAW,iBAAiB,EACvC,OAAO,gBACP,uDACD;MACC,EACJ,kBACD,CAAC;AACF,QAAM,WAAW,OAAO,EAAE,WAAW,QAAQ,WAAW,CAAC,CAAC,YAAY,KAAA,EAAU;UACzE,OAAO;EACd,MAAM,UACJ,iBAAiB,QAAQ,MAAM,UAAU;AAC3C,QAAM,IAAI,MAAM,GAAG,QAAQ,WAAW,SAAS,MAAM,CAAC;WAC9C;AACR,QAAM,KAAK,UAAU;;;AAIzB,eAAe,YACb,SACA,WACA,SACY;CACZ,IAAI;CACJ,MAAM,iBAAiB,IAAI,SAAgB,GAAG,WAAW;AACvD,kBAAgB,iBAAiB,OAAO,IAAI,MAAM,QAAQ,CAAC,EAAE,UAAU;GACvE;AACF,KAAI;AACF,SAAO,MAAM,QAAQ,KAAK,CAAC,SAAS,eAAe,CAAC;WAC5C;AACR,MAAI,cACF,cAAa,cAAc"}
|
|
@@ -3,7 +3,6 @@ import { NcpAgentConversationStateManager, NcpAgentRunInput, NcpAgentRunOptions,
|
|
|
3
3
|
|
|
4
4
|
//#region src/stdio-runtime.service.d.ts
|
|
5
5
|
type StdioRuntimeNcpAgentRuntimeConfig = StdioRuntimeResolvedConfig & {
|
|
6
|
-
sessionId: string;
|
|
7
6
|
stateManager?: NcpAgentConversationStateManager;
|
|
8
7
|
resolveTools?: (input: NcpAgentRunInput) => ReadonlyArray<OpenAITool> | undefined;
|
|
9
8
|
resolveProviderRoute?: (input: NcpAgentRunInput) => NcpProviderRuntimeRoute | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stdio-runtime.service.d.ts","names":[],"sources":["../src/stdio-runtime.service.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"stdio-runtime.service.d.ts","names":[],"sources":["../src/stdio-runtime.service.ts"],"mappings":";;;;KAgCY,iCAAA,GAAoC,0BAAA;EAC9C,YAAA,GAAe,gCAAA;EACf,YAAA,IAAgB,KAAA,EAAO,gBAAA,KAAqB,aAAA,CAAc,UAAA;EAC1D,oBAAA,IAAwB,KAAA,EAAO,gBAAA,KAAqB,uBAAA;AAAA;AAAA,cAq0BzC,2BAAA,YAAuC,eAAA;EAAA,iBAGrB,MAAA;EAAA,iBAFZ,OAAA;cAEY,MAAA,EAAQ,iCAAA;EAIrC,GAAA,GACE,IAAA,EAAM,2BAAA,EACN,KAAA,EAAO,gBAAA,EACP,OAAA,GAAU,kBAAA,KACT,cAAA,CAAe,gBAAA;EAelB,OAAA,QAAoB,OAAA;AAAA"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { NARP_STDIO_PROMPT_META_KEY, buildStdioRuntimeLaunchEnv
|
|
1
|
+
import { NARP_STDIO_PROMPT_META_KEY, buildStdioRuntimeLaunchEnv } from "./stdio-runtime-config.utils.js";
|
|
2
2
|
import { buildSpawnFailureMessage, isAbortLikeRuntimeError, normalizeRuntimeError } from "./stdio-runtime-error.utils.js";
|
|
3
|
+
import { SESSION_METADATA_PATCH_KIND, createPromptTimeoutRecoveryEvents } from "./utils/stdio-runtime-recovery.utils.js";
|
|
4
|
+
import { extractPromptText, resolveModelId } from "./utils/stdio-runtime-input.utils.js";
|
|
3
5
|
import { resolveToolNameFromAcpUpdate } from "./stdio-runtime-tool-name.utils.js";
|
|
4
6
|
import { randomUUID } from "node:crypto";
|
|
5
7
|
import { spawn } from "node:child_process";
|
|
@@ -8,7 +10,6 @@ import * as acp from "@agentclientprotocol/sdk";
|
|
|
8
10
|
import { NcpEventType } from "@nextclaw/ncp";
|
|
9
11
|
//#region src/stdio-runtime.service.ts
|
|
10
12
|
const HERMES_ACP_ROUTE_BRIDGE_ENV = "NEXTCLAW_HERMES_ACP_ROUTE_BRIDGE";
|
|
11
|
-
const SESSION_METADATA_PATCH_KIND = "session_metadata_patch";
|
|
12
13
|
var UpdateBuffer = class {
|
|
13
14
|
updates = [];
|
|
14
15
|
waiters = /* @__PURE__ */ new Set();
|
|
@@ -158,16 +159,21 @@ var StdioRuntimeSession = class {
|
|
|
158
159
|
connection = null;
|
|
159
160
|
promptInFlight = false;
|
|
160
161
|
remoteSessionId = null;
|
|
162
|
+
remoteSessionCwd = null;
|
|
161
163
|
clientBridge = new StdioRuntimeClientBridge();
|
|
162
164
|
stderr = "";
|
|
163
165
|
pendingProviderRoute;
|
|
164
|
-
constructor(config
|
|
166
|
+
constructor(config) {
|
|
165
167
|
this.config = config;
|
|
166
|
-
this.sessionId = sessionId;
|
|
167
168
|
}
|
|
168
169
|
ensureStarted = async (params) => {
|
|
169
|
-
|
|
170
|
-
|
|
170
|
+
const { cwd, providerRoute } = params;
|
|
171
|
+
this.pendingProviderRoute = providerRoute;
|
|
172
|
+
if (this.connection && this.remoteSessionId) {
|
|
173
|
+
if (this.remoteSessionCwd === cwd) return;
|
|
174
|
+
await this.dispose();
|
|
175
|
+
}
|
|
176
|
+
if (!cwd) throw new Error("[narp-stdio] missing execution cwd for stdio runtime session");
|
|
171
177
|
const env = buildStdioRuntimeLaunchEnv({
|
|
172
178
|
configEnv: this.config.env,
|
|
173
179
|
providerRoute: this.pendingProviderRoute
|
|
@@ -201,15 +207,16 @@ var StdioRuntimeSession = class {
|
|
|
201
207
|
await withTimeout(this.connection?.initialize({
|
|
202
208
|
protocolVersion: acp.PROTOCOL_VERSION,
|
|
203
209
|
clientCapabilities: {}
|
|
204
|
-
}) ?? Promise.reject(/* @__PURE__ */ new Error("[narp-stdio] stdio runtime connection not started")), this.config.startupTimeoutMs,
|
|
210
|
+
}) ?? Promise.reject(/* @__PURE__ */ new Error("[narp-stdio] stdio runtime connection not started")), this.config.startupTimeoutMs, "[narp-stdio] timed out initializing stdio runtime");
|
|
205
211
|
return withTimeout(this.connection?.newSession({
|
|
206
|
-
cwd
|
|
212
|
+
cwd,
|
|
207
213
|
mcpServers: []
|
|
208
|
-
}) ?? Promise.reject(/* @__PURE__ */ new Error("[narp-stdio] stdio runtime connection not started")), this.config.startupTimeoutMs,
|
|
214
|
+
}) ?? Promise.reject(/* @__PURE__ */ new Error("[narp-stdio] stdio runtime connection not started")), this.config.startupTimeoutMs, "[narp-stdio] timed out creating remote stdio session");
|
|
209
215
|
})(), spawnErrorPromise])).sessionId;
|
|
216
|
+
this.remoteSessionCwd = cwd;
|
|
210
217
|
};
|
|
211
218
|
runPrompt = async (params) => {
|
|
212
|
-
const { meta, modelId, onUpdate, signal, text } = params;
|
|
219
|
+
const { meta, modelId, onUpdate, sessionId, signal, text } = params;
|
|
213
220
|
if (!this.connection || !this.remoteSessionId) throw new Error("[narp-stdio] stdio runtime connection not started");
|
|
214
221
|
if (this.promptInFlight) throw new Error("[narp-stdio] concurrent prompt is not supported for one stdio session");
|
|
215
222
|
this.promptInFlight = true;
|
|
@@ -232,7 +239,7 @@ var StdioRuntimeSession = class {
|
|
|
232
239
|
text
|
|
233
240
|
}],
|
|
234
241
|
_meta: { [NARP_STDIO_PROMPT_META_KEY]: meta }
|
|
235
|
-
}), this.config.requestTimeoutMs, `[narp-stdio] prompt timed out for session ${
|
|
242
|
+
}), this.config.requestTimeoutMs, `[narp-stdio] prompt timed out for session ${sessionId}`);
|
|
236
243
|
} finally {
|
|
237
244
|
releaseAbort();
|
|
238
245
|
detach();
|
|
@@ -260,20 +267,26 @@ var StdioRuntimeSession = class {
|
|
|
260
267
|
};
|
|
261
268
|
};
|
|
262
269
|
readStderr = () => this.stderr;
|
|
270
|
+
readPromptTimeoutMetadataResetKeys = () => this.config.resetSessionMetadataOnPromptTimeout;
|
|
263
271
|
dispose = async () => {
|
|
264
272
|
await this.cancel();
|
|
265
273
|
const child = this.child;
|
|
266
274
|
this.connection = null;
|
|
267
275
|
this.remoteSessionId = null;
|
|
276
|
+
this.remoteSessionCwd = null;
|
|
268
277
|
this.child = null;
|
|
269
278
|
if (!child || child.killed || child.exitCode !== null || child.signalCode !== null) return;
|
|
279
|
+
const exited = new Promise((resolve) => {
|
|
280
|
+
child.once("exit", () => resolve());
|
|
281
|
+
child.once("error", () => resolve());
|
|
282
|
+
});
|
|
270
283
|
const forceKill = setTimeout(() => {
|
|
271
284
|
child.kill("SIGKILL");
|
|
272
285
|
}, 3e3);
|
|
273
|
-
|
|
274
|
-
clearTimeout(forceKill);
|
|
275
|
-
});
|
|
286
|
+
forceKill.unref();
|
|
276
287
|
child.kill("SIGTERM");
|
|
288
|
+
await exited;
|
|
289
|
+
clearTimeout(forceKill);
|
|
277
290
|
};
|
|
278
291
|
};
|
|
279
292
|
var StdioRuntimeRunController = class {
|
|
@@ -300,6 +313,7 @@ var StdioRuntimeRunController = class {
|
|
|
300
313
|
if (!requestMessage) throw new Error("[narp-stdio] runtime.run requires at least one input message");
|
|
301
314
|
const assistantMessageId = createAssistantMessageId(requestMessage.id);
|
|
302
315
|
const promptPromise = this.session.runPrompt({
|
|
316
|
+
sessionId: this.input.sessionId,
|
|
303
317
|
text: extractPromptText(requestMessage),
|
|
304
318
|
meta: {
|
|
305
319
|
...this.input.correlationId ? { correlationId: this.input.correlationId } : {},
|
|
@@ -398,6 +412,14 @@ var StdioRuntimeRunController = class {
|
|
|
398
412
|
};
|
|
399
413
|
emitFailureEvents = async function* (assistantMessageId, error) {
|
|
400
414
|
const ncpError = normalizeRuntimeError(error, { stderr: this.session.readStderr() });
|
|
415
|
+
for (const recoveryEvent of createPromptTimeoutRecoveryEvents({
|
|
416
|
+
correlationId: this.input.correlationId,
|
|
417
|
+
error,
|
|
418
|
+
messageId: assistantMessageId,
|
|
419
|
+
resetKeys: this.session.readPromptTimeoutMetadataResetKeys(),
|
|
420
|
+
runId: this.runId,
|
|
421
|
+
sessionId: this.input.sessionId
|
|
422
|
+
})) yield* this.emitEvent(recoveryEvent);
|
|
401
423
|
yield* this.emitEvent({
|
|
402
424
|
type: NcpEventType.MessageFailed,
|
|
403
425
|
payload: {
|
|
@@ -597,28 +619,19 @@ var StdioRuntimeNcpAgentRuntime = class {
|
|
|
597
619
|
session;
|
|
598
620
|
constructor(config) {
|
|
599
621
|
this.config = config;
|
|
600
|
-
this.session = new StdioRuntimeSession(config
|
|
622
|
+
this.session = new StdioRuntimeSession(config);
|
|
601
623
|
}
|
|
602
624
|
run = async function* (input, options) {
|
|
603
|
-
await this.session.ensureStarted({
|
|
625
|
+
await this.session.ensureStarted({
|
|
626
|
+
cwd: input.executionContext?.cwd,
|
|
627
|
+
providerRoute: this.config.resolveProviderRoute?.(input)
|
|
628
|
+
});
|
|
604
629
|
yield* new StdioRuntimeRunController(this.session, input, this.config.stateManager, this.config.resolveTools, this.config.resolveProviderRoute).execute(options);
|
|
605
630
|
};
|
|
606
631
|
dispose = async () => {
|
|
607
632
|
await this.session.dispose();
|
|
608
633
|
};
|
|
609
634
|
};
|
|
610
|
-
function extractPromptText(message) {
|
|
611
|
-
const text = (message.parts ?? []).map((part) => {
|
|
612
|
-
if (part.type === "text" || part.type === "reasoning" || part.type === "rich-text") return part.text ?? "";
|
|
613
|
-
return "";
|
|
614
|
-
}).join("\n").trim();
|
|
615
|
-
return text.length > 0 ? text : "[empty message]";
|
|
616
|
-
}
|
|
617
|
-
function resolveModelId(params) {
|
|
618
|
-
const { metadata, providerRoute } = params;
|
|
619
|
-
const modelId = providerRoute?.model ?? readString(metadata?.preferred_model) ?? readString(metadata?.preferredModel) ?? readString(metadata?.model);
|
|
620
|
-
return modelId === "__nextclaw_runtime_default__" ? void 0 : modelId;
|
|
621
|
-
}
|
|
622
635
|
function readSessionMetadataPatch(meta) {
|
|
623
636
|
const narpMeta = isRecord(meta) ? meta[NARP_STDIO_PROMPT_META_KEY] : void 0;
|
|
624
637
|
const patch = isRecord(narpMeta) ? narpMeta.sessionMetadataPatch : void 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stdio-runtime.service.js","names":[],"sources":["../src/stdio-runtime.service.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { spawn, type ChildProcessWithoutNullStreams } from \"node:child_process\";\nimport { Readable, Writable } from \"node:stream\";\nimport * as acp from \"@agentclientprotocol/sdk\";\nimport {\n NcpEventType,\n type NcpAgentConversationStateManager,\n type NcpAgentRunInput,\n type NcpAgentRunOptions,\n type NcpAgentRuntime,\n type NcpEndpointEvent,\n type NcpProviderRuntimeRoute,\n type OpenAITool,\n} from \"@nextclaw/ncp\";\nimport type { StdioRuntimeResolvedConfig, NarpStdioPromptMeta } from \"./stdio-runtime-config.utils.js\";\nimport {\n NARP_STDIO_PROMPT_META_KEY,\n buildStdioRuntimeLaunchEnv,\n readString,\n} from \"./stdio-runtime-config.utils.js\";\nimport {\n buildSpawnFailureMessage,\n isAbortLikeRuntimeError,\n normalizeRuntimeError,\n} from \"./stdio-runtime-error.utils.js\";\nimport { resolveToolNameFromAcpUpdate } from \"./stdio-runtime-tool-name.utils.js\";\ntype AcpClientUpdate = acp.SessionUpdate;\nconst HERMES_ACP_ROUTE_BRIDGE_ENV = \"NEXTCLAW_HERMES_ACP_ROUTE_BRIDGE\";\nconst SESSION_METADATA_PATCH_KIND = \"session_metadata_patch\";\nexport type StdioRuntimeNcpAgentRuntimeConfig = StdioRuntimeResolvedConfig & {\n sessionId: string;\n stateManager?: NcpAgentConversationStateManager;\n resolveTools?: (input: NcpAgentRunInput) => ReadonlyArray<OpenAITool> | undefined;\n resolveProviderRoute?: (input: NcpAgentRunInput) => NcpProviderRuntimeRoute | undefined;\n};\ntype AcpToolState = {\n toolName: string;\n args?: string;\n completed: boolean;\n};\n\ntype PromptExecutionState = { settled: boolean; error: unknown };\n\nclass UpdateBuffer {\n private readonly updates: AcpClientUpdate[] = [];\n private waiters = new Set<() => void>();\n\n push = (update: AcpClientUpdate): void => {\n this.updates.push(update);\n this.flush();\n };\n\n shift = (): AcpClientUpdate | undefined => this.updates.shift();\n\n hasItems = (): boolean => this.updates.length > 0;\n\n waitForChange = async (): Promise<void> => {\n if (this.updates.length > 0) {\n return;\n }\n await new Promise<void>((resolve) => {\n this.waiters.add(resolve);\n });\n };\n\n notify = (): void => {\n this.flush();\n };\n\n private flush = (): void => {\n if (this.waiters.size === 0) {\n return;\n }\n const waiters = [...this.waiters];\n this.waiters.clear();\n for (const waiter of waiters) {\n waiter();\n }\n };\n}\n\nclass PromptUpdateCollector {\n private readonly parts: Array<\n | { type: \"text\"; text: string }\n | { type: \"reasoning\"; text: string }\n | { type: \"tool-invocation\"; toolCallId: string; toolName: string; state: \"partial-call\" | \"call\"; args: string }\n > = [];\n private readonly toolIndex = new Map<string, number>();\n\n apply = (event: NcpEndpointEvent): void => {\n switch (event.type) {\n case NcpEventType.MessageTextDelta:\n this.appendPart(\"text\", event.payload.delta);\n return;\n case NcpEventType.MessageReasoningDelta:\n this.appendPart(\"reasoning\", event.payload.delta);\n return;\n case NcpEventType.MessageToolCallStart:\n this.upsertTool({\n toolCallId: event.payload.toolCallId,\n toolName: event.payload.toolName,\n args: \"\",\n state: \"partial-call\",\n });\n return;\n case NcpEventType.MessageToolCallArgs:\n {\n const tool = this.readTool(event.payload.toolCallId);\n this.upsertTool({\n toolCallId: event.payload.toolCallId,\n toolName: tool.toolName,\n args: event.payload.args,\n state: \"partial-call\",\n });\n }\n return;\n case NcpEventType.MessageToolCallArgsDelta:\n {\n const tool = this.readTool(event.payload.toolCallId);\n this.upsertTool({\n toolCallId: event.payload.toolCallId,\n toolName: tool.toolName,\n args: `${tool.args}${event.payload.delta}`,\n state: \"partial-call\",\n });\n }\n return;\n case NcpEventType.MessageToolCallEnd:\n {\n const tool = this.readTool(event.payload.toolCallId);\n this.upsertTool({\n toolCallId: event.payload.toolCallId,\n toolName: tool.toolName,\n args: tool.args,\n state: \"call\",\n });\n }\n return;\n default:\n return;\n }\n };\n\n hasParts = (): boolean => this.parts.length > 0;\n\n buildParts = (): Array<Record<string, unknown>> => structuredClone(this.parts);\n\n private appendPart = (type: \"text\" | \"reasoning\", text: string): void => {\n if (!text) {\n return;\n }\n const last = this.parts.at(-1);\n if (last?.type === type) {\n last.text = `${last.text}${text}`;\n return;\n }\n this.parts.push({ type, text });\n };\n\n private upsertTool = (nextTool: {\n toolCallId: string;\n toolName: string;\n args: string;\n state: \"partial-call\" | \"call\";\n }): void => {\n const existingIndex = this.toolIndex.get(nextTool.toolCallId);\n if (typeof existingIndex === \"number\") {\n const existing = this.parts[existingIndex];\n if (existing?.type !== \"tool-invocation\") {\n return;\n }\n this.parts[existingIndex] = {\n ...existing,\n ...nextTool,\n };\n return;\n }\n\n this.toolIndex.set(nextTool.toolCallId, this.parts.length);\n this.parts.push({\n type: \"tool-invocation\",\n ...nextTool,\n });\n };\n\n private readTool = (toolCallId: string): { toolName: string; args: string } => {\n const index = this.toolIndex.get(toolCallId);\n const part = typeof index === \"number\" ? this.parts[index] : null;\n if (part?.type !== \"tool-invocation\") {\n return { toolName: \"unknown\", args: \"\" };\n }\n return { toolName: part.toolName, args: part.args };\n };\n}\n\nclass StdioRuntimeClientBridge {\n private activeSessionId: string | null = null;\n private updateHandler: ((update: AcpClientUpdate) => void) | null = null;\n\n attach = (params: {\n sessionId: string;\n onUpdate: (update: AcpClientUpdate) => void;\n }): (() => void) => {\n this.activeSessionId = params.sessionId;\n this.updateHandler = params.onUpdate;\n return () => {\n if (this.activeSessionId !== params.sessionId) {\n return;\n }\n this.activeSessionId = null;\n this.updateHandler = null;\n };\n };\n\n sessionUpdate = async (params: { sessionId: string; update: AcpClientUpdate }): Promise<void> => {\n if (params.sessionId !== this.activeSessionId) {\n return;\n }\n this.updateHandler?.(params.update);\n };\n\n requestPermission = async (): Promise<{\n outcome: { outcome: \"cancelled\" };\n }> => ({\n outcome: { outcome: \"cancelled\" },\n });\n\n readTextFile = async (): Promise<{ content: string }> => ({ content: \"\" });\n\n writeTextFile = async (): Promise<Record<string, never>> => ({});\n}\n\nclass StdioRuntimeSession {\n private child: ChildProcessWithoutNullStreams | null = null;\n private connection: acp.ClientSideConnection | null = null;\n private promptInFlight = false;\n private remoteSessionId: string | null = null;\n private readonly clientBridge = new StdioRuntimeClientBridge();\n private stderr = \"\";\n private pendingProviderRoute: NcpProviderRuntimeRoute | undefined;\n\n constructor(\n private readonly config: StdioRuntimeResolvedConfig,\n private readonly sessionId: string,\n ) {}\n\n ensureStarted = async (params?: {\n providerRoute?: NcpProviderRuntimeRoute;\n }): Promise<void> => {\n this.pendingProviderRoute = params?.providerRoute;\n if (this.connection && this.remoteSessionId) {\n return;\n }\n\n const env = buildStdioRuntimeLaunchEnv({\n configEnv: this.config.env,\n providerRoute: this.pendingProviderRoute,\n });\n\n this.child = spawn(this.config.command, this.config.args, {\n cwd: this.config.cwd,\n env,\n stdio: [\"pipe\", \"pipe\", \"pipe\"], windowsHide: true,\n });\n const spawnErrorPromise = new Promise<never>((_, reject) => {\n this.child?.once(\"error\", (error) => {\n reject(\n new Error(\n buildSpawnFailureMessage({\n command: this.config.command,\n cwd: this.config.cwd,\n error,\n }),\n ),\n );\n });\n });\n this.child.stderr.setEncoding(\"utf8\");\n this.child.stderr.on(\"data\", (chunk: string) => {\n this.stderr = `${this.stderr}${chunk}`.slice(-4000);\n });\n\n const stream = acp.ndJsonStream(\n Writable.toWeb(this.child.stdin),\n Readable.toWeb(this.child.stdout),\n );\n this.connection = new acp.ClientSideConnection(() => this.clientBridge, stream);\n\n const session = await Promise.race([\n (async () => {\n await withTimeout(\n this.connection?.initialize({\n protocolVersion: acp.PROTOCOL_VERSION,\n clientCapabilities: {},\n }) ?? Promise.reject(new Error(\"[narp-stdio] stdio runtime connection not started\")),\n this.config.startupTimeoutMs,\n `[narp-stdio] timed out initializing stdio runtime for session ${this.sessionId}`,\n );\n\n return withTimeout(\n this.connection?.newSession({\n cwd: this.config.cwd ?? process.cwd(),\n mcpServers: [],\n }) ?? Promise.reject(new Error(\"[narp-stdio] stdio runtime connection not started\")),\n this.config.startupTimeoutMs,\n `[narp-stdio] timed out creating remote session for ${this.sessionId}`,\n );\n })(),\n spawnErrorPromise,\n ]);\n this.remoteSessionId = session.sessionId;\n };\n\n runPrompt = async (params: {\n text: string;\n meta: NarpStdioPromptMeta;\n modelId?: string;\n signal?: AbortSignal;\n onUpdate: (update: AcpClientUpdate) => void;\n }): Promise<acp.PromptResponse> => {\n const { meta, modelId, onUpdate, signal, text } = params;\n if (!this.connection || !this.remoteSessionId) {\n throw new Error(\"[narp-stdio] stdio runtime connection not started\");\n }\n if (this.promptInFlight) {\n throw new Error(\"[narp-stdio] concurrent prompt is not supported for one stdio session\");\n }\n\n this.promptInFlight = true;\n const detach = this.clientBridge.attach({\n sessionId: this.remoteSessionId,\n onUpdate,\n });\n const releaseAbort = this.bindAbortSignal(signal);\n\n try {\n if (modelId && this.config.env?.[HERMES_ACP_ROUTE_BRIDGE_ENV] !== \"1\") {\n try {\n // Hermes ACP must switch on prompt-scoped providerRoute, not modelId alone.\n await this.connection.unstable_setSessionModel({\n sessionId: this.remoteSessionId,\n modelId,\n });\n } catch {\n // Not all ACP agents implement unstable session model switching.\n }\n }\n\n return await withTimeout(\n this.connection.prompt({\n sessionId: this.remoteSessionId,\n prompt: [{ type: \"text\", text }],\n _meta: {\n [NARP_STDIO_PROMPT_META_KEY]: meta,\n },\n }),\n this.config.requestTimeoutMs,\n `[narp-stdio] prompt timed out for session ${this.sessionId}`,\n );\n } finally {\n releaseAbort();\n detach();\n this.promptInFlight = false;\n }\n };\n\n cancel = async (): Promise<void> => {\n if (!this.connection || !this.remoteSessionId) {\n return;\n }\n try {\n await this.connection.cancel({\n sessionId: this.remoteSessionId,\n });\n } catch {\n // Best effort.\n }\n };\n\n private bindAbortSignal = (signal?: AbortSignal): (() => void) => {\n if (!signal) {\n return () => undefined;\n }\n\n const onAbort = (): void => {\n void this.cancel();\n };\n\n if (signal.aborted) {\n onAbort();\n return () => undefined;\n }\n\n signal.addEventListener(\"abort\", onAbort, { once: true });\n return () => {\n signal.removeEventListener(\"abort\", onAbort);\n };\n };\n\n readStderr = (): string => this.stderr;\n\n dispose = async (): Promise<void> => {\n await this.cancel();\n const child = this.child;\n this.connection = null;\n this.remoteSessionId = null;\n this.child = null;\n if (!child || child.killed || child.exitCode !== null || child.signalCode !== null) {\n return;\n }\n\n const forceKill = setTimeout(() => {\n child.kill(\"SIGKILL\");\n }, 3_000);\n child.once(\"exit\", () => {\n clearTimeout(forceKill);\n });\n child.kill(\"SIGTERM\");\n };\n}\n\nclass StdioRuntimeRunController {\n private readonly buffer = new UpdateBuffer();\n private readonly collector = new PromptUpdateCollector();\n private readonly toolStates = new Map<string, AcpToolState>();\n private textStarted = false;\n private reasoningStarted = false;\n private readonly resolvedTools: ReadonlyArray<OpenAITool>;\n private readonly resolvedProviderRoute: NcpProviderRuntimeRoute | undefined;\n private readonly runId: string;\n\n constructor(\n private readonly session: StdioRuntimeSession,\n private readonly input: NcpAgentRunInput,\n private readonly stateManager?: NcpAgentConversationStateManager,\n private readonly resolveTools?: (input: NcpAgentRunInput) => ReadonlyArray<OpenAITool> | undefined,\n private readonly resolveProviderRoute?: (input: NcpAgentRunInput) => NcpProviderRuntimeRoute | undefined,\n ) {\n this.resolvedTools = resolveTools?.(input) ?? [];\n this.resolvedProviderRoute = resolveProviderRoute?.(input);\n this.runId = (input as NcpAgentRunInput & { runId?: string }).runId ?? `narp-stdio:${input.sessionId}:${randomUUID()}`;\n }\n execute = async function* (\n this: StdioRuntimeRunController,\n options?: NcpAgentRunOptions,\n ): AsyncGenerator<NcpEndpointEvent> {\n const requestMessage = this.input.messages.at(-1);\n if (!requestMessage) {\n throw new Error(\"[narp-stdio] runtime.run requires at least one input message\");\n }\n\n const assistantMessageId = createAssistantMessageId(requestMessage.id);\n const promptPromise = this.session.runPrompt({\n text: extractPromptText(requestMessage),\n meta: {\n ...(this.input.correlationId ? { correlationId: this.input.correlationId } : {}),\n ...(this.resolvedProviderRoute ? { providerRoute: this.resolvedProviderRoute } : {}),\n ...(this.input.metadata ? { sessionMetadata: this.input.metadata } : {}),\n ...(this.resolvedTools.length > 0 ? { tools: this.resolvedTools } : {}),\n },\n modelId: resolveModelId({\n providerRoute: this.resolvedProviderRoute,\n metadata: this.input.metadata,\n }),\n signal: options?.signal,\n onUpdate: (update) => this.buffer.push(update),\n });\n const promptState = this.trackPromptState(promptPromise);\n\n yield* this.emitRunStartedEvents(assistantMessageId);\n\n try {\n yield* this.drainPromptUpdates(assistantMessageId, promptState);\n if (this.shouldExitForAbort(options, promptState.error)) {\n return;\n }\n if (promptState.error) throw promptState.error;\n yield* this.emitCompletionEvents(assistantMessageId);\n } catch (error) {\n if (this.shouldExitForAbort(options, error)) {\n return;\n }\n yield* this.emitFailureEvents(assistantMessageId, error);\n }\n };\n private trackPromptState = (\n promptPromise: Promise<acp.PromptResponse>,\n ): PromptExecutionState => {\n const promptState: PromptExecutionState = {\n settled: false,\n error: null,\n };\n\n promptPromise\n .then(() => {\n promptState.settled = true;\n this.buffer.notify();\n })\n .catch((error) => {\n promptState.settled = true;\n promptState.error = error;\n this.buffer.notify();\n });\n\n return promptState;\n };\n private emitRunStartedEvents = async function* (\n this: StdioRuntimeRunController,\n assistantMessageId: string,\n ): AsyncGenerator<NcpEndpointEvent> {\n yield* this.emitEvent({\n type: NcpEventType.MessageAccepted,\n payload: {\n messageId: assistantMessageId,\n ...(this.input.correlationId ? { correlationId: this.input.correlationId } : {}),\n },\n });\n yield* this.emitEvent({\n type: NcpEventType.RunStarted,\n payload: {\n sessionId: this.input.sessionId,\n messageId: assistantMessageId,\n runId: this.runId,\n },\n });\n };\n private drainPromptUpdates = async function* (\n this: StdioRuntimeRunController,\n assistantMessageId: string,\n promptState: PromptExecutionState,\n ): AsyncGenerator<NcpEndpointEvent> {\n while (!promptState.settled || this.buffer.hasItems()) {\n const update = this.buffer.shift();\n if (!update) {\n await this.buffer.waitForChange();\n continue;\n }\n for (const event of this.translateUpdate(update, assistantMessageId)) {\n yield* this.emitEvent(event);\n }\n }\n };\n private shouldExitForAbort = (\n options: NcpAgentRunOptions | undefined,\n error: unknown,\n ): boolean => options?.signal?.aborted === true || isAbortLikeRuntimeError(error);\n private emitCompletionEvents = async function* (\n this: StdioRuntimeRunController,\n assistantMessageId: string,\n ): AsyncGenerator<NcpEndpointEvent> {\n for (const terminalEvent of this.createTerminalEvents(assistantMessageId)) {\n yield* this.emitEvent(terminalEvent);\n }\n\n if (!this.collector.hasParts()) {\n throw new Error(\n `[narp-stdio] ACP prompt completed without any assistant content for session ${this.input.sessionId}. stderr=${this.session.readStderr()}`,\n );\n }\n\n yield* this.emitEvent({\n type: NcpEventType.MessageCompleted,\n payload: {\n sessionId: this.input.sessionId,\n correlationId: this.input.correlationId,\n message: {\n id: assistantMessageId,\n sessionId: this.input.sessionId,\n role: \"assistant\",\n status: \"final\",\n parts: this.collector.buildParts() as never,\n timestamp: new Date().toISOString(),\n },\n },\n });\n yield* this.emitEvent({\n type: NcpEventType.RunFinished,\n payload: {\n sessionId: this.input.sessionId,\n messageId: assistantMessageId,\n runId: this.runId,\n },\n });\n };\n private emitFailureEvents = async function* (\n this: StdioRuntimeRunController,\n assistantMessageId: string,\n error: unknown,\n ): AsyncGenerator<NcpEndpointEvent> {\n const ncpError = normalizeRuntimeError(error, { stderr: this.session.readStderr() });\n yield* this.emitEvent({\n type: NcpEventType.MessageFailed,\n payload: {\n sessionId: this.input.sessionId,\n messageId: assistantMessageId,\n correlationId: this.input.correlationId,\n error: ncpError,\n },\n });\n yield* this.emitEvent({\n type: NcpEventType.RunError,\n payload: {\n sessionId: this.input.sessionId,\n messageId: assistantMessageId,\n runId: this.runId,\n error: ncpError.message,\n },\n });\n };\n private emitEvent = async function* (\n this: StdioRuntimeRunController,\n event: NcpEndpointEvent,\n ): AsyncGenerator<NcpEndpointEvent> {\n this.collector.apply(event);\n await this.stateManager?.dispatch(event);\n yield event;\n };\n private translateUpdate = (\n update: AcpClientUpdate,\n messageId: string,\n ): NcpEndpointEvent[] => {\n switch (update.sessionUpdate) {\n case \"agent_message_chunk\":\n return this.emitTextDelta(update.content, messageId);\n case \"agent_thought_chunk\":\n return this.emitReasoningDelta(update.content, messageId);\n case \"tool_call\":\n return this.emitToolCallStart(update, messageId);\n case \"tool_call_update\":\n return this.emitToolCallUpdate(update);\n case \"session_info_update\":\n return this.emitSessionInfoUpdate(update, messageId);\n default:\n return [];\n }\n };\n\n private emitSessionInfoUpdate = (\n update: Extract<AcpClientUpdate, { sessionUpdate: \"session_info_update\" }>,\n messageId: string,\n ): NcpEndpointEvent[] => {\n const patch = readSessionMetadataPatch(update._meta);\n if (!patch) {\n return [];\n }\n return [\n {\n type: NcpEventType.RunMetadata,\n payload: {\n sessionId: this.input.sessionId,\n messageId,\n runId: this.runId,\n ...(this.input.correlationId ? { correlationId: this.input.correlationId } : {}),\n metadata: {\n kind: SESSION_METADATA_PATCH_KIND,\n sessionMetadataPatch: patch,\n },\n },\n },\n ];\n };\n\n private emitTextDelta = (\n content: { type: string; text?: string },\n messageId: string,\n ): NcpEndpointEvent[] => this.emitContentDelta({\n content,\n messageId,\n started: this.textStarted,\n markStarted: () => {\n this.textStarted = true;\n },\n startType: NcpEventType.MessageTextStart,\n deltaType: NcpEventType.MessageTextDelta,\n });\n\n private emitReasoningDelta = (\n content: { type: string; text?: string },\n messageId: string,\n ): NcpEndpointEvent[] => this.emitContentDelta({\n content,\n messageId,\n started: this.reasoningStarted,\n markStarted: () => {\n this.reasoningStarted = true;\n },\n startType: NcpEventType.MessageReasoningStart,\n deltaType: NcpEventType.MessageReasoningDelta,\n });\n\n private emitContentDelta = (params: {\n content: { type: string; text?: string };\n messageId: string;\n started: boolean;\n markStarted: () => void;\n startType: NcpEventType.MessageTextStart | NcpEventType.MessageReasoningStart;\n deltaType: NcpEventType.MessageTextDelta | NcpEventType.MessageReasoningDelta;\n }): NcpEndpointEvent[] => {\n const { content, deltaType, markStarted, messageId, started, startType } = params;\n if (content.type !== \"text\" || !content.text) {\n return [];\n }\n const events: NcpEndpointEvent[] = [];\n if (!started) {\n markStarted();\n events.push({\n type: startType,\n payload: {\n sessionId: this.input.sessionId,\n messageId,\n },\n });\n }\n events.push({\n type: deltaType,\n payload: {\n sessionId: this.input.sessionId,\n messageId,\n delta: content.text,\n },\n });\n return events;\n };\n\n private emitToolCallStart = (\n update: Extract<AcpClientUpdate, { sessionUpdate: \"tool_call\" }>,\n messageId: string,\n ): NcpEndpointEvent[] => {\n const toolName = resolveToolName(update);\n const args = serializeToolArgs(update.rawInput);\n this.toolStates.set(update.toolCallId, {\n toolName,\n args,\n completed: false,\n });\n return [\n {\n type: NcpEventType.MessageToolCallStart,\n payload: {\n sessionId: this.input.sessionId,\n messageId,\n toolCallId: update.toolCallId,\n toolName,\n },\n },\n {\n type: NcpEventType.MessageToolCallArgs,\n payload: {\n sessionId: this.input.sessionId,\n toolCallId: update.toolCallId,\n args,\n },\n },\n ];\n };\n\n private emitToolCallUpdate = (\n update: Extract<AcpClientUpdate, { sessionUpdate: \"tool_call_update\" }>,\n ): NcpEndpointEvent[] => {\n const existing = this.toolStates.get(update.toolCallId);\n if (!existing) {\n return [];\n }\n\n const nextArgs = serializeToolArgs(update.rawInput);\n const argsChanged = typeof update.rawInput !== \"undefined\" && nextArgs !== existing.args;\n const events: NcpEndpointEvent[] = [];\n if (argsChanged) {\n existing.args = nextArgs;\n events.push({\n type: NcpEventType.MessageToolCallArgs,\n payload: {\n sessionId: this.input.sessionId,\n toolCallId: update.toolCallId,\n args: nextArgs,\n },\n });\n }\n\n if (update.status === \"completed\" || update.status === \"failed\") {\n if (!existing.completed) {\n existing.completed = true;\n events.push({\n type: NcpEventType.MessageToolCallEnd,\n payload: {\n sessionId: this.input.sessionId,\n toolCallId: update.toolCallId,\n },\n });\n }\n if (typeof update.rawOutput !== \"undefined\") {\n events.push({\n type: NcpEventType.MessageToolCallResult,\n payload: {\n sessionId: this.input.sessionId,\n toolCallId: update.toolCallId,\n content: update.rawOutput,\n },\n });\n }\n }\n return events;\n };\n\n private createTerminalEvents = (messageId: string): NcpEndpointEvent[] => {\n const events: NcpEndpointEvent[] = [];\n if (this.textStarted) {\n events.push({\n type: NcpEventType.MessageTextEnd,\n payload: {\n sessionId: this.input.sessionId,\n messageId,\n },\n });\n this.textStarted = false;\n }\n if (this.reasoningStarted) {\n events.push({\n type: NcpEventType.MessageReasoningEnd,\n payload: {\n sessionId: this.input.sessionId,\n messageId,\n },\n });\n this.reasoningStarted = false;\n }\n for (const [toolCallId, state] of this.toolStates.entries()) {\n if (state.completed) {\n continue;\n }\n events.push({\n type: NcpEventType.MessageToolCallEnd,\n payload: {\n sessionId: this.input.sessionId,\n toolCallId,\n },\n });\n state.completed = true;\n }\n return events;\n };\n}\n\nexport class StdioRuntimeNcpAgentRuntime implements NcpAgentRuntime {\n private readonly session: StdioRuntimeSession;\n\n constructor(private readonly config: StdioRuntimeNcpAgentRuntimeConfig) {\n this.session = new StdioRuntimeSession(config, config.sessionId);\n }\n\n run = async function* (\n this: StdioRuntimeNcpAgentRuntime,\n input: NcpAgentRunInput,\n options?: NcpAgentRunOptions,\n ): AsyncGenerator<NcpEndpointEvent> {\n await this.session.ensureStarted({\n providerRoute: this.config.resolveProviderRoute?.(input),\n });\n const controller = new StdioRuntimeRunController(\n this.session,\n input,\n this.config.stateManager,\n this.config.resolveTools,\n this.config.resolveProviderRoute,\n );\n yield* controller.execute(options);\n };\n\n dispose = async (): Promise<void> => {\n await this.session.dispose();\n };\n}\n\nfunction extractPromptText(message: { parts?: Array<{ type: string; text?: string }> }): string {\n const text = (message.parts ?? [])\n .map((part) => {\n if (part.type === \"text\" || part.type === \"reasoning\" || part.type === \"rich-text\") {\n return part.text ?? \"\";\n }\n return \"\";\n })\n .join(\"\\n\")\n .trim();\n return text.length > 0 ? text : \"[empty message]\";\n}\n\nfunction resolveModelId(params: {\n providerRoute?: NcpProviderRuntimeRoute;\n metadata?: Record<string, unknown>;\n}): string | undefined {\n const { metadata, providerRoute } = params;\n const modelId =\n providerRoute?.model ??\n readString(metadata?.preferred_model) ??\n readString(metadata?.preferredModel) ??\n readString(metadata?.model);\n return modelId === \"__nextclaw_runtime_default__\" ? undefined : modelId;\n}\n\nfunction readSessionMetadataPatch(meta: unknown): Record<string, unknown> | null {\n const narpMeta = isRecord(meta)\n ? meta[NARP_STDIO_PROMPT_META_KEY]\n : undefined;\n const patch = isRecord(narpMeta)\n ? narpMeta.sessionMetadataPatch\n : undefined;\n return isRecord(patch) && Object.keys(patch).length > 0\n ? structuredClone(patch)\n : null;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction resolveToolName(\n update: Extract<AcpClientUpdate, { sessionUpdate: \"tool_call\" }>,\n): string {\n return resolveToolNameFromAcpUpdate(update);\n}\n\nfunction createAssistantMessageId(requestMessageId: string): string {\n const normalizedRequestId = requestMessageId.trim() || \"request\";\n return `assistant:${normalizedRequestId}:${randomUUID()}`;\n}\n\nfunction serializeToolArgs(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n if (typeof value === \"undefined\") {\n return \"{}\";\n }\n return JSON.stringify(value);\n}\n\nasync function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n message: string,\n): Promise<T> {\n let timeoutHandle: ReturnType<typeof setTimeout> | null = null;\n try {\n return await Promise.race([\n promise,\n new Promise<T>((_, reject) => {\n timeoutHandle = setTimeout(() => {\n reject(new Error(message));\n }, timeoutMs);\n }),\n ]);\n } finally {\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"stdio-runtime.service.js","names":[],"sources":["../src/stdio-runtime.service.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { spawn, type ChildProcessWithoutNullStreams } from \"node:child_process\";\nimport { Readable, Writable } from \"node:stream\";\nimport * as acp from \"@agentclientprotocol/sdk\";\nimport {\n NcpEventType,\n type NcpAgentConversationStateManager,\n type NcpAgentRunInput,\n type NcpAgentRunOptions,\n type NcpAgentRuntime,\n type NcpEndpointEvent,\n type NcpProviderRuntimeRoute,\n type OpenAITool,\n} from \"@nextclaw/ncp\";\nimport type { StdioRuntimeResolvedConfig, NarpStdioPromptMeta } from \"./stdio-runtime-config.utils.js\";\nimport {\n NARP_STDIO_PROMPT_META_KEY,\n buildStdioRuntimeLaunchEnv,\n} from \"./stdio-runtime-config.utils.js\";\nimport {\n buildSpawnFailureMessage,\n isAbortLikeRuntimeError,\n normalizeRuntimeError,\n} from \"./stdio-runtime-error.utils.js\";\nimport {\n createPromptTimeoutRecoveryEvents,\n SESSION_METADATA_PATCH_KIND,\n} from \"./utils/stdio-runtime-recovery.utils.js\";\nimport { extractPromptText, resolveModelId } from \"./utils/stdio-runtime-input.utils.js\";\nimport { resolveToolNameFromAcpUpdate } from \"./stdio-runtime-tool-name.utils.js\";\ntype AcpClientUpdate = acp.SessionUpdate;\nconst HERMES_ACP_ROUTE_BRIDGE_ENV = \"NEXTCLAW_HERMES_ACP_ROUTE_BRIDGE\";\nexport type StdioRuntimeNcpAgentRuntimeConfig = StdioRuntimeResolvedConfig & {\n stateManager?: NcpAgentConversationStateManager;\n resolveTools?: (input: NcpAgentRunInput) => ReadonlyArray<OpenAITool> | undefined;\n resolveProviderRoute?: (input: NcpAgentRunInput) => NcpProviderRuntimeRoute | undefined;\n};\ntype AcpToolState = {\n toolName: string;\n args?: string;\n completed: boolean;\n};\n\ntype PromptExecutionState = { settled: boolean; error: unknown };\n\nclass UpdateBuffer {\n private readonly updates: AcpClientUpdate[] = [];\n private waiters = new Set<() => void>();\n\n push = (update: AcpClientUpdate): void => {\n this.updates.push(update);\n this.flush();\n };\n\n shift = (): AcpClientUpdate | undefined => this.updates.shift();\n\n hasItems = (): boolean => this.updates.length > 0;\n\n waitForChange = async (): Promise<void> => {\n if (this.updates.length > 0) {\n return;\n }\n await new Promise<void>((resolve) => {\n this.waiters.add(resolve);\n });\n };\n\n notify = (): void => {\n this.flush();\n };\n\n private flush = (): void => {\n if (this.waiters.size === 0) {\n return;\n }\n const waiters = [...this.waiters];\n this.waiters.clear();\n for (const waiter of waiters) {\n waiter();\n }\n };\n}\n\nclass PromptUpdateCollector {\n private readonly parts: Array<\n | { type: \"text\"; text: string }\n | { type: \"reasoning\"; text: string }\n | { type: \"tool-invocation\"; toolCallId: string; toolName: string; state: \"partial-call\" | \"call\"; args: string }\n > = [];\n private readonly toolIndex = new Map<string, number>();\n\n apply = (event: NcpEndpointEvent): void => {\n switch (event.type) {\n case NcpEventType.MessageTextDelta:\n this.appendPart(\"text\", event.payload.delta);\n return;\n case NcpEventType.MessageReasoningDelta:\n this.appendPart(\"reasoning\", event.payload.delta);\n return;\n case NcpEventType.MessageToolCallStart:\n this.upsertTool({\n toolCallId: event.payload.toolCallId,\n toolName: event.payload.toolName,\n args: \"\",\n state: \"partial-call\",\n });\n return;\n case NcpEventType.MessageToolCallArgs:\n {\n const tool = this.readTool(event.payload.toolCallId);\n this.upsertTool({\n toolCallId: event.payload.toolCallId,\n toolName: tool.toolName,\n args: event.payload.args,\n state: \"partial-call\",\n });\n }\n return;\n case NcpEventType.MessageToolCallArgsDelta:\n {\n const tool = this.readTool(event.payload.toolCallId);\n this.upsertTool({\n toolCallId: event.payload.toolCallId,\n toolName: tool.toolName,\n args: `${tool.args}${event.payload.delta}`,\n state: \"partial-call\",\n });\n }\n return;\n case NcpEventType.MessageToolCallEnd:\n {\n const tool = this.readTool(event.payload.toolCallId);\n this.upsertTool({\n toolCallId: event.payload.toolCallId,\n toolName: tool.toolName,\n args: tool.args,\n state: \"call\",\n });\n }\n return;\n default:\n return;\n }\n };\n\n hasParts = (): boolean => this.parts.length > 0;\n\n buildParts = (): Array<Record<string, unknown>> => structuredClone(this.parts);\n\n private appendPart = (type: \"text\" | \"reasoning\", text: string): void => {\n if (!text) {\n return;\n }\n const last = this.parts.at(-1);\n if (last?.type === type) {\n last.text = `${last.text}${text}`;\n return;\n }\n this.parts.push({ type, text });\n };\n\n private upsertTool = (nextTool: {\n toolCallId: string;\n toolName: string;\n args: string;\n state: \"partial-call\" | \"call\";\n }): void => {\n const existingIndex = this.toolIndex.get(nextTool.toolCallId);\n if (typeof existingIndex === \"number\") {\n const existing = this.parts[existingIndex];\n if (existing?.type !== \"tool-invocation\") {\n return;\n }\n this.parts[existingIndex] = {\n ...existing,\n ...nextTool,\n };\n return;\n }\n\n this.toolIndex.set(nextTool.toolCallId, this.parts.length);\n this.parts.push({\n type: \"tool-invocation\",\n ...nextTool,\n });\n };\n\n private readTool = (toolCallId: string): { toolName: string; args: string } => {\n const index = this.toolIndex.get(toolCallId);\n const part = typeof index === \"number\" ? this.parts[index] : null;\n if (part?.type !== \"tool-invocation\") {\n return { toolName: \"unknown\", args: \"\" };\n }\n return { toolName: part.toolName, args: part.args };\n };\n}\n\nclass StdioRuntimeClientBridge {\n private activeSessionId: string | null = null;\n private updateHandler: ((update: AcpClientUpdate) => void) | null = null;\n\n attach = (params: {\n sessionId: string;\n onUpdate: (update: AcpClientUpdate) => void;\n }): (() => void) => {\n this.activeSessionId = params.sessionId;\n this.updateHandler = params.onUpdate;\n return () => {\n if (this.activeSessionId !== params.sessionId) {\n return;\n }\n this.activeSessionId = null;\n this.updateHandler = null;\n };\n };\n\n sessionUpdate = async (params: { sessionId: string; update: AcpClientUpdate }): Promise<void> => {\n if (params.sessionId !== this.activeSessionId) {\n return;\n }\n this.updateHandler?.(params.update);\n };\n\n requestPermission = async (): Promise<{\n outcome: { outcome: \"cancelled\" };\n }> => ({\n outcome: { outcome: \"cancelled\" },\n });\n\n readTextFile = async (): Promise<{ content: string }> => ({ content: \"\" });\n\n writeTextFile = async (): Promise<Record<string, never>> => ({});\n}\n\nclass StdioRuntimeSession {\n private child: ChildProcessWithoutNullStreams | null = null;\n private connection: acp.ClientSideConnection | null = null;\n private promptInFlight = false;\n private remoteSessionId: string | null = null;\n private remoteSessionCwd: string | null = null;\n private readonly clientBridge = new StdioRuntimeClientBridge();\n private stderr = \"\";\n private pendingProviderRoute: NcpProviderRuntimeRoute | undefined;\n\n constructor(private readonly config: StdioRuntimeNcpAgentRuntimeConfig) {}\n\n ensureStarted = async (params: {\n cwd?: string;\n providerRoute?: NcpProviderRuntimeRoute;\n }): Promise<void> => {\n const { cwd, providerRoute } = params;\n this.pendingProviderRoute = providerRoute;\n if (this.connection && this.remoteSessionId) {\n if (this.remoteSessionCwd === cwd) {\n return;\n }\n await this.dispose();\n }\n if (!cwd) {\n throw new Error(\"[narp-stdio] missing execution cwd for stdio runtime session\");\n }\n\n const env = buildStdioRuntimeLaunchEnv({\n configEnv: this.config.env,\n providerRoute: this.pendingProviderRoute,\n });\n\n this.child = spawn(this.config.command, this.config.args, {\n cwd: this.config.cwd,\n env,\n stdio: [\"pipe\", \"pipe\", \"pipe\"], windowsHide: true,\n });\n const spawnErrorPromise = new Promise<never>((_, reject) => {\n this.child?.once(\"error\", (error) => {\n reject(\n new Error(\n buildSpawnFailureMessage({\n command: this.config.command,\n cwd: this.config.cwd,\n error,\n }),\n ),\n );\n });\n });\n this.child.stderr.setEncoding(\"utf8\");\n this.child.stderr.on(\"data\", (chunk: string) => {\n this.stderr = `${this.stderr}${chunk}`.slice(-4000);\n });\n\n const stream = acp.ndJsonStream(\n Writable.toWeb(this.child.stdin),\n Readable.toWeb(this.child.stdout),\n );\n this.connection = new acp.ClientSideConnection(() => this.clientBridge, stream);\n\n const session = await Promise.race([\n (async () => {\n await withTimeout(\n this.connection?.initialize({\n protocolVersion: acp.PROTOCOL_VERSION,\n clientCapabilities: {},\n }) ?? Promise.reject(new Error(\"[narp-stdio] stdio runtime connection not started\")),\n this.config.startupTimeoutMs,\n \"[narp-stdio] timed out initializing stdio runtime\",\n );\n\n return withTimeout(\n this.connection?.newSession({\n cwd,\n mcpServers: [],\n }) ?? Promise.reject(new Error(\"[narp-stdio] stdio runtime connection not started\")),\n this.config.startupTimeoutMs,\n \"[narp-stdio] timed out creating remote stdio session\",\n );\n })(),\n spawnErrorPromise,\n ]);\n this.remoteSessionId = session.sessionId;\n this.remoteSessionCwd = cwd;\n };\n\n runPrompt = async (params: {\n sessionId: string;\n text: string;\n meta: NarpStdioPromptMeta;\n modelId?: string;\n signal?: AbortSignal;\n onUpdate: (update: AcpClientUpdate) => void;\n }): Promise<acp.PromptResponse> => {\n const { meta, modelId, onUpdate, sessionId, signal, text } = params;\n if (!this.connection || !this.remoteSessionId) {\n throw new Error(\"[narp-stdio] stdio runtime connection not started\");\n }\n if (this.promptInFlight) {\n throw new Error(\"[narp-stdio] concurrent prompt is not supported for one stdio session\");\n }\n\n this.promptInFlight = true;\n const detach = this.clientBridge.attach({\n sessionId: this.remoteSessionId,\n onUpdate,\n });\n const releaseAbort = this.bindAbortSignal(signal);\n\n try {\n if (modelId && this.config.env?.[HERMES_ACP_ROUTE_BRIDGE_ENV] !== \"1\") {\n try {\n // Hermes ACP must switch on prompt-scoped providerRoute, not modelId alone.\n await this.connection.unstable_setSessionModel({\n sessionId: this.remoteSessionId,\n modelId,\n });\n } catch {\n // Not all ACP agents implement unstable session model switching.\n }\n }\n\n return await withTimeout(\n this.connection.prompt({\n sessionId: this.remoteSessionId,\n prompt: [{ type: \"text\", text }],\n _meta: {\n [NARP_STDIO_PROMPT_META_KEY]: meta,\n },\n }),\n this.config.requestTimeoutMs,\n `[narp-stdio] prompt timed out for session ${sessionId}`,\n );\n } finally {\n releaseAbort();\n detach();\n this.promptInFlight = false;\n }\n };\n\n cancel = async (): Promise<void> => {\n if (!this.connection || !this.remoteSessionId) {\n return;\n }\n try {\n await this.connection.cancel({\n sessionId: this.remoteSessionId,\n });\n } catch {\n // Best effort.\n }\n };\n\n private bindAbortSignal = (signal?: AbortSignal): (() => void) => {\n if (!signal) {\n return () => undefined;\n }\n\n const onAbort = (): void => {\n void this.cancel();\n };\n\n if (signal.aborted) {\n onAbort();\n return () => undefined;\n }\n\n signal.addEventListener(\"abort\", onAbort, { once: true });\n return () => {\n signal.removeEventListener(\"abort\", onAbort);\n };\n };\n\n readStderr = (): string => this.stderr;\n\n readPromptTimeoutMetadataResetKeys = (): readonly string[] | undefined =>\n this.config.resetSessionMetadataOnPromptTimeout;\n\n dispose = async (): Promise<void> => {\n await this.cancel();\n const child = this.child;\n this.connection = null;\n this.remoteSessionId = null;\n this.remoteSessionCwd = null;\n this.child = null;\n if (!child || child.killed || child.exitCode !== null || child.signalCode !== null) {\n return;\n }\n\n const exited = new Promise<void>((resolve) => {\n child.once(\"exit\", () => resolve());\n child.once(\"error\", () => resolve());\n });\n const forceKill = setTimeout(() => {\n child.kill(\"SIGKILL\");\n }, 3_000);\n forceKill.unref();\n child.kill(\"SIGTERM\");\n await exited;\n clearTimeout(forceKill);\n };\n}\n\nclass StdioRuntimeRunController {\n private readonly buffer = new UpdateBuffer();\n private readonly collector = new PromptUpdateCollector();\n private readonly toolStates = new Map<string, AcpToolState>();\n private textStarted = false;\n private reasoningStarted = false;\n private readonly resolvedTools: ReadonlyArray<OpenAITool>;\n private readonly resolvedProviderRoute: NcpProviderRuntimeRoute | undefined;\n private readonly runId: string;\n\n constructor(\n private readonly session: StdioRuntimeSession,\n private readonly input: NcpAgentRunInput,\n private readonly stateManager?: NcpAgentConversationStateManager,\n private readonly resolveTools?: (input: NcpAgentRunInput) => ReadonlyArray<OpenAITool> | undefined,\n private readonly resolveProviderRoute?: (input: NcpAgentRunInput) => NcpProviderRuntimeRoute | undefined,\n ) {\n this.resolvedTools = resolveTools?.(input) ?? [];\n this.resolvedProviderRoute = resolveProviderRoute?.(input);\n this.runId = (input as NcpAgentRunInput & { runId?: string }).runId ?? `narp-stdio:${input.sessionId}:${randomUUID()}`;\n }\n execute = async function* (\n this: StdioRuntimeRunController,\n options?: NcpAgentRunOptions,\n ): AsyncGenerator<NcpEndpointEvent> {\n const requestMessage = this.input.messages.at(-1);\n if (!requestMessage) {\n throw new Error(\"[narp-stdio] runtime.run requires at least one input message\");\n }\n\n const assistantMessageId = createAssistantMessageId(requestMessage.id);\n const promptPromise = this.session.runPrompt({\n sessionId: this.input.sessionId,\n text: extractPromptText(requestMessage),\n meta: {\n ...(this.input.correlationId ? { correlationId: this.input.correlationId } : {}),\n ...(this.resolvedProviderRoute ? { providerRoute: this.resolvedProviderRoute } : {}),\n ...(this.input.metadata ? { sessionMetadata: this.input.metadata } : {}),\n ...(this.resolvedTools.length > 0 ? { tools: this.resolvedTools } : {}),\n },\n modelId: resolveModelId({\n providerRoute: this.resolvedProviderRoute,\n metadata: this.input.metadata,\n }),\n signal: options?.signal,\n onUpdate: (update) => this.buffer.push(update),\n });\n const promptState = this.trackPromptState(promptPromise);\n\n yield* this.emitRunStartedEvents(assistantMessageId);\n\n try {\n yield* this.drainPromptUpdates(assistantMessageId, promptState);\n if (this.shouldExitForAbort(options, promptState.error)) {\n return;\n }\n if (promptState.error) throw promptState.error;\n yield* this.emitCompletionEvents(assistantMessageId);\n } catch (error) {\n if (this.shouldExitForAbort(options, error)) {\n return;\n }\n yield* this.emitFailureEvents(assistantMessageId, error);\n }\n };\n private trackPromptState = (\n promptPromise: Promise<acp.PromptResponse>,\n ): PromptExecutionState => {\n const promptState: PromptExecutionState = {\n settled: false,\n error: null,\n };\n\n promptPromise\n .then(() => {\n promptState.settled = true;\n this.buffer.notify();\n })\n .catch((error) => {\n promptState.settled = true;\n promptState.error = error;\n this.buffer.notify();\n });\n\n return promptState;\n };\n private emitRunStartedEvents = async function* (\n this: StdioRuntimeRunController,\n assistantMessageId: string,\n ): AsyncGenerator<NcpEndpointEvent> {\n yield* this.emitEvent({\n type: NcpEventType.MessageAccepted,\n payload: {\n messageId: assistantMessageId,\n ...(this.input.correlationId ? { correlationId: this.input.correlationId } : {}),\n },\n });\n yield* this.emitEvent({\n type: NcpEventType.RunStarted,\n payload: {\n sessionId: this.input.sessionId,\n messageId: assistantMessageId,\n runId: this.runId,\n },\n });\n };\n private drainPromptUpdates = async function* (\n this: StdioRuntimeRunController,\n assistantMessageId: string,\n promptState: PromptExecutionState,\n ): AsyncGenerator<NcpEndpointEvent> {\n while (!promptState.settled || this.buffer.hasItems()) {\n const update = this.buffer.shift();\n if (!update) {\n await this.buffer.waitForChange();\n continue;\n }\n for (const event of this.translateUpdate(update, assistantMessageId)) {\n yield* this.emitEvent(event);\n }\n }\n };\n private shouldExitForAbort = (\n options: NcpAgentRunOptions | undefined,\n error: unknown,\n ): boolean => options?.signal?.aborted === true || isAbortLikeRuntimeError(error);\n private emitCompletionEvents = async function* (\n this: StdioRuntimeRunController,\n assistantMessageId: string,\n ): AsyncGenerator<NcpEndpointEvent> {\n for (const terminalEvent of this.createTerminalEvents(assistantMessageId)) {\n yield* this.emitEvent(terminalEvent);\n }\n\n if (!this.collector.hasParts()) {\n throw new Error(\n `[narp-stdio] ACP prompt completed without any assistant content for session ${this.input.sessionId}. stderr=${this.session.readStderr()}`,\n );\n }\n\n yield* this.emitEvent({\n type: NcpEventType.MessageCompleted,\n payload: {\n sessionId: this.input.sessionId,\n correlationId: this.input.correlationId,\n message: {\n id: assistantMessageId,\n sessionId: this.input.sessionId,\n role: \"assistant\",\n status: \"final\",\n parts: this.collector.buildParts() as never,\n timestamp: new Date().toISOString(),\n },\n },\n });\n yield* this.emitEvent({\n type: NcpEventType.RunFinished,\n payload: {\n sessionId: this.input.sessionId,\n messageId: assistantMessageId,\n runId: this.runId,\n },\n });\n };\n private emitFailureEvents = async function* (\n this: StdioRuntimeRunController,\n assistantMessageId: string,\n error: unknown,\n ): AsyncGenerator<NcpEndpointEvent> {\n const ncpError = normalizeRuntimeError(error, { stderr: this.session.readStderr() });\n for (const recoveryEvent of createPromptTimeoutRecoveryEvents({\n correlationId: this.input.correlationId,\n error,\n messageId: assistantMessageId,\n resetKeys: this.session.readPromptTimeoutMetadataResetKeys(),\n runId: this.runId,\n sessionId: this.input.sessionId,\n })) {\n yield* this.emitEvent(recoveryEvent);\n }\n yield* this.emitEvent({\n type: NcpEventType.MessageFailed,\n payload: {\n sessionId: this.input.sessionId,\n messageId: assistantMessageId,\n correlationId: this.input.correlationId,\n error: ncpError,\n },\n });\n yield* this.emitEvent({\n type: NcpEventType.RunError,\n payload: {\n sessionId: this.input.sessionId,\n messageId: assistantMessageId,\n runId: this.runId,\n error: ncpError.message,\n },\n });\n };\n private emitEvent = async function* (\n this: StdioRuntimeRunController,\n event: NcpEndpointEvent,\n ): AsyncGenerator<NcpEndpointEvent> {\n this.collector.apply(event);\n await this.stateManager?.dispatch(event);\n yield event;\n };\n private translateUpdate = (\n update: AcpClientUpdate,\n messageId: string,\n ): NcpEndpointEvent[] => {\n switch (update.sessionUpdate) {\n case \"agent_message_chunk\":\n return this.emitTextDelta(update.content, messageId);\n case \"agent_thought_chunk\":\n return this.emitReasoningDelta(update.content, messageId);\n case \"tool_call\":\n return this.emitToolCallStart(update, messageId);\n case \"tool_call_update\":\n return this.emitToolCallUpdate(update);\n case \"session_info_update\":\n return this.emitSessionInfoUpdate(update, messageId);\n default:\n return [];\n }\n };\n\n private emitSessionInfoUpdate = (\n update: Extract<AcpClientUpdate, { sessionUpdate: \"session_info_update\" }>,\n messageId: string,\n ): NcpEndpointEvent[] => {\n const patch = readSessionMetadataPatch(update._meta);\n if (!patch) {\n return [];\n }\n return [\n {\n type: NcpEventType.RunMetadata,\n payload: {\n sessionId: this.input.sessionId,\n messageId,\n runId: this.runId,\n ...(this.input.correlationId ? { correlationId: this.input.correlationId } : {}),\n metadata: {\n kind: SESSION_METADATA_PATCH_KIND,\n sessionMetadataPatch: patch,\n },\n },\n },\n ];\n };\n\n private emitTextDelta = (\n content: { type: string; text?: string },\n messageId: string,\n ): NcpEndpointEvent[] => this.emitContentDelta({\n content,\n messageId,\n started: this.textStarted,\n markStarted: () => {\n this.textStarted = true;\n },\n startType: NcpEventType.MessageTextStart,\n deltaType: NcpEventType.MessageTextDelta,\n });\n\n private emitReasoningDelta = (\n content: { type: string; text?: string },\n messageId: string,\n ): NcpEndpointEvent[] => this.emitContentDelta({\n content,\n messageId,\n started: this.reasoningStarted,\n markStarted: () => {\n this.reasoningStarted = true;\n },\n startType: NcpEventType.MessageReasoningStart,\n deltaType: NcpEventType.MessageReasoningDelta,\n });\n\n private emitContentDelta = (params: {\n content: { type: string; text?: string };\n messageId: string;\n started: boolean;\n markStarted: () => void;\n startType: NcpEventType.MessageTextStart | NcpEventType.MessageReasoningStart;\n deltaType: NcpEventType.MessageTextDelta | NcpEventType.MessageReasoningDelta;\n }): NcpEndpointEvent[] => {\n const { content, deltaType, markStarted, messageId, started, startType } = params;\n if (content.type !== \"text\" || !content.text) {\n return [];\n }\n const events: NcpEndpointEvent[] = [];\n if (!started) {\n markStarted();\n events.push({\n type: startType,\n payload: {\n sessionId: this.input.sessionId,\n messageId,\n },\n });\n }\n events.push({\n type: deltaType,\n payload: {\n sessionId: this.input.sessionId,\n messageId,\n delta: content.text,\n },\n });\n return events;\n };\n\n private emitToolCallStart = (\n update: Extract<AcpClientUpdate, { sessionUpdate: \"tool_call\" }>,\n messageId: string,\n ): NcpEndpointEvent[] => {\n const toolName = resolveToolName(update);\n const args = serializeToolArgs(update.rawInput);\n this.toolStates.set(update.toolCallId, {\n toolName,\n args,\n completed: false,\n });\n return [\n {\n type: NcpEventType.MessageToolCallStart,\n payload: {\n sessionId: this.input.sessionId,\n messageId,\n toolCallId: update.toolCallId,\n toolName,\n },\n },\n {\n type: NcpEventType.MessageToolCallArgs,\n payload: {\n sessionId: this.input.sessionId,\n toolCallId: update.toolCallId,\n args,\n },\n },\n ];\n };\n\n private emitToolCallUpdate = (\n update: Extract<AcpClientUpdate, { sessionUpdate: \"tool_call_update\" }>,\n ): NcpEndpointEvent[] => {\n const existing = this.toolStates.get(update.toolCallId);\n if (!existing) {\n return [];\n }\n\n const nextArgs = serializeToolArgs(update.rawInput);\n const argsChanged = typeof update.rawInput !== \"undefined\" && nextArgs !== existing.args;\n const events: NcpEndpointEvent[] = [];\n if (argsChanged) {\n existing.args = nextArgs;\n events.push({\n type: NcpEventType.MessageToolCallArgs,\n payload: {\n sessionId: this.input.sessionId,\n toolCallId: update.toolCallId,\n args: nextArgs,\n },\n });\n }\n\n if (update.status === \"completed\" || update.status === \"failed\") {\n if (!existing.completed) {\n existing.completed = true;\n events.push({\n type: NcpEventType.MessageToolCallEnd,\n payload: {\n sessionId: this.input.sessionId,\n toolCallId: update.toolCallId,\n },\n });\n }\n if (typeof update.rawOutput !== \"undefined\") {\n events.push({\n type: NcpEventType.MessageToolCallResult,\n payload: {\n sessionId: this.input.sessionId,\n toolCallId: update.toolCallId,\n content: update.rawOutput,\n },\n });\n }\n }\n return events;\n };\n\n private createTerminalEvents = (messageId: string): NcpEndpointEvent[] => {\n const events: NcpEndpointEvent[] = [];\n if (this.textStarted) {\n events.push({\n type: NcpEventType.MessageTextEnd,\n payload: {\n sessionId: this.input.sessionId,\n messageId,\n },\n });\n this.textStarted = false;\n }\n if (this.reasoningStarted) {\n events.push({\n type: NcpEventType.MessageReasoningEnd,\n payload: {\n sessionId: this.input.sessionId,\n messageId,\n },\n });\n this.reasoningStarted = false;\n }\n for (const [toolCallId, state] of this.toolStates.entries()) {\n if (state.completed) {\n continue;\n }\n events.push({\n type: NcpEventType.MessageToolCallEnd,\n payload: {\n sessionId: this.input.sessionId,\n toolCallId,\n },\n });\n state.completed = true;\n }\n return events;\n };\n}\n\nexport class StdioRuntimeNcpAgentRuntime implements NcpAgentRuntime {\n private readonly session: StdioRuntimeSession;\n\n constructor(private readonly config: StdioRuntimeNcpAgentRuntimeConfig) {\n this.session = new StdioRuntimeSession(config);\n }\n\n run = async function* (\n this: StdioRuntimeNcpAgentRuntime,\n input: NcpAgentRunInput,\n options?: NcpAgentRunOptions,\n ): AsyncGenerator<NcpEndpointEvent> {\n await this.session.ensureStarted({\n cwd: input.executionContext?.cwd,\n providerRoute: this.config.resolveProviderRoute?.(input),\n });\n const controller = new StdioRuntimeRunController(\n this.session,\n input,\n this.config.stateManager,\n this.config.resolveTools,\n this.config.resolveProviderRoute,\n );\n yield* controller.execute(options);\n };\n\n dispose = async (): Promise<void> => {\n await this.session.dispose();\n };\n}\n\nfunction readSessionMetadataPatch(meta: unknown): Record<string, unknown> | null {\n const narpMeta = isRecord(meta)\n ? meta[NARP_STDIO_PROMPT_META_KEY]\n : undefined;\n const patch = isRecord(narpMeta)\n ? narpMeta.sessionMetadataPatch\n : undefined;\n return isRecord(patch) && Object.keys(patch).length > 0\n ? structuredClone(patch)\n : null;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction resolveToolName(\n update: Extract<AcpClientUpdate, { sessionUpdate: \"tool_call\" }>,\n): string {\n return resolveToolNameFromAcpUpdate(update);\n}\n\nfunction createAssistantMessageId(requestMessageId: string): string {\n const normalizedRequestId = requestMessageId.trim() || \"request\";\n return `assistant:${normalizedRequestId}:${randomUUID()}`;\n}\n\nfunction serializeToolArgs(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n if (typeof value === \"undefined\") {\n return \"{}\";\n }\n return JSON.stringify(value);\n}\n\nasync function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n message: string,\n): Promise<T> {\n let timeoutHandle: ReturnType<typeof setTimeout> | null = null;\n try {\n return await Promise.race([\n promise,\n new Promise<T>((_, reject) => {\n timeoutHandle = setTimeout(() => {\n reject(new Error(message));\n }, timeoutMs);\n }),\n ]);\n } finally {\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { readString } from "../stdio-runtime-config.utils.js";
|
|
2
|
+
//#region src/utils/stdio-runtime-input.utils.ts
|
|
3
|
+
function extractPromptText(message) {
|
|
4
|
+
const text = (message.parts ?? []).map((part) => {
|
|
5
|
+
if (part.type === "text" || part.type === "reasoning" || part.type === "rich-text") return part.text ?? "";
|
|
6
|
+
return "";
|
|
7
|
+
}).join("\n").trim();
|
|
8
|
+
return text.length > 0 ? text : "[empty message]";
|
|
9
|
+
}
|
|
10
|
+
function resolveModelId(params) {
|
|
11
|
+
const { metadata, providerRoute } = params;
|
|
12
|
+
const modelId = providerRoute?.model ?? readString(metadata?.preferred_model) ?? readString(metadata?.preferredModel) ?? readString(metadata?.model);
|
|
13
|
+
return modelId === "__nextclaw_runtime_default__" ? void 0 : modelId;
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
export { extractPromptText, resolveModelId };
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=stdio-runtime-input.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio-runtime-input.utils.js","names":[],"sources":["../../src/utils/stdio-runtime-input.utils.ts"],"sourcesContent":["import type { NcpProviderRuntimeRoute } from \"@nextclaw/ncp\";\nimport { readString } from \"../stdio-runtime-config.utils.js\";\n\nexport function extractPromptText(message: { parts?: Array<{ type: string; text?: string }> }): string {\n const text = (message.parts ?? [])\n .map((part) => {\n if (part.type === \"text\" || part.type === \"reasoning\" || part.type === \"rich-text\") {\n return part.text ?? \"\";\n }\n return \"\";\n })\n .join(\"\\n\")\n .trim();\n return text.length > 0 ? text : \"[empty message]\";\n}\n\nexport function resolveModelId(params: {\n providerRoute?: NcpProviderRuntimeRoute;\n metadata?: Record<string, unknown>;\n}): string | undefined {\n const { metadata, providerRoute } = params;\n const modelId =\n providerRoute?.model ??\n readString(metadata?.preferred_model) ??\n readString(metadata?.preferredModel) ??\n readString(metadata?.model);\n return modelId === \"__nextclaw_runtime_default__\" ? undefined : modelId;\n}\n"],"mappings":";;AAGA,SAAgB,kBAAkB,SAAqE;CACrG,MAAM,QAAQ,QAAQ,SAAS,EAAE,EAC9B,KAAK,SAAS;AACb,MAAI,KAAK,SAAS,UAAU,KAAK,SAAS,eAAe,KAAK,SAAS,YACrE,QAAO,KAAK,QAAQ;AAEtB,SAAO;GACP,CACD,KAAK,KAAK,CACV,MAAM;AACT,QAAO,KAAK,SAAS,IAAI,OAAO;;AAGlC,SAAgB,eAAe,QAGR;CACrB,MAAM,EAAE,UAAU,kBAAkB;CACpC,MAAM,UACJ,eAAe,SACf,WAAW,UAAU,gBAAgB,IACrC,WAAW,UAAU,eAAe,IACpC,WAAW,UAAU,MAAM;AAC7B,QAAO,YAAY,iCAAiC,KAAA,IAAY"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { NcpEventType } from "@nextclaw/ncp";
|
|
2
|
+
//#region src/utils/stdio-runtime-recovery.utils.ts
|
|
3
|
+
const SESSION_METADATA_PATCH_KIND = "session_metadata_patch";
|
|
4
|
+
function createPromptTimeoutRecoveryEvents(params) {
|
|
5
|
+
const { correlationId, error, messageId, resetKeys, runId, sessionId } = params;
|
|
6
|
+
if (!resetKeys?.length || !isPromptTimeoutError(error)) return [];
|
|
7
|
+
return [{
|
|
8
|
+
type: NcpEventType.RunMetadata,
|
|
9
|
+
payload: {
|
|
10
|
+
sessionId,
|
|
11
|
+
messageId,
|
|
12
|
+
runId,
|
|
13
|
+
...correlationId ? { correlationId } : {},
|
|
14
|
+
metadata: {
|
|
15
|
+
kind: SESSION_METADATA_PATCH_KIND,
|
|
16
|
+
sessionMetadataPatch: Object.fromEntries(resetKeys.map((key) => [key, null]))
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}];
|
|
20
|
+
}
|
|
21
|
+
function isPromptTimeoutError(error) {
|
|
22
|
+
return (error instanceof Error ? error.message : String(error)).includes("[narp-stdio] prompt timed out");
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { SESSION_METADATA_PATCH_KIND, createPromptTimeoutRecoveryEvents };
|
|
26
|
+
|
|
27
|
+
//# sourceMappingURL=stdio-runtime-recovery.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio-runtime-recovery.utils.js","names":[],"sources":["../../src/utils/stdio-runtime-recovery.utils.ts"],"sourcesContent":["import { NcpEventType, type NcpEndpointEvent } from \"@nextclaw/ncp\";\n\nexport const SESSION_METADATA_PATCH_KIND = \"session_metadata_patch\";\n\nexport function createPromptTimeoutRecoveryEvents(params: {\n correlationId?: string;\n error: unknown;\n messageId: string;\n resetKeys?: readonly string[];\n runId: string;\n sessionId: string;\n}): NcpEndpointEvent[] {\n const { correlationId, error, messageId, resetKeys, runId, sessionId } = params;\n if (!resetKeys?.length || !isPromptTimeoutError(error)) {\n return [];\n }\n return [\n {\n type: NcpEventType.RunMetadata,\n payload: {\n sessionId,\n messageId,\n runId,\n ...(correlationId ? { correlationId } : {}),\n metadata: {\n kind: SESSION_METADATA_PATCH_KIND,\n sessionMetadataPatch: Object.fromEntries(\n resetKeys.map((key) => [key, null]),\n ),\n },\n },\n },\n ];\n}\n\nfunction isPromptTimeoutError(error: unknown): boolean {\n const message = error instanceof Error ? error.message : String(error);\n return message.includes(\"[narp-stdio] prompt timed out\");\n}\n"],"mappings":";;AAEA,MAAa,8BAA8B;AAE3C,SAAgB,kCAAkC,QAO3B;CACrB,MAAM,EAAE,eAAe,OAAO,WAAW,WAAW,OAAO,cAAc;AACzE,KAAI,CAAC,WAAW,UAAU,CAAC,qBAAqB,MAAM,CACpD,QAAO,EAAE;AAEX,QAAO,CACL;EACE,MAAM,aAAa;EACnB,SAAS;GACP;GACA;GACA;GACA,GAAI,gBAAgB,EAAE,eAAe,GAAG,EAAE;GAC1C,UAAU;IACR,MAAM;IACN,sBAAsB,OAAO,YAC3B,UAAU,KAAK,QAAQ,CAAC,KAAK,KAAK,CAAC,CACpC;IACF;GACF;EACF,CACF;;AAGH,SAAS,qBAAqB,OAAyB;AAErD,SADgB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,EACvD,SAAS,gCAAgC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextclaw/nextclaw-ncp-runtime-stdio-client",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.14-beta.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Optional NCP runtime adapter backed by a protocol-aware stdio agent command.",
|
|
6
6
|
"type": "module",
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"@agentclientprotocol/sdk": "^0.19.0",
|
|
20
|
-
"@nextclaw/core": "0.14.
|
|
21
|
-
"@nextclaw/ncp": "0.6.
|
|
20
|
+
"@nextclaw/core": "0.14.5-beta.1",
|
|
21
|
+
"@nextclaw/ncp": "0.6.4-beta.1"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@types/node": "^20.17.6",
|