@ai-sdk/harness-acp 1.0.29 → 1.0.31

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,28 @@
1
1
  # @ai-sdk/harness-acp
2
2
 
3
+ ## 1.0.31
4
+
5
+ ### Patch Changes
6
+
7
+ - 7608210: feat(harness): add `model` parameter to `HarnessAgent` instead of having each harness adapter support it on their own constructor functions
8
+ - f7bd978: chore(harness): update underlying adapter SDKs to their latest versions
9
+ - 14d4fc0: feat(harness): allow changing harness settings between turns via `prepareCall()` support on `HarnessAgent`
10
+ - Updated dependencies [cc9f6ce]
11
+ - Updated dependencies [7608210]
12
+ - Updated dependencies [6f8a2d7]
13
+ - Updated dependencies [14d4fc0]
14
+ - Updated dependencies [90192f1]
15
+ - @ai-sdk/harness@1.0.93
16
+ - @ai-sdk/provider-utils@5.0.33
17
+
18
+ ## 1.0.30
19
+
20
+ ### Patch Changes
21
+
22
+ - e0d7cfb: feat(harness): allow harness sessions to optionally authenticate from an isolated environment supplied through the `auth` option, and remove support for the formerly deprecated legacy auth options types
23
+ - Updated dependencies [e0d7cfb]
24
+ - @ai-sdk/harness@1.0.92
25
+
3
26
  ## 1.0.29
4
27
 
5
28
  ### Patch Changes
