@nextclaw/nextclaw-ncp-runtime-stdio-client 0.2.14-beta.1 → 0.2.15

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.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
+ {"version":3,"file":"stdio-runtime.service.d.ts","names":[],"sources":["../src/stdio-runtime.service.ts"],"mappings":";;;;KAkCY,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,cA8tBzC,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"}
@@ -8,6 +8,7 @@ import { spawn } from "node:child_process";
8
8
  import { Readable, Writable } from "node:stream";
9
9
  import * as acp from "@agentclientprotocol/sdk";
10
10
  import { NcpEventType } from "@nextclaw/ncp";
11
+ import { DefaultNcpAgentConversationStateManager } from "@nextclaw/ncp-toolkit";
11
12
  //#region src/stdio-runtime.service.ts
12
13
  const HERMES_ACP_ROUTE_BRIDGE_ENV = "NEXTCLAW_HERMES_ACP_ROUTE_BRIDGE";
13
14
  var UpdateBuffer = class {
@@ -35,105 +36,6 @@ var UpdateBuffer = class {
35
36
  for (const waiter of waiters) waiter();
36
37
  };
37
38
  };
38
- var PromptUpdateCollector = class {
39
- parts = [];
40
- toolIndex = /* @__PURE__ */ new Map();
41
- apply = (event) => {
42
- switch (event.type) {
43
- case NcpEventType.MessageTextDelta:
44
- this.appendPart("text", event.payload.delta);
45
- return;
46
- case NcpEventType.MessageReasoningDelta:
47
- this.appendPart("reasoning", event.payload.delta);
48
- return;
49
- case NcpEventType.MessageToolCallStart:
50
- this.upsertTool({
51
- toolCallId: event.payload.toolCallId,
52
- toolName: event.payload.toolName,
53
- args: "",
54
- state: "partial-call"
55
- });
56
- return;
57
- case NcpEventType.MessageToolCallArgs:
58
- {
59
- const tool = this.readTool(event.payload.toolCallId);
60
- this.upsertTool({
61
- toolCallId: event.payload.toolCallId,
62
- toolName: tool.toolName,
63
- args: event.payload.args,
64
- state: "partial-call"
65
- });
66
- }
67
- return;
68
- case NcpEventType.MessageToolCallArgsDelta:
69
- {
70
- const tool = this.readTool(event.payload.toolCallId);
71
- this.upsertTool({
72
- toolCallId: event.payload.toolCallId,
73
- toolName: tool.toolName,
74
- args: `${tool.args}${event.payload.delta}`,
75
- state: "partial-call"
76
- });
77
- }
78
- return;
79
- case NcpEventType.MessageToolCallEnd:
80
- {
81
- const tool = this.readTool(event.payload.toolCallId);
82
- this.upsertTool({
83
- toolCallId: event.payload.toolCallId,
84
- toolName: tool.toolName,
85
- args: tool.args,
86
- state: "call"
87
- });
88
- }
89
- return;
90
- default: return;
91
- }
92
- };
93
- hasParts = () => this.parts.length > 0;
94
- buildParts = () => structuredClone(this.parts);
95
- appendPart = (type, text) => {
96
- if (!text) return;
97
- const last = this.parts.at(-1);
98
- if (last?.type === type) {
99
- last.text = `${last.text}${text}`;
100
- return;
101
- }
102
- this.parts.push({
103
- type,
104
- text
105
- });
106
- };
107
- upsertTool = (nextTool) => {
108
- const existingIndex = this.toolIndex.get(nextTool.toolCallId);
109
- if (typeof existingIndex === "number") {
110
- const existing = this.parts[existingIndex];
111
- if (existing?.type !== "tool-invocation") return;
112
- this.parts[existingIndex] = {
113
- ...existing,
114
- ...nextTool
115
- };
116
- return;
117
- }
118
- this.toolIndex.set(nextTool.toolCallId, this.parts.length);
119
- this.parts.push({
120
- type: "tool-invocation",
121
- ...nextTool
122
- });
123
- };
124
- readTool = (toolCallId) => {
125
- const index = this.toolIndex.get(toolCallId);
126
- const part = typeof index === "number" ? this.parts[index] : null;
127
- if (part?.type !== "tool-invocation") return {
128
- toolName: "unknown",
129
- args: ""
130
- };
131
- return {
132
- toolName: part.toolName,
133
- args: part.args
134
- };
135
- };
136
- };
137
39
  var StdioRuntimeClientBridge = class {
138
40
  activeSessionId = null;
139
41
  updateHandler = null;
@@ -291,7 +193,7 @@ var StdioRuntimeSession = class {
291
193
  };
292
194
  var StdioRuntimeRunController = class {
293
195
  buffer = new UpdateBuffer();
294
- collector = new PromptUpdateCollector();
196
+ conversationStateManager;
295
197
  toolStates = /* @__PURE__ */ new Map();
296
198
  textStarted = false;
297
199
  reasoningStarted = false;
@@ -301,9 +203,9 @@ var StdioRuntimeRunController = class {
301
203
  constructor(session, input, stateManager, resolveTools, resolveProviderRoute) {
302
204
  this.session = session;
303
205
  this.input = input;
304
- this.stateManager = stateManager;
305
206
  this.resolveTools = resolveTools;
306
207
  this.resolveProviderRoute = resolveProviderRoute;
208
+ this.conversationStateManager = stateManager ?? new DefaultNcpAgentConversationStateManager();
307
209
  this.resolvedTools = resolveTools?.(input) ?? [];
308
210
  this.resolvedProviderRoute = resolveProviderRoute?.(input);
309
211
  this.runId = input.runId ?? `narp-stdio:${input.sessionId}:${randomUUID()}`;
@@ -385,20 +287,14 @@ var StdioRuntimeRunController = class {
385
287
  shouldExitForAbort = (options, error) => options?.signal?.aborted === true || isAbortLikeRuntimeError(error);
386
288
  emitCompletionEvents = async function* (assistantMessageId) {
387
289
  for (const terminalEvent of this.createTerminalEvents(assistantMessageId)) yield* this.emitEvent(terminalEvent);
388
- if (!this.collector.hasParts()) throw new Error(`[narp-stdio] ACP prompt completed without any assistant content for session ${this.input.sessionId}. stderr=${this.session.readStderr()}`);
290
+ const completedMessage = this.buildCompletedAssistantMessage(assistantMessageId);
291
+ if (!completedMessage.parts.length) throw new Error(`[narp-stdio] ACP prompt completed without any assistant content for session ${this.input.sessionId}. stderr=${this.session.readStderr()}`);
389
292
  yield* this.emitEvent({
390
293
  type: NcpEventType.MessageCompleted,
391
294
  payload: {
392
295
  sessionId: this.input.sessionId,
393
296
  correlationId: this.input.correlationId,
394
- message: {
395
- id: assistantMessageId,
396
- sessionId: this.input.sessionId,
397
- role: "assistant",
398
- status: "final",
399
- parts: this.collector.buildParts(),
400
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
401
- }
297
+ message: completedMessage
402
298
  }
403
299
  });
404
300
  yield* this.emitEvent({
@@ -440,10 +336,24 @@ var StdioRuntimeRunController = class {
440
336
  });
441
337
  };
442
338
  emitEvent = async function* (event) {
443
- this.collector.apply(event);
444
- await this.stateManager?.dispatch(event);
339
+ await this.conversationStateManager.dispatch(event);
445
340
  yield event;
446
341
  };
342
+ buildCompletedAssistantMessage = (assistantMessageId) => {
343
+ const snapshot = this.conversationStateManager.getSnapshot();
344
+ const message = snapshot.streamingMessage?.id === assistantMessageId ? snapshot.streamingMessage : snapshot.messages.find((candidate) => candidate.id === assistantMessageId);
345
+ return message ? {
346
+ ...structuredClone(message),
347
+ status: "final"
348
+ } : {
349
+ id: assistantMessageId,
350
+ sessionId: this.input.sessionId,
351
+ role: "assistant",
352
+ status: "final",
353
+ parts: [],
354
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
355
+ };
356
+ };
447
357
  translateUpdate = (update, messageId) => {
448
358
  switch (update.sessionUpdate) {
449
359
  case "agent_message_chunk": return this.emitTextDelta(update.content, messageId);
@@ -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} 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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"}
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 NcpMessage,\n type NcpProviderRuntimeRoute,\n type OpenAITool,\n} from \"@nextclaw/ncp\";\nimport { DefaultNcpAgentConversationStateManager } from \"@nextclaw/ncp-toolkit\";\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 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 conversationStateManager: NcpAgentConversationStateManager;\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 stateManager?: NcpAgentConversationStateManager,\n private readonly resolveTools?: (input: NcpAgentRunInput) => ReadonlyArray<OpenAITool> | undefined,\n private readonly resolveProviderRoute?: (input: NcpAgentRunInput) => NcpProviderRuntimeRoute | undefined,\n ) {\n this.conversationStateManager =\n stateManager ?? new DefaultNcpAgentConversationStateManager();\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 const completedMessage = this.buildCompletedAssistantMessage(assistantMessageId);\n if (!completedMessage.parts.length) {\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: completedMessage,\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 await this.conversationStateManager.dispatch(event);\n yield event;\n };\n private buildCompletedAssistantMessage = (assistantMessageId: string): NcpMessage => {\n const snapshot = this.conversationStateManager.getSnapshot();\n const message = snapshot.streamingMessage?.id === assistantMessageId\n ? snapshot.streamingMessage\n : snapshot.messages.find((candidate) => candidate.id === assistantMessageId);\n return message\n ? { ...structuredClone(message), status: \"final\" }\n : {\n id: assistantMessageId,\n sessionId: this.input.sessionId,\n role: \"assistant\",\n status: \"final\",\n parts: [],\n timestamp: new Date().toISOString(),\n };\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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextclaw/nextclaw-ncp-runtime-stdio-client",
3
- "version": "0.2.14-beta.1",
3
+ "version": "0.2.15",
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,9 @@
17
17
  ],
18
18
  "dependencies": {
19
19
  "@agentclientprotocol/sdk": "^0.19.0",
20
- "@nextclaw/core": "0.14.5-beta.1",
21
- "@nextclaw/ncp": "0.6.4-beta.1"
20
+ "@nextclaw/ncp-toolkit": "0.5.40",
21
+ "@nextclaw/core": "0.14.6",
22
+ "@nextclaw/ncp": "0.6.5"
22
23
  },
23
24
  "devDependencies": {
24
25
  "@types/node": "^20.17.6",