@ai-sdk/harness 1.0.92 → 1.0.93

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.
@@ -42,7 +42,8 @@ var HarnessCapabilityUnsupportedError = class extends (_b2 = HarnessError, _a2 =
42
42
  import {
43
43
  asArray as asArray2,
44
44
  asSchema,
45
- generateId as generateId5
45
+ generateId as generateId5,
46
+ validateTypes
46
47
  } from "@ai-sdk/provider-utils";
47
48
 
48
49
  // src/agent/internal/lifecycle-state-validation.ts
@@ -107,7 +108,8 @@ async function validateLifecycleStateData(input) {
107
108
  specificationVersion: state.specificationVersion,
108
109
  data,
109
110
  ...state.pendingToolApprovals !== void 0 ? { pendingToolApprovals: state.pendingToolApprovals } : {},
110
- ...state.pendingToolResults !== void 0 ? { pendingToolResults: state.pendingToolResults } : {}
111
+ ...state.pendingToolResults !== void 0 ? { pendingToolResults: state.pendingToolResults } : {},
112
+ ...state.turnSettings !== void 0 ? { turnSettings: state.turnSettings } : {}
111
113
  };
112
114
  }
113
115
 
@@ -1511,17 +1513,22 @@ function runPrompt(input) {
1511
1513
  result.fail(err);
1512
1514
  };
