Skip to content

v1.3.155

Choose a tag to compare

@topcheer topcheer released this 16 Jul 05:13

v1.3.155

Fixes

Context usage display — baseline collapse & CacheRead semantics

TUI ctx indicator showed absurdly small numbers (e.g. ctx 76/358K instead of ctx 204/358K).

Root cause was three-fold:

  1. RecordUsage ignored CacheRead for Anthropic protocol — Anthropic's SSE events split input tokens into input_tokens (non-cached only) and cache_read_input_tokens (cached portion). RecordUsage only used input_tokens, producing a baseline roughly 3–4× too small. Now detects Anthropic additive semantics via PromptTokensTotal > InputTokens and adds CacheRead. OpenAI/Gemini InputTokens already includes cached tokens (no double-counting).

  2. RecordUsage collapsed on InputTokens=0 — when a provider fallback path didn't fill InputTokens, the old code set baselineTokens = 0 + OutputTokens. Now skips the baseline update entirely when InputTokens <= 0, preserving the previous estimate.

  3. Anthropic message_delta overwrote message_start usage — the message_delta SSE event only carries output_tokens reliably; its input_tokens field is often 0 or partial. The old code unconditionally overwrote the correct values from message_start. Now only updates from message_delta when the value is non-zero and message_start hadn't already set it.

Session restore — all context messages lost on resume

Resuming a session after compaction loaded zero context messages, causing the agent to lose all conversation history.

  • store.go sets CheckpointMessageCount = len(ContextMessages) (the full post-compaction message list).
  • The old restore code in sessions.go did msgs = msgs[CheckpointMessageCount:], producing an empty slice.
  • Fix: removed the obsolete slicing — ContextMessages is already the checkpoint-aware slice built by loadSession().

Anthropic provider fallback — missing InputTokens

When the stream completed without receiving usage events (e.g. retry fallback), the provider only set OutputTokens. Now estimates InputTokens via CountTokens, matching the OpenAI provider's behavior.