@ai-sdk/harness-acp 1.0.30 → 1.0.32
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 +25 -0
- package/README.md +11 -0
- package/dist/bridge/host-tool-mcp.mjs +1 -1
- package/dist/bridge/index.mjs +94 -30
- package/dist/bridge/index.mjs.map +1 -1
- package/dist/bridge/package.json +2 -2
- package/dist/bridge/pnpm-lock.yaml +57 -55
- package/dist/index.d.ts +26 -2
- package/dist/index.js +121 -104
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/src/acp-harness.ts +9 -2
- package/src/index.ts +1 -0
- package/src/v1/acp-v1-bridge-protocol.ts +27 -6
- package/src/v1/acp-v1-harness.ts +85 -47
- package/src/v1/acp-v1-lifecycle.ts +1 -29
- package/src/v1/acp-v1-prompt.ts +1 -1
- package/src/v1/acp-v1-settings.ts +20 -1
- package/src/v1/acp-v1-skills.ts +15 -56
- package/src/v1/acp-v1-turn-start-config.ts +7 -3
- package/src/v1/bridge/acp-v1-bridge-environment.ts +4 -0
- package/src/v1/bridge/index.ts +16 -5
- package/src/v1/bridge/model-mapping.ts +35 -0
- package/src/v1/bridge/package.json +2 -2
- package/src/v1/bridge/pnpm-lock.yaml +57 -55
- package/src/v1/bridge/protocol-configuration.ts +6 -2
- package/src/v1/implementation.ts +8 -0
- package/src/v1/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/harness-acp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.32",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -26,16 +26,16 @@
|
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@ai-sdk/harness": "1.0.
|
|
30
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
29
|
+
"@ai-sdk/harness": "1.0.94",
|
|
30
|
+
"@ai-sdk/provider-utils": "5.0.34",
|
|
31
31
|
"ws": "^8.21.0"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"zod": "^3.25.76 || ^4.1.8"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@agentclientprotocol/sdk": "1.
|
|
38
|
-
"@modelcontextprotocol/sdk": "1.
|
|
37
|
+
"@agentclientprotocol/sdk": "1.4.0",
|
|
38
|
+
"@modelcontextprotocol/sdk": "1.30.0",
|
|
39
39
|
"@types/node": "22.19.19",
|
|
40
40
|
"@types/ws": "^8.5.13",
|
|
41
41
|
"@vercel/ai-tsconfig": "0.0.0",
|
package/src/acp-harness.ts
CHANGED
|
@@ -48,7 +48,15 @@ export type ACPHarnessSettings<TBuiltinTools extends ToolSet = {}> = {
|
|
|
48
48
|
readonly credentialForwarding?: ACPV1Settings['credentialForwarding'];
|
|
49
49
|
readonly env?: ACPV1Settings['env'];
|
|
50
50
|
readonly authentication?: ACPV1Settings['authentication'];
|
|
51
|
+
readonly clientCapabilities?: ACPV1Settings['clientCapabilities'];
|
|
51
52
|
readonly providerAuthentication?: ACPV1Settings['providerAuthentication'];
|
|
53
|
+
/**
|
|
54
|
+
* Maps the HarnessAgent model identifier to an ACP session operation.
|
|
55
|
+
*/
|
|
56
|
+
readonly modelMapping: ACPV1Settings['modelMapping'];
|
|
57
|
+
/**
|
|
58
|
+
* @deprecated Use `model` on `HarnessAgent` instead.
|
|
59
|
+
*/
|
|
52
60
|
readonly modelId?: ACPV1Settings['modelId'];
|
|
53
61
|
readonly skillsDirectory?: ACPV1Settings['skillsDirectory'];
|
|
54
62
|
readonly instructionMapping?: ACPV1Settings['instructionMapping'];
|
|
@@ -103,8 +111,7 @@ const acpResumeStateSchema = z.object({
|
|
|
103
111
|
})
|
|
104
112
|
.optional(),
|
|
105
113
|
initialGuidanceApplied: z.boolean().optional(),
|
|
106
|
-
|
|
107
|
-
skillsFingerprint: z.string().optional(),
|
|
114
|
+
instructionsFingerprint: z.string().optional(),
|
|
108
115
|
skillsDirectory: z.string().optional(),
|
|
109
116
|
});
|
|
110
117
|
|
package/src/index.ts
CHANGED
|
@@ -14,6 +14,7 @@ import { z } from 'zod/v4';
|
|
|
14
14
|
import type { ACPToolCall } from '../acp-tool-call';
|
|
15
15
|
import type {
|
|
16
16
|
ACPInstructionMapping,
|
|
17
|
+
ACPModelMapping,
|
|
17
18
|
ACPPermissionModeMapping,
|
|
18
19
|
} from './acp-v1-settings';
|
|
19
20
|
import { acpTextContentBlockSchema } from './acp-v1-prompt';
|
|
@@ -125,6 +126,20 @@ const outputSchemaMappingSchema: z.ZodType<ACPSerializableOutputSchemaMapping> =
|
|
|
125
126
|
path: z.array(z.string().min(1)).min(1),
|
|
126
127
|
});
|
|
127
128
|
|
|
129
|
+
const modelMappingSchema: z.ZodType<ACPModelMapping> = z.discriminatedUnion(
|
|
130
|
+
'type',
|
|
131
|
+
[
|
|
132
|
+
z.object({
|
|
133
|
+
type: z.literal('session-config-option'),
|
|
134
|
+
path: z.string().min(1),
|
|
135
|
+
}),
|
|
136
|
+
z.object({
|
|
137
|
+
type: z.literal('session-model'),
|
|
138
|
+
path: z.string().min(1),
|
|
139
|
+
}),
|
|
140
|
+
],
|
|
141
|
+
);
|
|
142
|
+
|
|
128
143
|
export type ACPTurnStartConfig = {
|
|
129
144
|
readonly version: 1;
|
|
130
145
|
readonly configurationFingerprint: string;
|
|
@@ -133,6 +148,8 @@ export type ACPTurnStartConfig = {
|
|
|
133
148
|
readonly builtinTools: Array<ACPBuiltinToolMapping>;
|
|
134
149
|
readonly permissionMode: HarnessV1PermissionMode;
|
|
135
150
|
readonly permissionModeMapping?: ACPPermissionModeMapping;
|
|
151
|
+
readonly model?: string;
|
|
152
|
+
readonly modelMapping?: ACPModelMapping;
|
|
136
153
|
readonly debug?: HarnessV1DebugConfig;
|
|
137
154
|
readonly responseFormat?: z.infer<
|
|
138
155
|
typeof harnessV1BridgeStartBaseSchema
|
|
@@ -148,6 +165,8 @@ export const acpTurnStartConfigSchema = z.object({
|
|
|
148
165
|
builtinTools: z.array(builtinToolSchema).default([]),
|
|
149
166
|
permissionMode: harnessV1BridgeStartBaseSchema.shape.permissionMode.unwrap(),
|
|
150
167
|
permissionModeMapping: permissionModeMappingSchema.optional(),
|
|
168
|
+
model: harnessV1BridgeStartBaseSchema.shape.model.optional(),
|
|
169
|
+
modelMapping: modelMappingSchema.optional(),
|
|
151
170
|
debug: harnessV1BridgeStartBaseSchema.shape.debug.optional(),
|
|
152
171
|
responseFormat:
|
|
153
172
|
harnessV1BridgeStartBaseSchema.shape.responseFormat.optional(),
|
|
@@ -156,14 +175,15 @@ export const acpTurnStartConfigSchema = z.object({
|
|
|
156
175
|
|
|
157
176
|
export type ACPColdSessionState = Omit<
|
|
158
177
|
ACPTurnStartConfig,
|
|
159
|
-
'prompt' | 'debug'
|
|
160
|
-
|
|
161
|
-
readonly modelId?: string;
|
|
162
|
-
};
|
|
178
|
+
'prompt' | 'debug' | 'model' | 'modelMapping'
|
|
179
|
+
>;
|
|
163
180
|
|
|
164
181
|
export const acpColdSessionStateSchema: z.ZodType<ACPColdSessionState> =
|
|
165
|
-
acpTurnStartConfigSchema.omit({
|
|
166
|
-
|
|
182
|
+
acpTurnStartConfigSchema.omit({
|
|
183
|
+
prompt: true,
|
|
184
|
+
debug: true,
|
|
185
|
+
model: true,
|
|
186
|
+
modelMapping: true,
|
|
167
187
|
});
|
|
168
188
|
|
|
169
189
|
const lossyRecoverySchema = z.object({
|
|
@@ -203,6 +223,7 @@ export const startMessageSchema = harnessV1BridgeStartBaseSchema.extend({
|
|
|
203
223
|
tools: z.array(acpSerializableToolSpecSchema).optional(),
|
|
204
224
|
builtinTools: z.array(builtinToolSchema).readonly().default([]),
|
|
205
225
|
permissionModeMapping: permissionModeMappingSchema.optional(),
|
|
226
|
+
modelMapping: modelMappingSchema.optional(),
|
|
206
227
|
turnStartConfig: acpTurnStartConfigSchema,
|
|
207
228
|
recoveryMode: z
|
|
208
229
|
.discriminatedUnion('type', [lossyRecoverySchema, coldRestoreSchema])
|
package/src/v1/acp-v1-harness.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
type HarnessV1PortEndpoint,
|
|
10
10
|
type HarnessV1PromptControl,
|
|
11
11
|
type HarnessV1Session,
|
|
12
|
+
type HarnessV1Skill,
|
|
12
13
|
type HarnessV1StreamPart,
|
|
13
14
|
type HarnessV1ToolSpec,
|
|
14
15
|
} from '@ai-sdk/harness';
|
|
@@ -70,16 +71,16 @@ import {
|
|
|
70
71
|
} from './acp-v1-turn-start-config';
|
|
71
72
|
import {
|
|
72
73
|
resolveACPInitialGuidanceApplied,
|
|
73
|
-
shouldMaterializeACPSkills,
|
|
74
74
|
validateACPLifecycleCompatibility,
|
|
75
75
|
type ACPLifecycleData,
|
|
76
76
|
} from './acp-v1-lifecycle';
|
|
77
77
|
import {
|
|
78
78
|
convertHarnessPromptToACPTextBlocks,
|
|
79
|
-
|
|
79
|
+
prependACPInstructionGuidance,
|
|
80
80
|
} from './acp-v1-prompt';
|
|
81
81
|
import type {
|
|
82
82
|
ACPInstructionMapping,
|
|
83
|
+
ACPModelMapping,
|
|
83
84
|
ACPOutputSchemaMapping,
|
|
84
85
|
ACPPermissionModeMapping,
|
|
85
86
|
ACPPermissionModeTarget,
|
|
@@ -88,7 +89,6 @@ import type {
|
|
|
88
89
|
ACPV1Settings,
|
|
89
90
|
} from './acp-v1-settings';
|
|
90
91
|
import {
|
|
91
|
-
createACPSkillsFingerprint,
|
|
92
92
|
materializeACPSkills,
|
|
93
93
|
resolveACPPrivateSessionDirectory,
|
|
94
94
|
resolveACPSkillsDirectory,
|
|
@@ -204,6 +204,8 @@ export function createACPV1<TBuiltinTools extends ToolSet = {}>({
|
|
|
204
204
|
acpVersion: 'v1',
|
|
205
205
|
implementation,
|
|
206
206
|
clientApp,
|
|
207
|
+
clientCapabilities: settings.clientCapabilities,
|
|
208
|
+
modelMapping: settings.modelMapping,
|
|
207
209
|
providerAuthentication: providerAuthenticationCompatibility,
|
|
208
210
|
permissionModeMapping: settings.permissionModeMapping,
|
|
209
211
|
});
|
|
@@ -381,24 +383,6 @@ export function createACPV1<TBuiltinTools extends ToolSet = {}>({
|
|
|
381
383
|
sessionWorkDir: workDir,
|
|
382
384
|
});
|
|
383
385
|
const bridgeStateDir = `${privateSessionDir}/bridge`;
|
|
384
|
-
const skills = startOptions.skills ?? [];
|
|
385
|
-
const skillsFingerprint = createACPSkillsFingerprint({ skills });
|
|
386
|
-
const shouldMaterializeSkills = shouldMaterializeACPSkills({
|
|
387
|
-
isResume,
|
|
388
|
-
lifecycleState: lifecycleData,
|
|
389
|
-
skillsFingerprint,
|
|
390
|
-
skillsDirectory,
|
|
391
|
-
});
|
|
392
|
-
if (skills.length > 0) {
|
|
393
|
-
await materializeACPSkills({
|
|
394
|
-
sandbox: toolSafeSandboxSession,
|
|
395
|
-
rootDir: skillsDirectory,
|
|
396
|
-
sessionWorkDir: workDir,
|
|
397
|
-
skills,
|
|
398
|
-
shouldMaterialize: shouldMaterializeSkills,
|
|
399
|
-
abortSignal: startOptions.abortSignal,
|
|
400
|
-
});
|
|
401
|
-
}
|
|
402
386
|
const report = startOptions.observability?.report;
|
|
403
387
|
const onDiagnostic = report
|
|
404
388
|
? (frame: Parameters<typeof harnessV1DiagnosticFromBridgeFrame>[0]) =>
|
|
@@ -453,7 +437,8 @@ export function createACPV1<TBuiltinTools extends ToolSet = {}>({
|
|
|
453
437
|
harnessId: settings.harnessId,
|
|
454
438
|
channel: attachChannel,
|
|
455
439
|
proc: undefined,
|
|
456
|
-
|
|
440
|
+
modelMapping: settings.modelMapping,
|
|
441
|
+
defaultModelId: settings.modelId,
|
|
457
442
|
sessionMeta: settings.session?.meta,
|
|
458
443
|
instructionMapping: settings.instructionMapping,
|
|
459
444
|
outputSchemaMapping: settings.outputSchemaMapping,
|
|
@@ -469,7 +454,9 @@ export function createACPV1<TBuiltinTools extends ToolSet = {}>({
|
|
|
469
454
|
isResume: true,
|
|
470
455
|
lifecycleState: lifecycleData,
|
|
471
456
|
}),
|
|
472
|
-
|
|
457
|
+
instructionsFingerprint: lifecycleData.instructionsFingerprint,
|
|
458
|
+
sandbox: toolSafeSandboxSession,
|
|
459
|
+
sessionWorkDir: workDir,
|
|
473
460
|
skillsDirectory,
|
|
474
461
|
acpSessionId: lifecycleData.acpSessionId,
|
|
475
462
|
bridgePort: coords.port,
|
|
@@ -517,6 +504,7 @@ export function createACPV1<TBuiltinTools extends ToolSet = {}>({
|
|
|
517
504
|
sessionMeta: settings.session?.meta,
|
|
518
505
|
instructionMapping: settings.instructionMapping,
|
|
519
506
|
outputSchemaMapping: settings.outputSchemaMapping,
|
|
507
|
+
modelMapping: settings.modelMapping,
|
|
520
508
|
builtinTools: builtinToolCatalog,
|
|
521
509
|
permissionModeMapping,
|
|
522
510
|
mcpServers: settings.mcpServers,
|
|
@@ -543,12 +531,12 @@ export function createACPV1<TBuiltinTools extends ToolSet = {}>({
|
|
|
543
531
|
}
|
|
544
532
|
const turnStartConfig = validateACPColdSessionConfiguration({
|
|
545
533
|
coldSession,
|
|
546
|
-
modelId: settings.modelId,
|
|
547
534
|
permissionMode,
|
|
548
535
|
authenticationProfile,
|
|
549
536
|
sessionMeta: settings.session?.meta,
|
|
550
537
|
instructionMapping: settings.instructionMapping,
|
|
551
538
|
outputSchemaMapping: settings.outputSchemaMapping,
|
|
539
|
+
modelMapping: settings.modelMapping,
|
|
552
540
|
builtinTools: builtinToolCatalog,
|
|
553
541
|
permissionModeMapping,
|
|
554
542
|
mcpServers: settings.mcpServers,
|
|
@@ -607,6 +595,7 @@ export function createACPV1<TBuiltinTools extends ToolSet = {}>({
|
|
|
607
595
|
providerEnvironment:
|
|
608
596
|
sandboxProviderEnvironment == null ? undefined : {},
|
|
609
597
|
sessionMeta: settings.session?.meta,
|
|
598
|
+
clientCapabilities: settings.clientCapabilities,
|
|
610
599
|
}),
|
|
611
600
|
...sandboxProviderAuthenticationEnvironment,
|
|
612
601
|
BRIDGE_CHANNEL_TOKEN: token,
|
|
@@ -719,7 +708,8 @@ export function createACPV1<TBuiltinTools extends ToolSet = {}>({
|
|
|
719
708
|
harnessId: settings.harnessId,
|
|
720
709
|
channel,
|
|
721
710
|
proc,
|
|
722
|
-
|
|
711
|
+
modelMapping: settings.modelMapping,
|
|
712
|
+
defaultModelId: settings.modelId,
|
|
723
713
|
sessionMeta: settings.session?.meta,
|
|
724
714
|
instructionMapping: settings.instructionMapping,
|
|
725
715
|
outputSchemaMapping: settings.outputSchemaMapping,
|
|
@@ -735,7 +725,9 @@ export function createACPV1<TBuiltinTools extends ToolSet = {}>({
|
|
|
735
725
|
isResume,
|
|
736
726
|
lifecycleState: lifecycleData,
|
|
737
727
|
}),
|
|
738
|
-
|
|
728
|
+
instructionsFingerprint: lifecycleData?.instructionsFingerprint,
|
|
729
|
+
sandbox: toolSafeSandboxSession,
|
|
730
|
+
sessionWorkDir: workDir,
|
|
739
731
|
skillsDirectory,
|
|
740
732
|
acpSessionId: lifecycleData?.acpSessionId,
|
|
741
733
|
bridgePort: boundPort,
|
|
@@ -1041,7 +1033,8 @@ function createSession({
|
|
|
1041
1033
|
harnessId,
|
|
1042
1034
|
channel,
|
|
1043
1035
|
proc,
|
|
1044
|
-
|
|
1036
|
+
modelMapping,
|
|
1037
|
+
defaultModelId,
|
|
1045
1038
|
sessionMeta,
|
|
1046
1039
|
instructionMapping,
|
|
1047
1040
|
outputSchemaMapping,
|
|
@@ -1054,7 +1047,9 @@ function createSession({
|
|
|
1054
1047
|
mcpServers,
|
|
1055
1048
|
isMcpToolCall,
|
|
1056
1049
|
initialGuidanceApplied: initialGuidanceAppliedAtStart,
|
|
1057
|
-
|
|
1050
|
+
instructionsFingerprint: instructionsFingerprintAtStart,
|
|
1051
|
+
sandbox,
|
|
1052
|
+
sessionWorkDir,
|
|
1058
1053
|
skillsDirectory,
|
|
1059
1054
|
acpSessionId: acpSessionIdAtStart,
|
|
1060
1055
|
bridgePort,
|
|
@@ -1074,7 +1069,8 @@ function createSession({
|
|
|
1074
1069
|
harnessId: string;
|
|
1075
1070
|
channel: ACPChannel;
|
|
1076
1071
|
proc: Experimental_SandboxProcess | undefined;
|
|
1077
|
-
|
|
1072
|
+
modelMapping: ACPModelMapping;
|
|
1073
|
+
defaultModelId: string | undefined;
|
|
1078
1074
|
sessionMeta: Readonly<Record<string, ACPSerializableValue>> | undefined;
|
|
1079
1075
|
instructionMapping: ACPInstructionMapping | undefined;
|
|
1080
1076
|
outputSchemaMapping: ACPOutputSchemaMapping | undefined;
|
|
@@ -1087,7 +1083,9 @@ function createSession({
|
|
|
1087
1083
|
mcpServers: Record<string, unknown> | undefined;
|
|
1088
1084
|
isMcpToolCall: ((toolCall: ACPToolCall) => boolean) | undefined;
|
|
1089
1085
|
initialGuidanceApplied: boolean;
|
|
1090
|
-
|
|
1086
|
+
instructionsFingerprint: string | undefined;
|
|
1087
|
+
sandbox: SandboxSession;
|
|
1088
|
+
sessionWorkDir: string;
|
|
1091
1089
|
skillsDirectory: string;
|
|
1092
1090
|
acpSessionId: string | undefined;
|
|
1093
1091
|
bridgePort: number;
|
|
@@ -1106,6 +1104,7 @@ function createSession({
|
|
|
1106
1104
|
let stopped = false;
|
|
1107
1105
|
let turnInFlight = turnInFlightAtStart;
|
|
1108
1106
|
let initialGuidanceApplied = initialGuidanceAppliedAtStart;
|
|
1107
|
+
let instructionsFingerprint = instructionsFingerprintAtStart;
|
|
1109
1108
|
let latestACPSessionId = acpSessionIdAtStart;
|
|
1110
1109
|
let latestTurnStartConfig = turnStartConfigAtStart;
|
|
1111
1110
|
|
|
@@ -1365,7 +1364,6 @@ function createSession({
|
|
|
1365
1364
|
: {
|
|
1366
1365
|
coldSession: createACPColdSessionState({
|
|
1367
1366
|
turnStartConfig: latestTurnStartConfig,
|
|
1368
|
-
modelId,
|
|
1369
1367
|
}),
|
|
1370
1368
|
}),
|
|
1371
1369
|
...(!includeTurnStartConfig || latestTurnStartConfig == null
|
|
@@ -1374,16 +1372,34 @@ function createSession({
|
|
|
1374
1372
|
...(recoveryStatus == null ? {} : { recovery: recoveryStatus }),
|
|
1375
1373
|
...(restoration == null ? {} : { restoration }),
|
|
1376
1374
|
initialGuidanceApplied,
|
|
1377
|
-
|
|
1378
|
-
skillsFingerprint,
|
|
1375
|
+
...(instructionsFingerprint == null ? {} : { instructionsFingerprint }),
|
|
1379
1376
|
skillsDirectory,
|
|
1380
1377
|
});
|
|
1381
1378
|
|
|
1379
|
+
const synchronizeSkills = async ({
|
|
1380
|
+
skills,
|
|
1381
|
+
abortSignal,
|
|
1382
|
+
}: {
|
|
1383
|
+
skills: ReadonlyArray<HarnessV1Skill>;
|
|
1384
|
+
abortSignal?: AbortSignal;
|
|
1385
|
+
}): Promise<void> => {
|
|
1386
|
+
await materializeACPSkills({
|
|
1387
|
+
sandbox,
|
|
1388
|
+
rootDir: skillsDirectory,
|
|
1389
|
+
sessionWorkDir,
|
|
1390
|
+
skills,
|
|
1391
|
+
abortSignal,
|
|
1392
|
+
});
|
|
1393
|
+
};
|
|
1394
|
+
|
|
1382
1395
|
return {
|
|
1383
1396
|
sessionId,
|
|
1384
1397
|
isResume,
|
|
1385
|
-
...(modelId == null ? {} : { modelId }),
|
|
1386
1398
|
doPromptTurn: async options => {
|
|
1399
|
+
await synchronizeSkills({
|
|
1400
|
+
skills: options.skills,
|
|
1401
|
+
abortSignal: options.abortSignal,
|
|
1402
|
+
});
|
|
1387
1403
|
if (options.responseFormat?.type === 'json') {
|
|
1388
1404
|
if (options.responseFormat.schema == null) {
|
|
1389
1405
|
throw unsupported({
|
|
@@ -1413,6 +1429,7 @@ function createSession({
|
|
|
1413
1429
|
prompt: options.prompt,
|
|
1414
1430
|
harnessId,
|
|
1415
1431
|
});
|
|
1432
|
+
const model = options.model ?? defaultModelId;
|
|
1416
1433
|
const turnStartConfig = createACPTurnStartConfig({
|
|
1417
1434
|
prompt,
|
|
1418
1435
|
tools: options.tools ?? [],
|
|
@@ -1426,6 +1443,11 @@ function createSession({
|
|
|
1426
1443
|
instructionMapping,
|
|
1427
1444
|
responseFormat: options.responseFormat,
|
|
1428
1445
|
outputSchemaMapping,
|
|
1446
|
+
model,
|
|
1447
|
+
modelMapping,
|
|
1448
|
+
});
|
|
1449
|
+
const nextInstructionsFingerprint = fingerprintValue({
|
|
1450
|
+
value: options.instructions ?? null,
|
|
1429
1451
|
});
|
|
1430
1452
|
const control = wireTurn({
|
|
1431
1453
|
emit: options.emit,
|
|
@@ -1439,15 +1461,14 @@ function createSession({
|
|
|
1439
1461
|
turnInFlight = true;
|
|
1440
1462
|
channel.send({
|
|
1441
1463
|
type: 'start',
|
|
1442
|
-
prompt:
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
}),
|
|
1464
|
+
prompt:
|
|
1465
|
+
instructionsFingerprint !== nextInstructionsFingerprint &&
|
|
1466
|
+
(instructionMapping == null || initialGuidanceApplied)
|
|
1467
|
+
? prependACPInstructionGuidance({
|
|
1468
|
+
prompt,
|
|
1469
|
+
instructions: options.instructions,
|
|
1470
|
+
})
|
|
1471
|
+
: prompt,
|
|
1451
1472
|
...(instructionMapping == null
|
|
1452
1473
|
? {}
|
|
1453
1474
|
: {
|
|
@@ -1460,6 +1481,7 @@ function createSession({
|
|
|
1460
1481
|
builtinTools,
|
|
1461
1482
|
permissionMode,
|
|
1462
1483
|
permissionModeMapping,
|
|
1484
|
+
...(model == null ? {} : { model, modelMapping }),
|
|
1463
1485
|
...(options.responseFormat == null
|
|
1464
1486
|
? {}
|
|
1465
1487
|
: { responseFormat: options.responseFormat }),
|
|
@@ -1472,11 +1494,16 @@ function createSession({
|
|
|
1472
1494
|
});
|
|
1473
1495
|
latestTurnStartConfig = turnStartConfig;
|
|
1474
1496
|
initialGuidanceApplied = true;
|
|
1497
|
+
instructionsFingerprint = nextInstructionsFingerprint;
|
|
1475
1498
|
},
|
|
1476
1499
|
});
|
|
1477
1500
|
return control;
|
|
1478
1501
|
},
|
|
1479
1502
|
doContinueTurn: async options => {
|
|
1503
|
+
await synchronizeSkills({
|
|
1504
|
+
skills: options.skills,
|
|
1505
|
+
abortSignal: options.abortSignal,
|
|
1506
|
+
});
|
|
1480
1507
|
if (options.responseFormat?.type === 'json') {
|
|
1481
1508
|
if (options.responseFormat.schema == null) {
|
|
1482
1509
|
throw unsupported({
|
|
@@ -1518,6 +1545,12 @@ function createSession({
|
|
|
1518
1545
|
builtinTools: turnStartConfig.builtinTools,
|
|
1519
1546
|
permissionMode: turnStartConfig.permissionMode,
|
|
1520
1547
|
permissionModeMapping: turnStartConfig.permissionModeMapping,
|
|
1548
|
+
...(turnStartConfig.model == null
|
|
1549
|
+
? {}
|
|
1550
|
+
: {
|
|
1551
|
+
model: turnStartConfig.model,
|
|
1552
|
+
modelMapping: turnStartConfig.modelMapping,
|
|
1553
|
+
}),
|
|
1521
1554
|
...(turnStartConfig.responseFormat == null
|
|
1522
1555
|
? {}
|
|
1523
1556
|
: { responseFormat: turnStartConfig.responseFormat }),
|
|
@@ -1715,6 +1748,7 @@ function validateACPTurnStartConfig({
|
|
|
1715
1748
|
sessionMeta,
|
|
1716
1749
|
instructionMapping,
|
|
1717
1750
|
outputSchemaMapping,
|
|
1751
|
+
modelMapping,
|
|
1718
1752
|
builtinTools,
|
|
1719
1753
|
permissionModeMapping,
|
|
1720
1754
|
mcpServers,
|
|
@@ -1724,6 +1758,7 @@ function validateACPTurnStartConfig({
|
|
|
1724
1758
|
sessionMeta: Readonly<Record<string, ACPSerializableValue>> | undefined;
|
|
1725
1759
|
instructionMapping: ACPInstructionMapping | undefined;
|
|
1726
1760
|
outputSchemaMapping: ACPOutputSchemaMapping | undefined;
|
|
1761
|
+
modelMapping: ACPModelMapping;
|
|
1727
1762
|
builtinTools: ReadonlyArray<ACPBuiltinToolMapping>;
|
|
1728
1763
|
permissionModeMapping: ACPPermissionModeMapping | undefined;
|
|
1729
1764
|
mcpServers: Record<string, unknown> | undefined;
|
|
@@ -1741,6 +1776,8 @@ function validateACPTurnStartConfig({
|
|
|
1741
1776
|
instructionMapping,
|
|
1742
1777
|
responseFormat: turnStartConfig.responseFormat,
|
|
1743
1778
|
outputSchemaMapping,
|
|
1779
|
+
model: turnStartConfig.model,
|
|
1780
|
+
modelMapping,
|
|
1744
1781
|
});
|
|
1745
1782
|
if (
|
|
1746
1783
|
current.configurationFingerprint !==
|
|
@@ -1754,24 +1791,24 @@ function validateACPTurnStartConfig({
|
|
|
1754
1791
|
|
|
1755
1792
|
function validateACPColdSessionConfiguration({
|
|
1756
1793
|
coldSession,
|
|
1757
|
-
modelId,
|
|
1758
1794
|
permissionMode,
|
|
1759
1795
|
authenticationProfile,
|
|
1760
1796
|
sessionMeta,
|
|
1761
1797
|
instructionMapping,
|
|
1762
1798
|
outputSchemaMapping,
|
|
1799
|
+
modelMapping,
|
|
1763
1800
|
builtinTools,
|
|
1764
1801
|
permissionModeMapping,
|
|
1765
1802
|
mcpServers,
|
|
1766
1803
|
debug,
|
|
1767
1804
|
}: {
|
|
1768
1805
|
coldSession: ACPColdSessionState;
|
|
1769
|
-
modelId: string | undefined;
|
|
1770
1806
|
permissionMode: NonNullable<StartMessage['permissionMode']>;
|
|
1771
1807
|
authenticationProfile: ACPAuthenticationProfileIdentity;
|
|
1772
1808
|
sessionMeta: Readonly<Record<string, ACPSerializableValue>> | undefined;
|
|
1773
1809
|
instructionMapping: ACPInstructionMapping | undefined;
|
|
1774
1810
|
outputSchemaMapping: ACPOutputSchemaMapping | undefined;
|
|
1811
|
+
modelMapping: ACPModelMapping;
|
|
1775
1812
|
builtinTools: ReadonlyArray<ACPBuiltinToolMapping>;
|
|
1776
1813
|
permissionModeMapping: ACPPermissionModeMapping | undefined;
|
|
1777
1814
|
mcpServers: Record<string, unknown> | undefined;
|
|
@@ -1790,11 +1827,12 @@ function validateACPColdSessionConfiguration({
|
|
|
1790
1827
|
instructionMapping,
|
|
1791
1828
|
responseFormat: coldSession.responseFormat,
|
|
1792
1829
|
outputSchemaMapping,
|
|
1830
|
+
model: undefined,
|
|
1831
|
+
modelMapping,
|
|
1793
1832
|
});
|
|
1794
1833
|
if (
|
|
1795
1834
|
current.configurationFingerprint !== coldSession.configurationFingerprint ||
|
|
1796
|
-
coldSession.permissionMode !== permissionMode
|
|
1797
|
-
coldSession.modelId !== modelId
|
|
1835
|
+
coldSession.permissionMode !== permissionMode
|
|
1798
1836
|
) {
|
|
1799
1837
|
throw new Error(
|
|
1800
1838
|
'ACP cold-session state is incompatible with the current non-secret session configuration.',
|
|
@@ -6,8 +6,7 @@ import type {
|
|
|
6
6
|
|
|
7
7
|
export type ACPPromptGuidanceLifecycleState = {
|
|
8
8
|
readonly initialGuidanceApplied?: boolean;
|
|
9
|
-
readonly
|
|
10
|
-
readonly skillsFingerprint?: string;
|
|
9
|
+
readonly instructionsFingerprint?: string;
|
|
11
10
|
readonly skillsDirectory?: string;
|
|
12
11
|
};
|
|
13
12
|
|
|
@@ -47,33 +46,6 @@ export function resolveACPInitialGuidanceApplied({
|
|
|
47
46
|
return lifecycleState?.initialGuidanceApplied ?? true;
|
|
48
47
|
}
|
|
49
48
|
|
|
50
|
-
export function shouldMaterializeACPSkills({
|
|
51
|
-
isResume,
|
|
52
|
-
lifecycleState,
|
|
53
|
-
skillsFingerprint,
|
|
54
|
-
skillsDirectory,
|
|
55
|
-
}: {
|
|
56
|
-
isResume: boolean;
|
|
57
|
-
lifecycleState: ACPPromptGuidanceLifecycleState | undefined;
|
|
58
|
-
skillsFingerprint: string;
|
|
59
|
-
skillsDirectory: string;
|
|
60
|
-
}): boolean {
|
|
61
|
-
if (
|
|
62
|
-
isResume &&
|
|
63
|
-
lifecycleState?.skillsFingerprint != null &&
|
|
64
|
-
lifecycleState.skillsFingerprint !== skillsFingerprint
|
|
65
|
-
) {
|
|
66
|
-
throw new Error(
|
|
67
|
-
'ACP lifecycle state was created with a different set of skills.',
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
return (
|
|
71
|
-
!isResume ||
|
|
72
|
-
lifecycleState?.skillsMaterialized !== true ||
|
|
73
|
-
lifecycleState.skillsDirectory !== skillsDirectory
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
49
|
export function validateACPLifecycleCompatibility({
|
|
78
50
|
harnessId,
|
|
79
51
|
lifecycleHarnessId,
|
package/src/v1/acp-v1-prompt.ts
CHANGED
|
@@ -75,6 +75,16 @@ export type ACPProviderAuthentication = {
|
|
|
75
75
|
};
|
|
76
76
|
};
|
|
77
77
|
|
|
78
|
+
export type ACPModelMapping =
|
|
79
|
+
| {
|
|
80
|
+
readonly type: 'session-config-option';
|
|
81
|
+
readonly path: string;
|
|
82
|
+
}
|
|
83
|
+
| {
|
|
84
|
+
readonly type: 'session-model';
|
|
85
|
+
readonly path: string;
|
|
86
|
+
};
|
|
87
|
+
|
|
78
88
|
export type ACPCredentialBrokering = ({
|
|
79
89
|
env,
|
|
80
90
|
sandboxEnv,
|
|
@@ -143,7 +153,15 @@ export type ACPV1Settings = {
|
|
|
143
153
|
*/
|
|
144
154
|
readonly env?: Readonly<Record<string, string>>;
|
|
145
155
|
readonly authentication?: ACPAuthentication;
|
|
156
|
+
readonly clientCapabilities?: Readonly<Record<string, ACPSerializableValue>>;
|
|
146
157
|
readonly providerAuthentication?: ACPProviderAuthentication;
|
|
158
|
+
/**
|
|
159
|
+
* Maps the HarnessAgent model identifier to an ACP session operation.
|
|
160
|
+
*/
|
|
161
|
+
readonly modelMapping: ACPModelMapping;
|
|
162
|
+
/**
|
|
163
|
+
* @deprecated Use `model` on `HarnessAgent` instead.
|
|
164
|
+
*/
|
|
147
165
|
readonly modelId?: string;
|
|
148
166
|
/**
|
|
149
167
|
* Native skills directory relative to the ACP implementation's home
|
|
@@ -152,7 +170,8 @@ export type ACPV1Settings = {
|
|
|
152
170
|
readonly skillsDirectory?: string;
|
|
153
171
|
/**
|
|
154
172
|
* Routes HarnessAgent instructions to a runtime-native system or developer
|
|
155
|
-
* prompt.
|
|
173
|
+
* prompt. Changed instructions are prepended to the next user prompt when
|
|
174
|
+
* ACP does not expose a native per-turn instruction update.
|
|
156
175
|
*/
|
|
157
176
|
readonly instructionMapping?: ACPInstructionMapping;
|
|
158
177
|
/**
|