fix(ai): forget the remembered working provider when the chain is saved

The in-memory memo of the last provider that answered reorders the
chain for up to an hour. Saving a new chain now drops it for that
account, so a provider the person removed or disabled no longer leads
the chain they just arranged.
This commit is contained in:
Marc-André Bombeck committed 2026-10-03 18:04:09 +02:00
1 parent 916f918674
commit 7022b698e7
4 files changed
+24 -1

No files matched your search

@@ -61,8 +61,14 @@ vi.mock("@/lib/logging/context", () => ({
annotate: vi.fn(),
}));
vi.mock("@/lib/ai/provider-runner", () => ({
getLastWorkingProvider: vi.fn(),
forgetLastWorkingProvider: vi.fn(),
}));
import { PUT } from "../route";
import { prisma } from "@/lib/db";
import { forgetLastWorkingProvider } from "@/lib/ai/provider-runner";
import { annotate } from "@/lib/logging/context";
interface Envelope {
@@ -108,6 +114,9 @@ describe("PUT /api/insights/provider-chain", () => {
],
});
expect(annotate).toHaveBeenCalled();
// The remembered working provider would reorder the chain the person
// just arranged; a save drops it for this account.
expect(forgetLastWorkingProvider).toHaveBeenCalledWith("u-1");
});
it("rejects unknown provider types with 422", async () => {
@@ -30,6 +30,7 @@ vi.mock("@/lib/ai/provider", () => ({
vi.mock("@/lib/ai/provider-runner", () => ({
getLastWorkingProvider: vi.fn(),
forgetLastWorkingProvider: vi.fn(),
}));
vi.mock("@/lib/logging/context", () => ({
+5 -1
View File
@@ -10,7 +10,10 @@ import {
} from "@/lib/api-response";
import { annotate } from "@/lib/logging/context";
import { resolveProviderChain } from "@/lib/ai/provider";
import { getLastWorkingProvider } from "@/lib/ai/provider-runner";
import {
forgetLastWorkingProvider,
getLastWorkingProvider,
} from "@/lib/ai/provider-runner";
import { prisma } from "@/lib/db";
import {
parseProviderChain,
@@ -149,6 +152,7 @@ export const PUT = apiHandler(async (request: NextRequest) => {
where: { id: user.id },
data: { aiProviderChain: normalised },
});
forgetLastWorkingProvider(user.id);
annotate({
meta: {
+9
View File
@@ -98,6 +98,15 @@ export function getLastWorkingProvider(
return entry.providerType;
}
/**
* Drop one user's "last working provider" memo. Called when the person saves
* a new chain: the memo reorders the chain they just arranged, and a provider
* they removed or disabled must not keep leading it for up to an hour.
*/
export function forgetLastWorkingProvider(userId: string): void {
lastWorkingCache.delete(userId);
}
function rememberWorkingProvider(
userId: string,
providerType: ProviderChainType,