1513
1515
  const done = (async () => {
1514
- var _a5, _b5, _c2, _d2, _e2, _f2, _g2, _h, _i, _j, _k, _l, _m;
1516
+ var _a5, _b5, _c2, _d2, _e2, _f2, _g2, _h, _i, _j, _k, _l, _m, _n;
1515
1517
  let bridge;
1516
1518
  try {
1517
1519
  bridge = await toHarnessStream({
1518
- invoke: input.mode === "continue" ? (emit) => input.session.doContinueTurn({
1519
- responseFormat: input.responseFormat,
1520
- tools: input.toolSpecs,
1521
- instructions: input.instructions,
1522
- abortSignal: input.abortSignal,
1523
- emit
1524
- }) : (emit) => {
1520
+ invoke: input.mode === "continue" ? (emit) => {
1521
+ var _a6;
1522
+ return input.session.doContinueTurn({
1523
+ skills: (_a6 = input.skills) != null ? _a6 : [],
1524
+ responseFormat: input.responseFormat,
1525
+ tools: input.toolSpecs,
1526
+ instructions: input.instructions,
1527
+ abortSignal: input.abortSignal,
1528
+ emit
1529
+ });
1530
+ } : (emit) => {
1531
+ var _a6;
1525
1532
  if (input.prompt == null) {
1526
1533
  throw new Error(
1527
1534
  'runPrompt: `prompt` is required for mode "prompt".'
@@ -1529,6 +1536,7 @@ function runPrompt(input) {
1529
1536
  }
1530
1537
  return input.session.doPromptTurn({
1531
1538
  prompt: input.prompt,
1539
+ skills: (_a6 = input.skills) != null ? _a6 : [],
1532
1540
  responseFormat: input.responseFormat,
1533
1541
  tools: input.toolSpecs,
1534
1542
  instructions: input.instructions,
@@ -1944,12 +1952,14 @@ function runPrompt(input) {
1944
1952
  if (value.type === "error" && displayValue.type === "error") {
1945
1953
  await waitForOutstandingHostToolExecutions();
1946
1954
  await telemetry.error(value.error);
1947
- logBridgeError({
1948
- harnessId: input.harness.harnessId,
1949
- sessionId: input.session.sessionId,
1950
- context: "harness stream error",
1951
- error: value.error
1952
- });
1955
+ if (!((_g2 = input.abortSignal) == null ? void 0 : _g2.aborted)) {
1956
+ logBridgeError({
1957
+ harnessId: input.harness.harnessId,
1958
+ sessionId: input.session.sessionId,
1959
+ context: "harness stream error",
1960
+ error: value.error
1961
+ });
1962
+ }
1953
1963
  settleFailure(displayValue.error);
1954
1964
  return;
1955
1965
  }
@@ -2003,13 +2013,13 @@ function runPrompt(input) {
2003
2013
  );
2004
2014
  }
2005
2015
  const rawToolCall = rawToolCallsByToolCallId.get(value.toolCallId);
2006
- const pendingApproval = (_i = pendingApprovalsByApprovalId.get(value.approvalId)) != null ? _i : {
2016
+ const pendingApproval = (_j = pendingApprovalsByApprovalId.get(value.approvalId)) != null ? _j : {
2007
2017
  approvalId: value.approvalId,
2008
2018
  toolCallId: value.toolCallId,
2009
2019
  toolName: toolCall.toolName,
2010
- input: (_g2 = rawToolCall == null ? void 0 : rawToolCall.input) != null ? _g2 : JSON.stringify(toolCall.input),
2020
+ input: (_h = rawToolCall == null ? void 0 : rawToolCall.input) != null ? _h : JSON.stringify(toolCall.input),
2011
2021
  kind: "builtin",
2012
- providerExecuted: (_h = rawToolCall == null ? void 0 : rawToolCall.providerExecuted) != null ? _h : true,
2022
+ providerExecuted: (_i = rawToolCall == null ? void 0 : rawToolCall.providerExecuted) != null ? _i : true,
2013
2023
  ...(rawToolCall == null ? void 0 : rawToolCall.nativeName) !== void 0 ? { nativeName: rawToolCall.nativeName } : {}
2014
2024
  };
2015
2025
  pendingApprovalsByApprovalId.set(
@@ -2114,7 +2124,7 @@ function runPrompt(input) {
2114
2124
  await telemetry.toolEnd(toolCall.toolCallId, { ok: true, output });
2115
2125
  continue;
2116
2126
  }
2117
- const pendingApproval = (_j = pendingApprovalsByToolCallId.get(toolCall.toolCallId)) != null ? _j : customToolApprovalDecision.type === "request" ? {
2127
+ const pendingApproval = (_k = pendingApprovalsByToolCallId.get(toolCall.toolCallId)) != null ? _k : customToolApprovalDecision.type === "request" ? {
2118
2128
  approvalId: generateId4(),
2119
2129
  toolCallId: toolCall.toolCallId,
2120
2130
  toolName: toolCall.toolName,
@@ -2213,15 +2223,15 @@ function runPrompt(input) {
2213
2223
  }
2214
2224
  }
2215
2225
  await waitForOutstandingHostToolExecutions();
2216
- const isTurnSuspending = ((_k = input.isTurnSuspending) == null ? void 0 : _k.call(input)) === true;
2226
+ const isTurnSuspending = ((_l = input.isTurnSuspending) == null ? void 0 : _l.call(input)) === true;
2217
2227
  if (isTurnSuspending) {
2218
2228
  if (finalFinish == null) {
2219
2229
  result.discardCurrentStepContent();
2220
2230
  }
2221
2231
  } else if (finalFinish != null) {
2222
- (_l = input.onTurnFinished) == null ? void 0 : _l.call(input);
2232
+ (_m = input.onTurnFinished) == null ? void 0 : _m.call(input);
2223
2233
  } else {
2224
- (_m = input.onTurnFailed) == null ? void 0 : _m.call(input);
2234
+ (_n = input.onTurnFailed) == null ? void 0 : _n.call(input);
2225
2235
  }
2226
2236
  await result.finish(
2227
2237
  finalFinish ? {
@@ -2368,6 +2378,7 @@ var HarnessAgentSession = class {
2368
2378
  for (const pendingResult of (_c = options.pendingToolResults) != null ? _c : []) {
2369
2379
  this.pendingToolResults.set(pendingResult.toolCallId, pendingResult);
2370
2380
  }
2381
+ this.persistedTurnSettings = options.turnSettings;
2371
2382
  this.turnState = (_d = options.turnState) != null ? _d : this.pendingToolApprovals.size > 0 ? "awaiting-approval" : this.pendingToolResults.size > 0 ? "awaiting-tool-result" : "idle";
2372
2383
  this.isResume = options.underlyingSession.isResume;
2373
2384
  }
@@ -2399,6 +2410,17 @@ var HarnessAgentSession = class {
2399
2410
  promptTurn(options) {
2400
2411
  const session = this.requireReusableSession();
2401
2412
  this.requirePromptableTurn();
2413
+ this.persistedTurnSettings = {
2414
+ skills: options.skills,
2415
+ ...options.instructions == null ? {} : { instructions: options.instructions },
2416
+ tools: options.toolSpecs
2417
+ };
2418
+ this.activeTurnSettings = {
2419
+ persisted: this.persistedTurnSettings,
2420
+ tools: options.tools,
2421
+ activeTools: options.activeTools,
2422
+ builtinToolFiltering: options.builtinToolFiltering
2423
+ };
2402
2424
  const sandboxSession = this.getSandboxSession();
2403
2425
  const turnId = this.startTrackedTurn();
2404
2426
  try {
@@ -2406,6 +2428,7 @@ var HarnessAgentSession = class {
2406
2428
  harness: this.harness,
2407
2429
  session,
2408
2430
  prompt: options.prompt,
2431
+ skills: options.skills,
2409
2432
  instructions: options.instructions,
2410
2433
  tools: options.tools,
2411
2434
  activeTools: options.activeTools,
@@ -2448,7 +2471,10 @@ var HarnessAgentSession = class {
2448
2471
  isTurnSuspending: () => this.activeTurnSequence === turnId && this.suspendedTurnState != null,
2449
2472
  onStopConditionMet: () => this.captureStopConditionBoundary({ session, turnId })
2450
2473
  });
2451
- return turn;
2474
+ return {
2475
+ ...turn,
2476
+ ready: this.waitForPromptControl({ turnId })
2477
+ };
2452
2478
  } catch (error) {
2453
2479
  this.finishTrackedTurn({ turnId });
2454
2480
  throw error;
@@ -2457,6 +2483,14 @@ var HarnessAgentSession = class {
2457
2483
  continueTurn(options) {
2458
2484
  const session = this.requireReusableSession();
2459
2485
  this.requireContinuableTurn();
2486
+ const turnSettings = this.resolveActiveTurnSettings({
2487
+ skills: options.skills,
2488
+ instructions: options.instructions,
2489
+ tools: options.tools,
2490
+ activeTools: options.activeTools,
2491
+ toolSpecs: options.toolSpecs,
2492
+ builtinToolFiltering: options.builtinToolFiltering
2493
+ });
2460
2494
  const sandboxSession = this.getSandboxSession();
2461
2495
  const turnId = this.startTrackedTurn();
2462
2496
  try {
@@ -2464,11 +2498,12 @@ var HarnessAgentSession = class {
2464
2498
  harness: this.harness,
2465
2499
  session,
2466
2500
  mode: "continue",
2467
- instructions: options.instructions,
2468
- tools: options.tools,
2469
- activeTools: options.activeTools,
2470
- toolSpecs: options.toolSpecs,
2471
- builtinToolFiltering: options.builtinToolFiltering,
2501
+ skills: turnSettings.persisted.skills,
2502
+ instructions: turnSettings.persisted.instructions,
2503
+ tools: turnSettings.tools,
2504
+ activeTools: turnSettings.activeTools,
2505
+ toolSpecs: [...turnSettings.persisted.tools],
2506
+ builtinToolFiltering: turnSettings.builtinToolFiltering,
2472
2507
  sandboxSession: getRestrictedSandboxSession(sandboxSession),
2473
2508
  sessionWorkDir: this.sessionWorkDir,
2474
2509
  runtimeContext: options.runtimeContext,
@@ -2508,7 +2543,10 @@ var HarnessAgentSession = class {
2508
2543
  isTurnSuspending: () => this.activeTurnSequence === turnId && this.suspendedTurnState != null,
2509
2544
  onStopConditionMet: () => this.captureStopConditionBoundary({ session, turnId })
2510
2545
  });
2511
- return turn;
2546
+ return {
2547
+ ...turn,
2548
+ ready: this.waitForPromptControl({ turnId })
2549
+ };
2512
2550
  } catch (error) {
2513
2551
  this.finishTrackedTurn({ turnId });
2514
2552
  throw error;
@@ -2676,6 +2714,7 @@ var HarnessAgentSession = class {
2676
2714
  return Array.from(this.pendingToolResults.values());
2677
2715
  }
2678
2716
  addPendingToolState(state) {
2717
+ const turnSettings = this.persistedTurnSettings;
2679
2718
  const pendingToolApprovals = this.getPendingToolApprovals();
2680
2719
  const pendingToolResults = this.getPendingToolResults();
2681
2720
  if (pendingToolApprovals.length === 0 && pendingToolResults.length === 0) {
@@ -2683,11 +2722,13 @@ var HarnessAgentSession = class {
2683
2722
  type: state.type,
2684
2723
  harnessId: state.harnessId,
2685
2724
  specificationVersion: state.specificationVersion,
2686
- data: state.data
2725
+ data: state.data,
2726
+ ...turnSettings == null ? {} : { turnSettings }
2687
2727
  };
2688
2728
  }
2689
2729
  return {
2690
2730
  ...state,
2731
+ ...turnSettings == null ? {} : { turnSettings },
2691
2732
  ...pendingToolApprovals.length > 0 ? { pendingToolApprovals } : {},
2692
2733
  ...pendingToolResults.length > 0 ? { pendingToolResults } : {}
2693
2734
  };
@@ -2787,6 +2828,11 @@ var HarnessAgentSession = class {
2787
2828
  }
2788
2829
  this.settleActivePromptControl(options.control);
2789
2830
  }
2831
+ async waitForPromptControl(options) {
2832
+ const activePromptControl = this.activePromptControl;
2833
+ if ((activePromptControl == null ? void 0 : activePromptControl.turnId) !== options.turnId) return;
2834
+ await activePromptControl.promise;
2835
+ }
2790
2836
  settleActivePromptControl(control) {
2791
2837
  const activePromptControl = this.activePromptControl;
2792
2838
  if (activePromptControl == null || activePromptControl.settled) return;
@@ -2807,8 +2853,39 @@ var HarnessAgentSession = class {
2807
2853
  this.pendingToolApprovals.clear();
2808
2854
  this.pendingToolResults.clear();
2809
2855
  this.suspendedTurnState = void 0;
2856
+ this.activeTurnSettings = void 0;
2857
+ this.persistedTurnSettings = void 0;
2810
2858
  this.turnState = "idle";
2811
2859
  }
2860
+ resolveActiveTurnSettings(options) {
2861
+ var _a4;
2862
+ if (this.activeTurnSettings != null) {
2863
+ return this.activeTurnSettings;
2864
+ }
2865
+ const persisted = (_a4 = this.persistedTurnSettings) != null ? _a4 : {
2866
+ skills: options.skills,
2867
+ ...options.instructions == null ? {} : { instructions: options.instructions },
2868
+ tools: options.toolSpecs
2869
+ };
2870
+ this.persistedTurnSettings = persisted;
2871
+ const activeTools = {};
2872
+ for (const toolSpec of persisted.tools) {
2873
+ const tool = options.activeTools[toolSpec.name];
2874
+ if (tool == null) {
2875
+ throw new Error(
2876
+ `HarnessAgent cannot continue turn because tool '${toolSpec.name}' is no longer available.`
2877
+ );
2878
+ }
2879
+ activeTools[toolSpec.name] = tool;
2880
+ }
2881
+ this.activeTurnSettings = {
2882
+ persisted,
2883
+ tools: options.tools,
2884
+ activeTools,
2885
+ builtinToolFiltering: options.builtinToolFiltering
2886
+ };
2887
+ return this.activeTurnSettings;
2888
+ }
2812
2889
  endLocalHandle(options) {
2813
2890
  this.clearActivePromptControl();
2814
2891
  this.sessionState = options.sessionState;
@@ -3395,7 +3472,6 @@ var HarnessAgent = class {
3395
3472
  activeTools: settings.activeTools,
3396
3473
  inactiveTools: settings.inactiveTools
3397
3474
  });
3398
- this.activeUserTools = toolFiltering.activeUserTools;
3399
3475
  this.builtinToolFiltering = toolFiltering.builtinToolFiltering;
3400
3476
  if (Object.keys(settings.harness.builtinTools).length > 0 && permissionModeNeedsBuiltinSupport({
3401
3477
  permissionMode: this.permissionMode
@@ -3419,7 +3495,7 @@ var HarnessAgent = class {
3419
3495
  * `session.destroy()`.
3420
3496
  */
3421
3497
  async createSession(options) {
3422
- var _a4, _b4;
3498
+ var _a4, _b4, _c;
3423
3499
  const sessionId = (_a4 = options == null ? void 0 : options.sessionId) != null ? _a4 : generateId5();
3424
3500
  const resumeFrom = options == null ? void 0 : options.resumeFrom;
3425
3501
  const continueFrom = options == null ? void 0 : options.continueFrom;
@@ -3491,6 +3567,7 @@ var HarnessAgent = class {
3491
3567
  "HarnessAgent.createSession: configure `sandbox` on HarnessAgent or pass `sandboxSession` to createSession()."
3492
3568
  );
3493
3569
  }
3570
+ const recipe = await ((_c = harness.getBootstrap) == null ? void 0 : _c.call(harness, { abortSignal }));
3494
3571
  if (isResumedSession) {
3495
3572
  if (sandboxProvider.resumeSession == null) {
3496
3573
  throw new HarnessCapabilityUnsupportedError({
@@ -3509,11 +3586,25 @@ var HarnessAgent = class {
3509
3586
  sessionId,
3510
3587
  workDir: this.sandboxConfig.workDir
3511
3588
  });
3512
- } else {
3513
- let recipe;
3514
- if (harness.getBootstrap != null) {
3515
- recipe = await harness.getBootstrap({ abortSignal });
3589
+ if (recipe != null) {
3590
+ const recipeIdentity = await hashHarnessBootstrap(recipe);
3591
+ try {
3592
+ await applyBootstrapRecipe({
3593
+ session: resumedSandboxSession.restricted(),
3594
+ recipe,
3595
+ identity: recipeIdentity,
3596
+ defaultWorkingDirectory: resumedSandboxSession.defaultWorkingDirectory,
3597
+ abortSignal
3598
+ });
3599
+ } catch (err) {
3600
+ await cleanupAfterStartFailure({
3601
+ sandboxSession,
3602
+ ownsSandboxLifecycle
3603
+ });
3604
+ throw err;
3605
+ }
3516
3606
  }
3607
+ } else {
3517
3608
  const sandboxBootstrapPlan = await createSandboxBootstrapPlan({
3518
3609
  recipe,
3519
3610
  settings: this.sandboxConfig
@@ -3572,8 +3663,8 @@ var HarnessAgent = class {
3572
3663
  }
3573
3664
  try {
3574
3665
  const baseStartOptions = {
3666
+ model: this.settings.model,
3575
3667
  sessionId,
3576
- skills: this.settings.skills,
3577
3668
  resumeFrom: validatedResumeFrom,
3578
3669
  continueFrom: effectiveContinueFrom,
3579
3670
  permissionMode: this.permissionMode,
@@ -3596,6 +3687,7 @@ var HarnessAgent = class {
3596
3687
  toolApproval: this.settings.toolApproval,
3597
3688
  pendingToolApprovals: effectiveContinueFrom == null ? void 0 : effectiveContinueFrom.pendingToolApprovals,
3598
3689
  pendingToolResults: effectiveContinueFrom == null ? void 0 : effectiveContinueFrom.pendingToolResults,
3690
+ turnSettings: effectiveContinueFrom == null ? void 0 : effectiveContinueFrom.turnSettings,
3599
3691
  turnState: effectiveContinueFrom == null ? "idle" : effectiveContinueFrom.pendingToolApprovals != null && effectiveContinueFrom.pendingToolApprovals.length > 0 ? "awaiting-approval" : effectiveContinueFrom.pendingToolResults != null && effectiveContinueFrom.pendingToolResults.length > 0 ? "awaiting-tool-result" : "suspended"
3600
3692
  });
3601
3693
  } catch (error) {
@@ -3607,30 +3699,27 @@ var HarnessAgent = class {
3607
3699
  }
3608
3700
  }
3609
3701
  async generate(options) {
3610
- const turnInput = this._resolveTurnInput(options);
3702
+ const continueTurnInput = this._resolveContinueTurnInput(options);
3611
3703
  const runtimeContext = {};
3612
- const responseFormat = await this._resolveResponseFormat();
3613
- const { result, done } = this._startTurn({
3704
+ const { result, done } = continueTurnInput == null ? await this._startPromptTurn({ options, runtimeContext }) : await this._startContinueTurn({
3614
3705
  session: options.session,
3615
- turnInput,
3706
+ turnInput: continueTurnInput,
3616
3707
  runtimeContext,
3617
- abortSignal: options.abortSignal,
3618
- responseFormat
3708
+ abortSignal: options.abortSignal
3619
3709
  });
3620
3710
  await done;
3621
3711
  return this._toGenerateResult(result);
3622
3712
  }
3623
3713
  async stream(options) {
3624
- const turnInput = this._resolveTurnInput(options);
3714
+ const continueTurnInput = this._resolveContinueTurnInput(options);
3625
3715
  const runtimeContext = {};
3626
- const responseFormat = await this._resolveResponseFormat();
3627
- const { result } = this._startTurn({
3716
+ const { result, ready } = continueTurnInput == null ? await this._startPromptTurn({ options, runtimeContext }) : await this._startContinueTurn({
3628
3717
  session: options.session,
3629
- turnInput,
3718
+ turnInput: continueTurnInput,
3630
3719
  runtimeContext,
3631
- abortSignal: options.abortSignal,
3632
- responseFormat
3720
+ abortSignal: options.abortSignal
3633
3721
  });
3722
+ await ready;
3634
3723
  return result;
3635
3724
  }
3636
3725
  /**
@@ -3641,17 +3730,14 @@ var HarnessAgent = class {
3641
3730
  async continueGenerate(options) {
3642
3731
  var _a4, _b4;
3643
3732
  const runtimeContext = {};
3644
- const responseFormat = await this._resolveResponseFormat();
3645
- const { result, done } = this._startTurn({
3733
+ const { result, done } = await this._startContinueTurn({
3646
3734
  session: options.session,
3647
3735
  turnInput: {
3648
- mode: "continue",
3649
3736
  toolApprovalContinuations: (_a4 = options.toolApprovalContinuations) != null ? _a4 : [],
3650
3737
  toolResultContinuations: (_b4 = options.toolResultContinuations) != null ? _b4 : []
3651
3738
  },
3652
3739
  runtimeContext,
3653
- abortSignal: options.abortSignal,
3654
- responseFormat
3740
+ abortSignal: options.abortSignal
3655
3741
  });
3656
3742
  await done;
3657
3743
  return this._toGenerateResult(result);
@@ -3667,18 +3753,16 @@ var HarnessAgent = class {
3667
3753
  async continueStream(options) {
3668
3754
  var _a4, _b4;
3669
3755
  const runtimeContext = {};
3670
- const responseFormat = await this._resolveResponseFormat();
3671
- const { result } = this._startTurn({
3756
+ const { result, ready } = await this._startContinueTurn({
3672
3757
  session: options.session,
3673
3758
  turnInput: {
3674
- mode: "continue",
3675
3759
  toolApprovalContinuations: (_a4 = options.toolApprovalContinuations) != null ? _a4 : [],
3676
3760
  toolResultContinuations: (_b4 = options.toolResultContinuations) != null ? _b4 : []
3677
3761
  },
3678
3762
  runtimeContext,
3679
- abortSignal: options.abortSignal,
3680
- responseFormat
3763
+ abortSignal: options.abortSignal
3681
3764
  });
3765
+ await ready;
3682
3766
  return result;
3683
3767
  }
3684
3768
  /**
@@ -3692,50 +3776,52 @@ var HarnessAgent = class {
3692
3776
  await options.session.experimental_steerTurn(options.text);
3693
3777
  }
3694
3778
  // ─── Internals ──────────────────────────────────────────────────────
3695
- _startTurn(input) {
3696
- if (input.turnInput.mode === "continue") {
3697
- return input.session.continueTurn({
3698
- instructions: this.settings.instructions,
3699
- tools: this.tools,
3700
- activeTools: this.activeUserTools,
3701
- toolSpecs: this._toToolSpecs(),
3702
- builtinToolFiltering: this.builtinToolFiltering,
3779
+ async _startPromptTurn(input) {
3780
+ const turnInput = await this._preparePromptTurnInput(input.options);
3781
+ const responseFormat = await this._resolveResponseFormat();
3782
+ return input.options.session.promptTurn({
3783
+ ...this._buildTurnOptions({
3784
+ turnSettings: turnInput,
3785
+ runtimeContext: input.runtimeContext,
3786
+ abortSignal: input.options.abortSignal,
3787
+ responseFormat
3788
+ }),
3789
+ prompt: turnInput.prompt
3790
+ });
3791
+ }
3792
+ async _startContinueTurn(input) {
3793
+ const turnInput = this._prepareContinueTurnInput(input.turnInput);
3794
+ const responseFormat = await this._resolveResponseFormat();
3795
+ return input.session.continueTurn({
3796
+ ...this._buildTurnOptions({
3797
+ turnSettings: turnInput,
3703
3798
  runtimeContext: input.runtimeContext,
3704
3799
  abortSignal: input.abortSignal,
3705
- responseFormat: input.responseFormat,
3706
- output: this.settings.output,
3707
- telemetry: this.settings.telemetry,
3708
- stopConditions: this.stopConditions,
3709
- toolApprovalContinuations: input.turnInput.toolApprovalContinuations,
3710
- toolResultContinuations: input.turnInput.toolResultContinuations
3711
- });
3712
- }
3713
- return input.session.promptTurn({
3714
- prompt: input.turnInput.prompt,
3715
- instructions: this.settings.instructions,
3716
- tools: this.tools,
3717
- activeTools: this.activeUserTools,
3718
- toolSpecs: this._toToolSpecs(),
3719
- builtinToolFiltering: this.builtinToolFiltering,
3800
+ responseFormat
3801
+ }),
3802
+ toolApprovalContinuations: turnInput.toolApprovalContinuations,
3803
+ toolResultContinuations: turnInput.toolResultContinuations
3804
+ });
3805
+ }
3806
+ _buildTurnOptions(input) {
3807
+ return {
3808
+ skills: input.turnSettings.skills,
3809
+ instructions: input.turnSettings.instructions,
3810
+ tools: input.turnSettings.tools,
3811
+ activeTools: input.turnSettings.activeTools,
3812
+ toolSpecs: input.turnSettings.toolSpecs,
3813
+ builtinToolFiltering: input.turnSettings.builtinToolFiltering,
3720
3814
  runtimeContext: input.runtimeContext,
3721
3815
  abortSignal: input.abortSignal,
3722
3816
  responseFormat: input.responseFormat,
3723
3817
  output: this.settings.output,
3724
3818
  telemetry: this.settings.telemetry,
3725
3819
  stopConditions: this.stopConditions
3726
- });
3820
+ };
3727
3821
  }
3728
- /*
3729
- * Reduce AI SDK input to the single user message the harness should run
3730
- * for this turn. The harness session owns prior-turn state (system
3731
- * prompt, assistant turns, tool results) — we never replay it. A bare
3732
- * string is forwarded as-is; a message array is collapsed to its last
3733
- * `role: 'user'` entry. Inputs whose only messages are non-user (system,
3734
- * assistant, tool) have no fresh user input and are rejected.
3735
- */
3736
- _resolveTurnInput(options) {
3822
+ _resolveContinueTurnInput(options) {
3737
3823
  if (typeof options.prompt === "string") {
3738
- return { mode: "prompt", prompt: options.prompt };
3824
+ return void 0;
3739
3825
  }
3740
3826
  const messages = Array.isArray(options.prompt) ? options.prompt : options.messages;
3741
3827
  if (Array.isArray(messages)) {
@@ -3743,15 +3829,30 @@ var HarnessAgent = class {
3743
3829
  const toolResultContinuations = collectHarnessAgentToolResultContinuations({ messages });
3744
3830
  if (toolApprovalContinuations.length > 0 || toolResultContinuations.length > 0) {
3745
3831
  return {
3746
- mode: "continue",
3747
3832
  toolApprovalContinuations,
3748
3833
  toolResultContinuations
3749
3834
  };
3750
3835
  }
3836
+ }
3837
+ return void 0;
3838
+ }
3839
+ /*
3840
+ * Reduce AI SDK input to the single user message the harness should run
3841
+ * for this turn. The harness session owns prior-turn state (system
3842
+ * prompt, assistant turns, tool results) — we never replay it. A bare
3843
+ * string is forwarded as-is; a message array is collapsed to its last
3844
+ * `role: 'user'` entry. Inputs whose only messages are non-user (system,
3845
+ * assistant, tool) have no fresh user input and are rejected.
3846
+ */
3847
+ _resolvePromptTurnInput(options) {
3848
+ if (typeof options.prompt === "string") {
3849
+ return options.prompt;
3850
+ }
3851
+ const messages = Array.isArray(options.prompt) ? options.prompt : options.messages;
3852
+ if (Array.isArray(messages)) {
3751
3853
  for (let i = messages.length - 1; i >= 0; i--) {
3752
3854
  const message = messages[i];
3753
- if ((message == null ? void 0 : message.role) === "user")
3754
- return { mode: "prompt", prompt: message };
3855
+ if ((message == null ? void 0 : message.role) === "user") return message;
3755
3856
  }
3756
3857
  throw new Error(
3757
3858
  'HarnessAgent: messages must contain at least one `role: "user"` entry.'
@@ -3759,15 +3860,107 @@ var HarnessAgent = class {
3759
3860
  }
3760
3861
  throw new Error("HarnessAgent: either `prompt` or `messages` is required.");
3761
3862
  }
3863
+ async _preparePromptTurnInput(options) {
3864
+ var _a4, _b4, _c;
3865
+ let callOptions = options;
3866
+ if (this.settings.callOptionsSchema != null && options.options !== void 0) {
3867
+ const validatedOptions = await validateTypes({
3868
+ value: options.options,
3869
+ schema: this.settings.callOptionsSchema,
3870
+ context: { field: "options" }
3871
+ });
3872
+ callOptions = {
3873
+ ...options,
3874
+ options: validatedOptions
3875
+ };
3876
+ }
3877
+ const {
3878
+ session: _session,
3879
+ abortSignal: _abortSignal,
3880
+ timeout: _timeout,
3881
+ onStart: _onStart,
3882
+ experimental_onStart: _experimentalOnStart,
3883
+ onStepStart: _onStepStart,
3884
+ experimental_onStepStart: _experimentalOnStepStart,
3885
+ onToolExecutionStart: _onToolExecutionStart,
3886
+ experimental_onToolCallStart: _experimentalOnToolCallStart,
3887
+ onToolExecutionEnd: _onToolExecutionEnd,
3888
+ experimental_onToolCallFinish: _experimentalOnToolCallFinish,
3889
+ onStepEnd: _onStepEnd,
3890
+ onStepFinish: _onStepFinish,
3891
+ onEnd: _onEnd,
3892
+ onFinish: _onFinish,
3893
+ experimental_sandbox: _experimentalSandbox,
3894
+ ...promptOptions
3895
+ } = callOptions;
3896
+ const baseCallArgs = {
3897
+ skills: this.settings.skills,
3898
+ instructions: this.settings.instructions,
3899
+ tools: this.settings.tools,
3900
+ ...promptOptions
3901
+ };
3902
+ const preparedCallArgs = (_c = await ((_b4 = (_a4 = this.settings).prepareCall) == null ? void 0 : _b4.call(
3903
+ _a4,
3904
+ baseCallArgs
3905
+ ))) != null ? _c : baseCallArgs;
3906
+ if (this._resolveContinueTurnInput(preparedCallArgs) != null) {
3907
+ throw new Error(
3908
+ "HarnessAgent.prepareCall must return a fresh user prompt, not a tool continuation."
3909
+ );
3910
+ }
3911
+ return {
3912
+ prompt: this._resolvePromptTurnInput(preparedCallArgs),
3913
+ ...this._prepareTurnSettings({
3914
+ skills: preparedCallArgs.skills,
3915
+ instructions: preparedCallArgs.instructions,
3916
+ tools: preparedCallArgs.tools
3917
+ })
3918
+ };
3919
+ }
3920
+ _prepareContinueTurnInput(options) {
3921
+ var _a4, _b4;
3922
+ return {
3923
+ ...this._prepareTurnSettings({
3924
+ skills: this.settings.skills,
3925
+ instructions: this.settings.instructions,
3926
+ tools: this.settings.tools
3927
+ }),
3928
+ toolApprovalContinuations: (_a4 = options.toolApprovalContinuations) != null ? _a4 : [],
3929
+ toolResultContinuations: (_b4 = options.toolResultContinuations) != null ? _b4 : []
3930
+ };
3931
+ }
3932
+ _prepareTurnSettings(options) {
3933
+ var _a4, _b4;
3934
+ const userTools = (_a4 = options.tools) != null ? _a4 : {};
3935
+ const tools = {
3936
+ ...this.settings.harness.builtinTools,
3937
+ ...userTools
3938
+ };
3939
+ const toolFiltering = resolveHarnessAgentToolFiltering({
3940
+ harness: this.settings.harness,
3941
+ userTools,
3942
+ allTools: tools,
3943
+ activeTools: this.settings.activeTools,
3944
+ inactiveTools: this.settings.inactiveTools
3945
+ });
3946
+ return {
3947
+ skills: (_b4 = options.skills) != null ? _b4 : [],
3948
+ instructions: options.instructions,
3949
+ tools,
3950
+ activeTools: toolFiltering.activeUserTools,
3951
+ toolSpecs: this._toToolSpecs(toolFiltering.activeUserTools),
3952
+ builtinToolFiltering: toolFiltering.builtinToolFiltering
3953
+ };
3954
+ }
3762
3955
  /*
3763
3956
  * Wire-format projection of user-defined tools only. Harness builtins are
3764
3957
  * executed by the runtime and the bridge already knows about them — we
3765
3958
  * never re-declare them over the wire.
3766
3959
  */
3767
- _toToolSpecs() {
3960
+ _toToolSpecs(activeUserTools) {
3768
3961
  const specs = [];
3769
3962
  for (const [name4, tool] of Object.entries(
3770
- this.activeUserTools
3963
+ activeUserTools
3771
3964
  )) {
3772
3965
  const t = tool;
3773
3966
  let inputSchema;