@ai-sdk/harness-acp 1.0.1 → 1.0.2

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 CHANGED
@@ -1,5 +1,16 @@
1
1
  # @ai-sdk/harness-acp
2
2
 
3
+ ## 1.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - a03ff6c: feat(harness): add support for per-harness MCP servers
8
+ - fc3baaf: feat(harness): add optional `mintBridgeToken(sandboxId)` to harness settings to control the bridge token value
9
+ - Updated dependencies [401a4ba]
10
+ - Updated dependencies [a03ff6c]
11
+ - @ai-sdk/provider-utils@5.0.26
12
+ - @ai-sdk/harness@1.0.65
13
+
3
14
  ## 1.0.1
4
15
 
5
16
  ### Patch Changes
@@ -12,7 +12,7 @@ import {
12
12
  ListToolsRequestSchema,
13
13
  McpError
14
14
  } from "@modelcontextprotocol/sdk/types.js";
15
- var VERSION = true ? "1.0.1" : "0.0.0-test";
15
+ var VERSION = true ? "1.0.2" : "0.0.0-test";
16
16
  function createHostToolMCPServer({
17
17
  tools: tools2,
18
18
  revision = 1,
@@ -890,6 +890,7 @@ function monitorACPAgentStderr({
890
890
  // src/v1/bridge/stream-translator.ts
891
891
  function createACPStreamTranslator({
892
892
  emit,
893
+ emitToolCallCandidate,
893
894
  builtinTools = []
894
895
  }) {
895
896
  let openBlock;
@@ -1000,13 +1001,12 @@ function createACPStreamTranslator({
1000
1001
  if (builtin != null) {
1001
1002
  state.toolName = builtin.toolName;
1002
1003
  state.nativeName = builtin.nativeName != null && builtin.toolName !== builtin.nativeName ? builtin.nativeName : void 0;
1003
- state.dynamic = false;
1004
1004
  } else {
1005
1005
  state.toolName = createDynamicToolName({
1006
1006
  programmaticName,
1007
1007
  toolCallId: state.toolCallId
1008
1008
  });
1009
- state.dynamic = true;
1009
+ emitToolCallCandidate?.({ toolCall: createACPToolCall({ state }) });
1010
1010
  }
1011
1011
  emit({
1012
1012
  type: "tool-call",
@@ -1014,7 +1014,6 @@ function createACPStreamTranslator({
1014
1014
  toolName: state.toolName,
1015
1015
  input: stringifyToolInput({ input: state.values.rawInput }),
1016
1016
  providerExecuted: true,
1017
- ...state.dynamic ? { dynamic: true } : {},
1018
1017
  ...state.nativeName == null ? {} : { nativeName: state.nativeName }
1019
1018
  });
1020
1019
  state.emittedCall = true;
@@ -1029,8 +1028,7 @@ function createACPStreamTranslator({
1029
1028
  toolCallId: state.toolCallId,
1030
1029
  toolName: state.toolName,
1031
1030
  result: createToolResult({ state }),
1032
- ...state.values.status === "failed" ? { isError: true } : {},
1033
- ...state.dynamic ? { dynamic: true } : {}
1031
+ ...state.values.status === "failed" ? { isError: true } : {}
1034
1032
  });
1035
1033
  state.emittedResult = true;
1036
1034
  pendingToolCallIds.delete(state.toolCallId);
@@ -1345,6 +1343,31 @@ function mergeToolUpdate({
1345
1343
  });
1346
1344
  if (programmaticName != null) state.values.name = programmaticName;
1347
1345
  }
1346
+ function createACPToolCall({ state }) {
1347
+ const title = getStringProperty2({
1348
+ value: state.values,
1349
+ property: "title"
1350
+ });
1351
+ const kind = state.values.kind;
1352
+ const status = state.values.status;
1353
+ return {
1354
+ toolCallId: state.toolCallId,
1355
+ title: title ?? state.toolName ?? `Tool ${state.toolCallId}`,
1356
+ ...isACPToolKind(kind) ? { kind } : {},
1357
+ ...isACPToolCallStatus(status) ? { status } : {},
1358
+ ...Array.isArray(state.values.content) ? { content: state.values.content } : {},
1359
+ ...Array.isArray(state.values.locations) ? { locations: state.values.locations } : {},
1360
+ ...Object.prototype.hasOwnProperty.call(state.values, "rawInput") ? { rawInput: state.values.rawInput } : {},
1361
+ ...Object.prototype.hasOwnProperty.call(state.values, "rawOutput") ? { rawOutput: state.values.rawOutput } : {},
1362
+ ...state.values._meta === null || isRecord3(state.values._meta) ? { _meta: state.values._meta } : {}
1363
+ };
1364
+ }
1365
+ function isACPToolKind(value) {
1366
+ return value === "read" || value === "edit" || value === "delete" || value === "move" || value === "search" || value === "execute" || value === "think" || value === "fetch" || value === "switch_mode" || value === "other";
1367
+ }
1368
+ function isACPToolCallStatus(value) {
1369
+ return value === "pending" || value === "in_progress" || value === "completed" || value === "failed";
1370
+ }
1348
1371
  function emitFileChanges({
1349
1372
  state,
1350
1373
  emit
@@ -1946,11 +1969,16 @@ function isTerminalToolUpdate(message) {
1946
1969
  // src/v1/bridge/create-emit-stream-event.ts
1947
1970
  function createEmitStreamEvent({
1948
1971
  emit,
1972
+ emitToolCallCandidate,
1949
1973
  builtinTools,
1950
1974
  hostToolServerName,
1951
1975
  hostTools
1952
1976
  }) {
1953
- const translator = createACPStreamTranslator({ emit, builtinTools });
1977
+ const translator = createACPStreamTranslator({
1978
+ emit,
1979
+ emitToolCallCandidate,
1980
+ builtinTools
1981
+ });
1954
1982
  const correlation = createHostToolCorrelation({
1955
1983
  emitSemanticUpdate: ({ message, rawUpdate }) => {
1956
1984
  translator.update({
@@ -2906,6 +2934,12 @@ async function runTurn(start, turn) {
2906
2934
  turn.emit({ type: "stream-start" });
2907
2935
  const emitStreamEvent = createEmitStreamEvent({
2908
2936
  emit: (event) => turn.emit(event),
2937
+ emitToolCallCandidate: ({ toolCall }) => {
2938
+ turn.emit({
2939
+ type: "acp-tool-call-candidate",
2940
+ toolCall
2941
+ });
2942
+ },
2909
2943
  builtinTools: start.builtinTools,
2910
2944
  hostToolServerName: HOST_TOOL_MCP_SERVER_NAME,
2911
2945
  hostTools: start.tools ?? []
@@ -2991,7 +3025,8 @@ async function ensureSession({
2991
3025
  providerAuthentication: bridgeConfiguration.providerAuthentication,
2992
3026
  sessionMeta: bridgeConfiguration.sessionMeta,
2993
3027
  permissionMode: start.permissionMode,
2994
- permissionModeMapping: start.permissionModeMapping
3028
+ permissionModeMapping: start.permissionModeMapping,
3029
+ mcpServers: start.mcpServers
2995
3030
  });
2996
3031
  if (session != null) {
2997
3032
  if (catalogRefreshError != null) throw catalogRefreshError;
@@ -3088,6 +3123,10 @@ async function ensureSession({
3088
3123
  authentication
3089
3124
  });
3090
3125
  }
3126
+ const externalMcpServers = createExternalMcpServers({
3127
+ mcpServers: start.mcpServers,
3128
+ initialization
3129
+ });
3091
3130
  const tools = start.tools ?? [];
3092
3131
  const catalogPath = `${bridgeStateDir}/host-tools.json`;
3093
3132
  await writeFile2(catalogPath, JSON.stringify(tools), { mode: 384 });
@@ -3096,6 +3135,7 @@ async function ensureSession({
3096
3135
  serverName: HOST_TOOL_MCP_SERVER_NAME
3097
3136
  });
3098
3137
  const mcpServers = [
3138
+ ...externalMcpServers,
3099
3139
  {
3100
3140
  name: HOST_TOOL_MCP_SERVER_NAME,
3101
3141
  command: process.execPath,
@@ -3197,6 +3237,33 @@ async function ensureSession({
3197
3237
  });
3198
3238
  sessionConfigurationFingerprint = fingerprint;
3199
3239
  }
3240
+ function createExternalMcpServers({
3241
+ mcpServers,
3242
+ initialization
3243
+ }) {
3244
+ if (mcpServers == null) return [];
3245
+ return Object.entries(mcpServers).map(([name2, value]) => {
3246
+ if (!isRecord6(value)) {
3247
+ throw new Error(
3248
+ `ACP MCP server ${JSON.stringify(name2)} must be configured with an object value.`
3249
+ );
3250
+ }
3251
+ if (value.type === "acp") {
3252
+ throw new HarnessBridgeCapabilityUnsupportedError({
3253
+ harnessId: bridgeType,
3254
+ message: "ACP-transport MCP servers require client-side mcp/connect handling, which this harness does not provide."
3255
+ });
3256
+ }
3257
+ const mcpCapabilities = initialization.agentCapabilities?.mcpCapabilities;
3258
+ if (value.type === "http" && mcpCapabilities?.http !== true || value.type === "sse" && mcpCapabilities?.sse !== true) {
3259
+ throw new HarnessBridgeCapabilityUnsupportedError({
3260
+ harnessId: bridgeType,
3261
+ message: `The ACP agent does not advertise support for ${value.type.toUpperCase()} MCP servers.`
3262
+ });
3263
+ }
3264
+ return { ...value, name: name2 };
3265
+ });
3266
+ }
3200
3267
  function unknownUsage2() {
3201
3268
  return {
3202
3269
  inputTokens: {