package/README.md CHANGED
@@ -34,6 +34,9 @@ const codexACP = createACP({
34
34
  packageVersion: '1.1.4',
35
35
  },
36
36
  executable: 'codex-acp',
37
+ resolveModel: ({ model }) => ({
38
+ env: { CODEX_CONFIG: JSON.stringify({ model }) },
39
+ }),
37
40
  credentialEnv: ['CODEX_API_KEY', 'OPENAI_API_KEY'],
38
41
  credentialBrokering: ({ env, sandboxEnv }) => {
39
42
  const environmentVariableName = env.CODEX_API_KEY
@@ -96,6 +99,13 @@ ACP supports only `permissionMode: 'allow-all'` because its
96
99
  restrictive modes enable Codex's internal sandbox. A bridge-backed ACP harness
97
100
  requires a sandbox with at least one exposed port.
98
101
 
102
+ `resolveModel` is required because each ACP implementation accepts its model in
103
+ a different place. It receives the `HarnessAgent` model when a session starts
104
+ and can return launch `args`, `env`, or both. Returned arguments replace the
105
+ static `args`; returned environment values overlay the static `env`. The
106
+ resolver is not called when `HarnessAgent` has no model and the deprecated
107
+ `modelId` fallback is also unset.
108
+
99
109
  Use `instructionMapping` when the ACP implementation exposes a native system
100
110
  or developer prompt. A `session-meta` mapping writes `HarnessAgent`
101
111
  instructions below the ACP session request's `_meta` field. A
@@ -12,7 +12,7 @@ import {
12
12
  ListToolsRequestSchema,
13
13
  McpError
14
14
  } from "@modelcontextprotocol/sdk/types.js";
15
- var VERSION = true ? "1.0.29" : "0.0.0-test";
15
+ var VERSION = true ? "1.0.31" : "0.0.0-test";
16
16
  function createHostToolMCPServer({
17
17
  tools: tools2,
18
18
  revision = 1,
@@ -157,6 +157,7 @@ var ENV_TRUTHY = /* @__PURE__ */ new Set(["1", "true", "yes", "on"]);
157
157
  var WS_OPEN = 1;
158
158
  async function runBridge(options) {
159
159
  const { bridgeType: bridgeType2, bridgeStateDir: bridgeStateDir2, onStart, onStop, onDestroy } = options;
160
+ const teardownGraceMs = options.turnTeardownGraceMs ?? 1e4;
160
161
  const expectedToken = options.token ?? procEnv.BRIDGE_CHANNEL_TOKEN ?? "";
161
162
  const bridgeWsPort = options.port ?? parseInt(procEnv.BRIDGE_WS_PORT ?? "0", 10);
162
163
  const bridgeMetaPath = `${bridgeStateDir2}/bridge-meta.json`;
@@ -173,6 +174,7 @@ async function runBridge(options) {
173
174
  let isFirstTurn = true;
174
175
  let turnAbort;
175
176
  let currentUserMessages;
177
+ let activeTurn;
176
178
  let debugConfig;
177
179
  let consoleCaptureInstalled = false;
178
180
  const envDebugEnabled = ENV_TRUTHY.has(
@@ -363,10 +365,28 @@ async function runBridge(options) {
363
365
  const handleInbound = async (msg, ws) => {
364
366
  switch (msg.type) {
365
367
  case "start": {
368
+ for (; ; ) {
369
+ const pendingTurn = activeTurn;
370
+ if (pendingTurn == null) break;
371
+ turnAbort?.abort();
372
+ currentUserMessages?.close(
373
+ new Error("A new bridge turn replaced the active turn.")
374
+ );
375
+ let graceTimer;
376
+ const settled = await Promise.race([
377
+ pendingTurn.then(() => true),
378
+ new Promise((resolve) => {
379
+ graceTimer = setTimeout(() => resolve(false), teardownGraceMs);
380
+ graceTimer.unref?.();
381
+ })
382
+ ]);
383
+ clearTimeout(graceTimer);
384
+ if (!settled) break;
385
+ }
386
+ let turnFinished;
387
+ const thisTurn = new Promise((resolve) => turnFinished = resolve);
388
+ activeTurn = thisTurn;
366
389
  activeSocket = ws;
367
- currentUserMessages?.close(
368
- new Error("A new bridge turn replaced the active turn.")
369
- );
370
390
  const firstTurn = isFirstTurn;
371
391
  isFirstTurn = false;
372
392
  eventLog = [];
@@ -423,8 +443,12 @@ async function runBridge(options) {
423
443
  if (currentUserMessages === userMessages) {
424
444
  currentUserMessages = void 0;
425
445
  }
426
- currentTurnState = "waiting";
427
- void writeBridgeMeta("waiting");
446
+ if (activeTurn === thisTurn) {
447
+ activeTurn = void 0;
448
+ currentTurnState = "waiting";
449
+ void writeBridgeMeta("waiting");
450
+ }
451
+ turnFinished();
428
452
  }
429
453
  return;
430
454
  }
@@ -659,7 +683,9 @@ var bridgeConfigurationSchema = z.object({
659
683
  authentication: authenticationSchema.optional(),
660
684
  providerAuthentication: providerAuthenticationSchema.optional(),
661
685
  providerEnvironment: z.record(z.string(), z.string()).optional(),
662
- sessionMeta: serializableRecordSchema.optional()
686
+ sessionMeta: serializableRecordSchema.optional(),
687
+ implementationArgs: z.array(z.string()).optional(),
688
+ implementationEnv: z.record(z.string(), z.string()).optional()
663
689
  });
664
690
  async function readACPBridgeEnvironment({
665
691
  env
@@ -3388,15 +3414,18 @@ async function ensureSession({
3388
3414
  instructions: start.instructions,
3389
3415
  instructionMapping: start.instructionMapping,
3390
3416
  sessionMeta: bridgeConfiguration.sessionMeta,
3391
- environment: createChildEnvironment({
3392
- launchEnv,
3393
- implementationDir,
3394
- privateHome: implementation.privateHome
3395
- })
3417
+ environment: {
3418
+ ...createChildEnvironment({
3419
+ launchEnv,
3420
+ implementationDir,
3421
+ privateHome: implementation.privateHome
3422
+ }),
3423
+ ...bridgeConfiguration.implementationEnv
3424
+ }
3396
3425
  });
3397
3426
  child = spawn(
3398
3427
  `${implementationDir}/${implementation.executablePath}`,
3399
- [...implementation.args],
3428
+ [...bridgeConfiguration.implementationArgs ?? implementation.args],
3400
3429
  {
3401
3430
  cwd: workDir,
3402
3431
  env: instructionConfiguration.environment,