[FEATURE] Desktop app: surface prompt-cache warmth and a TTL countdown — the data is already computed, no client renders it

Status Open
Reported on v2.1.275
Maintainer reply None cached
Activity 0 comments · opened Sep 21, 2026

Preflight Checklist

  • [x] I have searched existing requests. The closest matches are linked under Alternative Solutions; none cover the desktop app.
  • [x] This is a single feature request.

Problem Statement

The desktop app's Code tab surfaces no prompt-cache state at all, even though the bundled CLI already computes it for every session. There is no way, from inside the desktop app, to tell whether this conversation is warm or how long it has left — so there is no way to decide whether to send one more message now or let the session go cold.

The data exists. The bundled CLI computes a prompt_cache object per session (warm, ttl, expires_at, recache_tokens_if_cold, hit_ratio, misses, last_miss_cause) and two other surfaces render it:

| Surface | Cache warmth | Countdown | Re-cache estimate |
|---|---|---|---|
| Terminal CLI — /usage Prompt cache (main) line (v2.1.251+) | yes | no (shows "last activity 40s ago") | yes, on misses |
| Terminal CLI — statusLine prompt_cache object | yes | yes (expires_at) | yes (recache_tokens_if_cold) |
| VS Code extension — idle warning on resume (per #94456) | yes | no | yes ("will re-cache about 594k tokens") |
| Desktop app (Code tab) | no | no | no |

Three things close off in the desktop app specifically:

  1. The usage ring carries context and plan usage only. It is the natural home for this and shows nothing about the cache.
  2. statusLine is silently inert in the desktop app, so the documented extension point cannot be used as a workaround. Independently verified in #88598 (a script instrumented to append a timestamp on every run logged zero lines in two minutes, in both an existing session and one started after the settings were written).
  3. The get_usage MCP tool exposes no cache fields, so the agent cannot see its own cache state either. Called in a desktop session on 2.1.275 just now, the context block returns:
"context": {
  "session": "self", "status": "ok",
  "tokensUsed": 192431, "contextWindow": 1000000,
  "percentUsed": 19, "autoCompactsAtPercent": 97,
  "categories": [ { "name": "Messages", "tokens": 124270, "percent": 12 }, ... ]
}

No warm, no expires_at, no recache_tokens_if_cold. An agent told "finish this session warm" has no field to act on.

Why this matters more since Fable 5.1. Cache reads on Fable 5.1 and Mythos 5.1 are priced at 0.025x base input rather than the standard 0.1x (pricing). The read got four times cheaper; the relative cost of letting a cache lapse got four times worse:

| Model | 1h cache write | Cache read | One lapsed TTL costs |
|---|---|---|---|
| Fable 5.1 / Mythos 5.1 | $20 / MTok | $0.25 / MTok | 80 warm turns |
| Fable 5 / Mythos 5 | $20 / MTok | $1.00 / MTok | 20 warm turns |
| Opus 5 / 4.8 / 4.7 | $10 / MTok | $0.50 / MTok | 20 warm turns |

On a 500k-token desktop session on Fable 5.1, one TTL lapse rewrites $10 of context — eighty turns' worth of warm reads — and nothing in the window gives any warning before or after it happens. On a subscription the TTL is an hour, which is precisely long enough that you stop tracking it by hand.

Proposed Solution

Any one of these solves it; listed in order of preference.

  1. Put the cache state on the usage ring. It already opens to show context and plan usage; add a cache row — warm · 41m left (1h TTL) / cold · next message re-caches 594k. A colour on the ring itself (or a small dot beside it) when the cache is inside its last few minutes would make it glanceable without a click. The refresh trigger already exists in the CLI: the status line re-runs when a warm cache reaches its expires_at, so the desktop renderer can hook the same event rather than poll.
  1. Add the prompt_cache fields to get_usage's context block. Cheapest of the three and the only one that helps the agent. With warm, ttl, expires_at and recache_tokens_if_cold available, a session can pace itself against the TTL — batch its remaining tool calls, or say "we have 6 minutes of warm cache, want me to wrap up?" — which is impossible today at any prompt.
  1. Honor statusLine in the desktop app, or document that it is TUI-only. This is #88598's third option, and it would let users build the display themselves. Today it fails silently: valid config, executable script, no output, no warning, no log.

Alternative Solutions

Tried and rejected:

  • A statusLine script reading prompt_cache.expires_at — works in the terminal CLI, inert in the desktop app (#88598). This is the workaround the documentation implies exists and it does not apply here.
  • /usage in the desktop app — the Code tab documents that terminal-dialog commands behave differently, and there is no equivalent panel carrying the Prompt cache (main) line.
  • Watching the wall clock by hand — what the 1-hour subscription TTL makes unreliable: an hour is long enough to lose track of, and the cost of being wrong is a silent full-context rewrite.

Related issues, none of which cover the desktop case:

  • #94456 — the cold-cache warning appears in the VS Code extension on --resume but not the terminal CLI. Same underlying data, two other surfaces; the desktop app has it on neither resume nor live.
  • #88598 — statusLine and footerLinksRegexes are silently inert in the desktop app. That request wants a GitHub-issue footer chip; this one wants cache state, and its option 3 would serve both.
  • #52665 — "surface prompt cache expiry status in CLI status bar" (Apr 2026), closed not planned by the stale bot and locked. Its request was for the TUI, and the underlying data shipped afterwards.
  • #66115 — auto-compact on idle timeout to prevent cache expiry cost. An automatic mitigation rather than a display; a countdown lets the user decide instead.

Priority

Medium - Would be very helpful

Feature Category

Configuration and settings

Use Case Example

Long desktop sessions on Fable 5.1, several open across git worktrees, one per ticket.

The decision I want to make, several times a day: I am about to step away. Is this session warm, and for how long? If it has forty minutes left, I leave it. If it has four, I either finish the thought now or accept that the next message pays a full re-cache. On Fable 5.1 that re-cache is eighty times a warm read, so the answer changes what I do — and the desktop window gives me nothing to answer it with.

The same decision at the end of a session: "finish warm" is only actionable if something tells me where the boundary is.

Additional Context

  • Desktop app bundled CLI: 2.1.275 (Windows 11). Standalone CLI on the same machine: 2.1.273.
  • Plan: Max (1-hour cache TTL; per the costs documentation this drops to five minutes once drawing on usage credits, which is a second reason to surface the TTL in effect rather than assume it).
  • The prompt_cache fields and the expires_at refresh trigger are documented under status line — prompt cache fields; the Prompt cache (main) line is documented under costs — prompt cache statistics. Both are terminal-CLI surfaces.
  • Since the counts are derived from the cache token fields in API responses, they work on every provider and gateway — so a desktop renderer for them has no provider-specific dependency.

View original on GitHub ↗