summaryrefslogtreecommitdiffhomepage
path: root/src/features/chat/model-select.ts
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-10-19 17:02:40 +0900
committerAdam Malczewski <[email protected]>2026-10-19 17:02:40 +0900
commit01f9fb2a4ad6110def531ead16b370c818e8ee81 (patch)
tree398996139295c24350714bb02a88b0dc07545123 /src/features/chat/model-select.ts
parentc4397f633415a46852f0e3b49c78ab7b2d87d4c1 (diff)
downloaddispatch-web-01f9fb2a4ad6110def531ead16b370c818e8ee81.tar.gz
dispatch-web-01f9fb2a4ad6110def531ead16b370c818e8ee81.zip
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/<model>. 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.
Diffstat (limited to 'src/features/chat/model-select.ts')
-rw-r--r--src/features/chat/model-select.ts19
1 files changed, 19 insertions, 0 deletions
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
@@ -63,6 +63,25 @@ export function isNumberedOpenCode(id: string): boolean {
}
/**
+ * 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/<model>`.
+ */
+export const CLAUDE_SUBSCRIPTION_KEY = "claude";
+
+/**
+ * True iff `full` is a model served through the Claude Code subscription
+ * (`claude/<model>`). 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-<n>` →
* "OpenCode #<n>"; any other id is returned unchanged. The RAW id is still what
* gets selected/persisted — this only affects display.