@ai-sdk/harness-acp 1.0.25 → 1.0.28
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 +27 -0
- package/README.md +14 -6
- package/dist/bridge/host-tool-mcp.mjs +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +41 -61
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/acp-harness.ts +1 -0
- package/src/v1/acp-v1-harness.ts +61 -83
- package/src/v1/acp-v1-lifecycle.ts +1 -0
- package/src/v1/acp-v1-settings.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# @ai-sdk/harness-acp
|
|
2
2
|
|
|
3
|
+
## 1.0.28
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 0e590d2: feat(harness): harden credential brokering to only apply with correct ephemeral secret
|
|
8
|
+
- Updated dependencies [3e125ba]
|
|
9
|
+
- Updated dependencies [0e590d2]
|
|
10
|
+
- @ai-sdk/provider-utils@5.0.32
|
|
11
|
+
- @ai-sdk/harness@1.0.90
|
|
12
|
+
|
|
13
|
+
## 1.0.27
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- @ai-sdk/harness@1.0.89
|
|
18
|
+
|
|
19
|
+
## 1.0.26
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Updated dependencies [32349cc]
|
|
24
|
+
- Updated dependencies [a9782e1]
|
|
25
|
+
- Updated dependencies [35841f5]
|
|
26
|
+
- Updated dependencies [d2f3353]
|
|
27
|
+
- @ai-sdk/harness@1.0.88
|
|
28
|
+
- @ai-sdk/provider-utils@5.0.31
|
|
29
|
+
|
|
3
30
|
## 1.0.25
|
|
4
31
|
|
|
5
32
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -35,13 +35,20 @@ const codexACP = createACP({
|
|
|
35
35
|
},
|
|
36
36
|
executable: 'codex-acp',
|
|
37
37
|
credentialEnv: ['CODEX_API_KEY', 'OPENAI_API_KEY'],
|
|
38
|
-
credentialBrokering: ({ env }) => {
|
|
39
|
-
const
|
|
40
|
-
|
|
38
|
+
credentialBrokering: ({ env, sandboxEnv }) => {
|
|
39
|
+
const environmentVariableName = env.CODEX_API_KEY
|
|
40
|
+
? 'CODEX_API_KEY'
|
|
41
|
+
: 'OPENAI_API_KEY';
|
|
42
|
+
const credential = env[environmentVariableName];
|
|
43
|
+
const sandboxCredential = sandboxEnv?.[environmentVariableName];
|
|
44
|
+
if (!credential || !sandboxCredential) return [];
|
|
41
45
|
return [
|
|
42
46
|
createCredentialRequestTransformation({
|
|
43
|
-
|
|
44
|
-
|
|
47
|
+
matchUrl: 'https://api.openai.com/v1',
|
|
48
|
+
matchHeaders: {
|
|
49
|
+
Authorization: `Bearer ${sandboxCredential}`,
|
|
50
|
+
},
|
|
51
|
+
transformHeaders: { Authorization: `Bearer ${credential}` },
|
|
45
52
|
}),
|
|
46
53
|
];
|
|
47
54
|
},
|
|
@@ -82,7 +89,8 @@ try {
|
|
|
82
89
|
|
|
83
90
|
Set `CODEX_API_KEY` or `OPENAI_API_KEY` in the host environment. Sandboxes that
|
|
84
91
|
support additive request transformations receive only credential placeholders;
|
|
85
|
-
the real value is injected
|
|
92
|
+
the real value is injected only when a matching outbound request contains the
|
|
93
|
+
expected placeholder. Other sandboxes
|
|
86
94
|
retain the legacy behavior of forwarding the value to the ACP process. Codex
|
|
87
95
|
ACP supports only `permissionMode: 'allow-all'` because its
|
|
88
96
|
restrictive modes enable Codex's internal sandbox. A bridge-backed ACP harness
|
|
@@ -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.28" : "0.0.0-test";
|
|
16
16
|
function createHostToolMCPServer({
|
|
17
17
|
tools: tools2,
|
|
18
18
|
revision = 1,
|
package/dist/index.d.ts
CHANGED
|
@@ -145,8 +145,9 @@ type ACPProviderAuthentication = {
|
|
|
145
145
|
readonly env: Readonly<Record<string, ACPProfileValue>>;
|
|
146
146
|
};
|
|
147
147
|
};
|
|
148
|
-
type ACPCredentialBrokering = ({ env, }: {
|
|
148
|
+
type ACPCredentialBrokering = ({ env, sandboxEnv, }: {
|
|
149
149
|
env: Readonly<Record<string, string>>;
|
|
150
|
+
sandboxEnv?: Readonly<Record<string, string>>;
|
|
150
151
|
}) => ReadonlyArray<HarnessV1RequestTransformation>;
|
|
151
152
|
type ACPPermissionModeTarget = {
|
|
152
153
|
readonly type: 'session-mode';
|
package/dist/index.js
CHANGED
|
@@ -13,12 +13,12 @@ import {
|
|
|
13
13
|
applyCredentialForwarding,
|
|
14
14
|
createBridgeErrorHandler,
|
|
15
15
|
createBridgeStartupError,
|
|
16
|
+
createSandboxCredentialEnvironment,
|
|
16
17
|
classifyDiskLog,
|
|
17
18
|
drainBridgeProcessStream,
|
|
18
19
|
forwardBridgeProcessStream,
|
|
19
20
|
getRestrictedSandboxSession,
|
|
20
21
|
markBridgeStarting,
|
|
21
|
-
maskSandboxCredentials,
|
|
22
22
|
resolveSandboxDefaultWorkingDirectory,
|
|
23
23
|
resolveSandboxHomeDir,
|
|
24
24
|
SandboxChannel,
|
|
@@ -1318,6 +1318,21 @@ function createACPV1({
|
|
|
1318
1318
|
sandboxSession,
|
|
1319
1319
|
abortSignal: startOptions.abortSignal
|
|
1320
1320
|
});
|
|
1321
|
+
const continueFrom = startOptions.continueFrom ?? startOptions.resumeFrom?.continueFrom;
|
|
1322
|
+
const lifecycleState = continueFrom ?? startOptions.resumeFrom;
|
|
1323
|
+
const isContinue = continueFrom != null;
|
|
1324
|
+
const isResume = lifecycleState != null;
|
|
1325
|
+
const lifecycleData = lifecycleState != null ? lifecycleState.data : void 0;
|
|
1326
|
+
if (lifecycleData != null && lifecycleState != null) {
|
|
1327
|
+
validateACPLifecycleCompatibility({
|
|
1328
|
+
harnessId: settings.harnessId,
|
|
1329
|
+
lifecycleHarnessId: lifecycleState.harnessId,
|
|
1330
|
+
implementationIdentity,
|
|
1331
|
+
authenticationProfile,
|
|
1332
|
+
lifecycleData,
|
|
1333
|
+
sandboxId
|
|
1334
|
+
});
|
|
1335
|
+
}
|
|
1321
1336
|
const implementationEnvironment = resolveImplementationEnvironment({
|
|
1322
1337
|
implementation,
|
|
1323
1338
|
env
|
|
@@ -1340,30 +1355,35 @@ function createACPV1({
|
|
|
1340
1355
|
})
|
|
1341
1356
|
])
|
|
1342
1357
|
];
|
|
1358
|
+
let sandboxCredentialEnvironment;
|
|
1343
1359
|
if (settings.credentialBrokering != null && "addRequestTransformations" in sandboxSession && sandboxSession.addRequestTransformations != null) {
|
|
1344
1360
|
const providerEnvironment = resolveProviderEnvironment({
|
|
1345
1361
|
resolvedProviderAuthentication,
|
|
1346
1362
|
clientApp
|
|
1347
1363
|
});
|
|
1364
|
+
const brokeringEnvironment = {
|
|
1365
|
+
...implementationEnvironment,
|
|
1366
|
+
...providerEnvironment
|
|
1367
|
+
};
|
|
1368
|
+
sandboxCredentialEnvironment = lifecycleData?.sandboxCredentialEnvironment ?? await createSandboxCredentialEnvironment({
|
|
1369
|
+
environment: brokeringEnvironment,
|
|
1370
|
+
credentialEnvironmentVariables: credentialForwardingEnvironmentVariables,
|
|
1371
|
+
credentialForwarding: settings.credentialForwarding
|
|
1372
|
+
});
|
|
1373
|
+
sandboxImplementationEnvironment = {
|
|
1374
|
+
...brokeringEnvironment,
|
|
1375
|
+
...sandboxCredentialEnvironment
|
|
1376
|
+
};
|
|
1348
1377
|
const requestTransformations = settings.credentialBrokering({
|
|
1349
|
-
env:
|
|
1350
|
-
|
|
1351
|
-
...providerEnvironment
|
|
1352
|
-
}
|
|
1378
|
+
env: brokeringEnvironment,
|
|
1379
|
+
sandboxEnv: sandboxImplementationEnvironment
|
|
1353
1380
|
});
|
|
1354
1381
|
if (requestTransformations.length > 0) {
|
|
1355
1382
|
await sandboxSession.addRequestTransformations(
|
|
1356
1383
|
requestTransformations
|
|
1357
1384
|
);
|
|
1358
1385
|
}
|
|
1359
|
-
|
|
1360
|
-
environment: implementationEnvironment,
|
|
1361
|
-
credentialEnvironmentVariables
|
|
1362
|
-
});
|
|
1363
|
-
sandboxProviderEnvironment = resolveBrokeredProviderEnvironment({
|
|
1364
|
-
resolvedProviderAuthentication,
|
|
1365
|
-
clientApp
|
|
1366
|
-
});
|
|
1386
|
+
sandboxProviderEnvironment = resolvedProviderAuthentication.providerAuthentication?.type === "ai-gateway" ? {} : void 0;
|
|
1367
1387
|
} else if (settings.credentialBrokering != null) {
|
|
1368
1388
|
warnCredentialBrokeringUnavailable();
|
|
1369
1389
|
}
|
|
@@ -1401,21 +1421,6 @@ function createACPV1({
|
|
|
1401
1421
|
sessionId: startOptions.sessionId
|
|
1402
1422
|
});
|
|
1403
1423
|
const bridgeStateDir = `${privateSessionDir}/bridge`;
|
|
1404
|
-
const continueFrom = startOptions.continueFrom ?? startOptions.resumeFrom?.continueFrom;
|
|
1405
|
-
const lifecycleState = continueFrom ?? startOptions.resumeFrom;
|
|
1406
|
-
const isContinue = continueFrom != null;
|
|
1407
|
-
const isResume = lifecycleState != null;
|
|
1408
|
-
const lifecycleData = lifecycleState != null ? lifecycleState.data : void 0;
|
|
1409
|
-
if (lifecycleData != null && lifecycleState != null) {
|
|
1410
|
-
validateACPLifecycleCompatibility({
|
|
1411
|
-
harnessId: settings.harnessId,
|
|
1412
|
-
lifecycleHarnessId: lifecycleState.harnessId,
|
|
1413
|
-
implementationIdentity,
|
|
1414
|
-
authenticationProfile,
|
|
1415
|
-
lifecycleData,
|
|
1416
|
-
sandboxId
|
|
1417
|
-
});
|
|
1418
|
-
}
|
|
1419
1424
|
const skills = startOptions.skills ?? [];
|
|
1420
1425
|
const skillsFingerprint = createACPSkillsFingerprint({ skills });
|
|
1421
1426
|
const shouldMaterializeSkills = shouldMaterializeACPSkills({
|
|
@@ -1513,6 +1518,7 @@ function createACPV1({
|
|
|
1513
1518
|
turnStartConfig: lifecycleData.turnStartConfig,
|
|
1514
1519
|
recoveryStatus: lifecycleData.recovery,
|
|
1515
1520
|
restoration: lifecycleData.restoration,
|
|
1521
|
+
sandboxCredentialEnvironment,
|
|
1516
1522
|
replayOnly: false,
|
|
1517
1523
|
lossyRerun: false
|
|
1518
1524
|
});
|
|
@@ -1590,11 +1596,11 @@ function createACPV1({
|
|
|
1590
1596
|
};
|
|
1591
1597
|
}
|
|
1592
1598
|
}
|
|
1593
|
-
const forwardedImplementationEnvironment = await applyCredentialForwarding({
|
|
1599
|
+
const forwardedImplementationEnvironment = sandboxCredentialEnvironment == null ? await applyCredentialForwarding({
|
|
1594
1600
|
environment: sandboxImplementationEnvironment,
|
|
1595
1601
|
credentialEnvironmentVariables: credentialForwardingEnvironmentVariables,
|
|
1596
1602
|
credentialForwarding: settings.credentialForwarding
|
|
1597
|
-
});
|
|
1603
|
+
}) : sandboxImplementationEnvironment;
|
|
1598
1604
|
const port = resolveBridgePort({
|
|
1599
1605
|
sandboxSession,
|
|
1600
1606
|
override: portOverride,
|
|
@@ -1753,6 +1759,7 @@ function createACPV1({
|
|
|
1753
1759
|
reason: respawnStrategy.reason
|
|
1754
1760
|
} : void 0,
|
|
1755
1761
|
restoration: coldRestoration == null ? lifecycleData?.restoration : { method: coldRestoration },
|
|
1762
|
+
sandboxCredentialEnvironment,
|
|
1756
1763
|
replayOnly: respawnStrategy?.mode === "disk-replay",
|
|
1757
1764
|
lossyRerun: respawnStrategy?.mode === "lossy-rerun"
|
|
1758
1765
|
});
|
|
@@ -1782,36 +1789,6 @@ function resolveProviderEnvironment({
|
|
|
1782
1789
|
}
|
|
1783
1790
|
});
|
|
1784
1791
|
}
|
|
1785
|
-
function resolveBrokeredProviderEnvironment({
|
|
1786
|
-
resolvedProviderAuthentication,
|
|
1787
|
-
clientApp
|
|
1788
|
-
}) {
|
|
1789
|
-
const providerAuthentication = resolvedProviderAuthentication.providerAuthentication;
|
|
1790
|
-
if (providerAuthentication?.type !== "ai-gateway") return {};
|
|
1791
|
-
const baseUrl = requireResolvedEnvironmentValue({
|
|
1792
|
-
environment: resolvedProviderAuthentication.env,
|
|
1793
|
-
name: "AI_SDK_ACP_GATEWAY_BASE_URL"
|
|
1794
|
-
});
|
|
1795
|
-
return Object.fromEntries(
|
|
1796
|
-
Object.entries(providerAuthentication.env).map(
|
|
1797
|
-
([environmentVariableName, value]) => {
|
|
1798
|
-
const environment = resolveACPLaunchEnvironment({
|
|
1799
|
-
providerAuthentication: {
|
|
1800
|
-
type: "ai-gateway",
|
|
1801
|
-
env: { [environmentVariableName]: value }
|
|
1802
|
-
},
|
|
1803
|
-
gateway: {
|
|
1804
|
-
apiKey: environmentVariableName,
|
|
1805
|
-
baseUrl,
|
|
1806
|
-
clientAppName: clientApp.name,
|
|
1807
|
-
clientAppVersion: clientApp.version
|
|
1808
|
-
}
|
|
1809
|
-
});
|
|
1810
|
-
return [environmentVariableName, environment[environmentVariableName]];
|
|
1811
|
-
}
|
|
1812
|
-
)
|
|
1813
|
-
);
|
|
1814
|
-
}
|
|
1815
1792
|
function resolveACPProviderCredentialEnvironmentVariables({
|
|
1816
1793
|
providerAuthentication
|
|
1817
1794
|
}) {
|
|
@@ -2018,6 +1995,7 @@ function createSession({
|
|
|
2018
1995
|
turnStartConfig: turnStartConfigAtStart,
|
|
2019
1996
|
recoveryStatus,
|
|
2020
1997
|
restoration,
|
|
1998
|
+
sandboxCredentialEnvironment,
|
|
2021
1999
|
replayOnly,
|
|
2022
2000
|
lossyRerun
|
|
2023
2001
|
}) {
|
|
@@ -2253,6 +2231,7 @@ function createSession({
|
|
|
2253
2231
|
}) => ({
|
|
2254
2232
|
implementationIdentity,
|
|
2255
2233
|
authenticationProfile,
|
|
2234
|
+
...sandboxCredentialEnvironment == null ? {} : { sandboxCredentialEnvironment },
|
|
2256
2235
|
...latestACPSessionId == null ? {} : { acpSessionId: latestACPSessionId },
|
|
2257
2236
|
...bridge == null ? {} : { bridge },
|
|
2258
2237
|
...latestTurnStartConfig == null ? {} : {
|
|
@@ -2632,7 +2611,7 @@ function deserializeBridgeError({
|
|
|
2632
2611
|
}
|
|
2633
2612
|
|
|
2634
2613
|
// src/version.ts
|
|
2635
|
-
var VERSION = true ? "1.0.
|
|
2614
|
+
var VERSION = true ? "1.0.28" : "0.0.0-test";
|
|
2636
2615
|
|
|
2637
2616
|
// src/acp-harness.ts
|
|
2638
2617
|
var ACP_CLIENT_APP = {
|
|
@@ -2658,6 +2637,7 @@ var acpResumeStateSchema = z4.object({
|
|
|
2658
2637
|
providerMode: z4.enum(["auto", "direct", "ai-gateway"]).optional(),
|
|
2659
2638
|
gatewayCredentialSource: z4.enum(["AI_GATEWAY_API_KEY", "VERCEL_OIDC_TOKEN"]).nullable().optional()
|
|
2660
2639
|
}).optional(),
|
|
2640
|
+
sandboxCredentialEnvironment: z4.record(z4.string(), z4.string()).optional(),
|
|
2661
2641
|
acpSessionId: z4.string().optional(),
|
|
2662
2642
|
bridge: acpBridgeCoordsSchema.optional(),
|
|
2663
2643
|
coldSession: acpColdSessionStateSchema.optional(),
|