@ai-sdk/harness-acp 1.0.24 → 1.0.25
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 +93 -11
- package/dist/bridge/index.mjs.map +1 -1
- package/dist/index.d.ts +15 -1
- package/dist/index.js +119 -23
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
- package/src/acp-harness.ts +6 -0
- package/src/v1/acp-bootstrap.ts +12 -0
- package/src/v1/acp-v1-bridge-protocol.ts +14 -0
- package/src/v1/acp-v1-harness.ts +148 -31
- package/src/v1/acp-v1-settings.ts +9 -0
- package/src/v1/bridge/index.ts +44 -18
- package/src/v1/bridge/refresh-host-tool-catalog.ts +28 -0
- package/src/v1/bridge/stream-translator.ts +65 -0
- package/src/v1/implementation.ts +13 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HarnessV1RequestTransformation, HarnessV1PermissionMode, HarnessV1PortEndpoint, HarnessV1 } from '@ai-sdk/harness';
|
|
1
|
+
import { HarnessV1RequestTransformation, HarnessV1CredentialForwarding, HarnessV1PermissionMode, HarnessV1PortEndpoint, HarnessV1 } from '@ai-sdk/harness';
|
|
2
2
|
import { ToolSet } from '@ai-sdk/provider-utils';
|
|
3
3
|
|
|
4
4
|
type ACPMetadata = Record<string, unknown>;
|
|
@@ -126,6 +126,8 @@ type ACPNpmLockedSource = {
|
|
|
126
126
|
readonly type: 'npm-locked';
|
|
127
127
|
readonly packageJson: string;
|
|
128
128
|
readonly pnpmLockYaml: string;
|
|
129
|
+
/** Optional pnpm workspace configuration required by the locked install. */
|
|
130
|
+
readonly pnpmWorkspaceYaml?: string;
|
|
129
131
|
};
|
|
130
132
|
type ACPInstallCommandSource = {
|
|
131
133
|
readonly type: 'install-command';
|
|
@@ -184,6 +186,12 @@ type ACPV1Settings = {
|
|
|
184
186
|
readonly forwardEnv?: ReadonlyArray<string>;
|
|
185
187
|
readonly credentialEnv?: ReadonlyArray<string>;
|
|
186
188
|
readonly credentialBrokering?: ACPCredentialBrokering;
|
|
189
|
+
/**
|
|
190
|
+
* Customizes each credential value before it is forwarded into a sandbox
|
|
191
|
+
* process. This does not restrict which credentials the harness adapter can
|
|
192
|
+
* discover, read, or otherwise access in the host process.
|
|
193
|
+
*/
|
|
194
|
+
readonly credentialForwarding?: HarnessV1CredentialForwarding;
|
|
187
195
|
/**
|
|
188
196
|
* Runtime environment values that are safe to persist in bootstrap and
|
|
189
197
|
* lifecycle compatibility identity.
|
|
@@ -244,6 +252,12 @@ type ACPHarnessSettings<TBuiltinTools extends ToolSet = {}> = {
|
|
|
244
252
|
readonly forwardEnv?: ACPV1Settings['forwardEnv'];
|
|
245
253
|
readonly credentialEnv?: ACPV1Settings['credentialEnv'];
|
|
246
254
|
readonly credentialBrokering?: ACPV1Settings['credentialBrokering'];
|
|
255
|
+
/**
|
|
256
|
+
* Customizes each credential value before it is forwarded into a sandbox
|
|
257
|
+
* process. This does not restrict which credentials the harness adapter can
|
|
258
|
+
* discover, read, or otherwise access in the host process.
|
|
259
|
+
*/
|
|
260
|
+
readonly credentialForwarding?: ACPV1Settings['credentialForwarding'];
|
|
247
261
|
readonly env?: ACPV1Settings['env'];
|
|
248
262
|
readonly authentication?: ACPV1Settings['authentication'];
|
|
249
263
|
readonly providerAuthentication?: ACPV1Settings['providerAuthentication'];
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
} from "@ai-sdk/harness";
|
|
11
11
|
import { HarnessBridgeCapabilityUnsupportedError } from "@ai-sdk/harness/bridge";
|
|
12
12
|
import {
|
|
13
|
+
applyCredentialForwarding,
|
|
13
14
|
createBridgeErrorHandler,
|
|
14
15
|
createBridgeStartupError,
|
|
15
16
|
classifyDiskLog,
|
|
@@ -201,6 +202,9 @@ function validateACPV1Implementation(implementation) {
|
|
|
201
202
|
if (source.pnpmLockYaml.length === 0) {
|
|
202
203
|
throw new Error("ACP source.pnpmLockYaml must not be empty.");
|
|
203
204
|
}
|
|
205
|
+
if (source.pnpmWorkspaceYaml?.length === 0) {
|
|
206
|
+
throw new Error("ACP source.pnpmWorkspaceYaml must not be empty.");
|
|
207
|
+
}
|
|
204
208
|
} else if (source.type === "npm-simple") {
|
|
205
209
|
validateNpmSimpleSource({ source });
|
|
206
210
|
} else if (source.command.trim().length === 0) {
|
|
@@ -264,6 +268,12 @@ function getImplementationLockfile({
|
|
|
264
268
|
const { source } = implementation;
|
|
265
269
|
return source.type === "npm-locked" ? source.pnpmLockYaml : void 0;
|
|
266
270
|
}
|
|
271
|
+
function getImplementationWorkspaceFile({
|
|
272
|
+
implementation
|
|
273
|
+
}) {
|
|
274
|
+
const { source } = implementation;
|
|
275
|
+
return source.type === "npm-locked" ? source.pnpmWorkspaceYaml : void 0;
|
|
276
|
+
}
|
|
267
277
|
function createImplementationDescriptor({
|
|
268
278
|
implementation
|
|
269
279
|
}) {
|
|
@@ -290,7 +300,8 @@ function createImplementationIdentity({
|
|
|
290
300
|
const sourceIdentity = source.type === "npm-locked" ? {
|
|
291
301
|
type: source.type,
|
|
292
302
|
packageJson: source.packageJson,
|
|
293
|
-
pnpmLockYaml: source.pnpmLockYaml
|
|
303
|
+
pnpmLockYaml: source.pnpmLockYaml,
|
|
304
|
+
pnpmWorkspaceYaml: source.pnpmWorkspaceYaml
|
|
294
305
|
} : source.type === "npm-simple" ? {
|
|
295
306
|
type: source.type,
|
|
296
307
|
packageName: source.packageName,
|
|
@@ -462,6 +473,9 @@ function createACPBootstrap({
|
|
|
462
473
|
const implementationLock = getImplementationLockfile({
|
|
463
474
|
implementation
|
|
464
475
|
});
|
|
476
|
+
const implementationWorkspace = getImplementationWorkspaceFile({
|
|
477
|
+
implementation
|
|
478
|
+
});
|
|
465
479
|
const implementationInstallScript = getImplementationInstallScript({
|
|
466
480
|
implementation
|
|
467
481
|
});
|
|
@@ -498,6 +512,12 @@ function createACPBootstrap({
|
|
|
498
512
|
content: implementationLock
|
|
499
513
|
}
|
|
500
514
|
],
|
|
515
|
+
...implementationWorkspace == null ? [] : [
|
|
516
|
+
{
|
|
517
|
+
path: `${bootstrapDir}/implementation/pnpm-workspace.yaml`,
|
|
518
|
+
content: implementationWorkspace
|
|
519
|
+
}
|
|
520
|
+
],
|
|
501
521
|
...implementationInstallScript == null ? [] : [
|
|
502
522
|
{
|
|
503
523
|
path: `${bootstrapDir}/implementation/install.sh`,
|
|
@@ -658,6 +678,8 @@ function unsupportedPromptContent({
|
|
|
658
678
|
var builtinToolSchema = z2.object({
|
|
659
679
|
toolName: z2.string(),
|
|
660
680
|
nativeName: z2.string().optional(),
|
|
681
|
+
title: z2.string().optional(),
|
|
682
|
+
toolUseKind: z2.enum(["readonly", "edit", "bash"]).optional(),
|
|
661
683
|
inputSchema: z2.json().optional()
|
|
662
684
|
});
|
|
663
685
|
var jsonValueSchema = z2.json();
|
|
@@ -1303,18 +1325,26 @@ function createACPV1({
|
|
|
1303
1325
|
let sandboxImplementationEnvironment = implementationEnvironment;
|
|
1304
1326
|
let sandboxProviderAuthenticationEnvironment = resolvedProviderAuthentication.env;
|
|
1305
1327
|
let sandboxProviderEnvironment;
|
|
1328
|
+
const credentialEnvironmentVariables = [
|
|
1329
|
+
.../* @__PURE__ */ new Set([
|
|
1330
|
+
...settings.credentialEnv ?? [],
|
|
1331
|
+
"AI_GATEWAY_API_KEY",
|
|
1332
|
+
"VERCEL_OIDC_TOKEN"
|
|
1333
|
+
])
|
|
1334
|
+
];
|
|
1335
|
+
const credentialForwardingEnvironmentVariables = [
|
|
1336
|
+
.../* @__PURE__ */ new Set([
|
|
1337
|
+
...credentialEnvironmentVariables,
|
|
1338
|
+
...resolveACPProviderCredentialEnvironmentVariables({
|
|
1339
|
+
providerAuthentication: resolvedProviderAuthentication.providerAuthentication
|
|
1340
|
+
})
|
|
1341
|
+
])
|
|
1342
|
+
];
|
|
1306
1343
|
if (settings.credentialBrokering != null && "addRequestTransformations" in sandboxSession && sandboxSession.addRequestTransformations != null) {
|
|
1307
1344
|
const providerEnvironment = resolveProviderEnvironment({
|
|
1308
1345
|
resolvedProviderAuthentication,
|
|
1309
1346
|
clientApp
|
|
1310
1347
|
});
|
|
1311
|
-
const credentialEnvironmentVariables = [
|
|
1312
|
-
.../* @__PURE__ */ new Set([
|
|
1313
|
-
...settings.credentialEnv ?? [],
|
|
1314
|
-
"AI_GATEWAY_API_KEY",
|
|
1315
|
-
"VERCEL_OIDC_TOKEN"
|
|
1316
|
-
])
|
|
1317
|
-
];
|
|
1318
1348
|
const requestTransformations = settings.credentialBrokering({
|
|
1319
1349
|
env: {
|
|
1320
1350
|
...implementationEnvironment,
|
|
@@ -1330,21 +1360,29 @@ function createACPV1({
|
|
|
1330
1360
|
environment: implementationEnvironment,
|
|
1331
1361
|
credentialEnvironmentVariables
|
|
1332
1362
|
});
|
|
1333
|
-
sandboxProviderEnvironment =
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1363
|
+
sandboxProviderEnvironment = resolveBrokeredProviderEnvironment({
|
|
1364
|
+
resolvedProviderAuthentication,
|
|
1365
|
+
clientApp
|
|
1366
|
+
});
|
|
1367
|
+
} else if (settings.credentialBrokering != null) {
|
|
1368
|
+
warnCredentialBrokeringUnavailable();
|
|
1369
|
+
}
|
|
1370
|
+
if (settings.credentialForwarding != null && sandboxProviderEnvironment == null && resolvedProviderAuthentication.providerAuthentication?.type === "ai-gateway") {
|
|
1371
|
+
sandboxProviderEnvironment = resolveProviderEnvironment({
|
|
1372
|
+
resolvedProviderAuthentication,
|
|
1373
|
+
clientApp
|
|
1340
1374
|
});
|
|
1375
|
+
}
|
|
1376
|
+
if (sandboxProviderEnvironment != null) {
|
|
1377
|
+
sandboxImplementationEnvironment = {
|
|
1378
|
+
...sandboxImplementationEnvironment,
|
|
1379
|
+
...sandboxProviderEnvironment
|
|
1380
|
+
};
|
|
1341
1381
|
sandboxProviderAuthenticationEnvironment = Object.fromEntries(
|
|
1342
1382
|
Object.entries(resolvedProviderAuthentication.env).filter(
|
|
1343
1383
|
([key]) => key !== "AI_SDK_ACP_GATEWAY_API_KEY" && key !== "AI_SDK_ACP_GATEWAY_BASE_URL"
|
|
1344
1384
|
)
|
|
1345
1385
|
);
|
|
1346
|
-
} else if (settings.credentialBrokering != null) {
|
|
1347
|
-
warnCredentialBrokeringUnavailable();
|
|
1348
1386
|
}
|
|
1349
1387
|
const resolvedBridgeDir = posix.resolve(
|
|
1350
1388
|
defaultWorkingDirectory,
|
|
@@ -1552,6 +1590,11 @@ function createACPV1({
|
|
|
1552
1590
|
};
|
|
1553
1591
|
}
|
|
1554
1592
|
}
|
|
1593
|
+
const forwardedImplementationEnvironment = await applyCredentialForwarding({
|
|
1594
|
+
environment: sandboxImplementationEnvironment,
|
|
1595
|
+
credentialEnvironmentVariables: credentialForwardingEnvironmentVariables,
|
|
1596
|
+
credentialForwarding: settings.credentialForwarding
|
|
1597
|
+
});
|
|
1555
1598
|
const port = resolveBridgePort({
|
|
1556
1599
|
sandboxSession,
|
|
1557
1600
|
override: portOverride,
|
|
@@ -1571,11 +1614,11 @@ function createACPV1({
|
|
|
1571
1614
|
const proc = await toolSafeSandboxSession.spawn({
|
|
1572
1615
|
command: `node ${shellQuote(`${resolvedBridgeDir}/bridge.mjs`)} --workdir ${shellQuote(workDir)} --bridge-state-dir ${shellQuote(bridgeStateDir)} --implementation-dir ${shellQuote(resolvedImplementationDir)} --bridge-type ${shellQuote(settings.harnessId)}`,
|
|
1573
1616
|
env: {
|
|
1574
|
-
...
|
|
1617
|
+
...forwardedImplementationEnvironment,
|
|
1575
1618
|
...createACPBridgeEnvironment({
|
|
1576
1619
|
authentication: settings.authentication,
|
|
1577
1620
|
providerAuthentication: resolvedProviderAuthentication.providerAuthentication,
|
|
1578
|
-
providerEnvironment: sandboxProviderEnvironment,
|
|
1621
|
+
providerEnvironment: sandboxProviderEnvironment == null ? void 0 : {},
|
|
1579
1622
|
sessionMeta: settings.session?.meta
|
|
1580
1623
|
}),
|
|
1581
1624
|
...sandboxProviderAuthenticationEnvironment,
|
|
@@ -1718,8 +1761,7 @@ function createACPV1({
|
|
|
1718
1761
|
}
|
|
1719
1762
|
function resolveProviderEnvironment({
|
|
1720
1763
|
resolvedProviderAuthentication,
|
|
1721
|
-
clientApp
|
|
1722
|
-
gatewayApiKey
|
|
1764
|
+
clientApp
|
|
1723
1765
|
}) {
|
|
1724
1766
|
if (resolvedProviderAuthentication.providerAuthentication?.type !== "ai-gateway") {
|
|
1725
1767
|
return {};
|
|
@@ -1727,7 +1769,7 @@ function resolveProviderEnvironment({
|
|
|
1727
1769
|
return resolveACPLaunchEnvironment({
|
|
1728
1770
|
providerAuthentication: resolvedProviderAuthentication.providerAuthentication,
|
|
1729
1771
|
gateway: {
|
|
1730
|
-
apiKey:
|
|
1772
|
+
apiKey: requireResolvedEnvironmentValue({
|
|
1731
1773
|
environment: resolvedProviderAuthentication.env,
|
|
1732
1774
|
name: "AI_SDK_ACP_GATEWAY_API_KEY"
|
|
1733
1775
|
}),
|
|
@@ -1740,6 +1782,56 @@ function resolveProviderEnvironment({
|
|
|
1740
1782
|
}
|
|
1741
1783
|
});
|
|
1742
1784
|
}
|
|
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
|
+
function resolveACPProviderCredentialEnvironmentVariables({
|
|
1816
|
+
providerAuthentication
|
|
1817
|
+
}) {
|
|
1818
|
+
if (providerAuthentication?.type !== "ai-gateway") return [];
|
|
1819
|
+
return Object.entries(providerAuthentication.env).filter(([, value]) => containsACPProviderCredential({ value })).map(([name]) => name);
|
|
1820
|
+
}
|
|
1821
|
+
function containsACPProviderCredential({
|
|
1822
|
+
value
|
|
1823
|
+
}) {
|
|
1824
|
+
if (Array.isArray(value)) {
|
|
1825
|
+
return value.some((item) => containsACPProviderCredential({ value: item }));
|
|
1826
|
+
}
|
|
1827
|
+
if (value == null || typeof value !== "object") return false;
|
|
1828
|
+
if ("$source" in value) {
|
|
1829
|
+
return value.$source === "gateway-api-key" || value.$source === "gateway-authorization";
|
|
1830
|
+
}
|
|
1831
|
+
return Object.values(value).some(
|
|
1832
|
+
(item) => containsACPProviderCredential({ value: item })
|
|
1833
|
+
);
|
|
1834
|
+
}
|
|
1743
1835
|
function requireResolvedEnvironmentValue({
|
|
1744
1836
|
environment,
|
|
1745
1837
|
name
|
|
@@ -2418,6 +2510,8 @@ function serializeBuiltinTools({
|
|
|
2418
2510
|
}) {
|
|
2419
2511
|
return Object.entries(builtinTools).map(([toolName, tool]) => {
|
|
2420
2512
|
const nativeName = tool != null && typeof tool === "object" && "nativeName" in tool && typeof tool.nativeName === "string" ? tool.nativeName : void 0;
|
|
2513
|
+
const title = tool != null && typeof tool === "object" && "title" in tool && typeof tool.title === "string" ? tool.title : void 0;
|
|
2514
|
+
const toolUseKind = tool != null && typeof tool === "object" && "toolUseKind" in tool && (tool.toolUseKind === "readonly" || tool.toolUseKind === "edit" || tool.toolUseKind === "bash") ? tool.toolUseKind : void 0;
|
|
2421
2515
|
let inputSchema;
|
|
2422
2516
|
if (tool != null && typeof tool === "object" && "inputSchema" in tool && tool.inputSchema != null) {
|
|
2423
2517
|
try {
|
|
@@ -2430,6 +2524,8 @@ function serializeBuiltinTools({
|
|
|
2430
2524
|
return {
|
|
2431
2525
|
toolName,
|
|
2432
2526
|
...nativeName == null ? {} : { nativeName },
|
|
2527
|
+
...title == null ? {} : { title },
|
|
2528
|
+
...toolUseKind == null ? {} : { toolUseKind },
|
|
2433
2529
|
...inputSchema == null ? {} : { inputSchema }
|
|
2434
2530
|
};
|
|
2435
2531
|
});
|
|
@@ -2536,7 +2632,7 @@ function deserializeBridgeError({
|
|
|
2536
2632
|
}
|
|
2537
2633
|
|
|
2538
2634
|
// src/version.ts
|
|
2539
|
-
var VERSION = true ? "1.0.
|
|
2635
|
+
var VERSION = true ? "1.0.25" : "0.0.0-test";
|
|
2540
2636
|
|
|
2541
2637
|
// src/acp-harness.ts
|
|
2542
2638
|
var ACP_CLIENT_APP = {
|