fix(gateway): bind provider usage to refreshed auth store (#125709)

This commit is contained in:
Peter Steinberger
2026-08-18 01:16:19 -07:00
committed by GitHub
parent 5526c939e7
commit 74bf075d16
4 changed files with 16 additions and 3 deletions
@@ -108,8 +108,12 @@ function retainLastGoodOnTimeout(
.filter((provider) => provider.error === undefined)
.map((provider) => [provider.provider, provider]),
);
const retainedLastGood = summary.providers.some(
(provider) => provider.error === "Timeout" && lastGoodByProvider.has(provider.provider),
);
return {
...summary,
updatedAt: retainedLastGood ? lastGood.updatedAt : summary.updatedAt,
providers: summary.providers.map((provider) =>
provider.error === "Timeout"
? (lastGoodByProvider.get(provider.provider) ?? provider)
@@ -1286,7 +1286,7 @@ describe("models.authStatus", () => {
expect(warmed.providers[0]?.usage?.windows[0]?.usedPercent).toBe(10);
});
setPreparedAuthStore({
const rotatedStore: AuthProfileStore = {
version: 1,
profiles: {
"openai:default": {
@@ -1297,10 +1297,16 @@ describe("models.authStatus", () => {
expires: 1_000_000,
},
},
});
};
// Prepared catalog refresh can replace its owner before the ambient snapshot revision advances.
preparedAuthStore = rotatedStore;
const rotated = await readAuthStatus();
expect(mocks.buildAuthHealthSummary.mock.calls.at(-1)?.[0].store).toBe(rotatedStore);
expect(rotated.providers[0]?.usage).toBeUndefined();
expect(mocks.loadProviderUsageSummary).toHaveBeenCalledTimes(2);
expect(mocks.loadProviderUsageSummary).toHaveBeenLastCalledWith(
expect.objectContaining({ authStore: rotatedStore }),
);
});
it("does not reuse usage after a direct provider key rotates", async () => {
@@ -115,6 +115,8 @@ export function getProviderUsageRuntimeSnapshot(params: {
const authStoreGeneration = getRuntimeAuthProfileStoreSnapshotRevision(agentDir);
if (
current?.configRef === configRef &&
// Prepared owners can advance before the ambient snapshot; their exact store fences reuse.
(params.store === undefined || current.store === params.store) &&
current.agentDir === agentDir &&
current.agentId === agentId &&
current.pluginRegistryGeneration === pluginRegistryGeneration &&
@@ -226,10 +226,11 @@ describe("usage.status provider usage cache", () => {
const stale = await runUsageStatus();
expect(JSON.stringify(stale)).toBe(JSON.stringify(first));
await mocks.loadProviderUsageSummary.mock.results[1]?.value;
now = 62_000;
await vi.waitFor(async () => {
const retained = (await runUsageStatus()) as UsageSummary;
expect(retained.providers).toEqual(first.providers);
expect(retained.updatedAt).toBe(61_000);
expect(retained.updatedAt).toBe(first.updatedAt);
expect(mocks.loadProviderUsageSummary).toHaveBeenCalledTimes(2);
});
});