feat(agents): show Claude usage limits and session cost in the agent task header (#1041)

Claude Code reports the account's 5-hour and weekly usage limits (rate_limit_event) and the session cost (result.total_cost_usd); only the limit status was used. The limits now show as meters next to the context meter in the task header, with the reset time in the tooltip, and Settings › Tools › Agents › Chat turns each meter (context, work time, limits, cost) on or off. Limits are per provider and kept in memory; cost is off by default.

Closes #1057

Co-authored-by: matthiasdemauroy <[email protected]>
Цей коміт міститься в:
matthiasdemauroyтаmatthiasdemauroy authored and GitHub committed 2026-11-04 00:28:23 +08:00
1 джерело 4eda613c59
коміт 39fe96bd01
19 files changed
+459 -16

No files matched your search

+15
Переглянути файл
@@ -0,0 +1,15 @@
import { describe, expect, it } from "vitest";
import { validateSettings } from "../model/schema";
describe("agent chat settings", () => {
it("defaults every meter but the cost to on and keeps stored values", () => {
expect(validateSettings({}).agents).toEqual({
showContextUsage: true,
showWorkTime: true,
showUsageLimits: true,
showCost: false,
});
const stored = validateSettings({ agents: { showUsageLimits: false, showCost: true, showWorkTime: "no" } }).agents;
expect(stored).toEqual({ showContextUsage: true, showWorkTime: true, showUsageLimits: false, showCost: true });
});
});
+11 -1
Переглянути файл
@@ -7,7 +7,7 @@
import { validateCMake } from "@/platform/cmakeSettings";
import { DEFAULT_IGNORED_NAMES } from "@/platform/ignoredNames";
import { validateFileTypeOverrides, validateFileTypes, type FileTypeAssociations } from "@/platform/fileTypes";
import type { LanguageServerSettings, Settings } from "@/platform/ipc";
import type { AgentSettings, LanguageServerSettings, Settings } from "@/platform/ipc";
import {
DEFAULT_LANGUAGES,
DEFAULT_PROJECT_STRUCTURE,
@@ -92,6 +92,8 @@ export interface ValidSettings extends WorkflowSettings {
tools: Record<string, { path: string }>;
/** Settings › Language Servers, by server name (as the backend sends them). */
languageServers: Record<string, LanguageServerEntry>;
/** Tools › Agents › Chat: the meters in an agent task's header. */
agents: Required<AgentSettings>;
}
/** One `languageServers.<name>` entry; every field optional, like in settings.toml. */
@@ -158,6 +160,7 @@ export const DEFAULT_SETTINGS: ValidSettings = {
spelling: { ideWords: [], projectWords: [], customDictionaries: [] },
tools: {},
languageServers: {},
agents: { showContextUsage: true, showWorkTime: true, showUsageLimits: true, showCost: false },
...DEFAULT_WORKFLOW,
};
@@ -201,6 +204,7 @@ export function validateSettings(raw: Settings | unknown): ValidSettings {
const a = obj(root.appearance);
const e = obj(root.editor);
const f = obj(root.files);
const agents = obj(root.agents);
const overrides = bindingMap(root.keymapOverrides);
const customKeymaps: Record<string, CustomKeymapSettings> = {};
for (const [id, raw] of Object.entries(obj(root.customKeymaps))) {
@@ -270,6 +274,12 @@ export function validateSettings(raw: Settings | unknown): ValidSettings {
languageServers: Object.fromEntries(
Object.entries(obj(root.languageServers)).map(([name, ls]) => [name, obj(ls) as LanguageServerEntry]),
),
agents: {
showContextUsage: bool(agents.showContextUsage, d.agents.showContextUsage),
showWorkTime: bool(agents.showWorkTime, d.agents.showWorkTime),
showUsageLimits: bool(agents.showUsageLimits, d.agents.showUsageLimits),
showCost: bool(agents.showCost, d.agents.showCost),
},
...validateWorkflow(root),
};
}
+32 -3
Переглянути файл
@@ -1,7 +1,7 @@
/**
* Tools pages: Terminal, Actions on Save and External Tools. Consumed by the
* terminal feature, the editor save participants and the run feature
* (External Tools actions).
* Tools pages: Terminal, Actions on Save, External Tools and Agents › Chat. Consumed
* by the terminal feature, the editor save participants, the run feature
* (External Tools actions) and the agent task editor.
*/
import { FontPicker } from "../components/FontPicker";
@@ -623,6 +623,35 @@ export const TOOLS_PAGES: PageSpec[] = [
{ options: [{ kind: "custom", label: "Save", component: ActionsOnSaveNote }] },
],
},
{
// Under Settings › Tools › Agents (the agents feature registers `tools.agents`).
id: "tools.agents.chat",
title: "Chat",
group: TOOLS_GROUP,
order: 0,
keywords: ["agent", "claude", "codex", "usage", "quota", "rate limit", "cost", "tokens", "meter"],
sections: [
{
title: "Shown in the Task Header",
options: [
{ kind: "toggle", key: "agents.showContextUsage", label: "Context window usage" },
{ kind: "toggle", key: "agents.showWorkTime", label: "Time spent on the task" },
{
kind: "toggle",
key: "agents.showUsageLimits",
label: "Usage limits",
hint: "The account's 5-hour and weekly limits, when the agent reports them (Claude Code)",
},
{
kind: "toggle",
key: "agents.showCost",
label: "Session cost",
hint: "What the session has cost so far, as the agent reports it (API pricing, also shown on subscriptions)",
},
],
},
],
},
{
id: "tools.externalTools",
title: "External Tools",