Skip to content

feat: prompt-cache tracking + consistent styled dropdowns - #118

Merged
ddutchie merged 2 commits into
mainfrom
ddutchie/cacheanddropdowns
Aug 7, 2026
Merged

ddutchie merged 2 commits into
mainfrom
ddutchie/cacheanddropdowns

Conversation

@ddutchie

@ddutchie ddutchie commented Aug 7, 2026 •

Copy link
Copy Markdown
Owner

What does this PR do?

Two related chunks of work:

1. Prompt-cache visibility. Captures cache-read/creation tokens from provider usage (Anthropic cache_read_input_tokens / OpenAI cached_tokens) across chat, the Agent, subagents, automations, and one-shot AI calls. Surfaces them in the ContextRing (a Prompt cache row + tooltip), persists them to the usage log, and makes the Usage view show cached input as a stat and per-row column. Cost estimates from models.dev are now cache-aware (cached input priced at cache_read/cache_write rates instead of full input). The Usage view also gains an Estimates toggle to hide rows whose cost is a models.dev estimate.

2. Consistent styled dropdowns. The model picker now puts the model name on one line with capabilities + cost underneath, in both the open menu and the closed trigger. All remaining native <select> dropdowns were replaced with a shared styled Select component (Radix-based) so every dropdown has the same floating panel and theming: usage source filter, chat quick-settings provider, card column + blocker pickers, automation project scope + approval mode, schedule-builder units, spawn-agent binary, llama server context limit, service HTTP method, and the mobile topbar view selector.

Type of change

  • New feature
  • Bug fix
  • Refactor / code quality
  • Docs / changelog
  • Tests

Screenshots / recording

n/a (desktop UI — happy to add screenshots on request)

Checklist

  • npm run type-check:all passes
  • npm run lint passes
  • npm test passes (runs npm run compile first so electron/bundle-guard.test.ts actually executes — npm run test:bundle to run just that)
  • npm run test:e2e passes (run before merging UI changes or cutting a release)
  • If this ships a major, user-facing feature: added an entry to scripts/features.config.js so it appears in the "What's New" modal (generated JSON — run node scripts/generate-features.js)
  • No hardcoded colours — CSS variables only (var(--accent), var(--text-primary), etc.)
  • No text-[Npx] pixel font classes — rem equivalents only (text-[0.714rem], text-xs, etc.)
  • New IPC handlers wrapped in handle() and return IpcResult<T>
  • New DB migrations appended (not edited) in schema.ts — added columns via idempotent ensureColumns guards instead of a new migration
  • New SQL goes in electron/db/queries.ts — single source of truth (imported by both Electron main process and MCP server); never construct a Database instance outside db/client.ts (Electron) or mcp-server.ts (MCP runtime)
  • New dependencies or devDependencies added to ROLE_MAP in scripts/generate-licenses.js and licenses.json regenerated
  • New MCP tools registered in electron/mcp/tools/index.ts dispatch + electron/lib/tool-schemas.ts Zod schema
  • If you added/removed a --external:<pkg> flag in the compile script: updated the appropriate allowlist group (RUNTIME_PROVIDED / OPTIONAL_TRANSITIVE / SUBPROCESS_ONLY / SHIPPED_NATIVE) in electron/bundle-guard.test.ts and (if SHIPPED_NATIVE) shipped the package via electron-builder.yml

Notes for reviewer

  • The What's New feature entry was intentionally skipped — this is a refinement of existing surfaces (ContextRing + Usage view) rather than a new headline feature; it's recorded in changelogs/v2.6.7.md.
  • e2e tests not run locally (need the app harness) — flagged in the checklist for the merge gate.
  • One pre-existing quirk left untouched: coding-tools/subagent.ts forwards the third onUsage arg (reasoning tokens) into the subagent pi-agent:usage event's breakdown field. Out of scope here; cache fields map to the correct positional args regardless.

Summary by CodeRabbit

  • New Features

    • View prompt-cache reads, writes, and usage percentages in chat context indicators and Usage history.
    • Track cached input tokens in usage totals and recent activity.
    • Apply cache-aware cost estimates using model-specific cache pricing.
    • Filter estimated-cost entries from Usage reports.
    • Added support for consistent model cache-pricing data.
  • Style

    • Standardized dropdown controls across model pickers, settings, automation, chat, Kanban, and navigation views.
    • Improved model picker layout for clearer capability, warning, and pricing information.
  • Documentation

    • Added v2.6.7 release changelog entries.

- Capture prompt-cache read/creation tokens across chat, agent, subagents,
  automations and one-shot AI calls; surface cache hits in the ContextRing
  (cache row + tooltip) and persist to the usage log.
