Files
hapi/android/core/protocol
fb035051c2 feat(android): context-remaining indicator in composer (#2201)
* Add per-message metadata details popup to chat

Messages that carry usage signal (model, token counters, round cost or
duration) now expose an info entry under the message card; tapping it
opens a dialog listing model/tier, token totals, cached-input share,
USD cost, and round duration/turn count.

- protocol: decode result summaries into turn-summary events; native
  turn durations and token counts gate on top-level scope and merge
  per turn id onto the trailing block group
- protocol: response-group aggregation sums per-turn usage across a
  run of assistant blocks (adjacent-turn dedup, first-seen model
  order, synthesized round durations from the activity window)
- protocol: label builders render the popup lines with pinned number
  formatting (grouped totals, compact k/m counts, USD tiers,
  sub-minute durations); tests mirror the full label contract
- app: entry shows only when the message has labels, dialog follows
  the existing alert idiom, strings in en/ru/zh with aligned key order

Co-Authored-By: Claude Code <noreply@anthropic.com>

via [HAPI](https://hapi.run)

Co-Authored-By: HAPI <noreply@hapi.run>

* Add pure context-usage math for the chat status strip

Token-count abbreviation (plain below 1k, whole k, one-decimal M),
window-share percentages that always complement to 100, an unrounded
warning band (neutral, amber from 70%, red from 90%), a full readout
with cache-read and a clamped remainder, and the window estimate
table: a window reported alongside the usage wins, then per-flavor
defaults minus a 10k headroom (codex 258.4k, pi/claude 200k, claude
1M for [1m] and fable model ids, cursor names carrying an inline
context= segment). Sessions without an estimate keep a size-only
readout. Unit tests cover the thresholds, mid-point rounding, and the
missing-model / missing-usage edges of every flavor branch.

Co-Authored-By: Claude Code <noreply@anthropic.com>

via [HAPI](https://hapi.run)

Co-Authored-By: HAPI <noreply@hapi.run>

* Show context-remaining indicator above the composer

The composer status strip gains a compact readout of the session
context: the window budget with the free share while the window is
known (ctx 258k, 65% left), otherwise just the current size. The
color escalates neutral, amber, red as the window fills; the text
stays the same in every band. State derives from the session-level
usage projection in ChatUiState and stays hidden until the thread
reports usage. Strings ship in en/ru/zh with aligned key order.

Co-Authored-By: Claude Code <noreply@anthropic.com>

via [HAPI](https://hapi.run)

Co-Authored-By: HAPI <noreply@hapi.run>

* fix(android): salvage single-turn tool-group metadata in aggregation

One assistant message whose groupable tool calls form a single tool group
lost its details entry: aggregation emitted nothing for a one-turn group
without a round summary, and messageMetadataForBlock maps ToolGroupBlock
to null, so once the transcript projection strips the member tools the
usage/model they carried became unreachable.

A group that starts with a ToolGroupBlock now salvages its (deduped)
turn metadata into the aggregate map, keyed by the group block so the
stripped row still resolves it. Groups led by other block kinds keep
their own fields; silent groups salvage nothing. Covers shared-source
members with and without CLI-stamped local ids, the stripped-projection
readback, and the multi-turn aggregation path through a group.

Co-Authored-By: Claude Code <noreply@anthropic.com>

* fix(android): give the elevated context band a semantic amber

ELEVATED used MaterialTheme.colorScheme.tertiary, which the static themes
define as teal and dynamic color derives from the wallpaper, so the amber
caution band the PR promised was anything but. Add a `warning` token to
HapiExtendedColors (amber-700 on light, amber-400 on dark/OLED — outside
the M3 scheme, so wallpaper-derived tertiaries cannot reach it) and map
the band through a pure contextUsageColor() helper.

Unit tests pin the mapping (never the scheme tertiary, stays amber under
teal/wallpaper-like tertiaries) and verify WCAG-AA contrast of the amber
against the light, dark and OLED surfaces.

Co-Authored-By: Claude Code <noreply@anthropic.com>

* fix(android): align the Claude window fallback with the web presets

The copied preset set treated bare sonnet/opus as 200k models and omitted
haiku entirely, so a preset session without a reported window got a 190k
budget (200k of usage read as 0% left) or none at all. Resolve windows
through ClaudeModels.PRESETS mirroring web/src/chat/modelConfig.ts: the
picker aliases (opus/fable/sonnet/haiku) are 1M-window models, claude-
prefixed ids keep the 200k default, and [1m]-suffixed / claude-fable ids
are large.

A device test also pins the chip readout across light/dark/dynamic
themes: known vs unknown windows, all three warning bands, and no
indicator until measurable usage exists.

Co-Authored-By: Claude Code <noreply@anthropic.com>

---------

Co-authored-by: HAPI <noreply@hapi.run>
Co-authored-by: Claude Code <noreply@anthropic.com>
2026-11-02 18:23:23 +08:00
..