From 7c1375ceb8a48183f3d53a2adf19149abaa890c6 Mon Sep 17 00:00:00 2001 From: can1357 Date: Tue, 14 Jul 2026 18:03:50 +0200 Subject: [PATCH] fix(coding-agent): preserve auth fallback resolution warnings --- .../coding-agent/src/config/model-resolver.ts | 2 +- .../issue-985-subagent-auth-fallback.test.ts | 43 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/packages/coding-agent/src/config/model-resolver.ts b/packages/coding-agent/src/config/model-resolver.ts index 4263a1af1..e7b3249a4 100644 --- a/packages/coding-agent/src/config/model-resolver.ts +++ b/packages/coding-agent/src/config/model-resolver.ts @@ -1293,7 +1293,7 @@ export async function resolveModelOverrideWithAuthFallback( return { ...primary, authFallbackUsed: false }; } - return { ...fallback, authFallbackUsed: true }; + return { ...fallback, authFallbackUsed: true, warning: primary.warning ?? fallback.warning }; } /** diff --git a/packages/coding-agent/test/issue-985-subagent-auth-fallback.test.ts b/packages/coding-agent/test/issue-985-subagent-auth-fallback.test.ts index 2b072fe52..24046b11c 100644 --- a/packages/coding-agent/test/issue-985-subagent-auth-fallback.test.ts +++ b/packages/coding-agent/test/issue-985-subagent-auth-fallback.test.ts @@ -212,6 +212,49 @@ describe("issue #5325: sessionId forwarded to getApiKey for session-sticky OAuth expect(result.model?.provider).toBe("opencode-zen"); expect(result.model?.id).toBe("qwen3.6-plus-free"); }); + test("forwards sessionId to getApiKey for the fallback model", async () => { + const receivedSessionIds: string[] = []; + const registry: ModelLookupRegistry & { getApiKey(model: Model): Promise } = { + getAvailable: () => [parentModel, unauthedTaskModel], + getApiKey: async (model: Model, sessionId?: string) => { + if (sessionId) receivedSessionIds.push(`${model.provider}:${sessionId}`); + if (model.provider === "opencode-zen") return undefined; + return sessionId ? "sk-resolved-token" : undefined; + }, + } as never; + + const result = await resolveModelOverrideWithAuthFallback( + ["qwen3.6-plus-free"], + "deepseek/deepseek-v4-pro", + registry, + undefined, + "subagent-session-456", + ); + + expect(receivedSessionIds).toEqual([ + "opencode-zen:subagent-session-456", + "deepseek:subagent-session-456", + ]); + expect(result.authFallbackUsed).toBe(true); + expect(result.model?.provider).toBe("deepseek"); + }); + test("preserves the requested model warning when auth falls back", async () => { + const registry: ModelLookupRegistry & { getApiKey(model: Model): Promise } = { + getAvailable: () => [parentModel, unauthedTaskModel], + getApiKey: async (model: Model) => (model.provider === "deepseek" ? "sk-test" : undefined), + } as never; + + const result = await resolveModelOverrideWithAuthFallback( + ["qwen3.6-plus-free:invalid"], + "deepseek/deepseek-v4-pro", + registry, + ); + + expect(result.authFallbackUsed).toBe(true); + expect(result.warning).toBe( + 'Invalid thinking level "invalid" in pattern "qwen3.6-plus-free:invalid". Using default instead.', + ); + }); test("still falls back when getApiKey returns undefined even with sessionId", async () => { const registry: ModelLookupRegistry & { getApiKey(model: Model): Promise } = {