- Usage view: cached-input stat, per-row cached column with % of input, and
  an Estimates toggle to hide models.dev-estimated cost rows.
- Cost estimates are cache-aware (models.dev cache_read/cache_write rates).
- Model picker rows and triggers show name on one line with capabilities +
  cost underneath.
- Replace all native <select> dropdowns with the shared styled Select
  (usage source, quick-settings provider, card column/blocker, automations,
  schedule builder, spawn-agent, llama console, service method, topbar).
@coderabbitai

coderabbitai Bot commented Aug 7, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@ddutchie, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 49 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 748ef3e9-3fc6-4d2f-a0e8-35c0121970f7

📥 Commits

Reviewing files that changed from the base of the PR and between 7ab79c1 and 1ddd620.

📒 Files selected for processing (8)
  • electron/db/schema.ts
  • electron/db/usage-queries.test.ts
  • electron/db/usage-queries.ts
  • electron/lib/coding-tools/subagent.test.ts
  • electron/lib/coding-tools/subagent.ts
  • src/components/automations/schedule-builder.tsx
  • src/components/ui/select.tsx
  • src/components/usage/UsageView.tsx
📝 Walkthrough

Walkthrough

The change adds prompt-cache token extraction, cache-aware pricing, database tracking, estimated-cost filtering, cache metrics in chat and agent context displays, and a shared styled Select component across multiple views.

Changes

Prompt-cache accounting

Layer / File(s) Summary
Cache pricing and provider usage normalization
electron/lib/model-pricing.ts, electron/lib/usage-recorder.ts, shared/models/model-catalog.ts, src/lib/models-dev.ts
Provider cache fields are normalized and used for cache-aware cost estimation. Model catalogs expose cache read and write prices.
Usage propagation through model and agent flows
electron/lib/..., electron/ipc/..., src/store/..., src/types/..., electron/preload.ts
Chat, subagent, streaming, compaction, automation, tool, and Pi-agent usage flows record and emit cache-token metrics.
Usage persistence, filtering, and reporting
electron/db/..., electron/ipc/usage-handlers.ts, src/hooks/useUsage.ts, src/components/usage/UsageView.tsx
Database queries aggregate cache tokens and support excluding estimated-cost rows. Usage views display cached totals and per-call metrics.
Context-ring cache metrics
src/components/agent/..., src/components/chat/chat-panel/...
ContextRing displays cached tokens, cache-write tokens, and the percentage of prompt input served from cache.

Shared controls

Layer / File(s) Summary
Shared Select and control migrations
src/components/ui/select.tsx, src/components/agent/SpawnAgentModal.tsx, src/components/automations/..., src/components/chat/chat-panel/ChatQuickSettings.tsx, src/components/kanban/card-detail-sidebar.tsx, src/components/layout/topbar.tsx, src/components/settings/..., src/components/ui/model-picker.tsx
A generic styled Select replaces native dropdowns across the application. The model picker uses stacked identity and metadata rows.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Provider
  participant UsageRecorder
  participant ChatAndAgentLoops
  participant Database
  participant UsageView
  Provider->>UsageRecorder: Report cache usage
  UsageRecorder->>ChatAndAgentLoops: Pass normalized cache tokens
  ChatAndAgentLoops->>Database: Persist usage and estimated cost
  Database-->>UsageView: Return totals and recent usage
  UsageView->>UsageView: Display cached-token metrics and filters
Loading

