- Snapshot sessions Map with Array.from() in stopAll and finalizer to prevent entries being skipped when stopSessionInternal deletes during iteration (ClaudeCodeAdapter.ts) - Stop resolving aliases in normalizeCustomModelSlugs so dated model versions like claude-sonnet-4-6-20251117 are not silently dropped as built-in duplicates (appSettings.ts) - Remove incorrect model: gpt-5-codex assertion from claudeCode provider test since the test validates provider selection, not model resolution (ProviderCommandReactor.test.ts)
Unified · Split
| @@ -416,7 +416,6 @@ describe("ProviderCommandReactor", () => { · 415 unmodified lines | ||
| 416 | 416 | expect(harness.startSession.mock.calls[0]?.[1]).toMatchObject({ |
| 417 | 417 | provider: "claudeCode", |
| 418 | 418 | cwd: "/tmp/provider-project", |
| 419 | − model: "gpt-5-codex", | |
| 420 | 419 | runtimeMode: "approval-required", |
| 421 | 420 | }); |
| 422 | 421 | |
| @@ -1816,7 +1816,7 @@ function makeClaudeCodeAdapter(options?: ClaudeCodeAdapterLiveOptions) { · 1815 unmodified lines | ||
| 1816 | 1816 | |
| 1817 | 1817 | const stopAll: ClaudeCodeAdapterShape["stopAll"] = () => |
| 1818 | 1818 | Effect.forEach( |
| 1819 | − sessions, | |
| 1819 | + Array.from(sessions), | |
| 1820 | 1820 | ([, context]) => |
| 1821 | 1821 | stopSessionInternal(context, { |
| 1822 | 1822 | emitExitEvent: true, |
| @@ -1826,7 +1826,7 @@ function makeClaudeCodeAdapter(options?: ClaudeCodeAdapterLiveOptions) { · 3 unmodified lines | ||
| 1826 | 1826 | |
| 1827 | 1827 | yield* Effect.addFinalizer(() => |
| 1828 | 1828 | Effect.forEach( |
| 1829 | − sessions, | |
| 1829 | + Array.from(sessions), | |
| 1830 | 1830 | ([, context]) => |
| 1831 | 1831 | stopSessionInternal(context, { |
| 1832 | 1832 | emitExitEvent: false, |
| @@ -8,12 +8,11 @@ import { · 7 unmodified lines | ||
| 8 | 8 | } from "./appSettings"; |
| 9 | 9 | |
| 10 | 10 | describe("normalizeCustomModelSlugs", () => { |
| 11 | − it("normalizes aliases, removes built-ins, and deduplicates values", () => { | |
| 11 | + it("removes literal built-ins, trims whitespace, and deduplicates values", () => { | |
| 12 | 12 | expect( |
| 13 | 13 | normalizeCustomModelSlugs([ |
| 14 | 14 | " custom/internal-model ", |
| 15 | 15 | "gpt-5.3-codex", |
| 16 | − "5.3", | |
| 17 | 16 | "custom/internal-model", |
| 18 | 17 | "", |
| 19 | 18 | null, |
| @@ -21,8 +20,10 @@ describe("normalizeCustomModelSlugs", () => { · 1 unmodified line | ||
| 21 | 20 | ).toEqual(["custom/internal-model"]); |
| 22 | 21 | }); |
| 23 | 22 | |
| 24 | − it("normalizes provider-specific aliases for claude", () => { | |
| 25 | − expect(normalizeCustomModelSlugs(["sonnet"], "claudeCode")).toEqual([]); | |
| 23 | + it("preserves aliases and dated versions as custom models", () => { | |
| 24 | + expect(normalizeCustomModelSlugs(["claude-sonnet-4-6-20251117"], "claudeCode")).toEqual([ | |
| 25 | + "claude-sonnet-4-6-20251117", | |
| 26 | + ]); | |
| 26 | 27 | expect(normalizeCustomModelSlugs(["claude/custom-sonnet"], "claudeCode")).toEqual([ |
| 27 | 28 | "claude/custom-sonnet", |
| 28 | 29 | ]); |
| @@ -57,18 +57,19 @@ export function normalizeCustomModelSlugs( · 56 unmodified lines | ||
| 57 | 57 | const builtInModelSlugs = BUILT_IN_MODEL_SLUGS_BY_PROVIDER[provider]; |
| 58 | 58 | |
| 59 | 59 | for (const candidate of models) { |
| 60 | − const normalized = normalizeModelSlug(candidate, provider); | |
| 60 | + if (typeof candidate !== "string") continue; | |
| 61 | + const trimmed = candidate.trim(); | |
| 61 | 62 | if ( |
| 62 | − !normalized || | |
| 63 | − normalized.length > MAX_CUSTOM_MODEL_LENGTH || | |
| 64 | − builtInModelSlugs.has(normalized) || | |
| 65 | − seen.has(normalized) | |
| 63 | + !trimmed || | |
| 64 | + trimmed.length > MAX_CUSTOM_MODEL_LENGTH || | |
| 65 | + builtInModelSlugs.has(trimmed) || | |
| 66 | + seen.has(trimmed) | |
| 66 | 67 | ) { |
| 67 | 68 | continue; |
| 68 | 69 | } |
| 69 | 70 | |
| 70 | − seen.add(normalized); | |
| 71 | − normalizedModels.push(normalized); | |
| 71 | + seen.add(trimmed); | |
| 72 | + normalizedModels.push(trimmed); | |
| 72 | 73 | if (normalizedModels.length >= MAX_CUSTOM_MODEL_COUNT) { |
| 73 | 74 | break; |
| 74 | 75 | } |