@ai-sdk/harness-acp 1.0.28 → 1.0.29
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 +7 -0
- package/README.md +5 -0
- package/dist/bridge/host-tool-mcp.mjs +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.js +44 -53
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/acp-harness.ts +2 -0
- package/src/v1/acp-v1-harness.ts +23 -19
- package/src/v1/acp-v1-lifecycle.ts +8 -1
- package/src/v1/acp-v1-prompt.ts +2 -22
- package/src/v1/acp-v1-settings.ts +5 -0
- package/src/v1/acp-v1-skills.ts +38 -29
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# @ai-sdk/harness-acp
|
|
2
2
|
|
|
3
|
+
## 1.0.29
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 20312d6: fix(harness-acp): place skills in their harnesses' natively supported directory instead of applying a manual workaround
|
|
8
|
+
- @ai-sdk/harness@1.0.91
|
|
9
|
+
|
|
3
10
|
## 1.0.28
|
|
4
11
|
|
|
5
12
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -103,3 +103,8 @@ instructions below the ACP session request's `_meta` field. A
|
|
|
103
103
|
the implementation starts. Without a mapping, the adapter preserves its
|
|
104
104
|
backward-compatible behavior and prepends instructions to the first user
|
|
105
105
|
prompt.
|
|
106
|
+
|
|
107
|
+
Skills are written to `.agents/skills` below the ACP implementation's effective
|
|
108
|
+
`$HOME` and discovered natively by the implementation. Set `skillsDirectory`
|
|
109
|
+
to another relative path, such as `.claude/skills`, when required by the
|
|
110
|
+
implementation.
|
|
@@ -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.29" : "0.0.0-test";
|
|
16
16
|
function createHostToolMCPServer({
|
|
17
17
|
tools: tools2,
|
|
18
18
|
revision = 1,
|
package/dist/index.d.ts
CHANGED
|
@@ -201,6 +201,11 @@ type ACPV1Settings = {
|
|
|
201
201
|
readonly authentication?: ACPAuthentication;
|
|
202
202
|
readonly providerAuthentication?: ACPProviderAuthentication;
|
|
203
203
|
readonly modelId?: string;
|
|
204
|
+
/**
|
|
205
|
+
* Native skills directory relative to the ACP implementation's home
|
|
206
|
+
* directory. Defaults to `.agents/skills`.
|
|
207
|
+
*/
|
|
208
|
+
readonly skillsDirectory?: string;
|
|
204
209
|
/**
|
|
205
210
|
* Routes HarnessAgent instructions to a runtime-native system or developer
|
|
206
211
|
* prompt. When omitted, instructions are prepended to the first user prompt.
|
|
@@ -263,6 +268,7 @@ type ACPHarnessSettings<TBuiltinTools extends ToolSet = {}> = {
|
|
|
263
268
|
readonly authentication?: ACPV1Settings['authentication'];
|
|
264
269
|
readonly providerAuthentication?: ACPV1Settings['providerAuthentication'];
|
|
265
270
|
readonly modelId?: ACPV1Settings['modelId'];
|
|
271
|
+
readonly skillsDirectory?: ACPV1Settings['skillsDirectory'];
|
|
266
272
|
readonly instructionMapping?: ACPV1Settings['instructionMapping'];
|
|
267
273
|
readonly outputSchemaMapping?: ACPV1Settings['outputSchemaMapping'];
|
|
268
274
|
readonly permissionModeMapping?: ACPV1Settings['permissionModeMapping'];
|
package/dist/index.js
CHANGED
|
@@ -639,28 +639,15 @@ function convertHarnessPromptToACPTextBlocks({
|
|
|
639
639
|
}
|
|
640
640
|
function prependACPInitialGuidance({
|
|
641
641
|
prompt,
|
|
642
|
-
instructions
|
|
643
|
-
skills
|
|
642
|
+
instructions
|
|
644
643
|
}) {
|
|
645
644
|
const hasInstructions = instructions != null && instructions.length > 0;
|
|
646
|
-
if (!hasInstructions
|
|
645
|
+
if (!hasInstructions) return [...prompt];
|
|
647
646
|
const lines = [
|
|
648
647
|
"<session-guidance>",
|
|
649
648
|
"This block is operating guidance from the harness, not user-authored content."
|
|
650
649
|
];
|
|
651
|
-
|
|
652
|
-
lines.push("<instructions>", instructions, "</instructions>");
|
|
653
|
-
}
|
|
654
|
-
if (skills.length > 0) {
|
|
655
|
-
lines.push(
|
|
656
|
-
"<available-skills>",
|
|
657
|
-
"Load a skill only when relevant by reading its SKILL.md file at the listed absolute path."
|
|
658
|
-
);
|
|
659
|
-
for (const skill of skills) {
|
|
660
|
-
lines.push(`- ${skill.name}: ${skill.description} (${skill.path})`);
|
|
661
|
-
}
|
|
662
|
-
lines.push("</available-skills>");
|
|
663
|
-
}
|
|
650
|
+
lines.push("<instructions>", instructions, "</instructions>");
|
|
664
651
|
lines.push("</session-guidance>");
|
|
665
652
|
return [{ type: "text", text: lines.join("\n") }, ...prompt];
|
|
666
653
|
}
|
|
@@ -1015,14 +1002,15 @@ function resolveACPInitialGuidanceApplied({
|
|
|
1015
1002
|
function shouldMaterializeACPSkills({
|
|
1016
1003
|
isResume,
|
|
1017
1004
|
lifecycleState,
|
|
1018
|
-
skillsFingerprint
|
|
1005
|
+
skillsFingerprint,
|
|
1006
|
+
skillsDirectory
|
|
1019
1007
|
}) {
|
|
1020
1008
|
if (isResume && lifecycleState?.skillsFingerprint != null && lifecycleState.skillsFingerprint !== skillsFingerprint) {
|
|
1021
1009
|
throw new Error(
|
|
1022
1010
|
"ACP lifecycle state was created with a different set of skills."
|
|
1023
1011
|
);
|
|
1024
1012
|
}
|
|
1025
|
-
return !isResume || lifecycleState?.skillsMaterialized !== true;
|
|
1013
|
+
return !isResume || lifecycleState?.skillsMaterialized !== true || lifecycleState.skillsDirectory !== skillsDirectory;
|
|
1026
1014
|
}
|
|
1027
1015
|
function validateACPLifecycleCompatibility({
|
|
1028
1016
|
harnessId,
|
|
@@ -1064,6 +1052,7 @@ import { createHash as createHash4 } from "crypto";
|
|
|
1064
1052
|
import path from "path";
|
|
1065
1053
|
import { writeSkills } from "@ai-sdk/harness/utils";
|
|
1066
1054
|
var ACP_SKILL_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
1055
|
+
var DEFAULT_ACP_SKILLS_DIRECTORY = ".agents/skills";
|
|
1067
1056
|
function createACPSkillsFingerprint({
|
|
1068
1057
|
skills
|
|
1069
1058
|
}) {
|
|
@@ -1101,24 +1090,14 @@ function resolveACPPrivateSessionDirectory({
|
|
|
1101
1090
|
}
|
|
1102
1091
|
async function materializeACPSkills({
|
|
1103
1092
|
sandbox,
|
|
1104
|
-
|
|
1093
|
+
rootDir,
|
|
1105
1094
|
sessionWorkDir,
|
|
1106
|
-
harnessId,
|
|
1107
|
-
sessionId,
|
|
1108
1095
|
skills,
|
|
1109
1096
|
shouldMaterialize,
|
|
1110
1097
|
abortSignal
|
|
1111
1098
|
}) {
|
|
1112
1099
|
validateACPSkills({ skills });
|
|
1113
|
-
|
|
1114
|
-
resolveACPPrivateSessionDirectory({
|
|
1115
|
-
sandboxHomeDir,
|
|
1116
|
-
sessionWorkDir,
|
|
1117
|
-
harnessId,
|
|
1118
|
-
sessionId
|
|
1119
|
-
}),
|
|
1120
|
-
"skills"
|
|
1121
|
-
);
|
|
1100
|
+
assertOutsideSessionWorkDir({ rootDir, sessionWorkDir });
|
|
1122
1101
|
if (shouldMaterialize) {
|
|
1123
1102
|
await writeSkills({
|
|
1124
1103
|
sandbox,
|
|
@@ -1132,14 +1111,22 @@ async function materializeACPSkills({
|
|
|
1132
1111
|
)}: expected a relative POSIX path without traversal.`
|
|
1133
1112
|
});
|
|
1134
1113
|
}
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1114
|
+
}
|
|
1115
|
+
function resolveACPSkillsDirectory({
|
|
1116
|
+
implementationHomeDir,
|
|
1117
|
+
skillsDirectory = DEFAULT_ACP_SKILLS_DIRECTORY,
|
|
1118
|
+
sessionWorkDir
|
|
1119
|
+
}) {
|
|
1120
|
+
const containsTraversal = skillsDirectory.split(/[\\/]/).some((segment) => segment === "..");
|
|
1121
|
+
const normalizedDirectory = path.posix.normalize(skillsDirectory);
|
|
1122
|
+
if (skillsDirectory.length === 0 || skillsDirectory.includes("\\") || path.posix.isAbsolute(skillsDirectory) || path.win32.isAbsolute(skillsDirectory) || containsTraversal || normalizedDirectory === "." || normalizedDirectory.startsWith("../") || normalizedDirectory.includes("/../") || normalizedDirectory.endsWith("/..")) {
|
|
1123
|
+
throw new Error(
|
|
1124
|
+
`ACP skillsDirectory ${JSON.stringify(skillsDirectory)} must be a relative POSIX path without traversal.`
|
|
1125
|
+
);
|
|
1126
|
+
}
|
|
1127
|
+
const rootDir = path.posix.join(implementationHomeDir, normalizedDirectory);
|
|
1128
|
+
assertOutsideSessionWorkDir({ rootDir, sessionWorkDir });
|
|
1129
|
+
return rootDir;
|
|
1143
1130
|
}
|
|
1144
1131
|
function validateACPSkills({
|
|
1145
1132
|
skills
|
|
@@ -1420,26 +1407,29 @@ function createACPV1({
|
|
|
1420
1407
|
harnessId: settings.harnessId,
|
|
1421
1408
|
sessionId: startOptions.sessionId
|
|
1422
1409
|
});
|
|
1410
|
+
const skillsDirectory = resolveACPSkillsDirectory({
|
|
1411
|
+
implementationHomeDir: implementation.source.type === "install-command" ? `${resolvedImplementationDir}/home` : sandboxHomeDir,
|
|
1412
|
+
skillsDirectory: settings.skillsDirectory,
|
|
1413
|
+
sessionWorkDir: workDir
|
|
1414
|
+
});
|
|
1423
1415
|
const bridgeStateDir = `${privateSessionDir}/bridge`;
|
|
1424
1416
|
const skills = startOptions.skills ?? [];
|
|
1425
1417
|
const skillsFingerprint = createACPSkillsFingerprint({ skills });
|
|
1426
1418
|
const shouldMaterializeSkills = shouldMaterializeACPSkills({
|
|
1427
1419
|
isResume,
|
|
1428
1420
|
lifecycleState: lifecycleData,
|
|
1429
|
-
skillsFingerprint
|
|
1421
|
+
skillsFingerprint,
|
|
1422
|
+
skillsDirectory
|
|
1430
1423
|
});
|
|
1431
|
-
let skillCatalog = [];
|
|
1432
1424
|
if (skills.length > 0) {
|
|
1433
|
-
|
|
1425
|
+
await materializeACPSkills({
|
|
1434
1426
|
sandbox: toolSafeSandboxSession,
|
|
1435
|
-
|
|
1427
|
+
rootDir: skillsDirectory,
|
|
1436
1428
|
sessionWorkDir: workDir,
|
|
1437
|
-
harnessId: settings.harnessId,
|
|
1438
|
-
sessionId: startOptions.sessionId,
|
|
1439
1429
|
skills,
|
|
1440
1430
|
shouldMaterialize: shouldMaterializeSkills,
|
|
1441
1431
|
abortSignal: startOptions.abortSignal
|
|
1442
|
-
})
|
|
1432
|
+
});
|
|
1443
1433
|
}
|
|
1444
1434
|
const report = startOptions.observability?.report;
|
|
1445
1435
|
const onDiagnostic = report ? (frame) => report(
|
|
@@ -1506,8 +1496,8 @@ function createACPV1({
|
|
|
1506
1496
|
isResume: true,
|
|
1507
1497
|
lifecycleState: lifecycleData
|
|
1508
1498
|
}),
|
|
1509
|
-
skillCatalog,
|
|
1510
1499
|
skillsFingerprint,
|
|
1500
|
+
skillsDirectory,
|
|
1511
1501
|
acpSessionId: lifecycleData.acpSessionId,
|
|
1512
1502
|
bridgePort: coords.port,
|
|
1513
1503
|
bridgeToken: coords.token,
|
|
@@ -1744,8 +1734,8 @@ function createACPV1({
|
|
|
1744
1734
|
isResume,
|
|
1745
1735
|
lifecycleState: lifecycleData
|
|
1746
1736
|
}),
|
|
1747
|
-
skillCatalog,
|
|
1748
1737
|
skillsFingerprint,
|
|
1738
|
+
skillsDirectory,
|
|
1749
1739
|
acpSessionId: lifecycleData?.acpSessionId,
|
|
1750
1740
|
bridgePort: boundPort,
|
|
1751
1741
|
bridgeToken: token,
|
|
@@ -1983,8 +1973,8 @@ function createSession({
|
|
|
1983
1973
|
mcpServers,
|
|
1984
1974
|
isMcpToolCall,
|
|
1985
1975
|
initialGuidanceApplied: initialGuidanceAppliedAtStart,
|
|
1986
|
-
skillCatalog,
|
|
1987
1976
|
skillsFingerprint,
|
|
1977
|
+
skillsDirectory,
|
|
1988
1978
|
acpSessionId: acpSessionIdAtStart,
|
|
1989
1979
|
bridgePort,
|
|
1990
1980
|
bridgeToken,
|
|
@@ -2245,7 +2235,8 @@ function createSession({
|
|
|
2245
2235
|
...restoration == null ? {} : { restoration },
|
|
2246
2236
|
initialGuidanceApplied,
|
|
2247
2237
|
skillsMaterialized: true,
|
|
2248
|
-
skillsFingerprint
|
|
2238
|
+
skillsFingerprint,
|
|
2239
|
+
skillsDirectory
|
|
2249
2240
|
});
|
|
2250
2241
|
return {
|
|
2251
2242
|
sessionId,
|
|
@@ -2306,8 +2297,7 @@ function createSession({
|
|
|
2306
2297
|
type: "start",
|
|
2307
2298
|
prompt: initialGuidanceApplied ? prompt : prependACPInitialGuidance({
|
|
2308
2299
|
prompt,
|
|
2309
|
-
instructions: instructionMapping == null ? options.instructions : void 0
|
|
2310
|
-
skills: skillCatalog
|
|
2300
|
+
instructions: instructionMapping == null ? options.instructions : void 0
|
|
2311
2301
|
}),
|
|
2312
2302
|
...instructionMapping == null ? {} : {
|
|
2313
2303
|
instructionMapping,
|
|
@@ -2611,7 +2601,7 @@ function deserializeBridgeError({
|
|
|
2611
2601
|
}
|
|
2612
2602
|
|
|
2613
2603
|
// src/version.ts
|
|
2614
|
-
var VERSION = true ? "1.0.
|
|
2604
|
+
var VERSION = true ? "1.0.29" : "0.0.0-test";
|
|
2615
2605
|
|
|
2616
2606
|
// src/acp-harness.ts
|
|
2617
2607
|
var ACP_CLIENT_APP = {
|
|
@@ -2651,7 +2641,8 @@ var acpResumeStateSchema = z4.object({
|
|
|
2651
2641
|
}).optional(),
|
|
2652
2642
|
initialGuidanceApplied: z4.boolean().optional(),
|
|
2653
2643
|
skillsMaterialized: z4.boolean().optional(),
|
|
2654
|
-
skillsFingerprint: z4.string().optional()
|
|
2644
|
+
skillsFingerprint: z4.string().optional(),
|
|
2645
|
+
skillsDirectory: z4.string().optional()
|
|
2655
2646
|
});
|
|
2656
2647
|
function createACP(settings) {
|
|
2657
2648
|
if (settings.credentialEnv == null !== (settings.credentialBrokering == null)) {
|