| ... | @@ -132,6 +132,12 @@ const CLAUDE_TEST_MODEL_SELECTION = { | ... | @@ -132,6 +132,12 @@ const CLAUDE_TEST_MODEL_SELECTION = { |
| 132 | model: "claude-sonnet-4-6", | 132 | model: "claude-sonnet-4-6", |
| 133 | options: [{ id: "effort", value: "ultrathink" }], | 133 | options: [{ id: "effort", value: "ultrathink" }], |
| 134 | } satisfies ModelSelection; | 134 | } satisfies ModelSelection; |
| | 135 | // Thinking is a launch flag, so switching to this selection needs a new process. |
| | 136 | const CLAUDE_TEST_RESTART_MODEL_SELECTION = { |
| | 137 | ...CLAUDE_TEST_MODEL_SELECTION, |
| | 138 | model: "claude-haiku-4-5-20251001", |
| | 139 | options: [{ id: "thinking", value: false }], |
| | 140 | } satisfies ModelSelection; |
| 135 | const CLAUDE_TEST_RUNTIME_POLICY = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ | 141 | const CLAUDE_TEST_RUNTIME_POLICY = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 136 | runtimeMode: "full-access", | 142 | runtimeMode: "full-access", |
| 137 | interactionMode: "default", | 143 | interactionMode: "default", |
| ... | @@ -1027,6 +1033,7 @@ describe("ClaudeAdapterV2 Auto-accept edits", () => { | ... | @@ -1027,6 +1033,7 @@ describe("ClaudeAdapterV2 Auto-accept edits", () => { |
| 1027 | messages: Stream.never, | 1033 | messages: Stream.never, |
| 1028 | offer: () => Effect.void, | 1034 | offer: () => Effect.void, |
| 1029 | setModel: () => Effect.void, | 1035 | setModel: () => Effect.void, |
| | 1036 | applyFlagSettings: () => Effect.void, |
| 1030 | setPermissionMode: () => Effect.void, | 1037 | setPermissionMode: () => Effect.void, |
| 1031 | stopTask: () => Effect.void, | 1038 | stopTask: () => Effect.void, |
| 1032 | interrupt: Effect.void, | 1039 | interrupt: Effect.void, |
| ... | @@ -1187,6 +1194,7 @@ const captureSdkExecutablePaths = Effect.fn("captureSdkExecutablePaths")(functio | ... | @@ -1187,6 +1194,7 @@ const captureSdkExecutablePaths = Effect.fn("captureSdkExecutablePaths")(functio |
| 1187 | messages: Stream.never, | 1194 | messages: Stream.never, |
| 1188 | offer: () => Effect.void, | 1195 | offer: () => Effect.void, |
| 1189 | setModel: () => Effect.void, | 1196 | setModel: () => Effect.void, |
| | 1197 | applyFlagSettings: () => Effect.void, |
| 1190 | setPermissionMode: () => Effect.void, | 1198 | setPermissionMode: () => Effect.void, |
| 1191 | stopTask: () => Effect.void, | 1199 | stopTask: () => Effect.void, |
| 1192 | interrupt: Effect.void, | 1200 | interrupt: Effect.void, |
| ... | @@ -1307,6 +1315,7 @@ describe("ClaudeAdapterV2 resume compaction", () => { | ... | @@ -1307,6 +1315,7 @@ describe("ClaudeAdapterV2 resume compaction", () => { |
| 1307 | messages: Stream.never, | 1315 | messages: Stream.never, |
| 1308 | offer: () => Effect.void, | 1316 | offer: () => Effect.void, |
| 1309 | setModel: () => Effect.void, | 1317 | setModel: () => Effect.void, |
| | 1318 | applyFlagSettings: () => Effect.void, |
| 1310 | setPermissionMode: () => Effect.void, | 1319 | setPermissionMode: () => Effect.void, |
| 1311 | stopTask: () => Effect.void, | 1320 | stopTask: () => Effect.void, |
| 1312 | interrupt: Effect.void, | 1321 | interrupt: Effect.void, |
| ... | @@ -1533,6 +1542,7 @@ describe("ClaudeAdapterV2 attachments", () => { | ... | @@ -1533,6 +1542,7 @@ describe("ClaudeAdapterV2 attachments", () => { |
| 1533 | offeredMessages.push(message); | 1542 | offeredMessages.push(message); |
| 1534 | }), | 1543 | }), |
| 1535 | setModel: () => Effect.void, | 1544 | setModel: () => Effect.void, |
| | 1545 | applyFlagSettings: () => Effect.void, |
| 1536 | setPermissionMode: () => Effect.void, | 1546 | setPermissionMode: () => Effect.void, |
| 1537 | stopTask: () => Effect.void, | 1547 | stopTask: () => Effect.void, |
| 1538 | interrupt: Effect.void, | 1548 | interrupt: Effect.void, |
| ... | @@ -1678,6 +1688,7 @@ describe("ClaudeAdapterV2 attachments", () => { | ... | @@ -1678,6 +1688,7 @@ describe("ClaudeAdapterV2 attachments", () => { |
| 1678 | messages: Stream.never, | 1688 | messages: Stream.never, |
| 1679 | offer: () => Effect.void, | 1689 | offer: () => Effect.void, |
| 1680 | setModel: () => Effect.void, | 1690 | setModel: () => Effect.void, |
| | 1691 | applyFlagSettings: () => Effect.void, |
| 1681 | setPermissionMode: () => Effect.void, | 1692 | setPermissionMode: () => Effect.void, |
| 1682 | stopTask: () => Effect.void, | 1693 | stopTask: () => Effect.void, |
| 1683 | interrupt: Effect.void, | 1694 | interrupt: Effect.void, |
| ... | @@ -1773,6 +1784,7 @@ describe("ClaudeAdapterV2 native fork", () => { | ... | @@ -1773,6 +1784,7 @@ describe("ClaudeAdapterV2 native fork", () => { |
| 1773 | messages: Stream.empty, | 1784 | messages: Stream.empty, |
| 1774 | offer: () => Effect.void, | 1785 | offer: () => Effect.void, |
| 1775 | setModel: () => Effect.void, | 1786 | setModel: () => Effect.void, |
| | 1787 | applyFlagSettings: () => Effect.void, |
| 1776 | setPermissionMode: () => Effect.void, | 1788 | setPermissionMode: () => Effect.void, |
| 1777 | stopTask: () => Effect.void, | 1789 | stopTask: () => Effect.void, |
| 1778 | interrupt: Effect.void, | 1790 | interrupt: Effect.void, |
| ... | @@ -2065,6 +2077,7 @@ describe("ClaudeAdapterV2 native session identity", () => { | ... | @@ -2065,6 +2077,7 @@ describe("ClaudeAdapterV2 native session identity", () => { |
| 2065 | messages: Stream.empty, | 2077 | messages: Stream.empty, |
| 2066 | offer: () => Effect.void, | 2078 | offer: () => Effect.void, |
| 2067 | setModel: () => Effect.void, | 2079 | setModel: () => Effect.void, |
| | 2080 | applyFlagSettings: () => Effect.void, |
| 2068 | setPermissionMode: () => Effect.void, | 2081 | setPermissionMode: () => Effect.void, |
| 2069 | stopTask: () => Effect.void, | 2082 | stopTask: () => Effect.void, |
| 2070 | interrupt: Effect.void, | 2083 | interrupt: Effect.void, |
| ... | @@ -2356,6 +2369,8 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -2356,6 +2369,8 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 2356 | }); | 2369 | }); |
| 2357 | const offeredMessages: Array<SDKUserMessage> = []; | 2370 | const offeredMessages: Array<SDKUserMessage> = []; |
| 2358 | const permissionModeChanges: Array<string> = []; | 2371 | const permissionModeChanges: Array<string> = []; |
| | 2372 | // setModel and applyFlagSettings calls on the first process, in order. |
| | 2373 | const liveSelectionChanges: Array<unknown> = []; |
| 2359 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = | 2374 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 2360 | []; | 2375 | []; |
| 2361 | const continuationReceipts = | 2376 | const continuationReceipts = |
| ... | @@ -2403,6 +2418,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -2403,6 +2418,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 2403 | offeredMessages.push(message); | 2418 | offeredMessages.push(message); |
| 2404 | }), | 2419 | }), |
| 2405 | setModel: () => Effect.void, | 2420 | setModel: () => Effect.void, |
| | 2421 | applyFlagSettings: () => Effect.void, |
| 2406 | setPermissionMode: () => Effect.void, | 2422 | setPermissionMode: () => Effect.void, |
| 2407 | stopTask: options?.stopTask ?? (() => Effect.void), | 2423 | stopTask: options?.stopTask ?? (() => Effect.void), |
| 2408 | interrupt: Effect.void, | 2424 | interrupt: Effect.void, |
| ... | @@ -2432,7 +2448,14 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -2432,7 +2448,14 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 2432 | Effect.sync(() => { | 2448 | Effect.sync(() => { |
| 2433 | offeredMessages.push(message); | 2449 | offeredMessages.push(message); |
| 2434 | }), | 2450 | }), |
| 2435 | setModel: () => Effect.void, | 2451 | setModel: (model) => |
| | 2452 | Effect.sync(() => { |
| | 2453 | liveSelectionChanges.push({ model }); |
| | 2454 | }), |
| | 2455 | applyFlagSettings: (settings) => |
| | 2456 | Effect.sync(() => { |
| | 2457 | liveSelectionChanges.push(settings); |
| | 2458 | }), |
| 2436 | setPermissionMode: (mode) => | 2459 | setPermissionMode: (mode) => |
| 2437 | Effect.sync(() => { | 2460 | Effect.sync(() => { |
| 2438 | permissionModeChanges.push(mode); | 2461 | permissionModeChanges.push(mode); |
| ... | @@ -2503,6 +2526,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -2503,6 +2526,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 2503 | return uuid; | 2526 | return uuid; |
| 2504 | }, | 2527 | }, |
| 2505 | permissionModeChanges, | 2528 | permissionModeChanges, |
| | 2529 | liveSelectionChanges, |
| 2506 | continuationRequests, | 2530 | continuationRequests, |
| 2507 | continuationReceipts, | 2531 | continuationReceipts, |
| 2508 | events, | 2532 | events, |
| ... | @@ -2627,7 +2651,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -2627,7 +2651,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 2627 | ); | 2651 | ); |
| 2628 | | 2652 | |
| 2629 | it.effect( | 2653 | it.effect( |
| 2630 | "reuses a background shell's query for omitted and explicit Normal, but blocks Fast", | 2654 | "applies model, effort and Fast changes to a process running a background shell, but not thinking or a cleared effort", |
| 2631 | () => | 2655 | () => |
| 2632 | Effect.scoped( | 2656 | Effect.scoped( |
| 2633 | Effect.gen(function* () { | 2657 | Effect.gen(function* () { |
| ... | @@ -2648,41 +2672,65 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -2648,41 +2672,65 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 2648 | providerTurnOrdinal: ordinal, | 2672 | providerTurnOrdinal: ordinal, |
| 2649 | modelSelection, | 2673 | modelSelection, |
| 2650 | }); | 2674 | }); |
| | 2675 | const settle = Effect.gen(function* () { |
| | 2676 | yield* harness.offerAndWait(turnOneResult); |
| | 2677 | yield* Queue.take(harness.terminalReceipts); |
| | 2678 | }); |
| 2651 | yield* harness.runtime.startTurn(turn(1, normal)); | 2679 | yield* harness.runtime.startTurn(turn(1, normal)); |
| 2652 | const originalOptions = harness.getOpenedOptions(); | 2680 | const originalOptions = harness.getOpenedOptions(); |
| 2653 | yield* harness.offerAndWait(wakeTaskStarted); | 2681 | yield* harness.offerAndWait(wakeTaskStarted); |
| 2654 | yield* harness.offerAndWait(turnOneResult); | 2682 | yield* settle; |
| 2655 | yield* Queue.take(harness.terminalReceipts); | | |
| 2656 | assert.isTrue(yield* harness.hasPendingBackgroundWork); | 2683 | assert.isTrue(yield* harness.hasPendingBackgroundWork); |
| 2657 | | 2684 | |
| | 2685 | // Omitted and explicit Normal are the same selection. |
| 2658 | yield* harness.runtime.startTurn( | 2686 | yield* harness.runtime.startTurn( |
| 2659 | turn(2, { | 2687 | turn(2, { ...normal, options: [{ id: "fastMode", value: false }] }), |
| | 2688 | ); |
| | 2689 | yield* settle; |
| | 2690 | assert.deepEqual(harness.liveSelectionChanges, []); |
| | 2691 | |
| | 2692 | yield* harness.runtime.startTurn( |
| | 2693 | turn(3, { |
| 2660 | ...normal, | 2694 | ...normal, |
| 2661 | options: [{ id: "fastMode", value: false }], | 2695 | options: [ |
| | 2696 | { id: "effort", value: "ultracode" }, |
| | 2697 | { id: "fastMode", value: true }, |
| | 2698 | ], |
| 2662 | }), | 2699 | }), |
| 2663 | ); | 2700 | ); |
| | 2701 | yield* settle; |
| | 2702 | yield* harness.runtime.startTurn(turn(4, { ...normal, model: "claude-sonnet-4-6" })); |
| | 2703 | yield* settle; |
| | 2704 | assert.deepEqual(harness.liveSelectionChanges, [ |
| | 2705 | { model: "claude-opus-5-5" }, |
| | 2706 | { effortLevel: "xhigh", fastMode: true, ultracode: true }, |
| | 2707 | { model: "claude-sonnet-4-6" }, |
| | 2708 | // Sonnet's default effort; it has no Fast mode. |
| | 2709 | { effortLevel: "high", fastMode: null, ultracode: null }, |
| | 2710 | ]); |
| 2664 | assert.strictEqual(harness.getOpenedOptions(), originalOptions); | 2711 | assert.strictEqual(harness.getOpenedOptions(), originalOptions); |
| 2665 | assert.lengthOf(harness.offeredMessages, 2); | 2712 | assert.lengthOf(harness.offeredMessages, 4); |
| 2666 | yield* harness.offerAndWait(turnOneResult); | 2713 | |
| 2667 | yield* Queue.take(harness.terminalReceipts); | 2714 | // Thinking is a launch flag. Haiku 4.5 has no effort, and only a new |
| 2668 | | 2715 | // process reads the user's configured effort again. |
| 2669 | const refused = yield* harness.runtime | 2716 | for (const [ordinal, selection] of [ |
| 2670 | .startTurn( | 2717 | [5, CLAUDE_TEST_RESTART_MODEL_SELECTION], |
| 2671 | turn(3, { | 2718 | [6, { ...normal, model: "claude-haiku-4-5-20251001" }], |
| 2672 | ...normal, | 2719 | ] as const) { |
| 2673 | options: [{ id: "fastMode", value: true }], | 2720 | const refused = yield* harness.runtime |
| 2674 | }), | 2721 | .startTurn(turn(ordinal, selection)) |
| 2675 | ) | 2722 | .pipe(Effect.result); |
| 2676 | .pipe(Effect.result); | 2723 | assert.equal(refused._tag, "Failure"); |
| 2677 | assert.equal(refused._tag, "Failure"); | 2724 | if (refused._tag === "Failure") { |
| 2678 | if (refused._tag === "Failure") { | 2725 | assert.instanceOf( |
| 2679 | assert.instanceOf( | 2726 | refused.failure.cause, |
| 2680 | refused.failure.cause, | 2727 | ClaudeAdapterV2.ClaudeBackgroundWorkBlocksQueryReplacementError, |
| 2681 | ClaudeAdapterV2.ClaudeBackgroundWorkBlocksQueryReplacementError, | 2728 | ); |
| 2682 | ); | 2729 | } |
| 2683 | } | 2730 | } |
| 2684 | assert.strictEqual(harness.getOpenedOptions(), originalOptions); | 2731 | assert.strictEqual(harness.getOpenedOptions(), originalOptions); |
| 2685 | assert.lengthOf(harness.offeredMessages, 2); | 2732 | assert.lengthOf(harness.offeredMessages, 4); |
| | 2733 | assert.lengthOf(harness.liveSelectionChanges, 4); |
| 2686 | assert.isTrue(yield* harness.hasPendingBackgroundWork); | 2734 | assert.isTrue(yield* harness.hasPendingBackgroundWork); |
| 2687 | }).pipe( | 2735 | }).pipe( |
| 2688 | Effect.provide( | 2736 | Effect.provide( |
| ... | @@ -4948,6 +4996,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -4948,6 +4996,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 4948 | messages: Stream.fromQueue(sdkMessages), | 4996 | messages: Stream.fromQueue(sdkMessages), |
| 4949 | offer: () => Effect.void, | 4997 | offer: () => Effect.void, |
| 4950 | setModel: () => Effect.void, | 4998 | setModel: () => Effect.void, |
| | 4999 | applyFlagSettings: () => Effect.void, |
| 4951 | setPermissionMode: () => Effect.void, | 5000 | setPermissionMode: () => Effect.void, |
| 4952 | stopTask: () => Effect.void, | 5001 | stopTask: () => Effect.void, |
| 4953 | interrupt: Effect.void, | 5002 | interrupt: Effect.void, |
| ... | @@ -5208,6 +5257,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -5208,6 +5257,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 5208 | messages: Stream.fromQueue(queue), | 5257 | messages: Stream.fromQueue(queue), |
| 5209 | offer: () => Effect.void, | 5258 | offer: () => Effect.void, |
| 5210 | setModel: () => Effect.void, | 5259 | setModel: () => Effect.void, |
| | 5260 | applyFlagSettings: () => Effect.void, |
| 5211 | setPermissionMode: () => Effect.void, | 5261 | setPermissionMode: () => Effect.void, |
| 5212 | stopTask: () => Effect.void, | 5262 | stopTask: () => Effect.void, |
| 5213 | interrupt: Effect.void, | 5263 | interrupt: Effect.void, |
| ... | @@ -10299,6 +10349,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -10299,6 +10349,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 10299 | messages: Stream.fromQueue(sdkMessages), | 10349 | messages: Stream.fromQueue(sdkMessages), |
| 10300 | offer: () => Effect.void, | 10350 | offer: () => Effect.void, |
| 10301 | setModel: () => Effect.void, | 10351 | setModel: () => Effect.void, |
| | 10352 | applyFlagSettings: () => Effect.void, |
| 10302 | setPermissionMode: () => Effect.void, | 10353 | setPermissionMode: () => Effect.void, |
| 10303 | stopTask: () => Effect.void, | 10354 | stopTask: () => Effect.void, |
| 10304 | interrupt: Effect.void, | 10355 | interrupt: Effect.void, |
| ... | @@ -10370,10 +10421,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -10370,10 +10421,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 10370 | ); | 10421 | ); |
| 10371 | assert.isFalse(yield* hasPendingBackgroundWork); | 10422 | assert.isFalse(yield* hasPendingBackgroundWork); |
| 10372 | | 10423 | |
| 10373 | const alternateModel = { | 10424 | const alternateModel = CLAUDE_TEST_RESTART_MODEL_SELECTION; |
| 10374 | ...CLAUDE_TEST_MODEL_SELECTION, | | |
| 10375 | model: "claude-haiku-4-5-20251001", | | |
| 10376 | } satisfies ModelSelection; | | |
| 10377 | // ProviderTurnStartService marks the thread active before startTurn; | 10425 | // ProviderTurnStartService marks the thread active before startTurn; |
| 10378 | // the process-reset clear must preserve that status. | 10426 | // the process-reset clear must preserve that status. |
| 10379 | const activeProviderThread = { | 10427 | const activeProviderThread = { |
| ... | @@ -10489,6 +10537,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -10489,6 +10537,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 10489 | messages: Stream.fromQueue(sdkMessages), | 10537 | messages: Stream.fromQueue(sdkMessages), |
| 10490 | offer: () => Effect.void, | 10538 | offer: () => Effect.void, |
| 10491 | setModel: () => Effect.void, | 10539 | setModel: () => Effect.void, |
| | 10540 | applyFlagSettings: () => Effect.void, |
| 10492 | setPermissionMode: () => Effect.void, | 10541 | setPermissionMode: () => Effect.void, |
| 10493 | stopTask: () => Effect.void, | 10542 | stopTask: () => Effect.void, |
| 10494 | interrupt: Effect.void, | 10543 | interrupt: Effect.void, |
| ... | @@ -10556,10 +10605,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -10556,10 +10605,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 10556 | | 10605 | |
| 10557 | // User turn changes model, replacing the query while the wake buffer | 10606 | // User turn changes model, replacing the query while the wake buffer |
| 10558 | // stays queued for the later provider continuation. | 10607 | // stays queued for the later provider continuation. |
| 10559 | const alternateModel = { | 10608 | const alternateModel = CLAUDE_TEST_RESTART_MODEL_SELECTION; |
| 10560 | ...CLAUDE_TEST_MODEL_SELECTION, | | |
| 10561 | model: "claude-haiku-4-5-20251001", | | |
| 10562 | } satisfies ModelSelection; | | |
| 10563 | yield* runtime.startTurn( | 10609 | yield* runtime.startTurn( |
| 10564 | makeClaudeTestTurnInput({ | 10610 | makeClaudeTestTurnInput({ |
| 10565 | threadId, | 10611 | threadId, |
| ... | @@ -10731,6 +10777,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -10731,6 +10777,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 10731 | messages: Stream.fromQueue(sdkMessages), | 10777 | messages: Stream.fromQueue(sdkMessages), |
| 10732 | offer: () => Effect.void, | 10778 | offer: () => Effect.void, |
| 10733 | setModel: () => Effect.void, | 10779 | setModel: () => Effect.void, |
| | 10780 | applyFlagSettings: () => Effect.void, |
| 10734 | setPermissionMode: () => Effect.void, | 10781 | setPermissionMode: () => Effect.void, |
| 10735 | stopTask: () => Effect.void, | 10782 | stopTask: () => Effect.void, |
| 10736 | interrupt: Effect.void, | 10783 | interrupt: Effect.void, |
| ... | @@ -10818,10 +10865,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -10818,10 +10865,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 10818 | // Model-changing user turn replaces the query while continuation stays | 10865 | // Model-changing user turn replaces the query while continuation stays |
| 10819 | // queued. Process reset must not invent opaque classification for the | 10866 | // queued. Process reset must not invent opaque classification for the |
| 10820 | // buffered subagent notification. | 10867 | // buffered subagent notification. |
| 10821 | const alternateModel = { | 10868 | const alternateModel = CLAUDE_TEST_RESTART_MODEL_SELECTION; |
| 10822 | ...CLAUDE_TEST_MODEL_SELECTION, | | |
| 10823 | model: "claude-haiku-4-5-20251001", | | |
| 10824 | } satisfies ModelSelection; | | |
| 10825 | yield* runtime.startTurn( | 10869 | yield* runtime.startTurn( |
| 10826 | makeClaudeTestTurnInput({ | 10870 | makeClaudeTestTurnInput({ |
| 10827 | threadId, | 10871 | threadId, |
| ... | @@ -10900,7 +10944,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -10900,7 +10944,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 10900 | ), | 10944 | ), |
| 10901 | ); | 10945 | ); |
| 10902 | | 10946 | |
| 10903 | it.effect("refuses a model change that would kill a running background subagent", () => | 10947 | it.effect("refuses a thinking change that would kill a running background subagent", () => |
| 10904 | Effect.scoped( | 10948 | Effect.scoped( |
| 10905 | Effect.gen(function* () { | 10949 | Effect.gen(function* () { |
| 10906 | const SUBAGENT_TASK_ID = "task-model-change-running-subagent"; | 10950 | const SUBAGENT_TASK_ID = "task-model-change-running-subagent"; |
| ... | @@ -10932,6 +10976,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -10932,6 +10976,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 10932 | messages: Stream.fromQueue(sdkMessages), | 10976 | messages: Stream.fromQueue(sdkMessages), |
| 10933 | offer: () => Effect.void, | 10977 | offer: () => Effect.void, |
| 10934 | setModel: () => Effect.void, | 10978 | setModel: () => Effect.void, |
| | 10979 | applyFlagSettings: () => Effect.void, |
| 10935 | setPermissionMode: () => Effect.void, | 10980 | setPermissionMode: () => Effect.void, |
| 10936 | stopTask: () => Effect.void, | 10981 | stopTask: () => Effect.void, |
| 10937 | interrupt: Effect.void, | 10982 | interrupt: Effect.void, |
| ... | @@ -11004,12 +11049,9 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -11004,12 +11049,9 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 11004 | yield* awaitUntil(() => terminals().length === 1, "first turn terminal"); | 11049 | yield* awaitUntil(() => terminals().length === 1, "first turn terminal"); |
| 11005 | const settledTurn = terminals()[0]!; | 11050 | const settledTurn = terminals()[0]!; |
| 11006 | | 11051 | |
| 11007 | // The subagent runs inside the first CLI process. Another model needs | 11052 | // The subagent runs inside the first CLI process. A thinking change |
| 11008 | // another process, so the turn must not start and close this one. | 11053 | // needs another process, so the turn must not start and close this one. |
| 11009 | const alternateModel = { | 11054 | const alternateModel = CLAUDE_TEST_RESTART_MODEL_SELECTION; |
| 11010 | ...CLAUDE_TEST_MODEL_SELECTION, | | |
| 11011 | model: "claude-haiku-4-5-20251001", | | |
| 11012 | } satisfies ModelSelection; | | |
| 11013 | const switchTurn = (attempt: string) => | 11055 | const switchTurn = (attempt: string) => |
| 11014 | runtime.startTurn( | 11056 | runtime.startTurn( |
| 11015 | makeClaudeTestTurnInput({ | 11057 | makeClaudeTestTurnInput({ |
| ... | @@ -11115,6 +11157,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -11115,6 +11157,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 11115 | messages: Stream.fromQueue(sdkMessages), | 11157 | messages: Stream.fromQueue(sdkMessages), |
| 11116 | offer: () => Effect.void, | 11158 | offer: () => Effect.void, |
| 11117 | setModel: () => Effect.void, | 11159 | setModel: () => Effect.void, |
| | 11160 | applyFlagSettings: () => Effect.void, |
| 11118 | setPermissionMode: () => Effect.void, | 11161 | setPermissionMode: () => Effect.void, |
| 11119 | stopTask: () => Effect.void, | 11162 | stopTask: () => Effect.void, |
| 11120 | interrupt: Effect.void, | 11163 | interrupt: Effect.void, |
| ... | @@ -11174,10 +11217,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -11174,10 +11217,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 11174 | ); | 11217 | ); |
| 11175 | assert.isTrue(yield* hasPendingBackgroundWork); | 11218 | assert.isTrue(yield* hasPendingBackgroundWork); |
| 11176 | | 11219 | |
| 11177 | const alternateModel = { | 11220 | const alternateModel = CLAUDE_TEST_RESTART_MODEL_SELECTION; |
| 11178 | ...CLAUDE_TEST_MODEL_SELECTION, | | |
| 11179 | model: "claude-haiku-4-5-20251001", | | |
| 11180 | } satisfies ModelSelection; | | |
| 11181 | const failedStart = yield* runtime | 11221 | const failedStart = yield* runtime |
| 11182 | .startTurn( | 11222 | .startTurn( |
| 11183 | makeClaudeTestTurnInput({ | 11223 | makeClaudeTestTurnInput({ |
| ... | @@ -11254,6 +11294,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -11254,6 +11294,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 11254 | messages: Stream.fromQueue(sdkMessages), | 11294 | messages: Stream.fromQueue(sdkMessages), |
| 11255 | offer: () => Effect.void, | 11295 | offer: () => Effect.void, |
| 11256 | setModel: () => Effect.void, | 11296 | setModel: () => Effect.void, |
| | 11297 | applyFlagSettings: () => Effect.void, |
| 11257 | setPermissionMode: () => Effect.void, | 11298 | setPermissionMode: () => Effect.void, |
| 11258 | stopTask: () => Effect.void, | 11299 | stopTask: () => Effect.void, |
| 11259 | interrupt: Effect.void, | 11300 | interrupt: Effect.void, |
| ... | @@ -11317,10 +11358,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -11317,10 +11358,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 11317 | yield* awaitUntil(() => continuationRequests.length === 1, "first continuation request"); | 11358 | yield* awaitUntil(() => continuationRequests.length === 1, "first continuation request"); |
| 11318 | assert.isTrue(yield* hasPendingBackgroundWork); | 11359 | assert.isTrue(yield* hasPendingBackgroundWork); |
| 11319 | | 11360 | |
| 11320 | const alternateModel = { | 11361 | const alternateModel = CLAUDE_TEST_RESTART_MODEL_SELECTION; |
| 11321 | ...CLAUDE_TEST_MODEL_SELECTION, | | |
| 11322 | model: "claude-haiku-4-5-20251001", | | |
| 11323 | } satisfies ModelSelection; | | |
| 11324 | const failedStart = yield* runtime | 11362 | const failedStart = yield* runtime |
| 11325 | .startTurn( | 11363 | .startTurn( |
| 11326 | makeClaudeTestTurnInput({ | 11364 | makeClaudeTestTurnInput({ |