Files
codewhale/crates
Hunter Bown 6589ff44aa fix(v0.8.8 hotfix): worked-chip + RLM cost accrual + Windows OSC8 default
Three foreground-visible v0.8.8 regressions surfaced after the
GitHub Release went up. v0.8.8 was taken back down (release
deleted, tag deleted) so this lands cleanly on a re-tag.

1. Worked-chip claimed model work that never happened
=====================================================

`footer_worked_chip` read `App::session_started_at.elapsed()`, so a
TUI that had been open and idle for 4 minutes rendered "worked 4m"
even though no turn had ever fired. The label literally says
"worked" — it should track real model work, not idle uptime.

Fix:
- Add `App::cumulative_turn_duration: Duration`, init to zero.
- Increment on `EngineEvent::TurnComplete` from the just-finished
  turn's elapsed time (the same value already captured for the
  desktop-notification path).
- Drop the now-unused `session_started_at` field.
- `FooterProps::from_app` reads `cumulative_turn_duration`. The
  60s threshold inside `footer_worked_chip` stays — it now means
  "60s of real model work," not "60s since launch."

New regression test pins the invariant: idle app with zero
cumulative turn time → empty chip; 90s of real work → "worked 1m 30s."

2. RLM child-token cost wasn't reaching `session_cost`
=======================================================

A user reported the dashboard showing $0.15 spent for a session
that the DeepSeek website billed at $3+. Sub-agent token usage
already feeds the parent's cost via `MailboxMessage::TokenUsage`
(#166), but the `rlm` tool spawns its own DeepSeek calls under
`child_model` and reports them only in display metadata
(`input_tokens` / `output_tokens`) that nothing consumes for
billing. A session that uses RLM heavily under-reports cost
linearly with the child token count.

Fix: define a contract — tools that spawn their own LLM calls
populate `metadata.child_input_tokens` / `child_output_tokens` /
`child_prompt_cache_hit_tokens` / `child_prompt_cache_miss_tokens`
/ `child_model`. `tool_routing::accrue_child_token_cost_if_any`
runs after every `handle_tool_call_complete`, reads those fields,
and routes the cost through `accrue_subagent_cost`. RLM's
metadata block is updated to populate the contract.

Generic on purpose — future tools that spawn LLM calls (batch
summarizers, retrieval helpers) get accrued for free.

3. OSC 8 hyperlinks corrupting Windows console rendering
========================================================

A Windows user reported the model-name strip showing
"eepseek-v4-flash" (leading `d` consumed) and three overlapping
copies of the composer panel. Likely cause: legacy `cmd.exe` and
pre-Win11 PowerShell consoles don't always honor the OSC 8 string
terminator (`ESC \`) cleanly, and v0.8.8 emitted OSC 8 by default.

Fix: default `osc8_links` to `false` on Windows targets only
(`!cfg!(windows)`). Mac/Linux still default-on. Windows users on
modern terminals (Windows Terminal, Alacritty, WezTerm) can opt
back in via `[ui] osc8_links = true`.

Doesn't address the rest of the rendering corruption — that
needs a Windows machine to reproduce — but the OSC 8 escape was
the most likely culprit and disabling it on Windows is a strict
no-op for terminals that *don't* support it.

Verified
========
- `cargo fmt --all -- --check`
- `cargo clippy --workspace --all-targets --all-features --locked
   -- -D warnings`
- `cargo test --workspace --all-features --locked`
- New regression test for worked-chip pins the bug.
2026-05-03 12:53:17 -05:00
..