@ai-sdk/harness-acp 1.0.45 → 1.0.46

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 CHANGED
@@ -1,5 +1,19 @@
1
1
  # @ai-sdk/harness-acp
2
2
 
3
+ ## 1.0.46
4
+
5
+ ### Patch Changes
6
+
7
+ - cdc12a1: feat(harness): add support for using adapter-native subscriptions where available
8
+ - Updated dependencies [4d1bf28]
9
+ - Updated dependencies [cdc12a1]
10
+ - Updated dependencies [d70a334]
11
+ - Updated dependencies [81ba84c]
12
+ - Updated dependencies [813bb36]
13
+ - Updated dependencies [c43e4b7]
14
+ - @ai-sdk/harness@1.0.108
15
+ - @ai-sdk/provider-utils@5.0.40
16
+
3
17
  ## 1.0.45
4
18
 
5
19
  ### 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.45" : "0.0.0-test";
15
+ var VERSION = true ? "1.0.46" : "0.0.0-test";
16
16
  function createHostToolMCPServer({
17
17
  tools: tools2,
18
18
  revision = 1,
@@ -2416,7 +2416,7 @@ import {
2416
2416
  ListToolsRequestSchema,
2417
2417
  McpError
2418
2418
  } from "@modelcontextprotocol/sdk/types.js";
2419
- var VERSION = true ? "1.0.45" : "0.0.0-test";
2419
+ var VERSION = true ? "1.0.46" : "0.0.0-test";
2420
2420
  function createHostToolMCPServer({
2421
2421
  tools,
2422
2422
  revision = 1,
package/dist/index.d.ts CHANGED
@@ -157,6 +157,18 @@ type ACPCredentialBrokering = ({ env, sandboxEnv, headers, }: {
157
157
  sandboxEnv?: Readonly<Record<string, string>>;
158
158
  headers?: Readonly<Record<string, string>>;
159
159
  }) => ReadonlyArray<HarnessV1RequestTransformation>;
160
+ type ACPAuthenticationFile = {
161
+ /** Path relative to the ACP implementation's private home directory. */
162
+ readonly path: string;
163
+ readonly content: string;
164
+ };
165
+ type ACPAuthenticationFiles = (options: {
166
+ /** Host values resolved for the implementation. */
167
+ readonly env: Readonly<Record<string, string>>;
168
+ /** Values exposed to the sandbox process after credential brokering. */
169
+ readonly sandboxEnv: Readonly<Record<string, string>>;
170
+ readonly credentialBrokeringAvailable: boolean;
171
+ }) => ReadonlyArray<ACPAuthenticationFile>;
160
172
  type ACPPermissionModeTarget = {
161
173
  readonly type: 'session-mode';
162
174
  readonly modeId: string;
@@ -217,12 +229,25 @@ type ACPV1Settings = {
217
229
  readonly mcpServers?: Record<string, unknown>;
218
230
  readonly isMcpToolCall?: (toolCall: ACPToolCall) => boolean;
219
231
  readonly auth?: ACPAuthenticationMode$1;
232
+ /**
233
+ * Resolves adapter-owned authentication on the host before any environment
234
+ * values are forwarded to the ACP implementation.
235
+ */
236
+ readonly resolveAuthenticationEnvironment?: (options: {
237
+ readonly auth: ACPAuthenticationMode$1 | undefined;
238
+ readonly env: Readonly<Record<string, string | undefined>>;
239
+ }) => Promise<Readonly<Record<string, string | undefined>>>;
220
240
  readonly source: ACPSource;
221
241
  readonly executable: string;
222
242
  readonly args?: ReadonlyArray<string>;
223
243
  readonly forwardEnv?: ReadonlyArray<string>;
224
244
  readonly credentialEnv?: ReadonlyArray<string>;
225
245
  readonly credentialBrokering?: ACPCredentialBrokering;
246
+ /**
247
+ * Materializes private authentication files below the ACP implementation's
248
+ * home directory before the implementation starts.
249
+ */
250
+ readonly authenticationFiles?: ACPAuthenticationFiles;
226
251
  /**
227
252
  * Customizes each credential value before it is forwarded into a sandbox
228
253
  * process. This does not restrict which credentials the harness adapter can
@@ -302,12 +327,14 @@ type ACPHarnessSettings<TBuiltinTools extends ToolSet = {}, TAskUserQuestions ex
302
327
  readonly version?: ACPV1Settings['version'];
303
328
  readonly harnessId: ACPV1Settings['harnessId'];
304
329
  readonly auth?: ACPAuthenticationMode;
330
+ readonly resolveAuthenticationEnvironment?: ACPV1Settings['resolveAuthenticationEnvironment'];
305
331
  readonly source: ACPV1Settings['source'];
306
332
  readonly executable: ACPV1Settings['executable'];
307
333
  readonly args?: ACPV1Settings['args'];
308
334
  readonly forwardEnv?: ACPV1Settings['forwardEnv'];
309
335
  readonly credentialEnv?: ACPV1Settings['credentialEnv'];
310
336
  readonly credentialBrokering?: ACPV1Settings['credentialBrokering'];
337
+ readonly authenticationFiles?: ACPV1Settings['authenticationFiles'];
311
338
  /**
312
339
  * Customizes each credential value before it is forwarded into a sandbox
313
340
  * process. This does not restrict which credentials the harness adapter can
@@ -345,4 +372,4 @@ declare function createACP<TBuiltinTools extends ToolSet = {}, TAskUserQuestions
345
372
 
346
373
  declare const VERSION: string;
347
374
 
348
- export { type ACPAnnotations, type ACPAskUserQuestionsSettings, type ACPAudioContent, type ACPAuthentication, type ACPAuthenticationMode, type ACPBlobResourceContents, type ACPClientApp, type ACPContentBlock, type ACPCredentialBrokering, type ACPEmbeddedResource, type ACPHarnessSettings, type ACPHostToolMCPTransport, type ACPImageContent, type ACPInstallCommandSource, type ACPInstructionMapping, type ACPMetadata, type ACPModelMapping, type ACPNpmLockedSource, type ACPNpmSimpleSource, type ACPOutputSchemaMapping, type ACPPermissionModeMapping, type ACPPermissionModeTarget, type ACPProfileValue, type ACPProviderAuthentication, type ACPResourceLink, type ACPRole, type ACPSerializablePrimitive, type ACPSerializableValue, type ACPSource, type ACPTextContent, type ACPTextResourceContents, type ACPToolCall, type ACPToolCallContent, type ACPToolCallLocation, type ACPToolCallStatus, type ACPToolKind, type ACPV1Settings, type ACPValueSource, VERSION, createACP };
375
+ export { type ACPAnnotations, type ACPAskUserQuestionsSettings, type ACPAudioContent, type ACPAuthentication, type ACPAuthenticationFile, type ACPAuthenticationFiles, type ACPAuthenticationMode, type ACPBlobResourceContents, type ACPClientApp, type ACPContentBlock, type ACPCredentialBrokering, type ACPEmbeddedResource, type ACPHarnessSettings, type ACPHostToolMCPTransport, type ACPImageContent, type ACPInstallCommandSource, type ACPInstructionMapping, type ACPMetadata, type ACPModelMapping, type ACPNpmLockedSource, type ACPNpmSimpleSource, type ACPOutputSchemaMapping, type ACPPermissionModeMapping, type ACPPermissionModeTarget, type ACPProfileValue, type ACPProviderAuthentication, type ACPResourceLink, type ACPRole, type ACPSerializablePrimitive, type ACPSerializableValue, type ACPSource, type ACPTextContent, type ACPTextResourceContents, type ACPToolCall, type ACPToolCallContent, type ACPToolCallLocation, type ACPToolCallStatus, type ACPToolKind, type ACPV1Settings, type ACPValueSource, VERSION, createACP };
package/dist/index.js CHANGED
@@ -1239,14 +1239,17 @@ function createACPV1({
1239
1239
  }
1240
1240
  const permissionMode = startOptions.permissionMode ?? "allow-all";
1241
1241
  const env = { ...process.env };
1242
- const authenticationEnvironment = resolveACPAuthenticationEnvironment({
1242
+ const authenticationEnvironment = settings.resolveAuthenticationEnvironment == null ? resolveACPAuthenticationEnvironment({
1243
+ auth: settings.auth,
1244
+ env
1245
+ }) : await settings.resolveAuthenticationEnvironment({
1243
1246
  auth: settings.auth,
1244
1247
  env
1245
1248
  });
1246
1249
  const providerAuthenticationCompatibility = resolveACPProviderAuthenticationCompatibility({
1247
1250
  auth: settings.auth,
1248
1251
  providerAuthentication: settings.providerAuthentication,
1249
- env
1252
+ env: authenticationEnvironment
1250
1253
  });
1251
1254
  const implementationIdentity = createImplementationIdentity({
1252
1255
  harnessId: settings.harnessId,
@@ -1268,7 +1271,7 @@ function createACPV1({
1268
1271
  providerAuthentication: settings.providerAuthentication,
1269
1272
  clientApp
1270
1273
  },
1271
- env,
1274
+ env: authenticationEnvironment,
1272
1275
  compatibility: providerAuthenticationCompatibility
1273
1276
  });
1274
1277
  const sandboxSession = startOptions.sandboxSession;
@@ -1307,7 +1310,7 @@ function createACPV1({
1307
1310
  }
1308
1311
  const implementationEnvironment = resolveImplementationEnvironment({
1309
1312
  implementation,
1310
- env,
1313
+ env: { ...env, ...authenticationEnvironment },
1311
1314
  credentialEnv: authenticationEnvironment
1312
1315
  });
1313
1316
  let sandboxImplementationEnvironment = implementationEnvironment;
@@ -1579,6 +1582,16 @@ function createACPV1({
1579
1582
  ]
1580
1583
  });
1581
1584
  }
1585
+ await writeACPAuthenticationFiles({
1586
+ sandbox: toolSafeSandboxSession,
1587
+ homePath: implementationHomeDir,
1588
+ files: settings.authenticationFiles?.({
1589
+ env: implementationEnvironment,
1590
+ sandboxEnv: forwardedImplementationEnvironment,
1591
+ credentialBrokeringAvailable: sandboxCredentialEnvironment != null
1592
+ }) ?? [],
1593
+ abortSignal: startOptions.abortSignal
1594
+ });
1582
1595
  const port = resolveBridgePort({
1583
1596
  sandboxSession,
1584
1597
  override: portOverride,
@@ -1751,6 +1764,38 @@ function createACPV1({
1751
1764
  }
1752
1765
  };
1753
1766
  }
1767
+ async function writeACPAuthenticationFiles({
1768
+ sandbox,
1769
+ homePath,
1770
+ files,
1771
+ abortSignal
1772
+ }) {
1773
+ const targetPaths = files.map((file) => {
1774
+ if (file.path.length === 0 || posix.isAbsolute(file.path) || file.path.split("/").some((segment) => segment === "..")) {
1775
+ throw new Error(
1776
+ `ACP authentication file path must be relative without traversal: ${JSON.stringify(file.path)}.`
1777
+ );
1778
+ }
1779
+ return posix.join(homePath, file.path);
1780
+ });
1781
+ for (let index = 0; index < files.length; index++) {
1782
+ await sandbox.writeTextFile({
1783
+ path: targetPaths[index],
1784
+ content: files[index].content,
1785
+ abortSignal
1786
+ });
1787
+ }
1788
+ if (targetPaths.length === 0) return;
1789
+ const result = await sandbox.run({
1790
+ command: `chmod 600 -- ${targetPaths.map(shellQuote).join(" ")}`,
1791
+ abortSignal
1792
+ });
1793
+ if (result.exitCode !== 0) {
1794
+ throw new Error(
1795
+ `Failed to secure ACP authentication files (exit ${result.exitCode})${result.stderr ? `: ${result.stderr}` : ""}`
1796
+ );
1797
+ }
1798
+ }
1754
1799
  function resolveProviderEnvironment({
1755
1800
  resolvedProviderAuthentication,
1756
1801
  clientApp
@@ -2837,7 +2882,7 @@ function deserializeBridgeError({
2837
2882
  }
2838
2883
 
2839
2884
  // src/version.ts
2840
- var VERSION = true ? "1.0.45" : "0.0.0-test";
2885
+ var VERSION = true ? "1.0.46" : "0.0.0-test";
2841
2886
 
2842
2887
  // src/acp-harness.ts
2843
2888
  var ACP_CLIENT_APP = {