@ai-sdk/harness-acp 1.0.9 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/bridge/host-tool-mcp.mjs +1 -1
- package/dist/bridge/host-tool-mcp.mjs.map +1 -1
- package/dist/bridge/index.mjs +4 -10
- package/dist/bridge/index.mjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/v1/bridge/stream-translator.ts +4 -14
package/CHANGELOG.md
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
ListToolsRequestSchema,
|
|
13
13
|
McpError
|
|
14
14
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
15
|
-
var VERSION = true ? "1.0.
|
|
15
|
+
var VERSION = true ? "1.0.10" : "0.0.0-test";
|
|
16
16
|
function createHostToolMCPServer({
|
|
17
17
|
tools: tools2,
|
|
18
18
|
revision = 1,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/v1/bridge/host-tool-mcp.ts","../../src/v1/bridge/host-tool-mcp-server.ts","../../src/v1/bridge/host-tool-relay-client.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport { readFile } from 'node:fs/promises';\nimport { env } from 'node:process';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport type { HarnessV1BridgeToolWire } from '@ai-sdk/harness';\nimport {\n createHostToolMCPServer,\n type HostToolMCPInvocationResult,\n} from './host-tool-mcp-server';\nimport { postHostToolRelay } from './host-tool-relay-client';\n\nconst catalogPath = requireEnvironmentVariable({\n name: 'AI_SDK_ACP_HOST_TOOLS_FILE',\n});\nconst relayUrl = requireEnvironmentVariable({\n name: 'AI_SDK_ACP_HOST_TOOL_RELAY_URL',\n});\nconst relayCredential = requireEnvironmentVariable({\n name: 'AI_SDK_ACP_HOST_TOOL_RELAY_CREDENTIAL',\n});\nconst tools = await readToolCatalog({ path: catalogPath });\nconst hostToolServer = createHostToolMCPServer({\n tools,\n invoke: async ({ toolName, input, catalogRevision }) =>\n validateInvocationResult({\n value: await postRelay({\n path: '/invoke',\n body: {\n requestId: randomUUID(),\n toolName,\n input,\n catalogRevision,\n },\n }),\n }),\n onListTools: async ({ revision }) => {\n await postRelay({\n path: '/catalog/seen',\n body: { revision },\n });\n },\n});\n\nawait hostToolServer.server.connect(new StdioServerTransport());\nvoid watchCatalog({\n initialRevision: 1,\n updateCatalog: hostToolServer.updateCatalog,\n}).catch(error => {\n process.stderr.write(\n `Host tool catalog synchronization failed: ${\n error instanceof Error ? error.message : String(error)\n }\\n`,\n );\n void hostToolServer.server.close();\n process.exitCode = 1;\n});\n\nasync function watchCatalog({\n initialRevision,\n updateCatalog,\n}: {\n initialRevision: number;\n updateCatalog: (options: {\n revision: number;\n tools: ReadonlyArray<HarnessV1BridgeToolWire>;\n }) => Promise<void>;\n}): Promise<void> {\n let revision = initialRevision;\n for (;;) {\n const value = await postRelay({\n path: '/catalog/next',\n body: { afterRevision: revision },\n });\n if (isRecord(value) && value.closed === true) return;\n if (\n !isRecord(value) ||\n !Number.isSafeInteger(value.revision) ||\n (value.revision as number) < revision\n ) {\n throw new Error('Invalid host tool catalog poll response.');\n }\n const nextRevision = value.revision as number;\n if (nextRevision === revision) continue;\n const nextTools = validateToolCatalog({ value: value.tools });\n await updateCatalog({ revision: nextRevision, tools: nextTools });\n revision = nextRevision;\n }\n}\n\nasync function postRelay({\n path,\n body,\n}: {\n path: string;\n body: Readonly<Record<string, unknown>>;\n}): Promise<unknown> {\n const response = await postHostToolRelay({\n relayUrl,\n relayCredential,\n path,\n body,\n });\n const { value } = response;\n if (!response.ok) {\n throw new Error(readErrorMessage({ value, status: response.status }));\n }\n return value;\n}\n\nfunction validateToolCatalog({\n value,\n}: {\n value: unknown;\n}): ReadonlyArray<HarnessV1BridgeToolWire> {\n if (!Array.isArray(value) || !value.every(isTool)) {\n throw new Error('Invalid host tool catalog.');\n }\n return value;\n}\n\nasync function readToolCatalog({\n path,\n}: {\n path: string;\n}): Promise<ReadonlyArray<HarnessV1BridgeToolWire>> {\n const text = await readFile(path, 'utf8');\n const value = await new Response(text, {\n headers: { 'content-type': 'application/json' },\n }).json();\n return validateToolCatalog({ value });\n}\n\nfunction isTool(value: unknown): value is HarnessV1BridgeToolWire {\n return (\n isRecord(value) &&\n typeof value.name === 'string' &&\n (value.description === undefined ||\n typeof value.description === 'string') &&\n (value.inputSchema === undefined ||\n (isRecord(value.inputSchema) && !Array.isArray(value.inputSchema)))\n );\n}\n\nfunction validateInvocationResult({\n value,\n}: {\n value: unknown;\n}): HostToolMCPInvocationResult {\n if (\n !isRecord(value) ||\n typeof value.correlationToken !== 'string' ||\n (value.isError !== undefined && typeof value.isError !== 'boolean')\n ) {\n throw new Error('Invalid host tool relay response.');\n }\n return {\n output: value.output,\n ...(value.isError ? { isError: true } : {}),\n correlationToken: value.correlationToken,\n };\n}\n\nfunction readErrorMessage({\n value,\n status,\n}: {\n value: unknown;\n status: number;\n}): string {\n return isRecord(value) && typeof value.error === 'string'\n ? value.error\n : `Host tool relay returned HTTP ${status}.`;\n}\n\nfunction requireEnvironmentVariable({ name }: { name: string }): string {\n const value = env[name];\n if (value == null || value.length === 0) {\n throw new Error(`Missing ${name}.`);\n }\n return value;\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return value != null && typeof value === 'object' && !Array.isArray(value);\n}\n","import { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport {\n CallToolRequestSchema,\n ErrorCode,\n ListToolsRequestSchema,\n McpError,\n type CallToolResult,\n type Tool,\n} from '@modelcontextprotocol/sdk/types.js';\nimport type { HarnessV1BridgeToolWire } from '@ai-sdk/harness';\n\ndeclare const __PACKAGE_VERSION__: string | undefined;\n\nconst VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n\nexport type HostToolMCPInvocationResult = {\n readonly output: unknown;\n readonly isError?: boolean;\n readonly correlationToken: string;\n};\n\nexport type HostToolMCPServer = {\n readonly server: Server;\n updateCatalog(options: {\n revision: number;\n tools: ReadonlyArray<HarnessV1BridgeToolWire>;\n }): Promise<void>;\n};\n\nexport function createHostToolMCPServer({\n tools,\n revision = 1,\n invoke,\n onListTools,\n}: {\n tools: ReadonlyArray<HarnessV1BridgeToolWire>;\n revision?: number;\n invoke: (options: {\n toolName: string;\n input: Readonly<Record<string, unknown>>;\n catalogRevision: number;\n }) => Promise<HostToolMCPInvocationResult>;\n onListTools?: (options: { revision: number }) => Promise<void>;\n}): HostToolMCPServer {\n let catalog = createCatalog({ revision, tools });\n let catalogAcknowledgmentError: unknown;\n const server = new Server(\n {\n name: '@ai-sdk/harness-acp-host-tools',\n version: VERSION,\n },\n { capabilities: { tools: { listChanged: true } } },\n );\n\n server.setRequestHandler(ListToolsRequestSchema, async () => {\n if (catalogAcknowledgmentError != null) {\n throw catalogAcknowledgmentError;\n }\n const current = catalog;\n if (onListTools != null) {\n setImmediate(() => {\n void onListTools({ revision: current.revision }).catch(error => {\n catalogAcknowledgmentError = error;\n });\n });\n }\n return { tools: current.tools.map(toMCPTool) };\n });\n server.setRequestHandler(CallToolRequestSchema, async request => {\n const current = catalog;\n const tool = current.byName.get(request.params.name);\n if (tool == null) {\n throw new McpError(\n ErrorCode.InvalidParams,\n `Unknown host tool: ${request.params.name}`,\n );\n }\n const input = request.params.arguments ?? {};\n const result = await invoke({\n toolName: tool.name,\n input,\n catalogRevision: current.revision,\n });\n return toCallToolResult({ result });\n });\n\n return {\n server,\n updateCatalog: async ({ revision: nextRevision, tools: nextTools }) => {\n catalog = createCatalog({\n revision: nextRevision,\n tools: nextTools,\n });\n await server.sendToolListChanged();\n },\n };\n}\n\nfunction createCatalog({\n revision,\n tools,\n}: {\n revision: number;\n tools: ReadonlyArray<HarnessV1BridgeToolWire>;\n}): {\n readonly revision: number;\n readonly tools: ReadonlyArray<HarnessV1BridgeToolWire>;\n readonly byName: ReadonlyMap<string, HarnessV1BridgeToolWire>;\n} {\n return {\n revision,\n tools: [...tools],\n byName: new Map(tools.map(tool => [tool.name, tool])),\n };\n}\n\nfunction toMCPTool(tool: HarnessV1BridgeToolWire): Tool {\n return {\n name: tool.name,\n ...(tool.description == null ? {} : { description: tool.description }),\n inputSchema: requireObjectSchema({\n toolName: tool.name,\n schema: tool.inputSchema ?? { type: 'object' },\n }),\n };\n}\n\nfunction requireObjectSchema({\n toolName,\n schema,\n}: {\n toolName: string;\n schema: unknown;\n}): Tool['inputSchema'] {\n if (\n schema == null ||\n typeof schema !== 'object' ||\n Array.isArray(schema) ||\n (Reflect.get(schema, 'type') !== undefined &&\n Reflect.get(schema, 'type') !== 'object')\n ) {\n throw new Error(\n `Host tool ${toolName} must use an object JSON Schema for MCP.`,\n );\n }\n return schema as Tool['inputSchema'];\n}\n\nfunction toCallToolResult({\n result,\n}: {\n result: HostToolMCPInvocationResult;\n}): CallToolResult {\n return {\n content: [\n {\n type: 'text',\n text: stringifyOutput({ output: result.output }),\n },\n ],\n ...(result.isError ? { isError: true } : {}),\n _meta: {\n 'ai-sdk-harness-acp-correlation': result.correlationToken,\n },\n };\n}\n\nfunction stringifyOutput({ output }: { output: unknown }): string {\n if (output === undefined) return 'null';\n try {\n return JSON.stringify(output);\n } catch {\n return JSON.stringify({\n error: 'Host tool output could not be serialized as JSON.',\n });\n }\n}\n","import { Agent, request } from 'node:http';\n\n/*\n * A host-tool call can remain pending while a person reviews an approval.\n * The loopback connection therefore must not impose an inactivity deadline.\n */\nconst relayAgent = new Agent({ keepAlive: true, timeout: 0 });\n\nexport async function postHostToolRelay({\n relayUrl,\n relayCredential,\n path,\n body,\n}: {\n relayUrl: string;\n relayCredential: string;\n path: string;\n body: Readonly<Record<string, unknown>>;\n}): Promise<{ status: number; ok: boolean; value: unknown }> {\n const serializedBody = JSON.stringify(body);\n\n return new Promise((resolve, reject) => {\n const relayRequest = request(\n new URL(path, relayUrl),\n {\n agent: relayAgent,\n method: 'POST',\n headers: {\n authorization: `Bearer ${relayCredential}`,\n 'content-type': 'application/json',\n 'content-length': Buffer.byteLength(serializedBody),\n },\n },\n response => {\n const chunks: Buffer[] = [];\n response.on('data', (chunk: Buffer) => chunks.push(chunk));\n response.on('error', reject);\n response.on('end', () => {\n void new Response(Buffer.concat(chunks)).json().then(value => {\n const status = response.statusCode ?? 0;\n resolve({\n status,\n ok: status >= 200 && status < 300,\n value,\n });\n }, reject);\n });\n },\n );\n relayRequest.on('error', reject);\n relayRequest.end(serializedBody);\n });\n}\n"],"mappings":"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","names":["tools","request","relayUrl","relayCredential"]}
|
|
1
|
+
{"version":3,"sources":["../../src/v1/bridge/host-tool-mcp.ts","../../src/v1/bridge/host-tool-mcp-server.ts","../../src/v1/bridge/host-tool-relay-client.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport { readFile } from 'node:fs/promises';\nimport { env } from 'node:process';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport type { HarnessV1BridgeToolWire } from '@ai-sdk/harness';\nimport {\n createHostToolMCPServer,\n type HostToolMCPInvocationResult,\n} from './host-tool-mcp-server';\nimport { postHostToolRelay } from './host-tool-relay-client';\n\nconst catalogPath = requireEnvironmentVariable({\n name: 'AI_SDK_ACP_HOST_TOOLS_FILE',\n});\nconst relayUrl = requireEnvironmentVariable({\n name: 'AI_SDK_ACP_HOST_TOOL_RELAY_URL',\n});\nconst relayCredential = requireEnvironmentVariable({\n name: 'AI_SDK_ACP_HOST_TOOL_RELAY_CREDENTIAL',\n});\nconst tools = await readToolCatalog({ path: catalogPath });\nconst hostToolServer = createHostToolMCPServer({\n tools,\n invoke: async ({ toolName, input, catalogRevision }) =>\n validateInvocationResult({\n value: await postRelay({\n path: '/invoke',\n body: {\n requestId: randomUUID(),\n toolName,\n input,\n catalogRevision,\n },\n }),\n }),\n onListTools: async ({ revision }) => {\n await postRelay({\n path: '/catalog/seen',\n body: { revision },\n });\n },\n});\n\nawait hostToolServer.server.connect(new StdioServerTransport());\nvoid watchCatalog({\n initialRevision: 1,\n updateCatalog: hostToolServer.updateCatalog,\n}).catch(error => {\n process.stderr.write(\n `Host tool catalog synchronization failed: ${\n error instanceof Error ? error.message : String(error)\n }\\n`,\n );\n void hostToolServer.server.close();\n process.exitCode = 1;\n});\n\nasync function watchCatalog({\n initialRevision,\n updateCatalog,\n}: {\n initialRevision: number;\n updateCatalog: (options: {\n revision: number;\n tools: ReadonlyArray<HarnessV1BridgeToolWire>;\n }) => Promise<void>;\n}): Promise<void> {\n let revision = initialRevision;\n for (;;) {\n const value = await postRelay({\n path: '/catalog/next',\n body: { afterRevision: revision },\n });\n if (isRecord(value) && value.closed === true) return;\n if (\n !isRecord(value) ||\n !Number.isSafeInteger(value.revision) ||\n (value.revision as number) < revision\n ) {\n throw new Error('Invalid host tool catalog poll response.');\n }\n const nextRevision = value.revision as number;\n if (nextRevision === revision) continue;\n const nextTools = validateToolCatalog({ value: value.tools });\n await updateCatalog({ revision: nextRevision, tools: nextTools });\n revision = nextRevision;\n }\n}\n\nasync function postRelay({\n path,\n body,\n}: {\n path: string;\n body: Readonly<Record<string, unknown>>;\n}): Promise<unknown> {\n const response = await postHostToolRelay({\n relayUrl,\n relayCredential,\n path,\n body,\n });\n const { value } = response;\n if (!response.ok) {\n throw new Error(readErrorMessage({ value, status: response.status }));\n }\n return value;\n}\n\nfunction validateToolCatalog({\n value,\n}: {\n value: unknown;\n}): ReadonlyArray<HarnessV1BridgeToolWire> {\n if (!Array.isArray(value) || !value.every(isTool)) {\n throw new Error('Invalid host tool catalog.');\n }\n return value;\n}\n\nasync function readToolCatalog({\n path,\n}: {\n path: string;\n}): Promise<ReadonlyArray<HarnessV1BridgeToolWire>> {\n const text = await readFile(path, 'utf8');\n const value = await new Response(text, {\n headers: { 'content-type': 'application/json' },\n }).json();\n return validateToolCatalog({ value });\n}\n\nfunction isTool(value: unknown): value is HarnessV1BridgeToolWire {\n return (\n isRecord(value) &&\n typeof value.name === 'string' &&\n (value.description === undefined ||\n typeof value.description === 'string') &&\n (value.inputSchema === undefined ||\n (isRecord(value.inputSchema) && !Array.isArray(value.inputSchema)))\n );\n}\n\nfunction validateInvocationResult({\n value,\n}: {\n value: unknown;\n}): HostToolMCPInvocationResult {\n if (\n !isRecord(value) ||\n typeof value.correlationToken !== 'string' ||\n (value.isError !== undefined && typeof value.isError !== 'boolean')\n ) {\n throw new Error('Invalid host tool relay response.');\n }\n return {\n output: value.output,\n ...(value.isError ? { isError: true } : {}),\n correlationToken: value.correlationToken,\n };\n}\n\nfunction readErrorMessage({\n value,\n status,\n}: {\n value: unknown;\n status: number;\n}): string {\n return isRecord(value) && typeof value.error === 'string'\n ? value.error\n : `Host tool relay returned HTTP ${status}.`;\n}\n\nfunction requireEnvironmentVariable({ name }: { name: string }): string {\n const value = env[name];\n if (value == null || value.length === 0) {\n throw new Error(`Missing ${name}.`);\n }\n return value;\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return value != null && typeof value === 'object' && !Array.isArray(value);\n}\n","import { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport {\n CallToolRequestSchema,\n ErrorCode,\n ListToolsRequestSchema,\n McpError,\n type CallToolResult,\n type Tool,\n} from '@modelcontextprotocol/sdk/types.js';\nimport type { HarnessV1BridgeToolWire } from '@ai-sdk/harness';\n\ndeclare const __PACKAGE_VERSION__: string | undefined;\n\nconst VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n\nexport type HostToolMCPInvocationResult = {\n readonly output: unknown;\n readonly isError?: boolean;\n readonly correlationToken: string;\n};\n\nexport type HostToolMCPServer = {\n readonly server: Server;\n updateCatalog(options: {\n revision: number;\n tools: ReadonlyArray<HarnessV1BridgeToolWire>;\n }): Promise<void>;\n};\n\nexport function createHostToolMCPServer({\n tools,\n revision = 1,\n invoke,\n onListTools,\n}: {\n tools: ReadonlyArray<HarnessV1BridgeToolWire>;\n revision?: number;\n invoke: (options: {\n toolName: string;\n input: Readonly<Record<string, unknown>>;\n catalogRevision: number;\n }) => Promise<HostToolMCPInvocationResult>;\n onListTools?: (options: { revision: number }) => Promise<void>;\n}): HostToolMCPServer {\n let catalog = createCatalog({ revision, tools });\n let catalogAcknowledgmentError: unknown;\n const server = new Server(\n {\n name: '@ai-sdk/harness-acp-host-tools',\n version: VERSION,\n },\n { capabilities: { tools: { listChanged: true } } },\n );\n\n server.setRequestHandler(ListToolsRequestSchema, async () => {\n if (catalogAcknowledgmentError != null) {\n throw catalogAcknowledgmentError;\n }\n const current = catalog;\n if (onListTools != null) {\n setImmediate(() => {\n void onListTools({ revision: current.revision }).catch(error => {\n catalogAcknowledgmentError = error;\n });\n });\n }\n return { tools: current.tools.map(toMCPTool) };\n });\n server.setRequestHandler(CallToolRequestSchema, async request => {\n const current = catalog;\n const tool = current.byName.get(request.params.name);\n if (tool == null) {\n throw new McpError(\n ErrorCode.InvalidParams,\n `Unknown host tool: ${request.params.name}`,\n );\n }\n const input = request.params.arguments ?? {};\n const result = await invoke({\n toolName: tool.name,\n input,\n catalogRevision: current.revision,\n });\n return toCallToolResult({ result });\n });\n\n return {\n server,\n updateCatalog: async ({ revision: nextRevision, tools: nextTools }) => {\n catalog = createCatalog({\n revision: nextRevision,\n tools: nextTools,\n });\n await server.sendToolListChanged();\n },\n };\n}\n\nfunction createCatalog({\n revision,\n tools,\n}: {\n revision: number;\n tools: ReadonlyArray<HarnessV1BridgeToolWire>;\n}): {\n readonly revision: number;\n readonly tools: ReadonlyArray<HarnessV1BridgeToolWire>;\n readonly byName: ReadonlyMap<string, HarnessV1BridgeToolWire>;\n} {\n return {\n revision,\n tools: [...tools],\n byName: new Map(tools.map(tool => [tool.name, tool])),\n };\n}\n\nfunction toMCPTool(tool: HarnessV1BridgeToolWire): Tool {\n return {\n name: tool.name,\n ...(tool.description == null ? {} : { description: tool.description }),\n inputSchema: requireObjectSchema({\n toolName: tool.name,\n schema: tool.inputSchema ?? { type: 'object' },\n }),\n };\n}\n\nfunction requireObjectSchema({\n toolName,\n schema,\n}: {\n toolName: string;\n schema: unknown;\n}): Tool['inputSchema'] {\n if (\n schema == null ||\n typeof schema !== 'object' ||\n Array.isArray(schema) ||\n (Reflect.get(schema, 'type') !== undefined &&\n Reflect.get(schema, 'type') !== 'object')\n ) {\n throw new Error(\n `Host tool ${toolName} must use an object JSON Schema for MCP.`,\n );\n }\n return schema as Tool['inputSchema'];\n}\n\nfunction toCallToolResult({\n result,\n}: {\n result: HostToolMCPInvocationResult;\n}): CallToolResult {\n return {\n content: [\n {\n type: 'text',\n text: stringifyOutput({ output: result.output }),\n },\n ],\n ...(result.isError ? { isError: true } : {}),\n _meta: {\n 'ai-sdk-harness-acp-correlation': result.correlationToken,\n },\n };\n}\n\nfunction stringifyOutput({ output }: { output: unknown }): string {\n if (output === undefined) return 'null';\n try {\n return JSON.stringify(output);\n } catch {\n return JSON.stringify({\n error: 'Host tool output could not be serialized as JSON.',\n });\n }\n}\n","import { Agent, request } from 'node:http';\n\n/*\n * A host-tool call can remain pending while a person reviews an approval.\n * The loopback connection therefore must not impose an inactivity deadline.\n */\nconst relayAgent = new Agent({ keepAlive: true, timeout: 0 });\n\nexport async function postHostToolRelay({\n relayUrl,\n relayCredential,\n path,\n body,\n}: {\n relayUrl: string;\n relayCredential: string;\n path: string;\n body: Readonly<Record<string, unknown>>;\n}): Promise<{ status: number; ok: boolean; value: unknown }> {\n const serializedBody = JSON.stringify(body);\n\n return new Promise((resolve, reject) => {\n const relayRequest = request(\n new URL(path, relayUrl),\n {\n agent: relayAgent,\n method: 'POST',\n headers: {\n authorization: `Bearer ${relayCredential}`,\n 'content-type': 'application/json',\n 'content-length': Buffer.byteLength(serializedBody),\n },\n },\n response => {\n const chunks: Buffer[] = [];\n response.on('data', (chunk: Buffer) => chunks.push(chunk));\n response.on('error', reject);\n response.on('end', () => {\n void new Response(Buffer.concat(chunks)).json().then(value => {\n const status = response.statusCode ?? 0;\n resolve({\n status,\n ok: status >= 200 && status < 300,\n value,\n });\n }, reject);\n });\n },\n );\n relayRequest.on('error', reject);\n relayRequest.end(serializedBody);\n });\n}\n"],"mappings":"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","names":["tools","request","relayUrl","relayCredential"]}
|
package/dist/bridge/index.mjs
CHANGED
|
@@ -897,7 +897,6 @@ function createACPStreamTranslator({
|
|
|
897
897
|
let openBlock;
|
|
898
898
|
let blockCounter = 0;
|
|
899
899
|
let stepOpen = false;
|
|
900
|
-
let completedToolStepEligible = false;
|
|
901
900
|
let finished = false;
|
|
902
901
|
const blockIdCounts = /* @__PURE__ */ new Map();
|
|
903
902
|
const toolStates = /* @__PURE__ */ new Map();
|
|
@@ -953,10 +952,9 @@ function createACPStreamTranslator({
|
|
|
953
952
|
harnessMetadata: { acp: { inferredStep: true } }
|
|
954
953
|
});
|
|
955
954
|
stepOpen = false;
|
|
956
|
-
completedToolStepEligible = false;
|
|
957
955
|
};
|
|
958
|
-
const
|
|
959
|
-
if (!stepOpen ||
|
|
956
|
+
const finishCompletedToolStep = () => {
|
|
957
|
+
if (!stepOpen || pendingToolCallIds.size > 0) {
|
|
960
958
|
return;
|
|
961
959
|
}
|
|
962
960
|
emitInferredStep({
|
|
@@ -1020,7 +1018,6 @@ function createACPStreamTranslator({
|
|
|
1020
1018
|
state.emittedCall = true;
|
|
1021
1019
|
stepOpen = true;
|
|
1022
1020
|
pendingToolCallIds.add(state.toolCallId);
|
|
1023
|
-
completedToolStepEligible = false;
|
|
1024
1021
|
}
|
|
1025
1022
|
emitFileChanges({ state, emit });
|
|
1026
1023
|
if (!state.emittedResult && (state.values.status === "completed" || state.values.status === "failed")) {
|
|
@@ -1033,7 +1030,7 @@ function createACPStreamTranslator({
|
|
|
1033
1030
|
});
|
|
1034
1031
|
state.emittedResult = true;
|
|
1035
1032
|
pendingToolCallIds.delete(state.toolCallId);
|
|
1036
|
-
|
|
1033
|
+
finishCompletedToolStep();
|
|
1037
1034
|
}
|
|
1038
1035
|
};
|
|
1039
1036
|
const hostToolCall = ({
|
|
@@ -1051,7 +1048,6 @@ function createACPStreamTranslator({
|
|
|
1051
1048
|
});
|
|
1052
1049
|
stepOpen = true;
|
|
1053
1050
|
pendingToolCallIds.add(toolCallId);
|
|
1054
|
-
completedToolStepEligible = false;
|
|
1055
1051
|
};
|
|
1056
1052
|
const hostToolResult = ({
|
|
1057
1053
|
toolCallId,
|
|
@@ -1068,7 +1064,7 @@ function createACPStreamTranslator({
|
|
|
1068
1064
|
...isError ? { isError: true } : {}
|
|
1069
1065
|
});
|
|
1070
1066
|
pendingToolCallIds.delete(toolCallId);
|
|
1071
|
-
|
|
1067
|
+
finishCompletedToolStep();
|
|
1072
1068
|
};
|
|
1073
1069
|
return {
|
|
1074
1070
|
update: (options) => {
|
|
@@ -1082,7 +1078,6 @@ function createACPStreamTranslator({
|
|
|
1082
1078
|
emit({ type: "raw", rawValue: preservedUpdate });
|
|
1083
1079
|
}
|
|
1084
1080
|
if (update.sessionUpdate === "agent_message_chunk" && update.content?.type === "text" && typeof update.content.text === "string") {
|
|
1085
|
-
flushCompletedToolStep();
|
|
1086
1081
|
emitContent({
|
|
1087
1082
|
type: "text",
|
|
1088
1083
|
text: update.content.text,
|
|
@@ -1091,7 +1086,6 @@ function createACPStreamTranslator({
|
|
|
1091
1086
|
return;
|
|
1092
1087
|
}
|
|
1093
1088
|
if (update.sessionUpdate === "agent_thought_chunk" && update.content?.type === "text" && typeof update.content.text === "string") {
|
|
1094
|
-
flushCompletedToolStep();
|
|
1095
1089
|
emitContent({
|
|
1096
1090
|
type: "reasoning",
|
|
1097
1091
|
text: update.content.text,
|