@ai-sdk/harness-acp 1.0.54 → 1.0.56

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,25 @@
1
1
  # @ai-sdk/harness-acp
2
2
 
3
+ ## 1.0.56
4
+
5
+ ### Patch Changes
6
+
7
+ - d975097: feat(harness): add `AbortSignal` to `SandboxChannel.connect`, plus a `sleep()` helper function
8
+ - c0e5d1d: feat(harness): allow consumers of bridge backed harnesses to configure `reconnect` timeout
9
+ - Updated dependencies [d975097]
10
+ - Updated dependencies [b2baeba]
11
+ - @ai-sdk/harness@1.0.118
12
+
13
+ ## 1.0.55
14
+
15
+ ### Patch Changes
16
+
17
+ - Updated dependencies [2973485]
18
+ - Updated dependencies [a4db5ea]
19
+ - Updated dependencies [2937ea2]
20
+ - @ai-sdk/provider-utils@5.0.45
21
+ - @ai-sdk/harness@1.0.117
22
+
3
23
  ## 1.0.54
4
24
 
5
25
  ### 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.54" : "0.0.0-test";
15
+ var VERSION = true ? "1.0.56" : "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.54" : "0.0.0-test";
2419
+ var VERSION = true ? "1.0.56" : "0.0.0-test";
2420
2420
  function createHostToolMCPServer({
2421
2421
  tools,
2422
2422
  revision = 1,
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { HarnessV1StreamPart, HarnessV1Authentication, HarnessV1RequestTransformation, HarnessV1CredentialForwarding, HarnessV1PermissionMode, HarnessV1MintBridgeTokenCallback, HarnessV1PortEndpoint, HarnessV1, HARNESS_V1_BUILTIN_TOOLS } from '@ai-sdk/harness';
2
+ import { SandboxChannelReconnectOptions } from '@ai-sdk/harness/utils';
2
3
  import { ToolResultPart, ToolSet } from '@ai-sdk/provider-utils';
3
4
 
4
5
  type ACPMetadata = Record<string, unknown>;
@@ -323,6 +324,13 @@ type ACPHarnessSettings<TBuiltinTools extends ToolSet = {}, TAskUserQuestions ex
323
324
  */
324
325
  readonly portEndpoint?: HarnessV1PortEndpoint;
325
326
  readonly startupTimeoutMs?: number;
327
+ /**
328
+ * Configures reconnection attempts after an established bridge connection
329
+ * drops. The reconnect window includes connection establishment and
330
+ * backoff delays. Defaults to 30 seconds with exponential backoff from 50
331
+ * milliseconds up to 2 seconds.
332
+ */
333
+ readonly reconnect?: SandboxChannelReconnectOptions;
326
334
  readonly clientApp?: ACPClientApp;
327
335
  readonly version?: ACPV1Settings['version'];
328
336
  readonly harnessId: ACPV1Settings['harnessId'];
package/dist/index.js CHANGED
@@ -1192,6 +1192,7 @@ function createACPV1({
1192
1192
  port: portOverride,
1193
1193
  portEndpoint: portEndpointOverride,
1194
1194
  startupTimeoutMs,
1195
+ reconnect,
1195
1196
  clientApp,
1196
1197
  lifecycleStateSchema
1197
1198
  }) {
@@ -1438,11 +1439,12 @@ function createACPV1({
1438
1439
  token: coords.token
1439
1440
  });
1440
1441
  const attachChannel = new SandboxChannel({
1441
- connect: () => openWebSocket(attachEndpoint),
1442
+ connect: ({ abortSignal }) => openWebSocket({ ...attachEndpoint, abortSignal }),
1442
1443
  outboundSchema: outboundMessageSchema,
1443
1444
  initialLastSeenEventId: coords.lastSeenEventId,
1444
1445
  onDiagnostic,
1445
- onBridgeError
1446
+ onBridgeError,
1447
+ reconnect
1446
1448
  });
1447
1449
  await attachChannel.open(isContinue ? { resume: true } : void 0);
1448
1450
  return createSession({
@@ -1669,11 +1671,12 @@ function createACPV1({
1669
1671
  });
1670
1672
  const bridgeEndpoint = withBridgeToken({ endpoint, token });
1671
1673
  const channel = new SandboxChannel({
1672
- connect: () => openWebSocket(bridgeEndpoint),
1674
+ connect: ({ abortSignal }) => openWebSocket({ ...bridgeEndpoint, abortSignal }),
1673
1675
  outboundSchema: outboundMessageSchema,
1674
1676
  ...respawnStrategy?.mode === "disk-replay" ? { initialLastSeenEventId: respawnStrategy.afterSeq } : {},
1675
1677
  onDiagnostic,
1676
- onBridgeError
1678
+ onBridgeError,
1679
+ reconnect
1677
1680
  });
1678
1681
  await channel.open(
1679
1682
  respawnStrategy?.mode === "disk-replay" ? { resume: true } : void 0
@@ -1900,22 +1903,54 @@ async function resolveBridgeEndpoint({
1900
1903
  }
1901
1904
  function openWebSocket({
1902
1905
  url,
1903
- headers
1906
+ headers,
1907
+ abortSignal
1904
1908
  }) {
1905
1909
  return new Promise((resolve, reject) => {
1910
+ if (abortSignal.aborted) {
1911
+ reject(abortSignal.reason ?? new Error("WebSocket connection aborted"));
1912
+ return;
1913
+ }
1906
1914
  const ws = new WebSocket(url, {
1907
1915
  headers: headers == null ? void 0 : { ...headers }
1908
1916
  });
1909
- const onOpen = () => {
1917
+ let settled = false;
1918
+ const cleanup = () => {
1919
+ abortSignal.removeEventListener("abort", onAbort);
1920
+ ws.off("open", onOpen);
1910
1921
  ws.off("error", onError);
1922
+ };
1923
+ const rejectWithCleanup = (error) => {
1924
+ if (settled) return;
1925
+ settled = true;
1926
+ cleanup();
1927
+ ws.once("error", () => {
1928
+ });
1929
+ try {
1930
+ ws.terminate();
1931
+ } catch {
1932
+ try {
1933
+ ws.close();
1934
+ } catch {
1935
+ }
1936
+ }
1937
+ reject(error);
1938
+ };
1939
+ const onOpen = () => {
1940
+ if (settled) return;
1941
+ settled = true;
1942
+ cleanup();
1911
1943
  resolve(ws);
1912
1944
  };
1913
1945
  const onError = (error) => {
1914
- ws.off("open", onOpen);
1915
- reject(error);
1946
+ rejectWithCleanup(error);
1916
1947
  };
1948
+ const onAbort = () => rejectWithCleanup(
1949
+ abortSignal.reason ?? new Error("WebSocket connection aborted")
1950
+ );
1917
1951
  ws.once("open", onOpen);
1918
1952
  ws.once("error", onError);
1953
+ abortSignal.addEventListener("abort", onAbort, { once: true });
1919
1954
  });
1920
1955
  }
1921
1956
  function restoreColdACPSession({
@@ -2882,7 +2917,7 @@ function deserializeBridgeError({
2882
2917
  }
2883
2918
 
2884
2919
  // src/version.ts
2885
- var VERSION = true ? "1.0.54" : "0.0.0-test";
2920
+ var VERSION = true ? "1.0.56" : "0.0.0-test";
2886
2921
 
2887
2922
  // src/acp-harness.ts
2888
2923
  var ACP_CLIENT_APP = {
@@ -2952,6 +2987,7 @@ function createACP(settings) {
2952
2987
  port: settings.port,
2953
2988
  portEndpoint: settings.portEndpoint,
2954
2989
  startupTimeoutMs: settings.startupTimeoutMs,
2990
+ reconnect: settings.reconnect,
2955
2991
  clientApp,
2956
2992
  lifecycleStateSchema: acpResumeStateSchema
2957
2993
  });