fix: preserve chained fallback origin

This commit is contained in:
Peter Steinberger
2026-05-10 08:46:36 +01:00
parent 662b9d2f5d
commit d61b07a321
2 changed files with 56 additions and 2 deletions

View File

@@ -3658,4 +3658,39 @@ describe("runAgentTurnWithFallback", () => {
authProfileOverrideSource: "user",
});
});
it("preserves original auto-fallback origin across chained fallbacks", async () => {
const applyFallbackCandidateSelectionToEntry =
await getApplyFallbackCandidateSelectionToEntry();
const entry = {
sessionId: "session",
updatedAt: 1,
providerOverride: "openrouter",
modelOverride: "fallback-b",
modelOverrideSource: "auto" as const,
modelOverrideFallbackOriginProvider: "anthropic",
modelOverrideFallbackOriginModel: "claude-opus",
} as SessionEntry;
const { updated } = applyFallbackCandidateSelectionToEntry({
entry,
run: {
provider: "openrouter",
model: "fallback-b",
} as FollowupRun["run"],
provider: "openrouter",
model: "fallback-c",
now: 123,
});
expect(updated).toBe(true);
expect(entry).toMatchObject({
updatedAt: 123,
providerOverride: "openrouter",
modelOverride: "fallback-c",
modelOverrideSource: "auto",
modelOverrideFallbackOriginProvider: "anthropic",
modelOverrideFallbackOriginModel: "claude-opus",
});
});
});

View File

@@ -242,6 +242,24 @@ function buildFallbackSelectionState(params: {
};
}
function resolveFallbackSelectionOrigin(params: { entry: SessionEntry; run: FollowupRun["run"] }): {
provider: string;
model: string;
} {
if (params.entry.modelOverrideSource === "auto") {
const persistedOriginProvider = normalizeOptionalString(
params.entry.modelOverrideFallbackOriginProvider,
);
const persistedOriginModel = normalizeOptionalString(
params.entry.modelOverrideFallbackOriginModel,
);
if (persistedOriginProvider && persistedOriginModel) {
return { provider: persistedOriginProvider, model: persistedOriginModel };
}
}
return { provider: params.run.provider, model: params.run.model };
}
export function applyFallbackCandidateSelectionToEntry(params: {
entry: SessionEntry;
run: FollowupRun["run"];
@@ -253,11 +271,12 @@ export function applyFallbackCandidateSelectionToEntry(params: {
return { updated: false };
}
const scopedAuthProfile = resolveRunAuthProfile(params.run, params.provider);
const origin = resolveFallbackSelectionOrigin({ entry: params.entry, run: params.run });
const nextState = buildFallbackSelectionState({
provider: params.provider,
model: params.model,
originProvider: params.run.provider,
originModel: params.run.model,
originProvider: origin.provider,
originModel: origin.model,
authProfileId: scopedAuthProfile.authProfileId,
authProfileIdSource: scopedAuthProfile.authProfileIdSource,
});