mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-28 05:16:23 -06:00
fix(usage): don't resolve subscription windows for an absent auth signal
A missing per-turn authMode was mapped to "oauth", so an OpenAI api-key turn that arrived without an explicit auth mechanism could resolve and display ChatGPT subscription windows that aren't its own — served straight from the 60s limits cache, which the "re-checked at fetch time" guard does not cover. Treat a genuinely absent signal as non-eligible (same as api-key): no usage provider resolves and the footer omits limit windows. Present mechanisms are unchanged — oauth/auth-profile/token stay eligible, and only OpenAI is gated on the credential type so other providers are unaffected. A real oauth/profile turn always carries its mechanism; one arriving blank is an upstream tagging bug to fix at the source. Inverts the now-incorrect "absent => oauth-eligible" test into regression coverage for the absent/api-key case. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
committed by
Ayaan Zaidi
parent
56f2102c28
commit
618d78144e
@@ -33,13 +33,13 @@ describe("getProviderUsageLimits credential awareness", () => {
|
||||
expect(loadMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("resolves OpenAI limits when the credential type is absent (oauth-eligible)", async () => {
|
||||
loadMock.mockResolvedValue({
|
||||
updatedAt: 0,
|
||||
providers: [{ provider: "openai", displayName: "OpenAI", windows: [] }],
|
||||
});
|
||||
await getProviderUsageLimits("openai");
|
||||
expect(loadMock).toHaveBeenCalledTimes(1);
|
||||
it("returns undefined for an OpenAI turn with an absent credential type and never fetches", async () => {
|
||||
// A missing authMode is not evidence of an oauth turn, so we must NOT resolve
|
||||
// (and cache-borrow) ChatGPT windows for it — same outcome as an explicit
|
||||
// api-key turn. A real oauth/profile turn carries its mechanism explicitly.
|
||||
const out = await getProviderUsageLimits("openai");
|
||||
expect(out).toBeUndefined();
|
||||
expect(loadMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("resolves OpenAI limits for an oauth turn", async () => {
|
||||
|
||||
@@ -21,10 +21,19 @@ const limitsCache = new Map<string, LimitsCacheEntry>();
|
||||
// Map a per-turn auth signal — which may be the auth *mechanism* (e.g.
|
||||
// "auth-profile"), not a credential *type* — to the usage-credential vocabulary
|
||||
// resolveUsageProviderId expects. api-key/aws-sdk resolve NO usage provider, so an
|
||||
// api-key turn never resolves "openai" and cannot borrow cached oauth windows;
|
||||
// oauth/token/auth-profile and a missing signal are usage-eligible, and the actual
|
||||
// credential is re-checked at fetch time before any usage request is made.
|
||||
// api-key turn never resolves "openai" and cannot borrow cached oauth windows.
|
||||
// A genuinely *absent* signal is treated the same way (non-eligible): a missing
|
||||
// authMode is not evidence of an oauth/subscription turn, and resolving
|
||||
// optimistically would let an untagged OpenAI api-key turn borrow cached
|
||||
// oauth/ChatGPT windows (only OpenAI is gated on oauth/token here; other
|
||||
// providers ignore the credential type, so they are unaffected). A real
|
||||
// oauth/profile turn always carries its mechanism ("oauth"/"auth-profile"/
|
||||
// "token"); one arriving blank is an upstream tagging bug to fix at the source,
|
||||
// not a reason to show another turn's windows.
|
||||
function toUsageCredentialType(raw: string | null | undefined): string {
|
||||
if (raw == null) {
|
||||
return "api-key";
|
||||
}
|
||||
if (raw === "api-key" || raw === "aws-sdk") {
|
||||
return raw;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user