Possibly related PRs

  • ddutchie/cairn#117: Introduced usage-tracking and pricing systems extended here with prompt-cache metrics.
  • ddutchie/cairn#116: Introduced shared streaming and chat usage paths extended here with cache-token propagation.
  • ddutchie/cairn#78: Also modifies context-window usage tracking and ContextRing displays.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 54.76% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes both primary changes: prompt-cache tracking and replacement of native dropdowns with consistent styled controls.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ddutchie/cacheanddropdowns

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@electron/db/schema.ts`:
- Around line 1029-1032: Add a new versioned migration after the existing
migrations that adds cache_read_tokens and cache_creation_tokens to llm_usage
within the migration transaction, ensuring insertLlmUsage-required columns are
present before the schema version advances. Retain the existing ensure guards as
compatibility fallback, but do not rely on them as the primary schema update.

In `@electron/db/usage-queries.ts`:
- Around line 132-134: Update the excludeEstimated predicate in the usage query
to require both cost_estimated = 0 and cost_usd IS NOT NULL, preserving the UI
contract that excluding estimates shows only calls with provider-reported costs.

In `@electron/lib/coding-tools/subagent.ts`:
- Line 108: Update the onUsage callback in the subagent event forwarding to
accept arguments in the pi-agent-loop order: promptTokens, completionTokens,
reasoningTokens, breakdown, costUsd, cacheReadTokens, and cacheCreationTokens.
Forward each value to childToolCtx.send under the matching payload fields
without shifting or dropping values, and add a regression test using distinct
values for every usage argument.

In `@src/components/automations/schedule-builder.tsx`:
- Around line 241-246: Add accessible names to both schedule Select components:
set ariaLabel to “Interval unit” on the selector using intervalUnit and to “Day
of month” on the selector for the day-of-month value, preserving their existing
props and behavior.

In `@src/components/ui/select.tsx`:
- Around line 72-85: Restore a visible keyboard focus indicator on the Select
trigger button by updating its className focus styles around the button element,
replacing the unconditional focus outline removal with an appropriate
focus-visible outline or ring. Keep the existing hover, disabled, sizing, and
custom class behavior unchanged.

In `@src/components/usage/UsageView.tsx`:
- Around line 184-185: Replace the raw bg-white class on the toggle thumb span
in UsageView with a CSS custom-property background class such as
bg-[var(--surface)], while preserving the existing positioning and transition
classes.
- Around line 170-188: Add aria-pressed={excludeEstimated} to the
estimate-filter button in the UsageView toggle, preserving the existing state
and click behavior while exposing whether estimates are currently excluded.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 98386e1a-986e-4594-8131-6d54923bb049

📥 Commits

Reviewing files that changed from the base of the PR and between 996e519 and 7ab79c1.

📒 Files selected for processing (46)
  • changelogs/v2.6.7.md
  • electron/db/schema.ts
  • electron/db/usage-queries.test.ts
  • electron/db/usage-queries.ts
  • electron/ipc/chat.ts
  • electron/ipc/pi-agent.ts
  • electron/ipc/tool-builder.ts
  • electron/ipc/usage-handlers.ts
  • electron/lib/chat-loop.ts
  • electron/lib/chat-subagent-loop.ts
  • electron/lib/coding-tools/subagent.ts
  • electron/lib/compaction.ts
  • electron/lib/heartbeat-runner.ts
  • electron/lib/llm-stream.ts
  • electron/lib/llm.ts
  • electron/lib/model-pricing.test.ts
  • electron/lib/model-pricing.ts
  • electron/lib/pi-agent-loop.ts
  • electron/lib/usage-recorder.test.ts
  • electron/lib/usage-recorder.ts
  • electron/preload.ts
  • shared/models/model-catalog.test.ts
  • shared/models/model-catalog.ts
  • src/components/agent/AgentChatPane.tsx
  • src/components/agent/AgentMessageBubble.tsx
  • src/components/agent/ContextRing.tsx
  • src/components/agent/SpawnAgentModal.tsx
  • src/components/automations/automations-view.tsx
  • src/components/automations/schedule-builder.tsx
  • src/components/chat/chat-panel/ChatQuickSettings.tsx
  • src/components/chat/chat-panel/ChatSubagentBlock.tsx
  • src/components/chat/chat-panel/index.tsx
  • src/components/kanban/card-detail-sidebar.tsx
  • src/components/layout/topbar.tsx
  • src/components/settings/LlamaServerConsole.tsx
  • src/components/settings/tools/ServiceForm.tsx
  • src/components/ui/model-picker.tsx
  • src/components/ui/select.tsx
  • src/components/usage/UsageView.tsx
  • src/hooks/useChatStream.ts
  • src/hooks/useUsage.ts
  • src/lib/models-dev.ts
  • src/store/slices/chat.ts
  • src/store/slices/terminal-sessions.ts
  • src/types/index.ts
  • src/types/usage.ts

Comment thread electron/db/schema.ts
Comment thread electron/db/usage-queries.ts
Comment thread electron/lib/coding-tools/subagent.ts Outdated
Comment thread src/components/automations/schedule-builder.tsx
Comment thread src/components/ui/select.tsx
Comment thread src/components/usage/UsageView.tsx
Comment thread src/components/usage/UsageView.tsx Outdated
- schema: add versioned v39 migration for llm_usage cache columns (ensureColumns stays as fallback)
- usage-queries: excludeEstimated now drops rows with no provider-reported cost too (cost_usd IS NOT NULL)
- subagent: forward all onUsage args in pi-agent-loop order (was shifting reasoning/breakdown/cost); add regression test with distinct values
- schedule-builder: ariaLabel on interval-unit and day-of-month selects
- select: visible focus-visible ring on the trigger
- UsageView: theme-var toggle thumb + aria-pressed on the estimates button
@ddutchie
ddutchie merged commit 86f952c into main Aug 7, 2026
6 checks passed
@ddutchie
ddutchie deleted the ddutchie/cacheanddropdowns branch August 7, 2026 02:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant