@nextclaw/nextclaw-ncp-runtime-stdio-client 0.2.12 → 0.2.13

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.
@@ -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,cAyDW,0BAAA;EAAA,iBACkB,MAAA;cAAA,MAAA,GAAQ,MAAA;EAErC,OAAA,QAAc,0BAAA;EAAA,QA6CN,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"}
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,QA6CN,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"}
@@ -41,6 +41,30 @@ function readStringRecord(value) {
41
41
  }
42
42
  return Object.keys(output).length > 0 ? output : void 0;
43
43
  }
44
+ function readCommandOverrides(value) {
45
+ if (!value || typeof value !== "object" || Array.isArray(value)) return {};
46
+ const overrides = {};
47
+ for (const [rawCommand, rawOverride] of Object.entries(value)) {
48
+ const commandKey = readString(rawCommand);
49
+ if (!commandKey || !rawOverride || typeof rawOverride !== "object" || Array.isArray(rawOverride)) continue;
50
+ const overrideRecord = rawOverride;
51
+ const command = readString(overrideRecord.command);
52
+ const args = readStringArray(overrideRecord.args);
53
+ const cwd = readString(overrideRecord.cwd);
54
+ const env = readStringRecord(overrideRecord.env);
55
+ if (!command && !args && !cwd && !env) continue;
56
+ overrides[commandKey] = {
57
+ ...command ? { command } : {},
58
+ ...args ? { args } : {},
59
+ ...cwd ? { cwd } : {},
60
+ ...env ? { env } : {}
61
+ };
62
+ }
63
+ return overrides;
64
+ }
65
+ function readCommandOverride(command) {
66
+ return readCommandOverrides(parseJsonObject(process.env.NEXTCLAW_NARP_STDIO_COMMAND_OVERRIDES))[command];
67
+ }
44
68
  var StdioRuntimeConfigResolver = class {
45
69
  constructor(source = {}) {
46
70
  this.source = source;
@@ -50,13 +74,17 @@ var StdioRuntimeConfigResolver = class {
50
74
  const processScope = this.resolveProcessScope();
51
75
  const command = readString(this.source.command) ?? readString(process.env.NEXTCLAW_NARP_STDIO_COMMAND);
52
76
  if (!command) throw new Error("[narp-stdio] missing stdio command");
77
+ const override = readCommandOverride(command);
78
+ const args = override?.args ?? readStringArray(this.source.args) ?? readStringArray(parseJsonArray(process.env.NEXTCLAW_NARP_STDIO_ARGS)) ?? [];
79
+ const cwd = override?.cwd ?? readString(this.source.cwd) ?? readString(process.env.NEXTCLAW_NARP_STDIO_CWD);
80
+ const env = override?.env ?? readStringRecord(this.source.env) ?? readStringRecord(parseJsonObject(process.env.NEXTCLAW_NARP_STDIO_ENV));
53
81
  return {
54
82
  wireDialect,
55
83
  processScope,
56
- command,
57
- args: readStringArray(this.source.args) ?? readStringArray(parseJsonArray(process.env.NEXTCLAW_NARP_STDIO_ARGS)) ?? [],
58
- ...readString(this.source.cwd) ?? readString(process.env.NEXTCLAW_NARP_STDIO_CWD) ? { cwd: readString(this.source.cwd) ?? readString(process.env.NEXTCLAW_NARP_STDIO_CWD) } : {},
59
- ...readStringRecord(this.source.env) ?? readStringRecord(parseJsonObject(process.env.NEXTCLAW_NARP_STDIO_ENV)) ? { env: readStringRecord(this.source.env) ?? readStringRecord(parseJsonObject(process.env.NEXTCLAW_NARP_STDIO_ENV)) } : {},
84
+ command: override?.command ?? command,
85
+ args,
86
+ ...cwd ? { cwd } : {},
87
+ ...env ? { env } : {},
60
88
  startupTimeoutMs: readPositiveInteger(this.source.startupTimeoutMs) ?? readPositiveInteger(process.env.NEXTCLAW_NARP_STDIO_STARTUP_TIMEOUT_MS) ?? DEFAULT_STARTUP_TIMEOUT_MS,
61
89
  probeTimeoutMs: readPositiveInteger(this.source.probeTimeoutMs) ?? DEFAULT_PROBE_TIMEOUT_MS,
62
90
  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\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\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 return {\n wireDialect,\n processScope,\n command,\n args:\n readStringArray(this.source.args) ??\n readStringArray(parseJsonArray(process.env.NEXTCLAW_NARP_STDIO_ARGS)) ??\n [],\n ...(readString(this.source.cwd) ?? readString(process.env.NEXTCLAW_NARP_STDIO_CWD)\n ? {\n cwd:\n readString(this.source.cwd) ??\n readString(process.env.NEXTCLAW_NARP_STDIO_CWD),\n }\n : {}),\n ...(readStringRecord(this.source.env) ?? readStringRecord(parseJsonObject(process.env.NEXTCLAW_NARP_STDIO_ENV))\n ? {\n env:\n readStringRecord(this.source.env) ??\n readStringRecord(parseJsonObject(process.env.NEXTCLAW_NARP_STDIO_ENV)),\n }\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
+ {"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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"}
@@ -3,9 +3,9 @@ function buildSpawnFailureMessage(params) {
3
3
  const { command, cwd, error } = params;
4
4
  return `[narp-stdio] failed to start stdio runtime command "${command}"${cwd ? ` (cwd: ${cwd})` : ""}: ${error.message}`;
5
5
  }
6
- function normalizeRuntimeError(error) {
6
+ function normalizeRuntimeError(error, diagnostics = {}) {
7
7
  if (isNcpError(error)) return error;
8
- const message = error instanceof Error ? error.message : String(error);
8
+ const message = formatRuntimeErrorMessage(error, diagnostics);
9
9
  const lowered = message.toLowerCase();
10
10
  return {
11
11
  code: lowered.includes("abort") || lowered.includes("cancel") ? "abort-error" : "runtime-error",
@@ -17,6 +17,11 @@ function isAbortLikeRuntimeError(error) {
17
17
  const lowered = (error instanceof Error ? error.message : String(error)).toLowerCase();
18
18
  return lowered.includes("abort") || lowered.includes("cancel");
19
19
  }
20
+ function formatRuntimeErrorMessage(error, diagnostics = {}) {
21
+ const message = error instanceof Error ? error.message : String(error);
22
+ const stderr = diagnostics.stderr?.trim();
23
+ return stderr && !message.includes(stderr) ? `${message}. stderr=${stderr}` : message;
24
+ }
20
25
  function isNcpError(value) {
21
26
  if (!value || typeof value !== "object") return false;
22
27
  return typeof value.code === "string" && typeof value.message === "string";
@@ -1 +1 @@
1
- {"version":3,"file":"stdio-runtime-error.utils.js","names":[],"sources":["../src/stdio-runtime-error.utils.ts"],"sourcesContent":["import type { NcpError } from \"@nextclaw/ncp\";\n\nexport function buildSpawnFailureMessage(params: {\n command: string;\n cwd?: string;\n error: Error;\n}): string {\n const { command, cwd, error } = params;\n const cwdSuffix = cwd ? ` (cwd: ${cwd})` : \"\";\n return `[narp-stdio] failed to start stdio runtime command \"${command}\"${cwdSuffix}: ${error.message}`;\n}\n\nexport function normalizeRuntimeError(error: unknown): NcpError {\n if (isNcpError(error)) {\n return error;\n }\n const message = error instanceof Error ? error.message : String(error);\n const lowered = message.toLowerCase();\n return {\n code: lowered.includes(\"abort\") || lowered.includes(\"cancel\")\n ? \"abort-error\"\n : \"runtime-error\",\n message,\n };\n}\n\nexport function isAbortLikeRuntimeError(error: unknown): boolean {\n if (isNcpError(error)) {\n return error.code === \"abort-error\";\n }\n const message = error instanceof Error ? error.message : String(error);\n const lowered = message.toLowerCase();\n return lowered.includes(\"abort\") || lowered.includes(\"cancel\");\n}\n\nfunction isNcpError(value: unknown): value is NcpError {\n if (!value || typeof value !== \"object\") {\n return false;\n }\n return typeof (value as NcpError).code === \"string\" && typeof (value as NcpError).message === \"string\";\n}\n"],"mappings":";AAEA,SAAgB,yBAAyB,QAI9B;CACT,MAAM,EAAE,SAAS,KAAK,UAAU;AAEhC,QAAO,uDAAuD,QAAQ,GADpD,MAAM,UAAU,IAAI,KAAK,GACwC,IAAI,MAAM;;AAG/F,SAAgB,sBAAsB,OAA0B;AAC9D,KAAI,WAAW,MAAM,CACnB,QAAO;CAET,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;CACtE,MAAM,UAAU,QAAQ,aAAa;AACrC,QAAO;EACL,MAAM,QAAQ,SAAS,QAAQ,IAAI,QAAQ,SAAS,SAAS,GACzD,gBACA;EACJ;EACD;;AAGH,SAAgB,wBAAwB,OAAyB;AAC/D,KAAI,WAAW,MAAM,CACnB,QAAO,MAAM,SAAS;CAGxB,MAAM,WADU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,EAC9C,aAAa;AACrC,QAAO,QAAQ,SAAS,QAAQ,IAAI,QAAQ,SAAS,SAAS;;AAGhE,SAAS,WAAW,OAAmC;AACrD,KAAI,CAAC,SAAS,OAAO,UAAU,SAC7B,QAAO;AAET,QAAO,OAAQ,MAAmB,SAAS,YAAY,OAAQ,MAAmB,YAAY"}
1
+ {"version":3,"file":"stdio-runtime-error.utils.js","names":[],"sources":["../src/stdio-runtime-error.utils.ts"],"sourcesContent":["import type { NcpError } from \"@nextclaw/ncp\";\n\nexport function buildSpawnFailureMessage(params: {\n command: string;\n cwd?: string;\n error: Error;\n}): string {\n const { command, cwd, error } = params;\n const cwdSuffix = cwd ? ` (cwd: ${cwd})` : \"\";\n return `[narp-stdio] failed to start stdio runtime command \"${command}\"${cwdSuffix}: ${error.message}`;\n}\n\nexport function normalizeRuntimeError(\n error: unknown,\n diagnostics: { stderr?: string } = {},\n): NcpError {\n if (isNcpError(error)) {\n return error;\n }\n const message = formatRuntimeErrorMessage(error, diagnostics);\n const lowered = message.toLowerCase();\n return {\n code: lowered.includes(\"abort\") || lowered.includes(\"cancel\")\n ? \"abort-error\"\n : \"runtime-error\",\n message,\n };\n}\n\nexport function isAbortLikeRuntimeError(error: unknown): boolean {\n if (isNcpError(error)) {\n return error.code === \"abort-error\";\n }\n const message = error instanceof Error ? error.message : String(error);\n const lowered = message.toLowerCase();\n return lowered.includes(\"abort\") || lowered.includes(\"cancel\");\n}\n\nexport function formatRuntimeErrorMessage(\n error: unknown,\n diagnostics: { stderr?: string } = {},\n): string {\n const message = error instanceof Error ? error.message : String(error);\n const stderr = diagnostics.stderr?.trim();\n return stderr && !message.includes(stderr) ? `${message}. stderr=${stderr}` : message;\n}\n\nfunction isNcpError(value: unknown): value is NcpError {\n if (!value || typeof value !== \"object\") {\n return false;\n }\n return typeof (value as NcpError).code === \"string\" && typeof (value as NcpError).message === \"string\";\n}\n"],"mappings":";AAEA,SAAgB,yBAAyB,QAI9B;CACT,MAAM,EAAE,SAAS,KAAK,UAAU;AAEhC,QAAO,uDAAuD,QAAQ,GADpD,MAAM,UAAU,IAAI,KAAK,GACwC,IAAI,MAAM;;AAG/F,SAAgB,sBACd,OACA,cAAmC,EAAE,EAC3B;AACV,KAAI,WAAW,MAAM,CACnB,QAAO;CAET,MAAM,UAAU,0BAA0B,OAAO,YAAY;CAC7D,MAAM,UAAU,QAAQ,aAAa;AACrC,QAAO;EACL,MAAM,QAAQ,SAAS,QAAQ,IAAI,QAAQ,SAAS,SAAS,GACzD,gBACA;EACJ;EACD;;AAGH,SAAgB,wBAAwB,OAAyB;AAC/D,KAAI,WAAW,MAAM,CACnB,QAAO,MAAM,SAAS;CAGxB,MAAM,WADU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,EAC9C,aAAa;AACrC,QAAO,QAAQ,SAAS,QAAQ,IAAI,QAAQ,SAAS,SAAS;;AAGhE,SAAgB,0BACd,OACA,cAAmC,EAAE,EAC7B;CACR,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;CACtE,MAAM,SAAS,YAAY,QAAQ,MAAM;AACzC,QAAO,UAAU,CAAC,QAAQ,SAAS,OAAO,GAAG,GAAG,QAAQ,WAAW,WAAW;;AAGhF,SAAS,WAAW,OAAmC;AACrD,KAAI,CAAC,SAAS,OAAO,UAAU,SAC7B,QAAO;AAET,QAAO,OAAQ,MAAmB,SAAS,YAAY,OAAQ,MAAmB,YAAY"}
@@ -1 +1 @@
1
- {"version":3,"file":"stdio-runtime.service.d.ts","names":[],"sources":["../src/stdio-runtime.service.ts"],"mappings":";;;;KA4BY,iCAAA,GAAoC,0BAAA;EAC9C,SAAA;EACA,YAAA,GAAe,gCAAA;EACf,YAAA,IAAgB,KAAA,EAAO,gBAAA,KAAqB,aAAA,CAAc,UAAA;EAC1D,oBAAA,IAAwB,KAAA,EAAO,gBAAA,KAAqB,uBAAA;AAAA;AAAA,cA+wBzC,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;EAclB,OAAA,QAAoB,OAAA;AAAA"}
1
+ {"version":3,"file":"stdio-runtime.service.d.ts","names":[],"sources":["../src/stdio-runtime.service.ts"],"mappings":";;;;KA6BY,iCAAA,GAAoC,0BAAA;EAC9C,SAAA;EACA,YAAA,GAAe,gCAAA;EACf,YAAA,IAAgB,KAAA,EAAO,gBAAA,KAAqB,aAAA,CAAc,UAAA;EAC1D,oBAAA,IAAwB,KAAA,EAAO,gBAAA,KAAqB,uBAAA;AAAA;AAAA,cA0yBzC,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;EAclB,OAAA,QAAoB,OAAA;AAAA"}
@@ -8,6 +8,7 @@ import * as acp from "@agentclientprotocol/sdk";
8
8
  import { NcpEventType } from "@nextclaw/ncp";
9
9
  //#region src/stdio-runtime.service.ts
10
10
  const HERMES_ACP_ROUTE_BRIDGE_ENV = "NEXTCLAW_HERMES_ACP_ROUTE_BRIDGE";
11
+ const SESSION_METADATA_PATCH_KIND = "session_metadata_patch";
11
12
  var UpdateBuffer = class {
12
13
  updates = [];
13
14
  waiters = /* @__PURE__ */ new Set();
@@ -318,6 +319,7 @@ var StdioRuntimeRunController = class {
318
319
  try {
319
320
  yield* this.drainPromptUpdates(assistantMessageId, promptState);
320
321
  if (this.shouldExitForAbort(options, promptState.error)) return;
322
+ if (promptState.error) throw promptState.error;
321
323
  yield* this.emitCompletionEvents(assistantMessageId);
322
324
  } catch (error) {
323
325
  if (this.shouldExitForAbort(options, error)) return;
@@ -395,7 +397,7 @@ var StdioRuntimeRunController = class {
395
397
  });
396
398
  };
397
399
  emitFailureEvents = async function* (assistantMessageId, error) {
398
- const ncpError = normalizeRuntimeError(error);
400
+ const ncpError = normalizeRuntimeError(error, { stderr: this.session.readStderr() });
399
401
  yield* this.emitEvent({
400
402
  type: NcpEventType.MessageFailed,
401
403
  payload: {
@@ -426,9 +428,27 @@ var StdioRuntimeRunController = class {
426
428
  case "agent_thought_chunk": return this.emitReasoningDelta(update.content, messageId);
427
429
  case "tool_call": return this.emitToolCallStart(update, messageId);
428
430
  case "tool_call_update": return this.emitToolCallUpdate(update);
431
+ case "session_info_update": return this.emitSessionInfoUpdate(update, messageId);
429
432
  default: return [];
430
433
  }
431
434
  };
435
+ emitSessionInfoUpdate = (update, messageId) => {
436
+ const patch = readSessionMetadataPatch(update._meta);
437
+ if (!patch) return [];
438
+ return [{
439
+ type: NcpEventType.RunMetadata,
440
+ payload: {
441
+ sessionId: this.input.sessionId,
442
+ messageId,
443
+ runId: this.runId,
444
+ ...this.input.correlationId ? { correlationId: this.input.correlationId } : {},
445
+ metadata: {
446
+ kind: SESSION_METADATA_PATCH_KIND,
447
+ sessionMetadataPatch: patch
448
+ }
449
+ }
450
+ }];
451
+ };
432
452
  emitTextDelta = (content, messageId) => this.emitContentDelta({
433
453
  content,
434
454
  messageId,
@@ -596,7 +616,16 @@ function extractPromptText(message) {
596
616
  }
597
617
  function resolveModelId(params) {
598
618
  const { metadata, providerRoute } = params;
599
- return providerRoute?.model ?? readString(metadata?.preferred_model) ?? readString(metadata?.preferredModel) ?? readString(metadata?.model);
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
+ function readSessionMetadataPatch(meta) {
623
+ const narpMeta = isRecord(meta) ? meta[NARP_STDIO_PROMPT_META_KEY] : void 0;
624
+ const patch = isRecord(narpMeta) ? narpMeta.sessionMetadataPatch : void 0;
625
+ return isRecord(patch) && Object.keys(patch).length > 0 ? structuredClone(patch) : null;
626
+ }
627
+ function isRecord(value) {
628
+ return typeof value === "object" && value !== null && !Array.isArray(value);
600
629
  }
601
630
  function resolveToolName(update) {
602
631
  return resolveToolNameFromAcpUpdate(update);
@@ -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 type {\n NcpAgentConversationStateManager,\n NcpAgentRunInput,\n NcpAgentRunOptions,\n NcpAgentRuntime,\n NcpEndpointEvent,\n NcpProviderRuntimeRoute,\n OpenAITool,\n} from \"@nextclaw/ncp\";\nimport { NcpEventType } 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\";\nexport type StdioRuntimeNcpAgentRuntimeConfig = StdioRuntimeResolvedConfig & {\n sessionId: string;\n stateManager?: NcpAgentConversationStateManager;\n resolveTools?: (input: NcpAgentRunInput) => ReadonlyArray<OpenAITool> | undefined;\n resolveProviderRoute?: (input: NcpAgentRunInput) => NcpProviderRuntimeRoute | undefined;\n};\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 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);\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 default:\n return [];\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 return (\n providerRoute?.model ??\n readString(metadata?.preferred_model) ??\n readString(metadata?.preferredModel) ??\n readString(metadata?.model)\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 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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextclaw/nextclaw-ncp-runtime-stdio-client",
3
- "version": "0.2.12",
3
+ "version": "0.2.13",
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.3",
21
- "@nextclaw/ncp": "0.6.2"
20
+ "@nextclaw/core": "0.14.4",
21
+ "@nextclaw/ncp": "0.6.3"
22
22
  },
23
23
  "devDependencies": {
24
24
  "@types/node": "^20.17.6",