@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 +11 -0
- package/dist/bridge/host-tool-mcp.mjs +1 -1
- package/dist/bridge/index.mjs +74 -7
- package/dist/bridge/index.mjs.map +1 -1
- package/dist/index.d.ts +113 -1
- package/dist/index.js +90 -8
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/acp-harness.ts +19 -0
- package/src/acp-tool-call.ts +124 -0
- package/src/index.ts +18 -0
- package/src/v1/acp-v1-bridge-protocol.ts +17 -1
- package/src/v1/acp-v1-harness.ts +79 -3
- package/src/v1/acp-v1-settings.ts +8 -0
- package/src/v1/acp-v1-turn-start-config.ts +3 -0
- package/src/v1/bridge/create-emit-stream-event.ts +8 -1
- package/src/v1/bridge/index.ts +47 -0
- package/src/v1/bridge/stream-translator.ts +62 -5
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.
|
|
15
|
+
var VERSION = true ? "1.0.2" : "0.0.0-test";
|
|
16
16
|
function createHostToolMCPServer({
|
|
17
17
|
tools: tools2,
|
|
18
18
|
revision = 1,
|
package/dist/bridge/index.mjs
CHANGED
|
@@ -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
|
|
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({
|
|
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: {
|