From 01f9fb2a4ad6110def531ead16b370c818e8ee81 Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Mon, 19 Oct 2026 17:02:40 +0900 Subject: feat(chat): cache timer for Claude Code subscription models Per-step and per-turn timers for the gaps between model requests (the Claude prompt cache expires after 5 min idle). A step gap runs live under the executing tools from step-complete until its last tool result (or the next step's output), then is stamped on that step's metrics line beside its cache badge. A turn gap runs live on the turn's metrics line from done/error until the next message is sent, then is stamped there. Counts m:ss up to 10 min, then '10+ min'; colour tracks the 5-min TTL. Gated on claude/. Pure reducer in core/metrics/cache-timer.ts; the turn gap is seeded from an idle conversation's lastActivityAt so it survives a reload. Stamps are in-memory only. --- src/features/chat/model-select.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'src/features/chat/model-select.ts') diff --git a/src/features/chat/model-select.ts b/src/features/chat/model-select.ts index 6f198f3..bebad2c 100644 --- a/src/features/chat/model-select.ts +++ b/src/features/chat/model-select.ts @@ -62,6 +62,25 @@ export function isNumberedOpenCode(id: string): boolean { return openCodeNumber(id) !== null; } +/** + * The credential key of the Claude Code subscription (the external Claude + * extension — `auth-claude` + `provider-anthropic`). The backend registers it + * under `DISPATCH_CLAUDE_CREDENTIAL`, default `"claude"`, so its models arrive + * as `claude/`. + */ +export const CLAUDE_SUBSCRIPTION_KEY = "claude"; + +/** + * True iff `full` is a model served through the Claude Code subscription + * (`claude/`). Gates the cache timer (that subscription's prompt cache + * expires after 5 minutes). A bare key with no model is not a model. + */ +export function isClaudeSubscriptionModel(full: string | undefined): boolean { + if (full === undefined) return false; + const { key, model } = splitModelName(full); + return key === CLAUDE_SUBSCRIPTION_KEY && model !== ""; +} + /** * A friendly human label for a model key/provider id: `opencode-` → * "OpenCode #"; any other id is returned unchanged. The RAW id is still what -- cgit v1.2.3