From a0aa52a3f4f6da4a60535ced9f31a2be72d72b7a Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Wed, 28 Oct 2026 09:07:06 -0700 Subject: [PATCH 01/27] feat(usage): add a Usage tab with provider limits and usage history --- packages/types/src/history.ts | 19 + packages/types/src/providers/vscode-llm.ts | 58 ++ packages/types/src/vscode-extension-host.ts | 6 +- .../taskMetadata.usageByModel.spec.ts | 82 ++ .../__tests__/usageByModel.spec.ts | 113 ++ src/core/task-persistence/taskMetadata.ts | 5 + src/core/task-persistence/usageByModel.ts | 51 + src/core/task/Task.ts | 5 + ...bviewMessageHandler.providerQuotas.spec.ts | 215 ++++ src/core/webview/webviewMessageHandler.ts | 45 + .../__tests__/copilotQuota.spec.ts | 204 ++++ .../__tests__/providerQuotas.spec.ts | 970 ++++++++++++++++++ .../__tests__/quotaUtils.spec.ts | 109 ++ src/services/language-models/copilotQuota.ts | 132 +++ .../language-models/providerQuotas.ts | 673 ++++++++++++ src/services/language-models/quotaUtils.ts | 66 ++ webview-ui/playwright/gallery/stories.tsx | 12 + .../components/settings/ProviderLimits.tsx | 186 ++++ .../src/components/settings/SettingsView.tsx | 7 + .../src/components/settings/UsageSettings.tsx | 441 ++++++++ .../__tests__/ProviderLimits.spec.tsx | 255 +++++ .../__tests__/UsageSettings.branches.spec.tsx | 276 +++++ .../__tests__/UsageSettings.midnight.spec.tsx | 103 ++ .../settings/__tests__/UsageSettings.spec.tsx | 263 +++++ .../UsageSettings.visual.fixture.tsx | 143 +++ .../__tests__/UsageSettings.visual.tsx | 59 ++ webview-ui/src/i18n/locales/ca/settings.json | 54 +- webview-ui/src/i18n/locales/de/settings.json | 54 +- webview-ui/src/i18n/locales/en/settings.json | 54 +- webview-ui/src/i18n/locales/es/settings.json | 54 +- webview-ui/src/i18n/locales/fr/settings.json | 54 +- webview-ui/src/i18n/locales/hi/settings.json | 54 +- webview-ui/src/i18n/locales/id/settings.json | 54 +- webview-ui/src/i18n/locales/it/settings.json | 54 +- webview-ui/src/i18n/locales/ja/settings.json | 54 +- webview-ui/src/i18n/locales/ko/settings.json | 54 +- webview-ui/src/i18n/locales/nl/settings.json | 54 +- webview-ui/src/i18n/locales/pl/settings.json | 54 +- .../src/i18n/locales/pt-BR/settings.json | 54 +- webview-ui/src/i18n/locales/ru/settings.json | 54 +- webview-ui/src/i18n/locales/tr/settings.json | 54 +- webview-ui/src/i18n/locales/vi/settings.json | 54 +- .../src/i18n/locales/zh-CN/settings.json | 54 +- .../src/i18n/locales/zh-TW/settings.json | 54 +- .../src/utils/__tests__/providerLabel.spec.ts | 14 + .../src/utils/__tests__/usage.dst.spec.ts | 109 ++ webview-ui/src/utils/__tests__/usage.spec.ts | 484 +++++++++ webview-ui/src/utils/providerLabel.ts | 6 + webview-ui/src/utils/usage.ts | 340 ++++++ 49 files changed, 6404 insertions(+), 19 deletions(-) create mode 100644 src/core/task-persistence/__tests__/taskMetadata.usageByModel.spec.ts create mode 100644 src/core/task-persistence/__tests__/usageByModel.spec.ts create mode 100644 src/core/task-persistence/usageByModel.ts create mode 100644 src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts create mode 100644 src/services/language-models/__tests__/copilotQuota.spec.ts create mode 100644 src/services/language-models/__tests__/providerQuotas.spec.ts create mode 100644 src/services/language-models/__tests__/quotaUtils.spec.ts create mode 100644 src/services/language-models/copilotQuota.ts create mode 100644 src/services/language-models/providerQuotas.ts create mode 100644 src/services/language-models/quotaUtils.ts create mode 100644 webview-ui/src/components/settings/ProviderLimits.tsx create mode 100644 webview-ui/src/components/settings/UsageSettings.tsx create mode 100644 webview-ui/src/components/settings/__tests__/ProviderLimits.spec.tsx create mode 100644 webview-ui/src/components/settings/__tests__/UsageSettings.branches.spec.tsx create mode 100644 webview-ui/src/components/settings/__tests__/UsageSettings.midnight.spec.tsx create mode 100644 webview-ui/src/components/settings/__tests__/UsageSettings.spec.tsx create mode 100644 webview-ui/src/components/settings/__tests__/UsageSettings.visual.fixture.tsx create mode 100644 webview-ui/src/components/settings/__tests__/UsageSettings.visual.tsx create mode 100644 webview-ui/src/utils/__tests__/providerLabel.spec.ts create mode 100644 webview-ui/src/utils/__tests__/usage.dst.spec.ts create mode 100644 webview-ui/src/utils/__tests__/usage.spec.ts create mode 100644 webview-ui/src/utils/providerLabel.ts create mode 100644 webview-ui/src/utils/usage.ts diff --git a/packages/types/src/history.ts b/packages/types/src/history.ts index 131194212e..21cef89e47 100644 --- a/packages/types/src/history.ts +++ b/packages/types/src/history.ts @@ -26,6 +26,23 @@ export const pendingTaskActionSchema = z.discriminatedUnion("kind", [ export type PendingTaskAction = z.infer +/** + * Token/cost totals for one provider+model within a task. A task can span + * several (the user may switch profiles mid-task), so history keeps a list. + */ +export const usageByModelEntrySchema = z.object({ + apiProvider: z.string().optional(), + modelId: z.string().optional(), + requests: z.number(), + tokensIn: z.number(), + tokensOut: z.number(), + cacheReads: z.number().optional(), + cacheWrites: z.number().optional(), + cost: z.number(), +}) + +export type UsageByModelEntry = z.infer + export const historyItemSchema = z.object({ id: z.string(), rootTaskId: z.string().optional(), @@ -39,6 +56,8 @@ export const historyItemSchema = z.object({ cacheWrites: z.number().optional(), cacheReads: z.number().optional(), totalCost: z.number(), + /** Per provider+model breakdown, recorded as requests happen. Absent on tasks created before this was tracked. */ + usageByModel: z.array(usageByModelEntrySchema).optional(), size: z.number().optional(), workspace: z.string().optional(), mode: z.string().optional(), diff --git a/packages/types/src/providers/vscode-llm.ts b/packages/types/src/providers/vscode-llm.ts index b6ba122d53..91e74e54fd 100644 --- a/packages/types/src/providers/vscode-llm.ts +++ b/packages/types/src/providers/vscode-llm.ts @@ -11,8 +11,66 @@ export const vsCodeLmModelsMessageTypes = [ "githubCopilotManageAccount", "githubCopilotSignInResult", "githubCopilotModels", + "requestProviderQuotas", + "cancelProviderQuotas", + "providerQuotas", ] as const +/** + * One limit/balance a provider reports (e.g. Copilot premium credits for the + * month, an OpenRouter key limit, a DeepSeek prepaid balance). + */ +export interface ProviderQuotaWindow { + /** Stable key, e.g. "premium", "key_limit", "balance". */ + id: string + /** Pre-formatted primary figure, e.g. "39,389.3 / 140,000 used", "$12.40 left". */ + valueLabel: string + /** 0–100 when the provider reports a bounded allowance. */ + usedPercent?: number + /** Epoch ms. */ + resetAt?: number +} + +export type ProviderQuota = + | { + providerId: string + ok: true + plan?: string + windows: ProviderQuotaWindow[] + fetchedAt: number + } + | { + providerId: string + ok: false + reason: "signedOut" | "noCopilot" | "noKey" | "unsupported" | "error" + message?: string + fetchedAt: number + } + +/** + * The signed-in account's GitHub Copilot premium-request allowance, as reported by + * `GET /copilot_internal/user` (the same source Copilot Chat's own usage panel reads). + */ +export interface GitHubCopilotQuota { + /** e.g. "business", "individual". */ + plan?: string + unlimited: boolean + /** Total credits for the period; undefined when unlimited or not reported. */ + entitlement?: number + /** Credits used this period, `entitlement - quota_remaining` (one decimal, like GitHub's panel). */ + used?: number + /** 0–100. */ + usedPercent?: number + /** Epoch ms when the allowance resets. */ + resetAt?: number + /** Epoch ms when this snapshot was fetched. */ + fetchedAt: number +} + +export type GitHubCopilotQuotaResult = + | { ok: true; quota: GitHubCopilotQuota } + | { ok: false; reason: "signedOut" | "noCopilot" | "error"; message?: string } + export const vsCodeLmModelsMessageTypeSchema = z.enum(vsCodeLmModelsMessageTypes) export const VsCodeLmModelsMessageType = vsCodeLmModelsMessageTypeSchema.enum diff --git a/packages/types/src/vscode-extension-host.ts b/packages/types/src/vscode-extension-host.ts index dc407325d9..3870bf33d4 100644 --- a/packages/types/src/vscode-extension-host.ts +++ b/packages/types/src/vscode-extension-host.ts @@ -16,7 +16,7 @@ import { RouterModelsMessageType, type ModelInfo, type ModelRecord, type RouterM import { LmStudioModelsMessageType } from "./providers/lm-studio.js" import { OllamaModelsMessageType } from "./providers/ollama.js" import { OpenAiModelsMessageType } from "./providers/openai.js" -import { VsCodeLmModelsMessageType } from "./providers/vscode-llm.js" +import { VsCodeLmModelsMessageType, type ProviderQuota } from "./providers/vscode-llm.js" import type { OpenAiCodexRateLimitInfo } from "./providers/openai-codex-rate-limits.js" import type { SkillMetadata } from "./skills.js" import type { RuleMetadata } from "./rules.js" @@ -50,6 +50,7 @@ export interface ExtensionMessage { | typeof VsCodeLmModelsMessageType.vsCodeLmModels | typeof VsCodeLmModelsMessageType.githubCopilotModels | typeof VsCodeLmModelsMessageType.githubCopilotSignInResult + | typeof VsCodeLmModelsMessageType.providerQuotas | "vsCodeLmApiAvailable" | "updatePrompt" | "systemPrompt" @@ -158,6 +159,7 @@ export interface ExtensionMessage { modelInfo?: ModelInfo }[] githubCopilotAccount?: string | null + providerQuotas?: ProviderQuota[] mcpServers?: McpServer[] commits?: GitCommit[] listApiConfig?: ProviderSettingsEntry[] @@ -516,6 +518,8 @@ export interface WebviewMessage { | typeof VsCodeLmModelsMessageType.githubCopilotSignIn | typeof VsCodeLmModelsMessageType.githubCopilotReconnect | typeof VsCodeLmModelsMessageType.githubCopilotManageAccount + | typeof VsCodeLmModelsMessageType.requestProviderQuotas + | typeof VsCodeLmModelsMessageType.cancelProviderQuotas | "openImage" | "saveImage" | "openFile" diff --git a/src/core/task-persistence/__tests__/taskMetadata.usageByModel.spec.ts b/src/core/task-persistence/__tests__/taskMetadata.usageByModel.spec.ts new file mode 100644 index 0000000000..a16e27259d --- /dev/null +++ b/src/core/task-persistence/__tests__/taskMetadata.usageByModel.spec.ts @@ -0,0 +1,82 @@ +import { describe, expect, it, vi } from "vitest" + +import { providerIdentifiers, type ClineMessage } from "@roo-code/types" + +vi.mock("get-folder-size", () => ({ default: { loose: vi.fn(async () => 1234) } })) +vi.mock("../../../utils/storage", () => ({ getTaskDirectoryPath: vi.fn(async () => "/tmp/task") })) +vi.mock("../../../i18n", () => ({ t: (k: string) => k })) + +import { taskMetadata } from "../taskMetadata" + +const say = (say: ClineMessage["say"], text: string, ts: number): ClineMessage => ({ ts, type: "say", say, text }) + +const base = { + taskId: "t1", + taskNumber: 1, + globalStoragePath: "/tmp", + workspace: "/ws", +} + +describe("taskMetadata – usageByModel", () => { + it("records per provider+model usage on the history item", async () => { + const messages = [ + say("text", "do the thing", 1), + say( + "api_req_started", + JSON.stringify({ + apiProvider: providerIdentifiers.githubCopilot, + modelId: "claude-opus-5.5", + tokensIn: 900, + tokensOut: 90, + cost: 0, + }), + 2, + ), + say( + "api_req_started", + JSON.stringify({ + apiProvider: providerIdentifiers.gemini, + modelId: "gemini-pro", + tokensIn: 100, + tokensOut: 10, + cost: 0.2, + }), + 3, + ), + ] + const { historyItem } = await taskMetadata({ ...base, messages }) + + expect(historyItem.usageByModel).toEqual([ + { + apiProvider: providerIdentifiers.githubCopilot, + modelId: "claude-opus-5.5", + requests: 1, + tokensIn: 900, + tokensOut: 90, + cost: 0, + }, + { + apiProvider: providerIdentifiers.gemini, + modelId: "gemini-pro", + requests: 1, + tokensIn: 100, + tokensOut: 10, + cost: 0.2, + }, + ]) + // Existing totals are unchanged by the new breakdown. + expect(historyItem.tokensIn).toBe(1000) + expect(historyItem.totalCost).toBeCloseTo(0.2) + }) + + it("omits usageByModel entirely when nothing was recorded, keeping old items' shape", async () => { + const { historyItem } = await taskMetadata({ ...base, messages: [say("text", "hello", 1)] }) + expect(historyItem).not.toHaveProperty("usageByModel") + }) + + it("omits usageByModel for a task with no messages", async () => { + const { historyItem } = await taskMetadata({ ...base, messages: [] }) + expect(historyItem).not.toHaveProperty("usageByModel") + expect(historyItem.tokensIn).toBe(0) + }) +}) diff --git a/src/core/task-persistence/__tests__/usageByModel.spec.ts b/src/core/task-persistence/__tests__/usageByModel.spec.ts new file mode 100644 index 0000000000..092272ff6d --- /dev/null +++ b/src/core/task-persistence/__tests__/usageByModel.spec.ts @@ -0,0 +1,113 @@ +import { describe, expect, it } from "vitest" + +import { providerIdentifiers, type ClineMessage } from "@roo-code/types" + +import { summarizeUsageByModel } from "../usageByModel" + +const req = (data: Record, ts = 1): ClineMessage => ({ + ts, + type: "say", + say: "api_req_started", + text: JSON.stringify(data), +}) + +describe("summarizeUsageByModel", () => { + it("groups requests by the provider+model recorded on each request", () => { + const result = summarizeUsageByModel([ + req({ + apiProvider: providerIdentifiers.githubCopilot, + modelId: "claude-opus-5.5", + tokensIn: 1000, + tokensOut: 100, + cost: 0, + }), + req({ + apiProvider: providerIdentifiers.githubCopilot, + modelId: "claude-opus-5.5", + tokensIn: 500, + tokensOut: 50, + cost: 0, + }), + req({ + apiProvider: providerIdentifiers.gemini, + modelId: "gemini-3.1-pro-preview", + tokensIn: 200, + tokensOut: 20, + cost: 0.4, + }), + ]) + + expect(result).toEqual([ + { + apiProvider: providerIdentifiers.githubCopilot, + modelId: "claude-opus-5.5", + requests: 2, + tokensIn: 1500, + tokensOut: 150, + cost: 0, + }, + { + apiProvider: providerIdentifiers.gemini, + modelId: "gemini-3.1-pro-preview", + requests: 1, + tokensIn: 200, + tokensOut: 20, + cost: 0.4, + }, + ]) + }) + + it("keeps a task that switched providers mid-way split by what actually served each request", () => { + const result = summarizeUsageByModel([ + req({ + apiProvider: providerIdentifiers.githubCopilot, + modelId: "claude-opus-5.5", + tokensIn: 100, + tokensOut: 10, + }), + req({ apiProvider: providerIdentifiers.gemini, modelId: "gemini-pro", tokensIn: 300, tokensOut: 30 }), + ]) + expect(result.map((r) => r.apiProvider)).toEqual([ + providerIdentifiers.githubCopilot, + providerIdentifiers.gemini, + ]) + }) + + it("sums cache counters only when reported", () => { + const [entry] = summarizeUsageByModel([ + req({ + apiProvider: providerIdentifiers.anthropic, + modelId: "m", + tokensIn: 1, + tokensOut: 1, + cacheReads: 5, + cacheWrites: 2, + }), + req({ apiProvider: providerIdentifiers.anthropic, modelId: "m", tokensIn: 1, tokensOut: 1, cacheReads: 3 }), + ]) + expect(entry.cacheReads).toBe(8) + expect(entry.cacheWrites).toBe(2) + + const [bare] = summarizeUsageByModel([req({ apiProvider: "a", modelId: "m", tokensIn: 1, tokensOut: 1 })]) + expect(bare).not.toHaveProperty("cacheReads") + }) + + it("puts requests recorded before this was tracked in an unrecorded entry rather than guessing", () => { + const [entry] = summarizeUsageByModel([req({ apiProtocol: "openai", tokensIn: 10, tokensOut: 5, cost: 0 })]) + expect(entry).toMatchObject({ apiProvider: undefined, modelId: undefined, requests: 1, tokensIn: 10 }) + }) + + it("ignores in-flight placeholders and non-request messages", () => { + const result = summarizeUsageByModel([ + req({ apiProtocol: "openai", apiProvider: providerIdentifiers.gemini, modelId: "m" }), // no counts yet + { ts: 2, type: "say", say: "text", text: "hello" }, + { ts: 3, type: "say", say: "api_req_started", text: "not json" }, + { ts: 4, type: "say", say: "api_req_started" }, + ]) + expect(result).toEqual([]) + }) + + it("returns an empty list for no messages", () => { + expect(summarizeUsageByModel([])).toEqual([]) + }) +}) diff --git a/src/core/task-persistence/taskMetadata.ts b/src/core/task-persistence/taskMetadata.ts index c52b0bdc33..827095f67a 100644 --- a/src/core/task-persistence/taskMetadata.ts +++ b/src/core/task-persistence/taskMetadata.ts @@ -5,6 +5,7 @@ import type { ClineMessage, HistoryItem } from "@roo-code/types" import { combineApiRequests } from "../../shared/combineApiRequests" import { combineCommandSequences } from "../../shared/combineCommandSequences" +import { summarizeUsageByModel } from "./usageByModel" import { getApiMetrics } from "../../shared/getApiMetrics" import { findLastIndex } from "../../shared/array" import { getTaskDirectoryPath } from "../../utils/storage" @@ -89,6 +90,8 @@ export async function taskMetadata({ } } + const usageByModel = hasMessages ? summarizeUsageByModel(messages) : [] + // Create historyItem once with pre-calculated values. // initialStatus is included when provided (e.g., "active" for child tasks) // to ensure the status is set from the very first save, avoiding race conditions @@ -107,6 +110,8 @@ export async function taskMetadata({ cacheWrites: tokenUsage.totalCacheWrites, cacheReads: tokenUsage.totalCacheReads, totalCost: tokenUsage.totalCost, + // Only emitted when something was recorded, so older tasks and empty tasks keep their exact shape. + ...(usageByModel.length > 0 ? { usageByModel } : {}), size: taskDirSize, workspace, mode, diff --git a/src/core/task-persistence/usageByModel.ts b/src/core/task-persistence/usageByModel.ts new file mode 100644 index 0000000000..16027c281e --- /dev/null +++ b/src/core/task-persistence/usageByModel.ts @@ -0,0 +1,51 @@ +import type { ClineMessage, UsageByModelEntry } from "@roo-code/types" + +/** + * Totals per provider+model from a task's `api_req_started` messages. + * + * Provider and model are read from the message itself (recorded when the + * request was made), never from the *current* profile, so a task that ran on + * Copilot keeps saying so after the user switches providers. A task can span + * several models, hence a list. + * + * Messages written before this was recorded carry no provider/model; their + * tokens are grouped under an entry with both fields undefined ("not + * recorded") rather than guessed. + */ +export function summarizeUsageByModel(messages: ClineMessage[]): UsageByModelEntry[] { + const byKey = new Map() + + for (const message of messages) { + if (message.type !== "say" || message.say !== "api_req_started" || !message.text) continue + + let parsed: Record + try { + parsed = JSON.parse(message.text) + } catch { + continue + } + + // A placeholder (request not finished) has no token counts yet. + if (typeof parsed.tokensIn !== "number" && typeof parsed.tokensOut !== "number") continue + + const apiProvider = typeof parsed.apiProvider === "string" ? parsed.apiProvider : undefined + const modelId = typeof parsed.modelId === "string" ? parsed.modelId : undefined + const key = `${apiProvider ?? ""}\u0000${modelId ?? ""}` + + let entry = byKey.get(key) + if (!entry) { + entry = { apiProvider, modelId, requests: 0, tokensIn: 0, tokensOut: 0, cost: 0 } + byKey.set(key, entry) + } + + const num = (v: unknown) => (typeof v === "number" && Number.isFinite(v) ? v : 0) + entry.requests += 1 + entry.tokensIn += num(parsed.tokensIn) + entry.tokensOut += num(parsed.tokensOut) + entry.cost += num(parsed.cost) + if (typeof parsed.cacheReads === "number") entry.cacheReads = (entry.cacheReads ?? 0) + parsed.cacheReads + if (typeof parsed.cacheWrites === "number") entry.cacheWrites = (entry.cacheWrites ?? 0) + parsed.cacheWrites + } + + return [...byKey.values()] +} diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index e573a7f107..d5e8cc7b79 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -3936,6 +3936,9 @@ export class Task extends EventEmitter implements TaskLike { "api_req_started", JSON.stringify({ apiProtocol, + // Recorded now so Usage reflects what served this request, not the profile selected later. + apiProvider, + modelId, }), ) @@ -4013,6 +4016,8 @@ export class Task extends EventEmitter implements TaskLike { this.clineMessages[lastApiReqIndex].text = JSON.stringify({ apiProtocol, + apiProvider, + modelId, } satisfies ClineApiReqInfo) await this.saveClineMessages() diff --git a/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts b/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts new file mode 100644 index 0000000000..d83aa92aac --- /dev/null +++ b/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts @@ -0,0 +1,215 @@ +// npx vitest core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts + +import { beforeEach, describe, expect, it, vi } from "vitest" + +import { providerIdentifiers } from "@roo-code/types" + +const quotas = vi.hoisted(() => ({ + getProviderQuotas: vi.fn(), +})) + +// Keep the real `loadProfiles` (it is the code under test alongside the handler) and stub only the network part. +vi.mock("../../../services/language-models/providerQuotas", async (importOriginal) => ({ + ...(await importOriginal()), + getProviderQuotas: quotas.getProviderQuotas, +})) + +import { webviewMessageHandler } from "../webviewMessageHandler" +import type { ClineProvider } from "../ClineProvider" + +const SECRET = "sk-super-secret" + +const makeProvider = (overrides: Record = {}) => + ({ + postMessageToWebview: vi.fn(), + providerSettingsManager: { + listConfig: vi.fn(async () => [{ id: "a" }, { id: "b" }]), + getProfile: vi.fn(async ({ id }: { id: string }) => ({ + apiProvider: providerIdentifiers.openrouter, + openRouterApiKey: SECRET, + id, + })), + }, + ...overrides, + }) as unknown as ClineProvider & { postMessageToWebview: ReturnType } + +describe("webviewMessageHandler – requestProviderQuotas", () => { + beforeEach(() => { + quotas.getProviderQuotas.mockReset() + quotas.getProviderQuotas.mockResolvedValue([ + { + providerId: providerIdentifiers.openrouter, + ok: true, + fetchedAt: 1, + windows: [{ id: "key_limit", valueLabel: "$5.00 / $10.00 used", usedPercent: 50 }], + }, + ]) + }) + + it("loads every saved profile and posts the formatted quotas back", async () => { + const provider = makeProvider() + await webviewMessageHandler(provider, { type: "requestProviderQuotas" }) + + expect(provider.providerSettingsManager.getProfile).toHaveBeenCalledTimes(2) + expect(quotas.getProviderQuotas.mock.calls[0][0]).toHaveLength(2) + expect(provider.postMessageToWebview).toHaveBeenCalledWith({ + type: "providerQuotas", + providerQuotas: expect.arrayContaining([ + expect.objectContaining({ providerId: providerIdentifiers.openrouter }), + ]), + requestId: undefined, + }) + }) + + it("does not force a refresh by default, and forces when the user presses refresh", async () => { + const provider = makeProvider() + await webviewMessageHandler(provider, { type: "requestProviderQuotas" }) + expect(quotas.getProviderQuotas).toHaveBeenLastCalledWith(expect.any(Array), { + force: false, + signal: expect.any(AbortSignal), + }) + + await webviewMessageHandler(provider, { type: "requestProviderQuotas", bool: true }) + expect(quotas.getProviderQuotas).toHaveBeenLastCalledWith(expect.any(Array), { + force: true, + signal: expect.any(AbortSignal), + }) + }) + + it("passes API keys to the host service but never posts them to the webview", async () => { + const provider = makeProvider() + await webviewMessageHandler(provider, { type: "requestProviderQuotas" }) + + // The service needs the key... + expect(JSON.stringify(quotas.getProviderQuotas.mock.calls[0][0])).toContain(SECRET) + // ...but nothing posted to the webview may contain it. + expect(JSON.stringify(provider.postMessageToWebview.mock.calls)).not.toContain(SECRET) + }) + + it("still answers when one profile cannot be loaded", async () => { + const provider = makeProvider() + provider.providerSettingsManager.getProfile = vi.fn(async ({ id }: { id: string }) => { + if (id === "a") throw new Error("corrupt secret storage") + return { apiProvider: providerIdentifiers.openrouter, openRouterApiKey: SECRET } as never + }) as never + + await webviewMessageHandler(provider, { type: "requestProviderQuotas" }) + expect(quotas.getProviderQuotas.mock.calls[0][0]).toHaveLength(1) + expect(provider.postMessageToWebview).toHaveBeenCalled() + }) + + it("still answers, and logs, when the profile list cannot be read", async () => { + const log = vi.fn() + const provider = makeProvider({ log }) + provider.providerSettingsManager.listConfig = vi.fn(async () => { + throw new Error("secret storage unavailable") + }) as never + + await webviewMessageHandler(provider, { type: "requestProviderQuotas" }) + + expect(provider.postMessageToWebview).toHaveBeenCalledWith({ + type: "providerQuotas", + providerQuotas: [], + requestId: undefined, + }) + expect(log).toHaveBeenCalledWith(expect.stringContaining("secret storage unavailable")) + }) + + it("still answers when the quota service throws something that is not an Error", async () => { + const log = vi.fn() + const provider = makeProvider({ log }) + quotas.getProviderQuotas.mockRejectedValue("nope") + + await webviewMessageHandler(provider, { type: "requestProviderQuotas" }) + + expect(provider.postMessageToWebview).toHaveBeenCalledWith({ + type: "providerQuotas", + providerQuotas: [], + requestId: undefined, + }) + expect(log).toHaveBeenCalledWith(expect.stringContaining("Failed to load provider limits")) + }) + + it("answers with an empty list when there are no profiles", async () => { + quotas.getProviderQuotas.mockResolvedValue([]) + const provider = makeProvider() + provider.providerSettingsManager.listConfig = vi.fn(async () => []) as never + + await webviewMessageHandler(provider, { type: "requestProviderQuotas" }) + expect(provider.postMessageToWebview).toHaveBeenCalledWith({ + type: "providerQuotas", + providerQuotas: [], + requestId: undefined, + }) + }) + + describe("request lifecycle", () => { + it("echoes the request id on the answer", async () => { + const provider = makeProvider() + await webviewMessageHandler(provider, { type: "requestProviderQuotas", requestId: "req-1" }) + expect(provider.postMessageToWebview).toHaveBeenCalledWith( + expect.objectContaining({ type: "providerQuotas", requestId: "req-1" }), + ) + }) + + it("passes an abort signal to the quota service", async () => { + const provider = makeProvider() + await webviewMessageHandler(provider, { type: "requestProviderQuotas", requestId: "req-2" }) + expect(quotas.getProviderQuotas).toHaveBeenLastCalledWith(expect.any(Array), { + force: false, + signal: expect.any(AbortSignal), + }) + }) + + it("aborts the work and posts nothing when the request is cancelled while it is running", async () => { + let signal: AbortSignal | undefined + let finish: (value: never[]) => void = () => {} + quotas.getProviderQuotas.mockImplementation((_profiles, options: { signal: AbortSignal }) => { + signal = options.signal + return new Promise((resolve) => (finish = resolve)) + }) + const provider = makeProvider() + + const running = webviewMessageHandler(provider, { type: "requestProviderQuotas", requestId: "req-3" }) + await vi.waitFor(() => expect(signal).toBeDefined()) + await webviewMessageHandler(provider, { type: "cancelProviderQuotas", requestId: "req-3" }) + + expect(signal!.aborted).toBe(true) + finish([]) + await running + expect(provider.postMessageToWebview).not.toHaveBeenCalled() + }) + + it("does not post when the request was cancelled before the profiles finished loading", async () => { + const provider = makeProvider() + let release: (entries: { id: string }[]) => void = () => {} + provider.providerSettingsManager.listConfig = vi.fn( + () => new Promise((resolve) => (release = resolve)), + ) as never + + const running = webviewMessageHandler(provider, { type: "requestProviderQuotas", requestId: "req-4" }) + await vi.waitFor(() => expect(provider.providerSettingsManager.listConfig).toHaveBeenCalled()) + await webviewMessageHandler(provider, { type: "cancelProviderQuotas", requestId: "req-4" }) + release([{ id: "a" }]) + await running + + expect(quotas.getProviderQuotas).not.toHaveBeenCalled() + expect(provider.postMessageToWebview).not.toHaveBeenCalled() + }) + + it("ignores a cancel for an unknown or missing id, and for a request that already finished", async () => { + const provider = makeProvider() + await webviewMessageHandler(provider, { type: "requestProviderQuotas", requestId: "req-5" }) + provider.postMessageToWebview.mockClear() + + await expect( + webviewMessageHandler(provider, { type: "cancelProviderQuotas", requestId: "req-5" }), + ).resolves.not.toThrow() + await expect( + webviewMessageHandler(provider, { type: "cancelProviderQuotas", requestId: "nope" }), + ).resolves.not.toThrow() + await expect(webviewMessageHandler(provider, { type: "cancelProviderQuotas" })).resolves.not.toThrow() + expect(provider.postMessageToWebview).not.toHaveBeenCalled() + }) + }) +}) diff --git a/src/core/webview/webviewMessageHandler.ts b/src/core/webview/webviewMessageHandler.ts index bd7c589958..207403c5da 100644 --- a/src/core/webview/webviewMessageHandler.ts +++ b/src/core/webview/webviewMessageHandler.ts @@ -30,6 +30,7 @@ import { RouterModelsMessageType, VsCodeLmModelsMessageType, isTelemetryOptedIn, + type ProviderQuota, } from "@roo-code/types" import { customToolRegistry } from "@roo-code/core" import { CloudService } from "@roo-code/cloud" @@ -130,6 +131,9 @@ import { const handlerFor = (apiConfiguration: ProviderSettings, provider: RouterName): ApiHandler => buildApiHandler({ ...apiConfiguration, apiProvider: provider }) +/** In-flight `requestProviderQuotas` work by request id, so a cancel message can abort it. */ +const pendingProviderQuotaRequests = new Map() + export const webviewMessageHandler = async ( provider: ClineProvider, message: WebviewMessage, @@ -1570,6 +1574,47 @@ export const webviewMessageHandler = async ( } break } + case VsCodeLmModelsMessageType.cancelProviderQuotas: + // The Usage tab was closed (or the request superseded): stop the profile load and any fetches. + if (message.requestId) pendingProviderQuotaRequests.get(message.requestId)?.abort() + break + case VsCodeLmModelsMessageType.requestProviderQuotas: { + // Always answer (unless cancelled): the webview shows a spinner until a response arrives and + // disables refresh while it waits, so a thrown error here would leave it stuck. The answer + // carries the request's id so the webview can ignore one that has been superseded. + const requestId = message.requestId + const controller = new AbortController() + if (requestId) pendingProviderQuotaRequests.set(requestId, controller) + let providerQuotas: ProviderQuota[] = [] + try { + const { getProviderQuotas, loadProfiles } = + await import("../../services/language-models/providerQuotas") + const profiles = await loadProfiles(provider.providerSettingsManager) + if (!controller.signal.aborted) { + providerQuotas = await getProviderQuotas(profiles, { + force: message.bool === true, + signal: controller.signal, + }) + } + } catch (error) { + if (!controller.signal.aborted) { + provider.log( + `[requestProviderQuotas] ${error instanceof Error ? error.message : "Failed to load provider limits"}`, + ) + } + } finally { + if (requestId) pendingProviderQuotaRequests.delete(requestId) + } + // Nobody is waiting for a cancelled request: skip the post. + if (!controller.signal.aborted) { + await provider.postMessageToWebview({ + type: VsCodeLmModelsMessageType.providerQuotas, + providerQuotas, + requestId, + }) + } + break + } case VsCodeLmModelsMessageType.githubCopilotManageAccount: try { await openGitHubAccountManagement() diff --git a/src/services/language-models/__tests__/copilotQuota.spec.ts b/src/services/language-models/__tests__/copilotQuota.spec.ts new file mode 100644 index 0000000000..65996ad300 --- /dev/null +++ b/src/services/language-models/__tests__/copilotQuota.spec.ts @@ -0,0 +1,204 @@ +import { beforeEach, describe, expect, it, vi } from "vitest" + +vi.mock("vscode", () => ({ version: "1.0.0", authentication: { getSession: vi.fn() } })) + +import { parseCopilotQuota } from "../copilotQuota" + +const NOW = 1_800_000_000_000 + +// Shape recorded from GET api.github.com/copilot_internal/user (business plan). +const businessPayload = { + copilot_plan: "business", + quota_reset_date: "2026-11-01", + quota_reset_date_utc: "2026-11-01T00:00:00.000Z", + quota_snapshots: { + chat: { unlimited: true, entitlement: 0, remaining: 0 }, + completions: { unlimited: true, entitlement: 0, remaining: 0 }, + premium_interactions: { + entitlement: 140000, + remaining: 100610, + quota_remaining: 100610.7, + unlimited: false, + percent_remaining: 71.8, + }, + }, +} + +describe("parseCopilotQuota", () => { + it("derives used credits from the precise quota_remaining, like GitHub's panel", () => { + const q = parseCopilotQuota(businessPayload, NOW)! + expect(q.plan).toBe("business") + expect(q.unlimited).toBe(false) + expect(q.entitlement).toBe(140000) + expect(q.used).toBe(39389.3) + expect(q.usedPercent).toBeCloseTo(28.135, 2) + expect(q.resetAt).toBe(Date.parse("2026-11-01T00:00:00.000Z")) + expect(q.fetchedAt).toBe(NOW) + }) + + it("falls back to the integer remaining twin", () => { + const payload = structuredClone(businessPayload) + delete (payload.quota_snapshots.premium_interactions as Record).quota_remaining + expect(parseCopilotQuota(payload, NOW)!.used).toBe(39390) + }) + + it("falls back to percent_remaining when counts are missing", () => { + const q = parseCopilotQuota( + { quota_snapshots: { premium_interactions: { unlimited: false, percent_remaining: 40 } } }, + NOW, + )! + expect(q.used).toBeUndefined() + expect(q.entitlement).toBeUndefined() + expect(q.usedPercent).toBe(60) + }) + + it("leaves usage unset when neither counts nor percent_remaining are reported", () => { + const q = parseCopilotQuota({ quota_snapshots: { premium_interactions: { unlimited: false } } }, NOW)! + expect(q.used).toBeUndefined() + expect(q.usedPercent).toBeUndefined() + }) + + it("reports unlimited plans without numbers", () => { + const q = parseCopilotQuota( + { copilot_plan: "enterprise", quota_snapshots: { premium_interactions: { unlimited: true } } }, + NOW, + )! + expect(q).toMatchObject({ plan: "enterprise", unlimited: true }) + expect(q.usedPercent).toBeUndefined() + }) + + it("clamps over-consumption to 100%", () => { + const q = parseCopilotQuota( + { quota_snapshots: { premium_interactions: { entitlement: 300, quota_remaining: -12 } } }, + NOW, + )! + expect(q.used).toBe(300) + expect(q.usedPercent).toBe(100) + }) + + it("uses the date-only reset field when the UTC variant is absent", () => { + const payload = { ...businessPayload, quota_reset_date_utc: undefined } + expect(parseCopilotQuota(payload, NOW)!.resetAt).toBe(Date.parse("2026-11-01")) + }) + + it.each([null, undefined, "nope", [], {}, { quota_snapshots: {} }])("returns undefined for %j", (payload) => { + expect(parseCopilotQuota(payload, NOW)).toBeUndefined() + }) +}) + +// --- getGitHubCopilotQuota (network + auth paths) ---------------------------------------------- + +import * as vscodeApi from "vscode" +import { getGitHubCopilotQuota, resetGitHubCopilotQuotaCache } from "../copilotQuota" + +const getSession = vscodeApi.authentication.getSession as unknown as ReturnType + +const json = (body: unknown, status = 200) => new Response(JSON.stringify(body), { status }) + +describe("getGitHubCopilotQuota", () => { + beforeEach(() => { + resetGitHubCopilotQuotaCache() + getSession.mockReset() + getSession.mockResolvedValue({ accessToken: "gho_token" }) + }) + + it("returns the parsed quota using the existing VS Code GitHub session, silently", async () => { + const fetchSpy = vi.fn(async () => json(businessPayload)) + const result = await getGitHubCopilotQuota({}, fetchSpy as never) + + expect(result).toMatchObject({ ok: true, quota: { plan: "business", entitlement: 140000 } }) + // Silent: must never raise a sign-in prompt from a background usage refresh. + expect(getSession).toHaveBeenCalledWith("github", expect.any(Array), { silent: true }) + expect(fetchSpy).toHaveBeenCalledWith( + "https://api.github.com/copilot_internal/user", + expect.objectContaining({ + headers: expect.objectContaining({ Authorization: "token gho_token" }), + }), + ) + }) + + it("falls back to the second scope set when the first has no session", async () => { + getSession.mockResolvedValueOnce(undefined).mockResolvedValueOnce({ accessToken: "second" }) + const fetchSpy = vi.fn(async () => json(businessPayload)) + await getGitHubCopilotQuota({}, fetchSpy as never) + expect(getSession).toHaveBeenCalledTimes(2) + expect(fetchSpy).toHaveBeenCalledWith( + expect.any(String), + expect.objectContaining({ headers: expect.objectContaining({ Authorization: "token second" }) }), + ) + }) + + it("reports signedOut without calling GitHub when there is no session", async () => { + getSession.mockResolvedValue(undefined) + const fetchSpy = vi.fn() + expect(await getGitHubCopilotQuota({}, fetchSpy as never)).toEqual({ ok: false, reason: "signedOut" }) + expect(fetchSpy).not.toHaveBeenCalled() + }) + + it.each([ + [401, "signedOut"], + [403, "noCopilot"], + [404, "noCopilot"], + ] as const)("maps HTTP %s to %s", async (status, reason) => { + const result = await getGitHubCopilotQuota({}, (async () => json({}, status)) as never) + expect(result).toMatchObject({ ok: false, reason }) + }) + + it("reports other HTTP failures as an error with the status", async () => { + const result = await getGitHubCopilotQuota({}, (async () => json({}, 500)) as never) + expect(result).toEqual({ ok: false, reason: "error", message: "GitHub API error 500" }) + }) + + it("reports noCopilot when the payload has no premium snapshot", async () => { + const result = await getGitHubCopilotQuota({}, (async () => json({ quota_snapshots: {} })) as never) + expect(result).toMatchObject({ ok: false, reason: "noCopilot" }) + }) + + it("turns network errors into a generic error result instead of throwing", async () => { + const result = await getGitHubCopilotQuota({}, (async () => { + throw new Error("offline") + }) as never) + // Arbitrary error text is never forwarded: it can embed URLs, headers or tokens. + expect(result).toEqual({ ok: false, reason: "error", message: "Request failed" }) + }) + + it("never leaks the access token through an error message", async () => { + const result = await getGitHubCopilotQuota({}, (async () => { + throw new Error("request to https://api.github.com failed: Authorization: token gho_token") + }) as never) + expect(JSON.stringify(result)).not.toContain("gho_token") + }) + + it("reports a timeout plainly", async () => { + const result = await getGitHubCopilotQuota({}, (async () => { + throw Object.assign(new Error("The operation timed out"), { name: "TimeoutError" }) + }) as never) + expect(result).toEqual({ ok: false, reason: "error", message: "Request timed out" }) + }) + + it("caches successful results and bypasses the cache when forced", async () => { + const fetchSpy = vi.fn(async () => json(businessPayload)) + await getGitHubCopilotQuota({}, fetchSpy as never) + await getGitHubCopilotQuota({}, fetchSpy as never) + expect(fetchSpy).toHaveBeenCalledTimes(1) + await getGitHubCopilotQuota({ force: true }, fetchSpy as never) + expect(fetchSpy).toHaveBeenCalledTimes(2) + }) + + it("does not cache failures", async () => { + const fail = vi.fn(async () => json({}, 500)) + await getGitHubCopilotQuota({}, fail as never) + await getGitHubCopilotQuota({}, fail as never) + expect(fail).toHaveBeenCalledTimes(2) + }) + + it("shares one in-flight request between concurrent callers", async () => { + const fetchSpy = vi.fn(async () => json(businessPayload)) + const [a, b] = await Promise.all([ + getGitHubCopilotQuota({}, fetchSpy as never), + getGitHubCopilotQuota({}, fetchSpy as never), + ]) + expect(fetchSpy).toHaveBeenCalledTimes(1) + expect(a).toEqual(b) + }) +}) diff --git a/src/services/language-models/__tests__/providerQuotas.spec.ts b/src/services/language-models/__tests__/providerQuotas.spec.ts new file mode 100644 index 0000000000..b27a7830aa --- /dev/null +++ b/src/services/language-models/__tests__/providerQuotas.spec.ts @@ -0,0 +1,970 @@ +import { beforeEach, describe, expect, it, vi } from "vitest" + +import { providerIdentifiers } from "@roo-code/types" + +vi.mock("vscode", () => ({ version: "1.0.0", authentication: { getSession: vi.fn() } })) +vi.mock("../copilotQuota", () => ({ + getGitHubCopilotQuota: vi.fn(async () => ({ + ok: true, + quota: { + plan: "business", + unlimited: false, + entitlement: 140000, + used: 39389.3, + usedPercent: 28.1, + resetAt: 1, + fetchedAt: 2, + }, + })), +})) + +import { + getProviderQuotas, + loadProfiles, + parseDeepSeekBalance, + parseKimiCodeUsage, + parseMiniMaxRemains, + parseMoonshotBalance, + parseNanoGptUsage, + parseOpenCodeGoUsage, + parseOpenRouterKey, + parseZaiQuota, + resetProviderQuotaCache, + windowLabel, +} from "../providerQuotas" + +describe("parseOpenRouterKey", () => { + it("reports a bounded key limit as used / limit with a percent", () => { + expect(parseOpenRouterKey({ data: { limit: 50, limit_remaining: 37.6 } })).toEqual([ + { id: "key_limit", valueLabel: "$12.40 / $50.00 used", usedPercent: expect.closeTo(24.8, 5) }, + ]) + }) + + it("falls back to monthly spend for unlimited keys", () => { + expect(parseOpenRouterKey({ data: { limit: null, usage_monthly: 3.2 } })).toEqual([ + { id: "spend", valueLabel: "$3.20 spent this month" }, + ]) + }) + + it("returns undefined without data", () => { + expect(parseOpenRouterKey({})).toBeUndefined() + expect(parseOpenRouterKey({ data: {} })).toBeUndefined() + }) +}) + +describe("parseDeepSeekBalance", () => { + it("prefers a positive USD balance", () => { + expect( + parseDeepSeekBalance({ + balance_infos: [ + { currency: "CNY", total_balance: "10.00" }, + { currency: "USD", total_balance: "4.25" }, + ], + }), + ).toEqual([{ id: "balance", valueLabel: "$4.25 left" }]) + }) + + it("uses ¥ for a CNY-only balance", () => { + expect(parseDeepSeekBalance({ balance_infos: [{ currency: "CNY", total_balance: "8" }] })).toEqual([ + { id: "balance", valueLabel: "¥8.00 left" }, + ]) + }) + + it("returns undefined for empty or malformed payloads", () => { + expect(parseDeepSeekBalance({ balance_infos: [] })).toBeUndefined() + expect(parseDeepSeekBalance(null)).toBeUndefined() + }) +}) + +describe("parseDeepSeekBalance – fallbacks", () => { + it("falls back to a zero USD balance, then to the first row", () => { + expect( + parseDeepSeekBalance({ + balance_infos: [ + { currency: "EUR", total_balance: "0" }, + { currency: "USD", total_balance: "0" }, + ], + }), + ).toEqual([{ id: "balance", valueLabel: "$0.00 left" }]) + expect(parseDeepSeekBalance({ balance_infos: [{ currency: "EUR", total_balance: "3" }] })).toEqual([ + { id: "balance", valueLabel: "$3.00 left" }, + ]) + }) +}) + +describe("parseMoonshotBalance", () => { + it("reads available_balance", () => { + expect(parseMoonshotBalance({ data: { available_balance: 19.5 } })).toEqual([ + { id: "balance", valueLabel: "$19.50 left" }, + ]) + }) +}) + +describe("windowLabel", () => { + it("names rolling windows by length", () => { + expect(windowLabel(5 * 3600, "x")).toBe("5-hour") + expect(windowLabel(7 * 86400, "x")).toBe("Weekly") + expect(windowLabel(3 * 86400, "x")).toBe("3-day") + expect(windowLabel(undefined, "Tokens")).toBe("Tokens") + expect(windowLabel(90, "Tokens")).toBe("Tokens") + }) +}) + +describe("parseKimiCodeUsage", () => { + it("reads the ratio-based usages block in display order", () => { + expect( + parseKimiCodeUsage({ + usages: { + limit_month_total: { used_ratio: 0.1 }, + limit_5h: { used_ratio: 0.25, reset_time: 1_800_000_000 }, + limit_7d: { used_ratio: 0.5 }, + }, + }), + ).toEqual([ + { id: "limit_5h", valueLabel: "5-hour", usedPercent: 25, resetAt: 1_800_000_000_000 }, + { id: "limit_7d", valueLabel: "Weekly", usedPercent: 50, resetAt: undefined }, + { id: "limit_month_total", valueLabel: "Monthly", usedPercent: expect.closeTo(10, 5), resetAt: undefined }, + ]) + }) + + it("skips entries without a finite ratio", () => { + expect(parseKimiCodeUsage({ usages: { limit_5h: {}, limit_7d: { used_ratio: "x" } } })).toBeUndefined() + }) + + it("falls back to the legacy weekly usage block, deriving used from remaining", () => { + expect(parseKimiCodeUsage({ usage: { limit: 200, remaining: 150 } })).toEqual([ + { id: "weekly", valueLabel: "Weekly", usedPercent: 25, resetAt: undefined }, + ]) + }) + + it("returns undefined for junk", () => { + expect(parseKimiCodeUsage(null)).toBeUndefined() + expect(parseKimiCodeUsage({})).toBeUndefined() + }) +}) + +describe("parseZaiQuota", () => { + it("maps 5-hour and weekly limits, including credit counts", () => { + expect( + parseZaiQuota({ + code: 200, + data: { + limits: [ + { type: "TOKENS_LIMIT", unit: 3, number: 5, percentage: 40, nextResetTime: 1_800_000_000_000 }, + { type: "CREDIT_LIMIT", unit: 6, number: 1, usage: 2000, currentValue: 500 }, + { type: "TIME_LIMIT", percentage: 99 }, + ], + }, + }), + ).toEqual([ + { id: "limit_0", valueLabel: "5-hour", usedPercent: 40, resetAt: 1_800_000_000_000 }, + { id: "limit_1", valueLabel: "Weekly: 500 / 2,000 credits", usedPercent: 25, resetAt: undefined }, + ]) + }) + + it("treats a business failure inside HTTP 200 as no data", () => { + expect(parseZaiQuota({ success: false, code: 1001, msg: "expired", data: { limits: [] } })).toBeUndefined() + expect(parseZaiQuota({ code: 1001, data: { limits: [{ type: "TOKENS_LIMIT" }] } })).toBeUndefined() + }) +}) + +describe("parseMiniMaxRemains", () => { + const row = { + model_name: "MiniMax-M2", + current_interval_total_count: 100, + current_interval_remaining_percent: 80, + end_time: 1_800_000_000_000, + current_weekly_total_count: 1000, + current_weekly_usage_count: 900, + weekly_end_time: 1_900_000_000_000, + } + + it("reports the 5-hour window and a weekly window when the plan has one", () => { + expect(parseMiniMaxRemains({ model_remains: [{ model_name: "other" }, row] })).toEqual([ + { id: "5h", valueLabel: "5-hour", usedPercent: 20, resetAt: 1_800_000_000_000 }, + { id: "weekly", valueLabel: "Weekly", usedPercent: 10, resetAt: 1_900_000_000_000 }, + ]) + }) + + it("reads counters as used (not left) for the legacy coding plan", () => { + const windows = parseMiniMaxRemains( + { + model_remains: [ + { + model_name: "MiniMax-M2", + current_interval_total_count: 100, + current_interval_usage_count: 30, + current_weekly_total_count: 1000, + current_weekly_usage_count: 900, + }, + ], + }, + false, + )! + expect(windows[0].usedPercent).toBe(30) + expect(windows[1].usedPercent).toBe(90) + }) + + it("omits the weekly window when the plan tier does not apply it (status 3)", () => { + const result = parseMiniMaxRemains({ model_remains: [{ ...row, current_weekly_status: 3 }] }) + expect(result?.map((w) => w.id)).toEqual(["5h"]) + }) + + it("rejects an error envelope or an empty list", () => { + expect(parseMiniMaxRemains({ base_resp: { status_code: 1004 }, model_remains: [row] })).toBeUndefined() + expect(parseMiniMaxRemains({ model_remains: [] })).toBeUndefined() + }) +}) + +describe("parseNanoGptUsage", () => { + it("derives percent from percentUsed or used/limit and keeps state in the label", () => { + expect( + parseNanoGptUsage({ + state: "grace", + limits: { dailyInputTokens: 1000 }, + dailyInputTokens: { used: 250 }, + monthly: { percentUsed: 0.4, resetAt: 1_800_000_000 }, + }), + ).toEqual([ + { id: "daily", valueLabel: "Daily (grace)", usedPercent: 25, resetAt: undefined }, + { id: "monthly", valueLabel: "Monthly (grace)", usedPercent: 40, resetAt: 1_800_000_000_000 }, + ]) + }) + + it("shows no percent for a degraded window", () => { + const daily = parseNanoGptUsage({ dailyInputTokens: { percentUsed: 0.9, degraded: true } })![0] + expect(daily.usedPercent).toBeUndefined() + }) +}) + +describe("parseOpenCodeGoUsage", () => { + it("maps rolling, weekly and monthly windows that carry a percent and a reset", () => { + expect( + parseOpenCodeGoUsage({ + usage: { + rolling: { percent: 12, resetsAt: 1_800_000_000 }, + weekly: { percent: 140, resetsAt: 1_800_000_001 }, + monthly: { percent: 5 }, + }, + }), + ).toEqual([ + { id: "5h", valueLabel: "5-hour", usedPercent: 12, resetAt: 1_800_000_000_000 }, + { id: "weekly", valueLabel: "Weekly", usedPercent: 100, resetAt: 1_800_000_001_000 }, + ]) + }) +}) + +describe("balance parser edge cases", () => { + it("DeepSeek: rejects non-object and empty payloads, and a row without a balance", () => { + expect(parseDeepSeekBalance(null)).toBeUndefined() + expect(parseDeepSeekBalance({ balance_infos: [] })).toBeUndefined() + expect(parseDeepSeekBalance({ balance_infos: [{ currency: "USD" }] })).toBeUndefined() + expect(parseDeepSeekBalance({ balance_infos: ["x", null] })).toBeUndefined() + }) + + it("DeepSeek: prefers a positive CNY balance over a zero USD one, then any USD row, then the first row", () => { + expect( + parseDeepSeekBalance({ + balance_infos: [ + { currency: "USD", total_balance: "0" }, + { currency: "CNY", total_balance: "12" }, + ], + }), + ).toEqual([{ id: "balance", valueLabel: "¥12.00 left" }]) + expect( + parseDeepSeekBalance({ + balance_infos: [ + { currency: "EUR", total_balance: "0" }, + { currency: "USD", total_balance: "0" }, + ], + }), + ).toEqual([{ id: "balance", valueLabel: "$0.00 left" }]) + expect(parseDeepSeekBalance({ balance_infos: [{ currency: "EUR", total_balance: "3" }] })).toEqual([ + { id: "balance", valueLabel: "$3.00 left" }, + ]) + }) + + it("Moonshot: returns undefined without an available_balance", () => { + expect(parseMoonshotBalance({ data: {} })).toBeUndefined() + expect(parseMoonshotBalance(null)).toBeUndefined() + }) +}) + +describe("parser edge cases", () => { + it("Kimi Code: skips a legacy usage block with no limit, and derives used from `used`", () => { + expect(parseKimiCodeUsage({ usage: { used: 5 } })).toBeUndefined() + expect(parseKimiCodeUsage({ usage: { limit: 100, used: 40, resetTime: 1_800_000_000 } })).toEqual([ + { id: "weekly", valueLabel: "Weekly", usedPercent: 40, resetAt: 1_800_000_000_000 }, + ]) + expect(parseKimiCodeUsage({ usage: { limit: 100 } })).toBeUndefined() + }) + + it("z.ai: ignores non-object, wrong-type and unit-less limits; falls back to counts for percent", () => { + expect(parseZaiQuota("nope")).toBeUndefined() + expect(parseZaiQuota({ data: {} })).toBeUndefined() + expect(parseZaiQuota({ data: { limits: [null, { type: "TIME_LIMIT" }] } })).toBeUndefined() + expect( + parseZaiQuota({ + data: { limits: [{ type: "TOKENS_LIMIT", unit: 9, number: 5, usage: 200, currentValue: 50 }] }, + }), + ).toEqual([{ id: "limit_0", valueLabel: "Tokens", usedPercent: 25, resetAt: undefined }]) + expect(parseZaiQuota({ data: { limits: [{ type: "CREDIT_LIMIT", usage: 0, currentValue: 0 }] } })).toEqual([ + { id: "limit_0", valueLabel: "Credits: 0 / 0 credits", usedPercent: undefined, resetAt: undefined }, + ]) + }) + + it("MiniMax: picks a chat-named or percent-bearing model when no minimax-m model exists", () => { + expect(parseMiniMaxRemains(null)).toBeUndefined() + expect(parseMiniMaxRemains({ model_remains: ["x", null] })).toBeUndefined() + + const byName = parseMiniMaxRemains({ + model_remains: [ + { model_name: "other", current_interval_remaining_percent: 10 }, + { model_name: "Chat", current_interval_remaining_percent: 60 }, + ], + }) + expect(byName?.[0].usedPercent).toBe(40) + + const byPercent = parseMiniMaxRemains({ + model_remains: [{ model_name: "a" }, { model_name: "b", current_interval_remaining_percent: 75 }], + }) + expect(byPercent?.[0].usedPercent).toBe(25) + + const first = parseMiniMaxRemains({ model_remains: [{ model_name: "only" }] }) + expect(first).toEqual([{ id: "5h", valueLabel: "5-hour", usedPercent: undefined, resetAt: undefined }]) + expect( + parseMiniMaxRemains({ model_remains: [{ current_interval_remaining_percent: 5 }] })?.[0].usedPercent, + ).toBe(95) + }) + + it("MiniMax: skips a weekly window with no data and clamps an out-of-range percent", () => { + const [interval, weekly] = parseMiniMaxRemains({ + model_remains: [{ model_name: "MiniMax-M2", current_interval_remaining_percent: 150 }], + })! + expect(interval.usedPercent).toBe(0) + expect(weekly).toBeUndefined() + }) + + it("NanoGPT: handles non-object input, legacy `daily`, nested limits and unusable windows", () => { + expect(parseNanoGptUsage(null)).toBeUndefined() + expect(parseNanoGptUsage({})).toBeUndefined() + expect( + parseNanoGptUsage({ + daily: { used: 30, limit: 120, resetAt: "2026-05-01T00:00:00Z" }, + monthly: { used: 10, limits: { monthly: 100 } }, + period: { currentPeriodEnd: 1_800_000_000 }, + }), + ).toEqual([ + { id: "daily", valueLabel: "Daily", usedPercent: 25, resetAt: Date.parse("2026-05-01T00:00:00Z") }, + { id: "monthly", valueLabel: "Monthly", usedPercent: 10, resetAt: 1_800_000_000_000 }, + ]) + expect(parseNanoGptUsage({ daily: { used: 30, limits: { daily: 60 } } })?.[0].usedPercent).toBe(50) + expect(parseNanoGptUsage({ monthly: { used: 5, limit: 0 } })?.[0].usedPercent).toBeUndefined() + expect(parseNanoGptUsage({ monthly: {} })?.[0].usedPercent).toBeUndefined() + }) + + it("OpenCode Go: returns undefined without a usage block or with no usable window", () => { + expect(parseOpenCodeGoUsage(null)).toBeUndefined() + expect(parseOpenCodeGoUsage({})).toBeUndefined() + expect(parseOpenCodeGoUsage({ usage: { rolling: { percent: 10 } } })).toBeUndefined() + }) +}) + +describe("getProviderQuotas – Copilot window and misc", () => { + beforeEach(() => resetProviderQuotaCache()) + + it("shows a percent-only Copilot window, and 'Unlimited' for unlimited plans", async () => { + const { getGitHubCopilotQuota } = await import("../copilotQuota") + const mocked = vi.mocked(getGitHubCopilotQuota) + + mocked.mockResolvedValueOnce({ ok: true, quota: { unlimited: false, usedPercent: 41.6, fetchedAt: 1 } }) + const [pct] = await getProviderQuotas([{ apiProvider: providerIdentifiers.githubCopilot } as never]) + expect(pct).toMatchObject({ ok: true, windows: [{ valueLabel: "42% used", usedPercent: 41.6 }] }) + + resetProviderQuotaCache() + mocked.mockResolvedValueOnce({ ok: true, quota: { unlimited: false, fetchedAt: 1 } }) + const [none] = await getProviderQuotas([{ apiProvider: providerIdentifiers.githubCopilot } as never]) + // Unknown usage is reported as unknown (no bar), never as a measured 0%. + expect(none).toMatchObject({ ok: true, windows: [{ valueLabel: "Usage not reported" }] }) + expect((none as { windows: Array<{ usedPercent?: number }> }).windows[0].usedPercent).toBeUndefined() + + resetProviderQuotaCache() + mocked.mockResolvedValueOnce({ ok: true, quota: { unlimited: true, resetAt: 7, fetchedAt: 1 } }) + const [unl] = await getProviderQuotas([{ apiProvider: providerIdentifiers.githubCopilot } as never]) + expect(unl).toMatchObject({ ok: true, windows: [{ valueLabel: "Unlimited", resetAt: 7 }] }) + }) + + it("passes Copilot failures through with their reason and message", async () => { + const { getGitHubCopilotQuota } = await import("../copilotQuota") + vi.mocked(getGitHubCopilotQuota).mockResolvedValueOnce({ ok: false, reason: "error", message: "boom" }) + const [q] = await getProviderQuotas([{ apiProvider: providerIdentifiers.githubCopilot } as never]) + expect(q).toMatchObject({ ok: false, reason: "error", message: "boom" }) + }) + + it("uses the default z.ai line when the profile sets none", async () => { + const fetchSpy = vi.fn(async (_url: RequestInfo | URL, _init?: RequestInit) => new Response("{}")) + await getProviderQuotas([{ apiProvider: providerIdentifiers.zai, zaiApiKey: "k" } as never], {}, fetchSpy) + expect(fetchSpy.mock.calls[0][0]).toBe("https://api.z.ai/api/monitor/usage/quota/limit") + }) + + it("reports an error when a keyed provider answers with no usable data, and surfaces the last failure", async () => { + const [empty] = await getProviderQuotas( + [{ apiProvider: providerIdentifiers.nanogpt, nanoGptApiKey: "k" } as never], + {}, + vi.fn(async () => new Response("{}")), + ) + expect(empty).toMatchObject({ ok: false, reason: "error", message: "No usage data" }) + + resetProviderQuotaCache() + const [failed] = await getProviderQuotas( + [{ apiProvider: providerIdentifiers.minimax, minimaxApiKey: "k" } as never], + {}, + vi.fn(async () => new Response("", { status: 500 })), + ) + expect(failed).toMatchObject({ ok: false, reason: "error", message: "HTTP 500" }) + }) + + it("treats an auth failure on the first MiniMax URL as a missing/invalid key without trying the fallback", async () => { + const fetchSpy = vi.fn( + async (_url: RequestInfo | URL, _init?: RequestInit) => new Response("", { status: 401 }), + ) + const [q] = await getProviderQuotas( + [{ apiProvider: providerIdentifiers.minimax, minimaxApiKey: "k" } as never], + {}, + fetchSpy, + ) + expect(q).toMatchObject({ ok: false, reason: "noKey" }) + expect(fetchSpy).toHaveBeenCalledTimes(1) + }) +}) + +describe("getProviderQuotas – coding-plan providers", () => { + beforeEach(() => resetProviderQuotaCache()) + + it("queries z.ai on the host matching the profile's API line", async () => { + const fetchSpy = vi.fn(async () => new Response(JSON.stringify({ code: 200, data: { limits: [] } }))) + await getProviderQuotas( + [{ apiProvider: providerIdentifiers.zai, zaiApiKey: "k", zaiApiLine: "china_coding" } as never], + {}, + fetchSpy, + ) + expect(fetchSpy).toHaveBeenCalledWith( + "https://open.bigmodel.cn/api/monitor/usage/quota/limit", + expect.anything(), + ) + }) + + it("falls back to the coding-plan endpoint for MiniMax and reads its counters as used", async () => { + const body = { + model_remains: [ + { + model_name: "MiniMax-M2", + current_interval_total_count: 100, + current_interval_usage_count: 30, + }, + ], + } + const fetchSpy = vi + .fn() + .mockResolvedValueOnce(new Response("", { status: 404 })) + .mockResolvedValueOnce(new Response(JSON.stringify(body))) + const [q] = await getProviderQuotas( + [{ apiProvider: providerIdentifiers.minimax, minimaxApiKey: "k" } as never], + {}, + fetchSpy, + ) + expect(fetchSpy.mock.calls.map((c) => c[0])).toEqual([ + "https://api.minimax.io/v1/token_plan/remains", + "https://api.minimax.io/v1/api/openplatform/coding_plan/remains", + ]) + expect(q).toMatchObject({ ok: true, windows: [{ id: "5h", usedPercent: 30 }] }) + }) + + it("uses the China MiniMax hosts for a minimaxi.com base URL", async () => { + const fetchSpy = vi.fn( + async (_url: RequestInfo | URL, _init?: RequestInit) => new Response("", { status: 404 }), + ) + await getProviderQuotas( + [ + { + apiProvider: providerIdentifiers.minimax, + minimaxApiKey: "k", + minimaxBaseUrl: "https://api.minimaxi.com/anthropic", + } as never, + ], + {}, + fetchSpy, + ) + expect(fetchSpy.mock.calls.map((c) => c[0])).toEqual([ + "https://api.minimaxi.com/v1/token_plan/remains", + "https://www.minimaxi.com/v1/api/openplatform/coding_plan/remains", + ]) + }) + + it("never sends a MiniMax key to an unknown base URL", async () => { + const fetchSpy = vi.fn() + const [q] = await getProviderQuotas( + [ + { + apiProvider: providerIdentifiers.minimax, + minimaxApiKey: "k", + minimaxBaseUrl: "https://gateway.example/anthropic", + } as never, + ], + {}, + fetchSpy, + ) + expect(q).toMatchObject({ ok: false, reason: "unsupported" }) + expect(fetchSpy).not.toHaveBeenCalled() + }) + + it("reports noKey for a Kimi Code profile signed in with OAuth (no API key)", async () => { + const fetchSpy = vi.fn() + const [q] = await getProviderQuotas([{ apiProvider: providerIdentifiers.kimiCode } as never], {}, fetchSpy) + expect(q).toMatchObject({ ok: false, reason: "noKey" }) + expect(fetchSpy).not.toHaveBeenCalled() + }) + + it("calls NanoGPT, Kimi Code and OpenCode Go on their own hosts only", async () => { + const fetchSpy = vi.fn(async (_url: RequestInfo | URL, _init?: RequestInit) => new Response(JSON.stringify({}))) + await getProviderQuotas( + [ + { apiProvider: providerIdentifiers.nanogpt, nanoGptApiKey: "k" } as never, + { apiProvider: providerIdentifiers.kimiCode, kimiCodeApiKey: "k" } as never, + { apiProvider: providerIdentifiers.opencodeGo, opencodeGoApiKey: "k" } as never, + ], + {}, + fetchSpy, + ) + expect(fetchSpy.mock.calls.map((c) => c[0]).sort()).toEqual([ + "https://api.kimi.com/coding/v1/usages", + "https://nano-gpt.com/api/subscription/v1/usage", + "https://opencode.ai/zen/go/v1/usage", + ]) + }) +}) + +describe("getProviderQuotas", () => { + beforeEach(() => resetProviderQuotaCache()) + + const okFetch = vi.fn(async () => new Response(JSON.stringify({ data: { limit: 10, limit_remaining: 5 } }))) + + it("only queries providers that are connected", async () => { + const result = await getProviderQuotas([{ apiProvider: providerIdentifiers.anthropic } as never], {}, okFetch) + expect(result).toEqual([]) + expect(okFetch).not.toHaveBeenCalled() + }) + + it("returns Copilot credits formatted for display", async () => { + const [copilot] = await getProviderQuotas([{ apiProvider: providerIdentifiers.githubCopilot } as never]) + expect(copilot).toMatchObject({ + providerId: providerIdentifiers.githubCopilot, + ok: true, + plan: "business", + windows: [{ id: "premium", valueLabel: "39,389.3 / 140,000 used", usedPercent: 28.1, resetAt: 1 }], + }) + }) + + it("reports noKey when the profile has no API key", async () => { + const [q] = await getProviderQuotas([{ apiProvider: providerIdentifiers.openrouter } as never], {}, okFetch) + expect(q).toMatchObject({ providerId: providerIdentifiers.openrouter, ok: false, reason: "noKey" }) + expect(okFetch).not.toHaveBeenCalled() + }) + + it("treats a malformed custom base URL as a different host and never sends the key", async () => { + const fetchSpy = vi.fn(okFetch) + const [q] = await getProviderQuotas( + [ + { + apiProvider: providerIdentifiers.openrouter, + openRouterApiKey: "sk", + openRouterBaseUrl: "not a url", + } as never, + ], + {}, + fetchSpy, + ) + expect(q).toMatchObject({ ok: false, reason: "unsupported" }) + expect(fetchSpy).not.toHaveBeenCalled() + }) + + it("accepts the provider's own host written with a trailing path or slash", async () => { + const fetchSpy = vi.fn(async () => new Response(JSON.stringify({ data: { limit: 10, limit_remaining: 5 } }))) + const [q] = await getProviderQuotas( + [ + { + apiProvider: providerIdentifiers.openrouter, + openRouterApiKey: "sk", + openRouterBaseUrl: "https://openrouter.ai/api/v1/", + } as never, + ], + {}, + fetchSpy, + ) + expect(q).toMatchObject({ ok: true }) + }) + + it("never sends a key to a custom base URL", async () => { + const fetchSpy = vi.fn(okFetch) + const [q] = await getProviderQuotas( + [ + { + apiProvider: providerIdentifiers.openrouter, + openRouterApiKey: "sk", + openRouterBaseUrl: "https://evil.example/api/v1", + } as never, + ], + {}, + fetchSpy, + ) + expect(q).toMatchObject({ ok: false, reason: "unsupported" }) + expect(fetchSpy).not.toHaveBeenCalled() + }) + + it("calls the provider's own host with the saved key", async () => { + const fetchSpy = vi.fn(okFetch) + const [q] = await getProviderQuotas( + [{ apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "sk-test" } as never], + {}, + fetchSpy, + ) + expect(fetchSpy).toHaveBeenCalledWith( + "https://openrouter.ai/api/v1/key", + expect.objectContaining({ headers: expect.objectContaining({ Authorization: "Bearer sk-test" }) }), + ) + expect(q).toMatchObject({ ok: true, windows: [{ valueLabel: "$5.00 / $10.00 used" }] }) + }) + + it("maps 401 to noKey", async () => { + const [q] = await getProviderQuotas( + [{ apiProvider: providerIdentifiers.deepseek, deepSeekApiKey: "bad" } as never], + {}, + vi.fn(async () => new Response("", { status: 401 })), + ) + expect(q).toMatchObject({ providerId: providerIdentifiers.deepseek, ok: false, reason: "noKey" }) + }) + + it("queries a profile on the provider's own host even when an earlier profile uses a custom gateway", async () => { + const fetchSpy = vi.fn(async (_url: RequestInfo | URL, _init?: RequestInit) => { + return new Response(JSON.stringify({ balance_infos: [{ currency: "USD", total_balance: "7.5" }] })) + }) + const [q] = await getProviderQuotas( + [ + { + apiProvider: providerIdentifiers.deepseek, + deepSeekApiKey: "gateway-key", + deepSeekBaseUrl: "https://gateway.example.com/v1", + } as never, + { apiProvider: providerIdentifiers.deepseek, deepSeekApiKey: "real-key" } as never, + ], + {}, + fetchSpy, + ) + expect(q).toMatchObject({ ok: true, windows: [{ valueLabel: "$7.50 left" }] }) + expect(String(fetchSpy.mock.calls[0][0])).toContain("api.deepseek.com") + // The gateway profile's key is never sent anywhere. + expect(JSON.stringify(fetchSpy.mock.calls)).not.toContain("gateway-key") + }) + + it("reports unsupported only when every keyed profile uses a custom gateway", async () => { + const [q] = await getProviderQuotas( + [ + { + apiProvider: providerIdentifiers.deepseek, + deepSeekApiKey: "k", + deepSeekBaseUrl: "https://gateway.example.com/v1", + } as never, + ], + {}, + vi.fn(), + ) + expect(q).toMatchObject({ ok: false, reason: "unsupported" }) + }) + + it("does not cache a missing key: adding one shows up on the next call", async () => { + const fetchSpy = vi.fn(async () => new Response(JSON.stringify({ data: { limit: 10, limit_remaining: 5 } }))) + const [before] = await getProviderQuotas( + [{ apiProvider: providerIdentifiers.openrouter } as never], + {}, + fetchSpy, + ) + expect(before).toMatchObject({ ok: false, reason: "noKey" }) + + const [after] = await getProviderQuotas( + [{ apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "sk" } as never], + {}, + fetchSpy, + ) + expect(after).toMatchObject({ ok: true }) + }) + + it("does not cache a failure: a retry within the TTL is fetched again", async () => { + const fetchSpy = vi + .fn() + .mockResolvedValueOnce(new Response("", { status: 500 })) + .mockResolvedValueOnce(new Response(JSON.stringify({ data: { limit: 10, limit_remaining: 5 } }))) + const profiles = [{ apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "sk" } as never] + + const [first] = await getProviderQuotas(profiles, {}, fetchSpy) + expect(first).toMatchObject({ ok: false, reason: "error" }) + const [second] = await getProviderQuotas(profiles, {}, fetchSpy) + expect(second).toMatchObject({ ok: true }) + expect(fetchSpy).toHaveBeenCalledTimes(2) + }) + + it("refetches when the API key changes", async () => { + const fetchSpy = vi.fn(async () => new Response(JSON.stringify({ data: { limit: 10, limit_remaining: 5 } }))) + await getProviderQuotas( + [{ apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "sk-one" } as never], + {}, + fetchSpy, + ) + await getProviderQuotas( + [{ apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "sk-two" } as never], + {}, + fetchSpy, + ) + expect(fetchSpy).toHaveBeenCalledTimes(2) + }) + + it("does not hand a result fetched with one key to a caller using another, even while the first is in flight", async () => { + const pending = new Map void>() + const fetchSpy = vi.fn( + (_url: RequestInfo | URL, init?: RequestInit) => + new Promise((resolve) => { + pending.set(String((init?.headers as Record).Authorization), resolve) + }), + ) + const body = (remaining: number) => + new Response(JSON.stringify({ data: { limit: 10, limit_remaining: remaining } })) + + const first = getProviderQuotas( + [{ apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "sk-one" } as never], + {}, + fetchSpy, + ) + const second = getProviderQuotas( + [{ apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "sk-two" } as never], + {}, + fetchSpy, + ) + await vi.waitFor(() => expect(fetchSpy).toHaveBeenCalledTimes(2)) + // Each request went out with its own key, and nothing else. + expect([...pending.keys()].sort()).toEqual(["Bearer sk-one", "Bearer sk-two"]) + + // Answer them with different data, in the opposite order, so a mix-up would show. + pending.get("Bearer sk-two")!(body(2)) + pending.get("Bearer sk-one")!(body(9)) + + const [[a], [b]] = await Promise.all([first, second]) + expect(a).toMatchObject({ ok: true, windows: [{ usedPercent: 10 }] }) + expect(b).toMatchObject({ ok: true, windows: [{ usedPercent: 80 }] }) + }) + + it("drops a cached success when a forced refresh fails, so the next normal call retries", async () => { + const ok = () => new Response(JSON.stringify({ data: { limit: 10, limit_remaining: 5 } })) + const fetchSpy = vi + .fn() + .mockResolvedValueOnce(ok()) + .mockResolvedValueOnce(new Response("", { status: 500 })) + .mockResolvedValueOnce(ok()) + const profiles = [{ apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "sk" } as never] + + await getProviderQuotas(profiles, {}, fetchSpy) + const [failed] = await getProviderQuotas(profiles, { force: true }, fetchSpy) + expect(failed).toMatchObject({ ok: false, reason: "error" }) + + // The old success must not be served as if it were current. + const [retry] = await getProviderQuotas(profiles, {}, fetchSpy) + expect(retry).toMatchObject({ ok: true }) + expect(fetchSpy).toHaveBeenCalledTimes(3) + }) + + it("aborts the network request when the only caller goes away", async () => { + let seen: AbortSignal | undefined + const fetchSpy = vi.fn( + (_url: RequestInfo | URL, init?: RequestInit) => + new Promise((_resolve, reject) => { + seen = init?.signal ?? undefined + seen?.addEventListener("abort", () => reject(new DOMException("Aborted", "AbortError"))) + }), + ) + const controller = new AbortController() + const result = getProviderQuotas( + [{ apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "sk" } as never], + { signal: controller.signal }, + fetchSpy, + ) + await vi.waitFor(() => expect(seen).toBeDefined()) + expect(seen!.aborted).toBe(false) + + controller.abort() + await expect(result).rejects.toMatchObject({ name: "AbortError" }) + expect(seen!.aborted).toBe(true) + }) + + it("keeps the shared request running until its last caller leaves", async () => { + let seen: AbortSignal | undefined + let release: (r: Response) => void = () => {} + const fetchSpy = vi.fn( + (_url: RequestInfo | URL, init?: RequestInit) => + new Promise((resolve) => { + seen = init?.signal ?? undefined + release = resolve + }), + ) + const profiles = [{ apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "sk" } as never] + const leaver = new AbortController() + + const staying = getProviderQuotas(profiles, {}, fetchSpy) + const leaving = getProviderQuotas(profiles, { signal: leaver.signal }, fetchSpy) + await vi.waitFor(() => expect(seen).toBeDefined()) + + leaver.abort() + await expect(leaving).rejects.toMatchObject({ name: "AbortError" }) + // Someone is still waiting, so the shared fetch must keep going. + expect(seen!.aborted).toBe(false) + + release(new Response(JSON.stringify({ data: { limit: 10, limit_remaining: 5 } }))) + const [quota] = await staying + expect(quota).toMatchObject({ ok: true }) + expect(fetchSpy).toHaveBeenCalledTimes(1) + }) + + it("rejects at once with an already-aborted signal, without keeping a request alive", async () => { + const fetchSpy = vi.fn(() => new Promise(() => {})) + const controller = new AbortController() + controller.abort() + await expect( + getProviderQuotas( + [{ apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "sk" } as never], + { signal: controller.signal }, + fetchSpy, + ), + ).rejects.toMatchObject({ name: "AbortError" }) + }) + + it("shares one request between concurrent callers for the same credentials", async () => { + let release: (r: Response) => void = () => {} + const fetchSpy = vi.fn(() => new Promise((resolve) => (release = resolve))) + const profiles = [{ apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "sk" } as never] + + const a = getProviderQuotas(profiles, {}, fetchSpy) + const b = getProviderQuotas(profiles, { force: true }, fetchSpy) + await vi.waitFor(() => expect(fetchSpy).toHaveBeenCalled()) + release(new Response(JSON.stringify({ data: { limit: 10, limit_remaining: 5 } }))) + + const [ra, rb] = await Promise.all([a, b]) + expect(fetchSpy).toHaveBeenCalledTimes(1) + expect(ra).toEqual(rb) + }) + + it("caches results for the same set of providers unless forced", async () => { + const fetchSpy = vi.fn(async () => new Response(JSON.stringify({ data: { limit: 10, limit_remaining: 5 } }))) + const profiles = [{ apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "sk" } as never] + await getProviderQuotas(profiles, {}, fetchSpy) + await getProviderQuotas(profiles, {}, fetchSpy) + expect(fetchSpy).toHaveBeenCalledTimes(1) + await getProviderQuotas(profiles, { force: true }, fetchSpy) + expect(fetchSpy).toHaveBeenCalledTimes(2) + }) +}) + +describe("loadProfiles", () => { + it("loads every saved profile through the manager, with keys", async () => { + const source = { + listConfig: vi.fn(async () => [{ id: "a" }, { id: "b" }]), + getProfile: vi.fn( + async ({ id }: { id: string }) => ({ apiProvider: "x", openRouterApiKey: `key-${id}` }) as never, + ), + } + const profiles = await loadProfiles(source) + expect(profiles).toEqual([ + { apiProvider: "x", openRouterApiKey: "key-a" }, + { apiProvider: "x", openRouterApiKey: "key-b" }, + ]) + expect(source.getProfile).toHaveBeenCalledWith({ id: "a" }) + }) + + it("skips a profile that fails to load instead of failing the whole refresh", async () => { + const source = { + listConfig: vi.fn(async () => [{ id: "ok" }, { id: "broken" }]), + getProfile: vi.fn(async ({ id }: { id: string }) => { + if (id === "broken") throw new Error("corrupt secret storage") + return { apiProvider: "x" } as never + }), + } + expect(await loadProfiles(source)).toEqual([{ apiProvider: "x" }]) + }) + + it("returns an empty list when there are no profiles", async () => { + expect(await loadProfiles({ listConfig: async () => [], getProfile: vi.fn() })).toEqual([]) + }) +}) + +describe("error handling never leaks credentials", () => { + beforeEach(() => resetProviderQuotaCache()) + + it("reports a generic message for network errors that embed the key", async () => { + const [q] = await getProviderQuotas( + [{ apiProvider: providerIdentifiers.deepseek, deepSeekApiKey: "sk-secret" } as never], + {}, + vi.fn(async () => { + throw new Error("connect ECONNREFUSED https://api.deepseek.com Authorization: Bearer sk-secret") + }), + ) + expect(q).toMatchObject({ ok: false, reason: "error", message: "Request failed" }) + expect(JSON.stringify(q)).not.toContain("sk-secret") + }) + + it("reports only the status for non-auth HTTP failures", async () => { + const [q] = await getProviderQuotas( + [{ apiProvider: providerIdentifiers.moonshot, moonshotApiKey: "sk" } as never], + {}, + vi.fn(async () => new Response("secret internal page", { status: 502 })), + ) + expect(q).toMatchObject({ ok: false, reason: "error", message: "HTTP 502" }) + }) + + it("treats an empty payload as an error", async () => { + const [q] = await getProviderQuotas( + [{ apiProvider: providerIdentifiers.deepseek, deepSeekApiKey: "sk" } as never], + {}, + vi.fn(async () => new Response(JSON.stringify({ balance_infos: [] }))), + ) + expect(q).toMatchObject({ ok: false, reason: "error", message: "No usage data" }) + }) + + it("surfaces Copilot failures with their reason", async () => { + const copilotMod = await import("../copilotQuota") + vi.mocked(copilotMod.getGitHubCopilotQuota).mockResolvedValueOnce({ ok: false, reason: "signedOut" }) + const [q] = await getProviderQuotas([{ apiProvider: providerIdentifiers.githubCopilot } as never], { + force: true, + }) + expect(q).toMatchObject({ ok: false, reason: "signedOut" }) + }) + + it("shows Copilot unlimited plans without numbers", async () => { + const copilotMod = await import("../copilotQuota") + vi.mocked(copilotMod.getGitHubCopilotQuota).mockResolvedValueOnce({ + ok: true, + quota: { plan: "enterprise", unlimited: true, fetchedAt: 1, resetAt: 2 }, + }) + const [q] = await getProviderQuotas([{ apiProvider: providerIdentifiers.githubCopilot } as never], { + force: true, + }) + expect(q).toMatchObject({ ok: true, windows: [{ id: "premium", valueLabel: "Unlimited", resetAt: 2 }] }) + }) + + it("falls back to a percent label when counts are missing", async () => { + const copilotMod = await import("../copilotQuota") + vi.mocked(copilotMod.getGitHubCopilotQuota).mockResolvedValueOnce({ + ok: true, + quota: { unlimited: false, usedPercent: 60, fetchedAt: 1 }, + }) + const [q] = await getProviderQuotas([{ apiProvider: providerIdentifiers.githubCopilot } as never], { + force: true, + }) + expect(q).toMatchObject({ ok: true, windows: [{ valueLabel: "60% used", usedPercent: 60 }] }) + }) +}) diff --git a/src/services/language-models/__tests__/quotaUtils.spec.ts b/src/services/language-models/__tests__/quotaUtils.spec.ts new file mode 100644 index 0000000000..30f5185140 --- /dev/null +++ b/src/services/language-models/__tests__/quotaUtils.spec.ts @@ -0,0 +1,109 @@ +import { describe, expect, it } from "vitest" + +import { + QuotaHttpError, + asRecord, + clampPercent, + formatCredits, + formatMoney, + roundToTenth, + safeErrorMessage, + toEpochMs, + toNumber, +} from "../quotaUtils" + +describe("toEpochMs", () => { + it("treats numbers below 1e12 as epoch seconds and larger ones as milliseconds", () => { + expect(toEpochMs(1_800_000_000)).toBe(1_800_000_000_000) + expect(toEpochMs(1_800_000_000_000)).toBe(1_800_000_000_000) + }) + + it("parses date strings", () => { + expect(toEpochMs("2026-01-02T03:04:05Z")).toBe(Date.parse("2026-01-02T03:04:05Z")) + }) + + it("rejects zero, negatives, non-finite numbers, blank and unparseable strings, and other types", () => { + expect(toEpochMs(0)).toBeUndefined() + expect(toEpochMs(-5)).toBeUndefined() + expect(toEpochMs(Number.NaN)).toBeUndefined() + expect(toEpochMs(Number.POSITIVE_INFINITY)).toBeUndefined() + expect(toEpochMs(" ")).toBeUndefined() + expect(toEpochMs("not a date")).toBeUndefined() + expect(toEpochMs(null)).toBeUndefined() + expect(toEpochMs({})).toBeUndefined() + }) +}) + +describe("toNumber", () => { + it.each([ + [5, 5], + [0, 0], + ["12.5", 12.5], + [" 7 ", 7], + ])("accepts %j", (input, expected) => expect(toNumber(input)).toBe(expected)) + + it.each([[NaN], [Infinity], [""], [" "], ["abc"], [null], [undefined], [{}], [[]]])("rejects %j", (input) => + expect(toNumber(input)).toBeUndefined(), + ) +}) + +describe("asRecord", () => { + it("returns plain objects only", () => { + expect(asRecord({ a: 1 })).toEqual({ a: 1 }) + for (const bad of [null, undefined, [], "x", 1]) expect(asRecord(bad)).toBeUndefined() + }) +}) + +describe("clampPercent", () => { + it.each([ + [-5, 0], + [0, 0], + [42.5, 42.5], + [100, 100], + [250, 100], + ])("%j → %j", (input, expected) => expect(clampPercent(input)).toBe(expected)) +}) + +describe("formatMoney", () => { + it("formats with two decimals and a sign before the symbol", () => { + expect(formatMoney(12.4)).toBe("$12.40") + expect(formatMoney(-0.5)).toBe("-$0.50") + expect(formatMoney(8, "¥")).toBe("¥8.00") + }) +}) + +describe("formatCredits", () => { + it("keeps whole numbers whole and fractions to one decimal", () => { + expect(formatCredits(140000)).toBe("140,000") + expect(formatCredits(39389.34)).toBe("39,389.3") + }) +}) + +describe("roundToTenth", () => { + it("rounds to one decimal", () => { + expect(roundToTenth(39389.26)).toBe(39389.3) + expect(roundToTenth(5)).toBe(5) + }) +}) + +describe("safeErrorMessage", () => { + it("keeps the status for HTTP errors", () => { + expect(safeErrorMessage(new QuotaHttpError(503))).toBe("HTTP 503") + }) + + it("normalises timeouts and aborts", () => { + const timeout = Object.assign(new Error("x"), { name: "TimeoutError" }) + const abort = Object.assign(new Error("x"), { name: "AbortError" }) + expect(safeErrorMessage(timeout)).toBe("Request timed out") + expect(safeErrorMessage(abort)).toBe("Request timed out") + }) + + it("never leaks the text of arbitrary errors (could embed URLs, headers or keys)", () => { + const leaky = new Error( + "fetch failed: https://api.example.com/v1?key=sk-secret Authorization: Bearer sk-secret", + ) + expect(safeErrorMessage(leaky)).toBe("Request failed") + expect(safeErrorMessage("sk-secret")).toBe("Request failed") + expect(safeErrorMessage(undefined)).toBe("Request failed") + }) +}) diff --git a/src/services/language-models/copilotQuota.ts b/src/services/language-models/copilotQuota.ts new file mode 100644 index 0000000000..6a8c6be07f --- /dev/null +++ b/src/services/language-models/copilotQuota.ts @@ -0,0 +1,132 @@ +import * as vscode from "vscode" + +import { githubCopilotLanguageModel, type GitHubCopilotQuota, type GitHubCopilotQuotaResult } from "@roo-code/types" + +import { asRecord, clampPercent, roundToTenth, safeErrorMessage, toNumber } from "./quotaUtils" + +/** + * GitHub Copilot premium-request allowance for the Usage tab. + * + * Source: `GET https://api.github.com/copilot_internal/user`, the endpoint + * Copilot Chat's own usage panel reads. It returns + * `quota_snapshots.premium_interactions` plus `quota_reset_date`. + * + * Auth reuses the GitHub session VS Code already holds for Copilot (silent: + * never prompts). The token is only ever sent to api.github.com. + */ + +const COPILOT_USER_URL = "https://api.github.com/copilot_internal/user" +const REQUEST_TIMEOUT_MS = 15_000 +/** Avoid hammering the endpoint when the Usage tab is reopened repeatedly. */ +const CACHE_TTL_MS = 60_000 + +/** + * Parses the endpoint payload. Pure, so it is unit-tested against recorded + * shapes. Returns undefined when the payload has no premium snapshot at all. + * + * Semantics mirror Copilot Chat (CopilotUserQuotaInfo): + * - `quota_remaining` is the precise (fractional) twin of `remaining`; prefer it. + * - used = entitlement - remaining, so the figure matches GitHub's own panel. + * - `percent_remaining` is a server-computed fallback when counts are missing. + */ +export function parseCopilotQuota(payload: unknown, now = Date.now()): GitHubCopilotQuota | undefined { + const root = asRecord(payload) + const snapshot = asRecord(asRecord(root?.quota_snapshots)?.premium_interactions) + if (!root || !snapshot) return undefined + + const plan = typeof root.copilot_plan === "string" ? root.copilot_plan : undefined + const resetRaw = root.quota_reset_date_utc ?? root.quota_reset_date + const resetAt = + typeof resetRaw === "string" && !Number.isNaN(Date.parse(resetRaw)) ? Date.parse(resetRaw) : undefined + + if (snapshot.unlimited === true) { + return { plan, unlimited: true, resetAt, fetchedAt: now } + } + + const entitlement = toNumber(snapshot.entitlement) + const remaining = toNumber(snapshot.quota_remaining) ?? toNumber(snapshot.remaining) + + let used: number | undefined + let usedPercent: number | undefined + + if (entitlement !== undefined && entitlement > 0 && remaining !== undefined) { + used = roundToTenth(Math.min(entitlement, Math.max(0, entitlement - remaining))) + usedPercent = clampPercent((used / entitlement) * 100) + } else { + const percentRemaining = toNumber(snapshot.percent_remaining) + if (percentRemaining !== undefined) usedPercent = clampPercent(100 - percentRemaining) + } + + return { + plan, + unlimited: false, + entitlement: entitlement !== undefined && entitlement > 0 ? entitlement : undefined, + used, + usedPercent, + resetAt, + fetchedAt: now, + } +} + +async function getGitHubToken(): Promise { + const { authProviderId, authScopeSets } = githubCopilotLanguageModel + for (const scopes of authScopeSets) { + const session = await vscode.authentication.getSession(authProviderId, scopes, { silent: true }) + if (session) return session.accessToken + } + return undefined +} + +let cache: { at: number; result: GitHubCopilotQuotaResult } | undefined +let inFlight: Promise | undefined + +/** + * Fetches the quota. Concurrent callers share one request; successful results + * are cached briefly unless `force` is set (the Refresh button). + */ +export function getGitHubCopilotQuota( + { force = false }: { force?: boolean } = {}, + fetchImpl: typeof fetch = fetch, +): Promise { + if (!force && cache && Date.now() - cache.at < CACHE_TTL_MS) return Promise.resolve(cache.result) + if (inFlight) return inFlight + + inFlight = (async (): Promise => { + try { + const token = await getGitHubToken() + if (!token) return { ok: false, reason: "signedOut" } + + const response = await fetchImpl(COPILOT_USER_URL, { + method: "GET", + headers: { + Authorization: `token ${token}`, + Accept: "application/json", + "Editor-Version": `vscode/${vscode.version}`, + "X-Github-Api-Version": "2025-04-01", + }, + signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS), + }) + + if (response.status === 401) return { ok: false, reason: "signedOut" } + if (response.status === 403 || response.status === 404) return { ok: false, reason: "noCopilot" } + if (!response.ok) return { ok: false, reason: "error", message: `GitHub API error ${response.status}` } + + const quota = parseCopilotQuota(await response.json()) + const result: GitHubCopilotQuotaResult = quota ? { ok: true, quota } : { ok: false, reason: "noCopilot" } + if (result.ok) cache = { at: Date.now(), result } + return result + } catch (error) { + return { ok: false, reason: "error", message: safeErrorMessage(error) } + } finally { + inFlight = undefined + } + })() + + return inFlight +} + +/** @internal test hook */ +export function resetGitHubCopilotQuotaCache() { + cache = undefined + inFlight = undefined +} diff --git a/src/services/language-models/providerQuotas.ts b/src/services/language-models/providerQuotas.ts new file mode 100644 index 0000000000..4286b4f6d1 --- /dev/null +++ b/src/services/language-models/providerQuotas.ts @@ -0,0 +1,673 @@ +import { + providerIdentifiers, + type ProviderQuota, + type ProviderQuotaWindow, + type ProviderSettings, +} from "@roo-code/types" + +import { getGitHubCopilotQuota } from "./copilotQuota" +import { + QuotaHttpError, + asRecord, + clampPercent, + formatCredits, + formatMoney, + safeErrorMessage, + toEpochMs, + toNumber, +} from "./quotaUtils" + +/** + * Live limits/balances for every connected provider that exposes a usage API, + * for the Usage tab's "Provider limits" section. + * + * Endpoints are each provider's own usage API. Credentials come from the + * user's saved Zoo profiles and are sent only to that provider's own host. + * Providers without a usage API are simply not listed. + */ + +const REQUEST_TIMEOUT_MS = 15_000 +const CACHE_TTL_MS = 60_000 + +// Parsers (pure; unit-tested) ---------------------------------------------------------------------- + +/** OpenRouter `GET /api/v1/key` → key limit, or monthly spend when unlimited. */ +export function parseOpenRouterKey(payload: unknown): ProviderQuotaWindow[] | undefined { + const data = asRecord(asRecord(payload)?.data) + if (!data) return undefined + + const limit = toNumber(data.limit) + const remaining = toNumber(data.limit_remaining) + + if (limit !== undefined && limit > 0 && remaining !== undefined) { + const used = Math.max(0, limit - remaining) + return [ + { + id: "key_limit", + valueLabel: `${formatMoney(used)} / ${formatMoney(limit)} used`, + usedPercent: clampPercent((used / limit) * 100), + }, + ] + } + + const usage = toNumber(data.usage_monthly) ?? toNumber(data.usage) + return usage === undefined ? undefined : [{ id: "spend", valueLabel: `${formatMoney(usage)} spent this month` }] +} + +/** DeepSeek `GET /user/balance` → prepaid balance (prefers a positive USD balance). */ +export function parseDeepSeekBalance(payload: unknown): ProviderQuotaWindow[] | undefined { + const infos = asRecord(payload)?.balance_infos + if (!Array.isArray(infos) || infos.length === 0) return undefined + + const rows = infos.map(asRecord).filter((r): r is Record => !!r) + const pick = + rows.find((r) => r.currency === "USD" && (toNumber(r.total_balance) ?? 0) > 0) ?? + rows.find((r) => r.currency === "CNY" && (toNumber(r.total_balance) ?? 0) > 0) ?? + rows.find((r) => r.currency === "USD") ?? + rows[0] + + const balance = toNumber(pick?.total_balance) + if (balance === undefined) return undefined + return [{ id: "balance", valueLabel: `${formatMoney(balance, pick?.currency === "CNY" ? "¥" : "$")} left` }] +} + +/** Moonshot `GET /v1/users/me/balance` → available balance. */ +export function parseMoonshotBalance(payload: unknown): ProviderQuotaWindow[] | undefined { + const balance = toNumber(asRecord(asRecord(payload)?.data)?.available_balance) + return balance === undefined ? undefined : [{ id: "balance", valueLabel: `${formatMoney(balance)} left` }] +} + +/** "5-hour", "Weekly", "3d", … for a rolling window of the given length. */ +export function windowLabel(seconds: number | undefined, fallback: string): string { + if (!seconds || seconds <= 0) return fallback + if (seconds === 7 * 86400) return "Weekly" + if (seconds % 86400 === 0) return `${seconds / 86400}-day` + if (seconds % 3600 === 0) return `${seconds / 3600}-hour` + return fallback +} + +/** Kimi Code `GET /coding/v1/usages` → 5-hour / weekly / monthly usage. */ +export function parseKimiCodeUsage(payload: unknown): ProviderQuotaWindow[] | undefined { + const root = asRecord(payload) + if (!root) return undefined + const windows: ProviderQuotaWindow[] = [] + + const usages = asRecord(root.usages) + if (usages) { + // `used_ratio` is a 0-1 fraction, in the order Kimi's own CLI renders it. + for (const [key, label] of [ + ["limit_5h", "5-hour"], + ["limit_7d", "Weekly"], + ["limit_month_total", "Monthly"], + ] as const) { + const entry = asRecord(usages[key]) + const ratio = toNumber(entry?.used_ratio) + if (ratio === undefined) continue + windows.push({ + id: key, + valueLabel: label, + usedPercent: clampPercent(ratio * 100), + resetAt: toEpochMs(entry?.reset_time), + }) + } + return windows.length ? windows : undefined + } + + // Pre-ratio payload: one counted weekly `usage` block. + const usage = asRecord(root.usage) + const limit = toNumber(usage?.limit) + if (usage && limit && limit > 0) { + const used = toNumber(usage.used) + const remaining = toNumber(usage.remaining) + const usedAmount = used ?? (remaining !== undefined ? limit - remaining : undefined) + if (usedAmount !== undefined) { + windows.push({ + id: "weekly", + valueLabel: "Weekly", + usedPercent: clampPercent((usedAmount / limit) * 100), + resetAt: toEpochMs(usage.resetTime), + }) + } + } + return windows.length ? windows : undefined +} + +/** + * z.ai / Zhipu `GET /api/monitor/usage/quota/limit`. Business failures arrive + * as HTTP 200 with `{ code, msg, success: false }`, so the envelope is checked + * first. TOKENS_LIMIT / CREDIT_LIMIT entries are the 5-hour and weekly windows. + */ +export function parseZaiQuota(payload: unknown): ProviderQuotaWindow[] | undefined { + const root = asRecord(payload) + if (!root) return undefined + const code = root.code + if (root.success === false || (code !== undefined && code !== null && code !== 200)) return undefined + + const limits = asRecord(root.data)?.limits + if (!Array.isArray(limits)) return undefined + + const windows: ProviderQuotaWindow[] = [] + for (const raw of limits) { + const limit = asRecord(raw) + if (!limit || (limit.type !== "TOKENS_LIMIT" && limit.type !== "CREDIT_LIMIT")) continue + + // unit 3 = hours, unit 6 = weeks. + const number = toNumber(limit.number) + const unitSeconds = limit.unit === 3 ? 3600 : limit.unit === 6 ? 7 * 86400 : undefined + const seconds = number && unitSeconds ? number * unitSeconds : undefined + + const total = toNumber(limit.usage) + const consumed = toNumber(limit.currentValue) + const percentage = toNumber(limit.percentage) + const usedPercent = + percentage !== undefined + ? clampPercent(percentage) + : total && total > 0 && consumed !== undefined + ? clampPercent((consumed / total) * 100) + : undefined + + windows.push({ + id: `limit_${windows.length}`, + valueLabel: + limit.type === "CREDIT_LIMIT" && total !== undefined && consumed !== undefined + ? `${windowLabel(seconds, "Credits")}: ${formatCredits(consumed)} / ${formatCredits(total)} credits` + : windowLabel(seconds, "Tokens"), + usedPercent, + resetAt: toEpochMs(limit.nextResetTime), + }) + } + return windows.length ? windows : undefined +} + +/** + * MiniMax `GET /v1/token_plan/remains` (or the legacy coding-plan endpoint) → + * 5-hour interval and, when the plan has one, weekly usage for the chat model. + */ +export function parseMiniMaxRemains(payload: unknown, isTokenPlan = true): ProviderQuotaWindow[] | undefined { + const root = asRecord(payload) + const base = asRecord(root?.base_resp) + if (base && base.status_code !== 0) return undefined + const remains = root?.model_remains + if (!Array.isArray(remains) || remains.length === 0) return undefined + + const rows = remains.map(asRecord).filter((r): r is Record => !!r) + const name = (r: Record) => (typeof r.model_name === "string" ? r.model_name : "") + const model = + rows.find((r) => /^minimax-m/i.test(name(r)) && (toNumber(r.current_interval_total_count) ?? 0) > 0) ?? + rows.find((r) => ["general", "chat", "text"].includes(name(r).toLowerCase())) ?? + rows.find((r) => typeof r.current_interval_remaining_percent === "number") ?? + rows[0] + if (!model) return undefined + + const usedPercentOf = (prefix: "interval" | "weekly"): number | undefined => { + const remainingPercent = toNumber(model[`current_${prefix}_remaining_percent`]) + if (remainingPercent !== undefined) return clampPercent(100 - clampPercent(remainingPercent)) + const total = toNumber(model[`current_${prefix}_total_count`]) + const raw = toNumber(model[`current_${prefix}_usage_count`]) + if (!total || total <= 0 || raw === undefined) return undefined + // Token-plan counters report what is left; coding-plan counters report what is used. + const used = isTokenPlan ? Math.max(0, total - raw) : raw + return clampPercent((used / total) * 100) + } + + const windows: ProviderQuotaWindow[] = [ + { + id: "5h", + valueLabel: "5-hour", + usedPercent: usedPercentOf("interval"), + resetAt: toEpochMs(model.end_time), + }, + ] + + // Status 3 = the window does not apply to this plan tier. + const weeklyApplies = toNumber(model.current_weekly_status) !== 3 + const weeklyPercent = usedPercentOf("weekly") + if (weeklyApplies && weeklyPercent !== undefined) { + windows.push({ + id: "weekly", + valueLabel: "Weekly", + usedPercent: weeklyPercent, + resetAt: toEpochMs(model.weekly_end_time), + }) + } + return windows +} + +/** NanoGPT `GET /api/subscription/v1/usage` → daily / weekly / monthly allowance. */ +export function parseNanoGptUsage(payload: unknown): ProviderQuotaWindow[] | undefined { + const root = asRecord(payload) + if (!root) return undefined + + const state = typeof root.state === "string" ? root.state : "active" + const limits = asRecord(root.limits) + const dailyQuota = root.dailyInputTokens !== undefined ? root.dailyInputTokens : root.daily + const monthly = asRecord(root.monthly) + + const entries: { id: string; label: string; quota: unknown; limit: unknown; resetAt: unknown }[] = [ + { + id: "daily", + label: "Daily", + quota: dailyQuota, + limit: + root.dailyInputTokens !== undefined + ? limits?.dailyInputTokens + : (asRecord(dailyQuota)?.limit ?? asRecord(asRecord(dailyQuota)?.limits)?.daily), + resetAt: asRecord(dailyQuota)?.resetAt, + }, + { + id: "weekly", + label: "Weekly", + quota: root.weeklyInputTokens, + limit: limits?.weeklyInputTokens, + resetAt: asRecord(root.weeklyInputTokens)?.resetAt, + }, + { + id: "monthly", + label: "Monthly", + quota: monthly, + limit: monthly?.limit ?? asRecord(monthly?.limits)?.monthly, + resetAt: monthly?.resetAt ?? asRecord(root.period)?.currentPeriodEnd, + }, + ] + + const windows: ProviderQuotaWindow[] = [] + for (const { id, label, quota, limit, resetAt } of entries) { + const q = asRecord(quota) + if (!q) continue + let usedPercent: number | undefined + if (!q.degraded) { + const fraction = toNumber(q.percentUsed) + const used = toNumber(q.used) + const cap = toNumber(limit) + if (fraction !== undefined) usedPercent = clampPercent(fraction * 100) + else if (used !== undefined && cap !== undefined && cap > 0) usedPercent = clampPercent((used / cap) * 100) + } + windows.push({ + id, + valueLabel: state !== "active" ? `${label} (${state})` : label, + usedPercent, + resetAt: toEpochMs(resetAt), + }) + } + return windows.length ? windows : undefined +} + +/** OpenCode Go `GET /zen/go/v1/usage` (API key) → rolling 5-hour, weekly, monthly percent used. */ +export function parseOpenCodeGoUsage(payload: unknown): ProviderQuotaWindow[] | undefined { + const usage = asRecord(asRecord(payload)?.usage) + if (!usage) return undefined + + const windows: ProviderQuotaWindow[] = [] + for (const [id, field, label] of [ + ["5h", "rolling", "5-hour"], + ["weekly", "weekly", "Weekly"], + ["monthly", "monthly", "Monthly"], + ] as const) { + const entry = asRecord(usage[field]) + const percent = toNumber(entry?.percent) + const resetAt = toEpochMs(entry?.resetsAt) + if (percent === undefined || resetAt === undefined) continue + windows.push({ id, valueLabel: label, usedPercent: clampPercent(percent), resetAt }) + } + return windows.length ? windows : undefined +} + +// Fetchers ---------------------------------------------------------------------------------------- + +type Fetch = typeof fetch + +async function getJson(fetchImpl: Fetch, url: string, apiKey: string, signal?: AbortSignal): Promise { + const timeout = AbortSignal.timeout(REQUEST_TIMEOUT_MS) + const response = await fetchImpl(url, { + method: "GET", + headers: { Authorization: `Bearer ${apiKey}`, Accept: "application/json" }, + signal: signal ? AbortSignal.any([signal, timeout]) : timeout, + }) + if (response.status === 401 || response.status === 403) throw new AuthError() + if (!response.ok) throw new QuotaHttpError(response.status) + return response.json() +} + +class AuthError extends Error { + constructor() { + super("Invalid or expired API key") + } +} + +interface KeyedProvider { + providerId: string + /** + * Returns the API key and the usage URLs to try, in order. `urls` is + * undefined when the profile targets a host we must not send the key to + * (a custom gateway); the provider is then reported as unsupported. + */ + credentials: (s: ProviderSettings) => { apiKey?: string; urls?: string[] } + parse: (payload: unknown, urlIndex: number) => ProviderQuotaWindow[] | undefined +} + +const sameOrigin = (a: string, b: string) => { + try { + return new URL(a).origin === new URL(b).origin + } catch { + return false + } +} + +/** The provider's own default host, unless the profile points at a different one. */ +const ownHost = (defaultBase: string, path: string, baseUrl?: string): string[] | undefined => + baseUrl && !sameOrigin(baseUrl, defaultBase) ? undefined : [defaultBase + path] + +/** z.ai (international) and Zhipu (China) host the same monitor API on different origins. */ +const ZAI_ORIGINS: Record = { + international_coding: "https://api.z.ai", + international_api: "https://api.z.ai", + china_coding: "https://open.bigmodel.cn", + china_api: "https://open.bigmodel.cn", +} + +const KEYED_PROVIDERS: KeyedProvider[] = [ + { + providerId: providerIdentifiers.openrouter, + credentials: (s) => ({ + apiKey: s.openRouterApiKey, + urls: ownHost("https://openrouter.ai/api/v1", "/key", s.openRouterBaseUrl), + }), + parse: parseOpenRouterKey, + }, + { + providerId: providerIdentifiers.deepseek, + credentials: (s) => ({ + apiKey: s.deepSeekApiKey, + urls: ownHost("https://api.deepseek.com", "/user/balance", s.deepSeekBaseUrl), + }), + parse: parseDeepSeekBalance, + }, + { + providerId: providerIdentifiers.moonshot, + credentials: (s) => ({ + apiKey: s.moonshotApiKey, + urls: ownHost("https://api.moonshot.ai/v1", "/users/me/balance", s.moonshotBaseUrl), + }), + parse: parseMoonshotBalance, + }, + { + // Only API-key profiles are queried; OAuth sign-ins have no key to send. + providerId: providerIdentifiers.kimiCode, + credentials: (s) => ({ + apiKey: s.kimiCodeApiKey, + urls: ["https://api.kimi.com/coding/v1/usages"], + }), + parse: parseKimiCodeUsage, + }, + { + providerId: providerIdentifiers.zai, + credentials: (s) => ({ + apiKey: s.zaiApiKey, + urls: [`${ZAI_ORIGINS[s.zaiApiLine ?? "international_coding"]}/api/monitor/usage/quota/limit`], + }), + parse: parseZaiQuota, + }, + { + providerId: providerIdentifiers.minimax, + credentials: (s) => { + const base = s.minimaxBaseUrl || "https://api.minimax.io/anthropic" + if (sameOrigin(base, "https://api.minimax.io")) { + return { + apiKey: s.minimaxApiKey, + urls: [ + "https://api.minimax.io/v1/token_plan/remains", + "https://api.minimax.io/v1/api/openplatform/coding_plan/remains", + ], + } + } + if (sameOrigin(base, "https://api.minimaxi.com")) { + return { + apiKey: s.minimaxApiKey, + urls: [ + "https://api.minimaxi.com/v1/token_plan/remains", + "https://www.minimaxi.com/v1/api/openplatform/coding_plan/remains", + ], + } + } + return { apiKey: s.minimaxApiKey } + }, + // The first URL is the token plan, whose counters report what is left. + parse: (payload, urlIndex) => parseMiniMaxRemains(payload, urlIndex === 0), + }, + { + providerId: providerIdentifiers.nanogpt, + credentials: (s) => ({ + apiKey: s.nanoGptApiKey, + urls: ["https://nano-gpt.com/api/subscription/v1/usage"], + }), + parse: parseNanoGptUsage, + }, + { + providerId: providerIdentifiers.opencodeGo, + credentials: (s) => ({ + apiKey: s.opencodeGoApiKey, + urls: ["https://opencode.ai/zen/go/v1/usage"], + }), + parse: parseOpenCodeGoUsage, + }, +] + +type KeyedCredentials = ReturnType + +/** + * The credentials to query with: a profile whose host is safe to query wins over + * one pointed at a custom gateway, which is only a fallback (reported as + * unsupported when nothing better exists). + */ +function pickCredentials(provider: KeyedProvider, profiles: ProviderSettings[]): KeyedCredentials | undefined { + const withKey = profiles + .filter((p) => p.apiProvider === provider.providerId) + .map(provider.credentials) + .filter((c) => !!c.apiKey) + return withKey.find((c) => c.urls?.length) ?? withKey[0] +} + +/** Resolves without any network call when there is nothing to query. */ +function unqueryable(provider: KeyedProvider, creds: KeyedCredentials | undefined): ProviderQuota | undefined { + const base = { providerId: provider.providerId, ok: false, fetchedAt: Date.now() } as const + if (!creds?.apiKey) return { ...base, reason: "noKey" } + // SAFETY: never send a key to a host other than the provider's own API. A + // profile pointed at a custom gateway is reported as unsupported instead. + if (!creds.urls?.length) return { ...base, reason: "unsupported" } + return undefined +} + +async function fetchKeyed( + provider: KeyedProvider, + creds: KeyedCredentials, + fetchImpl: Fetch, + signal?: AbortSignal, +): Promise { + const now = Date.now() + if (!creds.apiKey || !creds.urls?.length) { + return { providerId: provider.providerId, ok: false, reason: "unsupported", fetchedAt: now } + } + + try { + // Try each URL in order; a failing fallback only matters if no URL yields data. + let windows: ProviderQuotaWindow[] | undefined + let lastError: unknown + for (const [index, url] of creds.urls.entries()) { + try { + windows = provider.parse(await getJson(fetchImpl, url, creds.apiKey, signal), index) + if (windows?.length) break + } catch (error) { + if (error instanceof AuthError) throw error + lastError = error + } + } + if (!windows?.length && lastError) throw lastError + return windows?.length + ? { providerId: provider.providerId, ok: true, windows, fetchedAt: now } + : { providerId: provider.providerId, ok: false, reason: "error", message: "No usage data", fetchedAt: now } + } catch (error) { + return { + providerId: provider.providerId, + ok: false, + reason: error instanceof AuthError ? "noKey" : "error", + message: error instanceof AuthError ? undefined : safeErrorMessage(error), + fetchedAt: now, + } + } +} + +async function fetchCopilot(force: boolean): Promise { + const result = await getGitHubCopilotQuota({ force }) + const providerId = providerIdentifiers.githubCopilot + if (!result.ok) + return { providerId, ok: false, reason: result.reason, message: result.message, fetchedAt: Date.now() } + + const q = result.quota + const window: ProviderQuotaWindow = q.unlimited + ? { id: "premium", valueLabel: "Unlimited", resetAt: q.resetAt } + : { + id: "premium", + valueLabel: + q.used !== undefined && q.entitlement !== undefined + ? `${formatCredits(q.used)} / ${formatCredits(q.entitlement)} used` + : q.usedPercent !== undefined + ? `${Math.round(q.usedPercent)}% used` + : // Neither counts nor a percentage were reported: that is unknown, not a measured zero. + "Usage not reported", + usedPercent: q.usedPercent, + resetAt: q.resetAt, + } + return { providerId, ok: true, plan: q.plan, windows: [window], fetchedAt: q.fetchedAt } +} + +// Entry point ------------------------------------------------------------------------------------- + +/** The slice of `ProviderSettingsManager` this service needs (keeps it testable without the manager). */ +export interface ProfileSource { + listConfig(): Promise<{ id: string }[]> + getProfile(params: { id: string }): Promise +} + +/** + * Loads full profiles (including API keys) host-side. A profile that fails to + * load is skipped rather than failing the whole refresh. Keys never leave the + * extension host: only formatted quota rows are posted to the webview. + */ +export async function loadProfiles(source: ProfileSource): Promise { + const entries = await source.listConfig() + const profiles = await Promise.all( + entries.map((entry) => source.getProfile({ id: entry.id }).catch(() => undefined)), + ) + return profiles.filter((p): p is ProviderSettings => !!p) +} + +// Successful results only, per provider and URL set. A missing key, a sign-out or a +// transient error is never pinned, so fixing it shows up on the next open instead of +// after the TTL. An entry is reused only for the exact key it was fetched with, so +// switching keys refetches. The key is compared, never hashed or used in a map key. +const cache = new Map() +interface Inflight { + apiKey: string + request: Promise + /** Callers still waiting on this request. The shared fetch is aborted only when the last one leaves. */ + waiters: number + controller: AbortController +} +const inflight = new Map() + +/** Identifies a provider and the URLs it is queried at (the credential itself is not part of it). */ +function cacheKey(provider: KeyedProvider, creds: KeyedCredentials): string { + return `${provider.providerId}|${(creds.urls ?? []).join(",")}` +} + +/** Rejects as soon as `signal` aborts, without cancelling `work` (which other callers may still be using). */ +function until(work: Promise, signal: AbortSignal | undefined, onAbort: () => void): Promise { + if (!signal) return work + return new Promise((resolve, reject) => { + const abort = () => { + onAbort() + reject(new DOMException("Aborted", "AbortError")) + } + if (signal.aborted) return abort() + signal.addEventListener("abort", abort, { once: true }) + work.then(resolve, reject).finally(() => signal.removeEventListener("abort", abort)) + }) +} + +function quotaForKeyedProvider( + provider: KeyedProvider, + profiles: ProviderSettings[], + force: boolean, + fetchImpl: Fetch, + signal?: AbortSignal, +): Promise { + const creds = pickCredentials(provider, profiles) + const skipped = unqueryable(provider, creds) + if (skipped) return Promise.resolve(skipped) + + const resolved = creds as KeyedCredentials + const apiKey = resolved.apiKey as string + const key = cacheKey(provider, resolved) + const hit = cache.get(key) + if (!force && hit && hit.apiKey === apiKey && Date.now() - hit.at < CACHE_TTL_MS) return Promise.resolve(hit.result) + + // Concurrent callers (e.g. a refresh while the first load is still running) share one request. + let entry = inflight.get(key) + if (!entry || entry.apiKey !== apiKey) { + const controller = new AbortController() + const request: Promise = fetchKeyed(provider, resolved, fetchImpl, controller.signal) + .then((result) => { + if (result.ok) { + cache.set(key, { at: Date.now(), apiKey, result }) + } else { + // A failed refresh must not leave an older success to be served as if it were current. + cache.delete(key) + } + return result + }) + .finally(() => { + if (inflight.get(key)?.request === request) inflight.delete(key) + }) + entry = { apiKey, request, waiters: 0, controller } + inflight.set(key, entry) + } + + const shared = entry + shared.waiters++ + let left = false + const leave = () => { + if (left) return + left = true + // Last one out cancels the network work; earlier leavers just stop waiting. + if (--shared.waiters === 0) shared.controller.abort() + } + return until(shared.request, signal, leave).finally(leave) +} + +/** + * Quotas for every *connected* provider with a usage API. `profiles` are the + * user's saved provider settings; only providers present there are queried. + */ +export async function getProviderQuotas( + profiles: ProviderSettings[], + { force = false, signal }: { force?: boolean; signal?: AbortSignal } = {}, + fetchImpl: Fetch = fetch, +): Promise { + const connected = new Set(profiles.map((p) => p.apiProvider).filter(Boolean) as string[]) + + const tasks: Promise[] = [] + if (connected.has(providerIdentifiers.githubCopilot)) tasks.push(fetchCopilot(force)) + for (const provider of KEYED_PROVIDERS) { + if (connected.has(provider.providerId)) { + tasks.push(quotaForKeyedProvider(provider, profiles, force, fetchImpl, signal)) + } + } + + return Promise.all(tasks) +} + +/** @internal test hook */ +export function resetProviderQuotaCache() { + cache.clear() + inflight.clear() +} diff --git a/src/services/language-models/quotaUtils.ts b/src/services/language-models/quotaUtils.ts new file mode 100644 index 0000000000..f0e7d68d99 --- /dev/null +++ b/src/services/language-models/quotaUtils.ts @@ -0,0 +1,66 @@ +/** + * Small, pure helpers shared by the quota services (`copilotQuota`, + * `providerQuotas`). Kept in one place so payload parsing behaves identically + * everywhere and is tested once. + */ + +export const toNumber = (value: unknown): number | undefined => { + if (typeof value === "number" && Number.isFinite(value)) return value + if (typeof value === "string" && value.trim() !== "") { + const parsed = Number(value) + return Number.isFinite(parsed) ? parsed : undefined + } + return undefined +} + +export const asRecord = (value: unknown): Record | undefined => + value && typeof value === "object" && !Array.isArray(value) ? (value as Record) : undefined + +export const clampPercent = (value: number): number => Math.min(100, Math.max(0, value)) + +/** + * Epoch milliseconds from a provider timestamp. Numbers below 1e12 are treated + * as epoch seconds; strings are parsed as dates. Anything else is undefined. + */ +export const toEpochMs = (value: unknown): number | undefined => { + if (typeof value === "number" && Number.isFinite(value) && value > 0) { + return value < 1_000_000_000_000 ? value * 1000 : value + } + if (typeof value === "string" && value.trim() !== "") { + const parsed = Date.parse(value) + return Number.isNaN(parsed) ? undefined : parsed + } + return undefined +} + +/** `$12.40`, `-$0.50`, `¥8.00`. */ +export const formatMoney = (value: number, symbol = "$"): string => + `${value < 0 ? "-" : ""}${symbol}${Math.abs(value).toFixed(2)}` + +/** `140,000` / `39,389.3`: whole numbers stay whole, fractions keep one decimal. */ +export const formatCredits = (value: number): string => + value.toLocaleString("en-US", { maximumFractionDigits: Number.isInteger(value) ? 0 : 1 }) + +/** One decimal, matching GitHub's own panel. */ +export const roundToTenth = (value: number): number => Math.round(value * 10) / 10 + +/** + * Turns an unknown failure into a short, safe string for the UI. Only the + * well-understood cases keep their text; anything else (network stack errors + * can embed URLs or headers) collapses to a generic message so credentials + * can never ride an error back to the webview. + */ +export class QuotaHttpError extends Error { + constructor(readonly status: number) { + super(`HTTP ${status}`) + this.name = "QuotaHttpError" + } +} + +export function safeErrorMessage(error: unknown): string { + if (error instanceof QuotaHttpError) return error.message + if (error instanceof Error && (error.name === "TimeoutError" || error.name === "AbortError")) { + return "Request timed out" + } + return "Request failed" +} diff --git a/webview-ui/playwright/gallery/stories.tsx b/webview-ui/playwright/gallery/stories.tsx index 85d6919db4..8575d83fbc 100644 --- a/webview-ui/playwright/gallery/stories.tsx +++ b/webview-ui/playwright/gallery/stories.tsx @@ -415,6 +415,18 @@ export const stories: Record = { ) }, + "usage-settings": async () => { + const { UsageSettingsStory } = await import("@/components/settings/__tests__/UsageSettings.visual.fixture") + return + }, + "usage-settings-degraded": async () => { + const { UsageSettingsStory } = await import("@/components/settings/__tests__/UsageSettings.visual.fixture") + return + }, + "usage-settings-empty": async () => { + const { UsageSettingsStory } = await import("@/components/settings/__tests__/UsageSettings.visual.fixture") + return + }, "ui-settings": async () => { const { UISettingsStory } = await import("@/components/settings/__tests__/UISettings.visual.fixture") return diff --git a/webview-ui/src/components/settings/ProviderLimits.tsx b/webview-ui/src/components/settings/ProviderLimits.tsx new file mode 100644 index 0000000000..fb2d863c07 --- /dev/null +++ b/webview-ui/src/components/settings/ProviderLimits.tsx @@ -0,0 +1,186 @@ +import { useCallback, useEffect, useRef, useState } from "react" +import { RefreshCw } from "lucide-react" + +import { VsCodeLmModelsMessageType, type ProviderQuota } from "@roo-code/types" + +import { useAppTranslation } from "@/i18n/TranslationContext" +import { cn } from "@src/lib/utils" +import { vscode } from "@src/utils/vscode" +import i18next from "i18next" +import { providerLabel } from "@src/utils/providerLabel" + +const barColor = (pct: number) => + pct >= 90 ? "bg-vscode-charts-red" : pct >= 75 ? "bg-vscode-charts-yellow" : "bg-vscode-charts-green" + +/** + * "Provider limits": live credits/balances for every connected provider that + * exposes a usage API (GitHub Copilot, OpenRouter, DeepSeek, Moonshot, Kimi Code, + * z.ai, MiniMax, NanoGPT, OpenCode Go), one + * compact row each. Fetched by the extension host; keys never reach the webview. + */ +export const ProviderLimits = () => { + const { t } = useAppTranslation() + const [quotas, setQuotas] = useState() + const [loading, setLoading] = useState(true) + + // Only the newest request counts: an answer for an older one (a slow first load that a refresh + // overtook, or one that outlived this component) is ignored. + const latestRequestId = useRef(undefined) + const counter = useRef(0) + + const cancelLatest = useCallback(() => { + if (latestRequestId.current) { + vscode.postMessage({ + type: VsCodeLmModelsMessageType.cancelProviderQuotas, + requestId: latestRequestId.current, + }) + latestRequestId.current = undefined + } + }, []) + + const request = useCallback( + (force: boolean) => { + cancelLatest() + const requestId = `provider-quotas-${++counter.current}` + latestRequestId.current = requestId + setLoading(true) + vscode.postMessage({ type: VsCodeLmModelsMessageType.requestProviderQuotas, bool: force, requestId }) + }, + [cancelLatest], + ) + + useEffect(() => { + const onMessage = (event: MessageEvent) => { + if (event.data?.type !== VsCodeLmModelsMessageType.providerQuotas) return + if (event.data.requestId !== latestRequestId.current) return + latestRequestId.current = undefined + setQuotas(event.data.providerQuotas ?? []) + setLoading(false) + } + window.addEventListener("message", onMessage) + request(false) + return () => { + window.removeEventListener("message", onMessage) + // Tell the host nobody is waiting any more so it can stop the profile load and any fetches. + cancelLatest() + } + }, [request, cancelLatest]) + + // Nothing connected that has a usage API: hide the section entirely. + if (quotas && quotas.length === 0) return null + + const fetchedAt = quotas?.reduce((max, q) => Math.max(max, q.fetchedAt), 0) + + return ( +
+
+

+ {t("settings:usage.limits.title")} +

+ +
+ +
+ {!quotas && ( +
+ {t("settings:usage.limits.loading")} +
+ )} + {quotas?.map((q) => ( + + new Date(ts).toLocaleDateString(i18next.language || "en", { dateStyle: "medium" }) + } + /> + ))} +
+
+ ) +} + +const QuotaRow = ({ + quota, + name, + formatReset, +}: { + quota: ProviderQuota + name: string + formatReset: (ts: number) => string +}) => { + const { t } = useAppTranslation() + + return ( +
+
+ + {name} + {quota.ok && quota.plan && ( + {quota.plan} + )} + {!quota.ok && ( + + {t(`settings:usage.limits.${quota.reason}`)} + + )} +
+ + {quota.ok && + quota.windows.map((w) => ( +
+
+ {w.valueLabel} + {w.usedPercent !== undefined && ( + + {Math.round(w.usedPercent)}% + + )} +
+ {w.usedPercent !== undefined && ( +
+
+
+ )} + {w.resetAt && ( +
+ {t("settings:usage.limits.resets", { date: formatReset(w.resetAt) })} +
+ )} +
+ ))} +
+ ) +} diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx index 6100a373e1..050250a905 100644 --- a/webview-ui/src/components/settings/SettingsView.tsx +++ b/webview-ui/src/components/settings/SettingsView.tsx @@ -17,6 +17,7 @@ import { FlaskConical, TriangleAlert, Globe, + ChartColumn, Info, MessageSquare, LucideIcon, @@ -76,6 +77,7 @@ import { TerminalSettings } from "./TerminalSettings" import { ExperimentalSettings } from "./ExperimentalSettings" import { LanguageSettings } from "./LanguageSettings" import { About } from "./About" +import { UsageSettings } from "./UsageSettings" import { Section } from "./Section" import PromptsSettings from "./PromptsSettings" import { SlashCommandsSettings } from "./SlashCommandsSettings" @@ -116,6 +118,7 @@ export const sectionNames = [ "ui", "experimental", "language", + "usage", "about", ] as const @@ -558,6 +561,7 @@ const SettingsView = forwardRef(({ onDone, t { id: "ui", icon: Glasses }, { id: "experimental", icon: FlaskConical }, { id: "language", icon: Globe }, + { id: "usage", icon: ChartColumn }, { id: "about", icon: Info }, ], [], // No dependencies needed now @@ -974,6 +978,9 @@ const SettingsView = forwardRef(({ onDone, t )} + {/* Usage Section */} + {renderTab === "usage" && } + {/* About Section */} {renderTab === "about" && ( `$${cost.toFixed(2)}` + +const PALETTE = [ + "var(--vscode-charts-blue)", + "var(--vscode-charts-purple)", + "var(--vscode-charts-green)", + "var(--vscode-charts-orange)", + "var(--vscode-charts-yellow)", + "var(--vscode-charts-red)", +] + +const WEEKDAY_FMT = new Intl.DateTimeFormat(undefined, { weekday: "narrow" }) +const DAY_FMT = new Intl.DateTimeFormat(undefined, { day: "numeric" }) + +/** + * Usage tab. + * + * 1. Provider limits: live credits/balances from each connected provider. + * 2. Usage history: rollup of local task history (tokens, cost when the + * provider reports a price, breakdowns, top tasks). + * + * Subscription providers (e.g. GitHub Copilot) record no per-task price, so + * when a range has tokens but no cost the history switches to tokens and the + * cost stat is hidden rather than shown as a misleading "$0.00". + */ +export const UsageSettings = ({ className, ...props }: HTMLAttributes) => { + const { t } = useAppTranslation() + const { taskHistory, cwd } = useExtensionState() + + const [range, setRange] = useState("7d") + const [scope, setScope] = useState<"workspace" | "all">("workspace") + + const workspace = scope === "workspace" ? cwd : undefined + + // Provider and model come from what each request recorded, never from the + // currently selected profile, so switching providers doesn't relabel history. + const history = useMemo(() => taskHistory ?? [], [taskHistory]) + + // One "now" for the view and for the export, rolled over at the next local midnight. Without it a + // tab left open across midnight keeps yesterday's window while Export (computed at click time) + // would use today's, and the two would disagree. + const [now, setNow] = useState(() => Date.now()) + useEffect(() => { + const nextMidnight = new Date(now) + nextMidnight.setHours(24, 0, 0, 0) + const timer = setTimeout(() => setNow(Date.now()), nextMidnight.getTime() - now + 1000) + return () => clearTimeout(timer) + }, [now]) + + const summary = useMemo(() => summarizeUsage(history, { range, workspace, now }), [history, range, workspace, now]) + + const providerName = (key: string) => (key === UNRECORDED ? t("settings:usage.notRecorded") : providerLabel(key)) + + const metric: UsageMetric = pickMetric(summary) + const value = (cost: number, tokens: number) => (metric === "cost" ? cost : tokens) + const fmt = (cost: number, tokens: number) => (metric === "cost" ? formatCost(cost) : formatLargeNumber(tokens)) + const total = metricTotal(summary, metric) + + // Row view-model: the priced/unpriced rule lives in `bucketView` (pure, tested). + const bucketRow = (b: { cost: number; tokens: number; priced: boolean }) => { + const view = bucketView(b, metric, total) + return { + ...view, + label: view.unpriced + ? `${formatLargeNumber(b.tokens)} ${t("settings:usage.tokensShort")} · ${t("settings:usage.noPrice")}` + : fmt(b.cost, b.tokens), + } + } + + const maxDaily = Math.max(0, ...summary.daily.map((d) => value(d.cost, d.tokens))) + const showDayLabels = summary.daily.length <= 14 + const isEmpty = summary.taskCount === 0 + + const handleExport = () => { + const csv = usageToCsv(history, { range, workspace, now }) + const url = URL.createObjectURL(new Blob([csv], { type: "text/csv" })) + const a = document.createElement("a") + a.href = url + a.download = `zoo-usage-${range}.csv` + a.click() + URL.revokeObjectURL(url) + } + + return ( +
+ {t("settings:sections.usage")} + +
+
+ + +
+
+ {t("settings:usage.history")} + {!isEmpty && ( + + )} +
+ + {/* Filters */} + +
+
+ {USAGE_RANGES.map((r) => ( + + ))} +
+ +
+
+ + {isEmpty ? ( +
+ {t("settings:usage.empty")} +
+ ) : ( + <> + {/* Three compact stat cards, as in the design mock */} +
+ {metric === "cost" ? ( + + ) : ( + + )} + {metric === "cost" ? ( + 0 + ? t("settings:usage.stats.cacheHit", { + percent: Math.round(summary.cacheHitRate * 100), + }) + : undefined + } + /> + ) : ( + m.key !== UNRECORDED).length || "–", + )} + label={t("settings:usage.stats.models")} + /> + )} + +
+ + {metric === "tokens" && ( +

+ {t("settings:usage.noPricingNote")} +

+ )} + + {summary.daily.length > 1 && ( + +
+ {summary.daily.map((d) => { + const v = value(d.cost, d.tokens) + return ( +
0 + ? "bg-vscode-charts-blue" + : "bg-vscode-input-background", + )} + style={{ + height: + maxDaily > 0 && v > 0 + ? `${Math.max(6, (v / maxDaily) * 100)}%` + : "2px", + }} + title={`${new Date(d.day).toLocaleDateString()} · ${fmt(d.cost, d.tokens)}`} + /> + ) + })} +
+ {showDayLabels && ( +
+ {summary.daily.map((d) => ( + + {summary.daily.length <= 7 + ? WEEKDAY_FMT.format(d.day) + : DAY_FMT.format(d.day)} + + ))} +
+ )} + + )} + + ({ + key: b.key, + name: providerName(b.key), + ...bucketRow(b), + }))} + testId="usage-by-provider" + /> + ({ + key: b.key, + name: modelIdFromKey(b.key) ?? t("settings:usage.notRecorded"), + subtitle: b.apiProvider ? providerLabel(b.apiProvider) : undefined, + ...bucketRow(b), + }))} + testId="usage-by-model" + /> +

+ {t("settings:usage.byMode")}:{" "} + {summary.byMode + .map((m) => `${m.key} ${bucketRow(m).label.split(" · ")[0]}`) + .join(" · ")} +

+ + +
+ {summary.topTasks.map((task) => ( + + ))} +
+
+ +

+ {t("settings:usage.disclaimer")} +

+ + )} +
+
+
+
+ ) +} + +const SectionTitle = ({ children }: { children: React.ReactNode }) => ( +

{children}

+) + +const Block = ({ title, children, testId }: { title: string; children: React.ReactNode; testId?: string }) => ( +
+
{title}
+ {children} +
+) + +const Stat = ({ value, label, hint }: { value: string; label: string; hint?: string }) => ( +
+
{value}
+
{label}
+ {hint &&
{hint}
} +
+) + +const Breakdown = ({ + title, + rows, + testId, +}: { + title: string + rows: { key: string; name: string; subtitle?: string; label: string; percent: number; unpriced?: boolean }[] + testId: string +}) => ( + +
+ {rows.slice(0, 5).map((row, i) => { + const pct = row.percent + const color = row.unpriced ? "var(--vscode-descriptionForeground)" : PALETTE[i % PALETTE.length] + return ( +
+ + + {row.name} + {row.subtitle && ( + {row.subtitle} + )} + + + {row.label} + + + + + + {row.unpriced ? "–" : `${pct}%`} + +
+ ) + })} +
+
+) diff --git a/webview-ui/src/components/settings/__tests__/ProviderLimits.spec.tsx b/webview-ui/src/components/settings/__tests__/ProviderLimits.spec.tsx new file mode 100644 index 0000000000..01046c9bb9 --- /dev/null +++ b/webview-ui/src/components/settings/__tests__/ProviderLimits.spec.tsx @@ -0,0 +1,255 @@ +import { act, fireEvent, render, screen } from "@testing-library/react" +import { beforeEach, describe, expect, it, vi } from "vitest" + +import { providerIdentifiers, type ProviderQuota } from "@roo-code/types" + +import { ProviderLimits } from "../ProviderLimits" + +const post = vi.hoisted(() => vi.fn()) +vi.mock("@src/utils/vscode", () => ({ vscode: { postMessage: post } })) + +// Render the key plus its interpolation values so assertions can see the formatted output. +vi.mock("@/i18n/TranslationContext", () => ({ + useAppTranslation: () => ({ + t: (key: string, options?: Record) => + options ? `${key} ${Object.values(options).join(" ")}` : key, + }), +})) + +/** The id the component put on its most recent request (the host echoes it back). */ +const lastRequestId = () => { + const requests = post.mock.calls.map((c) => c[0]).filter((m) => m.type === "requestProviderQuotas") + return requests.at(-1)?.requestId as string +} + +/** Answers the most recent request, or the given id. Pass `null` to send an answer with no id at all. */ +const respond = (providerQuotas: ProviderQuota[], id?: string | null) => + act(() => { + const requestId = id === null ? undefined : (id ?? lastRequestId()) + window.dispatchEvent( + new MessageEvent("message", { data: { type: "providerQuotas", providerQuotas, requestId } }), + ) + }) + +describe("ProviderLimits", () => { + beforeEach(() => { + post.mockClear() + }) + + it("asks the extension for quotas on mount without forcing", () => { + render() + expect(post).toHaveBeenCalledWith({ + type: "requestProviderQuotas", + bool: false, + requestId: expect.stringMatching(/^provider-quotas-\d+$/), + }) + }) + + it("shows a loading row until the first response", () => { + render() + expect(screen.getByTestId("provider-limits")).toBeTruthy() + expect(screen.queryByTestId(`provider-limit-${providerIdentifiers.githubCopilot}`)).toBeNull() + }) + + it("renders credits with a progress bar and reset date", () => { + render() + respond([ + { + providerId: providerIdentifiers.githubCopilot, + ok: true, + plan: "business", + fetchedAt: Date.now(), + windows: [ + { + id: "premium", + valueLabel: "39,389.3 / 140,000 used", + usedPercent: 28.1, + resetAt: Date.parse("2026-11-01T12:00:00Z"), + }, + ], + }, + ]) + + const row = screen.getByTestId(`provider-limit-${providerIdentifiers.githubCopilot}`) + expect(row.textContent).toContain("GitHub Copilot") + expect(row.textContent).toContain("business") + expect(row.textContent).toContain("39,389.3 / 140,000 used") + expect(row.textContent).toContain("28%") + const bar = row.querySelector("[role=progressbar]")! + expect(bar.getAttribute("aria-valuenow")).toBe("28") + // The translation key plus the formatted reset date, not just the key. + expect(row.textContent).toContain( + `settings:usage.limits.resets ${new Date(Date.parse("2026-11-01T12:00:00Z")).toLocaleDateString("en", { dateStyle: "medium" })}`, + ) + }) + + it("omits the bar for balance-only providers", () => { + render() + respond([ + { + providerId: providerIdentifiers.deepseek, + ok: true, + fetchedAt: 1, + windows: [{ id: "balance", valueLabel: "$4.25 left" }], + }, + ]) + const row = screen.getByTestId(`provider-limit-${providerIdentifiers.deepseek}`) + expect(row.textContent).toContain("$4.25 left") + expect(row.querySelector("[role=progressbar]")).toBeNull() + }) + + it("writes the reset date and the updated time in the display language", () => { + render() + const resetAt = new Date(2026, 10, 1, 12, 0).getTime() + const fetchedAt = new Date(2026, 10, 1, 14, 41).getTime() + respond([ + { + providerId: providerIdentifiers.openrouter, + ok: true, + fetchedAt, + windows: [{ id: "key_limit", valueLabel: "x", usedPercent: 10, resetAt }], + }, + ]) + const row = screen.getByTestId(`provider-limit-${providerIdentifiers.openrouter}`) + expect(row.textContent).toContain( + `settings:usage.limits.resets ${new Date(resetAt).toLocaleDateString("en", { dateStyle: "medium" })}`, + ) + expect(screen.getByTestId("provider-limits-refresh").textContent).toContain( + `settings:usage.limits.updated ${new Date(fetchedAt).toLocaleTimeString("en", { hour: "numeric", minute: "2-digit" })}`, + ) + }) + + it.each(["noKey", "noCopilot", "signedOut", "unsupported", "error"] as const)( + "shows the quiet status text for %s", + (reason) => { + render() + respond([{ providerId: providerIdentifiers.openrouter, ok: false, reason, fetchedAt: 1 }]) + const row = screen.getByTestId(`provider-limit-${providerIdentifiers.openrouter}`) + expect(row.textContent).toContain(`settings:usage.limits.${reason}`) + expect(row.querySelector("[role=progressbar]")).toBeNull() + }, + ) + + it.each([ + [50, "bg-vscode-charts-green"], + [80, "bg-vscode-charts-yellow"], + [95, "bg-vscode-charts-red"], + ])("colours the bar by how much of the allowance is used (%i%%)", (usedPercent, expected) => { + render() + respond([ + { + providerId: providerIdentifiers.openrouter, + ok: true, + fetchedAt: 1, + windows: [{ id: "key_limit", valueLabel: "x", usedPercent }], + }, + ]) + const bar = screen + .getByTestId(`provider-limit-${providerIdentifiers.openrouter}`) + .querySelector("[role=progressbar] > div")! + expect(bar.className).toContain(expected) + }) + + it("treats a response without a providerQuotas list as empty", () => { + render() + act(() => { + window.dispatchEvent( + new MessageEvent("message", { data: { type: "providerQuotas", requestId: lastRequestId() } }), + ) + }) + expect(screen.queryByTestId("provider-limits")).toBeNull() + }) + + it("hides the whole section when nothing connected has a usage API", () => { + render() + respond([]) + expect(screen.queryByTestId("provider-limits")).toBeNull() + }) + + it("refresh forces a new request", () => { + render() + respond([ + { + providerId: providerIdentifiers.deepseek, + ok: true, + fetchedAt: 1, + windows: [{ id: "b", valueLabel: "$1.00 left" }], + }, + ]) + post.mockClear() + fireEvent.click(screen.getByTestId("provider-limits-refresh")) + expect(post).toHaveBeenCalledWith({ + type: "requestProviderQuotas", + bool: true, + requestId: expect.stringMatching(/^provider-quotas-\d+$/), + }) + }) + + it("ignores unrelated messages", () => { + render() + act(() => { + window.dispatchEvent(new MessageEvent("message", { data: { type: "somethingElse" } })) + }) + expect(screen.getByTestId("provider-limits")).toBeTruthy() + }) + + describe("request lifecycle", () => { + const ok = (providerId: string = providerIdentifiers.deepseek): ProviderQuota => ({ + providerId, + ok: true, + fetchedAt: 1, + windows: [{ id: "b", valueLabel: "$1.00 left" }], + }) + + it("ignores an answer for a request that a refresh has overtaken", () => { + render() + const first = lastRequestId() + respond([ok(providerIdentifiers.deepseek)]) + fireEvent.click(screen.getByTestId("provider-limits-refresh")) + const second = lastRequestId() + expect(second).not.toBe(first) + + // A late answer to the first request must not replace the newer state or end the spinner. + respond([ok(providerIdentifiers.moonshot)], first) + expect(screen.queryByTestId(`provider-limit-${providerIdentifiers.moonshot}`)).toBeNull() + expect(screen.getByTestId("provider-limits-refresh").hasAttribute("disabled")).toBe(true) + + respond([ok(providerIdentifiers.moonshot)], second) + expect(screen.getByTestId(`provider-limit-${providerIdentifiers.moonshot}`)).toBeTruthy() + expect(screen.getByTestId("provider-limits-refresh").hasAttribute("disabled")).toBe(false) + }) + + it("ignores an answer that carries no request id or an unknown one", () => { + render() + respond([ok()], null) + respond([ok()], "provider-quotas-999") + expect(screen.queryByTestId(`provider-limit-${providerIdentifiers.deepseek}`)).toBeNull() + }) + + it("does not offer a refresh while a request is pending, so a newer one never races an older one", () => { + render() + expect(screen.getByTestId("provider-limits-refresh").hasAttribute("disabled")).toBe(true) + post.mockClear() + fireEvent.click(screen.getByTestId("provider-limits-refresh")) + expect(post).not.toHaveBeenCalled() + }) + + it("cancels the in-flight request on unmount and ignores a late answer", () => { + const { unmount } = render() + const pending = lastRequestId() + post.mockClear() + unmount() + expect(post).toHaveBeenCalledWith({ type: "cancelProviderQuotas", requestId: pending }) + // Must not throw or update state after unmount. + expect(() => respond([ok()], pending)).not.toThrow() + }) + + it("does not cancel a request that has already been answered", () => { + const { unmount } = render() + respond([ok()]) + post.mockClear() + unmount() + expect(post).not.toHaveBeenCalledWith(expect.objectContaining({ type: "cancelProviderQuotas" })) + }) + }) +}) diff --git a/webview-ui/src/components/settings/__tests__/UsageSettings.branches.spec.tsx b/webview-ui/src/components/settings/__tests__/UsageSettings.branches.spec.tsx new file mode 100644 index 0000000000..f7518755ad --- /dev/null +++ b/webview-ui/src/components/settings/__tests__/UsageSettings.branches.spec.tsx @@ -0,0 +1,276 @@ +import { fireEvent, render, screen } from "@testing-library/react" +import { beforeEach, describe, expect, it, vi } from "vitest" + +import { providerIdentifiers, type HistoryItem } from "@roo-code/types" + +import { UsageSettings } from "../UsageSettings" + +const post = vi.hoisted(() => vi.fn()) +vi.mock("@src/utils/vscode", () => ({ vscode: { postMessage: post } })) + +const state = vi.hoisted(() => ({ taskHistory: [] as HistoryItem[], cwd: "/ws/a" })) +vi.mock("@/context/ExtensionStateContext", () => ({ useExtensionState: () => state })) + +vi.mock("../ProviderLimits", () => ({ ProviderLimits: () =>
})) + +// Radix Select does not open in jsdom; a native onValueChange(e.target.value)}> + {children} + + ), + SelectTrigger: ({ children }: { children: React.ReactNode }) => <>{children}, + SelectValue: () => null, + SelectContent: ({ children }: { children: React.ReactNode }) => <>{children}, + SelectItem: ({ value, children }: { value: string; children: React.ReactNode }) => ( + + ), +})) + +const NOW = Date.now() +const DAY = 24 * 60 * 60 * 1000 + +let n = 0 +const task = (overrides: Partial = {}): HistoryItem => ({ + id: `t${++n}`, + number: n, + ts: NOW - 60_000, + task: `Task ${n}`, + tokensIn: 1000, + tokensOut: 100, + totalCost: 0, + workspace: "/ws/a", + mode: "code", + ...overrides, +}) + +const withUsage = (overrides: Partial & { cost?: number; cacheReads?: number } = {}) => { + const { cost = 1, ...rest } = overrides + return task({ + totalCost: cost, + usageByModel: [ + { + apiProvider: providerIdentifiers.anthropic, + modelId: "claude-sonnet-5", + requests: 1, + tokensIn: 1000, + tokensOut: 100, + cost, + }, + ], + ...rest, + }) +} + +describe("UsageSettings – branches", () => { + beforeEach(() => { + post.mockClear() + state.taskHistory = [] + state.cwd = "/ws/a" + }) + + it("widening the scope to all workspaces includes tasks from other workspaces", () => { + state.taskHistory = [withUsage({ cost: 1 }), withUsage({ cost: 2, workspace: "/ws/other" })] + render() + expect(screen.getByTestId("usage-stats").textContent).not.toContain("$3.00") + fireEvent.change(screen.getByTestId("scope-select"), { target: { value: "all" } }) + expect(screen.getByTestId("usage-stats").textContent).toContain("$3.00") + fireEvent.change(screen.getByTestId("scope-select"), { target: { value: "workspace" } }) + expect(screen.getByTestId("usage-stats").textContent).not.toContain("$3.00") + }) + + it("shows the cache hit rate only when something was read from the cache", () => { + state.taskHistory = [withUsage({ cacheReads: 3000 })] + const { unmount } = render() + expect(screen.getByTestId("usage-stats").textContent).toContain("settings:usage.stats.cacheHit") + unmount() + + state.taskHistory = [withUsage()] + render() + expect(screen.getByTestId("usage-stats").textContent).not.toContain("settings:usage.stats.cacheHit") + }) + + it("labels chart bars by weekday for a week, and by date for a longer range", () => { + state.taskHistory = [withUsage()] + render() + const weekLabels = Array.from(screen.getByTestId("usage-daily-chart").parentElement!.querySelectorAll("span")) + .map((s) => s.textContent) + .filter(Boolean) + fireEvent.click(screen.getByTestId("usage-range-30d")) + const monthChart = screen.getByTestId("usage-daily-chart") + expect(monthChart.children.length).toBeGreaterThan(14) + expect(weekLabels.length).toBeGreaterThan(0) + }) + + it("shows an unpriced top task by tokens and a priced one by cost when metrics are mixed", () => { + state.taskHistory = [ + withUsage({ cost: 2, task: "priced task" }), + task({ + task: "unpriced task", + totalCost: 0, + tokensIn: 5000, + tokensOut: 500, + usageByModel: [ + { + apiProvider: providerIdentifiers.githubCopilot, + modelId: "gpt-5", + requests: 1, + tokensIn: 5000, + tokensOut: 500, + cost: 0, + }, + ], + }), + ] + render() + // Each task is one button; find it by its title and check that row on its own. + const rowFor = (title: string) => screen.getByText(title).closest("button")!.textContent! + + const priced = rowFor("priced task") + expect(priced).toContain("$2.00") + expect(priced).not.toContain("settings:usage.tokensShort") + + const unpriced = rowFor("unpriced task") + expect(unpriced).toContain("settings:usage.tokensShort") + expect(unpriced).not.toContain("$") + }) + + it("shows only the model when no provider was recorded, and nothing when no usage was recorded", () => { + state.taskHistory = [ + task({ + task: "model only", + totalCost: 1, + usageByModel: [{ modelId: "mystery-model", requests: 1, tokensIn: 10, tokensOut: 1, cost: 1 }], + }), + task({ task: "no usage rows", totalCost: 0.5 }), + ] + render() + const rows = screen.getByTestId("usage-top-tasks").textContent! + expect(rows).toContain("mystery-model") + expect(rows).not.toContain("·") + }) + + it("renders the empty state when the task history is not available yet", () => { + state.taskHistory = undefined as never + render() + expect(screen.getByTestId("usage-empty")).toBeTruthy() + }) + + it("labels chart bars by date when more than a week of days is charted", () => { + state.taskHistory = Array.from({ length: 9 }, (_, i) => withUsage({ ts: NOW - i * DAY })) + render() + fireEvent.click(screen.getByTestId("usage-range-all")) + const chart = screen.getByTestId("usage-daily-chart") + expect(chart.children.length).toBeGreaterThan(7) + expect(chart.children.length).toBeLessThanOrEqual(14) + // Date labels (e.g. "Oct 27") sit under the bars, one per day, each with a day number. + const labelRow = chart.nextElementSibling as HTMLElement + expect(labelRow.children).toHaveLength(chart.children.length) + expect(labelRow.textContent).toMatch(/\d/) + }) + + it("treats tasks with no recorded tokens or cost as zero rather than failing", () => { + // Mixed metrics (one priced task) so unpriced rows are shown by tokens. + state.taskHistory = [ + withUsage({ cost: 2 }), + task({ + task: "bare", + totalCost: undefined as never, + tokensIn: undefined as never, + tokensOut: undefined as never, + }), + ] + render() + expect(screen.getByTestId("usage-top-tasks").textContent).toContain("bare") + }) + + it("treats a task with no cost as zero when ranking by tokens", () => { + state.taskHistory = [ + task({ + task: "tokens only", + totalCost: undefined as never, + usageByModel: [ + { + apiProvider: providerIdentifiers.githubCopilot, + modelId: "gpt-5", + requests: 1, + tokensIn: 100, + tokensOut: 10, + cost: 0, + }, + ], + }), + ] + render() + expect(screen.getByTestId("usage-top-tasks").textContent).toContain("tokens only") + }) + it("shows the cost for a priced task whose token counters are missing", () => { + state.taskHistory = [ + task({ + task: "priced no counters", + totalCost: 3, + tokensIn: undefined as never, + tokensOut: undefined as never, + usageByModel: [ + { + apiProvider: providerIdentifiers.anthropic, + modelId: "claude-sonnet-5", + requests: 1, + tokensIn: 1, + tokensOut: 1, + cost: 3, + }, + ], + }), + ] + render() + expect(screen.getByTestId("usage-top-tasks").textContent).toContain("$3.00") + }) + + it("hides the export button when the task history is not available", () => { + state.taskHistory = undefined as never + render() + expect(screen.queryByTestId("usage-export-csv")).toBeNull() + }) + + it("shows a token count for an unpriced task whose token counters are missing", () => { + state.taskHistory = [ + withUsage({ cost: 2 }), + task({ + task: "no counters", + totalCost: 0, + tokensIn: undefined as never, + tokensOut: undefined as never, + usageByModel: [ + { + apiProvider: providerIdentifiers.githubCopilot, + modelId: "gpt-5", + requests: 1, + tokensIn: 1, + tokensOut: 1, + cost: 0, + }, + ], + }), + ] + render() + const text = screen.getByTestId("usage-top-tasks").textContent! + expect(text).toContain("no counters") + expect(text).toContain("settings:usage.tokensShort") + }) + + it("excludes tasks older than the range", () => { + state.taskHistory = [withUsage({ cost: 1 }), withUsage({ cost: 9, ts: NOW - 20 * DAY })] + render() + expect(screen.getByTestId("usage-stats").textContent).not.toContain("$10.00") + }) +}) diff --git a/webview-ui/src/components/settings/__tests__/UsageSettings.midnight.spec.tsx b/webview-ui/src/components/settings/__tests__/UsageSettings.midnight.spec.tsx new file mode 100644 index 0000000000..f688f68287 --- /dev/null +++ b/webview-ui/src/components/settings/__tests__/UsageSettings.midnight.spec.tsx @@ -0,0 +1,103 @@ +import { act, fireEvent, render, screen } from "@testing-library/react" +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest" + +import { providerIdentifiers, type HistoryItem } from "@roo-code/types" + +import { UsageSettings } from "../UsageSettings" + +const post = vi.hoisted(() => vi.fn()) +vi.mock("@src/utils/vscode", () => ({ vscode: { postMessage: post } })) + +const state = vi.hoisted(() => ({ taskHistory: [] as HistoryItem[], cwd: "/ws/a" })) +vi.mock("@/context/ExtensionStateContext", () => ({ useExtensionState: () => state })) + +vi.mock("../ProviderLimits", () => ({ ProviderLimits: () =>
})) + +// Spy on the real export so the test can see which "now" it was given. +const csvSpy = vi.hoisted(() => vi.fn()) +vi.mock("@src/utils/usage", async (importOriginal) => { + const actual = await importOriginal() + return { + ...actual, + usageToCsv: (...args: Parameters) => { + csvSpy(...args) + return actual.usageToCsv(...args) + }, + } +}) + +const MINUTE = 60_000 +// 23:50 local on 2026-10-27: ten minutes before midnight. +const BEFORE_MIDNIGHT = new Date(2026, 9, 27, 23, 50).getTime() + +const todaysTask: HistoryItem = { + id: "late", + number: 1, + ts: new Date(2026, 9, 27, 23, 0).getTime(), + task: "Late task", + tokensIn: 1000, + tokensOut: 100, + totalCost: 4, + workspace: "/ws/a", + usageByModel: [ + { + apiProvider: providerIdentifiers.anthropic, + modelId: "claude-sonnet-5", + requests: 1, + tokensIn: 1000, + tokensOut: 100, + cost: 4, + }, + ], +} + +describe("UsageSettings – across local midnight", () => { + beforeEach(() => { + vi.useFakeTimers({ toFake: ["setTimeout", "clearTimeout", "Date"] }) + vi.setSystemTime(BEFORE_MIDNIGHT) + post.mockClear() + csvSpy.mockClear() + state.taskHistory = [todaysTask] + state.cwd = "/ws/a" + }) + + afterEach(() => { + vi.useRealTimers() + }) + + it("rolls the Today view over at midnight instead of keeping yesterday's tasks", () => { + render() + fireEvent.click(screen.getByTestId("usage-range-today")) + expect(screen.getByTestId("usage-stats").textContent).toContain("$4.00") + + // Midnight plus the one-second margin: the view must re-evaluate "today" on its own. + act(() => { + vi.advanceTimersByTime(10 * MINUTE + 5_000) + }) + + expect(screen.queryByTestId("usage-stats")).toBeNull() + expect(screen.getByTestId("usage-empty")).toBeTruthy() + }) + + it("keeps the view and the export on the same day, even if the clock moves past midnight first", () => { + render() + fireEvent.click(screen.getByTestId("usage-range-today")) + Object.assign(URL, { createObjectURL: vi.fn(() => "blob:x"), revokeObjectURL: vi.fn() }) + const click = vi.spyOn(HTMLAnchorElement.prototype, "click").mockImplementation(() => {}) + + // The wall clock passes midnight but the roll-over timer has not fired yet: the view still shows the + // old day, so Export must use that same day rather than a fresh Date.now(). + vi.setSystemTime(BEFORE_MIDNIGHT + 20 * MINUTE) + fireEvent.click(screen.getByTestId("usage-export-csv")) + + expect(csvSpy).toHaveBeenCalledTimes(1) + expect(csvSpy.mock.calls[0][1]).toMatchObject({ range: "today", now: BEFORE_MIDNIGHT }) + click.mockRestore() + }) + + it("does not leave a timer running after unmount", () => { + const { unmount } = render() + unmount() + expect(vi.getTimerCount()).toBe(0) + }) +}) diff --git a/webview-ui/src/components/settings/__tests__/UsageSettings.spec.tsx b/webview-ui/src/components/settings/__tests__/UsageSettings.spec.tsx new file mode 100644 index 0000000000..7f7c2acb54 --- /dev/null +++ b/webview-ui/src/components/settings/__tests__/UsageSettings.spec.tsx @@ -0,0 +1,263 @@ +import { fireEvent, render, screen, within } from "@testing-library/react" +import { beforeEach, describe, expect, it, vi } from "vitest" + +import { providerIdentifiers, type HistoryItem } from "@roo-code/types" + +import { UsageSettings } from "../UsageSettings" + +const post = vi.hoisted(() => vi.fn()) +vi.mock("@src/utils/vscode", () => ({ vscode: { postMessage: post } })) + +const state = vi.hoisted(() => ({ taskHistory: [] as HistoryItem[], cwd: "/ws/a" })) +vi.mock("@/context/ExtensionStateContext", () => ({ useExtensionState: () => state })) + +// The provider-limits section talks to the extension host; it has its own spec. +vi.mock("../ProviderLimits", () => ({ ProviderLimits: () =>
})) + +const NOW = Date.now() + +let n = 0 +const task = (overrides: Partial = {}): HistoryItem => ({ + id: `t${++n}`, + number: n, + ts: NOW - 60_000, + task: `Task ${n}`, + tokensIn: 1000, + tokensOut: 100, + totalCost: 0, + workspace: "/ws/a", + mode: "code", + ...overrides, +}) + +const priced = (cost: number, overrides: Partial = {}) => + task({ + totalCost: cost, + usageByModel: [ + { + apiProvider: providerIdentifiers.anthropic, + modelId: "claude-sonnet-5", + requests: 1, + tokensIn: 1000, + tokensOut: 100, + cost, + }, + ], + ...overrides, + }) + +const copilot = (overrides: Partial = {}) => + task({ + usageByModel: [ + { + apiProvider: providerIdentifiers.githubCopilot, + modelId: "claude-opus-5.5", + requests: 1, + tokensIn: 1000, + tokensOut: 100, + cost: 0, + }, + ], + ...overrides, + }) + +describe("UsageSettings", () => { + beforeEach(() => { + post.mockClear() + state.taskHistory = [] + state.cwd = "/ws/a" + }) + + it("always renders the provider limits section", () => { + render() + expect(screen.getByTestId("provider-limits-stub")).toBeTruthy() + }) + + it("shows an empty state with no tasks", () => { + render() + expect(screen.getByTestId("usage-empty")).toBeTruthy() + expect(screen.queryByTestId("usage-stats")).toBeNull() + expect(screen.queryByTestId("usage-export-csv")).toBeNull() + }) + + describe("when a provider reports a price", () => { + beforeEach(() => { + state.taskHistory = [priced(1.25), priced(0.5)] + }) + + it("shows cost first and tokens second", () => { + render() + const stats = screen.getByTestId("usage-stats") + expect(stats.textContent).toContain("$1.75") + expect(stats.textContent).toContain("2.2") // 2 tasks x 1,100 tokens (suffix is a translation key in tests) + expect(screen.queryByTestId("usage-no-pricing-note")).toBeNull() + }) + + it("charts and ranks by cost", () => { + render() + const top = screen.getByTestId("usage-top-tasks") + expect(top.textContent).toContain("$1.25") + expect(within(screen.getByTestId("usage-by-provider")).getByText("settings:usage.byProvider")).toBeTruthy() + }) + }) + + describe("when no provider reports a price (e.g. GitHub Copilot)", () => { + beforeEach(() => { + state.taskHistory = [copilot()] + }) + + it("never shows a dollar figure and explains why", () => { + render() + expect(screen.getByTestId("usage-stats").textContent).not.toContain("$") + expect(screen.getByTestId("usage-no-pricing-note")).toBeTruthy() + }) + + it("leads with tokens and the in/out split", () => { + render() + const stats = screen.getByTestId("usage-stats").textContent! + expect(stats).toContain("1.1") + expect(stats).toContain("settings:usage.stats.inOut".split(".").pop()!) + }) + }) + + describe("mixed priced and unpriced providers", () => { + beforeEach(() => { + state.taskHistory = [priced(1.5), copilot({ tokensIn: 16_000_000 })] + }) + + it("prioritises cost over tokens when any provider reports a price", () => { + render() + const stats = screen.getByTestId("usage-stats").textContent! + expect(stats).toContain("$1.50") + expect(screen.queryByTestId("usage-no-pricing-note")).toBeNull() + }) + + it("shows subscription providers as tokens with a no-price tag, not $0.00 · 0%", () => { + render() + const providers = screen.getByTestId("usage-by-provider") + const unpriced = within(providers).getByTestId("usage-unpriced") + expect(unpriced.textContent).toContain("noPrice") + expect(unpriced.textContent).not.toContain("$0.00") + // The unpriced row has no share: it shows "–", never "0%". + const row = unpriced.parentElement! + expect(row.textContent).toContain("–") + expect(row.textContent).not.toMatch(/(^|\D)0%/) + expect(row.querySelector("span[style*='width: 0%']")).not.toBeNull() + }) + + it("gives priced providers their cost and share", () => { + render() + const providers = screen.getByTestId("usage-by-provider") + expect(providers.textContent).toContain("$1.50") + expect(providers.textContent).toContain("100%") + }) + + it("shows an unpriced top task by tokens rather than $0.00", () => { + render() + expect(screen.getByTestId("usage-top-tasks").textContent).not.toContain("$0.00") + }) + }) + + describe("attribution", () => { + it("lists the provider and model that were recorded", () => { + state.taskHistory = [copilot()] + render() + expect(screen.getByTestId("usage-by-provider").textContent).toContain("GitHub Copilot") + expect(screen.getByTestId("usage-by-model").textContent).toContain("claude-opus-5.5") + }) + + it("labels tasks with no recorded provider as not recorded rather than guessing", () => { + state.taskHistory = [task()] + render() + expect(screen.getByTestId("usage-by-provider").textContent).toContain("notRecorded") + expect(screen.getByTestId("usage-by-model").textContent).toContain("notRecorded") + }) + + it("shows provider · model under each top task", () => { + state.taskHistory = [copilot()] + render() + expect(screen.getByTestId("usage-top-tasks").textContent).toContain("GitHub Copilot · claude-opus-5.5") + }) + + it("summarises modes on a single line", () => { + state.taskHistory = [priced(1, { mode: "code" }), priced(0.5, { mode: "architect" })] + render() + const line = screen.getByTestId("usage-by-mode").textContent! + expect(line).toContain("code $1.00") + expect(line).toContain("architect $0.50") + }) + }) + + describe("filters", () => { + it("defaults to this workspace and can widen to all", () => { + state.taskHistory = [priced(1), priced(2, { workspace: "/ws/other" })] + render() + expect(screen.getByTestId("usage-stats").textContent).toContain("$1.00") + expect(screen.getByTestId("usage-stats").textContent).not.toContain("$3.00") + }) + + it("changes the range", () => { + state.taskHistory = [priced(1), priced(5, { ts: NOW - 20 * 24 * 60 * 60 * 1000 })] + render() + // default 7 days → only the recent task + expect(screen.getByTestId("usage-stats").textContent).toContain("$1.00") + fireEvent.click(screen.getByTestId("usage-range-30d")) + expect(screen.getByTestId("usage-stats").textContent).toContain("$6.00") + fireEvent.click(screen.getByTestId("usage-range-today")) + expect(screen.getByTestId("usage-stats").textContent).toContain("$1.00") + }) + + it("includes everything for the all-time range", () => { + state.taskHistory = [priced(1), priced(5, { ts: NOW - 200 * 24 * 60 * 60 * 1000 })] + render() + fireEvent.click(screen.getByTestId("usage-range-all")) + expect(screen.getByTestId("usage-stats").textContent).toContain("$6.00") + }) + + it("marks the active range for assistive tech", () => { + render() + expect(screen.getByTestId("usage-range-7d").getAttribute("aria-checked")).toBe("true") + expect(screen.getByTestId("usage-range-30d").getAttribute("aria-checked")).toBe("false") + }) + }) + + describe("interactions", () => { + it("opens a task when its row is clicked", () => { + const t = priced(1) + state.taskHistory = [t] + render() + fireEvent.click(within(screen.getByTestId("usage-top-tasks")).getByRole("button")) + expect(post).toHaveBeenCalledWith({ type: "showTaskWithId", text: t.id }) + }) + + it("exports a CSV of the filtered range", () => { + state.taskHistory = [priced(1)] + const createObjectURL = vi.fn(() => "blob:x") + const revokeObjectURL = vi.fn() + Object.assign(URL, { createObjectURL, revokeObjectURL }) + const click = vi.spyOn(HTMLAnchorElement.prototype, "click").mockImplementation(() => {}) + + render() + fireEvent.click(screen.getByTestId("usage-export-csv")) + + expect(createObjectURL).toHaveBeenCalledTimes(1) + expect(click).toHaveBeenCalled() + expect(revokeObjectURL).toHaveBeenCalledWith("blob:x") + click.mockRestore() + }) + }) + + it("exposes the chart to assistive tech as a single labelled image", () => { + state.taskHistory = [priced(1)] + render() + const chart = screen.getByTestId("usage-daily-chart") + expect(chart.getAttribute("role")).toBe("img") + expect(chart.getAttribute("aria-label")).toBeTruthy() + }) + + it("draws one chart bar per day for a bounded range", () => { + state.taskHistory = [priced(1)] + render() + expect(screen.getByTestId("usage-daily-chart").children).toHaveLength(7) + }) +}) diff --git a/webview-ui/src/components/settings/__tests__/UsageSettings.visual.fixture.tsx b/webview-ui/src/components/settings/__tests__/UsageSettings.visual.fixture.tsx new file mode 100644 index 0000000000..1dbb6e3c9c --- /dev/null +++ b/webview-ui/src/components/settings/__tests__/UsageSettings.visual.fixture.tsx @@ -0,0 +1,143 @@ +import { useEffect } from "react" + +import { providerIdentifiers, VsCodeLmModelsMessageType, type HistoryItem, type ProviderQuota } from "@roo-code/types" + +import { UsageSettings } from "../UsageSettings" +import { AppProviders } from "../../../../playwright/AppProviders" +import { vscode } from "@src/utils/vscode" + +/** Matches the clock the visual test pins, so the history and the "updated" label are stable. */ +export const USAGE_NOW = new Date("2026-06-01T12:00:00Z").getTime() +const DAY = 24 * 60 * 60 * 1000 +const WORKSPACE = "/work/project" + +const task = (n: number, daysAgo: number, overrides: Partial): HistoryItem => ({ + id: `usage-task-${n}`, + number: n, + ts: USAGE_NOW - daysAgo * DAY, + task: `Task ${n}`, + tokensIn: 0, + tokensOut: 0, + totalCost: 0, + workspace: WORKSPACE, + mode: "code", + ...overrides, +}) + +const used = (apiProvider: string, modelId: string, tokensIn: number, tokensOut: number, cost: number) => [ + { apiProvider, modelId, requests: 4, tokensIn, tokensOut, cost }, +] + +/** A week of mixed priced (Anthropic) and unpriced (Copilot) work. */ +const history: HistoryItem[] = [ + task(1, 0, { + task: "Add a loading spinner to the Save button", + tokensIn: 52_000, + tokensOut: 4_100, + totalCost: 1.84, + cacheReads: 31_000, + usageByModel: used(providerIdentifiers.anthropic, "claude-sonnet-5", 52_000, 4_100, 1.84), + }), + task(2, 1, { + task: "Refactor the auth middleware", + tokensIn: 91_000, + tokensOut: 8_800, + totalCost: 3.27, + cacheReads: 60_000, + mode: "architect", + usageByModel: used(providerIdentifiers.anthropic, "claude-sonnet-5", 91_000, 8_800, 3.27), + }), + task(3, 2, { + task: "Write unit tests for the billing service", + tokensIn: 210_000, + tokensOut: 15_000, + totalCost: 0, + usageByModel: used(providerIdentifiers.githubCopilot, "gpt-5", 210_000, 15_000, 0), + }), + task(4, 4, { + task: "Investigate the flaky checkout test", + tokensIn: 34_000, + tokensOut: 2_900, + totalCost: 0.61, + mode: "debug", + usageByModel: used(providerIdentifiers.anthropic, "claude-haiku-5", 34_000, 2_900, 0.61), + }), +] + +const healthyQuotas: ProviderQuota[] = [ + { + providerId: providerIdentifiers.githubCopilot, + ok: true, + plan: "business", + fetchedAt: USAGE_NOW, + windows: [ + { + id: "premium", + valueLabel: "39,389 / 140,000 used", + usedPercent: 28, + resetAt: new Date("2026-07-01T00:00:00Z").getTime(), + }, + ], + }, + { + providerId: providerIdentifiers.deepseek, + ok: true, + fetchedAt: USAGE_NOW, + windows: [{ id: "balance", valueLabel: "$4.25 left" }], + }, +] + +const degradedQuotas: ProviderQuota[] = [ + { + providerId: providerIdentifiers.githubCopilot, + ok: false, + reason: "signedOut", + fetchedAt: USAGE_NOW, + }, + { providerId: providerIdentifiers.openrouter, ok: false, reason: "noKey", fetchedAt: USAGE_NOW }, + { providerId: providerIdentifiers.deepseek, ok: false, reason: "error", message: "HTTP 500", fetchedAt: USAGE_NOW }, +] + +/** Plays the extension host: answers the component's quota request, echoing its request id. */ +function FakeHost({ quotas }: { quotas: ProviderQuota[] }) { + useEffect(() => { + const original = vscode.postMessage.bind(vscode) + vscode.postMessage = ((message: { type: string; requestId?: string }) => { + if (message.type === VsCodeLmModelsMessageType.requestProviderQuotas) { + queueMicrotask(() => + window.dispatchEvent( + new MessageEvent("message", { + data: { + type: VsCodeLmModelsMessageType.providerQuotas, + providerQuotas: quotas, + requestId: message.requestId, + }, + }), + ), + ) + return + } + return original(message as never) + }) as typeof vscode.postMessage + return () => { + vscode.postMessage = original as typeof vscode.postMessage + } + }, [quotas]) + return null +} + +export type UsageStoryVariant = "populated" | "degraded" | "empty" + +export function UsageSettingsStory({ variant = "populated" }: { variant?: UsageStoryVariant }) { + const quotas = variant === "degraded" ? degradedQuotas : variant === "empty" ? [] : healthyQuotas + return ( + + +
+ +
+
+ ) +} diff --git a/webview-ui/src/components/settings/__tests__/UsageSettings.visual.tsx b/webview-ui/src/components/settings/__tests__/UsageSettings.visual.tsx new file mode 100644 index 0000000000..5b227ac29c --- /dev/null +++ b/webview-ui/src/components/settings/__tests__/UsageSettings.visual.tsx @@ -0,0 +1,59 @@ +import { expect, test } from "../../../../playwright/coverage-fixture" +import { expectBoundedLayout } from "../../../../playwright/layout-contracts" +import { mountedStory } from "../../../../playwright/mounted-story" +import { applyVisualTheme, visualThemes } from "../../../../playwright/themes" + +const NOW = new Date("2026-06-01T12:00:00Z") + +for (const theme of visualThemes) { + test(`renders the Usage tab with provider limits and history in the VS Code ${theme.name} theme`, async ({ + mount, + page, + }) => { + await page.clock.setFixedTime(NOW) + const component = mountedStory(await mount("usage-settings")) + await applyVisualTheme(page, theme) + const story = component.getByTestId("usage-story") + + // Limits arrive from the (fake) host; wait for them so the screenshot is the settled state. + await expect(story.getByTestId(`provider-limit-github-copilot`)).toBeVisible() + await expect(story.getByTestId("usage-stats")).toBeVisible() + await expect(story.getByTestId("usage-daily-chart")).toBeVisible() + + await expect(story).toHaveScreenshot(`usage-settings-${theme.name}.png`) + const exportButton = story.getByTestId("usage-export-csv") + await expectBoundedLayout(page, story, { focusedControl: exportButton }) + }) +} + +test("shows quiet statuses for provider limits that cannot be read, and keeps the history", async ({ mount, page }) => { + await page.clock.setFixedTime(NOW) + const component = mountedStory(await mount("usage-settings-degraded")) + await applyVisualTheme(page, visualThemes[0]) + const story = component.getByTestId("usage-story") + + await expect(story.getByTestId("provider-limit-github-copilot")).toBeVisible() + await expect(story.getByTestId("provider-limit-openrouter")).toBeVisible() + await expect(story.getByTestId("provider-limit-deepseek")).toBeVisible() + // No bars for providers that report nothing, but the usage history is unaffected. + await expect(story.locator("[role=progressbar]")).toHaveCount(0) + await expect(story.getByTestId("usage-stats")).toBeVisible() + + await expect(story).toHaveScreenshot("usage-settings-degraded.png") +}) + +test("shows the empty state, and hides the limits section when no provider has a usage API", async ({ + mount, + page, +}) => { + await page.clock.setFixedTime(NOW) + const component = mountedStory(await mount("usage-settings-empty")) + await applyVisualTheme(page, visualThemes[0]) + const story = component.getByTestId("usage-story") + + await expect(story.getByTestId("usage-empty")).toBeVisible() + await expect(story.getByTestId("provider-limits")).toHaveCount(0) + await expect(story.getByTestId("usage-export-csv")).toHaveCount(0) + + await expect(story).toHaveScreenshot("usage-settings-empty.png") +}) diff --git a/webview-ui/src/i18n/locales/ca/settings.json b/webview-ui/src/i18n/locales/ca/settings.json index d39d8edd6a..bb82add8fc 100644 --- a/webview-ui/src/i18n/locales/ca/settings.json +++ b/webview-ui/src/i18n/locales/ca/settings.json @@ -42,7 +42,8 @@ "language": "Idioma", "about": "Sobre Zoo Code", "skills": "Skills", - "rules": "Regles" + "rules": "Regles", + "usage": "Ús" }, "about": { "bugReport": { @@ -1233,5 +1234,56 @@ "descriptionTooLong": "La descripció ha de tenir com a màxim 1024 caràcters" }, "footer": "Crea les teves pròpies skills amb el mode Skill Writer, disponible al Modes Marketplace." + }, + "usage": { + "description": "Tokens i cost de l'historial de tasques de Zoo Code en aquesta màquina.", + "range": { + "label": "Interval de temps", + "today": "Avui", + "7d": "7 dies", + "30d": "30 dies", + "all": "Tot el temps" + }, + "scope": { + "label": "Mostra", + "workspace": "Aquest espai de treball", + "all": "Tots els espais de treball" + }, + "empty": "No hi ha tasques en aquest interval de temps.", + "stats": { + "cost": "cost", + "tokens": "tokens", + "tasks": "tasques", + "cacheHit": "{{percent}}% de la memòria cau", + "inOut": "{{input}} d'entrada · {{output}} de sortida", + "models": "models" + }, + "dailyCost": "Cost diari", + "byMode": "Per mode", + "topTasks": "Tasques més cares", + "disclaimer": "Els costos són estimacions de l'historial de tasques i poden diferir de la factura del teu proveïdor.", + "exportCsv": "Exporta CSV", + "noPricingNote": "Alguns proveïdors (p. ex. GitHub Copilot) facturen per subscripció i no informen d'un preu per tasca, per això aquest historial es mostra en tokens. Consulta els límits dels proveïdors a dalt per als crèdits.", + "dailyTokens": "Tokens diaris", + "topTasksTokens": "Tasques més grans", + "byProvider": "Per proveïdor", + "history": "Historial d'ús", + "limits": { + "title": "Límits dels proveïdors", + "refresh": "Actualitza", + "updated": "Actualitzat {{time}}", + "loading": "Comprovant els proveïdors connectats…", + "resets": "Es restableix {{date}}", + "signedOut": "No has iniciat sessió", + "noCopilot": "Sense quota de Copilot", + "noKey": "Clau d'API absent o no vàlida", + "unsupported": "URL base personalitzada — no comprovat", + "error": "No s'ha pogut carregar" + }, + "byModel": "Per model", + "notRecorded": "No registrat", + "noPrice": "sense preu", + "tokensShort": "tok", + "chartLabel": "{{metric}}, total {{total}}" } } diff --git a/webview-ui/src/i18n/locales/de/settings.json b/webview-ui/src/i18n/locales/de/settings.json index 983db1df5d..7b2ba025ce 100644 --- a/webview-ui/src/i18n/locales/de/settings.json +++ b/webview-ui/src/i18n/locales/de/settings.json @@ -42,7 +42,8 @@ "language": "Sprache", "about": "Über Zoo Code", "skills": "Skills", - "rules": "Regeln" + "rules": "Regeln", + "usage": "Nutzung" }, "about": { "bugReport": { @@ -1233,5 +1234,56 @@ "descriptionTooLong": "Beschreibung muss 1024 Zeichen oder weniger sein" }, "footer": "Erstelle deine eigenen Skills mit dem Skill Writer Modus, verfügbar im Modes Marketplace." + }, + "usage": { + "description": "Tokens und Kosten aus deinem Zoo-Code-Aufgabenverlauf auf diesem Rechner.", + "range": { + "label": "Zeitraum", + "today": "Heute", + "7d": "7 Tage", + "30d": "30 Tage", + "all": "Gesamter Zeitraum" + }, + "scope": { + "label": "Anzeigen", + "workspace": "Dieser Workspace", + "all": "Alle Workspaces" + }, + "empty": "Keine Aufgaben in diesem Zeitraum.", + "stats": { + "cost": "Kosten", + "tokens": "Tokens", + "tasks": "Aufgaben", + "cacheHit": "{{percent}} % aus dem Cache", + "inOut": "{{input}} ein · {{output}} aus", + "models": "Modelle" + }, + "dailyCost": "Tägliche Kosten", + "byMode": "Nach Modus", + "topTasks": "Teuerste Aufgaben", + "disclaimer": "Die Kosten sind Schätzungen aus dem Aufgabenverlauf und können von der Rechnung deines Anbieters abweichen.", + "exportCsv": "CSV exportieren", + "noPricingNote": "Einige Anbieter (z. B. GitHub Copilot) rechnen per Abonnement ab und melden keinen Preis pro Aufgabe, daher wird dieser Verlauf in Tokens angezeigt. Credits findest du oben unter Anbieterlimits.", + "dailyTokens": "Tägliche Tokens", + "topTasksTokens": "Größte Aufgaben", + "byProvider": "Nach Anbieter", + "history": "Nutzungsverlauf", + "limits": { + "title": "Anbieterlimits", + "refresh": "Aktualisieren", + "updated": "Aktualisiert {{time}}", + "loading": "Verbundene Anbieter werden geprüft…", + "resets": "Zurücksetzung {{date}}", + "signedOut": "Nicht angemeldet", + "noCopilot": "Kein Copilot-Kontingent", + "noKey": "API-Schlüssel fehlt oder ist ungültig", + "unsupported": "Benutzerdefinierte Basis-URL – nicht geprüft", + "error": "Konnte nicht geladen werden" + }, + "byModel": "Nach Modell", + "notRecorded": "Nicht erfasst", + "noPrice": "kein Preis", + "tokensShort": "Tok.", + "chartLabel": "{{metric}}, insgesamt {{total}}" } } diff --git a/webview-ui/src/i18n/locales/en/settings.json b/webview-ui/src/i18n/locales/en/settings.json index ea924ce79e..ad2a3f87cf 100644 --- a/webview-ui/src/i18n/locales/en/settings.json +++ b/webview-ui/src/i18n/locales/en/settings.json @@ -42,7 +42,8 @@ "ui": "UI", "experimental": "Experimental", "language": "Language", - "about": "About Zoo Code" + "about": "About Zoo Code", + "usage": "Usage" }, "about": { "bugReport": { @@ -1233,5 +1234,56 @@ "output": "Output", "cacheReads": "Cache reads" } + }, + "usage": { + "description": "Tokens and cost from your Zoo Code task history on this machine.", + "range": { + "label": "Time range", + "today": "Today", + "7d": "7 days", + "30d": "30 days", + "all": "All time" + }, + "scope": { + "label": "Show", + "workspace": "This workspace", + "all": "All workspaces" + }, + "empty": "No tasks in this time range.", + "stats": { + "cost": "cost", + "tokens": "tokens", + "tasks": "tasks", + "cacheHit": "{{percent}}% from cache", + "inOut": "{{input}} in · {{output}} out", + "models": "models" + }, + "dailyCost": "Daily cost", + "byMode": "By mode", + "topTasks": "Most expensive tasks", + "disclaimer": "Costs are estimates from task history and may differ from your provider's bill.", + "exportCsv": "Export CSV", + "noPricingNote": "Some providers (e.g. GitHub Copilot) bill by subscription and don't report a per-task price, so this history is shown in tokens. See Provider limits above for credits.", + "dailyTokens": "Daily tokens", + "topTasksTokens": "Largest tasks", + "byProvider": "By provider", + "history": "Usage history", + "limits": { + "title": "Provider limits", + "refresh": "Refresh", + "updated": "Updated {{time}}", + "loading": "Checking connected providers…", + "resets": "Resets {{date}}", + "signedOut": "Not signed in", + "noCopilot": "No Copilot quota", + "noKey": "API key missing or invalid", + "unsupported": "Custom base URL — not checked", + "error": "Couldn't load" + }, + "byModel": "By model", + "notRecorded": "Not recorded", + "noPrice": "no price", + "tokensShort": "tok", + "chartLabel": "{{metric}}, total {{total}}" } } diff --git a/webview-ui/src/i18n/locales/es/settings.json b/webview-ui/src/i18n/locales/es/settings.json index 57612bf3e5..474a5c2437 100644 --- a/webview-ui/src/i18n/locales/es/settings.json +++ b/webview-ui/src/i18n/locales/es/settings.json @@ -42,7 +42,8 @@ "language": "Idioma", "about": "Acerca de Zoo Code", "skills": "Skills", - "rules": "Reglas" + "rules": "Reglas", + "usage": "Uso" }, "about": { "bugReport": { @@ -1233,5 +1234,56 @@ "descriptionTooLong": "La descripción debe tener como máximo 1024 caracteres" }, "footer": "Crea tus propias skills con el modo Skill Writer, disponible en el Modes Marketplace." + }, + "usage": { + "description": "Tokens y coste del historial de tareas de Zoo Code en este equipo.", + "range": { + "label": "Intervalo de tiempo", + "today": "Hoy", + "7d": "7 días", + "30d": "30 días", + "all": "Todo el tiempo" + }, + "scope": { + "label": "Mostrar", + "workspace": "Este espacio de trabajo", + "all": "Todos los espacios de trabajo" + }, + "empty": "No hay tareas en este intervalo de tiempo.", + "stats": { + "cost": "coste", + "tokens": "tokens", + "tasks": "tareas", + "cacheHit": "{{percent}} % desde la caché", + "inOut": "{{input}} de entrada · {{output}} de salida", + "models": "modelos" + }, + "dailyCost": "Coste diario", + "byMode": "Por modo", + "topTasks": "Tareas más caras", + "disclaimer": "Los costes son estimaciones del historial de tareas y pueden diferir de la factura de tu proveedor.", + "exportCsv": "Exportar CSV", + "noPricingNote": "Algunos proveedores (p. ej. GitHub Copilot) facturan por suscripción y no informan de un precio por tarea, por lo que este historial se muestra en tokens. Consulta los límites de los proveedores arriba para ver los créditos.", + "dailyTokens": "Tokens diarios", + "topTasksTokens": "Tareas más grandes", + "byProvider": "Por proveedor", + "history": "Historial de uso", + "limits": { + "title": "Límites de los proveedores", + "refresh": "Actualizar", + "updated": "Actualizado {{time}}", + "loading": "Comprobando los proveedores conectados…", + "resets": "Se restablece {{date}}", + "signedOut": "Sesión no iniciada", + "noCopilot": "Sin cuota de Copilot", + "noKey": "Falta la clave de API o no es válida", + "unsupported": "URL base personalizada: no comprobado", + "error": "No se pudo cargar" + }, + "byModel": "Por modelo", + "notRecorded": "No registrado", + "noPrice": "sin precio", + "tokensShort": "tok", + "chartLabel": "{{metric}}, total {{total}}" } } diff --git a/webview-ui/src/i18n/locales/fr/settings.json b/webview-ui/src/i18n/locales/fr/settings.json index a91a5137d3..2a8fe1e993 100644 --- a/webview-ui/src/i18n/locales/fr/settings.json +++ b/webview-ui/src/i18n/locales/fr/settings.json @@ -42,7 +42,8 @@ "language": "Langue", "about": "À propos de Zoo Code", "skills": "Skills", - "rules": "Règles" + "rules": "Règles", + "usage": "Utilisation" }, "about": { "bugReport": { @@ -1233,5 +1234,56 @@ "descriptionTooLong": "La description doit contenir au maximum 1024 caractères" }, "footer": "Créez vos propres skills avec le mode Skill Writer, disponible dans le Modes Marketplace." + }, + "usage": { + "description": "Tokens et coût de l'historique des tâches de Zoo Code sur cette machine.", + "range": { + "label": "Période", + "today": "Aujourd'hui", + "7d": "7 jours", + "30d": "30 jours", + "all": "Tout" + }, + "scope": { + "label": "Afficher", + "workspace": "Cet espace de travail", + "all": "Tous les espaces de travail" + }, + "empty": "Aucune tâche sur cette période.", + "stats": { + "cost": "coût", + "tokens": "tokens", + "tasks": "tâches", + "cacheHit": "{{percent}} % depuis le cache", + "inOut": "{{input}} en entrée · {{output}} en sortie", + "models": "modèles" + }, + "dailyCost": "Coût quotidien", + "byMode": "Par mode", + "topTasks": "Tâches les plus coûteuses", + "disclaimer": "Les coûts sont des estimations issues de l'historique des tâches et peuvent différer de la facture de votre fournisseur.", + "exportCsv": "Exporter en CSV", + "noPricingNote": "Certains fournisseurs (p. ex. GitHub Copilot) facturent par abonnement et ne communiquent pas de prix par tâche ; cet historique est donc affiché en tokens. Consultez les limites des fournisseurs ci-dessus pour les crédits.", + "dailyTokens": "Tokens quotidiens", + "topTasksTokens": "Plus grosses tâches", + "byProvider": "Par fournisseur", + "history": "Historique d'utilisation", + "limits": { + "title": "Limites des fournisseurs", + "refresh": "Actualiser", + "updated": "Mis à jour {{time}}", + "loading": "Vérification des fournisseurs connectés…", + "resets": "Réinitialisation {{date}}", + "signedOut": "Non connecté", + "noCopilot": "Aucun quota Copilot", + "noKey": "Clé API manquante ou invalide", + "unsupported": "URL de base personnalisée — non vérifiée", + "error": "Impossible de charger" + }, + "byModel": "Par modèle", + "notRecorded": "Non enregistré", + "noPrice": "sans prix", + "tokensShort": "tok", + "chartLabel": "{{metric}}, total {{total}}" } } diff --git a/webview-ui/src/i18n/locales/hi/settings.json b/webview-ui/src/i18n/locales/hi/settings.json index bc6e973623..738875d3b4 100644 --- a/webview-ui/src/i18n/locales/hi/settings.json +++ b/webview-ui/src/i18n/locales/hi/settings.json @@ -42,7 +42,8 @@ "language": "भाषा", "about": "परिचय", "skills": "Skills", - "rules": "नियम" + "rules": "नियम", + "usage": "उपयोग" }, "about": { "bugReport": { @@ -1233,5 +1234,56 @@ "descriptionTooLong": "विवरण 1024 वर्णों से अधिक नहीं होना चाहिए" }, "footer": "Skill Writer मोड के साथ अपने स्वयं के Skills बनाएं, Modes Marketplace में उपलब्ध।" + }, + "usage": { + "description": "इस मशीन पर आपके Zoo Code टास्क इतिहास से टोकन और लागत।", + "range": { + "label": "समय सीमा", + "today": "आज", + "7d": "7 दिन", + "30d": "30 दिन", + "all": "सभी समय" + }, + "scope": { + "label": "दिखाएँ", + "workspace": "यह वर्कस्पेस", + "all": "सभी वर्कस्पेस" + }, + "empty": "इस समय सीमा में कोई टास्क नहीं।", + "stats": { + "cost": "लागत", + "tokens": "टोकन", + "tasks": "टास्क", + "cacheHit": "{{percent}}% कैश से", + "inOut": "{{input}} इनपुट · {{output}} आउटपुट", + "models": "मॉडल" + }, + "dailyCost": "दैनिक लागत", + "byMode": "मोड के अनुसार", + "topTasks": "सबसे महंगे टास्क", + "disclaimer": "लागत टास्क इतिहास से अनुमान हैं और आपके प्रदाता के बिल से भिन्न हो सकती हैं।", + "exportCsv": "CSV निर्यात करें", + "noPricingNote": "कुछ प्रदाता (जैसे GitHub Copilot) सदस्यता के आधार पर बिल करते हैं और प्रति-टास्क मूल्य नहीं बताते, इसलिए यह इतिहास टोकन में दिखाया गया है। क्रेडिट के लिए ऊपर प्रदाता सीमाएँ देखें।", + "dailyTokens": "दैनिक टोकन", + "topTasksTokens": "सबसे बड़े टास्क", + "byProvider": "प्रदाता के अनुसार", + "history": "उपयोग इतिहास", + "limits": { + "title": "प्रदाता सीमाएँ", + "refresh": "रीफ़्रेश करें", + "updated": "{{time}} को अपडेट किया गया", + "loading": "कनेक्टेड प्रदाताओं की जाँच हो रही है…", + "resets": "{{date}} को रीसेट होगा", + "signedOut": "साइन इन नहीं है", + "noCopilot": "कोई Copilot कोटा नहीं", + "noKey": "API कुंजी अनुपलब्ध या अमान्य", + "unsupported": "कस्टम बेस URL — जाँच नहीं की गई", + "error": "लोड नहीं हो सका" + }, + "byModel": "मॉडल के अनुसार", + "notRecorded": "दर्ज नहीं", + "noPrice": "कोई मूल्य नहीं", + "tokensShort": "टोकन", + "chartLabel": "{{metric}}, कुल {{total}}" } } diff --git a/webview-ui/src/i18n/locales/id/settings.json b/webview-ui/src/i18n/locales/id/settings.json index 3ed57f373e..c929956917 100644 --- a/webview-ui/src/i18n/locales/id/settings.json +++ b/webview-ui/src/i18n/locales/id/settings.json @@ -42,7 +42,8 @@ "language": "Bahasa", "about": "Tentang Zoo Code", "skills": "Skills", - "rules": "Aturan" + "rules": "Aturan", + "usage": "Penggunaan" }, "about": { "bugReport": { @@ -1233,5 +1234,56 @@ "descriptionTooLong": "Deskripsi harus 1024 karakter atau kurang" }, "footer": "Buat skills Anda sendiri dengan mode Skill Writer, tersedia di Modes Marketplace." + }, + "usage": { + "description": "Token dan biaya dari riwayat tugas Zoo Code Anda di mesin ini.", + "range": { + "label": "Rentang waktu", + "today": "Hari ini", + "7d": "7 hari", + "30d": "30 hari", + "all": "Sepanjang waktu" + }, + "scope": { + "label": "Tampilkan", + "workspace": "Workspace ini", + "all": "Semua workspace" + }, + "empty": "Tidak ada tugas dalam rentang waktu ini.", + "stats": { + "cost": "biaya", + "tokens": "token", + "tasks": "tugas", + "cacheHit": "{{percent}}% dari cache", + "inOut": "{{input}} masuk · {{output}} keluar", + "models": "model" + }, + "dailyCost": "Biaya harian", + "byMode": "Menurut mode", + "topTasks": "Tugas termahal", + "disclaimer": "Biaya adalah perkiraan dari riwayat tugas dan bisa berbeda dari tagihan penyedia Anda.", + "exportCsv": "Ekspor CSV", + "noPricingNote": "Beberapa penyedia (mis. GitHub Copilot) menagih berdasarkan langganan dan tidak melaporkan harga per tugas, sehingga riwayat ini ditampilkan dalam token. Lihat Batas penyedia di atas untuk kredit.", + "dailyTokens": "Token harian", + "topTasksTokens": "Tugas terbesar", + "byProvider": "Menurut penyedia", + "history": "Riwayat penggunaan", + "limits": { + "title": "Batas penyedia", + "refresh": "Segarkan", + "updated": "Diperbarui {{time}}", + "loading": "Memeriksa penyedia yang terhubung…", + "resets": "Diatur ulang {{date}}", + "signedOut": "Belum masuk", + "noCopilot": "Tidak ada kuota Copilot", + "noKey": "Kunci API hilang atau tidak valid", + "unsupported": "URL dasar kustom — tidak diperiksa", + "error": "Tidak dapat dimuat" + }, + "byModel": "Menurut model", + "notRecorded": "Tidak dicatat", + "noPrice": "tanpa harga", + "tokensShort": "tok", + "chartLabel": "{{metric}}, total {{total}}" } } diff --git a/webview-ui/src/i18n/locales/it/settings.json b/webview-ui/src/i18n/locales/it/settings.json index b708304e63..46a62a2ed7 100644 --- a/webview-ui/src/i18n/locales/it/settings.json +++ b/webview-ui/src/i18n/locales/it/settings.json @@ -42,7 +42,8 @@ "language": "Lingua", "about": "Informazioni su Zoo Code", "skills": "Skills", - "rules": "Regole" + "rules": "Regole", + "usage": "Utilizzo" }, "about": { "bugReport": { @@ -1233,5 +1234,56 @@ "descriptionTooLong": "La descrizione deve essere di massimo 1024 caratteri" }, "footer": "Crea le tue skill con la modalità Skill Writer, disponibile in Modes Marketplace." + }, + "usage": { + "description": "Token e costi dalla cronologia delle attività di Zoo Code su questo computer.", + "range": { + "label": "Intervallo di tempo", + "today": "Oggi", + "7d": "7 giorni", + "30d": "30 giorni", + "all": "Sempre" + }, + "scope": { + "label": "Mostra", + "workspace": "Questo workspace", + "all": "Tutti i workspace" + }, + "empty": "Nessuna attività in questo intervallo di tempo.", + "stats": { + "cost": "costo", + "tokens": "token", + "tasks": "attività", + "cacheHit": "{{percent}}% dalla cache", + "inOut": "{{input}} in ingresso · {{output}} in uscita", + "models": "modelli" + }, + "dailyCost": "Costo giornaliero", + "byMode": "Per modalità", + "topTasks": "Attività più costose", + "disclaimer": "I costi sono stime basate sulla cronologia delle attività e possono differire dalla fattura del tuo provider.", + "exportCsv": "Esporta CSV", + "noPricingNote": "Alcuni provider (es. GitHub Copilot) fatturano tramite abbonamento e non riportano un prezzo per attività, quindi questa cronologia è mostrata in token. Vedi i limiti dei provider sopra per i crediti.", + "dailyTokens": "Token giornalieri", + "topTasksTokens": "Attività più grandi", + "byProvider": "Per provider", + "history": "Cronologia di utilizzo", + "limits": { + "title": "Limiti dei provider", + "refresh": "Aggiorna", + "updated": "Aggiornato {{time}}", + "loading": "Controllo dei provider collegati…", + "resets": "Si reimposta {{date}}", + "signedOut": "Accesso non effettuato", + "noCopilot": "Nessuna quota Copilot", + "noKey": "Chiave API mancante o non valida", + "unsupported": "URL di base personalizzato — non controllato", + "error": "Impossibile caricare" + }, + "byModel": "Per modello", + "notRecorded": "Non registrato", + "noPrice": "senza prezzo", + "tokensShort": "tok", + "chartLabel": "{{metric}}, totale {{total}}" } } diff --git a/webview-ui/src/i18n/locales/ja/settings.json b/webview-ui/src/i18n/locales/ja/settings.json index f6959b50dc..8d3e18b157 100644 --- a/webview-ui/src/i18n/locales/ja/settings.json +++ b/webview-ui/src/i18n/locales/ja/settings.json @@ -42,7 +42,8 @@ "language": "言語", "about": "Zoo Codeについて", "skills": "Skills", - "rules": "ルール" + "rules": "ルール", + "usage": "使用状況" }, "about": { "bugReport": { @@ -1233,5 +1234,56 @@ "descriptionTooLong": "説明は1024文字以内である必要があります" }, "footer": "スキルライターモードで独自のスキルを作成します。モードマーケットプレイスで入手可能です。" + }, + "usage": { + "description": "このマシン上の Zoo Code のタスク履歴によるトークンとコスト。", + "range": { + "label": "期間", + "today": "今日", + "7d": "7日間", + "30d": "30日間", + "all": "全期間" + }, + "scope": { + "label": "表示", + "workspace": "このワークスペース", + "all": "すべてのワークスペース" + }, + "empty": "この期間にタスクはありません。", + "stats": { + "cost": "コスト", + "tokens": "トークン", + "tasks": "タスク", + "cacheHit": "{{percent}}% がキャッシュから", + "inOut": "入力 {{input}} · 出力 {{output}}", + "models": "モデル" + }, + "dailyCost": "日別コスト", + "byMode": "モード別", + "topTasks": "コストの高いタスク", + "disclaimer": "コストはタスク履歴からの推定値であり、プロバイダーの請求額と異なる場合があります。", + "exportCsv": "CSV をエクスポート", + "noPricingNote": "一部のプロバイダー(GitHub Copilot など)はサブスクリプション課金で、タスクごとの価格を報告しないため、この履歴はトークンで表示されます。クレジットについては上のプロバイダーの上限を参照してください。", + "dailyTokens": "日別トークン", + "topTasksTokens": "大きいタスク", + "byProvider": "プロバイダー別", + "history": "使用履歴", + "limits": { + "title": "プロバイダーの上限", + "refresh": "更新", + "updated": "{{time}} に更新", + "loading": "接続済みのプロバイダーを確認中…", + "resets": "{{date}} にリセット", + "signedOut": "サインインしていません", + "noCopilot": "Copilot のクォータなし", + "noKey": "API キーがないか無効です", + "unsupported": "カスタムベース URL — 確認していません", + "error": "読み込めませんでした" + }, + "byModel": "モデル別", + "notRecorded": "記録なし", + "noPrice": "価格なし", + "tokensShort": "トークン", + "chartLabel": "{{metric}}、合計 {{total}}" } } diff --git a/webview-ui/src/i18n/locales/ko/settings.json b/webview-ui/src/i18n/locales/ko/settings.json index 6cadbd8a3b..55adcdf557 100644 --- a/webview-ui/src/i18n/locales/ko/settings.json +++ b/webview-ui/src/i18n/locales/ko/settings.json @@ -42,7 +42,8 @@ "language": "언어", "about": "Zoo Code 정보", "skills": "Skills", - "rules": "규칙" + "rules": "규칙", + "usage": "사용량" }, "about": { "bugReport": { @@ -1233,5 +1234,56 @@ "descriptionTooLong": "설명은 1024자 이하여야 합니다" }, "footer": "스킬 작성자 모드로 자신만의 스킬을 만들 수 있습니다. 모드 마켓플레이스에서 사용 가능합니다." + }, + "usage": { + "description": "이 컴퓨터의 Zoo Code 작업 기록에서 집계한 토큰과 비용입니다.", + "range": { + "label": "기간", + "today": "오늘", + "7d": "7일", + "30d": "30일", + "all": "전체 기간" + }, + "scope": { + "label": "표시", + "workspace": "이 워크스페이스", + "all": "모든 워크스페이스" + }, + "empty": "이 기간에 작업이 없습니다.", + "stats": { + "cost": "비용", + "tokens": "토큰", + "tasks": "작업", + "cacheHit": "{{percent}}% 캐시에서", + "inOut": "입력 {{input}} · 출력 {{output}}", + "models": "모델" + }, + "dailyCost": "일별 비용", + "byMode": "모드별", + "topTasks": "비용이 큰 작업", + "disclaimer": "비용은 작업 기록을 기반으로 한 추정치이며 공급자의 청구서와 다를 수 있습니다.", + "exportCsv": "CSV 내보내기", + "noPricingNote": "일부 공급자(예: GitHub Copilot)는 구독 방식으로 청구하며 작업별 가격을 보고하지 않으므로 이 기록은 토큰으로 표시됩니다. 크레딧은 위의 공급자 한도를 확인하세요.", + "dailyTokens": "일별 토큰", + "topTasksTokens": "큰 작업", + "byProvider": "공급자별", + "history": "사용 기록", + "limits": { + "title": "공급자 한도", + "refresh": "새로 고침", + "updated": "{{time}}에 업데이트됨", + "loading": "연결된 공급자를 확인하는 중…", + "resets": "{{date}}에 초기화", + "signedOut": "로그인하지 않음", + "noCopilot": "Copilot 할당량 없음", + "noKey": "API 키가 없거나 올바르지 않음", + "unsupported": "사용자 지정 기본 URL — 확인하지 않음", + "error": "불러올 수 없음" + }, + "byModel": "모델별", + "notRecorded": "기록되지 않음", + "noPrice": "가격 없음", + "tokensShort": "토큰", + "chartLabel": "{{metric}}, 합계 {{total}}" } } diff --git a/webview-ui/src/i18n/locales/nl/settings.json b/webview-ui/src/i18n/locales/nl/settings.json index 992e9c53e0..c29cfc42b5 100644 --- a/webview-ui/src/i18n/locales/nl/settings.json +++ b/webview-ui/src/i18n/locales/nl/settings.json @@ -42,7 +42,8 @@ "language": "Taal", "about": "Over Zoo Code", "skills": "Skills", - "rules": "Regels" + "rules": "Regels", + "usage": "Gebruik" }, "about": { "bugReport": { @@ -1233,5 +1234,56 @@ "descriptionTooLong": "Beschrijving moet maximaal 1024 tekens zijn" }, "footer": "Maak je eigen skills met de Skill Writer modus, beschikbaar in de Modes Marketplace." + }, + "usage": { + "description": "Tokens en kosten uit je Zoo Code-takengeschiedenis op deze machine.", + "range": { + "label": "Tijdsbereik", + "today": "Vandaag", + "7d": "7 dagen", + "30d": "30 dagen", + "all": "Alle tijd" + }, + "scope": { + "label": "Tonen", + "workspace": "Deze werkruimte", + "all": "Alle werkruimtes" + }, + "empty": "Geen taken in dit tijdsbereik.", + "stats": { + "cost": "kosten", + "tokens": "tokens", + "tasks": "taken", + "cacheHit": "{{percent}}% uit cache", + "inOut": "{{input}} in · {{output}} uit", + "models": "modellen" + }, + "dailyCost": "Dagelijkse kosten", + "byMode": "Per modus", + "topTasks": "Duurste taken", + "disclaimer": "Kosten zijn schattingen op basis van de takengeschiedenis en kunnen afwijken van de rekening van je provider.", + "exportCsv": "CSV exporteren", + "noPricingNote": "Sommige providers (bijv. GitHub Copilot) factureren via een abonnement en melden geen prijs per taak, daarom wordt deze geschiedenis in tokens getoond. Zie hierboven de providerlimieten voor credits.", + "dailyTokens": "Dagelijkse tokens", + "topTasksTokens": "Grootste taken", + "byProvider": "Per provider", + "history": "Gebruiksgeschiedenis", + "limits": { + "title": "Providerlimieten", + "refresh": "Vernieuwen", + "updated": "Bijgewerkt {{time}}", + "loading": "Verbonden providers controleren…", + "resets": "Reset {{date}}", + "signedOut": "Niet aangemeld", + "noCopilot": "Geen Copilot-quotum", + "noKey": "API-sleutel ontbreekt of is ongeldig", + "unsupported": "Aangepaste basis-URL — niet gecontroleerd", + "error": "Kon niet laden" + }, + "byModel": "Per model", + "notRecorded": "Niet vastgelegd", + "noPrice": "geen prijs", + "tokensShort": "tok", + "chartLabel": "{{metric}}, totaal {{total}}" } } diff --git a/webview-ui/src/i18n/locales/pl/settings.json b/webview-ui/src/i18n/locales/pl/settings.json index 459675b0e1..f65684ed5b 100644 --- a/webview-ui/src/i18n/locales/pl/settings.json +++ b/webview-ui/src/i18n/locales/pl/settings.json @@ -42,7 +42,8 @@ "language": "Język", "about": "O Zoo Code", "skills": "Skills", - "rules": "Reguły" + "rules": "Reguły", + "usage": "Użycie" }, "about": { "bugReport": { @@ -1233,5 +1234,56 @@ "descriptionTooLong": "Opis musi mieć maksymalnie 1024 znaki" }, "footer": "Twórz własne umiejętności za pomocą trybu Skill Writer, dostępnego w Modes Marketplace." + }, + "usage": { + "description": "Tokeny i koszty z historii zadań Zoo Code na tym komputerze.", + "range": { + "label": "Zakres czasu", + "today": "Dzisiaj", + "7d": "7 dni", + "30d": "30 dni", + "all": "Cały czas" + }, + "scope": { + "label": "Pokaż", + "workspace": "Ten obszar roboczy", + "all": "Wszystkie obszary robocze" + }, + "empty": "Brak zadań w tym zakresie czasu.", + "stats": { + "cost": "koszt", + "tokens": "tokeny", + "tasks": "zadania", + "cacheHit": "{{percent}}% z pamięci podręcznej", + "inOut": "{{input}} wejście · {{output}} wyjście", + "models": "modele" + }, + "dailyCost": "Koszt dzienny", + "byMode": "Według trybu", + "topTasks": "Najdroższe zadania", + "disclaimer": "Koszty są szacunkami z historii zadań i mogą różnić się od rachunku od dostawcy.", + "exportCsv": "Eksportuj CSV", + "noPricingNote": "Niektórzy dostawcy (np. GitHub Copilot) rozliczają się w ramach subskrypcji i nie podają ceny za zadanie, dlatego ta historia jest pokazana w tokenach. Kredyty znajdziesz wyżej w limitach dostawców.", + "dailyTokens": "Tokeny dzienne", + "topTasksTokens": "Największe zadania", + "byProvider": "Według dostawcy", + "history": "Historia użycia", + "limits": { + "title": "Limity dostawców", + "refresh": "Odśwież", + "updated": "Zaktualizowano {{time}}", + "loading": "Sprawdzanie połączonych dostawców…", + "resets": "Reset {{date}}", + "signedOut": "Nie zalogowano", + "noCopilot": "Brak limitu Copilot", + "noKey": "Brak klucza API lub jest nieprawidłowy", + "unsupported": "Niestandardowy bazowy URL — nie sprawdzono", + "error": "Nie udało się wczytać" + }, + "byModel": "Według modelu", + "notRecorded": "Nie zapisano", + "noPrice": "brak ceny", + "tokensShort": "tok.", + "chartLabel": "{{metric}}, łącznie {{total}}" } } diff --git a/webview-ui/src/i18n/locales/pt-BR/settings.json b/webview-ui/src/i18n/locales/pt-BR/settings.json index 500babaaa8..ad47efbbe9 100644 --- a/webview-ui/src/i18n/locales/pt-BR/settings.json +++ b/webview-ui/src/i18n/locales/pt-BR/settings.json @@ -42,7 +42,8 @@ "language": "Idioma", "about": "Sobre", "skills": "Skills", - "rules": "Regras" + "rules": "Regras", + "usage": "Uso" }, "about": { "bugReport": { @@ -1233,5 +1234,56 @@ "descriptionTooLong": "A descrição deve ter no máximo 1024 caracteres" }, "footer": "Crie suas próprias skills com o modo Skill Writer, disponível em Modes Marketplace." + }, + "usage": { + "description": "Tokens e custo do histórico de tarefas do Zoo Code nesta máquina.", + "range": { + "label": "Intervalo de tempo", + "today": "Hoje", + "7d": "7 dias", + "30d": "30 dias", + "all": "Todo o período" + }, + "scope": { + "label": "Mostrar", + "workspace": "Este espaço de trabalho", + "all": "Todos os espaços de trabalho" + }, + "empty": "Nenhuma tarefa neste intervalo de tempo.", + "stats": { + "cost": "custo", + "tokens": "tokens", + "tasks": "tarefas", + "cacheHit": "{{percent}}% do cache", + "inOut": "{{input}} de entrada · {{output}} de saída", + "models": "modelos" + }, + "dailyCost": "Custo diário", + "byMode": "Por modo", + "topTasks": "Tarefas mais caras", + "disclaimer": "Os custos são estimativas do histórico de tarefas e podem diferir da fatura do seu provedor.", + "exportCsv": "Exportar CSV", + "noPricingNote": "Alguns provedores (ex.: GitHub Copilot) cobram por assinatura e não informam um preço por tarefa, por isso este histórico é mostrado em tokens. Veja os limites dos provedores acima para os créditos.", + "dailyTokens": "Tokens diários", + "topTasksTokens": "Maiores tarefas", + "byProvider": "Por provedor", + "history": "Histórico de uso", + "limits": { + "title": "Limites dos provedores", + "refresh": "Atualizar", + "updated": "Atualizado {{time}}", + "loading": "Verificando os provedores conectados…", + "resets": "Redefine {{date}}", + "signedOut": "Sem login", + "noCopilot": "Sem cota do Copilot", + "noKey": "Chave de API ausente ou inválida", + "unsupported": "URL base personalizada — não verificada", + "error": "Não foi possível carregar" + }, + "byModel": "Por modelo", + "notRecorded": "Não registrado", + "noPrice": "sem preço", + "tokensShort": "tok", + "chartLabel": "{{metric}}, total {{total}}" } } diff --git a/webview-ui/src/i18n/locales/ru/settings.json b/webview-ui/src/i18n/locales/ru/settings.json index 053ff0684d..a2ff469dbb 100644 --- a/webview-ui/src/i18n/locales/ru/settings.json +++ b/webview-ui/src/i18n/locales/ru/settings.json @@ -42,7 +42,8 @@ "language": "Язык", "about": "О Zoo Code", "skills": "Skills", - "rules": "Правила" + "rules": "Правила", + "usage": "Использование" }, "about": { "bugReport": { @@ -1233,5 +1234,56 @@ "descriptionTooLong": "Описание должно быть не более 1024 символов" }, "footer": "Создавайте собственные навыки с режимом Skill Writer, доступным в Modes Marketplace." + }, + "usage": { + "description": "Токены и стоимость по истории задач Zoo Code на этом компьютере.", + "range": { + "label": "Период", + "today": "Сегодня", + "7d": "7 дней", + "30d": "30 дней", + "all": "Всё время" + }, + "scope": { + "label": "Показать", + "workspace": "Эта рабочая область", + "all": "Все рабочие области" + }, + "empty": "В этом периоде нет задач.", + "stats": { + "cost": "стоимость", + "tokens": "токены", + "tasks": "задачи", + "cacheHit": "{{percent}}% из кэша", + "inOut": "{{input}} вход · {{output}} выход", + "models": "модели" + }, + "dailyCost": "Стоимость по дням", + "byMode": "По режимам", + "topTasks": "Самые дорогие задачи", + "disclaimer": "Стоимость — это оценка по истории задач, она может отличаться от счёта вашего провайдера.", + "exportCsv": "Экспорт в CSV", + "noPricingNote": "Некоторые провайдеры (например, GitHub Copilot) тарифицируют по подписке и не сообщают цену за задачу, поэтому эта история показана в токенах. Кредиты смотрите выше в лимитах провайдеров.", + "dailyTokens": "Токены по дням", + "topTasksTokens": "Самые крупные задачи", + "byProvider": "По провайдерам", + "history": "История использования", + "limits": { + "title": "Лимиты провайдеров", + "refresh": "Обновить", + "updated": "Обновлено {{time}}", + "loading": "Проверка подключённых провайдеров…", + "resets": "Сброс {{date}}", + "signedOut": "Вход не выполнен", + "noCopilot": "Нет квоты Copilot", + "noKey": "Ключ API отсутствует или недействителен", + "unsupported": "Пользовательский базовый URL — не проверено", + "error": "Не удалось загрузить" + }, + "byModel": "По моделям", + "notRecorded": "Не записано", + "noPrice": "без цены", + "tokensShort": "ток.", + "chartLabel": "{{metric}}, всего {{total}}" } } diff --git a/webview-ui/src/i18n/locales/tr/settings.json b/webview-ui/src/i18n/locales/tr/settings.json index b37f28d44d..257cafd6ec 100644 --- a/webview-ui/src/i18n/locales/tr/settings.json +++ b/webview-ui/src/i18n/locales/tr/settings.json @@ -42,7 +42,8 @@ "language": "Dil", "about": "Zoo Code Hakkında", "skills": "Skills", - "rules": "Kurallar" + "rules": "Kurallar", + "usage": "Kullanım" }, "about": { "bugReport": { @@ -1233,5 +1234,56 @@ "descriptionTooLong": "Açıklama en fazla 1024 karakter olmalıdır" }, "footer": "Skill Writer modu ile kendi becerilerinizi oluşturun. Modes Marketplace'de mevcut." + }, + "usage": { + "description": "Bu makinedeki Zoo Code görev geçmişinizden token ve maliyet.", + "range": { + "label": "Zaman aralığı", + "today": "Bugün", + "7d": "7 gün", + "30d": "30 gün", + "all": "Tüm zamanlar" + }, + "scope": { + "label": "Göster", + "workspace": "Bu çalışma alanı", + "all": "Tüm çalışma alanları" + }, + "empty": "Bu zaman aralığında görev yok.", + "stats": { + "cost": "maliyet", + "tokens": "token", + "tasks": "görev", + "cacheHit": "%{{percent}} önbellekten", + "inOut": "{{input}} giriş · {{output}} çıkış", + "models": "model" + }, + "dailyCost": "Günlük maliyet", + "byMode": "Moda göre", + "topTasks": "En pahalı görevler", + "disclaimer": "Maliyetler görev geçmişinden yapılan tahminlerdir ve sağlayıcınızın faturasından farklı olabilir.", + "exportCsv": "CSV olarak dışa aktar", + "noPricingNote": "Bazı sağlayıcılar (ör. GitHub Copilot) abonelik üzerinden faturalandırır ve görev başına fiyat bildirmez; bu yüzden bu geçmiş token cinsinden gösterilir. Krediler için yukarıdaki sağlayıcı limitlerine bakın.", + "dailyTokens": "Günlük token", + "topTasksTokens": "En büyük görevler", + "byProvider": "Sağlayıcıya göre", + "history": "Kullanım geçmişi", + "limits": { + "title": "Sağlayıcı limitleri", + "refresh": "Yenile", + "updated": "Güncellendi: {{time}}", + "loading": "Bağlı sağlayıcılar kontrol ediliyor…", + "resets": "Sıfırlanma: {{date}}", + "signedOut": "Oturum açılmadı", + "noCopilot": "Copilot kotası yok", + "noKey": "API anahtarı eksik veya geçersiz", + "unsupported": "Özel temel URL — kontrol edilmedi", + "error": "Yüklenemedi" + }, + "byModel": "Modele göre", + "notRecorded": "Kaydedilmedi", + "noPrice": "fiyat yok", + "tokensShort": "tok", + "chartLabel": "{{metric}}, toplam {{total}}" } } diff --git a/webview-ui/src/i18n/locales/vi/settings.json b/webview-ui/src/i18n/locales/vi/settings.json index 94843217ae..55df86904e 100644 --- a/webview-ui/src/i18n/locales/vi/settings.json +++ b/webview-ui/src/i18n/locales/vi/settings.json @@ -42,7 +42,8 @@ "language": "Ngôn ngữ", "about": "Giới thiệu", "skills": "Skills", - "rules": "Quy tắc" + "rules": "Quy tắc", + "usage": "Mức sử dụng" }, "about": { "bugReport": { @@ -1233,5 +1234,56 @@ "descriptionTooLong": "Mô tả phải có tối đa 1024 ký tự" }, "footer": "Tạo các skill của riêng bạn với chế độ Skill Writer, có sẵn tại Modes Marketplace." + }, + "usage": { + "description": "Token và chi phí từ lịch sử nhiệm vụ Zoo Code của bạn trên máy này.", + "range": { + "label": "Khoảng thời gian", + "today": "Hôm nay", + "7d": "7 ngày", + "30d": "30 ngày", + "all": "Mọi lúc" + }, + "scope": { + "label": "Hiển thị", + "workspace": "Không gian làm việc này", + "all": "Tất cả không gian làm việc" + }, + "empty": "Không có nhiệm vụ nào trong khoảng thời gian này.", + "stats": { + "cost": "chi phí", + "tokens": "token", + "tasks": "nhiệm vụ", + "cacheHit": "{{percent}}% từ bộ nhớ đệm", + "inOut": "{{input}} vào · {{output}} ra", + "models": "mô hình" + }, + "dailyCost": "Chi phí hằng ngày", + "byMode": "Theo chế độ", + "topTasks": "Nhiệm vụ tốn kém nhất", + "disclaimer": "Chi phí là ước tính từ lịch sử nhiệm vụ và có thể khác với hóa đơn của nhà cung cấp.", + "exportCsv": "Xuất CSV", + "noPricingNote": "Một số nhà cung cấp (ví dụ GitHub Copilot) tính phí theo gói đăng ký và không báo cáo giá cho từng nhiệm vụ, nên lịch sử này được hiển thị bằng token. Xem Giới hạn nhà cung cấp ở trên để biết tín dụng.", + "dailyTokens": "Token hằng ngày", + "topTasksTokens": "Nhiệm vụ lớn nhất", + "byProvider": "Theo nhà cung cấp", + "history": "Lịch sử sử dụng", + "limits": { + "title": "Giới hạn nhà cung cấp", + "refresh": "Làm mới", + "updated": "Cập nhật {{time}}", + "loading": "Đang kiểm tra các nhà cung cấp đã kết nối…", + "resets": "Đặt lại {{date}}", + "signedOut": "Chưa đăng nhập", + "noCopilot": "Không có hạn mức Copilot", + "noKey": "Thiếu khóa API hoặc không hợp lệ", + "unsupported": "URL cơ sở tùy chỉnh — không kiểm tra", + "error": "Không thể tải" + }, + "byModel": "Theo mô hình", + "notRecorded": "Chưa ghi nhận", + "noPrice": "không có giá", + "tokensShort": "tok", + "chartLabel": "{{metric}}, tổng {{total}}" } } diff --git a/webview-ui/src/i18n/locales/zh-CN/settings.json b/webview-ui/src/i18n/locales/zh-CN/settings.json index 8be0fe1532..81cc7bd614 100644 --- a/webview-ui/src/i18n/locales/zh-CN/settings.json +++ b/webview-ui/src/i18n/locales/zh-CN/settings.json @@ -42,7 +42,8 @@ "language": "语言", "about": "关于 Zoo Code", "skills": "Skills", - "rules": "规则" + "rules": "规则", + "usage": "用量" }, "about": { "bugReport": { @@ -1233,5 +1234,56 @@ "descriptionTooLong": "描述不得超过1024个字符" }, "footer": "使用技能编写器模式创建您自己的技能,可在 模式市集 中获得。" + }, + "usage": { + "description": "来自此设备上 Zoo Code 任务历史的 Token 和费用。", + "range": { + "label": "时间范围", + "today": "今天", + "7d": "7 天", + "30d": "30 天", + "all": "全部时间" + }, + "scope": { + "label": "显示", + "workspace": "此工作区", + "all": "所有工作区" + }, + "empty": "此时间范围内没有任务。", + "stats": { + "cost": "费用", + "tokens": "Token", + "tasks": "任务", + "cacheHit": "{{percent}}% 来自缓存", + "inOut": "输入 {{input}} · 输出 {{output}}", + "models": "模型" + }, + "dailyCost": "每日费用", + "byMode": "按模式", + "topTasks": "费用最高的任务", + "disclaimer": "费用为根据任务历史得出的估算值,可能与提供商的账单不同。", + "exportCsv": "导出 CSV", + "noPricingNote": "部分提供商(如 GitHub Copilot)按订阅计费,不报告每个任务的价格,因此此历史以 Token 显示。额度请参见上方的提供商限额。", + "dailyTokens": "每日 Token", + "topTasksTokens": "最大的任务", + "byProvider": "按提供商", + "history": "用量历史", + "limits": { + "title": "提供商限额", + "refresh": "刷新", + "updated": "更新于 {{time}}", + "loading": "正在检查已连接的提供商…", + "resets": "重置于 {{date}}", + "signedOut": "未登录", + "noCopilot": "无 Copilot 配额", + "noKey": "API 密钥缺失或无效", + "unsupported": "自定义基础 URL — 未检查", + "error": "无法加载" + }, + "byModel": "按模型", + "notRecorded": "未记录", + "noPrice": "无价格", + "tokensShort": "Token", + "chartLabel": "{{metric}},共 {{total}}" } } diff --git a/webview-ui/src/i18n/locales/zh-TW/settings.json b/webview-ui/src/i18n/locales/zh-TW/settings.json index 65eb5c67a5..75b4d2aba6 100644 --- a/webview-ui/src/i18n/locales/zh-TW/settings.json +++ b/webview-ui/src/i18n/locales/zh-TW/settings.json @@ -42,7 +42,8 @@ "language": "語言", "about": "關於 Zoo Code", "skills": "Skills", - "rules": "規則" + "rules": "規則", + "usage": "用量" }, "about": { "bugReport": { @@ -1233,5 +1234,56 @@ "descriptionTooLong": "說明不得超過1024個字元" }, "footer": "使用技能編寫器模式建立您自己的技能,可在 模式市集 中取得。" + }, + "usage": { + "description": "來自此裝置上 Zoo Code 任務歷史的 Token 與費用。", + "range": { + "label": "時間範圍", + "today": "今天", + "7d": "7 天", + "30d": "30 天", + "all": "全部時間" + }, + "scope": { + "label": "顯示", + "workspace": "此工作區", + "all": "所有工作區" + }, + "empty": "此時間範圍內沒有任務。", + "stats": { + "cost": "費用", + "tokens": "Token", + "tasks": "任務", + "cacheHit": "{{percent}}% 來自快取", + "inOut": "輸入 {{input}} · 輸出 {{output}}", + "models": "模型" + }, + "dailyCost": "每日費用", + "byMode": "依模式", + "topTasks": "費用最高的任務", + "disclaimer": "費用為根據任務歷史得出的估算值,可能與供應商的帳單不同。", + "exportCsv": "匯出 CSV", + "noPricingNote": "部分供應商(如 GitHub Copilot)按訂閱計費,不回報每個任務的價格,因此此歷史以 Token 顯示。額度請參閱上方的供應商限額。", + "dailyTokens": "每日 Token", + "topTasksTokens": "最大的任務", + "byProvider": "依供應商", + "history": "用量歷史", + "limits": { + "title": "供應商限額", + "refresh": "重新整理", + "updated": "更新於 {{time}}", + "loading": "正在檢查已連線的供應商…", + "resets": "重設於 {{date}}", + "signedOut": "未登入", + "noCopilot": "無 Copilot 配額", + "noKey": "API 金鑰遺失或無效", + "unsupported": "自訂基底 URL — 未檢查", + "error": "無法載入" + }, + "byModel": "依模型", + "notRecorded": "未記錄", + "noPrice": "無價格", + "tokensShort": "Token", + "chartLabel": "{{metric}},共 {{total}}" } } diff --git a/webview-ui/src/utils/__tests__/providerLabel.spec.ts b/webview-ui/src/utils/__tests__/providerLabel.spec.ts new file mode 100644 index 0000000000..e2401a4f45 --- /dev/null +++ b/webview-ui/src/utils/__tests__/providerLabel.spec.ts @@ -0,0 +1,14 @@ +import { providerIdentifiers } from "@roo-code/types" + +import { providerLabel } from "../providerLabel" + +describe("providerLabel", () => { + it("returns the display name for a known provider", () => { + expect(providerLabel(providerIdentifiers.githubCopilot)).toBe("GitHub Copilot") + expect(providerLabel(providerIdentifiers.anthropic)).toBe("Anthropic") + }) + + it("falls back to the raw id for unknown or retired providers", () => { + expect(providerLabel("some-retired-provider")).toBe("some-retired-provider") + }) +}) diff --git a/webview-ui/src/utils/__tests__/usage.dst.spec.ts b/webview-ui/src/utils/__tests__/usage.dst.spec.ts new file mode 100644 index 0000000000..4b2a58c027 --- /dev/null +++ b/webview-ui/src/utils/__tests__/usage.dst.spec.ts @@ -0,0 +1,109 @@ +import { afterAll, describe, expect, it } from "vitest" + +import type { HistoryItem } from "@roo-code/types" + +import { rangeStart, summarizeUsage, usageToCsv } from "../usage" + +// These cases only mean something in a zone that observes DST: in UTC a fixed 24h step and a calendar +// day are the same thing, so the old implementation would pass. The zone is pinned here, and every test +// asserts that its fixture really crosses an offset change, so a runner that ignores TZ fails loudly +// instead of passing vacuously. +// +// The zone must be set before any fixture below is computed (they are built at collection time), so it +// is set at module level rather than in beforeAll. +const previousZone = process.env.TZ +process.env.TZ = "America/New_York" + +afterAll(() => { + if (previousZone === undefined) delete process.env.TZ + else process.env.TZ = previousZone +}) + +const at = (y: number, m: number, d: number, h = 0, min = 0) => new Date(y, m, d, h, min).getTime() +const offsetOf = (ts: number) => new Date(ts).getTimezoneOffset() + +let counter = 0 +const item = (overrides: Partial): HistoryItem => ({ + id: `dst${++counter}`, + number: counter, + ts: 0, + task: `task ${counter}`, + tokensIn: 100, + tokensOut: 0, + totalCost: 1, + workspace: "/ws/a", + ...overrides, +}) + +// US clocks go forward on 2026-03-08 (a 23h day) and back on 2026-11-01 (a 25h day). +const SPRING = { now: at(2026, 2, 11, 15), firstDay: at(2026, 2, 5), lastDay: at(2026, 2, 11) } +const FALL = { now: at(2026, 10, 4, 15), firstDay: at(2026, 9, 29), lastDay: at(2026, 10, 4) } + +describe.each([ + ["spring forward (23h day)", SPRING], + ["fall back (25h day)", FALL], +])("a 7-day window across %s", (_name, w) => { + it("really crosses a clock change in this runner", () => { + expect(offsetOf(w.firstDay)).not.toBe(offsetOf(w.lastDay)) + }) + + it("starts at local midnight", () => { + const start = rangeStart("7d", w.now)! + expect(start).toBe(w.firstDay) + expect(new Date(start).getHours()).toBe(0) + expect(new Date(start).getMinutes()).toBe(0) + }) + + it("charts one bar per calendar day, ending on today", () => { + const { daily } = summarizeUsage([item({ ts: w.now - 60_000 })], { range: "7d", now: w.now }) + + expect(daily).toHaveLength(7) + // Every bar is a local midnight, on consecutive calendar dates, with no day skipped or repeated. + const dates = daily.map((d) => new Date(d.day)) + dates.forEach((d) => expect([d.getHours(), d.getMinutes()]).toEqual([0, 0])) + dates.slice(1).forEach((d, i) => { + const prev = new Date(dates[i]) + prev.setDate(prev.getDate() + 1) + expect(d.getTime()).toBe(prev.getTime()) + }) + expect(daily[0].day).toBe(w.firstDay) + expect(daily.at(-1)!.day).toBe(w.lastDay) + }) + + it("puts today's spend in today's bar, so the bars add up to the total", () => { + const history = [ + item({ ts: w.firstDay + 30 * 60_000, totalCost: 2 }), + item({ ts: w.lastDay + 30 * 60_000, totalCost: 3 }), + ] + const s = summarizeUsage(history, { range: "7d", now: w.now }) + expect(s.totalCost).toBe(5) + expect(s.daily.at(-1)).toMatchObject({ day: w.lastDay, cost: 3 }) + expect(s.daily[0]).toMatchObject({ day: w.firstDay, cost: 2 }) + expect(s.daily.reduce((sum, d) => sum + d.cost, 0)).toBe(s.totalCost) + }) + + it("includes a task from the first minute of the first day, and excludes the minute before it", () => { + const csv = usageToCsv( + [ + item({ task: "first-minute", ts: w.firstDay + 60_000 }), + item({ task: "just-before", ts: w.firstDay - 60_000 }), + ], + { range: "7d", now: w.now }, + ) + expect(csv).toContain("first-minute") + expect(csv).not.toContain("just-before") + }) +}) + +describe("a 30-day window across a clock change", () => { + it("charts 30 consecutive local days ending on today", () => { + const now = at(2026, 10, 3, 15) + expect(offsetOf(rangeStart("30d", now)!)).not.toBe(offsetOf(now)) + + const { daily } = summarizeUsage([item({ ts: now - 60_000 })], { range: "30d", now }) + expect(daily).toHaveLength(30) + expect(daily.at(-1)!.day).toBe(at(2026, 10, 3)) + daily.forEach((d) => expect(new Date(d.day).getHours()).toBe(0)) + expect(new Set(daily.map((d) => d.day)).size).toBe(30) + }) +}) diff --git a/webview-ui/src/utils/__tests__/usage.spec.ts b/webview-ui/src/utils/__tests__/usage.spec.ts new file mode 100644 index 0000000000..7f5b8435b3 --- /dev/null +++ b/webview-ui/src/utils/__tests__/usage.spec.ts @@ -0,0 +1,484 @@ +import { providerIdentifiers, type HistoryItem } from "@roo-code/types" + +import { + UNRECORDED, + bucketView, + metricTotal, + modelIdFromKey, + pickMetric, + primaryUsage, + rangeStart, + summarizeUsage, + usageToCsv, +} from "../usage" + +// Fixed "now": Wed 2026-10-14 15:00 local time. +const NOW = new Date(2026, 9, 14, 15, 0, 0).getTime() +const DAY = 24 * 60 * 60 * 1000 + +let counter = 0 +const item = (overrides: Partial): HistoryItem => ({ + id: `t${++counter}`, + number: counter, + ts: NOW, + task: `task ${counter}`, + tokensIn: 0, + tokensOut: 0, + totalCost: 0, + workspace: "/ws/a", + ...overrides, +}) + +describe("rangeStart", () => { + it("returns local midnight for today", () => { + expect(rangeStart("today", NOW)).toBe(new Date(2026, 9, 14).getTime()) + }) + + it("includes today in 7d / 30d windows", () => { + expect(rangeStart("7d", NOW)).toBe(new Date(2026, 9, 8).getTime()) + expect(rangeStart("30d", NOW)).toBe(new Date(2026, 8, 15).getTime()) + }) + + it("is unbounded for all", () => { + expect(rangeStart("all", NOW)).toBeUndefined() + }) +}) + +describe("summarizeUsage", () => { + const used = (apiProvider: string, modelId: string, tokensIn: number, tokensOut: number, cost: number) => [ + { apiProvider, modelId, requests: 1, tokensIn, tokensOut, cost }, + ] + const history = [ + item({ + totalCost: 1.5, + tokensIn: 1000, + tokensOut: 200, + cacheReads: 3000, + mode: "code", + usageByModel: used(providerIdentifiers.anthropic, "opus", 1000, 200, 1.5), + }), + item({ + totalCost: 0.5, + tokensIn: 500, + tokensOut: 100, + mode: "architect", + ts: NOW - DAY, + usageByModel: used(providerIdentifiers.githubCopilot, "gpt-5", 500, 100, 0.5), + }), + item({ + totalCost: 2, + tokensIn: 10, + tokensOut: 10, + mode: "code", + workspace: "/ws/b", + usageByModel: used(providerIdentifiers.anthropic, "opus", 10, 10, 2), + }), + // Outside 7d window + item({ + totalCost: 99, + mode: "code", + ts: NOW - 10 * DAY, + usageByModel: used(providerIdentifiers.anthropic, "opus", 0, 0, 99), + }), + ] + + it("totals only items inside the range", () => { + const s = summarizeUsage(history, { range: "7d", now: NOW }) + expect(s.taskCount).toBe(3) + expect(s.totalCost).toBeCloseTo(4) + expect(s.totalTokens).toBe(1000 + 200 + 500 + 100 + 20) + }) + + it("filters by workspace", () => { + const s = summarizeUsage(history, { range: "7d", now: NOW, workspace: "/ws/a" }) + expect(s.taskCount).toBe(2) + expect(s.totalCost).toBeCloseTo(2) + }) + + it("groups by recorded provider and by model, sorted by cost desc", () => { + const s = summarizeUsage(history, { range: "7d", now: NOW }) + expect(s.byProvider.map((b) => [b.key, b.tasks])).toEqual([ + [providerIdentifiers.anthropic, 2], + [providerIdentifiers.githubCopilot, 1], + ]) + expect(s.byProvider[0].cost).toBeCloseTo(3.5) + expect(s.byModel.map((b) => [modelIdFromKey(b.key), b.apiProvider])).toEqual([ + ["opus", providerIdentifiers.anthropic], + ["gpt-5", providerIdentifiers.githubCopilot], + ]) + expect(s.byMode.map((b) => b.key)).toEqual(["code", "architect"]) + }) + + it("REGRESSION: provider/model come from what was recorded, not from any current profile", () => { + // The bug: usage was attributed via the *currently selected* profile, so + // switching providers relabelled past Copilot work as the new provider. + // Aggregation now takes no profile information at all. + const copilotTask = item({ + tokensIn: 16_700_000, + tokensOut: 83_400, + usageByModel: used(providerIdentifiers.githubCopilot, "claude-opus-5.5", 16_700_000, 83_400, 0), + apiConfigName: "default", // the profile name is irrelevant to attribution + }) + const before = summarizeUsage([copilotTask], { range: "all", now: NOW }) + + // "Switch provider": same history, but the user's profile now points at Gemini. + const after = summarizeUsage([{ ...copilotTask, apiConfigName: "gemini-profile" }], { range: "all", now: NOW }) + + for (const s of [before, after]) { + expect(s.byProvider.map((b) => b.key)).toEqual([providerIdentifiers.githubCopilot]) + expect(modelIdFromKey(s.byModel[0].key)).toBe("claude-opus-5.5") + } + }) + + it("attributes a task that switched providers mid-way to each provider by its own tokens", () => { + const s = summarizeUsage( + [ + item({ + tokensIn: 400, + tokensOut: 0, + usageByModel: [ + { + apiProvider: providerIdentifiers.githubCopilot, + modelId: "claude-opus-5.5", + requests: 1, + tokensIn: 100, + tokensOut: 0, + cost: 0, + }, + { + apiProvider: providerIdentifiers.gemini, + modelId: "gemini-pro", + requests: 1, + tokensIn: 300, + tokensOut: 0, + cost: 0, + }, + ], + }), + ], + { range: "all", now: NOW }, + ) + expect(s.byProvider.map((b) => [b.key, b.tokens])).toEqual([ + [providerIdentifiers.gemini, 300], + [providerIdentifiers.githubCopilot, 100], + ]) + expect(s.byProvider.every((b) => b.tasks === 1)).toBe(true) + }) + + it("buckets tasks with no recorded provider/model as unrecorded instead of guessing", () => { + const s = summarizeUsage([item({ totalCost: 1, tokensIn: 10, tokensOut: 5 })], { range: "all", now: NOW }) + expect(s.byProvider.map((b) => b.key)).toEqual([UNRECORDED]) + expect(s.byModel.map((b) => b.key)).toEqual([UNRECORDED]) + expect(modelIdFromKey(UNRECORDED)).toBeUndefined() + expect(s.byMode[0].key).toBe("unknown") + }) + + it("computes cache hit rate over input-side tokens", () => { + const s = summarizeUsage(history, { range: "today", now: NOW }) + // today: tokensIn 1000 + 10, cacheReads 3000 + expect(s.cacheHitRate).toBeCloseTo(3000 / (1010 + 3000)) + }) + + it("produces a dense daily series for bounded ranges", () => { + const s = summarizeUsage(history, { range: "7d", now: NOW }) + expect(s.daily).toHaveLength(7) + expect(s.daily.at(-1)!.cost).toBeCloseTo(3.5) + expect(s.daily.at(-2)!.cost).toBeCloseTo(0.5) + expect(s.daily[0].cost).toBe(0) + }) + + it("returns top tasks by cost, limited", () => { + const s = summarizeUsage(history, { range: "all", now: NOW, topTaskLimit: 2 }) + expect(s.topTasks.map((t) => t.totalCost)).toEqual([99, 2]) + }) + + it("breaks cost ties by tokens so equal-priced tasks still rank meaningfully", () => { + const s = summarizeUsage( + [item({ id: "few", totalCost: 1, tokensIn: 10 }), item({ id: "many", totalCost: 1, tokensIn: 9_000 })], + { range: "all", now: NOW }, + ) + expect(s.topTasks.map((t) => t.id)).toEqual(["many", "few"]) + }) + + it("is safe on empty history", () => { + const s = summarizeUsage([], { range: "7d", now: NOW }) + expect(s.taskCount).toBe(0) + expect(s.totalCost).toBe(0) + expect(s.cacheHitRate).toBe(0) + }) + + it("tracks tokens per day alongside cost", () => { + const s = summarizeUsage(history, { range: "7d", now: NOW }) + expect(s.daily.at(-1)!.tokens).toBe(1000 + 200 + 20) + }) + + it("ranks zero-cost tasks by tokens (subscription providers)", () => { + const s = summarizeUsage([item({ id: "small", tokensIn: 10 }), item({ id: "big", tokensIn: 5_000_000 })], { + range: "all", + now: NOW, + }) + expect(s.topTasks.map((t) => t.id)).toEqual(["big", "small"]) + }) + + it("ignores non-finite costs", () => { + const s = summarizeUsage([item({ totalCost: NaN })], { range: "all", now: NOW }) + expect(s.totalCost).toBe(0) + }) +}) + +describe("mixed priced and unpriced providers", () => { + const mixed = () => { + const mk = (provider: string, model: string, tokens: number, cost: number) => + item({ + tokensIn: tokens, + tokensOut: 0, + totalCost: cost, + usageByModel: [ + { apiProvider: provider, modelId: model, requests: 1, tokensIn: tokens, tokensOut: 0, cost }, + ], + }) + return summarizeUsage( + [ + mk(providerIdentifiers.githubCopilot, "claude-opus-5.5", 16_000_000, 0), + mk(providerIdentifiers.anthropic, "claude-sonnet-5", 200_000, 1.2), + ], + { range: "all", now: NOW }, + ) + } + + it("prioritises cost as soon as any usage in the range is priced", () => { + expect(pickMetric(mixed())).toBe("cost") + }) + + it("flags each bucket as priced or not so subscription usage isn't shown as $0.00", () => { + const s = mixed() + const byKey = Object.fromEntries(s.byProvider.map((b) => [b.key, b])) + expect(byKey[providerIdentifiers.anthropic].priced).toBe(true) + expect(byKey[providerIdentifiers.githubCopilot].priced).toBe(false) + expect(s.byModel.find((b) => modelIdFromKey(b.key) === "claude-opus-5.5")!.priced).toBe(false) + }) + + it("keeps all-unpriced ranges on tokens and all-priced ranges on cost", () => { + const unpriced = summarizeUsage([item({ tokensIn: 5, usageByModel: [] })], { range: "all", now: NOW }) + expect(pickMetric(unpriced)).toBe("tokens") + }) +}) + +describe("bucketView", () => { + const priced = { cost: 3, tokens: 1000, priced: true } + const unpriced = { cost: 0, tokens: 16_000_000, priced: false } + + it("cost mode: a priced bucket is its cost and its share of total cost", () => { + expect(bucketView(priced, "cost", 12)).toEqual({ value: 3, unpriced: false, percent: 25 }) + }) + + it("cost mode: an unpriced bucket carries tokens, is flagged, and has no share (never 0%)", () => { + expect(bucketView(unpriced, "cost", 12)).toEqual({ value: 0, unpriced: true, percent: 0 }) + }) + + it("tokens mode: everything is tokens and nothing is flagged unpriced", () => { + expect(bucketView(unpriced, "tokens", 32_000_000)).toEqual({ value: 16_000_000, unpriced: false, percent: 50 }) + expect(bucketView(priced, "tokens", 2000)).toEqual({ value: 1000, unpriced: false, percent: 50 }) + }) + + it("guards division by zero", () => { + expect(bucketView(priced, "cost", 0).percent).toBe(0) + }) + + it("rounds shares to whole numbers", () => { + expect(bucketView({ cost: 1, tokens: 0, priced: true }, "cost", 3).percent).toBe(33) + }) +}) + +describe("metricTotal", () => { + it("selects the headline value for the metric", () => { + const s = { totalCost: 2.5, totalTokens: 900 } + expect(metricTotal(s, "cost")).toBe(2.5) + expect(metricTotal(s, "tokens")).toBe(900) + }) +}) + +describe("primaryUsage", () => { + it("returns the provider+model that used the most tokens", () => { + const task = item({ + usageByModel: [ + { apiProvider: "a", modelId: "small", requests: 1, tokensIn: 10, tokensOut: 0, cost: 0 }, + { apiProvider: "b", modelId: "big", requests: 1, tokensIn: 900, tokensOut: 0, cost: 0 }, + ], + }) + expect(primaryUsage(task)).toEqual({ apiProvider: "b", modelId: "big" }) + }) + + it("is undefined when nothing was recorded", () => { + expect(primaryUsage(item({}))).toBeUndefined() + expect( + primaryUsage(item({ usageByModel: [{ requests: 1, tokensIn: 1, tokensOut: 1, cost: 0 }] })), + ).toBeUndefined() + }) +}) + +describe("pickMetric", () => { + it("uses cost when any cost was recorded", () => { + expect(pickMetric({ totalCost: 0.01, totalTokens: 10 })).toBe("cost") + }) + + it("falls back to tokens when tokens exist but cost is zero (e.g. GitHub Copilot)", () => { + expect(pickMetric({ totalCost: 0, totalTokens: 6_200_000 })).toBe("tokens") + }) + + it("stays on cost when there is no usage at all", () => { + expect(pickMetric({ totalCost: 0, totalTokens: 0 })).toBe("cost") + }) +}) + +describe("modelIdFromKey", () => { + it("returns undefined for the unrecorded bucket, the id after the provider separator, or a bare key", () => { + expect(modelIdFromKey(UNRECORDED)).toBeUndefined() + expect(modelIdFromKey("anthropic\u0000claude-sonnet-5")).toBe("claude-sonnet-5") + expect(modelIdFromKey("plain-model")).toBe("plain-model") + }) +}) + +describe("usage attribution edge cases", () => { + const entry = (overrides: Record) => ({ + requests: 1, + tokensIn: 10, + tokensOut: 0, + cost: 0, + ...overrides, + }) + + it("keeps the first entry when two entries used the same number of tokens", () => { + const task = item({ + usageByModel: [ + entry({ apiProvider: "a", modelId: "first", tokensIn: 50 }), + entry({ apiProvider: "b", modelId: "second", tokensIn: 50 }), + ], + }) + expect(primaryUsage(task)).toEqual({ apiProvider: "a", modelId: "first" }) + }) + + it("buckets a model with no provider under an empty provider key, and a provider with no model as unrecorded", () => { + const s = summarizeUsage( + [ + item({ + totalCost: 1, + usageByModel: [entry({ modelId: "orphan", cost: 1 }), entry({ apiProvider: "p", cost: 0 })], + }), + ], + { range: "all", now: NOW }, + ) + expect(new Set(s.byModel.map((b) => modelIdFromKey(b.key)))).toEqual(new Set([undefined, "orphan"])) + expect(new Set(s.byProvider.map((b) => b.key))).toEqual(new Set([UNRECORDED, "p"])) + }) + + it("counts a task once per bucket even when several of its requests land in it", () => { + const s = summarizeUsage( + [ + item({ + usageByModel: [ + entry({ apiProvider: "p", modelId: "m", tokensIn: 1 }), + entry({ apiProvider: "p", modelId: "m", tokensIn: 2 }), + ], + }), + ], + { range: "all", now: NOW }, + ) + expect(s.byProvider[0].tasks).toBe(1) + expect(s.byModel[0].tasks).toBe(1) + expect(s.byProvider[0].tokens).toBe(3) + }) + + it("orders top tasks by cost, then by tokens, and treats missing numbers as zero", () => { + const cheapBig = item({ id: "cheap-big", totalCost: 1, tokensIn: 900, tokensOut: 100 }) + const cheapSmall = item({ id: "cheap-small", totalCost: 1, tokensIn: 10, tokensOut: 0 }) + const pricey = item({ id: "pricey", totalCost: 5, tokensIn: 1, tokensOut: 0 }) + const bare = (id: string) => + item({ id, totalCost: undefined as never, tokensIn: undefined as never, tokensOut: undefined as never }) + const s = summarizeUsage([cheapSmall, bare("bare-1"), cheapBig, pricey, bare("bare-2")], { + range: "all", + now: NOW, + }) + expect(s.topTasks.map((t) => t.id).slice(0, 3)).toEqual(["pricey", "cheap-big", "cheap-small"]) + expect( + s.topTasks + .map((t) => t.id) + .slice(3) + .sort(), + ).toEqual(["bare-1", "bare-2"]) + }) +}) + +describe("usageToCsv formula safety", () => { + it.each(['=HYPERLINK("http://x")', "+1+1", "-2+3", "@SUM(A1)", "\tcmd", "\rcmd"])( + "neutralises a cell that starts with %j", + (text) => { + const csv = usageToCsv([item({ task: text, mode: text })], { range: "all", now: NOW }) + const row = csv.split("\n")[1] + // Each text cell is quoted and prefixed with an apostrophe, so it cannot start with a trigger character. + expect(row).toMatch(/^[^,]+,"'[=+\-@\t\r]/) + expect(row).not.toMatch(/,"[=+\-@\t\r]/) + }, + ) + + it("leaves ordinary text and the numeric columns alone", () => { + const csv = usageToCsv([item({ task: "Fix the = sign", totalCost: 1.5, tokensIn: 10 })], { + range: "all", + now: NOW, + }) + const row = csv.split("\n")[1] + expect(row).toContain('"Fix the = sign"') + expect(row).not.toContain("'Fix") + expect(row.endsWith(",1.5000")).toBe(true) + }) +}) + +describe("usageToCsv", () => { + it("sorts oldest first and leaves provider, model and counters blank or zero when nothing was recorded", () => { + const csv = usageToCsv( + [ + item({ task: "later", ts: NOW }), + item({ + task: "earlier", + title: undefined, + ts: NOW - DAY, + tokensIn: undefined as never, + tokensOut: undefined as never, + totalCost: undefined as never, + mode: undefined, + }), + ], + { range: "all", now: NOW }, + ) + const lines = csv.split("\n") + expect(lines[1]).toContain("earlier") + expect(lines[1].endsWith(',"","","",0,0,0,0,0.0000')).toBe(true) + expect(lines[2]).toContain("later") + }) + + it("exports a row for a task with neither a title nor a task text", () => { + const csv = usageToCsv([item({ task: undefined as never, title: undefined })], { range: "all", now: NOW }) + expect(csv.split("\n")[1]).toContain(',"",') + }) + + it("filters to a workspace and ignores one that is not set", () => { + const history = [item({ task: "in", workspace: "/ws/a" }), item({ task: "out", workspace: "/ws/b" })] + expect(usageToCsv(history, { range: "all", now: NOW, workspace: "/ws/a" }).split("\n")).toHaveLength(2) + expect(usageToCsv(history, { range: "all", now: NOW }).split("\n")).toHaveLength(3) + }) + + it("escapes quotes and newlines and respects the range", () => { + const csv = usageToCsv( + [ + item({ task: 'say "hi"\nthen go', totalCost: 0.12345, mode: "code" }), + item({ task: "old", ts: NOW - 40 * DAY }), + ], + { range: "30d", now: NOW }, + ) + const lines = csv.split("\n") + expect(lines[0]).toBe("date,task,mode,provider,model,tokensIn,tokensOut,cacheReads,cacheWrites,cost") + expect(lines).toHaveLength(2) + expect(lines[1]).toContain('"say ""hi"" then go"') + expect(lines[1].endsWith(",0.1235")).toBe(true) + }) +}) diff --git a/webview-ui/src/utils/providerLabel.ts b/webview-ui/src/utils/providerLabel.ts new file mode 100644 index 0000000000..740e0aef02 --- /dev/null +++ b/webview-ui/src/utils/providerLabel.ts @@ -0,0 +1,6 @@ +import { PROVIDERS } from "@src/components/settings/constants" + +const LABELS = new Map(PROVIDERS.map((p) => [p.value, p.label])) + +/** Human label for a provider id, falling back to the id itself for unknown/retired providers. */ +export const providerLabel = (id: string): string => LABELS.get(id) ?? id diff --git a/webview-ui/src/utils/usage.ts b/webview-ui/src/utils/usage.ts new file mode 100644 index 0000000000..3659198f8d --- /dev/null +++ b/webview-ui/src/utils/usage.ts @@ -0,0 +1,340 @@ +import type { HistoryItem } from "@roo-code/types" + +/** + * Pure aggregation over locally persisted task history for the Usage tab. + * + * Notes on correctness: + * - `HistoryItem.totalCost` is a task's *own* spend; subtasks are separate + * history items. Summing every item therefore counts each dollar once. + * - Provider and model come from `HistoryItem.usageByModel`, recorded when each + * request was made. They are never derived from the *current* profile, so + * switching providers does not relabel past usage. Tasks created before this + * was recorded have no such data and are bucketed as `UNRECORDED`. + */ + +/** Bucket key for usage whose provider/model was not recorded (older tasks). */ +export const UNRECORDED = "__unrecorded__" + +export const USAGE_RANGES = ["today", "7d", "30d", "all"] as const +export type UsageRange = (typeof USAGE_RANGES)[number] + +export interface UsageBucket { + key: string + cost: number + tokens: number + /** Tasks that contributed to this bucket (a task using two models counts once in each). */ + tasks: number + /** For model buckets: the provider that served it (undefined when unrecorded). */ + apiProvider?: string + /** + * True when this bucket has any cost > 0. When the tab is showing cost, a bucket + * with `priced: false` (e.g. GitHub Copilot, billed by subscription) must not be + * shown as "$0.00 · 0%": it has no price, not zero spend. + */ + priced: boolean +} + +export interface DailyUsage { + /** Local-midnight timestamp of the day. */ + day: number + cost: number + tokens: number +} + +/** + * Which metric the Usage tab should chart. Subscription-backed providers + * (e.g. GitHub Copilot via the VS Code LM API) report no per-token price, so + * their tasks persist `totalCost: 0`. Charting cost would show flat zeros. + */ +export type UsageMetric = "cost" | "tokens" + +export function pickMetric(summary: Pick): UsageMetric { + return summary.totalCost > 0 || summary.totalTokens === 0 ? "cost" : "tokens" +} + +/** + * What a breakdown row (provider / model / mode) should display for a bucket. + * + * Pure so the "priced vs unpriced" rule lives in one tested place instead of + * being re-derived by the component: + * - tokens mode: value = tokens + * - cost mode, priced bucket: value = cost, share of total cost + * - cost mode, unpriced: a subscription bucket (e.g. Copilot) has no price, + * not zero spend → value = tokens, `unpriced: true`, + * and no share (so no "$0.00 · 0%") + */ +export interface BucketView { + /** Numeric value the bar/share is computed from. */ + value: number + /** True when the bucket should be shown as tokens with a "no price" tag and no share. */ + unpriced: boolean + /** Whole-number share of the total, 0 for unpriced rows. */ + percent: number +} + +export function bucketView( + bucket: Pick, + metric: UsageMetric, + total: number, +): BucketView { + const unpriced = metric === "cost" && !bucket.priced + const value = metric === "cost" ? bucket.cost : bucket.tokens + return { value, unpriced, percent: unpriced || total <= 0 ? 0 : Math.round((value / total) * 100) } +} + +/** The metric's headline value for a summary (cost or tokens). */ +export function metricTotal(summary: Pick, metric: UsageMetric): number { + return metric === "cost" ? summary.totalCost : summary.totalTokens +} + +export interface UsageSummary { + totalCost: number + tokensIn: number + tokensOut: number + cacheReads: number + cacheWrites: number + totalTokens: number + /** Share of input-side tokens served from cache, 0–1. */ + cacheHitRate: number + taskCount: number + byProvider: UsageBucket[] + byModel: UsageBucket[] + byMode: UsageBucket[] + daily: DailyUsage[] + topTasks: HistoryItem[] +} + +export interface UsageOptions { + range: UsageRange + /** When set, only tasks from this workspace are included. */ + workspace?: string + now?: number + topTaskLimit?: number +} + +/** + * The provider+model that did most of a task's work (by tokens), for labelling + * a task row. Undefined when nothing was recorded. + */ +export function primaryUsage(item: HistoryItem): { apiProvider?: string; modelId?: string } | undefined { + const entries = item.usageByModel?.filter((e) => e.apiProvider || e.modelId) + if (!entries?.length) return undefined + const top = entries.reduce((a, b) => (b.tokensIn + b.tokensOut > a.tokensIn + a.tokensOut ? b : a)) + return { apiProvider: top.apiProvider, modelId: top.modelId } +} + +function startOfLocalDay(ts: number): number { + const d = new Date(ts) + d.setHours(0, 0, 0, 0) + return d.getTime() +} + +/** Local midnight `days` calendar days before `ts` (not `days * 24h`, which is off by an hour across a DST change). */ +function startOfLocalDayMinus(ts: number, days: number): number { + const d = new Date(ts) + d.setHours(0, 0, 0, 0) + d.setDate(d.getDate() - days) + return d.getTime() +} + +/** Inclusive lower bound for a range, or `undefined` for "all". */ +export function rangeStart(range: UsageRange, now: number): number | undefined { + switch (range) { + case "today": + return startOfLocalDay(now) + case "7d": + return startOfLocalDayMinus(now, 6) + case "30d": + return startOfLocalDayMinus(now, 29) + default: + return undefined + } +} + +function addTo( + map: Map, + key: string, + cost: number, + tokens: number, + countedForTask: Set, + extra?: Partial, +) { + const bucket = map.get(key) ?? { key, cost: 0, tokens: 0, tasks: 0, priced: false, ...extra } + bucket.cost += cost + bucket.tokens += tokens + if (cost > 0) bucket.priced = true + // Count the task once per bucket even if several of its requests land here. + if (!countedForTask.has(key)) { + countedForTask.add(key) + bucket.tasks += 1 + } + map.set(key, bucket) +} + +const byCostDesc = (a: UsageBucket, b: UsageBucket) => b.cost - a.cost || b.tokens - a.tokens + +export function summarizeUsage(history: HistoryItem[], options: UsageOptions): UsageSummary { + const now = options.now ?? Date.now() + const start = rangeStart(options.range, now) + const topTaskLimit = options.topTaskLimit ?? 5 + + const items = history.filter( + (item) => + typeof item.ts === "number" && + (start === undefined || item.ts >= start) && + (!options.workspace || item.workspace === options.workspace), + ) + + const providers = new Map() + const models = new Map() + const modes = new Map() + const daily = new Map() + + let totalCost = 0 + let tokensIn = 0 + let tokensOut = 0 + let cacheReads = 0 + let cacheWrites = 0 + + for (const item of items) { + const cost = Number.isFinite(item.totalCost) ? item.totalCost : 0 + const tIn = item.tokensIn || 0 + const tOut = item.tokensOut || 0 + const tokens = tIn + tOut + + totalCost += cost + tokensIn += tIn + tokensOut += tOut + cacheReads += item.cacheReads || 0 + cacheWrites += item.cacheWrites || 0 + + // Provider/model from what was recorded per request. A task with no record + // (created before this was tracked) goes to a single "unrecorded" bucket. + const seenProviders = new Set() + const seenModels = new Set() + const entries = item.usageByModel?.length + ? item.usageByModel + : [ + { requests: 0, tokensIn: tIn, tokensOut: tOut, cost } as NonNullable< + HistoryItem["usageByModel"] + >[number], + ] + + for (const e of entries) { + const entryTokens = e.tokensIn + e.tokensOut + const providerKey = e.apiProvider || UNRECORDED + const modelKey = e.modelId ? `${e.apiProvider ?? ""}\u0000${e.modelId}` : UNRECORDED + addTo(providers, providerKey, e.cost, entryTokens, seenProviders) + addTo(models, modelKey, e.cost, entryTokens, seenModels, { apiProvider: e.apiProvider }) + } + + const modeSeen = new Set() + addTo(modes, item.mode || "unknown", cost, tokens, modeSeen) + + const day = startOfLocalDay(item.ts) + const entry = daily.get(day) ?? { cost: 0, tokens: 0 } + entry.cost += cost + entry.tokens += tokens + daily.set(day, entry) + } + + // Densify the daily series for bounded ranges so the chart has a bar per day + // (including zero-spend days). "all" stays sparse to avoid huge arrays. + const dailySeries: DailyUsage[] = [] + if (start !== undefined) { + // Step by calendar date, not by 24h: a 23h or 25h day (DST) would otherwise drift the + // cursor off local midnight and drop today's bar while today's tasks are still counted. + const cursor = new Date(start) + const last = startOfLocalDay(now) + for (let day = cursor.getTime(); day <= last; day = cursor.getTime()) { + const entry = daily.get(day) + dailySeries.push({ day, cost: entry?.cost ?? 0, tokens: entry?.tokens ?? 0 }) + cursor.setDate(cursor.getDate() + 1) + cursor.setHours(0, 0, 0, 0) + } + } else { + for (const [day, entry] of [...daily.entries()].sort(([a], [b]) => a - b)) { + dailySeries.push({ day, ...entry }) + } + } + + const inputSide = tokensIn + cacheReads + + return { + totalCost, + tokensIn, + tokensOut, + cacheReads, + cacheWrites, + totalTokens: tokensIn + tokensOut, + cacheHitRate: inputSide > 0 ? cacheReads / inputSide : 0, + taskCount: items.length, + byProvider: [...providers.values()].sort(byCostDesc), + byModel: [...models.values()].sort(byCostDesc), + byMode: [...modes.values()].sort(byCostDesc), + daily: dailySeries, + // Cost first, tokens as tie-breaker so zero-cost (subscription) usage still ranks meaningfully. + topTasks: [...items] + .sort( + (a, b) => + (b.totalCost || 0) - (a.totalCost || 0) || + (b.tokensIn || 0) + (b.tokensOut || 0) - ((a.tokensIn || 0) + (a.tokensOut || 0)), + ) + .slice(0, topTaskLimit), + } +} + +/** The model id from a `byModel` bucket key (or undefined for the unrecorded bucket). */ +export function modelIdFromKey(key: string): string | undefined { + if (key === UNRECORDED) return undefined + const i = key.indexOf("\u0000") + return i === -1 ? key : key.slice(i + 1) +} + +/** Serialises the filtered usage rows as CSV (one row per task). */ +export function usageToCsv(history: HistoryItem[], options: UsageOptions): string { + const start = rangeStart(options.range, options.now ?? Date.now()) + const header = [ + "date", + "task", + "mode", + "provider", + "model", + "tokensIn", + "tokensOut", + "cacheReads", + "cacheWrites", + "cost", + ] + + // Spreadsheet apps evaluate a quoted cell that starts with = + - @ (or tab/CR) as a formula, and the + // task text is user- and model-controlled. A leading apostrophe makes the cell inert text. + const escape = (value: string) => { + const safe = /^[=+\-@\t\r]/.test(value) ? `'${value}` : value + return `"${safe.replace(/"/g, '""').replace(/\r?\n/g, " ")}"` + } + + const rows = history + .filter( + (item) => + (start === undefined || item.ts >= start) && + (!options.workspace || item.workspace === options.workspace), + ) + .sort((a, b) => a.ts - b.ts) + .map((item) => + [ + new Date(item.ts).toISOString(), + escape(item.title || item.task || ""), + escape(item.mode || ""), + escape(primaryUsage(item)?.apiProvider ?? ""), + escape(primaryUsage(item)?.modelId ?? ""), + item.tokensIn || 0, + item.tokensOut || 0, + item.cacheReads || 0, + item.cacheWrites || 0, + (item.totalCost || 0).toFixed(4), + ].join(","), + ) + + return [header.join(","), ...rows].join("\n") +} From c0891e465ddf22d6772c68c0bafac9bd58f47bd3 Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Wed, 28 Oct 2026 09:25:54 -0700 Subject: [PATCH 02/27] fix(types): add apiProvider and modelId to ClineApiReqInfo --- packages/types/src/vscode-extension-host.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/types/src/vscode-extension-host.ts b/packages/types/src/vscode-extension-host.ts index 3870bf33d4..bf1b8e0767 100644 --- a/packages/types/src/vscode-extension-host.ts +++ b/packages/types/src/vscode-extension-host.ts @@ -955,6 +955,13 @@ export interface ClineApiReqInfo { cancelReason?: ClineApiReqCancelReason streamingFailedMessage?: string apiProtocol?: "anthropic" | "openai" + /** + * The provider and model that actually served this request, recorded at the + * time of the call. Usage reporting reads these instead of the *current* + * profile, so switching providers later doesn't relabel past requests. + */ + apiProvider?: string + modelId?: string } export type ClineApiReqCancelReason = "streaming_failed" | "user_cancelled" From a7ba4adc313e4487e8caaeeec4e3f0b77fb508f1 Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Wed, 28 Oct 2026 09:34:33 -0700 Subject: [PATCH 03/27] test(visual): add Usage tab baselines --- .../__screenshots__/usage-settings-dark.png | Bin 0 -> 64531 bytes .../__screenshots__/usage-settings-degraded.png | Bin 0 -> 63770 bytes .../__screenshots__/usage-settings-empty.png | Bin 0 -> 12158 bytes .../usage-settings-high-contrast-light.png | Bin 0 -> 66509 bytes .../usage-settings-high-contrast.png | Bin 0 -> 66730 bytes .../__screenshots__/usage-settings-light.png | Bin 0 -> 66381 bytes 6 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 webview-ui/src/components/settings/__tests__/__screenshots__/usage-settings-dark.png create mode 100644 webview-ui/src/components/settings/__tests__/__screenshots__/usage-settings-degraded.png create mode 100644 webview-ui/src/components/settings/__tests__/__screenshots__/usage-settings-empty.png create mode 100644 webview-ui/src/components/settings/__tests__/__screenshots__/usage-settings-high-contrast-light.png create mode 100644 webview-ui/src/components/settings/__tests__/__screenshots__/usage-settings-high-contrast.png create mode 100644 webview-ui/src/components/settings/__tests__/__screenshots__/usage-settings-light.png diff --git a/webview-ui/src/components/settings/__tests__/__screenshots__/usage-settings-dark.png b/webview-ui/src/components/settings/__tests__/__screenshots__/usage-settings-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..7dde60d668b845079b8c1508f72211cf23ecf728 GIT binary patch literal 64531 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 TP-NW;-^lE9_jRi#P}qM1g@+Wy literal 0 HcmV?d00001 diff --git a/webview-ui/src/components/settings/__tests__/__screenshots__/usage-settings-degraded.png b/webview-ui/src/components/settings/__tests__/__screenshots__/usage-settings-degraded.png new file mode 100644 index 0000000000000000000000000000000000000000..13ff0ecbcda847dcea0d6262a3eb0fc88e370536 GIT binary patch literal 63770 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 literal 0 HcmV?d00001 diff --git a/webview-ui/src/components/settings/__tests__/__screenshots__/usage-settings-high-contrast-light.png b/webview-ui/src/components/settings/__tests__/__screenshots__/usage-settings-high-contrast-light.png new file mode 100644 index 0000000000000000000000000000000000000000..54a460f2d353920a526d4e6c2ca11a0d8bad946c GIT binary patch literal 66509 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 C7>Mxz literal 0 HcmV?d00001 diff --git a/webview-ui/src/components/settings/__tests__/__screenshots__/usage-settings-high-contrast.png b/webview-ui/src/components/settings/__tests__/__screenshots__/usage-settings-high-contrast.png new file mode 100644 index 0000000000000000000000000000000000000000..99a8f61e5174f05eb7abdca967be41f41e981dc1 GIT binary patch literal 66730 zcmdqJWmJ`6`!6WnEeO)x-BJ=Fje-gY(%qqS2!eogNQVldh|=Ain-GpC#uK((a+1MjI(yA5sqvC$zKNUt>lzq?rw7bz~ zv`|+LlRhXqjNhzFIf31Keleu+#CDBC!feUAGG@_3E?QRg zzUJ9C*B*0Q8_KG-5e$vK%^BTz${I`d%SJyl4sKD@sD|HZ2!A*M$lG8#51 z$D$!Iqhh4(pKp5b9g$_N`&JHCe=-_WJ3n}LyF_(3S6R?)89_)dcQb*8?fNMkJsINr zuaQt(mk~Bt^z9Q$gkoEFh`FDa-xapa)yO;>{;bOR?E6@WS!e@?Y!E6b=QFkU9Dnk) zzbyBsdz>BEXw!(hE|yyKS@y(R^u#m2!60b#+%-+%GeLZdq!3KvHInu{+4((F5%*VaT;k=z`mCN+I8J$Ao*j~MJPEtauJuJDbLc=J zocM8c`}TCh`GixGdOTB4u5v=_TfB&Br^)KLr`i5zYa>7OBS<-uxb-Vvt&jK}{?UO2 zB9>viQeE&QpIE@Wn@Zeuvi4O(3|!c5IJf659%V72KTUXjs_xjS=~D5OK<1*@VWLt~ z`ZPH5RCLC7fAwe1#p(V`gHQ6y)9D7Ef@eSO`5f6til-lM&t&s8vrq__->)M&u;@#I z5uVcx%3Q#wzV~vn+C?>q%SO7=ZWMnM(F(%=184PwGJ=}dP!i#JcCdDuBIaT`%>GrR zFO+~*+GSqhXk%ROYW5957}AX2apw4+tIP8$`*G7FmSDmG<}s|}?l?xBB10*^vxD`~ zBB$y4)ZkaWiR}H~B)#_NhTvu%20V5qrpv8lH>z>9$k+O;^tRZb&_MiO&KlQ3weq(| z*QWs=pTE1!&P5;WEFeoa>1lQFyCGPpyTRueu~%U?`pCT9W9WmdsMEClc! z7$U~bM0V}iz2j*gUhjj|8n+e0+L!s`=FP8>2D7BhNVC$YMAx>L`jYi|_WfaD5ne}R z^52oe3?)Ww^*h?ot9K5@B-)6F>71A$$bX!p_*vz>lE=&KY3es>mW*C|i%iPBN!)$N zYxY`W*W%l;^kwEfrXs0gE(|2^HxigUGsIlF?b7!$B|HRt!sjP2z8N+7&$Whd|F^HO z&=o^)hi8(v>4I3qUN^WRDxxQWHN9eN^P_y|-l%W8Hw*<@Nu%$n0Bvg2q7$t4mHzb5 zZINrM(1y4T$H{8`o~`+ghyp44I zFX@~KxV~%)B~b4PBVs(UPHH;)$C**l^QyTc;?DY?f-Yn%64VB(!7R@m_+5NT5qlUQ zH0;}a686*eULn||Tsq!N>S;oYUCQnW;`Fx&iPdP9XItLj-4)U;w~m9&puwV0@TUud z6hG~>*1RYFvwC{csp3N3REu^3O-sDsuII`Cb)BSPy=SVRm0^`5wRUtKlTM)l;%R9% z+*UgA#?jH{#N+)u_4KrOCgu3{ccgunGJBZx!Sb@@Z}xm9Sznyg{7b~y-izRwR8{+z z97h$Cej1zVTAvx#x$S7-3)sRvZx|;LzVS~?YF%O4 zVLR1Fp;~-fJZ#M{|Mn!`c?1KW%JXO=6~2KJqihC;R|A!c$xY>mo_@^;TU@@C`+wn; zIuVM_J=6BE5q*_<&t2HS##r=*qK#x*j#IUV>!aI)GS^hXwzqMP>hLAWMI8-dIiJIA zN8DyNZ4ekQvpU|#>!9^Jcsy16N;R3s0gV;=Hrvp46E3Z^FYLjQJ`xf8v7*K^+x9S` z{&dmn&8nH6;^#H4OYzLAmS}0WXmSapPd>mR-eSfgW`dFyl>Ht{ z?rFiZ3SZSX=y-@$)y#i(!PVyrF*4q_(Mx4JC_6@*@K2^ZW_GLm&W~6%GEzhw(hl)s zd0y1AJ^o}rR@~CS_i}YeDL24{6H{-cl?y)f7&dp6VbBaD z9>&n<72(qFbVgBLH3Te>iU(X>gwp!2u6#@3H*=*gvl^`QRf2_fb+SMpql4!B%_&V& z=JGeOtoqRPcRSdJ&nxXIST(4AJM7MP2wDx4>%b3xgR9z&eAg?tCK?cePGHg+{Bh?? zw!in@Vh>#Q>gs$Os-H~271ed4&+%4QT!|-lns_qW=eMRM!XWUt|PHOurPhEPFFJ8pz4fWe^yP#zQbeC z=<6jp1$#N*WG)oifL8{}w-gYMD7`bt z?P{tfDjjkLU_|-OPgpb#H^$5OP1|SHBzef*^w{u;lo}M-!x+Y#lJgjd4OqcyLMl&N z^5)(Dov;1aq3jhrRDPlT;bRN1)QjvubKkAHP2C zxMSoj!{5ZNl{-s(qFZd-0)y@xmGdxW`5QDNt#a$fg_qE-P%!Z8{mv_o-z@HK{A3dv zfnNF+pSm|3D#KToh0cr}t870qaaZ%d-tduBL1rCMl*x7N4nkI|{-U-c-+SoZl+E9l zjM~C0aa~e5cb4?0iCVwJop^tKwAr`jqOfIt>r1Z-MLrWOzZHk;tILh{OJtZzb$X9* zEB}qLl1T@VMc1?AZB2r`#z3g>dHC2kLN{NF`Jc0NBH;_JT}#X}DpBlKqhMUh=#inLyo`sbtZ%y#2RdW% zsG&<@qKIY*E(m)j78x~NEhQU$@;=a2S(TAoqLy%1;Qy7Yyx>Cjdu6?-$?;bno?X8z z_b6dC^l)gw>QQ%vPjm~Oac9XTCgO)@cx@m}=@lCz?bX8gKyCho;d$^dnyQCpr0_-G z^KG{eSFmGaarG;Ze&jyf{oob|9X9Wpah+?WJ1z$x#EG_h-=7jr4o0u9+{ry1!%y#d zY(=7{J{6(L)HioU-flRik=yn&^_PpMp4xrp;LS))?((s2kH}`M-b=75WB`G;IC)_w zjFP-iD65^PR^xkGdd$KS-i|MhbUt;*TnFlK*A(M4;b%m_8gAQLJPFU8S=a-QH@kV1 z=!U4me3p9Ob0-Vz#mRFSHD;)m)zdJ=^f6Hl^VkQm(rJt>F{>sqB^A@skbe@xSQ?V_ z+z8!S^AjCI-CcTHCVKpKc6s7lfuwC6f9abx< zVX>;^=Hjy=O5$16do}8v=#awG2l*ljSmaWeXu8q_t?*y*7}kfOxy%U4CMH>gN)86w z7N*q&W`D>YzW?KSMQJ-F<0`c%HSQ}jq=#?A7JCx9>hHxreD`ohNG60Fl?%5IHJ}_} zAE7_TI}m;1R5Q&T&Q^SyCFMiLW3cK%rL2-El51r-^&K{m&TSwEliskeDY^$*Q zxF2v*6BNX@0DsM(9lzTznMpygNVsp@zw=d|=|h=Uc1m_=XM*E+X-8cKP1vvU?OXf= z9VSRv3si(S*U$UWi~f~pZmU<9tEY>kjybOm(J#_;sT`QH?f0-|>jFj!s(7{jY+KNr zm4sE}`?DW+rIX`gUDoZpG2aT#eX4YtakQir5nAH$q? z!_xG*V~WN8fE`TC$BL@GG8gV5t1+1iiKlndmRZ_e#aiD}ELEE^uo0kCb=Mb>W_GxF z&fJ&7&zsmtHEb?x$r}IYg(o`kX=BT0ndk9L1~E@)KlF2_2njr^a8bn}98o{gC4s(} z7bzB~cPBz>pn7KKH@{iu$8FC^m4=bu7%=+x%WO^QB{3CYiJ}ioBO{Z z>5Op{S2Ns1Q8tM$wn^L7v*A^P89cp(VxM0Rw#XnpWaaFy`b=U^yql+*GU|EzuVyy9<0y4>o#~Fwl4DMS4Ju!#PxZSRp!xZS{jI-jmI1|5yW?C zY;<>Bx-?}^%F__b;h3uQ1}WJW?d?127AiS;2?w8-T-X`J{MR@R69N68Tad+nx4-z7 zJk+tx%(lgi;Zq!k0^S*If2Vowb5yiAp_^7YA-w5vVD399EJ=he|i5{sKj>BExx?1$&DK3!F$1qON@ z{`(UZ!n8IRK2`7a%ZG%A4`_oWNo3{H-FuJvaffXj6T25A=*0}m^hFlmk>85@%klJE z;u2G3&(43>0@B2r4Fp^1UP#!Da7kp(UeW0VzWFU9izct~7BxG9Wp6Zc_@bUNNd|Au z@QU|ta>SvApXZ}yw9y+1~?WdR8-DowJgJvfS?73cIU5XzATZ;o%!?8JN_PcbQ2a#GKlQ>- z^ga0b(120GD$(|o;6s>D&KdLX%v= ztZR}4M^|HuvNAd=@?tL6`Y!DC`_Y&kCUVF|J>*nvcBj9F^vWzPuEm5q_d2&+5|l?7 z9M~{TyAG1ivy_iTt%q*uF$u+oSUG*=IF6F&{E#IT%Q3fCbBd}_7T)#791VFGXOc4r zkLC8dI-St@$DiVE+jVnB^40q=j;x^)Z>fChUQjwR@)L`;x$qxa8Vd0dib*-r@uWX2 z2OM*PJG`X!TF|xx8PDv|yp$&OR{Ht%s8PVt7&K^A1lVP9nA7v?jpJBANO`kDkaZ% zQS^kuMYdEf@Aan>uKnS9vPjp9Y9d=pD}YY-&A$~^gEUF(A2UMEkGDZe zNO#p12lN0WHin#k9(p$bZw;)LP52wM7(P;949=%}OP;&)kE?+*fm}hxt`)o|;jy(b zQRM^|(9D)zG6M|(ke#E5*VV--pkhHwM0cgHFQ90^z1HEt3v05ietvpTWY}P#K9n0Stl%ErTMsp{s65SG01N<*% zuzd7Dm^%mqiA5t-pu?9-r*INP4B)av%`AYYr<($E+*Etmee5T8G_APr=U;cUuN2 z<`d093qaKBQL8}!amIo8-5m?eRnMVMyjp@7ST(EXsQ}Ozi4TZ`PoNPK&`6HKLY;7>SQUfW%^~TCq$q=ulh__kg7Hxo7%QyY@u#KcJ(KGs z++nB(vRrq9n&+z37-H)p=^7J@X=OAijdZIVryBjvYYW_iP_cmCbq$15=#`q6_-YU? zRy$4AKCri%19@%IC5WRB7N3()qrcS3rvfKE6M9De6hQ# zAxV|brxQN~jZWD8;>2Zt7uMT@OK$ogiW1X~PkkR$BnyF`W&?Z-Io)5enpHifH#7cb z62tN2YqQ|stSe|(VR!dbSUv_^U#&7qqX%|QL{kVZ|IB%)oWSznghs~ScX$3lOxs8A zY6|qCY~Q_b_LkJ2IRWRJqDjfTMjAoLZ$fJF?$V@6(d~wz%l`wi9YxL`R52!SkIt%< zg$=!Sw~auinij1^_!56q$wGs?uJf&uOc%pi%MxfsK_%7M$H6XG>9pdm?G1!YC&1^Q z7jj{@VfL+{>P1Tc8z<-#KAdvB~)<@n-O z=vcK2qva%*ph52ngGwUX)+@{=n0g7Xz1%|qXHz!bWaAop%$VOeqV!Vn?Ak1QrU!w1 zCart}rNNk%#^HB`tY1qDAS~*;s}tfFw89ij{nQ2mX@0|64#BxIU#h%4+|f;L{03P5 z!%EaUYT0rvKNS{Jq=N=ul$vAN;Ca96np^ew{vc$NSSuN%1%bW|R$%6flHAF6ogF>h zsj~7l9TO~aX~!RsAXt<_DSUn2sF5V7Nn=DQMm#o8QZAg|l&juxlgIZv*)fTc3%0Jp znM?_Icddwp+@-!xl3_z?y0_Kw zQr@V}AL=}|(-zTVZ?`?vEwl;=7Q+Fqy&^=eSTfO!dobCuMiOY_I_wNAzFGZb^q+{q zofwJm+gT_ZZ6FA2+TCF|Y2HT+C843$kyGCz8aV!rqwvnPb`TWi)egn59!E13L}j&( z8tJ!wc?~}U@iQe+tLR==3U;oD^Aa`91Cmyhq$ALH6c|oV`bB4S3)y)Rev9yJ~L4QeWrg1OiH%16*R#DTHH%NWC_rtYPIIahROX@Q5j?s@(B|ID# zj{TGgF-1R4=(AyUPpZfCe-#DwTBZG2J&aRLuHvgIgG%@EPgK z5ahj#Pg_qSB=7FNu{^)?3&*@5oK|v4awIT+&^T!Q`9IUYN3{@0ft$K6c9ys{gU z7Kv17#Nq$O%MK(9CChWuQx620BfYtkF-&K}+*)@8Fx_XcY|jxPOT8qZ7T>N>=)W9Goh4)5HTv|8ezB^VxUZvm_5vhsKn zbhV2a3uTY~FvZ%#gZx41bKHJ`vRz%aypS{zhj(N-xfh=aM^FFg7}2Mhx52iFE;VZc zk+F@ zMJ+Lcz&IgS(7#@Kfw>zH+i`T%5!h~?IwOs^<~4ao9I8%w4YW(WZ8?)|Q2cA?l3Nhn(;(ZK zI`>yzO+}gxhKzs6u<#rV<6V8ZzyvwL$5 zF2m-f|M_`SgjlZ~4*m4qtrvB~>`6sUcfV}A;Lr!R#XA3Azj~?$OMvj}wZF{$ez+pGu7H#_AEY0$Ys@xcUY+h)ko_Ai zlJVLzmsw}h%&G^G4Qcxe=wjK`#xh`86eDAp zDAS6L{V1>gPpD%s4HRGX3^D%U3$QSy{g0BYwLviX_E!eeh3&wTK5bk3^+nWvtXU3*LOWNfMGnN`$cVxBoTD%%9vfqEFg~tJy&-s% z?f{R0F#7##bww*<)yx9V4gHYyH?^c^tXwC&{@YXL+pzg@m?rii?b*~(Qy|`PG}v2M0ZJ2jFE&RTs&*gX0)vn;x@1@*@YiH)7WRbSW8VfCBcWI$+p% z=%7^m`IPph$AMz<@shu7z(G@_AyMzYJU`C)f%H`bRyfTx z1~X_3`Zy&KGK68~MN8}iW0PX5n;@}PdmsLT-SR;IL3O5c4OEX0UGRCiH44VrdD$%L zt(Q?~2bm!NZWeO-Iq+LbB>yca@{e|=#88UjlSHLjP*}820P}gZzueE12kysa!$;+p zgsMQG9#=chrHeW}4}3i&w-dG)q&sh=mGukS`mx8>q&R4}z!wEKigg_RmahT6PqH%{ zb?rx;9qNBX2N2Obkh~=k>}_CEu=`keHHBju^yI?m7*g(Sy|E)e+xbb2;0?EYLj1Ai zbGa`0K1fid@{T=^JRY|##zEEQN%VJCmzKjukD<8xL(uxmLw^`#bvJM`cYyztDx z{SrlIYBMETj*KA}Q)G235bY?%l__O6*{!pl_TI~{(D@KKriiKav0gh4#u0Zcd9pkQ zy)`Zy14PbWD{BVx4>pJ~ngs{RT8^MBN^ogZG?7V4EP14~&=J`HR4d{XVc z`Mh~QP>o!m#HL14Ox!@bn`QZ&6%=?mhN%!r43&YovO#GE__V#Dme4 zC={U=aamtpNd>avej$%i`0KadFY5285pObHYGE$!oSB=hK6kM8 zD>eALeictz^hfui7+%Z2&hzczi3`a+4P4I;vOUg(Y=%)&tnYDu_yMo}7r;c?yPF=|!j+SWSX&aPZGgcFnd}4b$_Vv^K*|H?(z<3lmiddsYxb zz>(3qM=C9yK@ZE3T(Pt^$w^k(Wt_$>JrHS^dGpOLQKR=na;R3mMW3RxGjMT}4Ri;P z8Z1BkftJza$r>#2^#nE)xZ|Evs}J-3pY-Sd>gV-%t(gKAy)X;VWe$L%7Y9t#Lbn2c z(xb`$65*8Ly#w%S5c(2`6-V11T~U-CW5p(r3?T;;4ezPb+kqA!VTm9=CvEeG@CNmE zwzzr{mmbVi1E&X|QE*o+#evko3@;JV`tAgJsLPCs*bE1AF4cl*VXGqd7I(bL$p{;I zhyC=sox8i+tfV2%gyF=@wotA?cLCS^4t$!n?sr}OduGsFfQ1^X07ZYm`i_kIZXeV< z-?^A`4EpFhTVgKrTtKP8`2&6EA?NkkIxltr6u0ksW#9li19OHFR+Zkn19YE0Q)m%9 zeklC+&mW7Kbw+}7{If8T%b=PM$`*9X&5<9J>Z(sp_WF1Q&AVq;u!a!Xen;cG3tdw< zP*x(Ay|2YQf90vOb3OhPd@2Ts4N!B+Z!$P#mf-5`eBEfMgnwar!0kY3>A^}jno+E% z!2&*vC8xPjV#rA~K-}6hq`tZb!_~GGj7K@*83!2*f{y$59=X+uOmo7o!PvFbrs}*B zwf(&c`}di1$8M`1>^0!~pe1dCrf{=hy+rYlM}c=jO){;Gp%UK%SF+kk!1ni7NV@Dm zj_3Mfe-QpZvI(S3wJ&P2=0T~!_Aisv;<>A47ftV@jUHrhf*wWvMCWIR)%8^n zCsLKr(G+D=48%Z4^MJz00>KW5Ef9&!oc9yRiA9+4AOsrXr`ua$a@X!0bitmO^>>#0 zC>Qd{4*GJ)RRq#CY{(zR2>rdX!ZAc^2+prt(2M67w>)99lv(!6d6f)K^SVaTNZqrI z$outtvB`0|J{%{Sh!K4p-F^-HUUDrHSJ2PG2Z$*Ntz~9xUaw?I`BZkTGh=N`3%fKf zN{tj54dSa~t$7|BVKw=lx&m(9h?%zg`Dou?3FRX*#1Ra_&h7q;wfi4_&IY?Zr39_V z;}h~Xb>)T5DE`sg&kO5mf^HH8`}awXlv)7*w-C?&cpc7`bp&8bzcBgxbfX`opK)QB zf9T8E3Vt3;O#IIJM}*g*1^ZxQ~GaA0unKVyjLmzV%8Q%R_ zmq&^@;u7rRBu*V3_#Tjz`iw=P%U>mK+AiksEn?8D-r{2r&@hdS{SosbKG+Ja zobg7~Gb7mpguIDRyr^>rQPNW_&c@w(h88t5VoCSNZUg0d&y+q$kenrc6ruCef@`$T zW{rIjSC2w1xGxLBe%Qug$M3_8hbD}Cin_9p;jP%0UH#$9B_WVH{LXJ*oY-PLY zIxA5$nzF9{D@KSZxAHAZrm#=tRHvwAShb2-feNUFH<7fYz6l@!$^9}Xvnb2t<5(i8 zdMd;HG@&d#uiMQAjXdMo7zyxBU!q&L<081q@^dGkI@*@sZ-e@Yl&&54m4?C~uON7|yi(ee5Eu1C;s#ue|rvW@AFRmZSfos-x}V$&{y zpPzkJA(dkevd-InG!5We;G(NM{>v2duvOx+l-hKR0j9?(%P(xRh}Y`~U}lEl01fFm1OX&Kw zrza)7nFX4^aP7q;+TDKX)T)-44;z^GDCj4bu6g} zS&>2U7wE4nMTl7)YY=!r_lYlHMi6s?euqH5bX(#*<}F_U!En>=3?WgAyPZGwsO zSbrsG(u!({CbhRL7iJt`NOplv&$(CoWWp6MpF^k6zQGam3MxdLEe<{MEH$y?F#gDT z+dzDiVfS~miJz&23@IOGIEWx_M?VLw{D1N~cjEM3A%^zHndqNkQZ>8q`);T0OU!Lo z;}xD&%)!od(H@gpn*p*Ji!QyskB5on#7I8>ht`W3R$CopymH>8SFOiod1{J9pAo*` zHYv(8NwweMc@q+&Nc=zl;EQW<3Mp@}9`rn6oIx{$9L@Tr?d+%qq>aS4z*wl)f!L@O zI3&|ckcXH6-vSEq<%AWai-4YHGdy^w{Y9fcg}<$SUJC4FXq;ih%)JmL9R03mX8R1H zkUmEnqK=cg)z0+i<;O-}AAN+S1E|YtrqM5naDKC6H~NNWfZ{q0-4Di_gjq$%yqj>} zaWX&_gynDG^rxgjQnELWF*LgXVdp-DMJdANQ>b6%2tqv9HSi{!k}qH|0lU4aTQ_DD zHUafLAs|s2i2B+a2L;#>L`oNd;y^P`XHmb4ZTI_YoVc4M_8so$zd_Z96xDONu&U&$ zIXp4ID1VDhP;f5#0r!C^1vm)20p-LkQ1^kq-wU{s^sfYm>ZX$bY5-Med!{KS%k&S} zNnvf&f|j^)h&?FPd_SOTYXa)rTkh{$2Bab3G9MfeT6y^jqygX&-7XF5bVcwrq+A!3 zZY94~gB)Z>yrAWFXPG9ne|tx1E+u7MH& znW7hUofXh!Q3M^a=%)>*v#3P>CPNkstT1XB|N7hrkoIE5WktD@SuLJIvPk(0U2me0 z-3YFeG}K%z&L~PzaPkBx-U9sjkPcX!Q@?Tpnzu`ZJ$bWiUn0918KGb9$lyH~*h5eG zdQr@S53+9%0^xB0*Qlhtg_F%!fMQO522dO#pwLwq+ZQ?cn!tR(BVs_cnFrHkzE_!6I~w`w zaMTFervMh279NP#-3hEQ=lI#ue(xr@4eQ1JjFlbQ);}4b{sWnlbEq|Ou8LS0;SJdG z>fx6qAVUPR@g(4=ffga|63+xcstv?OwXjmiK=L}han7;cG?>+TY}>~i0QR_`UC#wW zCM;&=OKM1(L7p+rB@a2xI)mLNVXiH-Zktf{%UvHj5;;k}HA@eGy~<2GY$b-N(AW>R zrhH%sLExENfG``8McF$-V!*tnkxMG;j9ccfB9&RQ&8(hu|GNpNoIAZSym$WJwSfOj z*|#DT0bv~o*pVqwf0)g!PaOx)H8WM`0X9y|3+Cjh8;9>fL_As^A$2Z(sm4Iy4>tN; zhnneGjS-NW*mXT!dr$OYP~uAY#O)R(0HAQijua!~?Y=3K3!B1G&NoX9=YdO#GDER8 z?{(eK7)P!3}iL)iWT>IYhnj&q2lm=tewwT-hj+FDpD2cxU zLB`wIRAL1 zCSI$l;SM^A0_t;3+}QI4PD+(B)2? z$5V#?h2-u3nA+VG1=ADAoi5a7h>v4h0zte4&H)=7)B{V%uz<8xY8VCdK@&tlCa_O!%dtXdWch1^y(79^;mNaf1Le1%$ z0qKTUuapUdQAk`j96GHHeQX1Ek-((v3Y!TkWmy5pm=Lxnvd7G8eUUHUv9VN|wv_SS zH5ixLR_hBp@8mz&`8SLVjB#|lyTKcK$p#Oh(Tx7kABC>VA>=rjf~o{+k6bAJ3*bqh z0zv4&9xP{QGLU5k3vgWnx|5`UDeVhR7+5Y_00Xfs*FPb-an^wyE zw{$|`i#iZ}Zj4D#mgirQsD((pXemeX#eEIFxdD(DNEe{tkVQh6{voZO!W>}u$NNy6 zEB*`TuikK3pM%w1a1KhyQenyYK%gN{Ej1n(>wmL#nUqiJfT=*-QOavC7&o$OI(8fA zCa?rAXm()xvlO+`WYwJ<{L%y+vl9zWbL^tS=v;ElX7c|AL9!OQ3V3d8Eedyd4XKnL zlmf9-#X_cr#I$w*OwPrF9Qk0(I8ZhLlR+CuI0F@V6^5Pk&a_XN!ML-~-;Lb+fyfsY z1W*=0WPJu~PAusr^!?hHV-jPOrc|4G*^Ev!64c30^*+ardsC45;rnDyH(KI<>8(~3 zFu_p4q(8KJBYJxT@^?MTS(x@IFl;yjY_Qpoie@Sg%)Yx*ElmhZhG&yZt{y9Btx9G2 zQYc`eezU4*dX5&y7Z>r&To9drMy+!Jwkp%Tp=a9BE}cY-U5i4+J&CagCjcY+{{s2h zPe!1Z`s~cgCLV*CBUHe*eIW%c@_0J-5SnU&*+(V-lvJax;#+X&!yP&|1cmYG;0R26 z0ihc8@g}E7-pfp~lQUq!xFjsNtqsm|tzgtWlEY3v5W*s~ysfNt{O?bMUOO1nkLkfy z1_7bKsHt&WME)%<$OWGPDYE?D0Q@lR3+4|N2@BKZRJo0IJd^(x-XX1kxe}like|!~ zVmhkrIp}6sxFIWFluY>J8SU|s-Kd{$^&MAGodqb>9>C$G-J+d_cmD!3u)$yO#A$lE zrFeqobn3pTMnTpxcY3DX0#1JH3+E}zZ7iUySStIi)rCYei5 z06^;g^4*ig1WojdJNqhv>3|%xX7)nCA?DJr{0@Sj%`fz$OIx@S2b2aWP#4rv1t8H@ z2DyV};l{VX(-~GFk+So32G$p}?F#Fk5b7s_(6<#QHmJ?8n*P4$0V!tIPzE;B_rv`m zkjD$5X##fyhOv7*6L52*%P#fKp|}*pqmd6Ay$@|+6>nBWeAdXUg^2*0&j0G7ri%r( zkLe%i|4{mcou(!C(KDc?-01(X^FTO&Gi@~iq300s28bpEIS*V40Vb71YsiAwk3l~a zwi{`WxZ?yLyf+2PT+~9q$RR9Js1mUAc^b*_rmCE>*;(C&YhSGgq2av6Bx*HF0I_SL z57dM6t-5VpOiGar2$=jlfR=Q;F}}Z&9dIQ543fY^TcDKQz#82{Ao>?)>qP)R1)SI+ zSYQr){zkcLtH;Za|8E)&h#zB30RceY*-n?!ohm_`C&Z|qgKtCRM%Wx93ut})4gs-&2*6;a6!ci zv-YsSEmrVRT-6_F_1n+4K-D`@<)Gp<0%=~q9Zxe$5{@9w_b;4K9fJ&+2B(ss%E9r2 zcn*3zzx5IB@;~1@B4zx}UV>wmv|bQcy#~@OB1`H9@n_e4$T&s#U!Gk;jW*W-yW#EA zZP4uM_N2)kf(nS`<(4N8va^HXs$&^^Meu3dtlcf3KT$4hdi9+H7EX;S4@!hWl5+)z z8mfW`w{aVFepanmw8$3zErx}6LxK3teh@>rj-2==V)uXe3P)9ZMtL5F5lukLuL^=A zk~0n7<9pojeqZP@xS1{gd0)&%;DvPk=zrdq+Rw{nfA(MRmosy0rb=}D=Y2*_GD)u! zx@*?Wn=@QuXfoR;vqw=m1!Q`S%$O{!I{5#HM6?p)sRNXfs@T@(;U1~bT0?x_U;XT?y?rOQ<+&+z|c)#{#Z2vf$>yn~aFP{juV$CdW}`YdZm*V>kl-bNjdQKQx? zi4C|pUYV>gb7T7cPw3_U5$*hc|9w<`@D;%t=cny^&sk;C z_Vz}wga{WkW5!k^%zN#TW28-%(Jm}AG1haSt!t(%!e(06Gb#sK{jlfWAczSalM0Bq8 zgTO*8ck%!XjuX`xtPl9q8UE%0lMqvc6xa`)TkK#uwE$R`>IHP20q)zG*dA!LWGe9C zP~0kjhf#%oQ>EJ2s?qKSu&S00- z@iNxBdGjI1GB;ad0x)_xW0{nR?=?evfE zS~7M~VGz|7`wei%m_xe|G#8MOrG1XL3ZP_%dR1MKPCtAY!mgRjLmklX2sK(Y}tX>vQh(l+@`P@a4&?Zz2I9~hTb-I}Rk zJw=9{KCscVMV)9YQ%i*7dyO;Wg#2ruQ73V-%2V$p`R4KxP>BsabLd;bA@Y#mgrLJC zVmd&b^)R=PK`D;OwR_}Dbqp=;CnSnkWhsEdnVcrgGEBlQxtt57?G^=L)eblstjY=l ztXMcZS5gdEd7csnPJ+!9>J_4|uFS(2i1-+n$B#dNpZt;BKA7Y4nkV6?REGFMxiV!5 zqOWc&N&(Qryj0Zau>=@o*zX+M*Acd&AFISLp4v#yXPj7DzP&)@7V(?(WI=}pKbSYe z-z=Q}5A@iDuS%Z7Ypd_ozL+#Xj^JIQ;62gHG@*!qd#c8Kd-M2(B`|PQ$PzP8JAHmC3rfid>m`EhM_BY7%k2GlsanGmb0G~Qu~z$=dVHk zvLqcu>JKkX@bU=Q7^sB<_5OhuHz%C|R`BOPW{Qsi^&9I$V^Iwm`+wI0x=!A!Ps%Xx zS_aCBzYvC#yp@E42AxWJh1PR3S8EIA4V%)@2QvN_6hdfj|YG= zydI7XUka+pMl~<4vMvkyd~}gPO>0M$)6BG*AadsjVwwMlzMX#P0*_W&5-GvwVX-g@ zbD!`ln+Aa^>M4{x)~|eT1onySiorEF#?E~xCS@AV9E=$YK2s`<2jE~}^q*h0Ak(rl zP4u7+<9GzUPK1gF>;8tZpWVkQOHQ)8hb{AvC79eek5HWKoxQu`8)bq!JQ+S%fpee+ zEf2ZOw?hCHjfScPNPQHM-#n_8BNgR1@$C$$^zW}@;P#h$Q!5xzENZq`w4)(%!iata z_zR5f`Dj5JS=t+Kvo$mGQKi9nJSZYJq6E}o$FX91eIhw_L_Bju{-YAp2j>MJ%<~W) zhsbZTA0C%k0{e>d6fnXahosKzC0^5ivEhhf#2Rd;fDZ-n{d^0LiH8nWVawdG#qSR| z^P6`@%?cprZ|d1Ez-XUWv1*qqJ%pr{2POhTV0b0n48%#G5@Xt}#Xxx6($OA~!jCYo z-Hy7Aq5a5Q=d0x%d~&{9qnfm=9JBeUyPuq4kz0%66NG<2b*VDY!2e~_XujbiSN`13 z_tD&K=-?;V%V)8w*NxRtwq`y6fE^of!C8<-_kv(b;0$WICc5P7MdcmTpZGjR7`Nr> zCHPVX;Mh#SJ7w(Oj6aCTQ@CGVpWQbWbKgi=Qe&Eg9D)2m83cr`m`jyEdafuNhMnIz zpZ5OG|G3SyqV07jomBlV8PNY@tnB7Oo;IIYHE1MWb;83NI_8Z2>k$?0>2q6u`jQE@ z8+<)yKFeQB`Rs2ftHQ5(vVUqoL({b1x zfTa0?kB7SkrHA>_JOg(V7J}@n`=9L2Ldw&!ClV?5+o$*}jVrRdLa-@EyjgcEZocPQ zXKKQVyF+C#rq;mLnDcsT>hF%;reYRDpUbaT-qvqOtvu`}#oQmkW%Rb00I^1r+S2Mu zwh=RsI~(^P)JW|x3_|NgD2Vgj`4$mJc%#v@z0WTh*QeS>Tl?)7-%N-?bR3DmaVji< zMf(;h%u2g`t^iX@5-CdEO5qHb)`sVZ#M`2fbD0_X$A9C!Ax(ob>v`5>T0CK)1~30dh(U z5j}h)K2$UZ!6LJeRr~?>yW0Hx;z#y*X& z9|&Ulr$!8lktx8^uWg^fY24QpPSMcJ+)N=;(E`tqs0jojo#zZeR46O-iy+T`hw#^x z!$ht!31`^-0ckkv483@Q7DV_c=NpMEXBmVyhtmw$YcKAVABX&@&(_US&Qe>)dt(RB zaCp09UaSCUahK=I&gV0teg!kVZQ>S?k8`Q$yyLQ|-rTi;$lPNmQVkRLqO zWKj|zpIvWFDkLJ=z_X1r1|JKgfpS91fxEjGFAy znP}x=FiA=4l`DP8gXeSC5Sg?70DPGrAu#clfVL4Nh?hv)EAM>dZX1AN0^%fsBy92; zR6om5O9HCoee(~^Vg0VJm}zu4_+l-_y%U^OAi_A1!k^ug0A%pE4>pytPN8MC+`Gw9Sa@sRT>iYi)jCFkRU5CWU&#$Xwb z@A~>AKmM?H<8K8gOadF-s0J@+#JByXHTbFjD?#x!>qQd;N>`^qCvC?{`T7hT8i=XH z7Thm-EVV`cD%R=QtJR^v^PZ*H-kbDINdjaXN(?E2cw{XAML>S=7?XqMHpi1yP$K~F zGwTOgnshy4`x|sY&>uKYw?3&BL}=Qz`Pm#iGfywapeio{$(!c`QH4DT&ramlPqMCs zo}cq^xm;Wn=H$##@qv9uYFV?JD&LO($zxwrnU)h6o1}Ft){!hQsbGIi4?cy95y^^t zVON*4hXMkR{+P|mi7e-mU@ef3xY+=(pcfcp2m`a#p&YEl6?<(N0ZjF zo;RYad17-G%vHd20+v$<%ez#90&8%epAkk5JNfBVW|GhTQLvccd|k37vVe zOmxrt;2L!AX3v9FqBe=7hHOr`2LPzCVj~|#CGMN=1wRT)OklP`ZI-VC3C7VFJX~wL zzahZ{exY?%RwdI^AP1IJOgwYI<|d+Rc~R{()H6NLqN^zVNg=$oO+8#s^=O=HmeH9_ zvUKCC?Cedl&R-)h`tIK)qj;zKpu} zk{&_CXo@}x=bB3mF>uHD)pa$7g>^+N*(q*M*wxr3<0U&|$t+67Ayv$K-$&7ftS^u<}{;n8W zpn>m{+>WZ*8>Xf(e4trQ>X4gaZo%CF~n=ndVH~F()w2spk*Vo(O)9{EPn?B)SE8TwN zj<^t-hnLonyOo`;+*HjbdW(WCx=09g}u zV9i8sI@XIK0Uh7dokkGWo)^Wuc4GWk1riXhpOVLHksfSjDfh77SF6aWNBcFcS}FZC zZDQ73A}G8W!m??wS)dlm01xu{`6L-3+gWP5Rc9( z;guoO{6>9?=8*2P`KDrAX0!AN^xh$dWO7+gaM%xcLob_dI|3JD&GHVq=9?tjK8Uqp~) z0V$6gak&eNiQh5J9xK%)vhvt1WQmoBVF?lkt;;#xxl>+}JKG1h?frug0Dc=ln%HnxgZu z@@{PxjjFuXTR9N z6RbueT(GY8WodgvFUEDdUYV;j^M3dy^>SrCAic+hQgQIo+3D-0-b8<=-%yj5V$cu&@Rfd~u?-u-?kMx6O%cQ+#&i z`$F(bCas-Lzh4Rl3cmfe)O)~r?$AoxF>{*b6mLW6dwxG={i)`K8c*ddrIZ?O%_;Es zv(okKlkoeLPR5!Dfl_MCW3d;OvsGSt?!dR)VWxQ`q@65z$yqmyC)gR2GgBEa&aZD4 z*cQ3OzjB+bKe%Ab*L8StY_;U=6kX&?&sd)LWV3@$wGxM!e^AkQU3dLA7I0^zeh0(J z>b-k?siV1eod0|5n{d0i6F3lz!TE)=JSKZj6KU$@e@=4t@BbOR> z81spQJyakqxHDQb&`KM=3nMqW%!4c zR1)twm4Jbw*-L9wkEXA0E=Xv&lCBO8e7yhad#G@*m$9t8$p2%S?4Jf!{EhxE1e}`Q zv+w#l-def*yr+`HXod&U6b&pwnNo4ZARqgSJK)atWl)S$U+$E2WrP`Ow6tk~ZA z;wJumyAQfQ%l&ZBIu&q~)7E@q`2aT=xE+M)Mqm&UhFSmz1uWf1@Mlw5pL>o*Ov zoa4_6V;e8hY^mLe9~a#ED`c+7)h_$^A<0*E%r1!_3hbU6eXGXQ(BSo+Mh3E8JxphR zFG*12Ww#4Y8~^8c(}K&(M9~9ja_(eX^tAPQ%F0;Vq|jxip^^-Yk-^`fAIm{ zvz>;LrUG~nz;~B##V^qj#Ch2O)PA!|;$&u+k0nreOvtPQhW{oAlw{7CRV9fBgd=28 z%9w)&MTZ=*SVOTp-klmFeb(U*2s09(NnA3v5rX~Hfm2#pThoBiqbftMVg~HpAXOQK z=x0D(+zOW|cW^^g29bZ){(WX8gO#iJvK+J3P4l~tz6tBZj)E5u^8{lFl!=&MN7sgQ zdk92S&~;Md;ekLd4;2jb|H94C`Pn0l^Yx zVbyChhmy~tR2P46DQ%!FasS@I*5wk(W}wY`PCOzj+r-3yuNlfB2K;h=7jK@2AdjC> zyTqJaBd)yR+y*+^=~|4DZ9v^dOi}{7@7>FEXu9||l;WT&HJC6!_TDPBkoDym3;+Q; zT5v<(f?>u+P;Ir-=fy#%p>;CNw+%hVIJ*sJ7XISCQw>Xcf zTbchEKHb>t)uof~6b^EX!3?)nQvXdoE!{pNC?3k1r-Tg1$gpSHk*e zJi@&(l`Pj1>bWjgwATGE?6c9$5pE@5dWZShxJJnp?I@6Wm3uoe{HMkXWSQ=b@jjQnZ+ zI^jj3**U`FiP%`)!es+9~t}H>}du*jrhqxHjD5F4FWoFt?~sK zJ1NL392Mo2socBF1;q-!P|8Pd)BwH+#{wTF+lVVaRHU*J)vch66}TJ&S*q#qG+(^` z3$hnQ0M-fATl>xhD0XO@M6KIyJv&m~hISRR01ydst1KTr`3j0!U>kGigSVR(UHk&t zj9tZK*!&~<>xIu4LwGhGNUzIL2EPAB_YyH0)IsaN5PTc5{L?@q&|rW?d1+RfFW#X@ zqIZh1mUzu{$tZOgLz1jHeoz)NoC|m0W|`oKb3ITaak{pk2;T`Hg`e8j7w_cg)D3CE=a|P z%6?@PG|JL~hhuLEt>J9~RA5Ub%rwO%?=I=P;+mC$QAHL&5;*?h^D7|Wjo+q44;{Sa zSW3G;oGzsq6DEsy3aQ$LE0_BVmh0?${yK+mIU8nu*N2xxyU3j36RUS0Pr(hoQ!h<^ z2XpfE%Fe?dp^v67DLOZDuK=&@nW4$15Er-u`U>1yd@z@b1|DNLMzsNK>1D4O9){KI zrRlw>dmtI-3yhsW#t7&;;90Cm$DbbO9Tygz1=IFyhh}%l6nL|dh4|vySW}5z4M)Fi zHgD@%2WT}@F8Hi=CDHxV;A%j3rO#`@^LxoodAQK*6q$oKAjxK}`n#lsyp^bDZ&LJe zeU_wtNd4F6 z8=$5n&v%C@Ztp+{bon*&KE0QH0yiOHBLWGe6mybaa?U|WTMq|AX_eqR&{KeGMf6|7 z1;TLi9NJBYl7Asp0gxw@vvFQ^ABY#>Fay*`^0087-6kCbsW1UMBCSEm2|9pq^hr^; za*KWqJTQPZXiUpc%iqhT=;25`kIzDY0xd_tQb=?lF?Yf!5?U`JHbdYn3d2vJASJ5= zSq-)c3OxHF21!m-kHod)VXPl#mjo#{P<&E9i;PCNi$3NOAqJ#n*M8*vEu>g~hdOx+e8?jSw^ z{Mzm#3ux*O$9-{zWXh|x`T_5F%*rl@^R#bO_zQv;MDv{2(D+fzK$rU8BTO;l$+-`O zU->X>M;c7Y@CZMI@YR6?7W8zCLm@v*SSLz0WGYT&O<$eqby#>lC4eX;yZ7q14L{c5 zqFj6=ULnFK=LbdEF~p$KAs~|?7=%OYn@)XrG(p-1(?%2!7H$dn^Go#0+>b&FOvQ=) z#QC8xh!VUS2eJB-E$W?F1+n`|t zDX4%t0s%}~lCRtTIq&2sXKSx?UfgL}Cia&&iqb*(8o9hM5C&M4_bG1j%LTyLtq3_y zj}tq0#5$|L!pUp%(7cK%<9-mmd;?CU{ynvf%0Zc-AMIziUAS>WZX*Esa<~5q@9HH+ zV=pJOgQi0tDwjhj>L)(_Lg6Jus;OOEKY9I-%X#j4vN}9<_P6eL!?W&ver292D{n|A zz|B6M_@`x$euA_hL>o~0?KzoANy?*qb>hR8w{~=Oj5Q$^tVe(oc4g^vmPr+yju<4M za|{VWWA@>@ciSAL*K537AL|mtEwh)2k?x$=iIBUqJ3x35EZDC|DXRoen_|jBEm8(g zeJ;U{(?u6gYYqT&p6IVUbTP^|ere&l90c){{Fh?|K(6i>+)p$7n1|_Y=GFj*44iXm zUTZ!1iv}KPje6uAQK%SYf42^X`)k<%&HBQX3kR8+VZ+;8$G! zYsQUso&QQS^lwSg{A@UCRM6qm(I|B;V#E^119Lt%@wiQL_AwB$u5k*zG^DM56|O`? zG3XiPaEIgC0fa-?Lwd*cc7P56{v&{8YBMZKVeAU;Ru!H#Dl!g;dZC*#lCW8aQu`=0 z5Q0Z{YH&p^t(?dOSC1wodjuRa=-mh_+ReXyQ7F$vmv>!Tk3FTH1GF2rXZSMXAv-fgb_Z0OIti!hVGuMXhh}PVMdP0L{ z(Qp>?c!%JDj!B0DmIk2GjQECFHbd}ZeeQ7`x=Oo$7XOO+ov^rFhf9$?JhA>s9$&^S zHP$^--{$Fab1(QNS|1^1Wsh+^Yd;)LT$z@sF+{?9k{57t4$?obMB#<_Sne`2uRC*( znD8(3LHYme+^gw_|HcBE{44g-+qw?pZ6HpD<+eOJ<~=)w-$+YkVI(__zJ`(NwU^U6 z2nG;j7c2+g+z`+~ZK%FL%v+Z95r8I>5^ACd@vYO}$1|l{T!Io(SLK7jdDZSS-P{-| zdm_=IH8SI*=-<@mUg?GcA!5`tw<|f?lU$Q_JhZmkE{vY{04#Q2c0JGq5j za6e&XTX+Z${i!(1H}{Q;{OsZAnBvWc16JnJ18SXa4&PO`yCLQs!6wz>e?F{XUnyaY z5V2h+8d@#>?tbQqwo4T|y*Rbdt+zKFN|Bk_fM-ij1)_zZhzL>@k zaY2~%k-0{^l||-P-%bhsbSNDyK^7RTLIX%Y*QR4xAb*$LF7$@4ZU{cC%R_fAFmFKj3 z5L=!&!)MUbYhbnizC0~MPJuR_XVCVV`ie;j>``_L>u=K~+Yjct%(rV`_o(6j@hg^F zl47%r$ng~px~F<%JZ}YD`l45}1^qT2&1Z`A~$*4K`e#4jy zbo~1qv*b0xcvd&h9x=VLW0yqlo%^@hF7%dPeaonP!YUnile?0)0MnH5Vg9$btf*4o?4<7VY42^)Ix9{$Ds)k3H}L_Rj}p%F ztBOKG!26f{pYloWf5*E2PCWd-|C)610Y-E|fDQ8Ipp%8g2Kc5)v_1Y`GkZ{q;Vha% zu#5`C_*FC*NN5IOh+@ybjc8o9rzv#!q3Fqcm4?Ajd#(zcO$Bzkjp%J|0lWwWLF~EA{ah(ki&Kb z518UUYnLvo27-X2o^)E|P`@I0EcAuO6)P$(8HXpHd5pZ5okE?0Sq7qM(m}0)%e8r)UMp0i zrUSmg=}QQdgNShHAQLf_P+!X`ay$*@3j}_GlZ^KFDPd0tfuAn`287h7W~B>24~Tj( z;IA*nSZdSB@?80Agie2|4%h@|WElxHF9XJ8qc6tW^m?L0pKk^xQa~hx+d43dYr`!7 zed&*K6czQtJgQ~T8n@xLf?NSr%snU@1=diddU+F?RRj9WqrIxP=bOa{qytq6aGk?w z#!r~eCVDNRQf;`+I{U!fKaWNyH?7%r75;phg(IW1BnpJP-J? z$hY4UW!jCQ!Jzkdx#2UZ?BLAEk1(VcC&vB)Ed~?(!EwFGI#`hbKXS0N)CX z9bYX+U5H!`9o9TLhVEPZ@F3MKk`-(r`e&8~3t>H33K9PjWf6zZ?k3#>KSaSDL#=|-lk-=#AVW=G`DJRM{oZ!+OZhr^bu~daJC^{sTdQ#*pSb0YKn~35?6M6xMT+4D>+%gT|}IeQTx`WIrF_ zi1KchFt$xTjAj{vjsuQel6?9Y;d*JY!$BlO8any6D#U0s%4>LvMag zH|5HL0NV?I7#4Nn^R}>RDY zO*)sbfqDeThYJmFVS74YvMF?Y<-|C;-=D%YXJQ`^6|aV*5T$!B#w=PvW>l4#^#snbsKg@~1#gX=biymT0>v|4GyU*NQ`8=OD@?Mr zkp-H2nFO@2o71sNj{+;k?biR3bXuUQZ!c`a9%fQsyN2_CyK1PGNM331K%x%?$lMgV zs0JZ^0^Wn1?)C{M>%M+pIh1xRdrpaDDk9h|Ib$M=a*0g! z`6zNZu1dNY>W}wH^0WV(_rD#1Z}^%a{nL>Jw=7hoz;$t4|L?n~U2AyxZNDIFqTD=2 zE>MNT-?fTR5JJWDE?e*gx5BT@b6MSFc~t?MRidbaTA=-(?xW__m=hMMrVFFbs79y) zoy}HN4tT@bK=CJm@&0+G1C4gcIfFpX<_M93Wc0{*aJiUA`U$<0;VS-^*{|bTa9APO zk%|U?TWH39m2r5*&9ojajSOTrMuZ;rA)Y`!XAvZiIt8O7)KL6sjn`*N_txm&?bED! z7NRhcrGIcSW>mAxbJl-t$w^33D}qgxmnjykk44o-za1rO80e4%G;ndWLv)qcc7ydl zHE)5kI~nf7N;RH;?lCg3B;QXtgCn7s-_mk=_zq|-7rgkcs7^LElOs6g30yL-uHWOP zb?QFzD&kPM@>8A^?$yGvEjgDL#hL-gh@1pMFZs_pOQrs+J!10{tAG5 zJk`gUpRPqXBe)_!R)kHUAgGm}h!+4&TZGVi7Qy?O((_l#ed%K3yORx*>sB|S_w|zT zp2ycw?Dicr55{cFr-#{{THvAZD6Of6-T}{1z<3KzJ8uK&Hd-uAV+=-IX& z0|Ls*pLj2k8w$-_rf%ac$QOOn9r$l7z`6;hiBfp$ff<_AekTkj(V<)=3BhFitpk6c zX9AjD1zz`_1xxkH@NIP3L}u52(&UaI63AsCnq;eS`26(a>f(3t)R9X=QFn?=%CbB% zGWW14T)0fQ%~6wf2>|QF%e@8&8U`E}kGd*pyv0qJ?yoFI>Oxwy`jv=qp|`#6*d9P1 zR=|ZoJN}(2XkXFxLTj@IvTx!@eHXqs?;<9rfxqXP&Bof*;X&L~E0&(6vuzi8;}2l$ z9ewKAiT4OXwdEJDEj#?4RTVi8xZyaDqbQ6V;?ZCAH>_p-5ajAJ|R4BD4XOelfF zzMw^!tlV60lsE@XGXhFltJr*w+RFD6v_OoJcD%eWi;q=+w38oV|^SUi*to;VP|o*93(+UM}GH*IhLlY@;`mNojur^RE^Bblt?oiux}+Rrl9 zxRB|2>sHnM$SX_!jpv6tjMMfq`t%K)5$jhCTNaS_`ssT9m+9yV^u?FY)q5hP!BeL0 z5V29JpR?GZ!xj)IQs=yg-LFX5`1SAr5OLHq%$`%hUyeIPGsd1pGA&XerU6l~?(CV( zti;l|i#H=8cB^pj;Knea?^~gF=OLb%C4bsq>dUMw9qymyn-4g<2n+V_ia%k!61;-G@4kpX zax>~qB9(&&&T?7wk_=punLUBh6Jmz42RvIwm%EPP+*b_T5%+D!vFrO5MMcXe>o0|Z zFiQZUC**s}8x+^y$2*&(Dzs>?vA-M;0p7F5x!U#x-9zHKYVsp}dC_t4L|v9HLizt$L( ze8xCAW(;pu(GDPyra9?yb(ea%bzBoao#JtO|E5n2N((QHZ=DkIxUFCBXIk|ZqL#&g z<;aC@y;-%*pCfKl@+XJg;$vj$O7S*@5l_JK)1$8AqTR{Ob*7*374u~tlsP4b-MfLS z3(X(d#w`99{&tj)N6Qmlr*X*Kr6l*@l$F>|2%xEncHskHQOWoH*~T)b{-USK^VR(i zgGb(vGG~t(m3ah_B^Xr&_|KMBul07xv|qDf^BI1hr?T(RT>W2|4aW4_P%%)lg))nt ztY_p4J6w2kP<*!W*QFB|cYL@Mk`qVo!uG6~(mn8S$xY5oW9!$!^mJ;~|HGCab?mhW znG+CbpbBcNNclp6XP=Hhc#VCq`GWr*8Oh)+^q@Y_=~0YRd=2)JrwZJi@E&g}fU4Hp zGze4sQCR?Xr8uqvstvhRR*7(SLJCy8I%R}VN*IX%;6@3RF+NUi1%L;MwP@AJY^fTc zJr*~3%}PShgEsHjJ&`*BTG_|bYtfhBh=m0LEpv{SXS3h0u|=oH$#n|h)|7XiS8%^ ziBJl-$&tvgh+v84>PuO~pu`5950o!pdzTUOO;lBpp)d$riC(mgakyysQo}=JMVG48 zZ8R+14|fD=4m zo$T#s{!opc_qx3GC9_zKt9H@bBpq5D(ZJjB-4myPu1QS(!X%UwWP_QQGF{qx~s~EWf<&3XAWD zhm^B)GrEYn+)bS7C6gIDWCj4R7tixiBL@k-LZeZQ^Y|&M*ZP7T45^_jbL^ z69+LKoT0?M?cIZ&($@)7ky2enk_b*zMD^-#?|Oic;y!mF>3ojBd1`DoNf|uM!ZE=N zEcdn6SH*eT5+^noSzvf}BCq&jhm3rg>uh2FhmM#COoRVtqvZ>pZD^=ZY#BS^%I=2R zgQ?TSh3G!63H{(WDNlQ=az{P;BjwLEY8OV)BC6{b((-S9MPmG9GxNlFyq`}KrR(p4 z7|Sy_6zm>&-yfqmJK((BsZhGUR?#|khTSAKWLPvIE{r0{p9yR&` zrJr_3HlL68*i;ZjKOU zLI~2cCiVD3^`FZm6|{SF+G`$5ugjiOxc+BpH1nMHll?RYc6E?WGtL|kJzL+I({fKp zhjxv>lp})sd24Z2kWy}V1IcDOP4wNN!V}v=`rq*;Zh!fj)%pcmr-{UJjcYsInWk#! zmt#1aH}dux1~%K0*_tGTZ$Ei*=WwDdj9M zX?}Ggs{jx>ojepC+E><$q!hY`8-Vv)BlA$*^LRu<= zt}f@ft|^?BhL8ov!Bymd7$eU(f1O@5^{=_>-$~g$llH|7*5v7C#ppw;(WHiMdaicH z?+Uof1IlaXX2ag1Kh8CARD0Cn{`=}7((CY&HV+axlO12~B%5}?(f-q)LfPU=Xa}sd z``_;?BNirQy3Oa#EZ3CBXpkKwb7vLvNTs^PcDngKMiL9qjdb0(+Y0-d3#D7d$Do0< z^1_O--QHY@C2SxoSX|5T5cACfb?F`|6$~Ma*c-}W`CsBLKhhoBlDn)5leRFq^<`}R zu`{Dtkv94IGPmTQb!5rmI6!{-QD?^?r(24JN*F1Hom!gw@|ueN(G0@+CYTCO&OmNWN`*XQ}2#QbnZKm9U2by;C}l zsWm%Ao~fMbVyr#O)8kTS+P|+fH<|QWtHuk#^Sj4&L)9wyE4D{Lg51B0-f5%p9=I@C zs@MPT{%KxaCI+e>fPnQ7+FW3#JxJQn3uSle{}bGsI+r44rDI4Zb9chV&{!N!O;8z5~K=zK&}GDA6ZUp?loE^K+LGDmeKKwsGdf= zxLCciANKle9zO{^6AEWURNWY!8r*lxiMIEkT(~D@ya1^l#9`G}r#S=x+Tzn203J?T zow#ukZ~!4w0pb8)%T-x5W(1q6#coB+I)BafW+B!6Hx>ZJS2K*rAbI@)|H}NIP_$J; z&T@`vmsSyE+`$UVKRWD?V&T}})SWN*0wa>d+AefosHsXo!rjZg3n1|K?0^a?IduGa zX3w`n0fmeA2K7bw9POp#7}C50|Lp62glrf5p4$gBhC*vCdl(01?jxKMjS=cdOi;nE zWk28}J6`zw0~~n>kaLd;oSigO&*@9pzog>DGtMukPKoOlWhi?K4ir=JT4$k5fygAel)5j z-06{dBXDxJ$q9e(!fqX5(h^n3*kE|E5R1>-<0mAI|8Pwlynw#_T?Kw#2i3=mzvoqh z4UJUw5k0gmXS?$1zy}VggkAlx+1>=&1wHA`Br&W=3423N_Ka}{GUR8d&%p<341V~Z z0l5lwRI>erS#-Gxl8UFUJnDr=H?&E!Bji=LkiH2k z|BPHDFGBvlV*V3;O>ek?5G6vwx%m}Un=~;UP>TNI>s|toL(6PjyM3k!xU)WKB-g=M z8$&NFyDFbXasT~$2mmk(CkyH$^sy4>6iz)NSlG!`>qoQ8M4|KDM`4fGd{60NF3giO5n#i^!_V8Un& zW0trif6H`A6F#k|USuM4Q^a-?K=0NGwK&w6?5FZX`Mves+>=qS;JOdefEUnZoMqU@J=noUP>4VUzvOb`3*P+0#+zLzA=`r4r* zM9qY-fdp*thY{0q=+e20F*|(PUPQl(&SZyOTh4GCM;jsI+Z+onOqEf`Ga0*|IKzQA%bD=*Z3@jt*VJCkLczM3_nNZ^Ssh<5&Fke`s-tqvBReQTuN!urV1fXIjt;jABF!YU^`?c7d(-#6HZb|btzc9P8yxSRCk@#^>|{HRP`2N3wlV7;iO%9 zQ-q_`!iQO*F_Kf(o_>!`mM8|P`;+*y0X*z~MWs1gGHcIb#dqQQvo~6aHt8XU44$*Q* z(gf|L-6|idN|lr`mCWpUUwtl~ucQ7*MaaPfNImjhA%%1f>(&8#Sn@r~7p3P^$F)#P z`?oT0ZenGq(zOF_i8a&?Ox$WIQX%^zPEkJ2YNxSNokeE5dTXbs{depTk-p?I8#>_7-Dxt<16KajMKZ zM-<41+f2Ag;@IT@=WtDijPRPs+{*V2gE`6ifM15MTt_)Nwai$zhNm)pAxSG(UDf?U z`!`=Vlul@ogA(SBTunHfYsOTQ$zZes%ZsYj@y$f`Bpr?$K9Mf9Cq6Z3Pf3gM$s8V) zz4H9*tEfXW1J%`Iv1)rHGb5RV>DGi_yiLe9EB!>x6>m&e?_gD@@@InoaxxdWWy0ZB z6X_jS^%-}PUA-Os?BjJh`Zb@dmQ|SF1 zUY&z{XYvj{BjE}#(7i&$p~1NIEe|8JQPQo z8Qq$GBuKHyM9`4FicrN){%$1ifxPTyWNExRlltbK5!_LPO@ ztvuFzR}3O$4Y;0)b3yKuq4IY18Vh=SNJ~2=JbJl(R%zKYmD6W@_3S3>@CEX2=U&Jm zR(>v1nK^S^2z_D0+_c@1|HlZ9*(0qkYqCUzl?-s1R#qPm-Fr~ehQxj6L@j?=1mE2U zt}4W~TZOAr+T<7Z*``XqS(lda|J>li=+YE#ioMqq>`wW0+PvRlcV@&0U+0hIut~FByY4RecxiG_s%}rA>2d4-ex$5ox}ZX zYe|eZgR}Hc?`pKDjS7u8LuMMc-cHNU+TzlW#`qsaT#&qBStX|N{q3}| z1kIJP_soAdZkh=By9TjoG{63j25D%o_SL&?Lh??P?72%*n>Ll)TblH~nG7G1r2gem z!XM-UJa}z%^jm`<>sLZKi5_Y!UyLLl!VBvh);Vo;gOG(p^-3i^b*}g`vXAhns zPkRI4T+*#UM=)*PiX^<>;gbM~co?KK-dohbmrct@Z5{%@MJ)2ch?)w177BQ1CFx)d z4xs=L!-f8zh?gp;695<;d#Et>H_)PTOo@#V2^!$9&-zoP8{Her$pdd+SE$bvzWpPc zBALFZNzjeW4uhpFoSf%bIM%S$E!UjdAC&CoMZPTv=^FPoUVwlO1!iWPBY&){`j%nE z!HR(egPSOl@8u*R*SZj$`)=TT$YH$SSIy(-2wpos_?!hM{}HO_hMif!4i zFp@QsBo6E*8v#Ek(ZRDG^>m$`q75dP)QMa18+4Up zmDkdRZivaQtccIXT{@r$Nof5BLj3r{+AUlYr8LhO9y?e}9&!Bz@e~3YbMWKTweR;t zVVObf%sJ?hk*>W*E!wq!TE?J_c#O$URu6uKg^&w0ZW?qRwNuHHV+_6E{}_TpY0rka za&ES%VFBZx<=Ne+^)Z?I!M*Y%yUma$11+e;#knE%+M9wEbN(>lZSm{6JX}x3m$N1W zyymU*CUjHytu?+bjy73Uj+*vcY3a^6ZQLm+pI!bdpZzvaE#cRhg3fJG??+xw;f&~{ zuiZ`!Y%=Zl6YmYTdO~fT&O7+Jf?sNsMd#4A1^l{uZ#(rbv>ktqmSHdkv+ycKQvm6P>s^m#)`56!2-Ed-b+*dLBTVrbuF&RpW|nlxvm2A(Rqq zYz(YY)HAaj+XY(pE;lBW<)*%1d~0yxm6xt=g%F0{rq5kCPv>mazYwJ%c}>p6`^mm< z8*O%E%M5u9ru}^`eEl)9O!5qFc7?+Orv3V5b?^L}%WISpY;rU9Hc0y{E*{=CC8ust zCMc6?t5#Lvr{VZMA z&23{{Q7&jFZNz!f-uYea;w^7%(QMPds+*FSzPCvfPRW+_N4x4N$mfEYW=Xr#rbgcy z!Q}NqEr}rFs7$!+q7zfu@^RLP(#E?yVZ}FdkioLPt+~?Xc#HLvS~$)OT(Z{5WsJ)v z;bjl)kWas@TE_nQF0)jfH{-<8w@`hXlp`!9Rzl2sd!<~wH=)hy8(4r9s^d7f{?;IJ zjt8qc&G$28qPJXd3YdKgU?U`3flSX~ z@mZO#5r3bz(Gzs-8qTKwupiHIk&wC?BiE{sWuPW_^Qt%ytn9Aj|XV_a^2avJ-Ey1??*h6^$ zYhc~IA|m)&5V62X28`7z&iMX~TlQT=)y+vJl2603Vqe{?Xo1mQ`Dg>@Mc5laFWi$s z&pQL4w10Cr^&$p_(omM*JaQ^}Nj|sie|@O~a??eHCA8^$>Q}vS?JY@f6c3B8`_A4- z2il`O2O?i5=&=5}Z;cy?D;+?aC6D`lDXLqCGLdJ4-q}i^zpC~AW2|ixc&2=FxG#bA<* z_jaSI(!-L1?%Q9iPqbr>cP}+b%bE`+}AV92~n7NoinC` z?-Zc2qIV+}x~)tA_Jk^uP$jSY0`Z=}8Q7hD>e(l7)WCs%e-2(#JxI3o0qQA)3ovp~ zb=}_``qyTxj(6cplH{#D#-X(qkgqkLRcrqJNtffEedLqzzg`s)%znEiEv|bvj3b>$ zPSqdu5m(KFz7*=Uq6QYcvyt??TNwx)r>q-LQMYBJ70biw8Q(Y|uPjIZ2WK(`yniID z@SV#;-qpu&q(cU>f4myE_>zu?tMiO-#FOz80wf)L5NzA{zL|)$ixs}R^me;s*`pZY zIp9LyB^d6q$xBk#=YObzbK{e~aHpA9P)r7|^tdgOK|3=C!l?0Z;$BoW! zfZ1s;=~YW#)OK7Mt&V@dV4B0)^lgpz*oD&mnXteQ=cuS=9=uxsICb1<@ngkkgs+5j zp;ZH&^6+r$rB36+hfs(d`)(&J;tvf$UwbKj;T69*ef4f~P0_Xmx z9dD;v+H*{OBSj1{nD#0C z?3gLsuN48Aq3EvW-wQh2B+H%E4F95nGjbqFUg%|Eid zVU-`JiA~Kmd%X@{%S7)&#=BPZi#zy$aR|9AnH8m`0Gm@7zmwQR1u0IKk|9)PZUXal!=YhA3$6?Zs zd|5*{E4q4bd&)b%e|#iF6C@a@#3XLCeYu-vG$qX@sx9qSW%}>>bB9JJzs$DrLB7Qu zZk%#*(|sF^cxdGJjBmvEd>Y@rL4R)CSnH(Je(p=V%jR56J=b(XYbyU3Z?_8DT~Cte zCdFhQb~|-H7<<*>S}~vM>RUDWR5DAVyt`-q0lqreAB~`v{P{#VtDVjOP`9+Vhu)*` zlT%w5mJiUY(PM0>fXSeL>8~nX{*ghA&R)S!88IEjGHi-7nb*SXuG$=R?Y6bA)%v90 zD@$F<+bdz^lW-(gOPu=y*;3N%?s5zDtQv>?e`BfT^PNYeQY~{gZglf552Un6t`)A= zoS&T6V?5XuZCo`HXmS1PxAxdd9}+`WYMtdv>t ztIQo8>_$A^7q*Q6q?I)EP(Q~O84u3C__HGc&m+35c!vQ7NMgtt<5;@pOA~pb^d-5! z+P?jt94G|db!KIJQt30F)Ap@>m@uTMW%)VU_72P8@VWT7y$ys4xA`$EZI^hbSq{5t z$<5uP*YwFX=WXw@rhHEdS+(3o;br8xHg&Gi;jTK5r)6pEUuzY~=W#Fe^-aQEF9{cQ z^%ipYCoCW&N!9ZBjJw(AV6uNjZ18F;nY4V2X+ui)9APkG*KS(}+lD(Cx#t;a59Br2 zdm_w3a`@v!jk9yg$>`br?2?1^XJu^k-$i%T*^_YAgv9OL)Z`vuY#aJNv&S-X<`f#I z6Iv{1?wt37sQfOo>K4MGS|iS^9?hbtrO+Ey-Rr@XLl`)2NAZ=sbm% z@Xc^Hz=|{uPOx5OcFYCo^&dN$TFbzL0mGJD6 zp}LfEEC-$w!Pf68J!>5`P_2}JU4FMc-Z_O#jl=W$;09t8iU3+(lb6cMPhF|^mZ-Vl z_C0J^kag^e(J4hPg8F|GrNz?I@cS7mEAnCf%&wZWj!x&6wq#zK82zd{ytYWIO#hbZ z`%-6}-!{XvdV_y4&ozGTv6%wS9J+x6P!8YLQD39#IP*2BMyYRz^KT!6UqDI?#o}Xi z-hPI_@{wY*&Bwt9&9-Is|2P7Yv(xqZNXT6Ytm~kc_{DDsE>4ng$^M`JXAR9-WL?zw zbP4qiFc}=!Yoi-xarmikq^S$np~eMf+yH2${4u)?PaI;s9>xoMtNgxQ>%+U-(7x!K8|EdftBnXs1S2eGigEIgHD>%8Ip|RYg!fT%3 zgLJ_`1)hsX(TegE4m>>>(#tQS2oay#5HTTk7S!+zSm^Iz<4)B#(((Of`OB9cf{f!p zX$2 z8jj=q#nErFz*Ftt8zZyi0ba;M5D&5R%ir75T#Q^uuI<|R(0-cI5R~Q1Hz!bsqMGyG z$w(5@2dN^Ih4U|7RjIMgdE%GQ5Um0oh}(R5rnkFN`R68zREVvJM}QiKSSlf+2$4BA zYdvAG&&U3Cl3&u3NLdFuK)W%@q2#us{%ClL7-;MN4JbGR*jXgz*@1*X5AB9JSP$b= zL#sy6CVoga9~RUvq;ncQ*VaV8n*FBc<@kr*ljWFvUCro(`AH`8@r%?aoH&RLN4}0< zvlAK&C=UW$;)H)1sKFkTz*v7)uzRb_jaJ6tFO-32AAH;b3EP{k0dBXuUXmZz|2G!! z4!k24Dcz0*iE8y~inV$i{_Fhe4*%{D3e2@ImIPa>xjMA3?B_AgL>#_)*SZy*h|EwS3s`GIrv zHTRu{sT~%~TC31xrIw|s5Bsv~(TAb~tvP{+8@y!z5)53Bc&7+wp5{eJJ|mqPb`~)I z27Y)cb=yWMdQi#%+~?!xx#a0~I><@j);~j`d8InC_ZIZjST`4BlM^Omw`G_7r8_B5 z4q5oTB;k#6KN!}7`IRnHiqmONLm^`YRrv$ ziV6!8E09T0t+9OUl^sLHNBOun6002-9c8|b9yUu9tbf5kcF>vo(oXh)$YaJZ)IfW| zU^sGNP82n9(WQm#jGoK1m&s0itMrjSsuf^y8U{)KBJC6`(K3lx3WvF1&=6`Z4$w2r zk9!CUECo|S#PLA)v2KSY|K?@sxkO4r+BoLgW6yLmGq!+dcc3*PZ8A_MnF9B2a=w!An5n05l8noXnLTVL!s{Fl* zW51+QT>h}hZKr6p=cu`GU(4Vsz*n{epn8k-9e0V1MeB4_#7xMCniv_4)T$fPiBPv( ztTneH?f#B&vlxqe9HQxTeZ&jQonS8;mbqPmF^?x)hl($l-Y{}v0jbbUBkJwJTU^!Wn5n>(qZpDj?Y%#XWAr__*+wTm2=v`&)KW)%&UG^zUzxj)| za1^~VACsp$+Ax6t5vl{T$9{IZZ@<>X%+H*%#pG7=Dp1jl>}b8a9Payud=KymtB;N- zo90|^-RgAo(uFI;av^H=V{<$osau#JEbW1J#CdKxXAZgUkuwmo-0af)nM_$j?p{3A ztF-8klIT&?#vN)!PQ^V?`wG0XD)jzbx?@J-eAroD43XJhc8K%&{qt=apt{E^JQ`a{ z=bt)8>uO)DVHp}@f5N2JGLiDK zrLFs>&U4qcu8ZzMOZBWztar5Z4b?lot$*#@olibiq}vrfwu9>rNQAD+DhWzQA)CSv z01rkUn;+d}+I#=}85VqI02HmsyRQ?+*>_tK+$R6@X#HSw%Y4Jyge9)9qT~ zRTFQ&;J=k5_2>qF*|8VyRK0sWrft98aIlLGVH!S72}#o@mpr+rByX-BTO`q@qf`*~S52Dc- zxyNMAy(>-U*^<0N+U}|kitlxyT}dO4E|h4Ga-NV|2<7vj>+h*4&ZKGdGRj#O+x_Ev z%jrZ>EyFG1Jhx&T_J0vO>(1h#ziZj+y0#l{5Z~-w4Kv4$e6tLS3(-viG0%8Z=WEN4 zw!QaVzWG8uMf*U>?CvIh!Ql4C``Nuq>?##`!h<}E&7!^~Gg@A^y^tVcz|o_Z$GA)9 zup7^^lTuZpTA|GM7ODbMmgC++UI*(Cy4+s1(1-GF4G{glZNXyj13cQv!rV4Sv#Ey2 z6i*J#420&H4eS72994SQ!ZgL`#LIQT(`eP(d3y$Z+{*3zp?h-;av9r|FE4s zBcklB>}c6DqY{x7Lc^9yq7XuMDyz&;Hibg=3PpshtWdIwlEUxt{*3Q^eD3>u|L*Va zIPQP0qw6{@I^XB}JYUb}^Rb@(E-xoV8h76q(h40=V^nm_r_QtzAl*0R(R$BF$CHKJ zBlQb4yU=y_`8g$$faL7PbHZ4P3Uwvp|wN(@myXm zyH!utF=ri~@rJqKX$!^k#)Gv#R3CkO;6ZxE*m1Zx!`tlZy=BdBBDVFOPiY&pNeF@} z${oaw&ToSWO98U_bc-1U6!%*Y0=daZOv6L@gW+R5%&fJQgZv`>yCwcfjKbKNQu^MK zzv7`db?2k3?^r4jW9~{~;lat2j~6^&?g#NS7v)8Jv@oHIaH@6knMfq(HELuo*;jOH zlhGe^oU5ZH9#E5c6hSTfYL4fbwwc}R;-{bqnRdw=x7^nId3NvW#E8_4 z(C@cg6cthBQlIutFdh+r?fVMQpWK#SHKVAeT?4_w}9=zQe9YD>kG#WSQTITCTSL~W3d;@Ja6RSh)0IzHo@iKb2T^A~s4Kd|8) zQ6pnn9u>H}+_xx8tVX85xWLoqLBn)}H}UQ2Z9$DWOr< zC%X4$(7eT$J@`yuXVKI^ejulOk+4)7br+JC8_+Y_HUtsOT8}ru?OnOmLkKX#^(G<) z3ja6Kc!a>}`odqKjODWd+K5RM3kWz@GK*<~5FU(?P1vySnF&pD?Unh{QO$;f1h+T( ztB(-eVhSOM(_qMjP`2a;;qzEk{d`IjWw_^OyAX1_X4DX0Hht6U&%PSefXm7jUW6_a z`!=B-7(}DFG+H%Vax1!H!sla9Fj!y@@lGb#q^aY$6n593ONRuu)DodTS+YTQ2?_xq zekYUB+e1wiR(c+}ge-(?2H<|8n%dxvIytkQ$@#S@`qMh2Y_Z>~`#@#wP8??s^EJA7ltZ0wJM1yeh;e0e~*n24a3 zt?!zM&(MlQGMp>Ed`q&f>1l|C_2Nb9)v(fYIXOG#GdhpV0w}(*X;j%Wq|pHBHijH5 z8~9TGycCZwM6ZM}3G7E)zys2Aff`Nq-N~s>k;x%AN|Ik_kb513s@FOAZVpMXqR*-G z0I@@tAacce*ZNjK6_+o>LlsyLi(*N1CDt~?KMKZPW5$5$=tW_X8(BKB?%m%~7(aj7 z8ivIRV%*EeyIm*gdIEJ?9ucy8G`lH(!Pf6Y|XyTpUx^ zKKWJPfkBKvEteu;Wg&##m2h+<=Tp+)fVebP{TpM$Hxus#NUhBFvpkYLZ>X=JOWX8l zb^mw2#gT(M=~P?&s+M9#$fd_YvLt+h!G?; zk4PlPX#c!y9X~Cf$mZ(<;|eqb{>Lj!nJ&VK-o}eJePXu9y~Ud(YN6Lscy4qY{z&xP4TIoSD#LPoAZR=d<3*T; z-b8Rcon}y4_t!lldnJssITw+T!{v{VdRyk}*of$kn8RaL*Cb!w#cxjwqZIj5f99Ue znF`lESKQ}8d^ZhFj)XBnsM@rLh4zHY_tCMOR(<|Nr=9o0P90f-u5tSHgO`N;IX4k7 zHKu*7DCCjCdA-8ho9@RRN}hEjQceH0CB5WmhHY`*!QEeGol~?#J6lYCX#F}YZsdTYkz=I@!5qu-1M zj|R+M_V94H9GBRhGX41cqHwz|Y>K~)1Stb;7#q(2_-Ok(PHfgcI53wfoWl1ZG{zIp zGX2HcuHWgW4&?DB>Y*OhTrsO-8y3JJ?$=)d*uly8%=TlsjF({h+ zx@i~>Wnd%Y1RI&EJ3HSKuaVd>Ta#cpI z5XuU|4^fs23!h>YeOT`GAwksW&Rw=N?tLs|s>{rKKmGi1`1-fD_XmX)Buwj7mnpBM z_aBX?E^+(mU3;oEb>!t!GF8Tu#$6}RHR&e`In=*jk#YQ_m|sQh8CWl-`hxq@>$P8L zXC=Rl@jb&|JEc;&|JzV?;jKHf(Rzl_^)h>?mc$lMf)flv>T^}6&ke}zFJI8EB(LTgMZyP?%RYN&obaHvHnl@uU!r9 z&qL~KU{kOi_(iV`#%}l<7+8cNhW8O1fk1=cm&b!3$0G>vQ;$3j)9RDssgHv(eL>=D zQsV}b=X*F2YpS6@L6l`~ojL#1z8_Agx}RKa(aKwGJ{$IE9V7@VWxtN>?SK>(bD&LU8kasr zejHLQ-n6z7{K28)koQR8CJqQC{&{uaDQ21S#u2DTP4EzER8S+*{!E%m0GLp|P;ZU? z$aBr%%}s#|v28dfJjNr`QOm#fWZrp6_vWolh`$UGGCTt1^-qI?4_0S}u1!nSDS+!F z3WMUMs68xC!Cm5OSHFvItKB`fm6zfrX!pva4^U{OIWq28bznW&Z9F!O<24O?kVLb3 zHyEcN=t*vVgiyqhMYlZ}BPuC&jpoA|f(2-&gxK{_oq=Puo9#W~&G=#Flm^#IscZBb z9(NyYHRGm-Ct_XlpDnxrUwy)b4PJ*`(B2O*<_bL}@|WYkCHDuVzQV6br*S5!S z?%h~GY}&e|lAA1gN@$M{OT@f-Hs?WKHsH1z&t3Nsj^#c$Zeo_Ad#6~$8A8Xsl#-pMo6eC;1+(~YLO$Q|! zq0(VmCm)=>`8&A!$@M&f1i zcdGD!1-E8-ri*h}+xXH=`~4Oj_Rr5z2m117&g9S%k#4SV=&VOU$@ zUDlnts_=@!~@cu7bv&eS&5Ql7JLoulrJ>5+=ApXed}gZBATrN=oo z#4-lgM;;~MHxuD=oEJy--ktTt>!G5kQkj_bE?I%$)O~UdTSP6QDQN6hNzYH7km9*D z-9^}VfChq@l-c3hm-n9u5?fD!X$`Nz2s(FWow}4K^ag!tiQog8g7?W2Iy{xrnt3KS7~IyHeX@&k}GNT42}>9cQjX zUZMBRE}`eB!75|$2<%H??D z3^0fR{Q(40>Y&Rtdq1qY@Xbmc>z>A(g;rXQXn=l78USivZbXitPPwx8a$T*RuA)iq z3Dum{HFe+ha1li(OtsTze+2Hi-X70G>6U|uY0eztAP?dECGyF4gj9FTS~zy0;C!(t zgDrlSA4C6SGGEq(cM7?-QcwA}pY=xXVa%F(g7d#=gXs{W{=P%{llgYz>QmUDY-{0Q zAmr`Ae5anh_J|Ubom#fRhpQIOzzHjyKfce@W{B9sWjvCMN7uIY!mKa`jyK{==zb;^ z#+|0T2|7#zh=ioxr24;x^F(FMbtOAlB?9rpRJYt3 z7V47t4m3mA5(tyuXYc&L^ub$^s^Dh5r>~5eMF^gl+=DJZEG521yVv3$Wjo5>`9Htr8ij&KG}-U?3xe<(t(O z)T@_-Dsl9o81RmGtJC!MmjbAwTnwJ{M`J%tq;40%SGLw6 ziK4C7ri>)kY!c+$o@gOuLtm|@<#bjH4p@$D71}0XQ-s~L`+H{wR@t*8K3|jQv?`ZLS~D0P}k&(cHN@a(T551;ki~Jz41>J z5r0>eKDxAwp*GiCmUMEX>CoTYp;MkBPuXXk(i`y=aJo@F@%bF3H3K_D&t(n%y;t|< zr?uF`DT<3_ueG|IRIA#vakF}V=t)TVGA3de6`OjIg!c{aL^|~mPwrpaC(y8gJNo_0 zkilmB14E{)si)tQON{E5lGoM9~2PH*aQXBz%+(up=U5W}Xr@5{XZdcRKyL7~JfS z1v~E=neMgIg_ay{G~6ygdir-Ad>JQlk}q7)uRf)2_qS6@AK5A50H}1czuo)e_x`U> z_?Y|cTiX500=|5b9xpQ`D5EA&_X}7j=3;lu5}~ck`^05e^&$R2H*2SgE?Y?#Ocj;` zm8S!qwtn-({0OxFz?7?uGN{+4e2v#(FS=Zr$a0FCd3Y>5U6>s%*Jn`ZM9$8S<}Htf zaxNiDeGjGhWsVvOT}^`+PPy28wCb5Ff~!Zf-cWj<%tgT6+{1kIvk#epW`xBygodAv z+AUB0yU{odw;F&FfD|PNclvpHbMN1z-6gNF)a?_o%TGM_7EjVny<-etj~0Qub*0b37xZ(W!{B>!cl++2R#a0seW)~OTwO+{b%0UDjCRP?PhhTOeHdkuDFnQ|7@eG@*IYvW`Ev1ReNpev9*-8;iek1nz3IQQkk_nPj70a57gL z2wHQ_&Lnv~nhNo@!ufYigLMThvmc7Wg;;XWW*=iaIeTP9H@`^LW(sY&NMr8r#j2(J z&x2zR{AnVh^VfF$YWYjIJL^G-Egp9?+ofA4Za*;HZ2X#Ad~**2eMr=0D$mAXn%3tw zc>M81YJ6(tWbDC4ub|>xPaS9*=jw!fDl81F@@$@z7l-9Pz56jj=4MqXj&+}1S$}W8 zHrHbey4I+7@1BT+N1k=dipnudb!Q&EGqpGUhAoO+##v90tjN@hzR^?+EB|_yl*g-C zy)Ng#C~I5~`j{>xNt++xM~3JJLN<;EHkiA}i-&>DKrhbqyPzY)~hkx3#%)y%w`0Sn+K%11ASdlZd@42vm- z!?Th$W2WFEJJb)h6~_$}7i3FrXcqr*gIAWOgnI70PEgV%x~3|}q$J2*wEO%|9=CYb zpld>NCVeZ%4Pjl^B4>`E2|O*xKHee%V4^u^z3mSw=h{*g0lQ%ON2~FFp&Lbu;==#N z0{+jCju2sCzXLlKO*sI6kcrpxjHv!Tzy<(?!JvCbrrmwY|2>D+6kHpbx(X=_D z6_PlS=IIny4&j57Qr#dS?ZWYXnX#_!A32l7>SR$>-Mh z#Z0!F{K68=af*=eeyh*;{z8Lo^0Aix4zg!R+ zkPgLh(-I^TPYMCyO?M^#!VK>XaSzgwfM8%Dx^@L?2|`6ora_7sVlF+NC_?~|=Rf3K zL#u#ldph?7#9A~vftFu&x&oumI=J5zMn%RZ2eg0)1>^NRj`%JJ)vqFZe~9Ivr+q&R z0+lGxXlc@dBww!ws%8L!$2fScU=bp4$DgoBsb`F0DMs2K^o0ySGvHxDj6;9zty@-W za1LS#x{l%qz6tohi`vv zVff+KWpzcPY@UA7tf#n1HUS?A2_1Q+L$Bh$Ua&`XNj-ACVb@XUq0yKAAZLYP3%4+b zn_!(4GeSc4d$-lw(a{W>-IyP?W-~D@7wh30;2>a6aX@h#Y4=9;xp0fAy3>zw zdf*Vcfrvs8$!9?^C60*lU+2^aL_0Vm=0F$cGvB|@E3)nY+~VcT(A-x*3EY>1V;1^& zx!JALaJ(CqC?lZ<6L$0}ZbiilCQrjy|@rvBBs5%?#)^@nF?(O5#hVUCY7gK2cJE~f-m82wg|y^~ zC*&z2krchA8vSp`Ta@FIo_+jPpnYjxU63-W;YKj$LNZ6XBK z@C*&2Q={yqoIGOc1<{xgu>_+Xi>Ay;m2bGDh%Dw`D>+xD0OWOH-xp#W20k!(Ke4zb{az;M8a1!ZH?@TDPF85Y~TRntkw9{LA?M zv$Q36%^m>ZVyuFCY-dN`n|`V~l?-8hTt1JKDRIj}?9j#us=&-;qr4!VT{}1e&Jp~6 zmd=*Lo%OM9^R!8IbPlUUj5~>0ZAc9JbW`q5R=TPO;05jNh>xgDD_bYJupsXJkWWTGZlFSPX~9u#>0@eV1T) zjw3yme41jL>|vsr(XHv1e4GiK7pS%98l&eU#Wj-RTU6cyc=5HUiE9sHbD-cH4e?hG zx_cwjYA4AA_IlnJWG_l(iY31!YVs^zhJsXIAX})vi{1NgM^whZx8XEZQio}FcFTf_ zUni8bVm@m6I{64q3_YnFu6*a)p|7-l8MGtW_nmFuf$$uk9sK&?6HkG|^UN1!)1gXE zQkNiDzu5mah3AB}*kA30D<1vimv*)E;M|lo7N4+Mc^{hG`S`j*13HAt@mkngngTf# zPS4=Fq`BffYIzQYdd6B}nz~oOD75Z->^;LRK+-Qe2Lk|n(4Ez}f7 z=1&%eA$sD-56f7(p_a;qn7Zwt8-wKDT{AhktP8>|8XRHjYsbPJj;UUuHKa`GlK)9d zPjsx6m+_#H(5o-D=QfC|s0swuA0eOhR>nF8&?y_2s;QcGpC##I1$91;j88tbnHBXK zcmA=$POMH_teUfPVeZmf7cCE36$+jA%F{8ZSUQg0sG5ZhT{hbYAYpzW%3srTp=+*C zdGeU*i^Kuu+U;u-j}e`}_bIhlptWYrud6DvYL%){vFr2-JebPOY924l@Hhg`BmVd; zB*1fb7F*|MqP~F_9@{#`Nusiqt zJ^LAbt_VtcGKIIl&{kfXwi$x-@D)5Bhcmv$?OvQ$NCk9BTtkLS7@$?TYR<{@o= zKKkRQH@_;ID^0^65_MYTdpx_Z^j6H0IE7|z4wJXix-^TQ6Vj-AYk8_j*r0386Tm0K z2c|ImB?;tBrbYEv`SpU{GB4e8;!wVMI&Rey7s_EU5a2h*$9 zO#T$Tap*W=`NM#vK{64w_vkSjL!RSB97>_m(HiwFk-do#rb(avetdvAJ^P&9a!WcK7BIPSl_f%|!mJygU7q=>&txl-DUyF>L3()NtNt&g}hqBxKtcy3>fy z)xov0_Gs(zORq1?Pn}C2O`GBe4Ww@V{C37DY5kjoO_Q?UM!c3-kp`Ga{LLwZlrJ;_ z>0am#o2vU29O4qAvC<4oRvWP$UuK7Mo#PzOMU~DuAf|-9yp?R|b6W@c-xVb>l0f$9a9v~0#`0H7~WZD_CcgjtQieI4-_xt!0r zC;DuqJIWpN>eR=vFw;-;I*!q?F{kQl>DCuHSamPS7TI#qj~A%9c8Ho4k7GdWyXCLH zaptzlf(gJkX89CfF-7;9QF&;*H(dA89jJL*OA~0JLzOY4>Q2h=HJZBWwR?kdXmeKG6lyb&A?FjHg^1HDVJ|M&JZa)53 ztIM_CI%|}HGGhT-=_bjQ)ZARj!PB;NzxW2XL*3|>t@DE1=0Uyqn&?-q(rE#l#CdIq zHaM{Z(?<^Ism=)Va_5&Qp$FXX3j5vcc|OZhMLk33G?n zk%FbX%QXh946$PDRI81vn4vN)Kq|KKXs4d=bS51J*f27-_~viO7n&$u!5`Z@HjeI4 zW!$0}6CWYVVbAYuSbo--Q`{y@XmOzJnW5Vj>WoMj`h%9)-lq$zXxcn^;suP@NzH`b z3#eyAoK-rpuD z3t96WRaf>^Uit5EoRZP(H~t#KZ5dL#c{ex6djaL#1Z(uobCY5};mSLI7KglAm}Ww6P|q{>)LEy?OiMkCLAZ6wcBGD0kZ+@boR;jInOU<22lC)K*1+u+;~ zWDUxlIeY{-chNt=oXvBGlE4>FI*UwM3tAXOQ6{bT{k>N_>data?#B5Qn2oCVi>ZTy zLr>QpnRl*jh+1#{IqXCCx*NdykKK&Bs>ZS}Rc#yZ`19)HtINe91eDOWJY1I|c%IXS zgEoPB?mLI#=q~DN_$Z~`Rs?Xn0`5Eu&Qt&0jO^rl?z z%dV2anT83}@l8BcLB$qrruaXwop0DZEE6;sQCad9+JEdqzVXb)vgdTz!rNX<&@6HH zq6Vl`9R4oT-DVj(lyUraf#(;WWU&S->~4M*%B{SGCsN07=w|=>eXe;p+wPZNK_UjM zHZc40iptqFQ9`uxaAJMnRotBV*^w>k;yYH120_QERBu$}@%YBKIa!f{p+9fTQ(w8f zd@dq&cmJ<6>cDYIrDp9hjE`7Uc>%v+Tz`7O|Nlgu@*k)RKl|g9)sI}2XB~DzdXi6e z+kMC9VKe+uNlukJBHV=U|DkUAk01Y^NMb5tP&n{v5+o%R6EzK+fRC|}^w}>BjMF$# zpFV`9xd%6kXweKuHU>Tl`ws9PUxEqpP;8YKlOohA)Um(F?M5QzFW7-zjXJ`G0dVHT zQc!AYD)o^i%gm3grvU)PEBX0gKB}tW@jc`##&qppGLDB}t3F`m(tHkRanzaVk`*ZA0)UT90q}()3#rSwQNo&LS_VV|2uxURI`Y4)1-mW;@JQ#=Ya?{%#x!8778^X zFB@Q_`Vs@asItFJ4VVpxjCO(35+VXXgA=$vZ0p{O zUI==(zkud|1|0I zQ{6{T!n=(;NV+}gF~D3-(pPaE_1P(J-CpEjAPd_k8(+Pm?5oS{C4)B+D8O}inCAuh zD5!k}y0VQdBAwe!Rkov%g2~^klkQUZ>ER1;{kdC1?LGUfs}*r{6xP&l`}*ZSHGd(- zeWt=Rkms)?J)>(7^9M&_tGigm(_df_n*c>rS`OL$Tw3Pq5Gi^kx)e9}kgw9mYUXtF zpQ3iDzPXv?NdQLpSa`qZ$f)VHP}mD%x`&$gx$E(gIY}|ctuN_a8d13iXdvA^4lav1 zTHs3Ah;Ilg?DvDjDCk#11JsvS20LEk zIkKAo`PF&QOvIx68vws6Ign#SS-oDLq$!B=(!|4wyXKS^8!dDGZN9p9#uR`*8E?qC zCh$oWykUvTxH7}7PXcm$Yl>*%=07lvzVFIE=JA$fmQxZ^GT07zUC9242kE*T|S?f(d(*Tu1j_sq+0@dgk?c<)r1)l01QJ z+(~WhEFv_+F9gYID_OAPKqHXjLATNd@dvFPE)xWGj$y^zXMA}p+faZ(a(upAn}eTg zu@y*SS52`&XH96Ol~Weu0h^Q?t8+}L?}_;Q93rTFBxle%iAB834vo>lQa#k^s>n z7pI|i#^&jk)BG9lymlmOa-=KBQi<^e9Zy=_-ppdU)G=MBZdz=#<4<8tK%%Tooj;cL zOyMT&MH-{^y(>3(&Bk{k9q;iKx-ttpo)dMVXMm z?HJ9TGVcq(+`C_39-n(=c2?U`cZ2Drt!!Up)2{h7>!6G|e(n`z>BCyTAvz7pPV=%S zKS{So{@$l~csrRtA~N3C5oe*srp`femjXLIM`3X=+~P+hoM);RuWO^!{wb|=o8qb%RjyXj=R?}GFMrhiPQ+7hjUH+ zw>w2dc|o_IxUJPWj#^WxQj&Civ@UZrFpPkd`rdmRK^oeh5nbzU?EaRnLsoLCr7!gr z1=}9EZzKxuJ^2>IzM}3}QsFwHeWX9Nna`KKWo@~!e;DHi!q^y#5LOXNZ(ZHtinF*z0P4)O$|8BtH0A%MUf`>#PTOzA8tZ{ z{Sr|!845$Uds?#|boOI*N<14^H>>lTQnfo68%e_CLlp%@il%%0rXO8Dn!XC#v3q9; zC6@yCZ0SS_v^J&8LBFUE-4)7s+j-)ov_pb0O0=B1RiIPgsnbbS#T--&BQGH?o$z2v zpI@8KU>vFF*O7>>Z&)nkj+LlS0*%PUqUiVMBA#GrYs#8LvY6g%TM;*KO7Sb*Y~lKE z2-~p;nP8)uLY?O35Vs~UE;C&YgjBXT8#&8;dM5>}as!XB?d5qK{nPMDiFKRsW?>xU ziA?M=c7JA{QZ)!udR%}ZwD={{srQ;22PHGCw)!{;KJEkW_)S$UEg_w%W@>QBza+c1 zd79BKg<$Nc+>Fl%EpeBZK8O>#BMCtsplgF-Goe2E8`jvK5U@$uF`wZm)N1)wV~&et z(#f$w4vhzFaa`9;TZsI)#U`WNr)KVP@{gJn+o)c}?A(CfsoR5s;`9ABy=+M0xZ9GN zA~_#+v(6KF^j+7OM52>OonP1K)Siu~>ltq9JibC-a~Qvym2(n@W|th($>M+W z%B+)ZhOKgzvZAO+@~c~jM+75rb))>;KU7Y)csf&n@&uAm#jm)3hYQ)PuJ-53N)P9A z*U=52zNRfz!?2upkX)4#B5k*KNZ<^5u8~iiPyewwOvzbg8b|)g&CUP{=?~45XJl7_2M{)Mxb)x!%j4qNs1mBuh;G#BpWiAAcPbn zJaLO^OR=Q^fWdz%c|zx%DL*DZoA8Y$zE&_qP7(5v2}xnR=(%<(>tB3LU|Ikz#(8WwgTjgOY{ zmNe_aW50EREUHZ_zZiTI_F)k;FLR`GLWVwJnV#`CG`MD__$eWe5y;m03>-$x-^uU_ z@7AW(3;+1;9fKqxsC)X6Zj>yAR3hKW!cSxkrorSG8m`K)7SVduK+z>6>H(z{j4R$- zd{|He((aq74B!E}R()Bwu1whl0)Mpbtl87Lcs z+vWYO{*47R?<4&zQvIutx%w{pah`m3As@Q9@TQo*n#JL4`wn3iZLlb11e0|_t4`0^ zaKC2lb$Li-;-x&NbuzAGt6lhvW3%mv%`>cNe+hmA`ZQtl^K>$iL0?i|^0u6pQkf5X zB+Y$9j-jTXVcbaK3;n!{Isj$09qr382YRlRWxU+r?@R2goR=l170ddT_*B{)8Oe`S zo6UD!dP|XYO($VaVb7}qwc0}`IjB6CRX0NVp(%_tFba{j`Lx!H~V zxd`-#P8$Tg)KM~D_oEaE!)YP?+|2xnA1e6LN6Yp1Oe|oo=~AW|?)q8$}$Uk3cb4Qxwdl&~lBKmt^^!)Mh_gk*fVW^#jwRWC&m(p%X? zl}-0uA(BjaGGly^KhG%iANRE_8+`n-)Rn@l(R;*P&cn^?_nWqL=>wQR343W@Q9I<8 z{WNm_aKGw2b*S%uh=1%`IV=4-;)cca*)``5`Q946Im59rD{>_gQuS=JM=|!d0YA*u zBz$VqTPLd*^}guI94wgI*P*y~?ygfPoxLbR7LNOVP0xi!0>Yo~;JO*L?ev2f9{TSo zQEK}>aVmN74J;L)b_go^=L99f-f#z^K@g5`X5Z&+a%_scauW%-h&((+J{A5`+I=kX zDC5xl#Q;33>jwy;9}yY4pZV#oc~bQPCtJjy!v%0hIxzGUlak_MOaWI?&wnX>f~GqG z@nP06tXp9iPcsOOTI2ZW|1I!AqH^qh%E0BbF+1Ez3{$O5 zJnX=6;da5M>Izbro&I+grT-4ZA!{U6R7xiO#VHLmDe%4xqwDVy8vsE(hVtd;iNXRm2a+C|({T{Qj-+Ck+G|1T)T$ug)Ft**ptjvax z+9zY&kMFubeSs6u#9tH=eQ0+`OC8V=Rl!OM%@(WF|J@QqbQ$7-;gb+UgUJz;AWWu& zP$yfA_?S{MOTBbX#2vZrsjRFlNZGJGi7SDa6RH4nNti(kP|s!v9YDT?klq7ls5>O& zoci@^l#lGP_%|qY4_yvcfK^{90|rC@r=b7fJmi&2%?`dG?@U>?&+&*ohaU`$-n73O zx`X}Hu6^cNW8ARtL~+Pw!w_<7#b{!z*j614@tN^$C{75- zSxzi>O+FYf)}n5zf+HMAR^$Ho{0Nm~(vyqbdnU_^5-1)WxgJNnh7_3dI%SK^%g~F+ z&VnUB&`4H9Cr;wgpBTfX_Lp>tjK)G7pm9IZ;^S4gj43sNuzi5Ah z#o@uYtbhNX@KC@u!AFz?8{~H;2Q8pYbas05!Wd6LAoVW@L^KC>H$%dc;lri)p=5=i zQ+bbFf~yc7@gFBV`bRI(N47{2CG5*`|H*gE!A6Da(-5n16HonxfPPeXOL8KMv*{ha z@?0~>rR5-9k2mj(C-Asaeg-e6|DjxUyi+^(Ku4|_6k`z7eEFR#&n3D*IIjQ~6q0nal6~9Al@`=@ zdm~%^+6Rm?0W4F#*(uWTEl9b5lN$=|V8LvyG>)$$2f`BH;B8qgR+V@+*UWpapJglg zb8+HZmu^Ex<%ow(-{%&EW;pz@^w@`ZBso~nJTGHQP@nCuJP8)dFOn70e>bS6nJYs3y=F<Nx!#|2-S-DZA0g$2=AdFWhyhYbeX5g9%nnoKK&t0|hTeCQK1-8Y`pRJ)Q8-!9UL0q?c;=)vC9BGq(%atcj!TdU2Jx;b8m|#A0 z(<2K0&#z)Yq|07phdL2eJl1>ig5B|L*NMt&OV)5IAq`D6(TuS?B9%3tv?)rOXsUVb z)H^Fx{;jm~A$l^{+s$sU0HKrqMdJ*l-X-n5BDF;8zO<64E-q^t|t7FI)N=qTu z#&O6?q>%g`t%Js=2zT~9NLDve>uxY6>>|ne!O^ah5u<0Lajhzjh@>b?E^aI~Ub6Ru z)5%WC#3OqY-HC2TQSp6}WYGx!z7%EAuq)fiK7I7&n?>XEN#3sM!S>%T3OwcvN&a|% zv(xn@v!vCltm=p~)1K(B?YeIt|0*2XV(s8ybN@gQ5y+4}^hT;4bO@KkGrFKbjjq9d zjm1z!mfa^8YyygGFs_OkWvOhnG0t^{58v0HBA|gk&N@G{LQ((>8znR^@1WQlq$+I| znC$pjLc!TtlkhffwZ&Y38gi?sPxpPfxZ)-u;!k zRNElf8~x3kH^=Ikv8cX|>_fxT*&qeD=zA$M*s^`lY&sq_970KU7tJ$%s>VjG-S;5z zyp0HazL*5uMqg=Ofc-|(krYe3ZI;LR{ob(#XO8FFj=aBi^*ZnOLgtCu2Kmk`0rt$B z#JmSm%QgKO<&TJ0h@TO13QWqhywH#3mCn(Uyj23qtEI1B#IG)K-iEb{x3y`i-%AJ6 zUGbOIDH{9qp3`0jz%*rLuF++G)6rvB3w>&3V!`2dN{aiB+GcyOnX;e@VaHNw=Idk~ z4pN4TV$6C?UySQ31Ha1{i}3%Ptz5p&{)F8|@jcKo3%xurT!eJG3s6TrPm#wAEPPGv zB*Cpr9XE#BZnxb1ako|eE*5%Gxe0p69lW(kTaQu%RlM66Q&GfW zjo1UQN|<`K+=o(jU&cS;;|Tb{AiV@UJMLQb|$95IVnIF+14R+Kvn_GQD{y z$zArUg982`hc28-iews=wMVp-?K_P9N$q_b?%7xKs%c+lIy+qD8al^e3?Uu|AgP5{ zJd1Kh92M{5Y|c-s^h&a)P0`YpbEZ_2g;kPI@Do!FgIOc_1qHFU*+H~9KiVbvdU2)Z zG`!c(Mb?L@U`Z`^hGTpQ=F~H#_AARiFAxotoUz@h!oj4VMNM3}_FBRe3+VK6J9ZMk zd|oL0`heTS0QqDNmg()VYMJACooz%Ru==RP7QCLbie{)cR2-sR8|)8dTz|KUU0<0b ze=%n#ZIN)x>uVp?#Lu-g&F-!+e*U1}xpyiEkpkSLl;W!UC!Vc&2n^gOOHkxZsNQ%7 zO!({h(^L=Eh64Zug$#btW?8N(QAPiy))z6LYJbV^Lv+}0Gtz(~>4h>}3m{S_9Yy$q zicaOw^Va?@-C-)F-hJw?SML*PRsHs~Vii`{Zl1^-xuCU+THx6F0}D0B=VC61NTFX!FFMwEJ}TA1y%^E_IRf7H~|Ty3#y9iYQFb! zPW!}=nb++>*nn1YTF1~lH9(5nsm`)xkI+^#t1Xe#*%Rq*OY=i7#MhX25AS|A7q}Kd zdhT`2OVEZhd3$usaZ}3ixN>DaSc7$5N^JZDf0a%-eM)<2_svnA15<>##Ca+8=&patkY&gllN-tTn@$k>mtVXc z(M$g)dSd7bXW64|Ci=+C^3jXh_8J{)G67UMkC=nTd5WXutFN)kRx)uF7`_Z#Y~>ERC8w* zS=Ai5+%8gA%x{>u%3ka**VyVbmT}~M_6Q&#l;&|GDw9tQ-9qF`aOx5~q)6q`_=WMZ z%yH0aiRi_PUgZ-maZ^n*7#Pn5tfXP`j3911%5h7-1roH>qc_-w-x|9(*eAB}Fge+5 zZ-VT1s~N!fUg6%uG<{I##r*;5Yajq##MvF8laacm{P|J6h%%7$4E;`5KedOH=ARtx zpCIci=!0)&n;dfrY=aKfSuvw)E{_Y;JPe(V%h)3hzs&KrsJhAIC<;YPX>VDJ1RDsJLQ%_D)B|W))W@k(&Yj0iS zXeQazMhm~1jV1kX&W12${K}gXH7abH+i(46z!3?EbSjrpl2gQk5w(XV2^^YCR zcf#_M=@`i-_*?Y&7x4qJo_z|&VvQl?F5^Gh=vllBa=wS&HJE@D?!L^;D}vV5-u)WX zufhTz!&B){eIdl1z5TV91rYoE;K6BKS6V_lvtO5nXW+j$Om>SKx#Y z+&;KVBA6P^Ye`rI7CvIq9F`dTNP9r;Ml~@#EghjCuCCXo_c)$(QC-(qejjSF9dr)T zP-(L6OdKy?&I(BJ?is*Rf%$iw<}d(k!X&Pya;zzQJB@}G)ev9$N-$wT@un!pgO724 zwa{0_T#-p6EBpHi8p#Nnk)JT3f4Q)Urd^S_?H5F&7yS3VB7~sK?@4n!e6;${AE-jW zf$|?!+Xtlqm*T{MR}qKN-M2s)Q%bjj+=Mj`W3LPoj(63FHKk=5D6ic5EeCvtoa?WW ztDTX|9o3(9{M8q~2bjGRi}7|9R&NFfyxPG>xzK(-E*y*=zl_T;Ge2eI&5G2+xao~d zt72crg@w_>GpbpBOKPO0d^{XxWvIoOHx0$3;sG;3vM;W;GzM$WvcU&_N`3Ej29bV? zl`%<;k)~1fc05u8k0TZoS_s0SQ1=_;O{3O-PUByy>8>A6BLw062O7km8~kU*rB*Vd zK@`UE`{ zR~zzgxUFUWtY({tDH6hbj=PxE11bvSA!B|Cjqm>?1L!|K`v0d&N=u6J8oZA1T@6%S zbK~Yt1>Pv06N@jOfJ%|GLLagOFb6EAF(WgQW(iv~Zw>wUV0!k<0GY>~bu4g@@4J(Q z85ZZ4EW-gr8bEaN70LvhD5QV(kat|$2uQO4s%vYZu6=z>9HRTJM>ax;hSPZsl5+L^yYy|;0Eglv_q>`QYHDat;QeaRric`94SZY;yt z6X96GNy)yAElSFgWGu(N6vH6Ii5!eIdyGOc=br01|G;xSzs_~d%=eo4em>v(^SKdBaNGXVs7_R_S;pSkDxw-eB0UBT&|0 zH>TlkKo|hP3?yp~A)&W_Z~(cZpCF;~ja5|RC+r1M zPckykTe?C}o3ODx#I=LqR~@ni?QEW-oHTb=6?dw@6z+p=5OvDZ9;pEOc?JZlkF*Pz z(tidWnOP!)U`{_;`m;E%QP(TawIbPIVxm8j3v6-Fqm~n*WeU^Ks)|3L3_H4?D7}gZJC{uc;#f7j`-@n=Ojbv@6NsQQ>F01$yMzs1BoDtTc%R|U9 z|42AemMEU)D4Msf8N+1gMhuIuJk5j3aVbxjI6>kDZ zp(4RHw+Cx0pu&!vLrrN~!Cvt8YQCF!36|0ia@FSN2B&=YfC2Cn0x(Iu;~_j4UYVWH zQ+pxiZ7>1#;ufhok!L1jOL(a_wG;xCpsidR9SU%Ox7PIR+XoAeWC#VS?f- zM#_~M394}0#2A+sF=1NeJESP%optC-a*enU(5Eu0(ofb$suu5=x+_>J7EbGCKH2^rQdZdR5^|bG)~kO z+lEGmyCSr3u$=l93a?pFO~X&RiIwtmip*u~ns7&1*EclgYesn6ByjlufivB*gC<-Y zDi+JPt}5JMv_#5vo65o@Bl8^a3W3nu8A~#Eu5>WfK8`!0>CRNZj6{G*O-~fx)gxQP zV^m`1$SqB_5P!=8WGcxQ-Uv=1rz6-@P=i0!@bGtYZgaPC_u=fSC9qEFnfy!YvLcez zr1x$yGvs+cM|EE&OAdA>&saO02+Clbwu0;Gm6OU4Ova;~5-|gB9#m>+Glv`<{qULG zc)OEDS8FpKx~y1-1zM!ots@B6;1ts31f4#8?q09!^@?my&wA*a<`-b6co)_h;R7R| zevn`oaD-@tM1?5N(_OXB)QL9L&e;(|vZW{A2G6+9&BM@x2Ez3n(N;^F8h$ny$=>a- zt;rj|Bv5gI1rOZ;;?F?X840eF#F7i~Rr?w4^G@{CD@3dhj?NEt5%^GPD`~z1cTxKw zG@y}b{hxYVjrKANdAwV!J;_l%nQRFoAAa>8;EU3(q%j6LBsjmy%@H!%f(MNT_{irS zrJm~Sh{@_dHH^CSoQn78e;M#Q5%t@RF!gD-MZ+FfnN%~9<&zhwBaL9HGHEvtAzx$H z5a4!mNt7t0j%KLS9VYGRu+S_is;5kpOLjI29DMP zr-^HKrs!{)G$?+5+8*%Gv-ha>cka#;ZFcmh1S_Y@557}&lBj!m*16Z!SRMr;ParVW ze;@Cii`bFs7pNG@Zmi;yEWdS-ia;${jIz# zkJ&6v5OK!UZF}C#g_INVNw^li>TDa|VGe=Ilf!b1(|8S^EJ45LTw1j-nLD*Vr$tMi zvX;Kwc}@kNoTgPyYIwY{{0YyZxBLxom>0QM!aq5w}%<&fFKMKESU_sq1tOf~OHf zWPc951xmjmD95TePFW#m_{?7y@q%N=)Wa-p$h|@!=nK$#+P~(W>nb|n;cZdUvt>Ln zo^t3(zeLX+=E8SrZK2`zxR3Ho(`2v*R$00?p~B|j%V7m#mjANl)Q<2)Oy%ElK<~fJ zvv{x0Mc#~jVis`&=WjgznAP6ruExGQJJs@(gIaNUMC@g^4s(kFF6~37_WAZLmDjnP zMgh2YiTqLm3baDnvD25+@s59OvB0u?2vSja8$;>F39*cr=-UANsQ-ThMi4 zdtr-Yh^mSG!n~uC_mP6|eYT#v>(k`Bkk@MIS%a3w{UUen1646v$=St_>Zo^lWY?T| z3DK#L%KiXnO7BT%t2HUX7tamX7;IDuFH8t}zxsyTw$u%4ni$@VQi;Ye1$G_&*0yZkPP8dD9b^doL3cryQO2jD8Vm_~IpAb6Z;w-X zJ1czmH_}m(B!Pp1I!^|UCI<)h|G{ehZzc7=EY5%5gcP0HX5*D9Y}E&D=2-@@*{AQr z0(J}x{{>vawJ}sl-h4?>31g3I3ZmGjF`%IbA2qY9cRh=;^5GDv6MJgJd7 z7~21Iubv(4=_u1_4mn&oN@r^jczdNGybR7F98KwO?uSpSy7yGnv=r^ljb(EqHQDlB zwP0v$&`gWU!Oa#=>eYsD{=Op0OPkW9IOZY`Q`>EFZ|ZAKG0ljdTivPeK^D+v*67er z;@7ks5D#I!C9LH0z65Dqi;M{rBX4-s=Db5^CUm*%Ez8jw{v2Uf8$;$EY|eUKV_(Zx vULmcHFCI|Y5eOXT2@CpL0Z>m?RV;}VoW5h(A literal 0 HcmV?d00001 diff --git a/webview-ui/src/components/settings/__tests__/__screenshots__/usage-settings-light.png b/webview-ui/src/components/settings/__tests__/__screenshots__/usage-settings-light.png new file mode 100644 index 0000000000000000000000000000000000000000..79d87f53949618703a3b4bd060281fbb1fd4c7a7 GIT binary patch literal 66381 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 jcUO-V!GQ Date: Wed, 28 Oct 2026 09:45:11 -0700 Subject: [PATCH 04/27] fix(usage): wrap long text instead of clipping it at the reflow width --- webview-ui/src/components/settings/UsageSettings.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/webview-ui/src/components/settings/UsageSettings.tsx b/webview-ui/src/components/settings/UsageSettings.tsx index 1db7ecd019..9f1efc1c1d 100644 --- a/webview-ui/src/components/settings/UsageSettings.tsx +++ b/webview-ui/src/components/settings/UsageSettings.tsx @@ -330,9 +330,9 @@ export const UsageSettings = ({ className, ...props }: HTMLAttributes - {task.task} + {task.task} {primaryUsage(task) && ( - + {[ primaryUsage(task)?.apiProvider ? providerLabel(primaryUsage(task)!.apiProvider!) @@ -387,9 +387,11 @@ const Block = ({ title, children, testId }: { title: string; children: React.Rea const Stat = ({ value, label, hint }: { value: string; label: string; hint?: string }) => (
-
{value}
+
+ {value} +
{label}
- {hint &&
{hint}
} + {hint &&
{hint}
}
) @@ -413,7 +415,7 @@ const Breakdown = ({ className="grid grid-cols-[8px_minmax(0,1fr)_auto_minmax(40px,25%)_30px] items-center gap-2 text-xs" title={row.subtitle ? `${row.name} · ${row.subtitle}` : row.name}> - + {row.name} {row.subtitle && ( {row.subtitle} From 010a565cae34047206932e2f7432692ea077541a Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Wed, 28 Oct 2026 10:41:35 -0700 Subject: [PATCH 05/27] fix(usage): address review feedback on quotas, cache hit rate, and retry --- packages/types/src/vscode-extension-host.ts | 2 + ...bviewMessageHandler.providerQuotas.spec.ts | 64 +++++++++++++++++++ src/core/webview/webviewMessageHandler.ts | 25 ++++++-- .../__tests__/copilotQuota.spec.ts | 24 +++++++ .../__tests__/providerQuotas.spec.ts | 50 +++++++++++++++ src/services/language-models/copilotQuota.ts | 21 ++++-- .../language-models/providerQuotas.ts | 3 +- .../components/settings/ProviderLimits.tsx | 21 ++++-- .../src/components/settings/UsageSettings.tsx | 4 +- .../__tests__/ProviderLimits.spec.tsx | 60 +++++++++++++++++ .../settings/__tests__/UsageSettings.spec.tsx | 10 +++ webview-ui/src/utils/__tests__/usage.spec.ts | 18 ++++-- webview-ui/src/utils/usage.ts | 6 +- 13 files changed, 281 insertions(+), 27 deletions(-) diff --git a/packages/types/src/vscode-extension-host.ts b/packages/types/src/vscode-extension-host.ts index bf1b8e0767..e2808ebce0 100644 --- a/packages/types/src/vscode-extension-host.ts +++ b/packages/types/src/vscode-extension-host.ts @@ -160,6 +160,8 @@ export interface ExtensionMessage { }[] githubCopilotAccount?: string | null providerQuotas?: ProviderQuota[] + /** True when the quotas could not be loaded at all (as opposed to "no provider has a usage API"). */ + providerQuotasFailed?: boolean mcpServers?: McpServer[] commits?: GitCommit[] listApiConfig?: ProviderSettingsEntry[] diff --git a/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts b/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts index d83aa92aac..914b9520a4 100644 --- a/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts +++ b/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts @@ -22,6 +22,7 @@ const SECRET = "sk-super-secret" const makeProvider = (overrides: Record = {}) => ({ postMessageToWebview: vi.fn(), + log: vi.fn(), providerSettingsManager: { listConfig: vi.fn(async () => [{ id: "a" }, { id: "b" }]), getProfile: vi.fn(async ({ id }: { id: string }) => ({ @@ -35,6 +36,7 @@ const makeProvider = (overrides: Record = {}) => describe("webviewMessageHandler – requestProviderQuotas", () => { beforeEach(() => { + // mockReset clears an earlier test's mockImplementation too, so a pending-promise stub cannot leak. quotas.getProviderQuotas.mockReset() quotas.getProviderQuotas.mockResolvedValue([ { @@ -57,6 +59,7 @@ describe("webviewMessageHandler – requestProviderQuotas", () => { providerQuotas: expect.arrayContaining([ expect.objectContaining({ providerId: providerIdentifiers.openrouter }), ]), + providerQuotasFailed: false, requestId: undefined, }) }) @@ -110,6 +113,7 @@ describe("webviewMessageHandler – requestProviderQuotas", () => { expect(provider.postMessageToWebview).toHaveBeenCalledWith({ type: "providerQuotas", providerQuotas: [], + providerQuotasFailed: true, requestId: undefined, }) expect(log).toHaveBeenCalledWith(expect.stringContaining("secret storage unavailable")) @@ -125,6 +129,7 @@ describe("webviewMessageHandler – requestProviderQuotas", () => { expect(provider.postMessageToWebview).toHaveBeenCalledWith({ type: "providerQuotas", providerQuotas: [], + providerQuotasFailed: true, requestId: undefined, }) expect(log).toHaveBeenCalledWith(expect.stringContaining("Failed to load provider limits")) @@ -139,6 +144,7 @@ describe("webviewMessageHandler – requestProviderQuotas", () => { expect(provider.postMessageToWebview).toHaveBeenCalledWith({ type: "providerQuotas", providerQuotas: [], + providerQuotasFailed: false, requestId: undefined, }) }) @@ -197,6 +203,64 @@ describe("webviewMessageHandler – requestProviderQuotas", () => { expect(provider.postMessageToWebview).not.toHaveBeenCalled() }) + it("keeps two webviews apart: a cancel from one never aborts the other's request with the same id", async () => { + // Each webview has its own provider, and both number their requests from 1. Their loads are held open + // at the profile list, so both are pending at once when the cancel arrives. + quotas.getProviderQuotas.mockResolvedValue([]) + const releases: Array<(entries: { id: string }[]) => void> = [] + const pendingProvider = () => { + const provider = makeProvider() + provider.providerSettingsManager.listConfig = vi.fn( + () => new Promise((resolve) => releases.push(resolve)), + ) as never + return provider + } + const sidebar = pendingProvider() + const editorTab = pendingProvider() + + const first = webviewMessageHandler(sidebar, { + type: "requestProviderQuotas", + requestId: "provider-quotas-1", + }) + const second = webviewMessageHandler(editorTab, { + type: "requestProviderQuotas", + requestId: "provider-quotas-1", + }) + await vi.waitFor(() => expect(releases).toHaveLength(2)) + + // Closing Settings in the sidebar cancels the sidebar's request only. + await webviewMessageHandler(sidebar, { type: "cancelProviderQuotas", requestId: "provider-quotas-1" }) + releases.forEach((release) => release([{ id: "a" }])) + await Promise.all([first, second]) + + // The sidebar was cancelled and is not answered. The editor tab is still answered. With one shared + // map keyed by id alone, the cancel would have aborted the editor tab's request instead. + expect(sidebar.postMessageToWebview).not.toHaveBeenCalled() + expect(editorTab.postMessageToWebview).toHaveBeenCalledWith( + expect.objectContaining({ type: "providerQuotas", requestId: "provider-quotas-1" }), + ) + // Only the editor tab's request went on to the service; the sidebar's was stopped while loading. + expect(quotas.getProviderQuotas.mock.calls.length).toBeLessThanOrEqual(1) + }) + + it("marks the answer as failed when the quotas could not be loaded, and not when there are simply none", async () => { + const failing = makeProvider() + failing.providerSettingsManager.listConfig = vi.fn(async () => { + throw new Error("secret storage unavailable") + }) as never + await webviewMessageHandler(failing, { type: "requestProviderQuotas", requestId: "a" }) + expect(failing.postMessageToWebview).toHaveBeenCalledWith( + expect.objectContaining({ providerQuotas: [], providerQuotasFailed: true }), + ) + + quotas.getProviderQuotas.mockResolvedValue([]) + const empty = makeProvider() + await webviewMessageHandler(empty, { type: "requestProviderQuotas", requestId: "b" }) + expect(empty.postMessageToWebview).toHaveBeenCalledWith( + expect.objectContaining({ providerQuotas: [], providerQuotasFailed: false }), + ) + }) + it("ignores a cancel for an unknown or missing id, and for a request that already finished", async () => { const provider = makeProvider() await webviewMessageHandler(provider, { type: "requestProviderQuotas", requestId: "req-5" }) diff --git a/src/core/webview/webviewMessageHandler.ts b/src/core/webview/webviewMessageHandler.ts index 207403c5da..11055fe2e9 100644 --- a/src/core/webview/webviewMessageHandler.ts +++ b/src/core/webview/webviewMessageHandler.ts @@ -131,8 +131,17 @@ import { const handlerFor = (apiConfiguration: ProviderSettings, provider: RouterName): ApiHandler => buildApiHandler({ ...apiConfiguration, apiProvider: provider }) -/** In-flight `requestProviderQuotas` work by request id, so a cancel message can abort it. */ -const pendingProviderQuotaRequests = new Map() +/** + * In-flight `requestProviderQuotas` work, so a cancel message can abort it. Each ClineProvider (sidebar, + * editor tab) has its own map: the webviews number their requests independently, so a shared map keyed by + * request id alone would let one webview cancel, or overwrite, another's request. + */ +const pendingProviderQuotaRequests = new WeakMap>() +const pendingQuotaFor = (provider: ClineProvider) => { + let pending = pendingProviderQuotaRequests.get(provider) + if (!pending) pendingProviderQuotaRequests.set(provider, (pending = new Map())) + return pending +} export const webviewMessageHandler = async ( provider: ClineProvider, @@ -1576,7 +1585,7 @@ export const webviewMessageHandler = async ( } case VsCodeLmModelsMessageType.cancelProviderQuotas: // The Usage tab was closed (or the request superseded): stop the profile load and any fetches. - if (message.requestId) pendingProviderQuotaRequests.get(message.requestId)?.abort() + if (message.requestId) pendingQuotaFor(provider).get(message.requestId)?.abort() break case VsCodeLmModelsMessageType.requestProviderQuotas: { // Always answer (unless cancelled): the webview shows a spinner until a response arrives and @@ -1584,8 +1593,9 @@ export const webviewMessageHandler = async ( // carries the request's id so the webview can ignore one that has been superseded. const requestId = message.requestId const controller = new AbortController() - if (requestId) pendingProviderQuotaRequests.set(requestId, controller) + if (requestId) pendingQuotaFor(provider).set(requestId, controller) let providerQuotas: ProviderQuota[] = [] + let providerQuotasFailed = false try { const { getProviderQuotas, loadProfiles } = await import("../../services/language-models/providerQuotas") @@ -1597,19 +1607,24 @@ export const webviewMessageHandler = async ( }) } } catch (error) { + providerQuotasFailed = true if (!controller.signal.aborted) { provider.log( `[requestProviderQuotas] ${error instanceof Error ? error.message : "Failed to load provider limits"}`, ) } } finally { - if (requestId) pendingProviderQuotaRequests.delete(requestId) + // Only remove our own entry: a newer request with the same id from this webview owns the slot now. + if (requestId && pendingQuotaFor(provider).get(requestId) === controller) { + pendingQuotaFor(provider).delete(requestId) + } } // Nobody is waiting for a cancelled request: skip the post. if (!controller.signal.aborted) { await provider.postMessageToWebview({ type: VsCodeLmModelsMessageType.providerQuotas, providerQuotas, + providerQuotasFailed, requestId, }) } diff --git a/src/services/language-models/__tests__/copilotQuota.spec.ts b/src/services/language-models/__tests__/copilotQuota.spec.ts index 65996ad300..413532038d 100644 --- a/src/services/language-models/__tests__/copilotQuota.spec.ts +++ b/src/services/language-models/__tests__/copilotQuota.spec.ts @@ -192,6 +192,30 @@ describe("getGitHubCopilotQuota", () => { expect(fail).toHaveBeenCalledTimes(2) }) + it.each([ + ["an HTTP error", async () => json({}, 500), { ok: false, reason: "error" }], + ["a signed-out answer", async () => json({}, 401), { ok: false, reason: "signedOut" }], + ["a missing Copilot plan", async () => json({}, 403), { ok: false, reason: "noCopilot" }], + [ + "a thrown error", + async () => { + throw new Error("network down") + }, + { ok: false, reason: "error" }, + ], + ])("drops an older success when a forced refresh fails with %s", async (_label, failure, expected) => { + const good = vi.fn(async () => json(businessPayload)) + await getGitHubCopilotQuota({}, good as never) + + const failed = await getGitHubCopilotQuota({ force: true }, failure as never) + expect(failed).toMatchObject(expected) + + // The old success must not be served as if it were current: the next normal call fetches again. + const retry = vi.fn(async () => json(businessPayload)) + await getGitHubCopilotQuota({}, retry as never) + expect(retry).toHaveBeenCalledTimes(1) + }) + it("shares one in-flight request between concurrent callers", async () => { const fetchSpy = vi.fn(async () => json(businessPayload)) const [a, b] = await Promise.all([ diff --git a/src/services/language-models/__tests__/providerQuotas.spec.ts b/src/services/language-models/__tests__/providerQuotas.spec.ts index b27a7830aa..a8cfbdbd38 100644 --- a/src/services/language-models/__tests__/providerQuotas.spec.ts +++ b/src/services/language-models/__tests__/providerQuotas.spec.ts @@ -438,6 +438,56 @@ describe("getProviderQuotas – Copilot window and misc", () => { }) }) +describe("Kimi Code authentication", () => { + beforeEach(() => resetProviderQuotaCache()) + + it("does not query an OAuth profile, even when an old API key is still stored in it", async () => { + const fetchSpy = vi.fn() + const [q] = await getProviderQuotas( + [ + { + apiProvider: providerIdentifiers.kimiCode, + kimiCodeAuthMethod: "oauth", + kimiCodeApiKey: "stale-key", + } as never, + ], + {}, + fetchSpy, + ) + expect(q).toMatchObject({ ok: false, reason: "noKey" }) + expect(fetchSpy).not.toHaveBeenCalled() + }) + + it("queries an API-key profile with its key", async () => { + const fetchSpy = vi.fn( + async (_url: RequestInfo | URL, _init?: RequestInit) => + new Response(JSON.stringify({ usage: { limit: 100, used: 10 } })), + ) + await getProviderQuotas( + [ + { + apiProvider: providerIdentifiers.kimiCode, + kimiCodeAuthMethod: "api-key", + kimiCodeApiKey: "real-key", + } as never, + ], + {}, + fetchSpy, + ) + expect((fetchSpy.mock.calls[0][1]?.headers as Record).Authorization).toBe("Bearer real-key") + }) + + it("treats a profile with no recorded method as an API-key profile", async () => { + const fetchSpy = vi.fn(async () => new Response(JSON.stringify({ usage: { limit: 100, used: 10 } }))) + await getProviderQuotas( + [{ apiProvider: providerIdentifiers.kimiCode, kimiCodeApiKey: "k" } as never], + {}, + fetchSpy, + ) + expect(fetchSpy).toHaveBeenCalledTimes(1) + }) +}) + describe("getProviderQuotas – coding-plan providers", () => { beforeEach(() => resetProviderQuotaCache()) diff --git a/src/services/language-models/copilotQuota.ts b/src/services/language-models/copilotQuota.ts index 6a8c6be07f..754edbeca5 100644 --- a/src/services/language-models/copilotQuota.ts +++ b/src/services/language-models/copilotQuota.ts @@ -91,7 +91,7 @@ export function getGitHubCopilotQuota( if (!force && cache && Date.now() - cache.at < CACHE_TTL_MS) return Promise.resolve(cache.result) if (inFlight) return inFlight - inFlight = (async (): Promise => { + const fetchQuota = async (): Promise => { try { const token = await getGitHubToken() if (!token) return { ok: false, reason: "signedOut" } @@ -112,15 +112,22 @@ export function getGitHubCopilotQuota( if (!response.ok) return { ok: false, reason: "error", message: `GitHub API error ${response.status}` } const quota = parseCopilotQuota(await response.json()) - const result: GitHubCopilotQuotaResult = quota ? { ok: true, quota } : { ok: false, reason: "noCopilot" } - if (result.ok) cache = { at: Date.now(), result } - return result + return quota ? { ok: true, quota } : { ok: false, reason: "noCopilot" } } catch (error) { return { ok: false, reason: "error", message: safeErrorMessage(error) } - } finally { - inFlight = undefined } - })() + } + + inFlight = fetchQuota() + .then((result) => { + // One place for every outcome: a success is cached, and anything else (signed out, no Copilot, an + // HTTP error, a thrown error) drops an older success so it is not served as if it were current. + cache = result.ok ? { at: Date.now(), result } : undefined + return result + }) + .finally(() => { + inFlight = undefined + }) return inFlight } diff --git a/src/services/language-models/providerQuotas.ts b/src/services/language-models/providerQuotas.ts index 4286b4f6d1..433c11278e 100644 --- a/src/services/language-models/providerQuotas.ts +++ b/src/services/language-models/providerQuotas.ts @@ -394,7 +394,8 @@ const KEYED_PROVIDERS: KeyedProvider[] = [ // Only API-key profiles are queried; OAuth sign-ins have no key to send. providerId: providerIdentifiers.kimiCode, credentials: (s) => ({ - apiKey: s.kimiCodeApiKey, + // An OAuth sign-in has no API key to send, even if an old key is still in the profile. + apiKey: s.kimiCodeAuthMethod === "oauth" ? undefined : s.kimiCodeApiKey, urls: ["https://api.kimi.com/coding/v1/usages"], }), parse: parseKimiCodeUsage, diff --git a/webview-ui/src/components/settings/ProviderLimits.tsx b/webview-ui/src/components/settings/ProviderLimits.tsx index fb2d863c07..1bab564b08 100644 --- a/webview-ui/src/components/settings/ProviderLimits.tsx +++ b/webview-ui/src/components/settings/ProviderLimits.tsx @@ -9,6 +9,10 @@ import { vscode } from "@src/utils/vscode" import i18next from "i18next" import { providerLabel } from "@src/utils/providerLabel" +// Module-level, so a component that is unmounted and mounted again never reuses an id that an older, +// still-settling request carries. +let quotaRequestCounter = 0 + const barColor = (pct: number) => pct >= 90 ? "bg-vscode-charts-red" : pct >= 75 ? "bg-vscode-charts-yellow" : "bg-vscode-charts-green" @@ -22,11 +26,11 @@ export const ProviderLimits = () => { const { t } = useAppTranslation() const [quotas, setQuotas] = useState() const [loading, setLoading] = useState(true) + const [failed, setFailed] = useState(false) // Only the newest request counts: an answer for an older one (a slow first load that a refresh // overtook, or one that outlived this component) is ignored. const latestRequestId = useRef(undefined) - const counter = useRef(0) const cancelLatest = useCallback(() => { if (latestRequestId.current) { @@ -41,7 +45,7 @@ export const ProviderLimits = () => { const request = useCallback( (force: boolean) => { cancelLatest() - const requestId = `provider-quotas-${++counter.current}` + const requestId = `provider-quotas-${++quotaRequestCounter}` latestRequestId.current = requestId setLoading(true) vscode.postMessage({ type: VsCodeLmModelsMessageType.requestProviderQuotas, bool: force, requestId }) @@ -55,6 +59,7 @@ export const ProviderLimits = () => { if (event.data.requestId !== latestRequestId.current) return latestRequestId.current = undefined setQuotas(event.data.providerQuotas ?? []) + setFailed(event.data.providerQuotasFailed === true) setLoading(false) } window.addEventListener("message", onMessage) @@ -66,8 +71,9 @@ export const ProviderLimits = () => { } }, [request, cancelLatest]) - // Nothing connected that has a usage API: hide the section entirely. - if (quotas && quotas.length === 0) return null + // Nothing connected that has a usage API: hide the section entirely. A failed load is different: keep + // the section so the user can press Refresh to try again. + if (quotas && quotas.length === 0 && !failed) return null const fetchedAt = quotas?.reduce((max, q) => Math.max(max, q.fetchedAt), 0) @@ -99,6 +105,13 @@ export const ProviderLimits = () => {
+ {failed && ( +
+ {t("settings:usage.limits.error")} +
+ )} {!quotas && (
{t("settings:usage.limits.loading")} diff --git a/webview-ui/src/components/settings/UsageSettings.tsx b/webview-ui/src/components/settings/UsageSettings.tsx index 9f1efc1c1d..543bfcff7f 100644 --- a/webview-ui/src/components/settings/UsageSettings.tsx +++ b/webview-ui/src/components/settings/UsageSettings.tsx @@ -308,9 +308,7 @@ export const UsageSettings = ({ className, ...props }: HTMLAttributes {t("settings:usage.byMode")}:{" "} - {summary.byMode - .map((m) => `${m.key} ${bucketRow(m).label.split(" · ")[0]}`) - .join(" · ")} + {summary.byMode.map((m) => `${m.key} ${bucketRow(m).label}`).join(" · ")}

{ expect(post).not.toHaveBeenCalledWith(expect.objectContaining({ type: "cancelProviderQuotas" })) }) }) + + describe("a failed load", () => { + const respondFailed = () => + act(() => { + window.dispatchEvent( + new MessageEvent("message", { + data: { + type: "providerQuotas", + providerQuotas: [], + providerQuotasFailed: true, + requestId: lastRequestId(), + }, + }), + ) + }) + + it("keeps the section and says so, instead of hiding it like 'no provider has a usage API'", () => { + render() + respondFailed() + expect(screen.getByTestId("provider-limits")).toBeTruthy() + expect(screen.getByTestId("provider-limits-failed").textContent).toContain("settings:usage.limits.error") + }) + + it("lets the user retry, and clears the failure when the retry works", () => { + render() + respondFailed() + + const before = lastRequestId() + post.mockClear() + fireEvent.click(screen.getByTestId("provider-limits-refresh")) + expect(post).toHaveBeenCalledWith(expect.objectContaining({ type: "requestProviderQuotas", bool: true })) + expect(lastRequestId()).not.toBe(before) + + respond([ + { + providerId: providerIdentifiers.deepseek, + ok: true, + fetchedAt: 1, + windows: [{ id: "b", valueLabel: "$1.00 left" }], + }, + ]) + expect(screen.queryByTestId("provider-limits-failed")).toBeNull() + expect(screen.getByTestId(`provider-limit-${providerIdentifiers.deepseek}`)).toBeTruthy() + }) + + it("still hides the section when the load worked and nothing has a usage API", () => { + render() + respond([]) + expect(screen.queryByTestId("provider-limits")).toBeNull() + }) + }) + + it("never reuses a request id when the tab is closed and opened again", () => { + const first = render() + const firstId = lastRequestId() + first.unmount() + + render() + expect(lastRequestId()).not.toBe(firstId) + }) }) diff --git a/webview-ui/src/components/settings/__tests__/UsageSettings.spec.tsx b/webview-ui/src/components/settings/__tests__/UsageSettings.spec.tsx index 7f7c2acb54..4c602677eb 100644 --- a/webview-ui/src/components/settings/__tests__/UsageSettings.spec.tsx +++ b/webview-ui/src/components/settings/__tests__/UsageSettings.spec.tsx @@ -188,6 +188,16 @@ describe("UsageSettings", () => { }) }) + describe("modes with and without a price", () => { + it("keeps 'no price' on an unpriced mode so it is not mistaken for a priced one", () => { + state.taskHistory = [priced(1, { mode: "code" }), copilot({ mode: "debug" })] + render() + const line = screen.getByTestId("usage-by-mode").textContent! + expect(line).toContain("code $1.00") + expect(line).toMatch(/debug .*settings:usage\.noPrice/) + }) + }) + describe("filters", () => { it("defaults to this workspace and can widen to all", () => { state.taskHistory = [priced(1), priced(2, { workspace: "/ws/other" })] diff --git a/webview-ui/src/utils/__tests__/usage.spec.ts b/webview-ui/src/utils/__tests__/usage.spec.ts index 7f5b8435b3..96254cf033 100644 --- a/webview-ui/src/utils/__tests__/usage.spec.ts +++ b/webview-ui/src/utils/__tests__/usage.spec.ts @@ -173,10 +173,20 @@ describe("summarizeUsage", () => { expect(s.byMode[0].key).toBe("unknown") }) - it("computes cache hit rate over input-side tokens", () => { - const s = summarizeUsage(history, { range: "today", now: NOW }) - // today: tokensIn 1000 + 10, cacheReads 3000 - expect(s.cacheHitRate).toBeCloseTo(3000 / (1010 + 3000)) + it("computes the cache hit rate against tokensIn, which already counts the cached tokens", () => { + const s = summarizeUsage( + [item({ tokensIn: 4000, cacheReads: 3000 }), item({ tokensIn: 1000, cacheReads: 0 })], + { range: "all", now: NOW }, + ) + // 3000 of 5000 input tokens came from the cache: 60%, not 3000 / (5000 + 3000). + expect(s.cacheHitRate).toBeCloseTo(0.6) + }) + + it("never reports more than 100%, and 0 with no input", () => { + expect( + summarizeUsage([item({ tokensIn: 100, cacheReads: 250 })], { range: "all", now: NOW }).cacheHitRate, + ).toBe(1) + expect(summarizeUsage([item({ tokensIn: 0, cacheReads: 0 })], { range: "all", now: NOW }).cacheHitRate).toBe(0) }) it("produces a dense daily series for bounded ranges", () => { diff --git a/webview-ui/src/utils/usage.ts b/webview-ui/src/utils/usage.ts index 3659198f8d..1d38c5de23 100644 --- a/webview-ui/src/utils/usage.ts +++ b/webview-ui/src/utils/usage.ts @@ -258,8 +258,6 @@ export function summarizeUsage(history: HistoryItem[], options: UsageOptions): U } } - const inputSide = tokensIn + cacheReads - return { totalCost, tokensIn, @@ -267,7 +265,9 @@ export function summarizeUsage(history: HistoryItem[], options: UsageOptions): U cacheReads, cacheWrites, totalTokens: tokensIn + tokensOut, - cacheHitRate: inputSide > 0 ? cacheReads / inputSide : 0, + // `tokensIn` already counts the cached tokens (the cost helpers store the total input), so it is the + // whole input side. Adding the cache reads again would understate the rate. + cacheHitRate: tokensIn > 0 ? Math.min(1, cacheReads / tokensIn) : 0, taskCount: items.length, byProvider: [...providers.values()].sort(byCostDesc), byModel: [...models.values()].sort(byCostDesc), From 56a7085cbda582264c8189e45f0f678dfb4f95bd Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Wed, 28 Oct 2026 10:44:10 -0700 Subject: [PATCH 06/27] fix(usage): reconcile condense cost and record the resolved model --- .../__tests__/usageByModel.spec.ts | 22 +++++++- src/core/task-persistence/usageByModel.ts | 10 ++++ src/core/task/Task.ts | 2 + webview-ui/src/utils/__tests__/usage.spec.ts | 50 +++++++++++++++++++ webview-ui/src/utils/usage.ts | 24 ++++++--- 5 files changed, 100 insertions(+), 8 deletions(-) diff --git a/src/core/task-persistence/__tests__/usageByModel.spec.ts b/src/core/task-persistence/__tests__/usageByModel.spec.ts index 092272ff6d..a30d074d36 100644 --- a/src/core/task-persistence/__tests__/usageByModel.spec.ts +++ b/src/core/task-persistence/__tests__/usageByModel.spec.ts @@ -2,7 +2,7 @@ import { describe, expect, it } from "vitest" import { providerIdentifiers, type ClineMessage } from "@roo-code/types" -import { summarizeUsageByModel } from "../usageByModel" +import { resolveRecordedModelId, summarizeUsageByModel } from "../usageByModel" const req = (data: Record, ts = 1): ClineMessage => ({ ts, @@ -111,3 +111,23 @@ describe("summarizeUsageByModel", () => { expect(summarizeUsageByModel([])).toEqual([]) }) }) + +describe("resolveRecordedModelId", () => { + it("keeps a model that was recorded when the request started", () => { + expect(resolveRecordedModelId("gpt-5", "gpt-5-mini")).toBe("gpt-5") + }) + + it("uses the model that served the request when the profile named none", () => { + expect(resolveRecordedModelId(undefined, "claude-sonnet-5")).toBe("claude-sonnet-5") + expect(resolveRecordedModelId("", "claude-sonnet-5")).toBe("claude-sonnet-5") + expect(resolveRecordedModelId(null, "claude-sonnet-5")).toBe("claude-sonnet-5") + }) + + it("stays unrecorded when neither is known", () => { + expect(resolveRecordedModelId(undefined, undefined)).toBeUndefined() + }) + + it("ignores a recorded value that is not a string", () => { + expect(resolveRecordedModelId(42, "claude-sonnet-5")).toBe("claude-sonnet-5") + }) +}) diff --git a/src/core/task-persistence/usageByModel.ts b/src/core/task-persistence/usageByModel.ts index 16027c281e..ab2fd72324 100644 --- a/src/core/task-persistence/usageByModel.ts +++ b/src/core/task-persistence/usageByModel.ts @@ -49,3 +49,13 @@ export function summarizeUsageByModel(messages: ClineMessage[]): UsageByModelEnt return [...byKey.values()] } + +/** + * The model to record for a finished request. The first write (before the request starts) only knows the + * model the profile names; a profile that names none leaves it empty. By the time the request is done the + * model that actually served it is known, so use that rather than leave the usage unattributed. A model + * recorded earlier is never overwritten. + */ +export function resolveRecordedModelId(recorded: unknown, served: string | undefined): string | undefined { + return typeof recorded === "string" && recorded.length > 0 ? recorded : served +} diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index d5e8cc7b79..7b8e0ded28 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -123,6 +123,7 @@ import { saveTaskMessages, taskMetadata, } from "../task-persistence" +import { resolveRecordedModelId } from "../task-persistence/usageByModel" import { getEnvironmentDetails } from "../environment/getEnvironmentDetails" import { checkContextWindowExceededError } from "../context/context-management/context-error-handling" import { @@ -4071,6 +4072,7 @@ export class Task extends EventEmitter implements TaskLike { this.clineMessages[lastApiReqIndex].text = JSON.stringify({ ...existingData, + modelId: resolveRecordedModelId(existingData.modelId, this.cachedStreamingModel?.id), tokensIn: costResult.totalInputTokens, tokensOut: costResult.totalOutputTokens, cacheWrites: cacheWriteTokens, diff --git a/webview-ui/src/utils/__tests__/usage.spec.ts b/webview-ui/src/utils/__tests__/usage.spec.ts index 96254cf033..5858b8a7c8 100644 --- a/webview-ui/src/utils/__tests__/usage.spec.ts +++ b/webview-ui/src/utils/__tests__/usage.spec.ts @@ -341,6 +341,56 @@ describe("pickMetric", () => { }) }) +describe("spend that has no provider or model (context condensing)", () => { + const entry = (cost: number) => ({ + apiProvider: "anthropic", + modelId: "claude-sonnet-5", + requests: 1, + tokensIn: 100, + tokensOut: 10, + cost, + }) + + it("puts the unattributed remainder in the 'not recorded' rows so the rows add up to the total", () => { + // The task cost 5.00, but its recorded requests only account for 4.00: 1.00 was condensing. + const s = summarizeUsage([item({ totalCost: 5, usageByModel: [entry(4)] })], { range: "all", now: NOW }) + + expect(s.totalCost).toBe(5) + expect(s.byProvider.reduce((sum, b) => sum + b.cost, 0)).toBeCloseTo(5) + expect(s.byModel.reduce((sum, b) => sum + b.cost, 0)).toBeCloseTo(5) + expect(s.byProvider.find((b) => b.key === UNRECORDED)?.cost).toBeCloseTo(1) + expect(s.byModel.find((b) => b.key === UNRECORDED)?.cost).toBeCloseTo(1) + }) + + it("does not add a token count or a task to the 'not recorded' rows for that remainder", () => { + const s = summarizeUsage([item({ totalCost: 5, usageByModel: [entry(4)] })], { range: "all", now: NOW }) + const unrecorded = s.byProvider.find((b) => b.key === UNRECORDED)! + expect(unrecorded.tokens).toBe(0) + // The one task is counted under its real provider; the remainder is a cost line, not another task. + expect(s.byProvider.find((b) => b.key === "anthropic")?.tasks).toBe(1) + }) + + it("ignores float noise: no spurious 'not recorded' row when the costs agree", () => { + const s = summarizeUsage([item({ totalCost: 0.1 + 0.2, usageByModel: [entry(0.1), entry(0.2)] })], { + range: "all", + now: NOW, + }) + expect(s.byProvider.find((b) => b.key === UNRECORDED)).toBeUndefined() + expect(s.byModel.find((b) => b.key === UNRECORDED)).toBeUndefined() + }) + + it("adds nothing when the recorded requests cost more than the task total", () => { + const s = summarizeUsage([item({ totalCost: 3, usageByModel: [entry(4)] })], { range: "all", now: NOW }) + expect(s.byProvider.find((b) => b.key === UNRECORDED)).toBeUndefined() + }) + + it("leaves tasks with no usage record exactly as before", () => { + const s = summarizeUsage([item({ totalCost: 2, tokensIn: 50 })], { range: "all", now: NOW }) + expect(s.byProvider).toHaveLength(1) + expect(s.byProvider[0]).toMatchObject({ key: UNRECORDED, cost: 2 }) + }) +}) + describe("modelIdFromKey", () => { it("returns undefined for the unrecorded bucket, the id after the provider separator, or a bare key", () => { expect(modelIdFromKey(UNRECORDED)).toBeUndefined() diff --git a/webview-ui/src/utils/usage.ts b/webview-ui/src/utils/usage.ts index 1d38c5de23..553c7eaa7a 100644 --- a/webview-ui/src/utils/usage.ts +++ b/webview-ui/src/utils/usage.ts @@ -15,6 +15,9 @@ import type { HistoryItem } from "@roo-code/types" /** Bucket key for usage whose provider/model was not recorded (older tasks). */ export const UNRECORDED = "__unrecorded__" +/** Cost below this (in dollars) is float noise, not unattributed spend. */ +const REMAINDER_EPSILON = 1e-6 + export const USAGE_RANGES = ["today", "7d", "30d", "all"] as const export type UsageRange = (typeof USAGE_RANGES)[number] @@ -212,13 +215,20 @@ export function summarizeUsage(history: HistoryItem[], options: UsageOptions): U // (created before this was tracked) goes to a single "unrecorded" bucket. const seenProviders = new Set() const seenModels = new Set() - const entries = item.usageByModel?.length - ? item.usageByModel - : [ - { requests: 0, tokensIn: tIn, tokensOut: tOut, cost } as NonNullable< - HistoryItem["usageByModel"] - >[number], - ] + type Entry = NonNullable[number] + const entries: Entry[] = item.usageByModel?.length + ? [...item.usageByModel] + : [{ requests: 0, tokensIn: tIn, tokensOut: tOut, cost }] + + // The task's cost also covers work that has no provider or model of its own (condensing the context). + // Without this, the provider and model rows would add up to less than the headline total. The + // remainder goes to the "not recorded" rows. Below a cent-fraction it is rounding noise and is ignored, + // so a float residue cannot create a spurious priced row. + if (item.usageByModel?.length) { + const attributed = item.usageByModel.reduce((sum, e) => sum + (Number.isFinite(e.cost) ? e.cost : 0), 0) + const remainder = cost - attributed + if (remainder > REMAINDER_EPSILON) entries.push({ requests: 0, tokensIn: 0, tokensOut: 0, cost: remainder }) + } for (const e of entries) { const entryTokens = e.tokensIn + e.tokensOut From a2cf471fc86187067d18c99da317bd88df41b728 Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Wed, 28 Oct 2026 10:55:53 -0700 Subject: [PATCH 07/27] fix(usage): use the provider registry in a test; refresh baselines for the corrected cache rate --- .../__screenshots__/usage-settings-dark.png | Bin 64531 -> 64530 bytes .../usage-settings-degraded.png | Bin 63770 -> 63769 bytes .../usage-settings-high-contrast-light.png | Bin 66509 -> 66513 bytes .../usage-settings-high-contrast.png | Bin 66730 -> 66743 bytes .../__screenshots__/usage-settings-light.png | Bin 66381 -> 66406 bytes webview-ui/src/utils/__tests__/usage.spec.ts | 4 ++-- 6 files changed, 2 insertions(+), 2 deletions(-) diff --git a/webview-ui/src/components/settings/__tests__/__screenshots__/usage-settings-dark.png b/webview-ui/src/components/settings/__tests__/__screenshots__/usage-settings-dark.png index 7dde60d668b845079b8c1508f72211cf23ecf728..fdbbc1b168a5a3b89c2d53f78fbc09e7b5e589af 100644 GIT binary patch literal 64530 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 literal 64531 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 TP-NW;-^lE9_jRi#P}qM1g@+Wy diff --git a/webview-ui/src/components/settings/__tests__/__screenshots__/usage-settings-degraded.png b/webview-ui/src/components/settings/__tests__/__screenshots__/usage-settings-degraded.png index 13ff0ecbcda847dcea0d6262a3eb0fc88e370536..8c04e5d3c0b8dfda1d45f5c56458925e0ed3f4a9 100644 GIT binary patch literal 63769 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

CGhHtdK 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

~v#vFfC|%$9i^O<&gp4xcL;G`pNiytb-NKt_@ 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 xh%Lx)8E_cE>_VktNC>!nCwrH$&} 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 NuB@$8rC=TU{{TGLbqD|e diff --git a/webview-ui/src/components/settings/__tests__/__screenshots__/usage-settings-light.png b/webview-ui/src/components/settings/__tests__/__screenshots__/usage-settings-light.png index 79d87f53949618703a3b4bd060281fbb1fd4c7a7..dc9e0eddbaf7266f5faa3f705f70ffd33f4919c3 100644 GIT binary patch literal 66406 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 puPGuBYio|-UJy}P| literal 66381 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 jcUO-V!GQ { describe("spend that has no provider or model (context condensing)", () => { const entry = (cost: number) => ({ - apiProvider: "anthropic", + apiProvider: providerIdentifiers.anthropic, modelId: "claude-sonnet-5", requests: 1, tokensIn: 100, @@ -367,7 +367,7 @@ describe("spend that has no provider or model (context condensing)", () => { const unrecorded = s.byProvider.find((b) => b.key === UNRECORDED)! expect(unrecorded.tokens).toBe(0) // The one task is counted under its real provider; the remainder is a cost line, not another task. - expect(s.byProvider.find((b) => b.key === "anthropic")?.tasks).toBe(1) + expect(s.byProvider.find((b) => b.key === providerIdentifiers.anthropic)?.tasks).toBe(1) }) it("ignores float noise: no spurious 'not recorded' row when the costs agree", () => { From dafd502baba37fde516b1a6b35dedac304736e99 Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Wed, 28 Oct 2026 11:59:54 -0700 Subject: [PATCH 08/27] fix(usage): cancel Copilot quota lookups with the request, unique request ids, close coverage gaps --- src/core/task/__tests__/Task.spec.ts | 103 ++++++++++++++++ .../__tests__/copilotQuota.spec.ts | 86 +++++++++++++ .../__tests__/providerQuotas.spec.ts | 18 +++ src/services/language-models/copilotQuota.ts | 116 ++++++++++++------ .../language-models/providerQuotas.ts | 35 +++--- .../components/settings/ProviderLimits.tsx | 7 +- .../__tests__/ProviderLimits.spec.tsx | 27 +++- webview-ui/src/utils/__tests__/usage.spec.ts | 40 ++++++ 8 files changed, 370 insertions(+), 62 deletions(-) diff --git a/src/core/task/__tests__/Task.spec.ts b/src/core/task/__tests__/Task.spec.ts index ad07230204..5bca3bdc68 100644 --- a/src/core/task/__tests__/Task.spec.ts +++ b/src/core/task/__tests__/Task.spec.ts @@ -2110,6 +2110,39 @@ describe("Cline", () => { await loop await vi.waitFor(() => expect(oldDispose).toHaveBeenCalledOnce()) }) + + it.each([ + { name: "fills in the serving model when the profile named none", profile: undefined, expected: "served-model" }, + { name: "keeps the model the profile named", profile: "profile-model", expected: "profile-model" }, + ])("finalized api_req_started $name", async ({ profile, expected }) => { + const task = await createTaskWithManualRetries() + task.apiConfiguration = { + ...task.apiConfiguration, + apiProvider: providerIdentifiers.anthropic, + apiModelId: profile, + } + disposableApi(task) + vi.spyOn(task.api, "getModel").mockReturnValue({ + id: "served-model", + info: { supportsPromptCache: true, contextWindow: 200_000, maxTokens: 4096 } as ModelInfo, + }) + vi.spyOn(getTaskTestAccess(task), "attemptApiRequestWithActiveApi").mockImplementation( + async function* () { + yield { type: "text", text: "a" } + yield { type: "usage", inputTokens: 1, outputTokens: 1 } + }, + ) + realRequestsThenStop(task) + vi.spyOn(console, "error").mockImplementation(() => {}) + + await task.recursivelyMakeClineRequests([{ type: "text", text: "go" }]) + + const started = task.clineMessages.find((m) => m.say === "api_req_started") + const payload = JSON.parse(started?.text ?? "{}") + expect(payload.apiProvider).toBe(providerIdentifiers.anthropic) + expect(payload.modelId).toBe(expected) + expect(payload.tokensIn).toBe(1) + }) }) it("disposes the current handler exactly once even when dispose is called twice", async () => { @@ -3486,6 +3519,76 @@ describe("Cline", () => { }) }) + describe("api_req_started usage attribution", () => { + /** Runs the request setup and returns the JSON the first api_req_started message was written with. */ + const firstApiReqPayload = async ( + apiConfiguration: ProviderSettings, + servedModelId?: string, + ): Promise> => { + const task = new Task({ + provider: mockProvider, + apiConfiguration, + task: "test task", + startTask: false, + }) + + Object.assign(task.api, { ensureModelFetched: vi.fn().mockResolvedValue(undefined) }) + vi.spyOn(task.api, "getModel").mockReturnValue({ + id: servedModelId ?? "served-model", + info: { + supportsImages: false, + supportsPromptCache: true, + contextWindow: 200_000, + maxTokens: 4096, + } as ModelInfo, + }) + vi.mocked(processUserContentMentions).mockResolvedValueOnce({ + content: [{ type: "text", text: "hello" }], + mode: undefined, + }) + vi.spyOn(getTaskTestAccess(task), "saveClineMessages").mockResolvedValue(true) + vi.spyOn(getTaskTestAccess(task), "addToApiConversationHistory").mockResolvedValue(undefined) + vi.spyOn(task.diffViewProvider, "reset").mockResolvedValue(undefined as never) + vi.spyOn(task, "attemptApiRequest").mockImplementation(() => { + throw new Error("stop after the request message is written") + }) + + const payloads: string[] = [] + vi.spyOn(task, "say").mockImplementation(async (type, text) => { + if (type === "api_req_started") payloads.push(String(text)) + return undefined as never + }) + task.clineMessages = [{ ts: Date.now(), type: "say", say: "api_req_started", text: "{}" }] + + await task.recursivelyMakeClineRequests([{ type: "text", text: "hello" }]).catch(() => {}) + return JSON.parse(payloads[0] ?? "{}") + } + + it("records the provider and model that serve the request", async () => { + const payload = await firstApiReqPayload({ + apiProvider: providerIdentifiers.anthropic, + apiKey: "k", + apiModelId: "claude-sonnet-5", + }) + expect(payload).toMatchObject({ + apiProvider: providerIdentifiers.anthropic, + modelId: "claude-sonnet-5", + }) + }) + + it("leaves the model unset when the profile names none, and records the provider", async () => { + const payload = await firstApiReqPayload({ apiProvider: providerIdentifiers.anthropic, apiKey: "k" }) + expect(payload.apiProvider).toBe(providerIdentifiers.anthropic) + // The first write cannot know the served model; the finalized message fills it in (below). + expect(payload.modelId).toBeUndefined() + }) + + it("records neither provider nor model when the profile sets no provider", async () => { + const payload = await firstApiReqPayload({} as ProviderSettings) + expect(payload.apiProvider).toBeUndefined() + }) + }) + describe("Subtask Rate Limiting", () => { let mockProvider: MockedClineProvider let mockApiConfig: RateLimitedProviderSettings diff --git a/src/services/language-models/__tests__/copilotQuota.spec.ts b/src/services/language-models/__tests__/copilotQuota.spec.ts index 413532038d..cc1cb910f6 100644 --- a/src/services/language-models/__tests__/copilotQuota.spec.ts +++ b/src/services/language-models/__tests__/copilotQuota.spec.ts @@ -216,6 +216,92 @@ describe("getGitHubCopilotQuota", () => { expect(retry).toHaveBeenCalledTimes(1) }) + describe("cancellation", () => { + /** A fetch that never answers on its own and records the signal it was given. */ + const hangingFetch = () => { + let seen: AbortSignal | undefined + const fetchSpy = vi.fn( + (_url: string, init?: RequestInit) => + new Promise((_resolve, reject) => { + seen = init?.signal ?? undefined + seen?.addEventListener("abort", () => reject(new DOMException("Aborted", "AbortError"))) + }), + ) + return { fetchSpy, signal: () => seen } + } + + it("stops the GitHub request when the only caller goes away", async () => { + const { fetchSpy, signal } = hangingFetch() + const controller = new AbortController() + const result = getGitHubCopilotQuota({ signal: controller.signal }, fetchSpy as never) + await vi.waitFor(() => expect(signal()).toBeDefined()) + expect(signal()!.aborted).toBe(false) + + controller.abort() + await expect(result).rejects.toMatchObject({ name: "AbortError" }) + expect(signal()!.aborted).toBe(true) + }) + + it("keeps the shared request running until its last caller leaves", async () => { + const { fetchSpy, signal } = hangingFetch() + const leaving = new AbortController() + const staying = new AbortController() + + const a = getGitHubCopilotQuota({ signal: staying.signal }, fetchSpy as never) + const b = getGitHubCopilotQuota({ signal: leaving.signal }, fetchSpy as never) + await vi.waitFor(() => expect(signal()).toBeDefined()) + expect(fetchSpy).toHaveBeenCalledTimes(1) + + leaving.abort() + await expect(b).rejects.toMatchObject({ name: "AbortError" }) + expect(signal()!.aborted).toBe(false) + + staying.abort() + await expect(a).rejects.toMatchObject({ name: "AbortError" }) + expect(signal()!.aborted).toBe(true) + }) + + it("rejects at once with a signal that is already aborted, and makes no request", async () => { + const fetchSpy = vi.fn() + const controller = new AbortController() + controller.abort() + await expect(getGitHubCopilotQuota({ signal: controller.signal }, fetchSpy as never)).rejects.toMatchObject( + { + name: "AbortError", + }, + ) + expect(fetchSpy).not.toHaveBeenCalled() + }) + + it("does not cache a cancelled request, so the next call fetches again", async () => { + const { fetchSpy } = hangingFetch() + const controller = new AbortController() + const cancelled = getGitHubCopilotQuota({ signal: controller.signal }, fetchSpy as never) + await vi.waitFor(() => expect(fetchSpy).toHaveBeenCalled()) + controller.abort() + await expect(cancelled).rejects.toBeDefined() + + const good = vi.fn(async () => json(businessPayload)) + await expect(getGitHubCopilotQuota({}, good as never)).resolves.toMatchObject({ ok: true }) + expect(good).toHaveBeenCalledTimes(1) + }) + + it("does not start the GitHub request when it was cancelled while the token was being fetched", async () => { + let release: (session: { accessToken: string }) => void = () => {} + getSession.mockImplementationOnce(() => new Promise((resolve) => (release = resolve))) + const fetchSpy = vi.fn() + const controller = new AbortController() + + const result = getGitHubCopilotQuota({ signal: controller.signal }, fetchSpy as never) + await vi.waitFor(() => expect(getSession).toHaveBeenCalled()) + controller.abort() + release({ accessToken: "gho_token" }) + + await expect(result).rejects.toMatchObject({ name: "AbortError" }) + expect(fetchSpy).not.toHaveBeenCalled() + }) + }) + it("shares one in-flight request between concurrent callers", async () => { const fetchSpy = vi.fn(async () => json(businessPayload)) const [a, b] = await Promise.all([ diff --git a/src/services/language-models/__tests__/providerQuotas.spec.ts b/src/services/language-models/__tests__/providerQuotas.spec.ts index a8cfbdbd38..ade24dccc0 100644 --- a/src/services/language-models/__tests__/providerQuotas.spec.ts +++ b/src/services/language-models/__tests__/providerQuotas.spec.ts @@ -77,6 +77,13 @@ describe("parseDeepSeekBalance", () => { }) describe("parseDeepSeekBalance – fallbacks", () => { + it("treats a USD or CNY row without a balance as zero when choosing a row", () => { + const result = parseDeepSeekBalance({ + balance_infos: [{ currency: "USD" }, { currency: "CNY" }, { currency: "CNY", total_balance: "5" }], + }) + expect(result).toEqual([{ id: "balance", valueLabel: "¥5.00 left" }]) + }) + it("falls back to a zero USD balance, then to the first row", () => { expect( parseDeepSeekBalance({ @@ -394,6 +401,17 @@ describe("getProviderQuotas – Copilot window and misc", () => { expect(unl).toMatchObject({ ok: true, windows: [{ valueLabel: "Unlimited", resetAt: 7 }] }) }) + it("hands the caller's abort signal to the Copilot lookup", async () => { + const { getGitHubCopilotQuota } = await import("../copilotQuota") + const mocked = vi.mocked(getGitHubCopilotQuota) + mocked.mockResolvedValueOnce({ ok: true, quota: { unlimited: true, fetchedAt: 1 } }) + const controller = new AbortController() + await getProviderQuotas([{ apiProvider: providerIdentifiers.githubCopilot } as never], { + signal: controller.signal, + }) + expect(mocked).toHaveBeenLastCalledWith({ force: false, signal: controller.signal }) + }) + it("passes Copilot failures through with their reason and message", async () => { const { getGitHubCopilotQuota } = await import("../copilotQuota") vi.mocked(getGitHubCopilotQuota).mockResolvedValueOnce({ ok: false, reason: "error", message: "boom" }) diff --git a/src/services/language-models/copilotQuota.ts b/src/services/language-models/copilotQuota.ts index 754edbeca5..4bf821e722 100644 --- a/src/services/language-models/copilotQuota.ts +++ b/src/services/language-models/copilotQuota.ts @@ -78,58 +78,94 @@ async function getGitHubToken(): Promise { } let cache: { at: number; result: GitHubCopilotQuotaResult } | undefined -let inFlight: Promise | undefined +let inFlight: + | { + request: Promise + /** Callers still waiting. The shared fetch is aborted only when the last one leaves. */ + waiters: number + controller: AbortController + } + | undefined + +/** Rejects when `signal` aborts, without cancelling `work` (other callers may still be using it). */ +function untilAborted(work: Promise, signal: AbortSignal | undefined, onAbort: () => void): Promise { + if (!signal) return work + return new Promise((resolve, reject) => { + const abort = () => { + onAbort() + reject(new DOMException("Aborted", "AbortError")) + } + if (signal.aborted) return abort() + signal.addEventListener("abort", abort, { once: true }) + work.then(resolve, reject).finally(() => signal.removeEventListener("abort", abort)) + }) +} /** * Fetches the quota. Concurrent callers share one request; successful results - * are cached briefly unless `force` is set (the Refresh button). + * are cached briefly unless `force` is set (the Refresh button). `signal` lets a caller stop waiting; the + * network work itself stops when the last waiting caller has gone. */ export function getGitHubCopilotQuota( - { force = false }: { force?: boolean } = {}, + { force = false, signal }: { force?: boolean; signal?: AbortSignal } = {}, fetchImpl: typeof fetch = fetch, ): Promise { + if (signal?.aborted) return Promise.reject(new DOMException("Aborted", "AbortError")) if (!force && cache && Date.now() - cache.at < CACHE_TTL_MS) return Promise.resolve(cache.result) - if (inFlight) return inFlight - - const fetchQuota = async (): Promise => { - try { - const token = await getGitHubToken() - if (!token) return { ok: false, reason: "signedOut" } - - const response = await fetchImpl(COPILOT_USER_URL, { - method: "GET", - headers: { - Authorization: `token ${token}`, - Accept: "application/json", - "Editor-Version": `vscode/${vscode.version}`, - "X-Github-Api-Version": "2025-04-01", - }, - signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS), - }) - - if (response.status === 401) return { ok: false, reason: "signedOut" } - if (response.status === 403 || response.status === 404) return { ok: false, reason: "noCopilot" } - if (!response.ok) return { ok: false, reason: "error", message: `GitHub API error ${response.status}` } - const quota = parseCopilotQuota(await response.json()) - return quota ? { ok: true, quota } : { ok: false, reason: "noCopilot" } - } catch (error) { - return { ok: false, reason: "error", message: safeErrorMessage(error) } + if (!inFlight) { + const controller = new AbortController() + const fetchQuota = async (): Promise => { + try { + const token = await getGitHubToken() + if (controller.signal.aborted) return { ok: false, reason: "error", message: "Request cancelled" } + if (!token) return { ok: false, reason: "signedOut" } + + const response = await fetchImpl(COPILOT_USER_URL, { + method: "GET", + headers: { + Authorization: `token ${token}`, + Accept: "application/json", + "Editor-Version": `vscode/${vscode.version}`, + "X-Github-Api-Version": "2025-04-01", + }, + signal: AbortSignal.any([controller.signal, AbortSignal.timeout(REQUEST_TIMEOUT_MS)]), + }) + + if (response.status === 401) return { ok: false, reason: "signedOut" } + if (response.status === 403 || response.status === 404) return { ok: false, reason: "noCopilot" } + if (!response.ok) return { ok: false, reason: "error", message: `GitHub API error ${response.status}` } + + const quota = parseCopilotQuota(await response.json()) + return quota ? { ok: true, quota } : { ok: false, reason: "noCopilot" } + } catch (error) { + return { ok: false, reason: "error", message: safeErrorMessage(error) } + } } + + const request: Promise = fetchQuota() + .then((result) => { + // One place for every outcome: a success is cached, and anything else (signed out, no Copilot, an + // HTTP error, a thrown or cancelled request) drops an older success so it is not served as current. + cache = result.ok ? { at: Date.now(), result } : undefined + return result + }) + .finally(() => { + if (inFlight?.request === request) inFlight = undefined + }) + inFlight = { request, waiters: 0, controller } } - inFlight = fetchQuota() - .then((result) => { - // One place for every outcome: a success is cached, and anything else (signed out, no Copilot, an - // HTTP error, a thrown error) drops an older success so it is not served as if it were current. - cache = result.ok ? { at: Date.now(), result } : undefined - return result - }) - .finally(() => { - inFlight = undefined - }) - - return inFlight + const shared = inFlight + shared.waiters++ + let left = false + const leave = () => { + if (left) return + left = true + // Last one out cancels the network work; earlier leavers just stop waiting. + if (--shared.waiters === 0) shared.controller.abort() + } + return untilAborted(shared.request, signal, leave).finally(leave) } /** @internal test hook */ diff --git a/src/services/language-models/providerQuotas.ts b/src/services/language-models/providerQuotas.ts index 433c11278e..70ed6def2b 100644 --- a/src/services/language-models/providerQuotas.ts +++ b/src/services/language-models/providerQuotas.ts @@ -316,12 +316,12 @@ export function parseOpenCodeGoUsage(payload: unknown): ProviderQuotaWindow[] | type Fetch = typeof fetch -async function getJson(fetchImpl: Fetch, url: string, apiKey: string, signal?: AbortSignal): Promise { +async function getJson(fetchImpl: Fetch, url: string, apiKey: string, signal: AbortSignal): Promise { const timeout = AbortSignal.timeout(REQUEST_TIMEOUT_MS) const response = await fetchImpl(url, { method: "GET", headers: { Authorization: `Bearer ${apiKey}`, Accept: "application/json" }, - signal: signal ? AbortSignal.any([signal, timeout]) : timeout, + signal: AbortSignal.any([signal, timeout]), }) if (response.status === 401 || response.status === 403) throw new AuthError() if (!response.ok) throw new QuotaHttpError(response.status) @@ -480,22 +480,20 @@ function unqueryable(provider: KeyedProvider, creds: KeyedCredentials | undefine async function fetchKeyed( provider: KeyedProvider, - creds: KeyedCredentials, + apiKey: string, + urls: string[], fetchImpl: Fetch, - signal?: AbortSignal, + signal: AbortSignal, ): Promise { const now = Date.now() - if (!creds.apiKey || !creds.urls?.length) { - return { providerId: provider.providerId, ok: false, reason: "unsupported", fetchedAt: now } - } try { // Try each URL in order; a failing fallback only matters if no URL yields data. let windows: ProviderQuotaWindow[] | undefined let lastError: unknown - for (const [index, url] of creds.urls.entries()) { + for (const [index, url] of urls.entries()) { try { - windows = provider.parse(await getJson(fetchImpl, url, creds.apiKey, signal), index) + windows = provider.parse(await getJson(fetchImpl, url, apiKey, signal), index) if (windows?.length) break } catch (error) { if (error instanceof AuthError) throw error @@ -517,8 +515,8 @@ async function fetchKeyed( } } -async function fetchCopilot(force: boolean): Promise { - const result = await getGitHubCopilotQuota({ force }) +async function fetchCopilot(force: boolean, signal?: AbortSignal): Promise { + const result = await getGitHubCopilotQuota({ force, signal }) const providerId = providerIdentifiers.githubCopilot if (!result.ok) return { providerId, ok: false, reason: result.reason, message: result.message, fetchedAt: Date.now() } @@ -577,8 +575,8 @@ interface Inflight { const inflight = new Map() /** Identifies a provider and the URLs it is queried at (the credential itself is not part of it). */ -function cacheKey(provider: KeyedProvider, creds: KeyedCredentials): string { - return `${provider.providerId}|${(creds.urls ?? []).join(",")}` +function cacheKey(provider: KeyedProvider, urls: string[]): string { + return `${provider.providerId}|${urls.join(",")}` } /** Rejects as soon as `signal` aborts, without cancelling `work` (which other callers may still be using). */ @@ -606,9 +604,10 @@ function quotaForKeyedProvider( const skipped = unqueryable(provider, creds) if (skipped) return Promise.resolve(skipped) - const resolved = creds as KeyedCredentials - const apiKey = resolved.apiKey as string - const key = cacheKey(provider, resolved) + // `unqueryable` returned early unless there is a key and at least one URL. + const apiKey = creds?.apiKey as string + const urls = creds?.urls as string[] + const key = cacheKey(provider, urls) const hit = cache.get(key) if (!force && hit && hit.apiKey === apiKey && Date.now() - hit.at < CACHE_TTL_MS) return Promise.resolve(hit.result) @@ -616,7 +615,7 @@ function quotaForKeyedProvider( let entry = inflight.get(key) if (!entry || entry.apiKey !== apiKey) { const controller = new AbortController() - const request: Promise = fetchKeyed(provider, resolved, fetchImpl, controller.signal) + const request: Promise = fetchKeyed(provider, apiKey, urls, fetchImpl, controller.signal) .then((result) => { if (result.ok) { cache.set(key, { at: Date.now(), apiKey, result }) @@ -657,7 +656,7 @@ export async function getProviderQuotas( const connected = new Set(profiles.map((p) => p.apiProvider).filter(Boolean) as string[]) const tasks: Promise[] = [] - if (connected.has(providerIdentifiers.githubCopilot)) tasks.push(fetchCopilot(force)) + if (connected.has(providerIdentifiers.githubCopilot)) tasks.push(fetchCopilot(force, signal)) for (const provider of KEYED_PROVIDERS) { if (connected.has(provider.providerId)) { tasks.push(quotaForKeyedProvider(provider, profiles, force, fetchImpl, signal)) diff --git a/webview-ui/src/components/settings/ProviderLimits.tsx b/webview-ui/src/components/settings/ProviderLimits.tsx index 1bab564b08..2a988e6426 100644 --- a/webview-ui/src/components/settings/ProviderLimits.tsx +++ b/webview-ui/src/components/settings/ProviderLimits.tsx @@ -10,8 +10,11 @@ import i18next from "i18next" import { providerLabel } from "@src/utils/providerLabel" // Module-level, so a component that is unmounted and mounted again never reuses an id that an older, -// still-settling request carries. +// still-settling request carries. The random part separates this webview from any other one (sidebar and +// editor tab each load their own copy of this module), so an id is unique across webviews too. let quotaRequestCounter = 0 +const quotaRequestSession = Math.random().toString(36).slice(2, 10) +const nextQuotaRequestId = () => `provider-quotas-${quotaRequestSession}-${++quotaRequestCounter}` const barColor = (pct: number) => pct >= 90 ? "bg-vscode-charts-red" : pct >= 75 ? "bg-vscode-charts-yellow" : "bg-vscode-charts-green" @@ -45,7 +48,7 @@ export const ProviderLimits = () => { const request = useCallback( (force: boolean) => { cancelLatest() - const requestId = `provider-quotas-${++quotaRequestCounter}` + const requestId = nextQuotaRequestId() latestRequestId.current = requestId setLoading(true) vscode.postMessage({ type: VsCodeLmModelsMessageType.requestProviderQuotas, bool: force, requestId }) diff --git a/webview-ui/src/components/settings/__tests__/ProviderLimits.spec.tsx b/webview-ui/src/components/settings/__tests__/ProviderLimits.spec.tsx index bf61987640..b11a6d17e9 100644 --- a/webview-ui/src/components/settings/__tests__/ProviderLimits.spec.tsx +++ b/webview-ui/src/components/settings/__tests__/ProviderLimits.spec.tsx @@ -23,6 +23,14 @@ const lastRequestId = () => { } /** Answers the most recent request, or the given id. Pass `null` to send an answer with no id at all. */ +const lastRequestIdAfterRender = (Component: typeof ProviderLimits = ProviderLimits) => { + post.mockClear() + const view = render() + const id = lastRequestId() + view.unmount() + return id +} + const respond = (providerQuotas: ProviderQuota[], id?: string | null) => act(() => { const requestId = id === null ? undefined : (id ?? lastRequestId()) @@ -41,7 +49,7 @@ describe("ProviderLimits", () => { expect(post).toHaveBeenCalledWith({ type: "requestProviderQuotas", bool: false, - requestId: expect.stringMatching(/^provider-quotas-\d+$/), + requestId: expect.stringMatching(/^provider-quotas-[a-z0-9]+-\d+$/), }) }) @@ -181,7 +189,7 @@ describe("ProviderLimits", () => { expect(post).toHaveBeenCalledWith({ type: "requestProviderQuotas", bool: true, - requestId: expect.stringMatching(/^provider-quotas-\d+$/), + requestId: expect.stringMatching(/^provider-quotas-[a-z0-9]+-\d+$/), }) }) @@ -304,6 +312,21 @@ describe("ProviderLimits", () => { }) }) + it("makes ids that differ between webviews, not just between requests", async () => { + // Each webview loads its own copy of the module and starts counting again from 1. + vi.resetModules() + const { ProviderLimits: First } = await import("../ProviderLimits") + const first = lastRequestIdAfterRender(First) + vi.resetModules() + const { ProviderLimits: Second } = await import("../ProviderLimits") + const second = lastRequestIdAfterRender(Second) + + expect(first).toMatch(/^provider-quotas-[a-z0-9]+-1$/) + expect(second).toMatch(/^provider-quotas-[a-z0-9]+-1$/) + // Same counter value, still different ids: the session part tells the webviews apart. + expect(first).not.toBe(second) + }) + it("never reuses a request id when the tab is closed and opened again", () => { const first = render() const firstId = lastRequestId() diff --git a/webview-ui/src/utils/__tests__/usage.spec.ts b/webview-ui/src/utils/__tests__/usage.spec.ts index 95c08f2437..0fae4293c4 100644 --- a/webview-ui/src/utils/__tests__/usage.spec.ts +++ b/webview-ui/src/utils/__tests__/usage.spec.ts @@ -542,3 +542,43 @@ describe("usageToCsv", () => { expect(lines[1].endsWith(",0.1235")).toBe(true) }) }) + +describe("defaults and non-finite input", () => { + afterEach(() => { + vi.useRealTimers() + }) + + it("uses the current time when no `now` is given", () => { + vi.useFakeTimers() + vi.setSystemTime(NOW) + const recent = item({ ts: NOW - 1000, totalCost: 1 }) + const old = item({ ts: NOW - 3 * DAY, totalCost: 2 }) + + expect(summarizeUsage([recent, old], { range: "today" }).totalCost).toBe(1) + expect(usageToCsv([recent, old], { range: "today" }).split("\n")).toHaveLength(2) + }) + + it("ignores a non-finite per-model cost when reconciling the task cost", () => { + const summary = summarizeUsage( + [ + item({ + totalCost: 3, + usageByModel: [ + { + apiProvider: providerIdentifiers.anthropic, + modelId: "m", + requests: 1, + tokensIn: 1, + tokensOut: 1, + cost: Number.NaN, + }, + ], + }), + ], + { range: "all", now: NOW }, + ) + + // The whole task cost is unattributed because the recorded model cost is unusable. + expect(summary.byProvider.find((b) => b.key === UNRECORDED)?.cost).toBe(3) + }) +}) From cda347557a848eea1e89d95c19a5a5824af046eb Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Wed, 28 Oct 2026 12:04:00 -0700 Subject: [PATCH 09/27] test(usage): require exactly one quota call, and avoid a racy dynamic import in the test --- .../__tests__/webviewMessageHandler.providerQuotas.spec.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts b/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts index 914b9520a4..dd234a9c95 100644 --- a/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts +++ b/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts @@ -222,6 +222,9 @@ describe("webviewMessageHandler – requestProviderQuotas", () => { type: "requestProviderQuotas", requestId: "provider-quotas-1", }) + // Start them one after the other: two overlapping dynamic imports of the handler's service module can + // resolve to the real module instead of the mock, which would make a real network call. + await vi.waitFor(() => expect(releases).toHaveLength(1)) const second = webviewMessageHandler(editorTab, { type: "requestProviderQuotas", requestId: "provider-quotas-1", @@ -240,7 +243,7 @@ describe("webviewMessageHandler – requestProviderQuotas", () => { expect.objectContaining({ type: "providerQuotas", requestId: "provider-quotas-1" }), ) // Only the editor tab's request went on to the service; the sidebar's was stopped while loading. - expect(quotas.getProviderQuotas.mock.calls.length).toBeLessThanOrEqual(1) + expect(quotas.getProviderQuotas).toHaveBeenCalledTimes(1) }) it("marks the answer as failed when the quotas could not be loaded, and not when there are simply none", async () => { From f263acfeb27b4a9277c9d599a08106989c19a555 Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Wed, 28 Oct 2026 12:36:35 -0700 Subject: [PATCH 10/27] style: format Task.spec --- src/core/task/__tests__/Task.spec.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/task/__tests__/Task.spec.ts b/src/core/task/__tests__/Task.spec.ts index 5bca3bdc68..d7ac471a0b 100644 --- a/src/core/task/__tests__/Task.spec.ts +++ b/src/core/task/__tests__/Task.spec.ts @@ -2112,7 +2112,11 @@ describe("Cline", () => { }) it.each([ - { name: "fills in the serving model when the profile named none", profile: undefined, expected: "served-model" }, + { + name: "fills in the serving model when the profile named none", + profile: undefined, + expected: "served-model", + }, { name: "keeps the model the profile named", profile: "profile-model", expected: "profile-model" }, ])("finalized api_req_started $name", async ({ profile, expected }) => { const task = await createTaskWithManualRetries() From ae50b610c63128ddaf4bc26c4c1314864d236eff Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Wed, 28 Oct 2026 13:06:59 -0700 Subject: [PATCH 11/27] fix(usage): do not join a cancelled quota request; ignore non-finite model costs; tighten tests --- .../__tests__/copilotQuota.spec.ts | 20 +++++++- .../__tests__/providerQuotas.spec.ts | 48 +++++++++++++++++++ src/services/language-models/copilotQuota.ts | 9 +++- .../language-models/providerQuotas.ts | 19 +++++--- webview-ui/src/utils/__tests__/usage.spec.ts | 6 +++ webview-ui/src/utils/usage.ts | 5 +- 6 files changed, 96 insertions(+), 11 deletions(-) diff --git a/src/services/language-models/__tests__/copilotQuota.spec.ts b/src/services/language-models/__tests__/copilotQuota.spec.ts index cc1cb910f6..c4ec2eacab 100644 --- a/src/services/language-models/__tests__/copilotQuota.spec.ts +++ b/src/services/language-models/__tests__/copilotQuota.spec.ts @@ -279,13 +279,31 @@ describe("getGitHubCopilotQuota", () => { const cancelled = getGitHubCopilotQuota({ signal: controller.signal }, fetchSpy as never) await vi.waitFor(() => expect(fetchSpy).toHaveBeenCalled()) controller.abort() - await expect(cancelled).rejects.toBeDefined() + await expect(cancelled).rejects.toMatchObject({ name: "AbortError" }) const good = vi.fn(async () => json(businessPayload)) await expect(getGitHubCopilotQuota({}, good as never)).resolves.toMatchObject({ ok: true }) expect(good).toHaveBeenCalledTimes(1) }) + it("starts a new request instead of joining one whose last caller already left", async () => { + let release: (session: { accessToken: string }) => void = () => {} + getSession.mockImplementationOnce(() => new Promise((resolve) => (release = resolve))) + const controller = new AbortController() + const first = getGitHubCopilotQuota({ signal: controller.signal }, vi.fn() as never) + await vi.waitFor(() => expect(getSession).toHaveBeenCalled()) + controller.abort() + await expect(first).rejects.toMatchObject({ name: "AbortError" }) + + // The cancelled request is still waiting on the token; a new caller must not be handed its result. + const good = vi.fn(async () => json(businessPayload)) + const second = getGitHubCopilotQuota({}, good as never) + release({ accessToken: "gho_token" }) + + await expect(second).resolves.toMatchObject({ ok: true }) + expect(good).toHaveBeenCalledTimes(1) + }) + it("does not start the GitHub request when it was cancelled while the token was being fetched", async () => { let release: (session: { accessToken: string }) => void = () => {} getSession.mockImplementationOnce(() => new Promise((resolve) => (release = resolve))) diff --git a/src/services/language-models/__tests__/providerQuotas.spec.ts b/src/services/language-models/__tests__/providerQuotas.spec.ts index ade24dccc0..b8e59b0895 100644 --- a/src/services/language-models/__tests__/providerQuotas.spec.ts +++ b/src/services/language-models/__tests__/providerQuotas.spec.ts @@ -927,6 +927,54 @@ describe("getProviderQuotas", () => { expect(ra).toEqual(rb) }) + it("starts a new request instead of joining one whose last caller already left", async () => { + const body = () => new Response(JSON.stringify({ data: { limit: 10, limit_remaining: 5 } })) + // A host that ignores cancellation: the first request is still pending after its caller left. + let finishFirst: () => void = () => {} + const fetchSpy = vi + .fn() + .mockImplementationOnce(() => new Promise((resolve) => (finishFirst = () => resolve(body())))) + .mockImplementation(async () => body()) + const profiles = [{ apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "sk" } as never] + const controller = new AbortController() + + const first = getProviderQuotas(profiles, { signal: controller.signal }, fetchSpy) + await vi.waitFor(() => expect(fetchSpy).toHaveBeenCalledTimes(1)) + controller.abort() + await expect(first).rejects.toMatchObject({ name: "AbortError" }) + + // A new caller must get its own fetch, not join the cancelled one. + const [q] = await getProviderQuotas(profiles, {}, fetchSpy) + expect(fetchSpy).toHaveBeenCalledTimes(2) + expect(q).toMatchObject({ providerId: providerIdentifiers.openrouter, ok: true }) + finishFirst() + }) + + it("does not let a cancelled request wipe a cached success", async () => { + const ok = vi.fn(async () => new Response(JSON.stringify({ data: { limit: 10, limit_remaining: 5 } }))) + const profiles = [{ apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "sk" } as never] + await getProviderQuotas(profiles, {}, ok) + + const hanging = vi.fn( + (_input: RequestInfo | URL, init?: RequestInit) => + new Promise((_resolve, reject) => + (init?.signal as AbortSignal).addEventListener("abort", () => + reject(new DOMException("Aborted", "AbortError")), + ), + ), + ) + const controller = new AbortController() + const refresh = getProviderQuotas(profiles, { force: true, signal: controller.signal }, hanging) + await vi.waitFor(() => expect(hanging).toHaveBeenCalled()) + controller.abort() + await expect(refresh).rejects.toMatchObject({ name: "AbortError" }) + await new Promise((resolve) => setTimeout(resolve, 0)) + + // The earlier success is still served from the cache. + await getProviderQuotas(profiles, {}, ok) + expect(ok).toHaveBeenCalledTimes(1) + }) + it("caches results for the same set of providers unless forced", async () => { const fetchSpy = vi.fn(async () => new Response(JSON.stringify({ data: { limit: 10, limit_remaining: 5 } }))) const profiles = [{ apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "sk" } as never] diff --git a/src/services/language-models/copilotQuota.ts b/src/services/language-models/copilotQuota.ts index 4bf821e722..f68b6dadee 100644 --- a/src/services/language-models/copilotQuota.ts +++ b/src/services/language-models/copilotQuota.ts @@ -147,7 +147,8 @@ export function getGitHubCopilotQuota( .then((result) => { // One place for every outcome: a success is cached, and anything else (signed out, no Copilot, an // HTTP error, a thrown or cancelled request) drops an older success so it is not served as current. - cache = result.ok ? { at: Date.now(), result } : undefined + // A cancelled request says nothing about the account, so it leaves the cache alone. + if (!controller.signal.aborted) cache = result.ok ? { at: Date.now(), result } : undefined return result }) .finally(() => { @@ -163,7 +164,11 @@ export function getGitHubCopilotQuota( if (left) return left = true // Last one out cancels the network work; earlier leavers just stop waiting. - if (--shared.waiters === 0) shared.controller.abort() + if (--shared.waiters === 0) { + shared.controller.abort() + // Do not let a later caller join a request that is already cancelled (it would only get "cancelled"). + if (inFlight === shared) inFlight = undefined + } } return untilAborted(shared.request, signal, leave).finally(leave) } diff --git a/src/services/language-models/providerQuotas.ts b/src/services/language-models/providerQuotas.ts index 70ed6def2b..bf4ba6afc7 100644 --- a/src/services/language-models/providerQuotas.ts +++ b/src/services/language-models/providerQuotas.ts @@ -617,11 +617,14 @@ function quotaForKeyedProvider( const controller = new AbortController() const request: Promise = fetchKeyed(provider, apiKey, urls, fetchImpl, controller.signal) .then((result) => { - if (result.ok) { - cache.set(key, { at: Date.now(), apiKey, result }) - } else { - // A failed refresh must not leave an older success to be served as if it were current. - cache.delete(key) + // A cancelled request says nothing about the account, so it leaves the cache as it is. + if (!controller.signal.aborted) { + if (result.ok) { + cache.set(key, { at: Date.now(), apiKey, result }) + } else { + // A failed refresh must not leave an older success to be served as if it were current. + cache.delete(key) + } } return result }) @@ -639,7 +642,11 @@ function quotaForKeyedProvider( if (left) return left = true // Last one out cancels the network work; earlier leavers just stop waiting. - if (--shared.waiters === 0) shared.controller.abort() + if (--shared.waiters === 0) { + shared.controller.abort() + // Do not let a later caller join a request that is already cancelled. + if (inflight.get(key) === shared) inflight.delete(key) + } } return until(shared.request, signal, leave).finally(leave) } diff --git a/webview-ui/src/utils/__tests__/usage.spec.ts b/webview-ui/src/utils/__tests__/usage.spec.ts index 0fae4293c4..7a8a9cfc43 100644 --- a/webview-ui/src/utils/__tests__/usage.spec.ts +++ b/webview-ui/src/utils/__tests__/usage.spec.ts @@ -580,5 +580,11 @@ describe("defaults and non-finite input", () => { // The whole task cost is unattributed because the recorded model cost is unusable. expect(summary.byProvider.find((b) => b.key === UNRECORDED)?.cost).toBe(3) + // The unusable cost never reaches the recorded buckets as NaN. + const recordedProvider = summary.byProvider.find((b) => b.key === providerIdentifiers.anthropic) + expect(recordedProvider).toMatchObject({ cost: 0, tokens: 2, priced: false }) + expect(summary.byModel.find((b) => b.key !== UNRECORDED)).toMatchObject({ cost: 0, tokens: 2, priced: false }) + expect(summary.byProvider.reduce((sum, b) => sum + b.cost, 0)).toBe(3) + expect(summary.byModel.reduce((sum, b) => sum + b.cost, 0)).toBe(3) }) }) diff --git a/webview-ui/src/utils/usage.ts b/webview-ui/src/utils/usage.ts index 553c7eaa7a..c87cde7825 100644 --- a/webview-ui/src/utils/usage.ts +++ b/webview-ui/src/utils/usage.ts @@ -232,10 +232,11 @@ export function summarizeUsage(history: HistoryItem[], options: UsageOptions): U for (const e of entries) { const entryTokens = e.tokensIn + e.tokensOut + const entryCost = Number.isFinite(e.cost) ? e.cost : 0 const providerKey = e.apiProvider || UNRECORDED const modelKey = e.modelId ? `${e.apiProvider ?? ""}\u0000${e.modelId}` : UNRECORDED - addTo(providers, providerKey, e.cost, entryTokens, seenProviders) - addTo(models, modelKey, e.cost, entryTokens, seenModels, { apiProvider: e.apiProvider }) + addTo(providers, providerKey, entryCost, entryTokens, seenProviders) + addTo(models, modelKey, entryCost, entryTokens, seenModels, { apiProvider: e.apiProvider }) } const modeSeen = new Set() From 9191d4a56f5ec6208ca7401ae10bdac8b63685de Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Wed, 28 Oct 2026 13:31:26 -0700 Subject: [PATCH 12/27] fix(usage): clear a stale usageByModel when messages are replaced; close coverage partials --- .../TaskHistoryStore.realConcurrency.spec.ts | 26 +++++++++++++++++++ .../taskMetadata.usageByModel.spec.ts | 10 ++++--- src/core/task-persistence/taskMetadata.ts | 7 +++-- ...bviewMessageHandler.providerQuotas.spec.ts | 25 ++++++++++++++++++ src/services/language-models/copilotQuota.ts | 1 - 5 files changed, 62 insertions(+), 7 deletions(-) diff --git a/src/core/task-persistence/__tests__/TaskHistoryStore.realConcurrency.spec.ts b/src/core/task-persistence/__tests__/TaskHistoryStore.realConcurrency.spec.ts index d35dfc49cf..990519de56 100644 --- a/src/core/task-persistence/__tests__/TaskHistoryStore.realConcurrency.spec.ts +++ b/src/core/task-persistence/__tests__/TaskHistoryStore.realConcurrency.spec.ts @@ -119,6 +119,32 @@ describe("TaskHistoryStore real cross-host locking", () => { } }) + it("clears a stored usageByModel when the same task is saved again without one (e.g. after a rewind)", async () => { + const storagePath = await fs.mkdtemp(path.join(os.tmpdir(), "task-history-usage-clear-")) + const store = new TaskHistoryStore(storagePath) + const usageByModel = [ + { apiProvider: "anthropic", modelId: "m", requests: 1, tokensIn: 5, tokensOut: 5, cost: 1 }, + ] + + try { + await store.initialize() + await store.upsert({ ...item("usage-task"), usageByModel }) + expect(store.get("usage-task")?.usageByModel).toEqual(usageByModel) + + // What taskMetadata emits when the replaced messages record no usage. + await store.upsert({ ...item("usage-task"), usageByModel: undefined }) + expect(store.get("usage-task")?.usageByModel).toBeUndefined() + + // ...and the stored file no longer carries the stale breakdown either. + await store.invalidate("usage-task") + expect(store.get("usage-task")).toBeDefined() + expect(store.get("usage-task")?.usageByModel).toBeUndefined() + } finally { + store.dispose() + await fs.rm(storagePath, { recursive: true, force: true }) + } + }) + it("reports a bounded error when one store never reaches the write barrier", async () => { const storagePath = await fs.mkdtemp(path.join(os.tmpdir(), "task-history-missed-barrier-")) const storeA = new TaskHistoryStore(storagePath) diff --git a/src/core/task-persistence/__tests__/taskMetadata.usageByModel.spec.ts b/src/core/task-persistence/__tests__/taskMetadata.usageByModel.spec.ts index a16e27259d..dc98a88536 100644 --- a/src/core/task-persistence/__tests__/taskMetadata.usageByModel.spec.ts +++ b/src/core/task-persistence/__tests__/taskMetadata.usageByModel.spec.ts @@ -69,14 +69,16 @@ describe("taskMetadata – usageByModel", () => { expect(historyItem.totalCost).toBeCloseTo(0.2) }) - it("omits usageByModel entirely when nothing was recorded, keeping old items' shape", async () => { + it("leaves usageByModel undefined when nothing was recorded, so a stored breakdown is cleared", async () => { const { historyItem } = await taskMetadata({ ...base, messages: [say("text", "hello", 1)] }) - expect(historyItem).not.toHaveProperty("usageByModel") + expect(historyItem).toHaveProperty("usageByModel", undefined) + // Nothing is written for it: the stored shape of older tasks is unchanged. + expect(JSON.parse(JSON.stringify(historyItem))).not.toHaveProperty("usageByModel") }) - it("omits usageByModel for a task with no messages", async () => { + it("leaves usageByModel undefined for a task with no messages", async () => { const { historyItem } = await taskMetadata({ ...base, messages: [] }) - expect(historyItem).not.toHaveProperty("usageByModel") + expect(historyItem).toHaveProperty("usageByModel", undefined) expect(historyItem.tokensIn).toBe(0) }) }) diff --git a/src/core/task-persistence/taskMetadata.ts b/src/core/task-persistence/taskMetadata.ts index 827095f67a..c5a6af102f 100644 --- a/src/core/task-persistence/taskMetadata.ts +++ b/src/core/task-persistence/taskMetadata.ts @@ -110,8 +110,11 @@ export async function taskMetadata({ cacheWrites: tokenUsage.totalCacheWrites, cacheReads: tokenUsage.totalCacheReads, totalCost: tokenUsage.totalCost, - // Only emitted when something was recorded, so older tasks and empty tasks keep their exact shape. - ...(usageByModel.length > 0 ? { usageByModel } : {}), + // Always present, as `undefined` when nothing was recorded: the history store merges onto the stored + // item, so omitting the key would keep a stale breakdown after the messages were replaced (e.g. a + // rewind). `undefined` overrides it and is dropped when the item is written, so the stored shape of + // older and empty tasks is unchanged. + usageByModel: usageByModel.length > 0 ? usageByModel : undefined, size: taskDirSize, workspace, mode, diff --git a/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts b/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts index dd234a9c95..457318ae8e 100644 --- a/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts +++ b/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts @@ -246,6 +246,31 @@ describe("webviewMessageHandler – requestProviderQuotas", () => { expect(quotas.getProviderQuotas).toHaveBeenCalledTimes(1) }) + it("lets a newer request with the same id keep its slot when the older one finishes first", async () => { + quotas.getProviderQuotas.mockResolvedValue([]) + const releases: Array<(entries: { id: string }[]) => void> = [] + const provider = makeProvider() + provider.providerSettingsManager.listConfig = vi.fn( + () => new Promise((resolve) => releases.push(resolve)), + ) as never + + // Start them one after the other: see the note in the test above. + const older = webviewMessageHandler(provider, { type: "requestProviderQuotas", requestId: "same-id" }) + await vi.waitFor(() => expect(releases).toHaveLength(1)) + const newer = webviewMessageHandler(provider, { type: "requestProviderQuotas", requestId: "same-id" }) + await vi.waitFor(() => expect(releases).toHaveLength(2)) + + // The older one finishes and cleans up; it must not remove the newer one's entry. + releases[0]([{ id: "a" }]) + await older + await webviewMessageHandler(provider, { type: "cancelProviderQuotas", requestId: "same-id" }) + releases[1]([{ id: "a" }]) + await newer + + // The cancel reached the newer request, so only the older one was answered. + expect(provider.postMessageToWebview).toHaveBeenCalledTimes(1) + }) + it("marks the answer as failed when the quotas could not be loaded, and not when there are simply none", async () => { const failing = makeProvider() failing.providerSettingsManager.listConfig = vi.fn(async () => { diff --git a/src/services/language-models/copilotQuota.ts b/src/services/language-models/copilotQuota.ts index f68b6dadee..f7b5e4f188 100644 --- a/src/services/language-models/copilotQuota.ts +++ b/src/services/language-models/copilotQuota.ts @@ -95,7 +95,6 @@ function untilAborted(work: Promise, signal: AbortSignal | undefined, onAb onAbort() reject(new DOMException("Aborted", "AbortError")) } - if (signal.aborted) return abort() signal.addEventListener("abort", abort, { once: true }) work.then(resolve, reject).finally(() => signal.removeEventListener("abort", abort)) }) From 56d07b15184a3c8060acc29a59ba57d757b5a63b Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Wed, 28 Oct 2026 13:36:12 -0700 Subject: [PATCH 13/27] test: use providerIdentifiers in the usageByModel store test --- .../TaskHistoryStore.realConcurrency.spec.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/core/task-persistence/__tests__/TaskHistoryStore.realConcurrency.spec.ts b/src/core/task-persistence/__tests__/TaskHistoryStore.realConcurrency.spec.ts index 990519de56..54cc1075d5 100644 --- a/src/core/task-persistence/__tests__/TaskHistoryStore.realConcurrency.spec.ts +++ b/src/core/task-persistence/__tests__/TaskHistoryStore.realConcurrency.spec.ts @@ -2,7 +2,7 @@ import * as fs from "fs/promises" import * as os from "os" import * as path from "path" -import type { HistoryItem } from "@roo-code/types" +import { providerIdentifiers, type HistoryItem } from "@roo-code/types" import { TaskHistoryStore } from "../TaskHistoryStore" @@ -123,7 +123,14 @@ describe("TaskHistoryStore real cross-host locking", () => { const storagePath = await fs.mkdtemp(path.join(os.tmpdir(), "task-history-usage-clear-")) const store = new TaskHistoryStore(storagePath) const usageByModel = [ - { apiProvider: "anthropic", modelId: "m", requests: 1, tokensIn: 5, tokensOut: 5, cost: 1 }, + { + apiProvider: providerIdentifiers.anthropic, + modelId: "m", + requests: 1, + tokensIn: 5, + tokensOut: 5, + cost: 1, + }, ] try { From 017237ca93a7c69e6646fd74fb90b8a197cb20aa Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Wed, 28 Oct 2026 13:50:41 -0700 Subject: [PATCH 14/27] fix(usage): cancel profile loading and the Copilot token stage; add schema and rewind regression tests --- packages/types/src/__tests__/history.test.ts | 35 +++++++++++++ src/core/task/__tests__/Task.spec.ts | 52 +++++++++++++++++++ ...bviewMessageHandler.providerQuotas.spec.ts | 16 ++++++ src/core/webview/webviewMessageHandler.ts | 12 ++--- .../__tests__/copilotQuota.spec.ts | 16 ++++++ .../__tests__/providerQuotas.spec.ts | 35 +++++++++++++ src/services/language-models/copilotQuota.ts | 22 ++++++-- .../language-models/providerQuotas.ts | 16 ++++-- 8 files changed, 190 insertions(+), 14 deletions(-) diff --git a/packages/types/src/__tests__/history.test.ts b/packages/types/src/__tests__/history.test.ts index 883bb138d2..991a991b33 100644 --- a/packages/types/src/__tests__/history.test.ts +++ b/packages/types/src/__tests__/history.test.ts @@ -64,3 +64,38 @@ describe("historyItemSchema", () => { expect(historyItemSchema.parse(baseItem)).not.toHaveProperty("title") }) }) + +describe("usageByModel on history items", () => { + const base = { id: "task-1", number: 1, ts: 1, task: "t", tokensIn: 1, tokensOut: 1, totalCost: 0 } + + it("preserves every field of a per-model entry", () => { + const entry = { + apiProvider: "provider-a", + modelId: "model-a", + requests: 3, + tokensIn: 100, + tokensOut: 50, + cacheReads: 40, + cacheWrites: 10, + cost: 0.25, + } + expect(historyItemSchema.parse({ ...base, usageByModel: [entry, { ...entry, modelId: "model-b" }] })).toEqual({ + ...base, + usageByModel: [entry, { ...entry, modelId: "model-b" }], + }) + }) + + it("accepts an entry with no provider, model or cache counts, and an item with no breakdown", () => { + const bare = { requests: 1, tokensIn: 2, tokensOut: 3, cost: 0 } + expect(historyItemSchema.parse({ ...base, usageByModel: [bare] }).usageByModel).toEqual([bare]) + expect(historyItemSchema.parse(base).usageByModel).toBeUndefined() + }) + + it.each([ + ["a missing request count", { tokensIn: 1, tokensOut: 1, cost: 0 }], + ["a non-numeric cost", { requests: 1, tokensIn: 1, tokensOut: 1, cost: "free" }], + ["a non-numeric token count", { requests: 1, tokensIn: "1", tokensOut: 1, cost: 0 }], + ])("rejects %s", (_name, entry) => { + expect(historyItemSchema.safeParse({ ...base, usageByModel: [entry] }).success).toBe(false) + }) +}) diff --git a/src/core/task/__tests__/Task.spec.ts b/src/core/task/__tests__/Task.spec.ts index d7ac471a0b..cee47a1fb8 100644 --- a/src/core/task/__tests__/Task.spec.ts +++ b/src/core/task/__tests__/Task.spec.ts @@ -7602,6 +7602,58 @@ describe("Cline", () => { } }) + it("overwriteClineMessages sends an explicit empty usageByModel when the replacement records no usage", async () => { + // The history store merges onto the stored item, so a replacement with no recorded usage (for example + // after a rewind) must say so explicitly, or the earlier breakdown would stay on the stored item. + const taskDir = path.join(os.tmpdir(), "test-storage", "tasks", "00000000-0000-7000-8000-000000000000") + fsReal.mkdirSync(taskDir, { recursive: true }) + const historySpy = vi.spyOn(mockProvider, "updateTaskHistory") + try { + const task = new Task({ + provider: mockProvider, + apiConfiguration: mockApiConfig, + task: "test task", + startTask: false, + }) + const say = (kind: ClineMessage["say"], text: string, ts: number): ClineMessage => ({ + ts, + type: "say", + say: kind, + text, + }) + const withUsage = [ + say("text", "do it", 1), + say( + "api_req_started", + JSON.stringify({ + apiProvider: providerIdentifiers.anthropic, + modelId: "claude-sonnet-5", + tokensIn: 10, + tokensOut: 5, + cost: 0.5, + }), + 2, + ), + ] + + await task.overwriteClineMessages(withUsage) + const first = historySpy.mock.calls.at(-1)?.[0] + expect(first?.usageByModel).toEqual([ + expect.objectContaining({ apiProvider: providerIdentifiers.anthropic, requests: 1, cost: 0.5 }), + ]) + + // A rewind to before the request: the replacement records nothing. + await task.overwriteClineMessages([say("text", "do it", 1)]) + const second = historySpy.mock.calls.at(-1)?.[0] + expect(second).toBeDefined() + expect(second).toHaveProperty("usageByModel", undefined) + expect(second?.totalCost).toBe(0) + } finally { + fsReal.rmSync(path.join(taskDir, "ui_messages.json"), { force: true }) + historySpy.mockRestore() + } + }) + it("finalizePartialToolAsk skips the webview update when the message write itself fails", async () => { // Complements the later-stage-failure test above by failing the first save // stage: with the real task directory removed, safeWriteJson's fs.access diff --git a/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts b/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts index 457318ae8e..a1c9387443 100644 --- a/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts +++ b/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts @@ -203,6 +203,22 @@ describe("webviewMessageHandler – requestProviderQuotas", () => { expect(provider.postMessageToWebview).not.toHaveBeenCalled() }) + it("releases the handler on cancel without waiting for a profile read that never settles", async () => { + const provider = makeProvider() + provider.providerSettingsManager.listConfig = vi.fn(() => new Promise(() => {})) as never + + const running = webviewMessageHandler(provider, { type: "requestProviderQuotas", requestId: "req-stuck" }) + await vi.waitFor(() => expect(provider.providerSettingsManager.listConfig).toHaveBeenCalled()) + await webviewMessageHandler(provider, { type: "cancelProviderQuotas", requestId: "req-stuck" }) + + // Resolves although listConfig never does. + await running + expect(provider.providerSettingsManager.getProfile).not.toHaveBeenCalled() + expect(quotas.getProviderQuotas).not.toHaveBeenCalled() + expect(provider.postMessageToWebview).not.toHaveBeenCalled() + expect(provider.log).not.toHaveBeenCalled() + }) + it("keeps two webviews apart: a cancel from one never aborts the other's request with the same id", async () => { // Each webview has its own provider, and both number their requests from 1. Their loads are held open // at the profile list, so both are pending at once when the cancel arrives. diff --git a/src/core/webview/webviewMessageHandler.ts b/src/core/webview/webviewMessageHandler.ts index 11055fe2e9..247c7f3951 100644 --- a/src/core/webview/webviewMessageHandler.ts +++ b/src/core/webview/webviewMessageHandler.ts @@ -1599,13 +1599,11 @@ export const webviewMessageHandler = async ( try { const { getProviderQuotas, loadProfiles } = await import("../../services/language-models/providerQuotas") - const profiles = await loadProfiles(provider.providerSettingsManager) - if (!controller.signal.aborted) { - providerQuotas = await getProviderQuotas(profiles, { - force: message.bool === true, - signal: controller.signal, - }) - } + const profiles = await loadProfiles(provider.providerSettingsManager, controller.signal) + providerQuotas = await getProviderQuotas(profiles, { + force: message.bool === true, + signal: controller.signal, + }) } catch (error) { providerQuotasFailed = true if (!controller.signal.aborted) { diff --git a/src/services/language-models/__tests__/copilotQuota.spec.ts b/src/services/language-models/__tests__/copilotQuota.spec.ts index c4ec2eacab..b8eaa2c394 100644 --- a/src/services/language-models/__tests__/copilotQuota.spec.ts +++ b/src/services/language-models/__tests__/copilotQuota.spec.ts @@ -304,6 +304,22 @@ describe("getGitHubCopilotQuota", () => { expect(good).toHaveBeenCalledTimes(1) }) + it("stops waiting for a session request that never settles when the caller goes away", async () => { + getSession.mockImplementationOnce(() => new Promise(() => {})) + const fetchSpy = vi.fn() + const controller = new AbortController() + + const result = getGitHubCopilotQuota({ signal: controller.signal }, fetchSpy as never) + await vi.waitFor(() => expect(getSession).toHaveBeenCalled()) + controller.abort() + + await expect(result).rejects.toMatchObject({ name: "AbortError" }) + expect(fetchSpy).not.toHaveBeenCalled() + // The stuck lookup is not left holding the slot: the next call starts over. + const good = vi.fn(async () => json(businessPayload)) + await expect(getGitHubCopilotQuota({}, good as never)).resolves.toMatchObject({ ok: true }) + }) + it("does not start the GitHub request when it was cancelled while the token was being fetched", async () => { let release: (session: { accessToken: string }) => void = () => {} getSession.mockImplementationOnce(() => new Promise((resolve) => (release = resolve))) diff --git a/src/services/language-models/__tests__/providerQuotas.spec.ts b/src/services/language-models/__tests__/providerQuotas.spec.ts index b8e59b0895..e26c43e161 100644 --- a/src/services/language-models/__tests__/providerQuotas.spec.ts +++ b/src/services/language-models/__tests__/providerQuotas.spec.ts @@ -1013,6 +1013,41 @@ describe("loadProfiles", () => { expect(await loadProfiles(source)).toEqual([{ apiProvider: "x" }]) }) + it("stops waiting for the profile list when the signal aborts, and reads no profile", async () => { + const source = { listConfig: vi.fn(() => new Promise(() => {})), getProfile: vi.fn() } + const controller = new AbortController() + const loading = loadProfiles(source, controller.signal) + controller.abort() + await expect(loading).rejects.toMatchObject({ name: "AbortError" }) + expect(source.getProfile).not.toHaveBeenCalled() + }) + + it("stops waiting for profile reads when the signal aborts", async () => { + const source = { + listConfig: vi.fn(async () => [{ id: "a" }]), + getProfile: vi.fn(() => new Promise(() => {})), + } + const controller = new AbortController() + const loading = loadProfiles(source, controller.signal) + await vi.waitFor(() => expect(source.getProfile).toHaveBeenCalled()) + controller.abort() + await expect(loading).rejects.toMatchObject({ name: "AbortError" }) + }) + + it("requests no profile once the signal has aborted while the list was loading", async () => { + let release: (entries: { id: string }[]) => void = () => {} + const source = { + listConfig: vi.fn(() => new Promise<{ id: string }[]>((resolve) => (release = resolve))), + getProfile: vi.fn(), + } + const controller = new AbortController() + const loading = loadProfiles(source, controller.signal) + controller.abort() + release([{ id: "a" }]) + await expect(loading).rejects.toMatchObject({ name: "AbortError" }) + expect(source.getProfile).not.toHaveBeenCalled() + }) + it("returns an empty list when there are no profiles", async () => { expect(await loadProfiles({ listConfig: async () => [], getProfile: vi.fn() })).toEqual([]) }) diff --git a/src/services/language-models/copilotQuota.ts b/src/services/language-models/copilotQuota.ts index f7b5e4f188..5afd2226c2 100644 --- a/src/services/language-models/copilotQuota.ts +++ b/src/services/language-models/copilotQuota.ts @@ -68,10 +68,24 @@ export function parseCopilotQuota(payload: unknown, now = Date.now()): GitHubCop } } -async function getGitHubToken(): Promise { +/** Rejects as soon as `signal` aborts. The pending work cannot be cancelled, but nobody waits for it any more. */ +function raceAbort(work: Promise, signal: AbortSignal): Promise { + return new Promise((resolve, reject) => { + const abort = () => reject(new DOMException("Aborted", "AbortError")) + if (signal.aborted) return abort() + signal.addEventListener("abort", abort, { once: true }) + work.then(resolve, reject).finally(() => signal.removeEventListener("abort", abort)) + }) +} + +/** Each lookup is bounded by `signal`, so a session request that never settles cannot hold the quota request open. */ +async function getGitHubToken(signal: AbortSignal): Promise { const { authProviderId, authScopeSets } = githubCopilotLanguageModel for (const scopes of authScopeSets) { - const session = await vscode.authentication.getSession(authProviderId, scopes, { silent: true }) + const session = await raceAbort( + Promise.resolve(vscode.authentication.getSession(authProviderId, scopes, { silent: true })), + signal, + ) if (session) return session.accessToken } return undefined @@ -116,7 +130,9 @@ export function getGitHubCopilotQuota( const controller = new AbortController() const fetchQuota = async (): Promise => { try { - const token = await getGitHubToken() + const token = await getGitHubToken( + AbortSignal.any([controller.signal, AbortSignal.timeout(REQUEST_TIMEOUT_MS)]), + ) if (controller.signal.aborted) return { ok: false, reason: "error", message: "Request cancelled" } if (!token) return { ok: false, reason: "signedOut" } diff --git a/src/services/language-models/providerQuotas.ts b/src/services/language-models/providerQuotas.ts index bf4ba6afc7..a75c14a5b6 100644 --- a/src/services/language-models/providerQuotas.ts +++ b/src/services/language-models/providerQuotas.ts @@ -552,10 +552,18 @@ export interface ProfileSource { * load is skipped rather than failing the whole refresh. Keys never leave the * extension host: only formatted quota rows are posted to the webview. */ -export async function loadProfiles(source: ProfileSource): Promise { - const entries = await source.listConfig() - const profiles = await Promise.all( - entries.map((entry) => source.getProfile({ id: entry.id }).catch(() => undefined)), +export async function loadProfiles(source: ProfileSource, signal?: AbortSignal): Promise { + // Stops waiting as soon as `signal` aborts. The reads themselves cannot be cancelled, but no further + // profile is requested once the caller has gone. + const entries = await until(source.listConfig(), signal, () => {}) + const profiles = await until( + Promise.all( + entries.map((entry) => + signal?.aborted ? undefined : source.getProfile({ id: entry.id }).catch(() => undefined), + ), + ), + signal, + () => {}, ) return profiles.filter((p): p is ProviderSettings => !!p) } From ed9657f253b4d1bd356d8a069abc9b83ee337cc9 Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Wed, 28 Oct 2026 14:06:12 -0700 Subject: [PATCH 15/27] fix(usage): compute metadata from the persisted (merged) messages; assert the same-id response payload --- src/core/task/Task.ts | 8 +++- src/core/task/__tests__/Task.spec.ts | 46 +++++++++++++++++++ ...bviewMessageHandler.providerQuotas.spec.ts | 12 ++++- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index 7b8e0ded28..a529edf083 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -1768,8 +1768,12 @@ export class Task extends EventEmitter implements TaskLike { * to replace the stored messages outright. */ private async saveClineMessages(merge = true): Promise { + // What was actually persisted: with `merge`, newer messages another host wrote are folded in. The metadata + // (including the usage breakdown) is computed from it, so a stale local snapshot cannot clear usage that + // the stored messages still contain. + let persistedMessages: ClineMessage[] | undefined try { - await saveTaskMessages({ + persistedMessages = await saveTaskMessages({ messages: structuredClone(this.clineMessages), taskId: this.taskId, globalStoragePath: this.globalStoragePath, @@ -1790,7 +1794,7 @@ export class Task extends EventEmitter implements TaskLike { rootTaskId: this.rootTaskId, parentTaskId: this.parentTaskId, taskNumber: this.taskNumber, - messages: this.clineMessages, + messages: persistedMessages ?? this.clineMessages, globalStoragePath: this.globalStoragePath, workspace: this.cwd, mode: this._taskMode || defaultModeSlug, // Use the task's own mode, not the current provider mode. diff --git a/src/core/task/__tests__/Task.spec.ts b/src/core/task/__tests__/Task.spec.ts index cee47a1fb8..9636b434b6 100644 --- a/src/core/task/__tests__/Task.spec.ts +++ b/src/core/task/__tests__/Task.spec.ts @@ -7654,6 +7654,52 @@ describe("Cline", () => { } }) + it("computes the usage breakdown from the merged persisted messages, not a stale local snapshot", async () => { + // Another host appended a request that records usage. This host's snapshot does not have that message; + // saving merges the stored one in, and the metadata must follow what was persisted. + const taskDir = path.join(os.tmpdir(), "test-storage", "tasks", "00000000-0000-7000-8000-000000000000") + fsReal.mkdirSync(taskDir, { recursive: true }) + // The mocked fs.readFile serves `mockMessages` as the stored ui_messages.json. + const originalStored = mockMessages.splice(0) + const historySpy = vi.spyOn(mockProvider, "updateTaskHistory") + try { + const task = new Task({ + provider: mockProvider, + apiConfiguration: mockApiConfig, + task: "test task", + startTask: false, + }) + const recorded = JSON.stringify({ + apiProvider: providerIdentifiers.anthropic, + modelId: "claude-sonnet-5", + tokensIn: 10, + tokensOut: 5, + cost: 0.5, + }) + const message = (text: string, messageId: string) => ({ + ts: 2, + type: "say" as const, + say: "api_req_started" as const, + text, + messageId, + }) + const first = { ts: 1, type: "say" as const, say: "text" as const, text: "do it", messageId: "m1" } + mockMessages.push(first, message(recorded, "m2")) + + task.clineMessages = [first] + await getTaskTestAccess(task).saveClineMessages() + + const saved = historySpy.mock.calls.at(-1)?.[0] + expect(saved?.usageByModel).toEqual([ + expect.objectContaining({ apiProvider: providerIdentifiers.anthropic, requests: 1, cost: 0.5 }), + ]) + } finally { + mockMessages.splice(0, mockMessages.length, ...originalStored) + fsReal.rmSync(path.join(taskDir, "ui_messages.json"), { force: true }) + historySpy.mockRestore() + } + }) + it("finalizePartialToolAsk skips the webview update when the message write itself fails", async () => { // Complements the later-stage-failure test above by failing the first save // stage: with the real task directory removed, safeWriteJson's fs.access diff --git a/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts b/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts index a1c9387443..8c3ac1421b 100644 --- a/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts +++ b/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts @@ -279,12 +279,22 @@ describe("webviewMessageHandler – requestProviderQuotas", () => { // The older one finishes and cleans up; it must not remove the newer one's entry. releases[0]([{ id: "a" }]) await older + // The older request is answered, with a successful (empty) result. + expect(provider.postMessageToWebview).toHaveBeenCalledTimes(1) + expect(provider.postMessageToWebview).toHaveBeenLastCalledWith({ + type: "providerQuotas", + providerQuotas: [], + providerQuotasFailed: false, + requestId: "same-id", + }) + await webviewMessageHandler(provider, { type: "cancelProviderQuotas", requestId: "same-id" }) releases[1]([{ id: "a" }]) await newer - // The cancel reached the newer request, so only the older one was answered. + // The cancel reached the newer request, so it posts nothing and the count stays at one. expect(provider.postMessageToWebview).toHaveBeenCalledTimes(1) + expect(quotas.getProviderQuotas).toHaveBeenCalledTimes(1) }) it("marks the answer as failed when the quotas could not be loaded, and not when there are simply none", async () => { From f19d08a95edddea77e9c1984565f0b68fcb67beb Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Wed, 28 Oct 2026 14:19:43 -0700 Subject: [PATCH 16/27] refactor(usage): remove guards made unreachable by the abortable waits --- src/services/language-models/copilotQuota.ts | 3 +-- src/services/language-models/providerQuotas.ts | 10 +++------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/services/language-models/copilotQuota.ts b/src/services/language-models/copilotQuota.ts index 5afd2226c2..c9df8aa15e 100644 --- a/src/services/language-models/copilotQuota.ts +++ b/src/services/language-models/copilotQuota.ts @@ -71,8 +71,8 @@ export function parseCopilotQuota(payload: unknown, now = Date.now()): GitHubCop /** Rejects as soon as `signal` aborts. The pending work cannot be cancelled, but nobody waits for it any more. */ function raceAbort(work: Promise, signal: AbortSignal): Promise { return new Promise((resolve, reject) => { + // The signal is never aborted before this is called (it combines a fresh controller and a timeout). const abort = () => reject(new DOMException("Aborted", "AbortError")) - if (signal.aborted) return abort() signal.addEventListener("abort", abort, { once: true }) work.then(resolve, reject).finally(() => signal.removeEventListener("abort", abort)) }) @@ -133,7 +133,6 @@ export function getGitHubCopilotQuota( const token = await getGitHubToken( AbortSignal.any([controller.signal, AbortSignal.timeout(REQUEST_TIMEOUT_MS)]), ) - if (controller.signal.aborted) return { ok: false, reason: "error", message: "Request cancelled" } if (!token) return { ok: false, reason: "signedOut" } const response = await fetchImpl(COPILOT_USER_URL, { diff --git a/src/services/language-models/providerQuotas.ts b/src/services/language-models/providerQuotas.ts index a75c14a5b6..362449533a 100644 --- a/src/services/language-models/providerQuotas.ts +++ b/src/services/language-models/providerQuotas.ts @@ -553,15 +553,11 @@ export interface ProfileSource { * extension host: only formatted quota rows are posted to the webview. */ export async function loadProfiles(source: ProfileSource, signal?: AbortSignal): Promise { - // Stops waiting as soon as `signal` aborts. The reads themselves cannot be cancelled, but no further - // profile is requested once the caller has gone. + // Stops waiting as soon as `signal` aborts. The reads themselves cannot be cancelled, but the profile reads + // are not started once the list wait has been abandoned. const entries = await until(source.listConfig(), signal, () => {}) const profiles = await until( - Promise.all( - entries.map((entry) => - signal?.aborted ? undefined : source.getProfile({ id: entry.id }).catch(() => undefined), - ), - ), + Promise.all(entries.map((entry) => source.getProfile({ id: entry.id }).catch(() => undefined))), signal, () => {}, ) From ab61e5500772b44b6e3caa684e7128abb0953e49 Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Thu, 29 Oct 2026 15:33:53 -0700 Subject: [PATCH 17/27] test(usage): pin the cache lifetime and hostile base URLs; report a Copilot payload without premium data as an error --- .../__tests__/copilotQuota.spec.ts | 36 ++++++- .../__tests__/providerQuotas.spec.ts | 93 +++++++++++++++---- src/services/language-models/copilotQuota.ts | 6 +- 3 files changed, 112 insertions(+), 23 deletions(-) diff --git a/src/services/language-models/__tests__/copilotQuota.spec.ts b/src/services/language-models/__tests__/copilotQuota.spec.ts index b8eaa2c394..64b196ff67 100644 --- a/src/services/language-models/__tests__/copilotQuota.spec.ts +++ b/src/services/language-models/__tests__/copilotQuota.spec.ts @@ -1,4 +1,4 @@ -import { beforeEach, describe, expect, it, vi } from "vitest" +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest" vi.mock("vscode", () => ({ version: "1.0.0", authentication: { getSession: vi.fn() } })) @@ -149,10 +149,17 @@ describe("getGitHubCopilotQuota", () => { expect(result).toEqual({ ok: false, reason: "error", message: "GitHub API error 500" }) }) - it("reports noCopilot when the payload has no premium snapshot", async () => { - const result = await getGitHubCopilotQuota({}, (async () => json({ quota_snapshots: {} })) as never) - expect(result).toMatchObject({ ok: false, reason: "noCopilot" }) - }) + it.each([ + ["an empty quota_snapshots", { quota_snapshots: {} }], + ["a renamed premium field", { copilot_plan: "pro", quota_snapshots: { premium_requests: {} } }], + ["no quota_snapshots", { copilot_plan: "pro" }], + ])( + "reports an error, not noCopilot, when a successful payload has no premium snapshot (%s)", + async (_name, body) => { + const result = await getGitHubCopilotQuota({}, (async () => json(body)) as never) + expect(result).toEqual({ ok: false, reason: "error", message: "GitHub returned no premium request quota" }) + }, + ) it("turns network errors into a generic error result instead of throwing", async () => { const result = await getGitHubCopilotQuota({}, (async () => { @@ -185,6 +192,25 @@ describe("getGitHubCopilotQuota", () => { expect(fetchSpy).toHaveBeenCalledTimes(2) }) + describe("the cache lifetime", () => { + afterEach(() => vi.useRealTimers()) + + it.each([ + [59_999, 1], + [60_000, 2], + ])("serves a cached result %i ms after it was fetched with %i request(s) in total", async (age, requests) => { + vi.useFakeTimers() + vi.setSystemTime(1_000_000) + const fetchSpy = vi.fn(async () => json(businessPayload)) + await getGitHubCopilotQuota({}, fetchSpy as never) + + vi.setSystemTime(1_000_000 + age) + await getGitHubCopilotQuota({}, fetchSpy as never) + + expect(fetchSpy).toHaveBeenCalledTimes(requests) + }) + }) + it("does not cache failures", async () => { const fail = vi.fn(async () => json({}, 500)) await getGitHubCopilotQuota({}, fail as never) diff --git a/src/services/language-models/__tests__/providerQuotas.spec.ts b/src/services/language-models/__tests__/providerQuotas.spec.ts index e26c43e161..52a24b4045 100644 --- a/src/services/language-models/__tests__/providerQuotas.spec.ts +++ b/src/services/language-models/__tests__/providerQuotas.spec.ts @@ -1,4 +1,4 @@ -import { beforeEach, describe, expect, it, vi } from "vitest" +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest" import { providerIdentifiers } from "@roo-code/types" @@ -672,25 +672,62 @@ describe("getProviderQuotas", () => { expect(q).toMatchObject({ ok: true }) }) - it("never sends a key to a custom base URL", async () => { - const fetchSpy = vi.fn(okFetch) - const [q] = await getProviderQuotas( - [ - { - apiProvider: providerIdentifiers.openrouter, - openRouterApiKey: "sk", - openRouterBaseUrl: "https://evil.example/api/v1", - } as never, - ], - {}, - fetchSpy, - ) - expect(q).toMatchObject({ ok: false, reason: "unsupported" }) - expect(fetchSpy).not.toHaveBeenCalled() + describe("never sends a key to a base URL that is not the provider's own host", () => { + const providers = [ + { + id: providerIdentifiers.openrouter, + host: "openrouter.ai", + own: "https://openrouter.ai/api/v1", + settings: { openRouterApiKey: "sk" }, + urlKey: "openRouterBaseUrl", + }, + { + id: providerIdentifiers.deepseek, + host: "api.deepseek.com", + own: "https://api.deepseek.com", + settings: { deepSeekApiKey: "sk" }, + urlKey: "deepSeekBaseUrl", + }, + { + id: providerIdentifiers.moonshot, + host: "api.moonshot.ai", + own: "https://api.moonshot.ai/v1", + settings: { moonshotApiKey: "sk" }, + urlKey: "moonshotBaseUrl", + }, + ] as const + + const hostile = (host: string) => [ + "https://evil.example/api/v1", + `https://${host}.evil.com`, + `https://user@${host}.evil.com`, + `http://${host}`, + `https://${host}:8443`, + ] + + const cases = providers.flatMap((p) => hostile(p.host).map((url) => [p.id, url, p] as const)) + + it.each(cases)("%s: %s", async (_id, url, p) => { + const fetchSpy = vi.fn(okFetch) + const [q] = await getProviderQuotas( + [{ apiProvider: p.id, ...p.settings, [p.urlKey]: url } as never], + {}, + fetchSpy, + ) + expect(q).toMatchObject({ ok: false, reason: "unsupported" }) + expect(fetchSpy).not.toHaveBeenCalled() + }) + + it.each(providers.map((p) => [p.id, p] as const))("%s: still queries its own host", async (_id, p) => { + const fetchSpy = vi.fn(async (_url: RequestInfo | URL, _init?: RequestInit) => okFetch()) + await getProviderQuotas([{ apiProvider: p.id, ...p.settings, [p.urlKey]: p.own } as never], {}, fetchSpy) + expect(fetchSpy).toHaveBeenCalled() + for (const [url] of fetchSpy.mock.calls) expect(String(url).startsWith(p.own)).toBe(true) + }) }) it("calls the provider's own host with the saved key", async () => { - const fetchSpy = vi.fn(okFetch) + const fetchSpy = vi.fn(async (_url: RequestInfo | URL, _init?: RequestInit) => okFetch()) const [q] = await getProviderQuotas( [{ apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "sk-test" } as never], {}, @@ -975,6 +1012,28 @@ describe("getProviderQuotas", () => { expect(ok).toHaveBeenCalledTimes(1) }) + describe("the cache lifetime", () => { + afterEach(() => vi.useRealTimers()) + + it.each([ + [59_999, 1], + [60_000, 2], + ])("a result %i ms old gives %i request(s) in total", async (age, requests) => { + vi.useFakeTimers() + vi.setSystemTime(1_000_000) + const fetchSpy = vi.fn( + async () => new Response(JSON.stringify({ data: { limit: 10, limit_remaining: 5 } })), + ) + const profiles = [{ apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "sk" } as never] + await getProviderQuotas(profiles, {}, fetchSpy) + + vi.setSystemTime(1_000_000 + age) + await getProviderQuotas(profiles, {}, fetchSpy) + + expect(fetchSpy).toHaveBeenCalledTimes(requests) + }) + }) + it("caches results for the same set of providers unless forced", async () => { const fetchSpy = vi.fn(async () => new Response(JSON.stringify({ data: { limit: 10, limit_remaining: 5 } }))) const profiles = [{ apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "sk" } as never] diff --git a/src/services/language-models/copilotQuota.ts b/src/services/language-models/copilotQuota.ts index c9df8aa15e..be59d1337b 100644 --- a/src/services/language-models/copilotQuota.ts +++ b/src/services/language-models/copilotQuota.ts @@ -151,7 +151,11 @@ export function getGitHubCopilotQuota( if (!response.ok) return { ok: false, reason: "error", message: `GitHub API error ${response.status}` } const quota = parseCopilotQuota(await response.json()) - return quota ? { ok: true, quota } : { ok: false, reason: "noCopilot" } + // A 403 or 404 is how GitHub says there is no Copilot. A success without a premium snapshot is more likely + // a changed payload on this undocumented endpoint, and must not be shown as "no Copilot". + return quota + ? { ok: true, quota } + : { ok: false, reason: "error", message: "GitHub returned no premium request quota" } } catch (error) { return { ok: false, reason: "error", message: safeErrorMessage(error) } } From a6a594cd816135c36ff55d4099b754d340633243 Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Thu, 29 Oct 2026 15:41:15 -0700 Subject: [PATCH 18/27] feat(usage): translate the names of fixed provider-limit windows --- packages/types/src/providers/vscode-llm.ts | 5 ++ .../__tests__/providerQuotas.spec.ts | 49 +++++++++++++++++++ .../language-models/providerQuotas.ts | 25 +++++++++- .../components/settings/ProviderLimits.tsx | 6 ++- .../__tests__/ProviderLimits.spec.tsx | 30 ++++++++++++ webview-ui/src/i18n/locales/ca/settings.json | 10 +++- webview-ui/src/i18n/locales/de/settings.json | 10 +++- webview-ui/src/i18n/locales/en/settings.json | 10 +++- webview-ui/src/i18n/locales/es/settings.json | 10 +++- webview-ui/src/i18n/locales/fr/settings.json | 10 +++- webview-ui/src/i18n/locales/hi/settings.json | 10 +++- webview-ui/src/i18n/locales/id/settings.json | 10 +++- webview-ui/src/i18n/locales/it/settings.json | 10 +++- webview-ui/src/i18n/locales/ja/settings.json | 10 +++- webview-ui/src/i18n/locales/ko/settings.json | 10 +++- webview-ui/src/i18n/locales/nl/settings.json | 10 +++- webview-ui/src/i18n/locales/pl/settings.json | 10 +++- .../src/i18n/locales/pt-BR/settings.json | 10 +++- webview-ui/src/i18n/locales/ru/settings.json | 10 +++- webview-ui/src/i18n/locales/tr/settings.json | 10 +++- webview-ui/src/i18n/locales/vi/settings.json | 10 +++- .../src/i18n/locales/zh-CN/settings.json | 10 +++- .../src/i18n/locales/zh-TW/settings.json | 10 +++- 23 files changed, 274 insertions(+), 21 deletions(-) diff --git a/packages/types/src/providers/vscode-llm.ts b/packages/types/src/providers/vscode-llm.ts index 91e74e54fd..e130cdbd9d 100644 --- a/packages/types/src/providers/vscode-llm.ts +++ b/packages/types/src/providers/vscode-llm.ts @@ -25,6 +25,11 @@ export interface ProviderQuotaWindow { id: string /** Pre-formatted primary figure, e.g. "39,389.3 / 140,000 used", "$12.40 left". */ valueLabel: string + /** + * Set when the label is just the name of a fixed window ("Weekly", "5-hour", "Unlimited"), so the webview can + * show it in the user's language. `valueLabel` stays as the English fallback. + */ + name?: { key: "weekly" | "daily" | "monthly" | "unlimited" | "hours" | "days"; count?: number } /** 0–100 when the provider reports a bounded allowance. */ usedPercent?: number /** Epoch ms. */ diff --git a/src/services/language-models/__tests__/providerQuotas.spec.ts b/src/services/language-models/__tests__/providerQuotas.spec.ts index 52a24b4045..4d11ea9871 100644 --- a/src/services/language-models/__tests__/providerQuotas.spec.ts +++ b/src/services/language-models/__tests__/providerQuotas.spec.ts @@ -1045,6 +1045,55 @@ describe("getProviderQuotas", () => { }) }) +describe("window names", () => { + beforeEach(() => resetProviderQuotaCache()) + + const quotaFrom = async (profile: Record, body: unknown) => { + const [q] = await getProviderQuotas( + [profile as never], + {}, + vi.fn(async () => new Response(JSON.stringify(body))), + ) + return q + } + + it("gives the fixed windows of OpenCode Go a structured name next to the English text", async () => { + const q = await quotaFrom( + { apiProvider: providerIdentifiers.opencodeGo, opencodeGoApiKey: "sk" }, + { + usage: { + rolling: { percent: 10, resetsAt: 1_800_000_000 }, + weekly: { percent: 20, resetsAt: 1_800_000_000 }, + monthly: { percent: 30, resetsAt: 1_800_000_000 }, + }, + }, + ) + expect(q).toMatchObject({ + ok: true, + windows: [ + { valueLabel: "5-hour", name: { key: "hours", count: 5 } }, + { valueLabel: "Weekly", name: { key: "weekly" } }, + { valueLabel: "Monthly", name: { key: "monthly" } }, + ], + }) + }) + + it("names a Copilot unlimited plan, and leaves a figure without a name", async () => { + const copilot = await import("../copilotQuota") + vi.mocked(copilot.getGitHubCopilotQuota).mockResolvedValueOnce({ + ok: true, + quota: { unlimited: true, resetAt: 7, fetchedAt: 1 }, + }) + const [unlimited] = await getProviderQuotas([{ apiProvider: providerIdentifiers.githubCopilot } as never], {}) + expect(unlimited).toMatchObject({ windows: [{ valueLabel: "Unlimited", name: { key: "unlimited" } }] }) + + resetProviderQuotaCache() + const [counted] = await getProviderQuotas([{ apiProvider: providerIdentifiers.githubCopilot } as never], {}) + expect(counted).toMatchObject({ ok: true, windows: [{ valueLabel: "39,389.3 / 140,000 used" }] }) + expect(counted.ok && counted.windows[0]).not.toHaveProperty("name") + }) +}) + describe("loadProfiles", () => { it("loads every saved profile through the manager, with keys", async () => { const source = { diff --git a/src/services/language-models/providerQuotas.ts b/src/services/language-models/providerQuotas.ts index 362449533a..342445d17e 100644 --- a/src/services/language-models/providerQuotas.ts +++ b/src/services/language-models/providerQuotas.ts @@ -86,6 +86,27 @@ export function windowLabel(seconds: number | undefined, fallback: string): stri return fallback } +const FIXED_WINDOW_NAMES: Record> = { + Weekly: { key: "weekly" }, + Daily: { key: "daily" }, + Monthly: { key: "monthly" }, + Unlimited: { key: "unlimited" }, +} + +/** The structured name of a window whose label is only its name, so it can be translated. Anything else is left as is. */ +function windowName(label: string): ProviderQuotaWindow["name"] { + const fixed = FIXED_WINDOW_NAMES[label] + if (fixed) return fixed + const rolling = /^(\d+)-(hour|day)$/.exec(label) + return rolling ? { key: rolling[2] === "hour" ? "hours" : "days", count: Number(rolling[1]) } : undefined +} + +const withNames = (windows: ProviderQuotaWindow[]): ProviderQuotaWindow[] => + windows.map((w) => { + const name = windowName(w.valueLabel) + return name ? { ...w, name } : w + }) + /** Kimi Code `GET /coding/v1/usages` → 5-hour / weekly / monthly usage. */ export function parseKimiCodeUsage(payload: unknown): ProviderQuotaWindow[] | undefined { const root = asRecord(payload) @@ -502,7 +523,7 @@ async function fetchKeyed( } if (!windows?.length && lastError) throw lastError return windows?.length - ? { providerId: provider.providerId, ok: true, windows, fetchedAt: now } + ? { providerId: provider.providerId, ok: true, windows: withNames(windows), fetchedAt: now } : { providerId: provider.providerId, ok: false, reason: "error", message: "No usage data", fetchedAt: now } } catch (error) { return { @@ -536,7 +557,7 @@ async function fetchCopilot(force: boolean, signal?: AbortSignal): Promise (

- {w.valueLabel} + + {w.name + ? t(`settings:usage.limits.window.${w.name.key}`, { n: w.name.count }) + : w.valueLabel} + {w.usedPercent !== undefined && ( {Math.round(w.usedPercent)}% diff --git a/webview-ui/src/components/settings/__tests__/ProviderLimits.spec.tsx b/webview-ui/src/components/settings/__tests__/ProviderLimits.spec.tsx index b11a6d17e9..1466ea1811 100644 --- a/webview-ui/src/components/settings/__tests__/ProviderLimits.spec.tsx +++ b/webview-ui/src/components/settings/__tests__/ProviderLimits.spec.tsx @@ -53,6 +53,36 @@ describe("ProviderLimits", () => { }) }) + describe("window names", () => { + const quota = (windows: Extract["windows"]): ProviderQuota => ({ + providerId: providerIdentifiers.zai, + ok: true, + windows, + fetchedAt: 1, + }) + + it.each([ + [{ key: "weekly" }, "settings:usage.limits.window.weekly"], + [{ key: "unlimited" }, "settings:usage.limits.window.unlimited"], + [{ key: "hours", count: 5 }, "settings:usage.limits.window.hours 5"], + [{ key: "days", count: 3 }, "settings:usage.limits.window.days 3"], + ] as const)("translates a window named %j", (name, expected) => { + render() + respond([quota([{ id: "w", valueLabel: "ENGLISH FALLBACK", name }])]) + + const row = screen.getByTestId(`provider-limit-${providerIdentifiers.zai}`) + expect(row.textContent).toContain(expected) + expect(row.textContent).not.toContain("ENGLISH FALLBACK") + }) + + it("shows the host's text for a window without a fixed name", () => { + render() + respond([quota([{ id: "b", valueLabel: "$4.25 left" }])]) + + expect(screen.getByTestId(`provider-limit-${providerIdentifiers.zai}`).textContent).toContain("$4.25 left") + }) + }) + it("shows a loading row until the first response", () => { render() expect(screen.getByTestId("provider-limits")).toBeTruthy() diff --git a/webview-ui/src/i18n/locales/ca/settings.json b/webview-ui/src/i18n/locales/ca/settings.json index bb82add8fc..2f4f9f6730 100644 --- a/webview-ui/src/i18n/locales/ca/settings.json +++ b/webview-ui/src/i18n/locales/ca/settings.json @@ -1278,7 +1278,15 @@ "noCopilot": "Sense quota de Copilot", "noKey": "Clau d'API absent o no vàlida", "unsupported": "URL base personalitzada — no comprovat", - "error": "No s'ha pogut carregar" + "error": "No s'ha pogut carregar", + "window": { + "weekly": "Setmanal", + "daily": "Diari", + "monthly": "Mensual", + "unlimited": "Il·limitat", + "hours": "{{n}} hores", + "days": "{{n}} dies" + } }, "byModel": "Per model", "notRecorded": "No registrat", diff --git a/webview-ui/src/i18n/locales/de/settings.json b/webview-ui/src/i18n/locales/de/settings.json index 7b2ba025ce..712aa2d30f 100644 --- a/webview-ui/src/i18n/locales/de/settings.json +++ b/webview-ui/src/i18n/locales/de/settings.json @@ -1278,7 +1278,15 @@ "noCopilot": "Kein Copilot-Kontingent", "noKey": "API-Schlüssel fehlt oder ist ungültig", "unsupported": "Benutzerdefinierte Basis-URL – nicht geprüft", - "error": "Konnte nicht geladen werden" + "error": "Konnte nicht geladen werden", + "window": { + "weekly": "Wöchentlich", + "daily": "Täglich", + "monthly": "Monatlich", + "unlimited": "Unbegrenzt", + "hours": "{{n}} Stunden", + "days": "{{n}} Tage" + } }, "byModel": "Nach Modell", "notRecorded": "Nicht erfasst", diff --git a/webview-ui/src/i18n/locales/en/settings.json b/webview-ui/src/i18n/locales/en/settings.json index ad2a3f87cf..860faa87e0 100644 --- a/webview-ui/src/i18n/locales/en/settings.json +++ b/webview-ui/src/i18n/locales/en/settings.json @@ -1278,7 +1278,15 @@ "noCopilot": "No Copilot quota", "noKey": "API key missing or invalid", "unsupported": "Custom base URL — not checked", - "error": "Couldn't load" + "error": "Couldn't load", + "window": { + "weekly": "Weekly", + "daily": "Daily", + "monthly": "Monthly", + "unlimited": "Unlimited", + "hours": "{{n}}-hour", + "days": "{{n}}-day" + } }, "byModel": "By model", "notRecorded": "Not recorded", diff --git a/webview-ui/src/i18n/locales/es/settings.json b/webview-ui/src/i18n/locales/es/settings.json index 474a5c2437..a4e5dc44c1 100644 --- a/webview-ui/src/i18n/locales/es/settings.json +++ b/webview-ui/src/i18n/locales/es/settings.json @@ -1278,7 +1278,15 @@ "noCopilot": "Sin cuota de Copilot", "noKey": "Falta la clave de API o no es válida", "unsupported": "URL base personalizada: no comprobado", - "error": "No se pudo cargar" + "error": "No se pudo cargar", + "window": { + "weekly": "Semanal", + "daily": "Diario", + "monthly": "Mensual", + "unlimited": "Ilimitado", + "hours": "{{n}} horas", + "days": "{{n}} días" + } }, "byModel": "Por modelo", "notRecorded": "No registrado", diff --git a/webview-ui/src/i18n/locales/fr/settings.json b/webview-ui/src/i18n/locales/fr/settings.json index 2a8fe1e993..656e250050 100644 --- a/webview-ui/src/i18n/locales/fr/settings.json +++ b/webview-ui/src/i18n/locales/fr/settings.json @@ -1278,7 +1278,15 @@ "noCopilot": "Aucun quota Copilot", "noKey": "Clé API manquante ou invalide", "unsupported": "URL de base personnalisée — non vérifiée", - "error": "Impossible de charger" + "error": "Impossible de charger", + "window": { + "weekly": "Hebdomadaire", + "daily": "Quotidien", + "monthly": "Mensuel", + "unlimited": "Illimité", + "hours": "{{n}} heures", + "days": "{{n}} jours" + } }, "byModel": "Par modèle", "notRecorded": "Non enregistré", diff --git a/webview-ui/src/i18n/locales/hi/settings.json b/webview-ui/src/i18n/locales/hi/settings.json index 738875d3b4..af07b366f1 100644 --- a/webview-ui/src/i18n/locales/hi/settings.json +++ b/webview-ui/src/i18n/locales/hi/settings.json @@ -1278,7 +1278,15 @@ "noCopilot": "कोई Copilot कोटा नहीं", "noKey": "API कुंजी अनुपलब्ध या अमान्य", "unsupported": "कस्टम बेस URL — जाँच नहीं की गई", - "error": "लोड नहीं हो सका" + "error": "लोड नहीं हो सका", + "window": { + "weekly": "साप्ताहिक", + "daily": "दैनिक", + "monthly": "मासिक", + "unlimited": "असीमित", + "hours": "{{n}} घंटे", + "days": "{{n}} दिन" + } }, "byModel": "मॉडल के अनुसार", "notRecorded": "दर्ज नहीं", diff --git a/webview-ui/src/i18n/locales/id/settings.json b/webview-ui/src/i18n/locales/id/settings.json index c929956917..acfe059c97 100644 --- a/webview-ui/src/i18n/locales/id/settings.json +++ b/webview-ui/src/i18n/locales/id/settings.json @@ -1278,7 +1278,15 @@ "noCopilot": "Tidak ada kuota Copilot", "noKey": "Kunci API hilang atau tidak valid", "unsupported": "URL dasar kustom — tidak diperiksa", - "error": "Tidak dapat dimuat" + "error": "Tidak dapat dimuat", + "window": { + "weekly": "Mingguan", + "daily": "Harian", + "monthly": "Bulanan", + "unlimited": "Tanpa batas", + "hours": "{{n}} jam", + "days": "{{n}} hari" + } }, "byModel": "Menurut model", "notRecorded": "Tidak dicatat", diff --git a/webview-ui/src/i18n/locales/it/settings.json b/webview-ui/src/i18n/locales/it/settings.json index 46a62a2ed7..3c658c7f48 100644 --- a/webview-ui/src/i18n/locales/it/settings.json +++ b/webview-ui/src/i18n/locales/it/settings.json @@ -1278,7 +1278,15 @@ "noCopilot": "Nessuna quota Copilot", "noKey": "Chiave API mancante o non valida", "unsupported": "URL di base personalizzato — non controllato", - "error": "Impossibile caricare" + "error": "Impossibile caricare", + "window": { + "weekly": "Settimanale", + "daily": "Giornaliero", + "monthly": "Mensile", + "unlimited": "Illimitato", + "hours": "{{n}} ore", + "days": "{{n}} giorni" + } }, "byModel": "Per modello", "notRecorded": "Non registrato", diff --git a/webview-ui/src/i18n/locales/ja/settings.json b/webview-ui/src/i18n/locales/ja/settings.json index 8d3e18b157..4702c26c66 100644 --- a/webview-ui/src/i18n/locales/ja/settings.json +++ b/webview-ui/src/i18n/locales/ja/settings.json @@ -1278,7 +1278,15 @@ "noCopilot": "Copilot のクォータなし", "noKey": "API キーがないか無効です", "unsupported": "カスタムベース URL — 確認していません", - "error": "読み込めませんでした" + "error": "読み込めませんでした", + "window": { + "weekly": "週間", + "daily": "日次", + "monthly": "月間", + "unlimited": "無制限", + "hours": "{{n}}時間", + "days": "{{n}}日" + } }, "byModel": "モデル別", "notRecorded": "記録なし", diff --git a/webview-ui/src/i18n/locales/ko/settings.json b/webview-ui/src/i18n/locales/ko/settings.json index 55adcdf557..19db9f45bc 100644 --- a/webview-ui/src/i18n/locales/ko/settings.json +++ b/webview-ui/src/i18n/locales/ko/settings.json @@ -1278,7 +1278,15 @@ "noCopilot": "Copilot 할당량 없음", "noKey": "API 키가 없거나 올바르지 않음", "unsupported": "사용자 지정 기본 URL — 확인하지 않음", - "error": "불러올 수 없음" + "error": "불러올 수 없음", + "window": { + "weekly": "주간", + "daily": "일간", + "monthly": "월간", + "unlimited": "무제한", + "hours": "{{n}}시간", + "days": "{{n}}일" + } }, "byModel": "모델별", "notRecorded": "기록되지 않음", diff --git a/webview-ui/src/i18n/locales/nl/settings.json b/webview-ui/src/i18n/locales/nl/settings.json index c29cfc42b5..df330c031d 100644 --- a/webview-ui/src/i18n/locales/nl/settings.json +++ b/webview-ui/src/i18n/locales/nl/settings.json @@ -1278,7 +1278,15 @@ "noCopilot": "Geen Copilot-quotum", "noKey": "API-sleutel ontbreekt of is ongeldig", "unsupported": "Aangepaste basis-URL — niet gecontroleerd", - "error": "Kon niet laden" + "error": "Kon niet laden", + "window": { + "weekly": "Wekelijks", + "daily": "Dagelijks", + "monthly": "Maandelijks", + "unlimited": "Onbeperkt", + "hours": "{{n}} uur", + "days": "{{n}} dagen" + } }, "byModel": "Per model", "notRecorded": "Niet vastgelegd", diff --git a/webview-ui/src/i18n/locales/pl/settings.json b/webview-ui/src/i18n/locales/pl/settings.json index f65684ed5b..908436ec20 100644 --- a/webview-ui/src/i18n/locales/pl/settings.json +++ b/webview-ui/src/i18n/locales/pl/settings.json @@ -1278,7 +1278,15 @@ "noCopilot": "Brak limitu Copilot", "noKey": "Brak klucza API lub jest nieprawidłowy", "unsupported": "Niestandardowy bazowy URL — nie sprawdzono", - "error": "Nie udało się wczytać" + "error": "Nie udało się wczytać", + "window": { + "weekly": "Tygodniowo", + "daily": "Dziennie", + "monthly": "Miesięcznie", + "unlimited": "Bez limitu", + "hours": "{{n}} godz.", + "days": "{{n}} dni" + } }, "byModel": "Według modelu", "notRecorded": "Nie zapisano", diff --git a/webview-ui/src/i18n/locales/pt-BR/settings.json b/webview-ui/src/i18n/locales/pt-BR/settings.json index ad47efbbe9..36947565a8 100644 --- a/webview-ui/src/i18n/locales/pt-BR/settings.json +++ b/webview-ui/src/i18n/locales/pt-BR/settings.json @@ -1278,7 +1278,15 @@ "noCopilot": "Sem cota do Copilot", "noKey": "Chave de API ausente ou inválida", "unsupported": "URL base personalizada — não verificada", - "error": "Não foi possível carregar" + "error": "Não foi possível carregar", + "window": { + "weekly": "Semanal", + "daily": "Diário", + "monthly": "Mensal", + "unlimited": "Ilimitado", + "hours": "{{n}} horas", + "days": "{{n}} dias" + } }, "byModel": "Por modelo", "notRecorded": "Não registrado", diff --git a/webview-ui/src/i18n/locales/ru/settings.json b/webview-ui/src/i18n/locales/ru/settings.json index a2ff469dbb..259921ab43 100644 --- a/webview-ui/src/i18n/locales/ru/settings.json +++ b/webview-ui/src/i18n/locales/ru/settings.json @@ -1278,7 +1278,15 @@ "noCopilot": "Нет квоты Copilot", "noKey": "Ключ API отсутствует или недействителен", "unsupported": "Пользовательский базовый URL — не проверено", - "error": "Не удалось загрузить" + "error": "Не удалось загрузить", + "window": { + "weekly": "Еженедельно", + "daily": "Ежедневно", + "monthly": "Ежемесячно", + "unlimited": "Без ограничений", + "hours": "{{n}} ч", + "days": "{{n}} дн." + } }, "byModel": "По моделям", "notRecorded": "Не записано", diff --git a/webview-ui/src/i18n/locales/tr/settings.json b/webview-ui/src/i18n/locales/tr/settings.json index 257cafd6ec..0ab8ca6e38 100644 --- a/webview-ui/src/i18n/locales/tr/settings.json +++ b/webview-ui/src/i18n/locales/tr/settings.json @@ -1278,7 +1278,15 @@ "noCopilot": "Copilot kotası yok", "noKey": "API anahtarı eksik veya geçersiz", "unsupported": "Özel temel URL — kontrol edilmedi", - "error": "Yüklenemedi" + "error": "Yüklenemedi", + "window": { + "weekly": "Haftalık", + "daily": "Günlük", + "monthly": "Aylık", + "unlimited": "Sınırsız", + "hours": "{{n}} saat", + "days": "{{n}} gün" + } }, "byModel": "Modele göre", "notRecorded": "Kaydedilmedi", diff --git a/webview-ui/src/i18n/locales/vi/settings.json b/webview-ui/src/i18n/locales/vi/settings.json index 55df86904e..a93b0ea60c 100644 --- a/webview-ui/src/i18n/locales/vi/settings.json +++ b/webview-ui/src/i18n/locales/vi/settings.json @@ -1278,7 +1278,15 @@ "noCopilot": "Không có hạn mức Copilot", "noKey": "Thiếu khóa API hoặc không hợp lệ", "unsupported": "URL cơ sở tùy chỉnh — không kiểm tra", - "error": "Không thể tải" + "error": "Không thể tải", + "window": { + "weekly": "Hằng tuần", + "daily": "Hằng ngày", + "monthly": "Hằng tháng", + "unlimited": "Không giới hạn", + "hours": "{{n}} giờ", + "days": "{{n}} ngày" + } }, "byModel": "Theo mô hình", "notRecorded": "Chưa ghi nhận", diff --git a/webview-ui/src/i18n/locales/zh-CN/settings.json b/webview-ui/src/i18n/locales/zh-CN/settings.json index 81cc7bd614..bcbf165d7e 100644 --- a/webview-ui/src/i18n/locales/zh-CN/settings.json +++ b/webview-ui/src/i18n/locales/zh-CN/settings.json @@ -1278,7 +1278,15 @@ "noCopilot": "无 Copilot 配额", "noKey": "API 密钥缺失或无效", "unsupported": "自定义基础 URL — 未检查", - "error": "无法加载" + "error": "无法加载", + "window": { + "weekly": "每周", + "daily": "每日", + "monthly": "每月", + "unlimited": "无限制", + "hours": "{{n}} 小时", + "days": "{{n}} 天" + } }, "byModel": "按模型", "notRecorded": "未记录", diff --git a/webview-ui/src/i18n/locales/zh-TW/settings.json b/webview-ui/src/i18n/locales/zh-TW/settings.json index 75b4d2aba6..5f70bdd4ba 100644 --- a/webview-ui/src/i18n/locales/zh-TW/settings.json +++ b/webview-ui/src/i18n/locales/zh-TW/settings.json @@ -1278,7 +1278,15 @@ "noCopilot": "無 Copilot 配額", "noKey": "API 金鑰遺失或無效", "unsupported": "自訂基底 URL — 未檢查", - "error": "無法載入" + "error": "無法載入", + "window": { + "weekly": "每週", + "daily": "每日", + "monthly": "每月", + "unlimited": "無限制", + "hours": "{{n}} 小時", + "days": "{{n}} 天" + } }, "byModel": "依模型", "notRecorded": "未記錄", From 361be13ea3efe077aaa7378a3149714f45f93a76 Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Thu, 29 Oct 2026 17:30:49 -0700 Subject: [PATCH 19/27] test(usage): cover the day-count window name --- .../language-models/__tests__/providerQuotas.spec.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/services/language-models/__tests__/providerQuotas.spec.ts b/src/services/language-models/__tests__/providerQuotas.spec.ts index 4d11ea9871..0731cec4a5 100644 --- a/src/services/language-models/__tests__/providerQuotas.spec.ts +++ b/src/services/language-models/__tests__/providerQuotas.spec.ts @@ -1078,6 +1078,14 @@ describe("window names", () => { }) }) + it("names a rolling window of whole days by its count", async () => { + const q = await quotaFrom( + { apiProvider: providerIdentifiers.zai, zaiApiKey: "sk" }, + { code: 200, data: { limits: [{ type: "TOKENS_LIMIT", unit: 6, number: 2, percentage: 10 }] } }, + ) + expect(q).toMatchObject({ ok: true, windows: [{ valueLabel: "14-day", name: { key: "days", count: 14 } }] }) + }) + it("names a Copilot unlimited plan, and leaves a figure without a name", async () => { const copilot = await import("../copilotQuota") vi.mocked(copilot.getGitHubCopilotQuota).mockResolvedValueOnce({ From dc9d128b1e94278d751744eac73cbb17e46931c5 Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Fri, 30 Oct 2026 22:36:28 -0700 Subject: [PATCH 20/27] fix(usage): record the serving handler per request; OpenRouter total spend; active profile first; fail when no profile loads; name progress bars --- .../__tests__/usageByModel.spec.ts | 39 ++++++++++- src/core/task-persistence/usageByModel.ts | 29 ++++++++ src/core/task/Task.ts | 19 +++++- ...bviewMessageHandler.providerQuotas.spec.ts | 38 +++++++++++ src/core/webview/webviewMessageHandler.ts | 6 +- .../__tests__/providerQuotas.spec.ts | 52 +++++++++++++++ .../language-models/providerQuotas.ts | 35 +++++++--- .../components/settings/ProviderLimits.tsx | 66 ++++++++++--------- .../__tests__/ProviderLimits.spec.tsx | 28 ++++++++ 9 files changed, 269 insertions(+), 43 deletions(-) diff --git a/src/core/task-persistence/__tests__/usageByModel.spec.ts b/src/core/task-persistence/__tests__/usageByModel.spec.ts index a30d074d36..fffe76a963 100644 --- a/src/core/task-persistence/__tests__/usageByModel.spec.ts +++ b/src/core/task-persistence/__tests__/usageByModel.spec.ts @@ -2,7 +2,7 @@ import { describe, expect, it } from "vitest" import { providerIdentifiers, type ClineMessage } from "@roo-code/types" -import { resolveRecordedModelId, summarizeUsageByModel } from "../usageByModel" +import { bindRequestToHandler, resolveRecordedModelId, summarizeUsageByModel } from "../usageByModel" const req = (data: Record, ts = 1): ClineMessage => ({ ts, @@ -131,3 +131,40 @@ describe("resolveRecordedModelId", () => { expect(resolveRecordedModelId(42, "claude-sonnet-5")).toBe("claude-sonnet-5") }) }) + +describe("bindRequestToHandler", () => { + const placeholder = JSON.stringify({ apiProtocol: "openai", apiProvider: "old-provider", modelId: "old-model" }) + + it("records the provider of the handler that serves the request, over the one the placeholder was written with", () => { + const bound = JSON.parse( + bindRequestToHandler(placeholder, { + apiProvider: "new-provider", + configuredModelId: "new-model", + servedModelId: "served-model", + }), + ) + expect(bound).toEqual({ apiProtocol: "openai", apiProvider: "new-provider", modelId: "new-model" }) + }) + + it("records the model the handler reports when the profile names none", () => { + const bound = JSON.parse( + bindRequestToHandler(placeholder, { + apiProvider: "p", + configuredModelId: undefined, + servedModelId: "served-model", + }), + ) + expect(bound.modelId).toBe("served-model") + }) + + it.each([[undefined], [""], ["not json"]])("starts from nothing when the placeholder is %j", (text) => { + const bound = JSON.parse( + bindRequestToHandler(text as string | undefined, { + apiProvider: "p", + configuredModelId: "m", + servedModelId: undefined, + }), + ) + expect(bound).toEqual({ apiProvider: "p", modelId: "m" }) + }) +}) diff --git a/src/core/task-persistence/usageByModel.ts b/src/core/task-persistence/usageByModel.ts index ab2fd72324..cc33a4c0e4 100644 --- a/src/core/task-persistence/usageByModel.ts +++ b/src/core/task-persistence/usageByModel.ts @@ -59,3 +59,32 @@ export function summarizeUsageByModel(messages: ClineMessage[]): UsageByModelEnt export function resolveRecordedModelId(recorded: unknown, served: string | undefined): string | undefined { return typeof recorded === "string" && recorded.length > 0 ? recorded : served } + +/** + * Binds a request's placeholder `api_req_started` to the handler that serves it. The placeholder is written before + * the rate-limit wait and the environment details, and a profile switch in that window replaces the handler, so the + * provider and model written then can differ from the handler whose tokens and cost are recorded at the end. Called + * once the serving handler is known. The configured model is kept when the profile names one; otherwise the model the + * handler reports is recorded. + */ +export function bindRequestToHandler( + text: string | undefined, + handler: { + apiProvider: string | undefined + configuredModelId: string | undefined + servedModelId: string | undefined + }, +): string { + let existing: Record = {} + try { + existing = JSON.parse(text || "{}") + } catch { + // An unreadable placeholder is replaced, not kept. + } + + return JSON.stringify({ + ...existing, + apiProvider: handler.apiProvider, + modelId: resolveRecordedModelId(handler.configuredModelId, handler.servedModelId), + }) +} diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index 6f8ab64f1e..8bfb537889 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -124,7 +124,7 @@ import { saveTaskMessages, taskMetadata, } from "../task-persistence" -import { resolveRecordedModelId } from "../task-persistence/usageByModel" +import { bindRequestToHandler, resolveRecordedModelId } from "../task-persistence/usageByModel" import { getEnvironmentDetails } from "../environment/getEnvironmentDetails" import { checkContextWindowExceededError } from "../context/context-management/context-error-handling" import { @@ -4035,6 +4035,9 @@ export class Task extends EventEmitter implements TaskLike { let inputTokens = 0 let outputTokens = 0 let totalCost: number | undefined + // The model that served this request, captured when it was chosen: a later request replaces + // `cachedStreamingModel` while this one's usage is still being collected in the background. + let servedModelId: string | undefined // We can't use `api_req_finished` anymore since it's a unique case // where it could come after a streaming message (i.e. in the middle @@ -4077,7 +4080,7 @@ export class Task extends EventEmitter implements TaskLike { this.clineMessages[lastApiReqIndex].text = JSON.stringify({ ...existingData, - modelId: resolveRecordedModelId(existingData.modelId, this.cachedStreamingModel?.id), + modelId: resolveRecordedModelId(existingData.modelId, servedModelId), tokensIn: costResult.totalInputTokens, tokensOut: costResult.totalOutputTokens, cacheWrites: cacheWriteTokens, @@ -4147,6 +4150,18 @@ export class Task extends EventEmitter implements TaskLike { // This is especially important for tools and background usage collection this.cachedStreamingModel = this.api.getModel() const streamModelInfo = this.cachedStreamingModel.info + servedModelId = this.cachedStreamingModel.id + + // The handler that serves this request is known now. The placeholder was written before the waits + // above, so bring its provider and model in line with this handler. + this.clineMessages[lastApiReqIndex].text = bindRequestToHandler( + this.clineMessages[lastApiReqIndex].text, + { + apiProvider: this.apiConfiguration.apiProvider, + configuredModelId: getModelId(this.apiConfiguration), + servedModelId, + }, + ) // Yields only if the first chunk is successful, otherwise will // allow the user to retry the request (most likely due to rate diff --git a/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts b/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts index 8c3ac1421b..f4423755dc 100644 --- a/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts +++ b/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts @@ -23,6 +23,7 @@ const makeProvider = (overrides: Record = {}) => ({ postMessageToWebview: vi.fn(), log: vi.fn(), + contextProxy: { getValue: vi.fn((key: string) => (key === "currentApiConfigName" ? "default" : undefined)) }, providerSettingsManager: { listConfig: vi.fn(async () => [{ id: "a" }, { id: "b" }]), getProfile: vi.fn(async ({ id }: { id: string }) => ({ @@ -48,6 +49,43 @@ describe("webviewMessageHandler – requestProviderQuotas", () => { ]) }) + it("puts the active profile first, so the quota row is the account the requests use", async () => { + const provider = makeProvider({ + contextProxy: { getValue: vi.fn(() => "personal") }, + providerSettingsManager: { + listConfig: vi.fn(async () => [ + { id: "a", name: "work" }, + { id: "b", name: "personal" }, + ]), + getProfile: vi.fn(async ({ id }: { id: string }) => ({ + apiProvider: providerIdentifiers.openrouter, + openRouterApiKey: `key-${id}`, + })), + }, + }) + await webviewMessageHandler(provider, { type: "requestProviderQuotas" }) + + expect( + quotas.getProviderQuotas.mock.calls[0][0].map((p: { openRouterApiKey: string }) => p.openRouterApiKey), + ).toEqual(["key-b", "key-a"]) + }) + + it("reports a failure, not an empty list, when no saved profile can be read", async () => { + const provider = makeProvider({ + providerSettingsManager: { + listConfig: vi.fn(async () => [{ id: "a" }]), + getProfile: vi.fn(async () => { + throw new Error("corrupt secret storage") + }), + }, + }) + await webviewMessageHandler(provider, { type: "requestProviderQuotas" }) + + expect(provider.postMessageToWebview).toHaveBeenCalledWith( + expect.objectContaining({ type: "providerQuotas", providerQuotas: [], providerQuotasFailed: true }), + ) + }) + it("loads every saved profile and posts the formatted quotas back", async () => { const provider = makeProvider() await webviewMessageHandler(provider, { type: "requestProviderQuotas" }) diff --git a/src/core/webview/webviewMessageHandler.ts b/src/core/webview/webviewMessageHandler.ts index 247c7f3951..cbbf66b8cf 100644 --- a/src/core/webview/webviewMessageHandler.ts +++ b/src/core/webview/webviewMessageHandler.ts @@ -1599,7 +1599,11 @@ export const webviewMessageHandler = async ( try { const { getProviderQuotas, loadProfiles } = await import("../../services/language-models/providerQuotas") - const profiles = await loadProfiles(provider.providerSettingsManager, controller.signal) + const profiles = await loadProfiles( + provider.providerSettingsManager, + controller.signal, + provider.contextProxy.getValue("currentApiConfigName"), + ) providerQuotas = await getProviderQuotas(profiles, { force: message.bool === true, signal: controller.signal, diff --git a/src/services/language-models/__tests__/providerQuotas.spec.ts b/src/services/language-models/__tests__/providerQuotas.spec.ts index 0731cec4a5..72279aee03 100644 --- a/src/services/language-models/__tests__/providerQuotas.spec.ts +++ b/src/services/language-models/__tests__/providerQuotas.spec.ts @@ -46,6 +46,18 @@ describe("parseOpenRouterKey", () => { ]) }) + it("labels the all-time usage as total spend, never as this month's", () => { + expect(parseOpenRouterKey({ data: { limit: null, usage: 42 } })).toEqual([ + { id: "spend", valueLabel: "$42.00 spent in total" }, + ]) + }) + + it("prefers the monthly figure when both are reported", () => { + expect(parseOpenRouterKey({ data: { usage: 42, usage_monthly: 3.2 } })).toEqual([ + { id: "spend", valueLabel: "$3.20 spent this month" }, + ]) + }) + it("returns undefined without data", () => { expect(parseOpenRouterKey({})).toBeUndefined() expect(parseOpenRouterKey({ data: {} })).toBeUndefined() @@ -1129,6 +1141,46 @@ describe("loadProfiles", () => { expect(await loadProfiles(source)).toEqual([{ apiProvider: "x" }]) }) + it("fails when none of the saved profiles can be read, instead of reporting no providers", async () => { + const source = { + listConfig: vi.fn(async () => [{ id: "a" }, { id: "b" }]), + getProfile: vi.fn(async () => { + throw new Error("corrupt secret storage") + }), + } + await expect(loadProfiles(source)).rejects.toThrow("None of the saved profiles could be read") + }) + + it("returns an empty list when there are no saved profiles", async () => { + const source = { listConfig: vi.fn(async () => []), getProfile: vi.fn() } + expect(await loadProfiles(source)).toEqual([]) + }) + + it("puts the active profile first, so a provider with several profiles shows the account in use", async () => { + const source = { + listConfig: vi.fn(async () => [ + { id: "a", name: "work" }, + { id: "b", name: "personal" }, + { id: "c", name: "spare" }, + ]), + getProfile: vi.fn(async ({ id }: { id: string }) => ({ apiProvider: "x", id }) as never), + } + expect((await loadProfiles(source, undefined, "personal")).map((p) => (p as { id: string }).id)).toEqual([ + "b", + "a", + "c", + ]) + expect((await loadProfiles(source)).map((p) => (p as { id: string }).id)).toEqual(["a", "b", "c"]) + }) + + it("keeps the list order when the active profile is not among the saved ones", async () => { + const source = { + listConfig: vi.fn(async () => [{ id: "a", name: "work" }]), + getProfile: vi.fn(async () => ({ apiProvider: "x" }) as never), + } + expect(await loadProfiles(source, undefined, "gone")).toEqual([{ apiProvider: "x" }]) + }) + it("stops waiting for the profile list when the signal aborts, and reads no profile", async () => { const source = { listConfig: vi.fn(() => new Promise(() => {})), getProfile: vi.fn() } const controller = new AbortController() diff --git a/src/services/language-models/providerQuotas.ts b/src/services/language-models/providerQuotas.ts index 342445d17e..62de799359 100644 --- a/src/services/language-models/providerQuotas.ts +++ b/src/services/language-models/providerQuotas.ts @@ -50,8 +50,12 @@ export function parseOpenRouterKey(payload: unknown): ProviderQuotaWindow[] | un ] } - const usage = toNumber(data.usage_monthly) ?? toNumber(data.usage) - return usage === undefined ? undefined : [{ id: "spend", valueLabel: `${formatMoney(usage)} spent this month` }] + const monthly = toNumber(data.usage_monthly) + if (monthly !== undefined) return [{ id: "spend", valueLabel: `${formatMoney(monthly)} spent this month` }] + + // OpenRouter documents `usage` as all-time credit use, so it must not be shown as this month's spend. + const total = toNumber(data.usage) + return total === undefined ? undefined : [{ id: "spend", valueLabel: `${formatMoney(total)} spent in total` }] } /** DeepSeek `GET /user/balance` → prepaid balance (prefers a positive USD balance). */ @@ -564,25 +568,40 @@ async function fetchCopilot(force: boolean, signal?: AbortSignal): Promise + listConfig(): Promise<{ id: string; name?: string }[]> getProfile(params: { id: string }): Promise } /** * Loads full profiles (including API keys) host-side. A profile that fails to - * load is skipped rather than failing the whole refresh. Keys never leave the - * extension host: only formatted quota rows are posted to the webview. + * load is skipped rather than failing the whole refresh, but if none of the saved + * profiles can be read that is a failure, not "no connected providers". The active + * profile (`activeName`) comes first, so a provider that has several profiles is + * shown with the account the requests use. Keys never leave the extension host: + * only formatted quota rows are posted to the webview. */ -export async function loadProfiles(source: ProfileSource, signal?: AbortSignal): Promise { +export async function loadProfiles( + source: ProfileSource, + signal?: AbortSignal, + activeName?: string, +): Promise { // Stops waiting as soon as `signal` aborts. The reads themselves cannot be cancelled, but the profile reads // are not started once the list wait has been abandoned. - const entries = await until(source.listConfig(), signal, () => {}) + const listed = await until(source.listConfig(), signal, () => {}) + const entries = activeName + ? [ + ...listed.filter((entry) => entry.name === activeName), + ...listed.filter((entry) => entry.name !== activeName), + ] + : listed const profiles = await until( Promise.all(entries.map((entry) => source.getProfile({ id: entry.id }).catch(() => undefined))), signal, () => {}, ) - return profiles.filter((p): p is ProviderSettings => !!p) + const loaded = profiles.filter((p): p is ProviderSettings => !!p) + if (entries.length > 0 && loaded.length === 0) throw new Error("None of the saved profiles could be read") + return loaded } // Successful results only, per provider and URL set. A missing key, a sign-out or a diff --git a/webview-ui/src/components/settings/ProviderLimits.tsx b/webview-ui/src/components/settings/ProviderLimits.tsx index 31b4df6459..e392e6b465 100644 --- a/webview-ui/src/components/settings/ProviderLimits.tsx +++ b/webview-ui/src/components/settings/ProviderLimits.tsx @@ -167,40 +167,44 @@ const QuotaRow = ({
{quota.ok && - quota.windows.map((w) => ( -
-
- - {w.name - ? t(`settings:usage.limits.window.${w.name.key}`, { n: w.name.count }) - : w.valueLabel} - + quota.windows.map((w) => { + const windowText = w.name + ? t(`settings:usage.limits.window.${w.name.key}`, { n: w.name.count }) + : w.valueLabel + + return ( +
+
+ {windowText} + {w.usedPercent !== undefined && ( + + {Math.round(w.usedPercent)}% + + )} +
{w.usedPercent !== undefined && ( - - {Math.round(w.usedPercent)}% - +
+
+
+ )} + {w.resetAt && ( +
+ {t("settings:usage.limits.resets", { date: formatReset(w.resetAt) })} +
)}
- {w.usedPercent !== undefined && ( -
-
-
- )} - {w.resetAt && ( -
- {t("settings:usage.limits.resets", { date: formatReset(w.resetAt) })} -
- )} -
- ))} + ) + })}
) } diff --git a/webview-ui/src/components/settings/__tests__/ProviderLimits.spec.tsx b/webview-ui/src/components/settings/__tests__/ProviderLimits.spec.tsx index 1466ea1811..74f46d1a37 100644 --- a/webview-ui/src/components/settings/__tests__/ProviderLimits.spec.tsx +++ b/webview-ui/src/components/settings/__tests__/ProviderLimits.spec.tsx @@ -53,6 +53,34 @@ describe("ProviderLimits", () => { }) }) + describe("progress bars", () => { + it("names each bar with its provider and window, so two windows of one provider can be told apart", () => { + render() + respond([ + { + providerId: providerIdentifiers.zai, + ok: true, + fetchedAt: 1, + windows: [ + { id: "a", valueLabel: "5-hour", usedPercent: 40, name: { key: "hours", count: 5 } }, + { id: "b", valueLabel: "Weekly", usedPercent: 10, name: { key: "weekly" } }, + { id: "c", valueLabel: "$4.25 left" }, + ], + }, + ]) + + const bars = screen.getAllByRole("progressbar") + expect(bars).toHaveLength(2) + const labels = bars.map((bar) => bar.getAttribute("aria-label")) + expect(labels[0]).toContain("settings:usage.limits.window.hours 5") + expect(labels[1]).toContain("settings:usage.limits.window.weekly") + expect(new Set(labels).size).toBe(2) + const shown = screen.getByTestId(`provider-limit-${providerIdentifiers.zai}`).querySelector(".font-medium") + expect(shown?.textContent).toBeTruthy() + for (const label of labels) expect(label).toContain(shown?.textContent as string) + }) + }) + describe("window names", () => { const quota = (windows: Extract["windows"]): ProviderQuota => ({ providerId: providerIdentifiers.zai, From f616c703862dd6a2ff83b5be3938ef543934cc12 Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Sat, 31 Oct 2026 09:25:14 -0700 Subject: [PATCH 21/27] fix(lint): hold the served model id in an object, not a let that is assigned once --- src/core/task/Task.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index 8bfb537889..a2149d0003 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -4037,7 +4037,7 @@ export class Task extends EventEmitter implements TaskLike { let totalCost: number | undefined // The model that served this request, captured when it was chosen: a later request replaces // `cachedStreamingModel` while this one's usage is still being collected in the background. - let servedModelId: string | undefined + const served: { modelId?: string } = {} // We can't use `api_req_finished` anymore since it's a unique case // where it could come after a streaming message (i.e. in the middle @@ -4080,7 +4080,7 @@ export class Task extends EventEmitter implements TaskLike { this.clineMessages[lastApiReqIndex].text = JSON.stringify({ ...existingData, - modelId: resolveRecordedModelId(existingData.modelId, servedModelId), + modelId: resolveRecordedModelId(existingData.modelId, served.modelId), tokensIn: costResult.totalInputTokens, tokensOut: costResult.totalOutputTokens, cacheWrites: cacheWriteTokens, @@ -4150,7 +4150,7 @@ export class Task extends EventEmitter implements TaskLike { // This is especially important for tools and background usage collection this.cachedStreamingModel = this.api.getModel() const streamModelInfo = this.cachedStreamingModel.info - servedModelId = this.cachedStreamingModel.id + served.modelId = this.cachedStreamingModel.id // The handler that serves this request is known now. The placeholder was written before the waits // above, so bring its provider and model in line with this handler. @@ -4159,7 +4159,7 @@ export class Task extends EventEmitter implements TaskLike { { apiProvider: this.apiConfiguration.apiProvider, configuredModelId: getModelId(this.apiConfiguration), - servedModelId, + servedModelId: served.modelId, }, ) From 34335c44e0a43bdf13a55ce6f8e82a8eafe1758f Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Sat, 31 Oct 2026 10:42:00 -0700 Subject: [PATCH 22/27] fix(usage): skip non-object stored requests; abort quota requests on dispose; MiniMax 5-hour window only with data --- .../__tests__/usageByModel.spec.ts | 16 ++++++++++ src/core/task-persistence/usageByModel.ts | 3 ++ src/core/webview/ClineProvider.ts | 5 +++- .../webview/__tests__/ClineProvider.spec.ts | 11 +++++++ ...bviewMessageHandler.providerQuotas.spec.ts | 30 ++++++++++++++++++- src/core/webview/webviewMessageHandler.ts | 6 ++++ .../__tests__/providerQuotas.spec.ts | 14 ++++++++- .../language-models/providerQuotas.ts | 18 +++++------ 8 files changed, 91 insertions(+), 12 deletions(-) diff --git a/src/core/task-persistence/__tests__/usageByModel.spec.ts b/src/core/task-persistence/__tests__/usageByModel.spec.ts index fffe76a963..a75b761d9f 100644 --- a/src/core/task-persistence/__tests__/usageByModel.spec.ts +++ b/src/core/task-persistence/__tests__/usageByModel.spec.ts @@ -112,6 +112,22 @@ describe("summarizeUsageByModel", () => { }) }) +describe("summarizeUsageByModel with stored text that is not a request object", () => { + const msg = (text: string) => + ({ ts: 1, type: "say", say: "api_req_started", text }) as unknown as Parameters< + typeof summarizeUsageByModel + >[0][number] + + it.each(["null", "42", '"text"', "true", "[]"])("skips %s and keeps reading the other messages", (text) => { + const summary = summarizeUsageByModel([ + msg(text), + msg(JSON.stringify({ apiProvider: "p", modelId: "m", tokensIn: 5, tokensOut: 2, cost: 0.5 })), + ]) + + expect(summary).toEqual([{ apiProvider: "p", modelId: "m", requests: 1, tokensIn: 5, tokensOut: 2, cost: 0.5 }]) + }) +}) + describe("resolveRecordedModelId", () => { it("keeps a model that was recorded when the request started", () => { expect(resolveRecordedModelId("gpt-5", "gpt-5-mini")).toBe("gpt-5") diff --git a/src/core/task-persistence/usageByModel.ts b/src/core/task-persistence/usageByModel.ts index cc33a4c0e4..a747e806ab 100644 --- a/src/core/task-persistence/usageByModel.ts +++ b/src/core/task-persistence/usageByModel.ts @@ -25,6 +25,9 @@ export function summarizeUsageByModel(messages: ClineMessage[]): UsageByModelEnt continue } + // Valid JSON that is not an object ("null", a number, a string) has no fields to read. + if (typeof parsed !== "object" || parsed === null) continue + // A placeholder (request not finished) has no token counts yet. if (typeof parsed.tokensIn !== "number" && typeof parsed.tokensOut !== "number") continue diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 39c6184d92..38fda05bec 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -116,7 +116,7 @@ import { ProviderSettingsManager } from "../config/ProviderSettingsManager" import { CustomModesManager } from "../config/CustomModesManager" import { PendingActionSettlementError, Task } from "../task/Task" -import { webviewMessageHandler } from "./webviewMessageHandler" +import { abortProviderQuotaRequests, webviewMessageHandler } from "./webviewMessageHandler" import type { WebviewFocusTracker } from "./WebviewFocusTracker" import type { ClineMessage, TodoItem } from "@roo-code/types" import { @@ -869,6 +869,9 @@ export class ClineProvider // hold the event loop after the provider is torn down. this.taskScheduler.cancelQueued() + // Provider-limit requests still running would keep fetching for a view that is gone. + abortProviderQuotaRequests(this) + // Clear all tasks from the stack. The first pop goes through evictCurrentTask() // so an active delegated child is marked interrupted before the extension shuts down, // rather than being left persisted as "active" across the reload. diff --git a/src/core/webview/__tests__/ClineProvider.spec.ts b/src/core/webview/__tests__/ClineProvider.spec.ts index 779313d385..4397b869c7 100644 --- a/src/core/webview/__tests__/ClineProvider.spec.ts +++ b/src/core/webview/__tests__/ClineProvider.spec.ts @@ -2119,6 +2119,17 @@ describe("ClineProvider", () => { expect(state.allowedReadFiles).toEqual([]) }) + test("dispose stops the provider-limit requests still in flight for this provider", async () => { + const abort = vi.spyOn(await import("../webviewMessageHandler"), "abortProviderQuotaRequests") + try { + await provider.dispose() + + expect(abort).toHaveBeenCalledWith(provider) + } finally { + abort.mockRestore() + } + }) + test("getState returns the saved allowed write files", async () => { await provider.contextProxy.setValue("allowedWriteFiles", ["notes.md"]) diff --git a/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts b/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts index f4423755dc..06afd18fd7 100644 --- a/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts +++ b/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts @@ -14,7 +14,7 @@ vi.mock("../../../services/language-models/providerQuotas", async (importOrigina getProviderQuotas: quotas.getProviderQuotas, })) -import { webviewMessageHandler } from "../webviewMessageHandler" +import { abortProviderQuotaRequests, webviewMessageHandler } from "../webviewMessageHandler" import type { ClineProvider } from "../ClineProvider" const SECRET = "sk-super-secret" @@ -86,6 +86,34 @@ describe("webviewMessageHandler – requestProviderQuotas", () => { ) }) + describe("when the provider is disposed", () => { + it("aborts the requests in flight, and posts nothing for them", async () => { + let signal: AbortSignal | undefined + quotas.getProviderQuotas.mockImplementation( + (_profiles: unknown, options: { signal: AbortSignal }) => + new Promise((_resolve, reject) => { + signal = options.signal + options.signal.addEventListener("abort", () => + reject(new DOMException("Aborted", "AbortError")), + ) + }), + ) + const provider = makeProvider() + const handling = webviewMessageHandler(provider, { type: "requestProviderQuotas", requestId: "q1" }) + await vi.waitFor(() => expect(signal).toBeDefined()) + + abortProviderQuotaRequests(provider) + await handling + + expect(signal?.aborted).toBe(true) + expect(provider.postMessageToWebview).not.toHaveBeenCalled() + }) + + it("does nothing for a provider with no requests in flight", () => { + expect(() => abortProviderQuotaRequests(makeProvider())).not.toThrow() + }) + }) + it("loads every saved profile and posts the formatted quotas back", async () => { const provider = makeProvider() await webviewMessageHandler(provider, { type: "requestProviderQuotas" }) diff --git a/src/core/webview/webviewMessageHandler.ts b/src/core/webview/webviewMessageHandler.ts index cbbf66b8cf..322955f28f 100644 --- a/src/core/webview/webviewMessageHandler.ts +++ b/src/core/webview/webviewMessageHandler.ts @@ -137,6 +137,12 @@ const handlerFor = (apiConfiguration: ProviderSettings, provider: RouterName): A * request id alone would let one webview cancel, or overwrite, another's request. */ const pendingProviderQuotaRequests = new WeakMap>() +/** Stops the provider-limit requests still in flight for a provider, e.g. when it is disposed. */ +export const abortProviderQuotaRequests = (provider: ClineProvider) => { + for (const controller of pendingProviderQuotaRequests.get(provider)?.values() ?? []) controller.abort() + pendingProviderQuotaRequests.delete(provider) +} + const pendingQuotaFor = (provider: ClineProvider) => { let pending = pendingProviderQuotaRequests.get(provider) if (!pending) pendingProviderQuotaRequests.set(provider, (pending = new Map())) diff --git a/src/services/language-models/__tests__/providerQuotas.spec.ts b/src/services/language-models/__tests__/providerQuotas.spec.ts index 72279aee03..4adab5fb3d 100644 --- a/src/services/language-models/__tests__/providerQuotas.spec.ts +++ b/src/services/language-models/__tests__/providerQuotas.spec.ts @@ -350,12 +350,24 @@ describe("parser edge cases", () => { expect(byPercent?.[0].usedPercent).toBe(25) const first = parseMiniMaxRemains({ model_remains: [{ model_name: "only" }] }) - expect(first).toEqual([{ id: "5h", valueLabel: "5-hour", usedPercent: undefined, resetAt: undefined }]) + // A row with neither a figure nor a reset time has nothing to show. + expect(first).toBeUndefined() expect( parseMiniMaxRemains({ model_remains: [{ current_interval_remaining_percent: 5 }] })?.[0].usedPercent, ).toBe(95) }) + it("MiniMax: shows the 5-hour window with only a reset time, and with only a figure", () => { + expect( + parseMiniMaxRemains({ model_remains: [{ model_name: "MiniMax-M2", end_time: 1_800_000_000_000 }] }), + ).toEqual([{ id: "5h", valueLabel: "5-hour", usedPercent: undefined, resetAt: 1_800_000_000_000 }]) + expect( + parseMiniMaxRemains({ + model_remains: [{ model_name: "MiniMax-M2", current_interval_remaining_percent: 70 }], + }), + ).toEqual([{ id: "5h", valueLabel: "5-hour", usedPercent: 30, resetAt: undefined }]) + }) + it("MiniMax: skips a weekly window with no data and clamps an out-of-range percent", () => { const [interval, weekly] = parseMiniMaxRemains({ model_remains: [{ model_name: "MiniMax-M2", current_interval_remaining_percent: 150 }], diff --git a/src/services/language-models/providerQuotas.ts b/src/services/language-models/providerQuotas.ts index 62de799359..b9282a94ad 100644 --- a/src/services/language-models/providerQuotas.ts +++ b/src/services/language-models/providerQuotas.ts @@ -235,14 +235,14 @@ export function parseMiniMaxRemains(payload: unknown, isTokenPlan = true): Provi return clampPercent((used / total) * 100) } - const windows: ProviderQuotaWindow[] = [ - { - id: "5h", - valueLabel: "5-hour", - usedPercent: usedPercentOf("interval"), - resetAt: toEpochMs(model.end_time), - }, - ] + const windows: ProviderQuotaWindow[] = [] + + // A window with neither a figure nor a reset time would show a label with no value. + const intervalPercent = usedPercentOf("interval") + const intervalReset = toEpochMs(model.end_time) + if (intervalPercent !== undefined || intervalReset !== undefined) { + windows.push({ id: "5h", valueLabel: "5-hour", usedPercent: intervalPercent, resetAt: intervalReset }) + } // Status 3 = the window does not apply to this plan tier. const weeklyApplies = toNumber(model.current_weekly_status) !== 3 @@ -255,7 +255,7 @@ export function parseMiniMaxRemains(payload: unknown, isTokenPlan = true): Provi resetAt: toEpochMs(model.weekly_end_time), }) } - return windows + return windows.length ? windows : undefined } /** NanoGPT `GET /api/subscription/v1/usage` → daily / weekly / monthly allowance. */ From a7b0743e264acbfb472243423ba9fd8891a1d780 Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Sat, 31 Oct 2026 10:44:25 -0700 Subject: [PATCH 23/27] fix(usage): query the active profile's own credentials; deadline for profile reads; look again when the webview regains focus --- ...bviewMessageHandler.providerQuotas.spec.ts | 22 +++ src/core/webview/webviewMessageHandler.ts | 5 +- .../__tests__/providerQuotas.spec.ts | 139 ++++++++++++++++++ .../language-models/providerQuotas.ts | 79 +++++++--- .../components/settings/ProviderLimits.tsx | 4 + .../__tests__/ProviderLimits.spec.tsx | 29 ++++ 6 files changed, 258 insertions(+), 20 deletions(-) diff --git a/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts b/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts index 06afd18fd7..78777b269c 100644 --- a/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts +++ b/src/core/webview/__tests__/webviewMessageHandler.providerQuotas.spec.ts @@ -70,6 +70,28 @@ describe("webviewMessageHandler – requestProviderQuotas", () => { ).toEqual(["key-b", "key-a"]) }) + it("passes the active profile's id on, so its own credentials are the ones queried", async () => { + const provider = makeProvider({ + contextProxy: { getValue: vi.fn(() => "personal") }, + providerSettingsManager: { + listConfig: vi.fn(async () => [ + { id: "a", name: "work" }, + { id: "b", name: "personal" }, + ]), + getProfile: vi.fn(async ({ id }: { id: string }) => ({ + apiProvider: providerIdentifiers.openrouter, + id, + })), + }, + }) + await webviewMessageHandler(provider, { type: "requestProviderQuotas" }) + + expect(quotas.getProviderQuotas).toHaveBeenCalledWith( + expect.any(Array), + expect.objectContaining({ activeProfileId: "b" }), + ) + }) + it("reports a failure, not an empty list, when no saved profile can be read", async () => { const provider = makeProvider({ providerSettingsManager: { diff --git a/src/core/webview/webviewMessageHandler.ts b/src/core/webview/webviewMessageHandler.ts index 322955f28f..1d96b8af8d 100644 --- a/src/core/webview/webviewMessageHandler.ts +++ b/src/core/webview/webviewMessageHandler.ts @@ -1603,9 +1603,9 @@ export const webviewMessageHandler = async ( let providerQuotas: ProviderQuota[] = [] let providerQuotasFailed = false try { - const { getProviderQuotas, loadProfiles } = + const { getProviderQuotas, loadProfilesWithActive } = await import("../../services/language-models/providerQuotas") - const profiles = await loadProfiles( + const { profiles, activeProfileId } = await loadProfilesWithActive( provider.providerSettingsManager, controller.signal, provider.contextProxy.getValue("currentApiConfigName"), @@ -1613,6 +1613,7 @@ export const webviewMessageHandler = async ( providerQuotas = await getProviderQuotas(profiles, { force: message.bool === true, signal: controller.signal, + activeProfileId, }) } catch (error) { providerQuotasFailed = true diff --git a/src/services/language-models/__tests__/providerQuotas.spec.ts b/src/services/language-models/__tests__/providerQuotas.spec.ts index 4adab5fb3d..7974c9d54a 100644 --- a/src/services/language-models/__tests__/providerQuotas.spec.ts +++ b/src/services/language-models/__tests__/providerQuotas.spec.ts @@ -21,6 +21,7 @@ vi.mock("../copilotQuota", () => ({ import { getProviderQuotas, loadProfiles, + loadProfilesWithActive, parseDeepSeekBalance, parseKimiCodeUsage, parseMiniMaxRemains, @@ -1069,6 +1070,86 @@ describe("getProviderQuotas", () => { }) }) +describe("the active profile decides which account is queried", () => { + beforeEach(() => resetProviderQuotaCache()) + + const okSpend = () => vi.fn(async () => new Response(JSON.stringify({ data: { limit: 10, limit_remaining: 5 } }))) + + it("reports no key for an active profile without one, instead of using a sibling's key", async () => { + const fetchSpy = okSpend() + const [q] = await getProviderQuotas( + [ + { id: "active", apiProvider: providerIdentifiers.openrouter } as never, + { id: "other", apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "sibling-key" } as never, + ], + { activeProfileId: "active" }, + fetchSpy, + ) + + expect(q).toMatchObject({ ok: false, reason: "noKey" }) + expect(fetchSpy).not.toHaveBeenCalled() + }) + + it("reports a custom gateway as unsupported when the active profile uses one, not a sibling on the default host", async () => { + const fetchSpy = okSpend() + const [q] = await getProviderQuotas( + [ + { + id: "active", + apiProvider: providerIdentifiers.deepseek, + deepSeekApiKey: "k1", + deepSeekBaseUrl: "https://gateway.example/v1", + } as never, + { id: "other", apiProvider: providerIdentifiers.deepseek, deepSeekApiKey: "k2" } as never, + ], + { activeProfileId: "active" }, + fetchSpy, + ) + + expect(q).toMatchObject({ ok: false, reason: "unsupported" }) + expect(fetchSpy).not.toHaveBeenCalled() + }) + + it("queries with the active profile's key when a sibling also has one", async () => { + const fetchSpy = okSpend() + await getProviderQuotas( + [ + { id: "other", apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "sibling-key" } as never, + { id: "active", apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "active-key" } as never, + ], + { activeProfileId: "active" }, + fetchSpy, + ) + + expect(fetchSpy).toHaveBeenCalledWith( + "https://openrouter.ai/api/v1/key", + expect.objectContaining({ headers: expect.objectContaining({ Authorization: "Bearer active-key" }) }), + ) + }) + + it.each([ + ["there is no active profile", undefined], + ["the active profile is for another provider", "elsewhere"], + ["the active profile is not among the loaded ones", "gone"], + ])("keeps the usual choice of profile when %s", async (_name, activeProfileId) => { + const fetchSpy = okSpend() + await getProviderQuotas( + [ + { id: "elsewhere", apiProvider: providerIdentifiers.anthropic } as never, + { id: "keyless", apiProvider: providerIdentifiers.openrouter } as never, + { id: "keyed", apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "the-key" } as never, + ], + { activeProfileId }, + fetchSpy, + ) + + expect(fetchSpy).toHaveBeenCalledWith( + "https://openrouter.ai/api/v1/key", + expect.objectContaining({ headers: expect.objectContaining({ Authorization: "Bearer the-key" }) }), + ) + }) +}) + describe("window names", () => { beforeEach(() => resetProviderQuotaCache()) @@ -1193,6 +1274,64 @@ describe("loadProfiles", () => { expect(await loadProfiles(source, undefined, "gone")).toEqual([{ apiProvider: "x" }]) }) + it("returns the id of the active profile with the profiles", async () => { + const source = { + listConfig: vi.fn(async () => [ + { id: "a", name: "work" }, + { id: "b", name: "personal" }, + ]), + getProfile: vi.fn(async ({ id }: { id: string }) => ({ apiProvider: "x", id }) as never), + } + + expect(await loadProfilesWithActive(source, undefined, "personal")).toMatchObject({ activeProfileId: "b" }) + expect((await loadProfilesWithActive(source, undefined, "gone")).activeProfileId).toBeUndefined() + expect((await loadProfilesWithActive(source)).activeProfileId).toBeUndefined() + }) + + describe("a profile read that never settles", () => { + afterEach(() => vi.useRealTimers()) + + it("is skipped after the deadline, so the profiles that were read still produce a response", async () => { + vi.useFakeTimers() + const source = { + listConfig: vi.fn(async () => [{ id: "ok" }, { id: "stuck" }]), + getProfile: vi.fn(({ id }: { id: string }) => + id === "stuck" ? new Promise(() => {}) : Promise.resolve({ apiProvider: "x" } as never), + ), + } + + const loading = loadProfiles(source) + await vi.advanceTimersByTimeAsync(10_000) + + expect(await loading).toEqual([{ apiProvider: "x" }]) + }) + + it("fails when every read is stuck, instead of waiting for ever", async () => { + vi.useFakeTimers() + const source = { + listConfig: vi.fn(async () => [{ id: "a" }, { id: "b" }]), + getProfile: vi.fn(() => new Promise(() => {})), + } + + const loading = loadProfiles(source) + const settled = expect(loading).rejects.toThrow("None of the saved profiles could be read") + await vi.advanceTimersByTimeAsync(10_000) + + await settled + }) + + it("does not wait for the deadline when the reads finish", async () => { + vi.useFakeTimers() + const source = { + listConfig: vi.fn(async () => [{ id: "a" }]), + getProfile: vi.fn(async () => ({ apiProvider: "x" }) as never), + } + + expect(await loadProfiles(source)).toEqual([{ apiProvider: "x" }]) + expect(vi.getTimerCount()).toBe(0) + }) + }) + it("stops waiting for the profile list when the signal aborts, and reads no profile", async () => { const source = { listConfig: vi.fn(() => new Promise(() => {})), getProfile: vi.fn() } const controller = new AbortController() diff --git a/src/services/language-models/providerQuotas.ts b/src/services/language-models/providerQuotas.ts index b9282a94ad..052f9c9359 100644 --- a/src/services/language-models/providerQuotas.ts +++ b/src/services/language-models/providerQuotas.ts @@ -3,6 +3,7 @@ import { type ProviderQuota, type ProviderQuotaWindow, type ProviderSettings, + type ProviderSettingsWithId, } from "@roo-code/types" import { getGitHubCopilotQuota } from "./copilotQuota" @@ -485,7 +486,20 @@ type KeyedCredentials = ReturnType * one pointed at a custom gateway, which is only a fallback (reported as * unsupported when nothing better exists). */ -function pickCredentials(provider: KeyedProvider, profiles: ProviderSettings[]): KeyedCredentials | undefined { +function pickCredentials( + provider: KeyedProvider, + profiles: ProviderSettings[], + activeProfileId?: string, +): KeyedCredentials | undefined { + // The active profile of this provider is the account the requests use: take its credentials as they are, so a + // keyless one is reported as no key and a custom gateway as unsupported, not replaced by a sibling profile. + const active = activeProfileId + ? (profiles as ProviderSettingsWithId[]).find( + (p) => p.id === activeProfileId && p.apiProvider === provider.providerId, + ) + : undefined + if (active) return provider.credentials(active) + const withKey = profiles .filter((p) => p.apiProvider === provider.providerId) .map(provider.credentials) @@ -572,19 +586,37 @@ export interface ProfileSource { getProfile(params: { id: string }): Promise } +/** How long one profile read may take. A read that never settles is skipped, so the others still produce a response. */ +const PROFILE_READ_TIMEOUT_MS = 10_000 + +function readProfile(source: ProfileSource, id: string): Promise { + return new Promise((resolve) => { + const timer = setTimeout(() => resolve(undefined), PROFILE_READ_TIMEOUT_MS) + source.getProfile({ id }).then( + (profile) => { + clearTimeout(timer) + resolve(profile) + }, + () => { + clearTimeout(timer) + resolve(undefined) + }, + ) + }) +} + /** - * Loads full profiles (including API keys) host-side. A profile that fails to - * load is skipped rather than failing the whole refresh, but if none of the saved - * profiles can be read that is a failure, not "no connected providers". The active - * profile (`activeName`) comes first, so a provider that has several profiles is - * shown with the account the requests use. Keys never leave the extension host: - * only formatted quota rows are posted to the webview. + * Loads full profiles (including API keys) host-side. A profile that fails to load, or takes too long, is skipped + * rather than failing the whole refresh, but if none of the saved profiles can be read that is a failure, not "no + * connected providers". The active profile (`activeName`) comes first, and its id is returned so that its own + * credentials are the ones queried for its provider. Keys never leave the extension host: only formatted quota rows + * are posted to the webview. */ -export async function loadProfiles( +export async function loadProfilesWithActive( source: ProfileSource, signal?: AbortSignal, activeName?: string, -): Promise { +): Promise<{ profiles: ProviderSettings[]; activeProfileId?: string }> { // Stops waiting as soon as `signal` aborts. The reads themselves cannot be cancelled, but the profile reads // are not started once the list wait has been abandoned. const listed = await until(source.listConfig(), signal, () => {}) @@ -594,14 +626,20 @@ export async function loadProfiles( ...listed.filter((entry) => entry.name !== activeName), ] : listed - const profiles = await until( - Promise.all(entries.map((entry) => source.getProfile({ id: entry.id }).catch(() => undefined))), - signal, - () => {}, - ) + const profiles = await until(Promise.all(entries.map((entry) => readProfile(source, entry.id))), signal, () => {}) const loaded = profiles.filter((p): p is ProviderSettings => !!p) if (entries.length > 0 && loaded.length === 0) throw new Error("None of the saved profiles could be read") - return loaded + + const activeEntry = activeName ? listed.find((entry) => entry.name === activeName) : undefined + return { profiles: loaded, activeProfileId: activeEntry?.id } +} + +export async function loadProfiles( + source: ProfileSource, + signal?: AbortSignal, + activeName?: string, +): Promise { + return (await loadProfilesWithActive(source, signal, activeName)).profiles } // Successful results only, per provider and URL set. A missing key, a sign-out or a @@ -643,8 +681,9 @@ function quotaForKeyedProvider( force: boolean, fetchImpl: Fetch, signal?: AbortSignal, + activeProfileId?: string, ): Promise { - const creds = pickCredentials(provider, profiles) + const creds = pickCredentials(provider, profiles, activeProfileId) const skipped = unqueryable(provider, creds) if (skipped) return Promise.resolve(skipped) @@ -701,7 +740,11 @@ function quotaForKeyedProvider( */ export async function getProviderQuotas( profiles: ProviderSettings[], - { force = false, signal }: { force?: boolean; signal?: AbortSignal } = {}, + { + force = false, + signal, + activeProfileId, + }: { force?: boolean; signal?: AbortSignal; activeProfileId?: string } = {}, fetchImpl: Fetch = fetch, ): Promise { const connected = new Set(profiles.map((p) => p.apiProvider).filter(Boolean) as string[]) @@ -710,7 +753,7 @@ export async function getProviderQuotas( if (connected.has(providerIdentifiers.githubCopilot)) tasks.push(fetchCopilot(force, signal)) for (const provider of KEYED_PROVIDERS) { if (connected.has(provider.providerId)) { - tasks.push(quotaForKeyedProvider(provider, profiles, force, fetchImpl, signal)) + tasks.push(quotaForKeyedProvider(provider, profiles, force, fetchImpl, signal, activeProfileId)) } } diff --git a/webview-ui/src/components/settings/ProviderLimits.tsx b/webview-ui/src/components/settings/ProviderLimits.tsx index e392e6b465..43254ab495 100644 --- a/webview-ui/src/components/settings/ProviderLimits.tsx +++ b/webview-ui/src/components/settings/ProviderLimits.tsx @@ -66,9 +66,13 @@ export const ProviderLimits = () => { setLoading(false) } window.addEventListener("message", onMessage) + // A profile saved in another webview does not reach this one, so look again when it regains focus. + const onFocus = () => request(false) + window.addEventListener("focus", onFocus) request(false) return () => { window.removeEventListener("message", onMessage) + window.removeEventListener("focus", onFocus) // Tell the host nobody is waiting any more so it can stop the profile load and any fetches. cancelLatest() } diff --git a/webview-ui/src/components/settings/__tests__/ProviderLimits.spec.tsx b/webview-ui/src/components/settings/__tests__/ProviderLimits.spec.tsx index 74f46d1a37..5b7157687f 100644 --- a/webview-ui/src/components/settings/__tests__/ProviderLimits.spec.tsx +++ b/webview-ui/src/components/settings/__tests__/ProviderLimits.spec.tsx @@ -53,6 +53,35 @@ describe("ProviderLimits", () => { }) }) + describe("when the webview regains focus", () => { + const requests = () => post.mock.calls.map((c) => c[0]).filter((m) => m.type === "requestProviderQuotas") + + it("asks again without forcing, so a profile saved elsewhere is picked up", () => { + render() + expect(requests()).toHaveLength(1) + + act(() => { + window.dispatchEvent(new Event("focus")) + }) + + expect(requests()).toHaveLength(2) + expect(requests()[1]).toMatchObject({ bool: false }) + expect(requests()[1].requestId).not.toBe(requests()[0].requestId) + }) + + it("stops listening once the section is gone", () => { + const { unmount } = render() + unmount() + post.mockClear() + + act(() => { + window.dispatchEvent(new Event("focus")) + }) + + expect(requests()).toHaveLength(0) + }) + }) + describe("progress bars", () => { it("names each bar with its provider and window, so two windows of one provider can be told apart", () => { render() From d66e03d7ced4410978329cb757be24251cca1f99 Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Sat, 31 Oct 2026 10:59:24 -0700 Subject: [PATCH 24/27] fix(ci): add the new export to the handler mock; drop the unused loadProfiles export --- .../webview/__tests__/ClineProvider.stale-view.spec.ts | 1 + .../language-models/__tests__/providerQuotas.spec.ts | 5 ++++- src/services/language-models/providerQuotas.ts | 8 -------- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/core/webview/__tests__/ClineProvider.stale-view.spec.ts b/src/core/webview/__tests__/ClineProvider.stale-view.spec.ts index b570ceb4bf..48321acaa1 100644 --- a/src/core/webview/__tests__/ClineProvider.stale-view.spec.ts +++ b/src/core/webview/__tests__/ClineProvider.stale-view.spec.ts @@ -132,6 +132,7 @@ vi.mock("../../../integrations/theme/getTheme", () => ({ vi.mock("../webviewMessageHandler", () => ({ webviewMessageHandler: vi.fn().mockResolvedValue(undefined), + abortProviderQuotaRequests: vi.fn(), })) type ProviderState = Awaited> diff --git a/src/services/language-models/__tests__/providerQuotas.spec.ts b/src/services/language-models/__tests__/providerQuotas.spec.ts index 7974c9d54a..1622f8e63b 100644 --- a/src/services/language-models/__tests__/providerQuotas.spec.ts +++ b/src/services/language-models/__tests__/providerQuotas.spec.ts @@ -20,7 +20,6 @@ vi.mock("../copilotQuota", () => ({ import { getProviderQuotas, - loadProfiles, loadProfilesWithActive, parseDeepSeekBalance, parseKimiCodeUsage, @@ -1207,6 +1206,10 @@ describe("window names", () => { }) }) +/** The profiles only: most of these tests do not look at the active profile's id. */ +const loadProfiles = async (...args: Parameters) => + (await loadProfilesWithActive(...args)).profiles + describe("loadProfiles", () => { it("loads every saved profile through the manager, with keys", async () => { const source = { diff --git a/src/services/language-models/providerQuotas.ts b/src/services/language-models/providerQuotas.ts index 052f9c9359..1eef3e866b 100644 --- a/src/services/language-models/providerQuotas.ts +++ b/src/services/language-models/providerQuotas.ts @@ -634,14 +634,6 @@ export async function loadProfilesWithActive( return { profiles: loaded, activeProfileId: activeEntry?.id } } -export async function loadProfiles( - source: ProfileSource, - signal?: AbortSignal, - activeName?: string, -): Promise { - return (await loadProfilesWithActive(source, signal, activeName)).profiles -} - // Successful results only, per provider and URL set. A missing key, a sign-out or a // transient error is never pinned, so fixing it shows up on the next open instead of // after the TTL. An entry is reused only for the exact key it was fetched with, so From e544e9c65ea28e0e24136c60045778e27fe4e60a Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Sat, 31 Oct 2026 13:09:39 -0700 Subject: [PATCH 25/27] fix(usage): keep another key's cache entry; abort on sidebar dispose; MiniMax-M rows with a percentage; deadline for the profile list --- src/core/webview/ClineProvider.ts | 2 + .../ClineProvider.stale-view.spec.ts | 16 +++++- .../__tests__/providerQuotas.spec.ts | 54 +++++++++++++++++++ .../language-models/providerQuotas.ts | 35 ++++++++++-- 4 files changed, 101 insertions(+), 6 deletions(-) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 38fda05bec..4230f47329 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -1058,6 +1058,8 @@ export class ClineProvider } else { this.log("Clearing webview resources for sidebar view") this.view = undefined + // The view that asked for provider limits is gone: stop fetching them. + abortProviderQuotaRequests(this) this.clearWebviewResources() } }, diff --git a/src/core/webview/__tests__/ClineProvider.stale-view.spec.ts b/src/core/webview/__tests__/ClineProvider.stale-view.spec.ts index 48321acaa1..04c46232bd 100644 --- a/src/core/webview/__tests__/ClineProvider.stale-view.spec.ts +++ b/src/core/webview/__tests__/ClineProvider.stale-view.spec.ts @@ -9,7 +9,7 @@ import type { ExtensionMessage, WebviewMessage } from "@roo-code/types" import { ContextProxy } from "../../config/ContextProxy" import { ClineProvider } from "../ClineProvider" -import { webviewMessageHandler } from "../webviewMessageHandler" +import { abortProviderQuotaRequests, webviewMessageHandler } from "../webviewMessageHandler" // Mock setup vi.mock("fs/promises", () => ({ @@ -415,9 +415,11 @@ describe("ClineProvider - stale view lifecycle", () => { expect(first.postMessage).not.toHaveBeenCalled() expect(second.postMessage).not.toHaveBeenCalled() - // A stale dispose must not clear the current view's listeners. + // A stale dispose must not clear the current view's listeners, nor stop the requests of the current view. + vi.mocked(abortProviderQuotaRequests).mockClear() first.disposed.fire() expect(provider["view"]).toBe(second.view) + expect(abortProviderQuotaRequests).not.toHaveBeenCalled() second.visibility.fire() await flushAsync() expect(second.postMessage).toHaveBeenCalledWith({ type: "action", action: "didBecomeVisible" }) @@ -510,6 +512,16 @@ describe("ClineProvider - stale view lifecycle", () => { expect(ClineProvider.getAllInstances()).toContain(provider) }) + test("disposing the sidebar view stops the provider-limit requests it started", async () => { + const first = createSidebarView() + await provider.resolveWebviewView(first.view) + vi.mocked(abortProviderQuotaRequests).mockClear() + + first.disposed.fire() + + expect(abortProviderQuotaRequests).toHaveBeenCalledWith(provider) + }) + test("the current view keeps dispatching messages, visibility, and theme refreshes", async () => { const first = createSidebarView() await provider.resolveWebviewView(first.view) diff --git a/src/services/language-models/__tests__/providerQuotas.spec.ts b/src/services/language-models/__tests__/providerQuotas.spec.ts index 1622f8e63b..65cbdf4d3c 100644 --- a/src/services/language-models/__tests__/providerQuotas.spec.ts +++ b/src/services/language-models/__tests__/providerQuotas.spec.ts @@ -357,6 +357,16 @@ describe("parser edge cases", () => { ).toBe(95) }) + it("MiniMax: prefers a MiniMax-M row that reports a percentage over a chat row", () => { + const windows = parseMiniMaxRemains({ + model_remains: [ + { model_name: "chat", current_interval_remaining_percent: 10 }, + { model_name: "MiniMax-M2", current_interval_remaining_percent: 80 }, + ], + }) + expect(windows?.[0].usedPercent).toBe(20) // the M row's 80% left, not the chat row's 10% left + }) + it("MiniMax: shows the 5-hour window with only a reset time, and with only a figure", () => { expect( parseMiniMaxRemains({ model_remains: [{ model_name: "MiniMax-M2", end_time: 1_800_000_000_000 }] }), @@ -1058,6 +1068,25 @@ describe("getProviderQuotas", () => { }) }) + it("a failed request for one key does not remove the cached success of another key", async () => { + const ok = () => new Response(JSON.stringify({ data: { limit: 10, limit_remaining: 5 } })) + const fetchSpy = vi.fn(async (_url: RequestInfo | URL, init?: RequestInit) => + String((init?.headers as Record)?.Authorization).includes("sk-two") + ? new Response("", { status: 500 }) + : ok(), + ) + const one = [{ apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "sk-one" } as never] + const two = [{ apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "sk-two" } as never] + + await getProviderQuotas(one, {}, fetchSpy) // cached for sk-one + const [failed] = await getProviderQuotas(two, {}, fetchSpy) // fails for sk-two + expect(failed).toMatchObject({ ok: false }) + const [again] = await getProviderQuotas(one, {}, fetchSpy) + + expect(again).toMatchObject({ ok: true }) + expect(fetchSpy).toHaveBeenCalledTimes(2) // the third call came from the cache + }) + it("caches results for the same set of providers unless forced", async () => { const fetchSpy = vi.fn(async () => new Response(JSON.stringify({ data: { limit: 10, limit_remaining: 5 } }))) const profiles = [{ apiProvider: providerIdentifiers.openrouter, openRouterApiKey: "sk" } as never] @@ -1323,6 +1352,31 @@ describe("loadProfiles", () => { await settled }) + it("fails when the list of saved profiles never arrives, instead of waiting for ever", async () => { + vi.useFakeTimers() + const source = { listConfig: vi.fn(() => new Promise(() => {})), getProfile: vi.fn() } + + const loading = loadProfiles(source) + const settled = expect(loading).rejects.toThrow("Reading the saved profiles timed out") + await vi.advanceTimersByTimeAsync(10_000) + + await settled + expect(source.getProfile).not.toHaveBeenCalled() + }) + + it("passes a failure of the list read on as it is, and clears its timer", async () => { + vi.useFakeTimers() + const source = { + listConfig: vi.fn(async () => { + throw new Error("storage unavailable") + }), + getProfile: vi.fn(), + } + + await expect(loadProfiles(source)).rejects.toThrow("storage unavailable") + expect(vi.getTimerCount()).toBe(0) + }) + it("does not wait for the deadline when the reads finish", async () => { vi.useFakeTimers() const source = { diff --git a/src/services/language-models/providerQuotas.ts b/src/services/language-models/providerQuotas.ts index 1eef3e866b..40994378e5 100644 --- a/src/services/language-models/providerQuotas.ts +++ b/src/services/language-models/providerQuotas.ts @@ -219,7 +219,12 @@ export function parseMiniMaxRemains(payload: unknown, isTokenPlan = true): Provi const rows = remains.map(asRecord).filter((r): r is Record => !!r) const name = (r: Record) => (typeof r.model_name === "string" ? r.model_name : "") const model = - rows.find((r) => /^minimax-m/i.test(name(r)) && (toNumber(r.current_interval_total_count) ?? 0) > 0) ?? + rows.find( + (r) => + /^minimax-m/i.test(name(r)) && + ((toNumber(r.current_interval_total_count) ?? 0) > 0 || + typeof r.current_interval_remaining_percent === "number"), + ) ?? rows.find((r) => ["general", "chat", "text"].includes(name(r).toLowerCase())) ?? rows.find((r) => typeof r.current_interval_remaining_percent === "number") ?? rows[0] @@ -589,6 +594,23 @@ export interface ProfileSource { /** How long one profile read may take. A read that never settles is skipped, so the others still produce a response. */ const PROFILE_READ_TIMEOUT_MS = 10_000 +/** Rejects with `message` if `work` has not settled within `ms`. */ +function withDeadline(work: Promise, ms: number, message: string): Promise { + return new Promise((resolve, reject) => { + const timer = setTimeout(() => reject(new Error(message)), ms) + work.then( + (value) => { + clearTimeout(timer) + resolve(value) + }, + (error: unknown) => { + clearTimeout(timer) + reject(error) + }, + ) + }) +} + function readProfile(source: ProfileSource, id: string): Promise { return new Promise((resolve) => { const timer = setTimeout(() => resolve(undefined), PROFILE_READ_TIMEOUT_MS) @@ -619,7 +641,11 @@ export async function loadProfilesWithActive( ): Promise<{ profiles: ProviderSettings[]; activeProfileId?: string }> { // Stops waiting as soon as `signal` aborts. The reads themselves cannot be cancelled, but the profile reads // are not started once the list wait has been abandoned. - const listed = await until(source.listConfig(), signal, () => {}) + const listed = await until( + withDeadline(source.listConfig(), PROFILE_READ_TIMEOUT_MS, "Reading the saved profiles timed out"), + signal, + () => {}, + ) const entries = activeName ? [ ...listed.filter((entry) => entry.name === activeName), @@ -696,8 +722,9 @@ function quotaForKeyedProvider( if (!controller.signal.aborted) { if (result.ok) { cache.set(key, { at: Date.now(), apiKey, result }) - } else { - // A failed refresh must not leave an older success to be served as if it were current. + } else if (cache.get(key)?.apiKey === apiKey) { + // A failed refresh must not leave an older success of this key to be served as if it were + // current. A success cached for another key is not this request's to remove. cache.delete(key) } } From c27fe1d6031cc27f228047a10db871823a263f2c Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Sat, 31 Oct 2026 15:53:34 -0700 Subject: [PATCH 26/27] fix(usage): inert CSV counters; an explicit usage clear wins over another host's; stop the Copilot scope lookup once cancelled; cover the Usage tab in SettingsView --- .../TaskHistoryStore.realConcurrency.spec.ts | 35 ++++++++++++ .../__tests__/taskStoreConcurrency.spec.ts | 37 ++++++++++++- .../task-persistence/taskStoreConcurrency.ts | 14 ++++- .../__tests__/copilotQuota.spec.ts | 35 ++++++++++++ src/services/language-models/copilotQuota.ts | 7 ++- .../settings/__tests__/SettingsView.spec.tsx | 45 ++++++++++++++++ webview-ui/src/utils/__tests__/usage.spec.ts | 54 +++++++++++++++++++ webview-ui/src/utils/usage.ts | 20 ++++--- 8 files changed, 237 insertions(+), 10 deletions(-) diff --git a/src/core/task-persistence/__tests__/TaskHistoryStore.realConcurrency.spec.ts b/src/core/task-persistence/__tests__/TaskHistoryStore.realConcurrency.spec.ts index 54cc1075d5..92d03faeb3 100644 --- a/src/core/task-persistence/__tests__/TaskHistoryStore.realConcurrency.spec.ts +++ b/src/core/task-persistence/__tests__/TaskHistoryStore.realConcurrency.spec.ts @@ -152,6 +152,41 @@ describe("TaskHistoryStore real cross-host locking", () => { } }) + it("clears a usageByModel that another host wrote, when this host saves the task without one", async () => { + const storagePath = await fs.mkdtemp(path.join(os.tmpdir(), "task-history-usage-clear-other-")) + const storeA = new TaskHistoryStore(storagePath) + const storeB = new TaskHistoryStore(storagePath) + const usageByModel = [ + { + apiProvider: providerIdentifiers.anthropic, + modelId: "m", + requests: 1, + tokensIn: 5, + tokensOut: 5, + cost: 1, + }, + ] + + try { + await storeA.initialize() + await storeA.upsert(item("shared-usage-task")) // A's cache has no usageByModel + await storeB.initialize() + await storeB.upsert({ ...item("shared-usage-task"), usageByModel }) // another host records usage on disk + + // This host saves the task after its messages were replaced: no usage, so none must remain on disk. + await storeA.upsert({ ...item("shared-usage-task"), usageByModel: undefined }) + + await storeA.invalidate("shared-usage-task") + expect(storeA.get("shared-usage-task")?.usageByModel).toBeUndefined() + await storeB.invalidate("shared-usage-task") + expect(storeB.get("shared-usage-task")?.usageByModel).toBeUndefined() + } finally { + storeA.dispose() + storeB.dispose() + await fs.rm(storagePath, { recursive: true, force: true }) + } + }) + it("reports a bounded error when one store never reaches the write barrier", async () => { const storagePath = await fs.mkdtemp(path.join(os.tmpdir(), "task-history-missed-barrier-")) const storeA = new TaskHistoryStore(storagePath) diff --git a/src/core/task-persistence/__tests__/taskStoreConcurrency.spec.ts b/src/core/task-persistence/__tests__/taskStoreConcurrency.spec.ts index 419ba03cb4..b9a173eefa 100644 --- a/src/core/task-persistence/__tests__/taskStoreConcurrency.spec.ts +++ b/src/core/task-persistence/__tests__/taskStoreConcurrency.spec.ts @@ -1,6 +1,6 @@ import type { HistoryItem } from "@roo-code/types" -import { DeltaRejectedError, mergeHistoryDelta } from "../taskStoreConcurrency" +import { computeHistoryDelta, DeltaRejectedError, mergeHistoryDelta } from "../taskStoreConcurrency" function item(status: HistoryItem["status"]): HistoryItem { return { @@ -34,3 +34,38 @@ describe("mergeHistoryDelta", () => { expect(mergeHistoryDelta(disk, incoming, { id: disk.id, status: undefined }).status).toBe("active") }) }) + +describe("computeHistoryDelta", () => { + it("leaves out a field that equals the cached one", () => { + expect(computeHistoryDelta(item("active"), { mode: "code", tokensIn: 0 } as Partial)).toEqual({ + mode: "code", + }) + }) + + it("always carries an explicit undefined usageByModel, even when the cache has none either", () => { + const delta = computeHistoryDelta(item("active"), { usageByModel: undefined, tokensIn: 0 }) + + expect(Object.keys(delta)).toEqual(["usageByModel"]) + }) + + it("still carries a usageByModel that changed, and leaves out one that did not", () => { + const usage = [{ apiProvider: "p", modelId: "m", requests: 1, tokensIn: 1, tokensOut: 1, cost: 0 }] + const cached = { ...item("active"), usageByModel: usage } + + expect(computeHistoryDelta(cached, { usageByModel: usage })).toEqual({}) + expect(computeHistoryDelta(cached, { usageByModel: [] })).toEqual({ usageByModel: [] }) + }) + + it("does not treat an undefined of any other field as a deletion", () => { + expect(computeHistoryDelta(item("active"), { mode: undefined })).toEqual({}) + }) + + it("lets mergeHistoryDelta clear the usage another host wrote", () => { + const onDisk = { ...item("active"), usageByModel: [{ requests: 1 }] } + const delta = computeHistoryDelta(item("active"), { usageByModel: undefined }) + + const merged = mergeHistoryDelta(onDisk, item("active"), delta) + + expect(JSON.parse(JSON.stringify(merged)).usageByModel).toBeUndefined() + }) +}) diff --git a/src/core/task-persistence/taskStoreConcurrency.ts b/src/core/task-persistence/taskStoreConcurrency.ts index 0f747c4cb2..49ce70efc4 100644 --- a/src/core/task-persistence/taskStoreConcurrency.ts +++ b/src/core/task-persistence/taskStoreConcurrency.ts @@ -14,9 +14,21 @@ export class DeltaRejectedError extends Error { } } +/** + * Fields whose `undefined` is a decision, not an absence: "this task has none". The delta normally leaves out a field + * that equals the cached one, but the cache can lack a value that another host wrote to disk, so an unchanged + * `undefined` would leave that stale value in place. For these fields an explicit `undefined` is always part of the + * delta, and `mergeHistoryDelta` applies it under the file lock (the key is dropped when the item is written). + */ +const EXPLICIT_CLEAR_KEYS: ReadonlySet = new Set(["usageByModel"]) + export function computeHistoryDelta(cached: HistoryItem, incoming: Partial): Partial { return Object.fromEntries( - Object.entries(incoming).filter(([key, value]) => !deepEqual(value, (cached as Record)[key])), + Object.entries(incoming).filter( + ([key, value]) => + (value === undefined && EXPLICIT_CLEAR_KEYS.has(key)) || + !deepEqual(value, (cached as Record)[key]), + ), ) as Partial } diff --git a/src/services/language-models/__tests__/copilotQuota.spec.ts b/src/services/language-models/__tests__/copilotQuota.spec.ts index 64b196ff67..38a9ecf15f 100644 --- a/src/services/language-models/__tests__/copilotQuota.spec.ts +++ b/src/services/language-models/__tests__/copilotQuota.spec.ts @@ -287,6 +287,41 @@ describe("getGitHubCopilotQuota", () => { expect(signal()!.aborted).toBe(true) }) + it("does not look up the second scope once the caller has gone, after the first scope found no session", async () => { + const fetchSpy = vi.fn() + const controller = new AbortController() + getSession.mockReset() + // The first scope answers "no session", and the caller goes away just after that answer, before the + // lookup moves on to the second scope. + getSession.mockImplementationOnce(() => ({ + then(resolve: (value: undefined) => void) { + resolve(undefined) + queueMicrotask(() => controller.abort()) + }, + })) + + const result = getGitHubCopilotQuota({ signal: controller.signal }, fetchSpy as never) + + await expect(result).rejects.toMatchObject({ name: "AbortError" }) + await new Promise((resolve) => setTimeout(resolve, 0)) // let the lookup loop run on, if it is going to + expect(getSession).toHaveBeenCalledTimes(1) + expect(fetchSpy).not.toHaveBeenCalled() + }) + + it("rejects a lookup that was cancelled before its session answered, with the cancellation", async () => { + const fetchSpy = vi.fn() + const controller = new AbortController() + getSession.mockReset() + getSession.mockImplementationOnce(() => new Promise(() => {})) // never answers + + const result = getGitHubCopilotQuota({ signal: controller.signal }, fetchSpy as never) + await vi.waitFor(() => expect(getSession).toHaveBeenCalledTimes(1)) + controller.abort() + + await expect(result).rejects.toMatchObject({ name: "AbortError" }) + expect(fetchSpy).not.toHaveBeenCalled() + }) + it("rejects at once with a signal that is already aborted, and makes no request", async () => { const fetchSpy = vi.fn() const controller = new AbortController() diff --git a/src/services/language-models/copilotQuota.ts b/src/services/language-models/copilotQuota.ts index be59d1337b..1194baae6e 100644 --- a/src/services/language-models/copilotQuota.ts +++ b/src/services/language-models/copilotQuota.ts @@ -70,9 +70,10 @@ export function parseCopilotQuota(payload: unknown, now = Date.now()): GitHubCop /** Rejects as soon as `signal` aborts. The pending work cannot be cancelled, but nobody waits for it any more. */ function raceAbort(work: Promise, signal: AbortSignal): Promise { + // The caller has checked that `signal` is not aborted yet (an abort event does not fire again for a signal that + // already is), and nothing can abort it between that check and this call. return new Promise((resolve, reject) => { - // The signal is never aborted before this is called (it combines a fresh controller and a timeout). - const abort = () => reject(new DOMException("Aborted", "AbortError")) + const abort = () => reject(signal.reason) signal.addEventListener("abort", abort, { once: true }) work.then(resolve, reject).finally(() => signal.removeEventListener("abort", abort)) }) @@ -82,6 +83,8 @@ function raceAbort(work: Promise, signal: AbortSignal): Promise { async function getGitHubToken(signal: AbortSignal): Promise { const { authProviderId, authScopeSets } = githubCopilotLanguageModel for (const scopes of authScopeSets) { + // A lookup that has been cancelled is not started: the session request is made before it is raced. + signal.throwIfAborted() const session = await raceAbort( Promise.resolve(vscode.authentication.getSession(authProviderId, scopes, { silent: true })), signal, diff --git a/webview-ui/src/components/settings/__tests__/SettingsView.spec.tsx b/webview-ui/src/components/settings/__tests__/SettingsView.spec.tsx index 0835f255f9..661c4a0d84 100644 --- a/webview-ui/src/components/settings/__tests__/SettingsView.spec.tsx +++ b/webview-ui/src/components/settings/__tests__/SettingsView.spec.tsx @@ -627,6 +627,51 @@ describe("SettingsView - Sound Settings", () => { }) }) +describe("SettingsView - Usage tab", () => { + beforeEach(() => { + vi.clearAllMocks() + }) + + it("renders the Usage tab content when it is the target section", () => { + renderWithExtensionState() + + const content = screen.getByTestId("settings-content") + expect(within(content).getByTestId("usage-empty")).toBeInTheDocument() + }) + + it("lists a Usage tab entry, and shows the usage content when it is clicked", () => { + renderWithExtensionState() + expect(within(screen.getByTestId("settings-content")).queryByTestId("usage-empty")).not.toBeInTheDocument() + + fireEvent.click(screen.getByTestId("tab-usage")) + + expect(within(screen.getByTestId("settings-content")).getByTestId("usage-empty")).toBeInTheDocument() + }) + + it("shows the totals and the filters when there is history", () => { + renderWithExtensionState(, { + state: { + taskHistory: [ + { + id: "t1", + number: 1, + ts: Date.now(), + task: "a task", + tokensIn: 100, + tokensOut: 50, + totalCost: 0.5, + }, + ], + }, + }) + + const content = screen.getByTestId("settings-content") + expect(within(content).getByTestId("usage-stats")).toBeInTheDocument() + expect(within(content).getByTestId("usage-export-csv")).toBeInTheDocument() + expect(within(content).queryByTestId("usage-empty")).not.toBeInTheDocument() + }) +}) + describe("SettingsView - API Configuration", () => { beforeEach(() => { vi.clearAllMocks() diff --git a/webview-ui/src/utils/__tests__/usage.spec.ts b/webview-ui/src/utils/__tests__/usage.spec.ts index 7a8a9cfc43..e0b712bcf6 100644 --- a/webview-ui/src/utils/__tests__/usage.spec.ts +++ b/webview-ui/src/utils/__tests__/usage.spec.ts @@ -493,6 +493,60 @@ describe("usageToCsv formula safety", () => { }) }) +describe("usageToCsv numeric columns", () => { + const numericKeys = ["tokensIn", "tokensOut", "cacheReads", "cacheWrites", "totalCost"] as const + const cells = (overrides: Record) => + usageToCsv([item(overrides as never)], { range: "all", now: NOW }) + .split("\n")[1] + .split(",") + .slice(-5) + + it.each(numericKeys)("exports a formula in %s as 0, so no cell can be evaluated", (key) => { + for (const text of ['=HYPERLINK("http://x")', "+1+1", "-2+3", "@SUM(A1)", "\tcmd", "1;2"]) { + const row = cells({ [key]: text }) + const index = numericKeys.indexOf(key) + expect(row[index]).toBe(key === "totalCost" ? "0.0000" : "0") + } + }) + + it.each([[Number.NaN], [Number.POSITIVE_INFINITY], [Number.NEGATIVE_INFINITY], [-5], [null], [{}]])( + "exports %p as 0", + (value) => { + expect( + cells({ tokensIn: value, tokensOut: value, cacheReads: value, cacheWrites: value, totalCost: value }), + ).toEqual(["0", "0", "0", "0", "0.0000"]) + }, + ) + + it("keeps real counters as they are", () => { + expect(cells({ tokensIn: 10, tokensOut: 20, cacheReads: 3, cacheWrites: 4, totalCost: 1.5 })).toEqual([ + "10", + "20", + "3", + "4", + "1.5000", + ]) + }) + + it("leaves the date empty for a time that cannot be written, instead of throwing", () => { + for (const ts of [Number.NaN, Number.POSITIVE_INFINITY, 8.64e15 + 1]) { + const csv = usageToCsv([item({ task: "t", ts })], { range: "all", now: NOW }) + expect(csv.split("\n")[1].startsWith(',"t"')).toBe(true) + } + }) + + it("every cell of a row is digits, a quoted text with no leading trigger, or an ISO date", () => { + const hostile = '=cmd|" /C calc"!A0' + const row = usageToCsv( + [item({ task: hostile, mode: hostile, tokensIn: hostile as never, totalCost: hostile as never })], + { range: "all", now: NOW }, + ).split("\n")[1] + + expect(row).not.toMatch(/(^|,)[=+\-@\t\r]/) + expect(row).not.toMatch(/,"[=+\-@\t\r]/) + }) +}) + describe("usageToCsv", () => { it("sorts oldest first and leaves provider, model and counters blank or zero when nothing was recorded", () => { const csv = usageToCsv( diff --git a/webview-ui/src/utils/usage.ts b/webview-ui/src/utils/usage.ts index c87cde7825..c5156e6a54 100644 --- a/webview-ui/src/utils/usage.ts +++ b/webview-ui/src/utils/usage.ts @@ -325,6 +325,14 @@ export function usageToCsv(history: HistoryItem[], options: UsageOptions): strin return `"${safe.replace(/"/g, '""').replace(/\r?\n/g, " ")}"` } + // A counter that is not a finite, non-negative number (corrupted history, or text such as "=1+1" that a + // spreadsheet would evaluate) is exported as 0. What is written is then only ever digits, so every cell is inert. + const counter = (value: unknown) => (typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : 0) + const date = (ts: unknown) => + typeof ts === "number" && Number.isFinite(ts) && !Number.isNaN(new Date(ts).getTime()) + ? new Date(ts).toISOString() + : "" + const rows = history .filter( (item) => @@ -334,16 +342,16 @@ export function usageToCsv(history: HistoryItem[], options: UsageOptions): strin .sort((a, b) => a.ts - b.ts) .map((item) => [ - new Date(item.ts).toISOString(), + date(item.ts), escape(item.title || item.task || ""), escape(item.mode || ""), escape(primaryUsage(item)?.apiProvider ?? ""), escape(primaryUsage(item)?.modelId ?? ""), - item.tokensIn || 0, - item.tokensOut || 0, - item.cacheReads || 0, - item.cacheWrites || 0, - (item.totalCost || 0).toFixed(4), + counter(item.tokensIn), + counter(item.tokensOut), + counter(item.cacheReads), + counter(item.cacheWrites), + counter(item.totalCost).toFixed(4), ].join(","), ) From e65ba256fec3acd2368da184956997b26d985ee1 Mon Sep 17 00:00:00 2001 From: Karthick Mahalingam Date: Sat, 31 Oct 2026 16:26:13 -0700 Subject: [PATCH 27/27] fix(usage): one selection for the totals and the CSV; stronger assertions in the usage tests --- .../TaskHistoryStore.realConcurrency.spec.ts | 6 ++++ .../__tests__/taskStoreConcurrency.spec.ts | 14 ++++++++- .../settings/__tests__/SettingsView.spec.tsx | 8 ++++- webview-ui/src/utils/__tests__/usage.spec.ts | 18 +++++++++++ webview-ui/src/utils/usage.ts | 30 +++++++++++-------- 5 files changed, 62 insertions(+), 14 deletions(-) diff --git a/src/core/task-persistence/__tests__/TaskHistoryStore.realConcurrency.spec.ts b/src/core/task-persistence/__tests__/TaskHistoryStore.realConcurrency.spec.ts index 92d03faeb3..03b1bd694c 100644 --- a/src/core/task-persistence/__tests__/TaskHistoryStore.realConcurrency.spec.ts +++ b/src/core/task-persistence/__tests__/TaskHistoryStore.realConcurrency.spec.ts @@ -173,9 +173,15 @@ describe("TaskHistoryStore real cross-host locking", () => { await storeB.initialize() await storeB.upsert({ ...item("shared-usage-task"), usageByModel }) // another host records usage on disk + // The setup really happened: the usage is on disk, and this host's cache does not have it yet. + const file = path.join(storagePath, "tasks", "shared-usage-task", "history_item.json") + expect(JSON.parse(await fs.readFile(file, "utf8")).usageByModel).toEqual(usageByModel) + expect(storeA.get("shared-usage-task")?.usageByModel).toBeUndefined() + // This host saves the task after its messages were replaced: no usage, so none must remain on disk. await storeA.upsert({ ...item("shared-usage-task"), usageByModel: undefined }) + expect(JSON.parse(await fs.readFile(file, "utf8")).usageByModel).toBeUndefined() await storeA.invalidate("shared-usage-task") expect(storeA.get("shared-usage-task")?.usageByModel).toBeUndefined() await storeB.invalidate("shared-usage-task") diff --git a/src/core/task-persistence/__tests__/taskStoreConcurrency.spec.ts b/src/core/task-persistence/__tests__/taskStoreConcurrency.spec.ts index b9a173eefa..7966bb8e63 100644 --- a/src/core/task-persistence/__tests__/taskStoreConcurrency.spec.ts +++ b/src/core/task-persistence/__tests__/taskStoreConcurrency.spec.ts @@ -56,10 +56,22 @@ describe("computeHistoryDelta", () => { expect(computeHistoryDelta(cached, { usageByModel: [] })).toEqual({ usageByModel: [] }) }) - it("does not treat an undefined of any other field as a deletion", () => { + it("omits an undefined other field when the cache has no value for it either", () => { expect(computeHistoryDelta(item("active"), { mode: undefined })).toEqual({}) }) + it("carries an undefined other field as an ordinary change when the cache has a value for it", () => { + const cached = { ...item("active"), mode: "code" } + + expect(computeHistoryDelta(cached, { mode: undefined })).toEqual({ mode: undefined }) + }) + + it("does not keep an undefined other field on every save: only usageByModel is a standing decision", () => { + const delta = computeHistoryDelta(item("active"), { mode: undefined, usageByModel: undefined }) + + expect(Object.keys(delta)).toEqual(["usageByModel"]) + }) + it("lets mergeHistoryDelta clear the usage another host wrote", () => { const onDisk = { ...item("active"), usageByModel: [{ requests: 1 }] } const delta = computeHistoryDelta(item("active"), { usageByModel: undefined }) diff --git a/webview-ui/src/components/settings/__tests__/SettingsView.spec.tsx b/webview-ui/src/components/settings/__tests__/SettingsView.spec.tsx index 661c4a0d84..95bd82e513 100644 --- a/webview-ui/src/components/settings/__tests__/SettingsView.spec.tsx +++ b/webview-ui/src/components/settings/__tests__/SettingsView.spec.tsx @@ -666,7 +666,13 @@ describe("SettingsView - Usage tab", () => { }) const content = screen.getByTestId("settings-content") - expect(within(content).getByTestId("usage-stats")).toBeInTheDocument() + // The totals of the supplied task, not just an element that exists. + const stats = within(content).getByTestId("usage-stats").textContent ?? "" + expect(stats).toContain("$0.50") + expect(stats).toContain("150") // 100 tokens in + 50 out + // The filter controls and the export are there. + expect(within(content).getByTestId("usage-range-7d")).toBeInTheDocument() + expect(within(content).getByTestId("usage-range-all")).toBeInTheDocument() expect(within(content).getByTestId("usage-export-csv")).toBeInTheDocument() expect(within(content).queryByTestId("usage-empty")).not.toBeInTheDocument() }) diff --git a/webview-ui/src/utils/__tests__/usage.spec.ts b/webview-ui/src/utils/__tests__/usage.spec.ts index e0b712bcf6..973068dc34 100644 --- a/webview-ui/src/utils/__tests__/usage.spec.ts +++ b/webview-ui/src/utils/__tests__/usage.spec.ts @@ -493,6 +493,24 @@ describe("usageToCsv formula safety", () => { }) }) +describe("usageToCsv and summarizeUsage count the same tasks", () => { + it("leaves out a task whose time is not a number, in the export as in the totals", () => { + const history = [ + item({ task: "good", ts: NOW, tokensIn: 7, totalCost: 1 }), + item({ task: "no time", ts: null as never, tokensIn: 99, totalCost: 50 }), + item({ task: "text time", ts: "yesterday" as never, tokensIn: 99, totalCost: 50 }), + ] + + const rows = usageToCsv(history, { range: "all", now: NOW }).split("\n").slice(1) + const summary = summarizeUsage(history, { range: "all", now: NOW }) + + expect(rows).toHaveLength(1) + expect(rows[0]).toContain('"good"') + expect(summary.taskCount).toBe(1) + expect(summary.totalCost).toBe(1) + }) +}) + describe("usageToCsv numeric columns", () => { const numericKeys = ["tokensIn", "tokensOut", "cacheReads", "cacheWrites", "totalCost"] as const const cells = (overrides: Record) => diff --git a/webview-ui/src/utils/usage.ts b/webview-ui/src/utils/usage.ts index c5156e6a54..2ee55755b0 100644 --- a/webview-ui/src/utils/usage.ts +++ b/webview-ui/src/utils/usage.ts @@ -176,17 +176,29 @@ function addTo( const byCostDesc = (a: UsageBucket, b: UsageBucket) => b.cost - a.cost || b.tokens - a.tokens -export function summarizeUsage(history: HistoryItem[], options: UsageOptions): UsageSummary { - const now = options.now ?? Date.now() - const start = rangeStart(options.range, now) - const topTaskLimit = options.topTaskLimit ?? 5 +/** + * The tasks the Usage tab counts for these options: the same selection for the totals and for the CSV, so an export + * never has a row the displayed totals leave out. An item whose time is not a number (a corrupted task file) is + * dropped. + */ +function itemsInScope(history: HistoryItem[], options: UsageOptions): HistoryItem[] { + const start = rangeStart(options.range, options.now ?? Date.now()) - const items = history.filter( + return history.filter( (item) => typeof item.ts === "number" && (start === undefined || item.ts >= start) && (!options.workspace || item.workspace === options.workspace), ) +} + +export function summarizeUsage(history: HistoryItem[], options: UsageOptions): UsageSummary { + const now = options.now ?? Date.now() + const start = rangeStart(options.range, now) + const topTaskLimit = options.topTaskLimit ?? 5 + + // The same `now` as above, so the range and the daily series agree on the day. + const items = itemsInScope(history, { ...options, now }) const providers = new Map() const models = new Map() @@ -304,7 +316,6 @@ export function modelIdFromKey(key: string): string | undefined { /** Serialises the filtered usage rows as CSV (one row per task). */ export function usageToCsv(history: HistoryItem[], options: UsageOptions): string { - const start = rangeStart(options.range, options.now ?? Date.now()) const header = [ "date", "task", @@ -333,12 +344,7 @@ export function usageToCsv(history: HistoryItem[], options: UsageOptions): strin ? new Date(ts).toISOString() : "" - const rows = history - .filter( - (item) => - (start === undefined || item.ts >= start) && - (!options.workspace || item.workspace === options.workspace), - ) + const rows = itemsInScope(history, options) .sort((a, b) => a.ts - b.ts) .map((item) => [

oj6Vwi(TlV@r!u(j#m|Hd%9+OC`Vp>f?C{@ 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 delta 51897 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 Q!&k6w-PBYrRkR5EKjZd)$p8QV diff --git a/webview-ui/src/components/settings/__tests__/__screenshots__/usage-settings-high-contrast.png b/webview-ui/src/components/settings/__tests__/__screenshots__/usage-settings-high-contrast.png index 99a8f61e5174f05eb7abdca967be41f41e981dc1..5ef985f3883f18105c0fc88909942976754a77f6 100644 GIT binary patch delta 59714 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 dHRH%4Ywc&NQZQ&Ac{eEcWy#dLb^dZq~n{M zbKZaa&lpbuZtlI-nsZ*Yc10M*moSVNKBV%|DD*HAh2X#iQE{j+W%JPo?o}IWY~YxGNgPQhnCMb zpE#|(KUrGyZ$zwVTTu{+JO-^tfnmL`=VtJkWclg#>d%howH=au?P{Uls_uvW$V4c8 zLDp^eqt1Gt;e1_r9LB(?P(iZ}m3U6?+4ZYt&)PRe&Rjsdi*5!+jxUCFiR@w-ML|x;Ksy|{6B8j?ErBtf$6ds=@INrtXQT#NP zV0?_-E%-MnqC|q@5rBq?cb#kAkc?R=!uIzUJ@`p9IqROKz2zUw29?ft-&`wF8_ZD= zc3VV|Fv?%9gJG+FGFMl+#O}+h=&p+>8(hZLF=Z0*jT>aVPfKs!vdz)VI3E0{#{J~m zNRe4c9hY1n#&zx|>TkJz=RN$i*qi2Yyl3-}PQrB_DYodb?25DKier6+OQHgJUO&DJ3G+r6|ILrTd zW$3$pIC7mkkypR`#p;mXzu!8r(BkRFOO;j#s}3kA_#a8_el?O-Nmc z>P@}1I#F}r)NrPBL@aw+=rC5UC36%MaU?e7ySw}&`}Amcs?I0r`O##Z&(|m4Z~N@q zM@Xa{Y))kfG_p|%nct})-LvRPgf*Vg4a}HBh-hy=AFp&#OXRVUDYqLY8b&q4LcrQt zJ)#b$br93_jpm=1D&7VQZkrk8PTrS6WNk{&i|z!@-Y-&KI}8KxH207P&SVTZYVTKFkVt2p&jD(u z%x?I;d8^03J2^3@N&C^_1=)+!SA@}|%NmJF+(=Z%^-zP#F> zDQ$K=GnGbcWpkk?NuO`m9}XAEML3cnctaj1gbbtEZ+}g%);S1=bS)0HbZm+^??JZG zN7c8=9?v%?X$il&IWFpfN!ybFnEPb(W)f3Fa- zGwj>y4U2(URPTEvM4u8l?*wOlsW&ZTQ}n_rq%L;NalBHnYh$)8JpSsvA&V!H-CT{d)HoKExYjq8kZJFNPffWNsD&Nr^6{x{ogsV}GeV13N0>bytN%i*-_*-|OK8V=(m z9?gY5E1Y)Q;rwS%$z89Q$5Fm7?;sdte#@S zaiaR)>hNa2>;=s&+iUpyHAGUBVvYte+)v^6hhO6~trHq8u{zi#Y@_$vdoWS`LM@5U z0h1l?8ppt90|C8^FI3b}54ouQNJ0IvZEGlLZ<^S}dd1XWuEt5T#w6^UWp64{SNOEb zbs>&b%@Q;93SADd%;7sYksGYIWGv950<+%Y%0K@4q|8_C6&4|?SuNwQT~Ou8T(qqB zHLPN}HtM$F2BO0WkE!hnzmt7-&GckZhtz*WF?`ReIUanlA1Q3A6L`KnpqzuaaO3DL zHS@r4J%C!RFwFc@X7@=e3(5Ri<2-}b6m2~Lo$FpSon8R}<5qhl^?4mKcU=NGKMkSx zUtao>ENJG+SYp**?yC%k=KOGuSXKwq`HNGkmh9OtGC7Tbi*I&NRZq+9sn|7XemQK< zwh3GHmFmC`e}PxE8~UbKYE9ZF0?pl|Iq3b?r!0T(o%yb0M9}Q~{A3gQnJjWnb5ZYe zu#qm|Hme~IF9v&Igq;0@cDI4u{O$Kwoz1_$zd~2B3V}nw^k!|M<_7N_CC(Hvr%Z{I z!|gd{!XmSdeevIL$b8R_meO0Gi;P@+R7=9U!DmqK>m@Y-rHLHQgg|HaN=N_lELWWh z=}W2mxAL=Njs3v~MQD-&{5c)J%N@oj%zFH9zxW$84_!1;zp0CuQeYZ(`)~-V{=+LA ziuXjAr3M9~rA7q=P-*;+KF8p`A*2?S@;?=)_D-j?tEw0)cgXI8H5E8HWYhe&Hd-QR z+B&T+#Ygd~%SJ%7*r323RxuhmqU19W@3Vpf+Jlz|Z8waZWd$2JwR5J)4s{ESn_%6Y zBeU;CFMfdmqg`tKApZ|~>TJ{&S9s1VA@Tz3?j#T6ZVUg>C>WQDE)9X{V%d6*ymxZ!jM--=Ay`+4T$+w#ppxV;m(M?#h;-8^m9 zzs@oVB+q!ZEpd)%#PFJpf(WRih6eU?)9m?hCsjU>i3*` z+wa^0U~cAKFt73~b;f1`G&p?d-t)VNn~T}&GjCE?+u-Bd9vcx@DUU^IGW5+|(KhQ2 z5IXryKU07CINFKrCl21sw3IIIYj#L&Mryr;D}wt_g!AL4cDK-z=JMqp=Biiu9u*(3 zv4yn~NnAadxM8ldzdqJ6!8}Rw5%qP2pyf58r03Q&RKkPxPCjLZ0h&;sh3>b!NkTiZ z3Oq*j>1rjlbS%+5EHs0B_JQmSnj;IWh*}~`Vj(>pg#jtgwUDh9Kd}*v?S5_ zw`Q#q!_}~~eu40>Z1Tx0bRDU}RzxrO3~NI%U8aQP5)v&!r22zw^HXaAvfgD4-a)=U zEh}!NW?rThqa}D@cJHNPQGzTcEd zij8quweQ4vEj;s~+-b_uwpv!1jz--13ZrE}W%G}slw6v(OGE-pGv0LzlP8YJ7Q20R zus83^Dt1a-cnhpXWKSg@-%MR(YjqWGeoM7bX~x7sj9$@MTW~$2&CPS_jyzHB*jkEV zV@Xry=zA|hv9S+p8$OGC52n%)GQN;rnA1+-l7v=aVoC$}Vt&^bgnFW%C0k(J91E_3 zMw*q^_-a**eaMIYd^z5lQP_+($&9(}&h=WdC3x-=j^#el8C1a!eBQ!`j}OIz8hyyeOYbS- zE(FTek%~uCc(6bDrd#LzuX&zNzdS-2C85ukq&kaP)l^6JWHkC;194o3=2~aRnM*^~ zxB?xSJie)Fcc8L;!Okw?sGG0s(5e}6{? zv#j)oP1Jh*M108k1b`M;l1G#;+`N6imtfGwF`;u#l2P2CL|=6N4ds>CKU|N$BrLF$ zcWqs{LUKh#QSMQyM5BRlGs81UyCELQtm$(Gy?|H0WaTgwR9|Ccg|qDpM+~0UQYXq1 z&KREa-%JYsr|IW;zY%lzk|eoU|6C4eI>Fl6%AQ`_NBmFLD^L`={OH*nzG4ThuB^Jr zECLIqxgn2l6le}eIu4qQXa~yn)6k+eu-e^zc&XovQg=Dnm>@Oq7JA6-zwxH85rykT ze4N~&^W?r3))(_BT{Wc8F9@5QO?_H7=V-t>+hfDoU@#bk6H8-Wi1JsyDfEo$2d4g! z7g2)m9`fU!0kfo4g6$FUvkb{Q&9oACI1T?w66ngN%VZ3=zVO^6S5Q~!`S2&gxA)zc z7Nw+F$2d8@uI2`Hc~oY^=}eCGO{n=hQ8;ZT@@Pg~lr$}NM?VMjN-Qld#Ba6lv~Re? zs|+(aaNwAB>?NIKsvL+}4_wh>5s3@7a{A155Q#{(zsr=4;hNd0I>OK_3F~-ej)^vi zKh7OU$aZa2gF)ov{SOJZ&6*h_h00x6O7;-R*EBvg&!`=l1Mc9@U_1bW1<|tS;*Y;P0)$!Y8&yE-0nAe^fupGzP@ntypE9d{ zxA@!ln?TRgTpvon(8`ioFaur=$jVXF>-_WxaH+5*s-W@ zs~;ck78usqYWCmHR*D4d?jqhN>VJ9&-M&-@sk=Bo0d8$jXe{^lS6)>Nr~;1)3@7}Y z0JWJr(G=+xnHms%I)?qy1KnsZ6od=S6rna>9-aJgPzHb;k~Xpdq@8R)E`V^=>aeON zECaZF^3oih4P+F`$I&~LE^`z-x-l}QGD@K&?+xp`ab^MTS)!6%kd;B!gKkEJ*Qd+b z(aYAMSJIM+G9}y=LE-p7x7P$9v2xg|A3&6G08!_A2`@exxsg(v`0v6>2_yT^8kfh4x)X_+lmfDhmsYht`AmrEH0 zXoRv!Dk5T2e>jU@>N?*U8*v{tR^DWJ;Qhp{Sgd!_@K%*9WY|>Vf-v`6&MY1$@jX*7 z1AL`jywsqZpR1ZFCDB9RHLwhW-#gu^FI~dx`MBD^IHjOza>+-=D!hk%SKgRy`zDi5 zKcbiNG$vBC62MPzZUxxJuU~H88N;}iqKi1-l0H|AqNxI8yx-w_wDW*$iwzjRocWo- zKcG>1{DB>GE%OhQWkI2O3?ycqY>)KTAPZCeOzqbHNHyD8;Y?f$8#gFai&t8DW)cZp+2FIURI0R2+^%@oT&FZss8F7 zh=B_h?6sp{NdL7POMn@gtxIHWLO_t_~B`Z==OA<%4}RW^?kY9L7Y6 ztm+8tb#oDQDmtD-uj8=!&WgH3H36S?qGU{lTkfZaF1y=s==_uiFMSOrS2x)f=K z?NBU*zrcGVDFp+|MucuNST(b8U{!Co5X)B5V>aD7BN|q=(4?$sf2}Or!L-t}02)kS zQDxRakPB`ay@YFP9ZAC>aO0W?z6V@D2v+8%J^6&?NCKiKlQ!< zx?gahgYj?77OQLywsle(zXHaM+$+bpp`In*^h0qzSthXmS+O~;4Waj&j+teTZ+C;& z$+VMz=L_|$u>(tFns~PLr9ZCV9BDZHIRsjRYOU8o3!uX z8@}Qj*Xn*yaF^SZLXj>RNl`&FG2y zpt&eA9UbpV zqUGEP(@y5P=nE>U$sjzyI!KZ9aGX2vQz5|-dq1Ynf!jH*ipVob@MK=^`Hh94%T)rh znx|t$%JrEC3}4JJaB52pu3VrD2oQFb#wZaxf`y1D(z^5n)(eDkki^im5_LjigH z#(}F(|C;_OwJ}%ozc}+a=wu1vms=aRNT9(a3;R1-vL}@P=N zyW=$;1q-Rp)vgO~IwnIE_Qa#*324v)-!Y$E)%yB@(dF56zm%m6ug*{>bNDQE;PCKO zs*f9R2Cc};&FDtFM|nYg-!hd8NSvxuPBBDIm?k;)TUwP-Yo zzdE1SrsvrocY?d0F2^y^=qmkle)i)ZCLF=Vgq7z#ZtBHtnMm%iaJe>qds6Z(j%vW7TpP( z&nPP#TfW~pHsTO+3N${Tcix)l1c6DbRn?CG-033pMlY z4tk`t!}Pm;1)FiI#mz>)c<9kH49Se!he`~eOptnm&XQUG=jd-A_#Oo4HRRV@|tT(E~V5C*+yzii-SrHdIGb(j7i)yloSyndMzf?lDLZC#Gs z;8anEHx$`9ryog%kACYIF{YZgK=DKsn>B#)*TUh|9zg{>;@wTJyU}jOsd#y9uj7&S zoUvKU0Xree#W9QAKA`GdkBomM|24M^U+%Z2_(3 zDN{123x1O~WFea6Ap~T&SLUhhkbi$4bBD&vQOM)42UxFGs0PKqd_Wx^{eS@eCPEM| zE&XEGcD%CL98G#bOB%p;puE{7@zYN>cuXd=a8u~Y$qnFmY`ahCJqdM)zh@}pI(`0+ z`_cso!4WhCpNmnW2oJYp!BFCJ$bwrS!{b2PsT%heUJV6W4u;IXDdfe8f>wX!{=PUp z{GDCn@uvK*;}MM!zQ>=qw_AUnQFjoP29Y$+e53!(|7fHzFZ^wVZ+Jnlq*?Hvdpej+ z{3Cdbt!dNCU)oZ*hRWePZsRDWxZ(03lG*RmJ2Q1IgXYEm`FT^6c()xsgR+7ZR^NENXm zq7fIkbU}ozz;t4P6MRk7;m>oB(|8g&hYZzjSbU_6|OB9q*~uCw#6TjM@2YV5eemHo0Okr$Bh1DKg0!izp%zK;hw zl_5AX6wb4E!zs!P>1ixZ54V}`MJXNwB=0{5)JxOp5KSlDy?AvPQ2`+u{OU!FOIm^x)fW3CsUlj{tgl%$tvN5#BX(D*CT)}IREsYbfE;NU4( zd@}wA6CQ859v2%VQp~_FXDt^|PZs!<_xNjKmJf$^jxvDeLpxFS)g2i6x_m4BV1ex} z^{3rJ?7*?&tMP}4yg6R=6G|I!HayQ)z}8g4mN}=dh-KcfIi5AW!VX;lVUbNe*?Db5 zurDM-;HL4C=OlP%z>ras`T$r?_Er?UK#B)I=(Ra19TmQES>Etepio&KwXFR7BxXO- zC=ZMAFh{vb9(31;aHRh&_b@Dr$J$6NERpL%cQ7HfI{;lETYi6=T`^18wKBnx!urSl zi&n}rM!ubCJO~vFHK9G(ZnJw1Q5es`}+ehB<6mcW~qaZPTJxhrVZ{b%#&;A1x#SqF2OQ*8ngY2Q!dHFpt{4_#i-BAx`R-4cJRc zbmSVnXD0{Q->-fa1+|>TsNPo*)7%?KO#(x!<>S``RA3F>!#JJ|=f|N#2#7k*K}nMY z&~CXUmvgk$LQHBcDq@oo$5$BygeonLg7>NYM0J_dRDBSWX1|Y9A_-F{PHvRsRuJBG zJPnhp?3LdC{zA>X6GG7(>s$bH6TlLFT564seSA_fjdA69B<5a5Fd&q<>|QRSrXs1o zb4r54?a9&9VnpOfWQqlqMe7*wm>0W?y)3!lC#=`KS9wmN26X5_rSnXhnA6jMmjm)! zq4R;dvsT)fKVdQ-cx;SIfE)_^Pk60R$Kg-u3PANlJHuhuUX1C1-un!I^vnY&n-ahR z25tmJ$i}aAE4ofkK9qqe`S!*uJ7UbOAG9chKg{wG+54uCaS}ynLB}Nq#=PtDr6W8s z1zQ|)G~n}u9{zdzfG<8(z*!N+sqN_0lTsMw&_zi6%rl+fQzV0_&4gGf8n%3Nfz_1& z%>86nmgMauxAt24+s{A4=t5%ir+Zl*$09a^7%2*8E(1B&)Gg9az%#l#n1ZWCG;>zxRDKMs0FY@C zn+A;QKgK>)c;|f?l1b8OdUCQeB;fp-PW}T8fW?Y~@oMj_*)xse1yqVK2BmpY0#5r8 z*i^;HX^0v4H^Q&*iH;Aq%{JH#)AAlQH$uf5+B(UHim8S^`5H~kmEOE_T}CFI5zZu~ zQgL;nlbnjnD4kncz}0Qm^;bW|jNX#UV_5kXe2B_QCm={N(CxcgXZhhbjE@FS_8`g6 zhfr2vA$v|N-^+!0W};jf{NI1ZM?4_@-?Y7)xL8OnVRMF%MK`Q9OqD$#)`iGeHB2Y) z_B`W3y#%c@A83YrspKrjgd#L+OSMatO3=<%Z#;U-p@3Oz4;Jw)c z4bFEa`UIOX>c)n+%PbGjVDQX9*}2DkalFcphd?9yrdI;~sWY%$Xjc_!-CMxX5ylLW zd2qX-&)+$DAa2$k0mkc(`~)6@N&#q5Fdo;3zEf+cJv!X!;TJaVoL<5mKxO&uk8aO( zOyENY319TS5cm97%hyz$ zqVqz`_SZ60>J#U-?PfoyDq!iL0&Rj4aCtDj#0b%bfht1(F|CfKk=Ox4uhL1#_Sa_! zer!Ro<>GX=AHE;a0FuWpBrcHt49N=Ur_^GO00J;cKh=3u8DEGLX0gBgQap6#Ck9EH zqm@rt;#AS8G@+kNAOf*ihn+qTBP;|QzZBo&l~4O)eFXmbXMevIjC_~K0{x8?E5@El z4)it6ba6QjQ}a8muCkvUQhJj3ohD=3aozOUv@+ABecVglY$MpDfHA~htc{T3^Z%xB zx(Ze`=pTYN{oveyfS1ZBp0N$$7!_ys@?KuW>u+2$}qbOo!ir2m{2#R6y>t7dWv(hR^QbX&u;Sxw&F)nj$VXHhaW!}oCwHt z1hE1o82ZoSPs2uoQvGi`)=JHBMk{uMG~~R!=peok0fWPVSGVw;7ynZTTC91@0@o7< zdCcZ#uC(*?OU`Y>v_4FB8$6HANex?XIU4A!4>F<=}kD!`^@qb={={v)`;Rz*EV%aP2Rn$Mp z?;1fTecLuX_vh332FJRA zvf{2y-g2p*mmVrG>L=2`UGY3H!fo(9as|A)7CmYAL2oax=fG{2ZyM=_CCo)$k*KxNo)zHFlSh<`{cgqVk3KXvwvN(+-a zxf_d;XAl`#+HAPUOc0BruIc@Z9c;?0a>bG*^g}7l5k?7awNhq)B1ZmYQY*1%4Df$a zuk7J8`Xc2hu4sy$>R>Nj2wT_7R$M;NBx4fNiF&dj-{JkI~FmBgM_YYv0O9!pPJGMn91hT z!~?KRjFqdZ)StL~Nl)u~t@BOyhok}Sj5wvij=+-CD*14PaCjoT}opzMQeL6oycKbPt49FdQ6{FyUOF8@z z!6VJ%*2y1uWKP*>_tPJ;9&$aRj^m+mKW^>bHOa#|xB%==r_r{kD6du388nxfyW;oPQT9Pa=R0q2n->51Hp z=J#8rbCZRf5#Kd%rNiY!`z4-Xy|5G|V|T1V5eD8NJB3X_%?SJb1L~#Q6z4H((S)U# zSlZa&`Jy1pxB{9K?48Hz3t^LH3`+&k5e##{;WxODRE>l|^; zp;g4%;xnR6(~>z35)G}k^u;w8c7DSg`;kJzl>9Eum(9ZM0t#BuOo8l^Df=K4+hEP#mPUaUIGGf!%C~Y^cT+SjB2$6 zY>!QG8Pmh&+{VTD#%XrjJTC)MR0;7W5wyt6>4gN9v^V$xdY-Uwpx;5dWcAE;dRP-; zI1(Em_Sfn_MA8a;i^&B@2#kT50G;-1%nDLBz%{d&?!I~WNwYUuu%&iZ8mv_qilJnz z-H@0Y{-$SU`vfw7KKpB8j^nzO&WtCe2S%UozlXB`z{zT=9`Q>gnO$$&j=CfaAb?K7 zWP=4HXH^w3?Q9ICs1-`>b)&l6bv)J3S2slF0Wi|*2DL;DwRG(f3 z@$Gb}TV*JKHzMsiuY4uxr8)%u+G_P8vzdRkVyU0OfdYHx&J5TzAPI+b5R2tEKvqraT(%9A0jCr^t7$KT35qW4h|4%>IGIT!_9qEqQs7b1%KF#lgoDZ!BOxco zo5XJM7!o%spBTCmMC_0u0w)=0rrO+*)M8+=2~)iWc=Ij|Fg3S+`5H`Smoj_GM!B8@ zPBRJ;znr1|+pxC(JQZriaQ5EGy+R3v#R49qk@gmWRjBc}nA*G}m>GKW7T1Cz?W3`4 zxoSxpkPxKwDy>m{%LNvYa1yFeq2SxK+4V&S5=S8f-JJ3mAT^{NVPG(~&T|VifFnRi z%7kGv3s%N#w+j8kD75o`!$vR~g>Wgf2|-QnjAxHNA0 z-;l#NfesSus)U;!R)?pc5q4GtxKYEwo5RZUIQc!0YS{fsqf;?jJ( z8y<(5OG2ANRIJ$-@STHk+o5W5T5||ABu-sV*X~2TX!O`(0SUW#Nw5-mVulLQ2)AFA z$cIkgtK^xbgz>>kim^fyHt!}yHv5H!+j3Y#)Z$ohA0~afWI*b-ny-^(NqM>UyyZ8& zx(@1>6Tef-d`|D1>)e<2Mcg?66R2ra3?sUC_dH8q>gg>m$cwo@qWqmLv|{Yby>R$Y zh#+BYyed9OoYRb@2GWtJllSN964hFo?x2h)Vm#F%n4SY1hiosdT|naOJmb0*8K*Xj zyIOnhlkZP24bH$zgBqYXRY`8HCghQ8p0CKC*FnAI2HE4bXGwHHQt~f=;+*H=`rV@> zZ3Xjz(ds&VnbK+Merci(nX*U}RfqRj&2{o6bb&XM=eXQL~{B> z1+uQd!bmO>8Avv!PfPOUakh&OCnLBXGyN|zdJ|a}17i@#lrD5j2rlDT0wFsCfDh#c zq}&qn6`&gx8%6?F*8wp}Af|)@QHH`(wf9RHgVi;|ee44Ax z&L@+jt>YGaES_q=1ZNq zbV5jaliK6tHb2W#Xj@w-PF+ZU>l#ErYpeZ5ar z^@m}wafvvNCu1msjv^mI^bA-D=qq5)+k-I+eIFvU;E_!%_Gi&U<-{;5d_X3C(f@5; z8~1SnP-Xk$LmNaQ2R~_DLR)%i?_Veu^^ymmlmxw=DZFq+Y%xk3M_L+n}izQKZ1``+)bKtDX`E6cM~n zixhVXDeu?%d9!v`>6#wVLL8dC)mb< z^*Q63&Jg?sf?qW>dN8FpniOyF8`7xUEe0Z|hKoiE3EzhZ?9b`lY=t14SWpfD`aolj zKL(+885aIJa%0k`#9-7}Kl4_vK*pHLSo8;$FNI}~0Kty?*>jUVUk&SyVPdb> zrC^#W0GaM=S5FnemE~KfkgvrJT&Yl9M9xHzvD)>Dg2@?rd|v|86LVoKVmkHqIVc>K z+XGJ?M!B?;GIz|26m})V>>UDo?EM2&V>bzfRqV4hEthZrPKU@>fz4BCm|F*vG5=uF z#hbln0pLb6>?*MVw+`H4oEK6U+8_U^5sm;SU7XJ;xfAm7;%77w3*)c<++bZq37^c{GnS)3Ql1RQkp+8u#8}{?9 zyx|JMF0&A|`dzqZvR$xM_vSC6iN_e!;)&nzct<-&Jq7R*&OOGCcoXC{GPh2;0cEKV zKT5Qfh~oj&8z1uJq68Tto@4hkP? znXjIbaH7H~i<8}Lu=>SnASV869MWd9co2-ndVqVMY}9P(;!umOL9*h<9yI)ewb9+B zEM#Bi2_#TSH$YUp1P;2$KcLB{$EyVZ@`Ri?!A&=ZL3$~1wbT;k#r;nO0r6m@0YQNL zavUwDIhBK$O@duJ1Mi2_k4B^iP$guC0ajBL{WULz8M5{)D*?wc{V}|IHqHB^u-#d6 zo-^$h%w-T2ABM&OCk_6?D830{aFfRiwo%#{J~Z9TYqS3G0R(|*XcEBLW4)LK;^WyA zTmfZ*U<7!g_XKvitr{ZIdThLIKtcgf`$o+L!(-2z-_?ewILKFUDpXGL^qgI;ecX&Z1q|B@}G+=`rya!i}yV||>vrW*-4%N75 z_>Dly)^8=$%9MipVY9t+hcpME=B2_l7wBA&e~;s0B=lPy;w}CCtt~><@Ax?wO^K^t z11eWQ#zbXGUn1+Qns@0(DF3tLGibc#I-t+Le!L07SIv$L#XZo{a8bZ5Vo)dtaDUqdt3D6s|&mmS{5k#^{P_Of&V#%UOF8@yJe=N-%>GKDSI>&W#;!y3 zmsC_cA&wSNPORWqVT8w^!MxWT?ECio@241(=5Oa8E5ImRtWbSI^f$9w_h{`FbsXIr zxQPbcw=ZB+dFPMMqNYr>ZPE2>7^BhZw0cD`$mR96B*m$@_?W9N5ez}_y}-?jVMWuh z?x|3WrmKSsMv$-;r0;plU18Gl`chqkoDh%TGxq=9&ilG+an8D=9 zsfz~)Z`GUn4^AF5%*pB(+^nF#slXX{W&)Q~;F4IeY$C^lS!hJyL|91xY-kHdZe)o% zJU!f+ftCx|B1C)HZx51AxyrH4lj!#@#dW>Ua2%mrz+R|?m=bK?gE$aO;R;>h76haL zP<+=bdF|#1x6^=iRq=Ia-wkhH=>-{pO#bjL2=9k#Q@HPlXw&`8k#R`GLDcBG&J|AZ zLz)12BGTP}71O~RIu_pnZIMD1emgXiGN2ak(UH?_Z0R}x$qg6hHF;oDEMFp2>O|u0 zvNcwi}iQJUWrnKTH4|DcfOfUp$z=@f>=1qSFOTEVa8lOU)5+(xL zm?rp-FiXG+6VcKKKs+k(0_IMT%kpRmd(Eu*fMbc9Eg3Obk=!vXDrC3oCpwBuhra%J zuYg@Tl3fTD0@c&fKQmc>y3+&vLwn>SqLu`i=SyJ~r>6q6CE!HRtIWF-y6gi(S(RfN z;gq_MpT|P*75asd^ENyY*jLG}j@|I1MI)zW29X^xUtn;LIJAmDI|tcQ#%G`BEA+?^ zuZr{QllSfgb802=(IUN$&=l2@KaQfTjiHOdMxHIEAx^sOdTF;|`X~(Py_*50`-aGb zE9O3=xPYzdpieyCoKtQB$(zc}Y;&vc`54IEv)#;h--uZC(fII0jeZCjY}(d>i$lc* zL<9|?Qy{tDqVn7vtIPIQ(jMYrO*jWc3J{HtI( zCUUbY(C#Gq=I|5Khz~q*=vlxg^^oKSL;gM)13_oHq{aYe<^0 z4pgI=k8EUS(+{mJU!P*|iu#RvvSGng?a!SOY`m5C7v#ga&&r;IE6Z;Y^-m^s;CH`C z5WX#TmMRjC+*UId*qJ5DFM_qBL6e+od?;@}Eu#K27cSC*xMO*}|7veoalDrYves7(7mWP_PA@O4 z!Za7md%zMG4SFr^yZVAE3eNvyxE+UYHO6I`_$>qEB%a-Z>zL&v!UpZidimBfQ|Bvl z=5^~bQG2rfrx^^^d0uk0&^k4GO<2$$| zNr`s1@nr9@1yLI3l1Nazv3GZTr9ymzFWm<>UgRo1duXUiKzlmb_V zwdmQort?y^KRCltw-zHJ4ts~;QemJ;^wXx^e9cF`^r@fk{h4bpR1fhMk7Lv>>MJ8{ z&3piSI@S?@8ZLw71tE%nDU38NEUB0CDq9#oi1>`KugTX+3MBX4g*y_+8x_1?%-=~V zlX;(C9N#e(cVA0hP-hvJ$1zgqD}g-AIcu@Xd(R~m!_bo(CzIa)`HtI6Gv-cb;$g+5 zN&5ebAzd1y|20Q1zu{@~fnAeM@j*0h<8-#tmhn{~dPQy&#hCwz9- zRMfy__2m4}s`jXM!UN~vE%QZe9PPsn1DWE@$ujOlPhrIfDoM>$bw~-R>wl1M>X$T- z_46IodbVLuZ(KKqk>dP`S5Lw$_^FHbr)bKDj(3s6D4$_x=aYlJG*{0yv{lwF!>JX;;t8-QS|pXO9|@IAfiBzPnE7!T5Yfl)YY`PdCdgl*EKdv0L}O<(^^}ARp4sNcj+aqwiCPYS;(gZti5T z2Bsn(zSl=)a7mNytz;+pEcA|DJ>v#M6<)UDvb8BuV|jXhI61+fmC z?Y@l>=hfzvUv1qDg=~gCXP?i#tzTWYLOkrp#oh12>*#H=05XiYZcDE#)k4NZ>1^DE zQonA8Z4go`N=26EE-;VUCmfEV?|yp5ygJb`+}vwF|7uJO^2b++9VbHL*&bfG4ja>I zpCiQ5lz1JzW+{J)M|;h4Nb+?-@QLgc;{!u|4Dw7_;zRBc);|ZPSSYfl