feat: 显示优化 — per-message usage 和 context window indicator (issue #24) #48

Merged
ph merged 3 commits from feature/issue-24-usage-display into master 2026-06-08 14:48:01 +00:00
Owner

修改内容

实现 Issue #24 显示优化需求

Go TUI

  • 在每条 assistant message 下方显示 per-turn usage(输入 tokens、输出 tokens、缓存命中率)
  • 复用了现有的 token 样式(StyleTokenInput/StyleTokenOutput/StyleTokenCache)

Web Frontend

stream.ts

  • 处理 token_budget 事件,提取 usage/maxTokens/tokenPct 到 StreamResult
  • 从 stream_update 事件中捕获 per-turn usage

chat-store.ts

  • 新增 tokenBudget$ BehaviorSubject 记录上下文预算状态
  • 新增 lastUsage$ BehaviorSubject 记录最新 per-turn usage
  • 导出 useTokenBudget() 和 useLastUsage() hooks

message.tsx

  • UsageFooter 组件:在最后一条 assistant message 下方显示输入/输出 tokens 和缓存命中率
  • ContextBar 组件:显示上下文窗口使用率(百分比 + 视觉进度条)

thread.tsx

  • 在 composer 上方显示 ContextBar(当 token_budget 数据可用时)

验证

  • make build
  • make test (全部通过)
  • cd web && pnpm build
## 修改内容 实现 Issue #24 显示优化需求 ### Go TUI - 在每条 assistant message 下方显示 per-turn usage(输入 tokens、输出 tokens、缓存命中率) - 复用了现有的 token 样式(StyleTokenInput/StyleTokenOutput/StyleTokenCache) ### Web Frontend **stream.ts** - 处理 token_budget 事件,提取 usage/maxTokens/tokenPct 到 StreamResult - 从 stream_update 事件中捕获 per-turn usage **chat-store.ts** - 新增 tokenBudget$ BehaviorSubject 记录上下文预算状态 - 新增 lastUsage$ BehaviorSubject 记录最新 per-turn usage - 导出 useTokenBudget() 和 useLastUsage() hooks **message.tsx** - UsageFooter 组件:在最后一条 assistant message 下方显示输入/输出 tokens 和缓存命中率 - ContextBar 组件:显示上下文窗口使用率(百分比 + 视觉进度条) **thread.tsx** - 在 composer 上方显示 ContextBar(当 token_budget 数据可用时) ## 验证 - make build ✅ - make test ✅(全部通过) - cd web && pnpm build ✅
- Go TUI: show per-message token usage (input/output tokens, cache hit ratio)
  below each assistant message
- Web frontend stream.ts: handle token_budget events, capture per-turn usage
  from stream_update events
- Web frontend chat-store.ts: track token budget state and per-message usage
  via BehaviorSubjects, export hooks
- Web frontend message.tsx: add UsageFooter component showing per-message
  usage stats, add ContextBar component showing context window progress
- Web frontend thread.tsx: show context window indicator above composer
- Add usage field to ChatMessage interface
- Accumulate usage across multiple turns in stream.ts (not just last turn)
- Normalize openai nested Usage format to flat frontend format
- Load usage from backend when resuming sessions (daemonMessagesToChatMessages)
- Show UsageFooter on every assistant message with usage, not just the last
- Remove global lastUsage$ state (usage now lives on each message)

Closes #24 (partial: per-message usage display)
- Combined action bar and UsageFooter inside a single container with flex layout
- Used justify-between to place action bar on left and UsageFooter on right when both are present
- Removed negative margin overlap issue by aligning them on the same line
- Imported and added ArrowDown, ArrowUp, and Database icons from lucide-react to UsageFooter
- Styled icons with distinct muted colors (blue, emerald, purple)
- Removed temporary console.log from chat-store
When loading history, consecutive assistant messages from the same agent
loop now have their usage accumulated and displayed only on the last
assistant message of the group. Intermediate assistant messages show no
usage footer.

This matches the streaming behavior where stream.ts already accumulates
usage across turns into a single value.
ph added 2 commits 2026-06-08 13:59:27 +00:00
- Remove reloadLast() from chat-store (backend doesn't support regenerate)
- Show Copy button on all assistant messages, not just the last
- Remove Refresh/Reload button and RefreshCwIcon import
- Remove stale TODO comments in chat-store.ts, message.tsx, thread.tsx
ph force-pushed feature/issue-24-usage-display from 7ac689a604 to cb33b0fcee 2026-06-08 14:22:11 +00:00 Compare
cached_tokens and reasoning_tokens are per-turn breakdown fields that don't
aggregate meaningfully. Summing them across turns produces inflated values
(e.g. cached_tokens: 30720 > prompt_tokens: 9597).

Now addUsage() only sums prompt_tokens, completion_tokens, total_tokens.
On multi-turn merge, cached_tokens and reasoning_tokens are dropped — the
UsageFooter already handles missing cached_tokens gracefully (hides Cache%).
Instead of discarding cached_tokens and reasoning_tokens on multi-turn merge,
preserve the last turn's values — they reflect the most recent cache hit state
and give a meaningful percentage when computed against the total prompt_tokens.
ph force-pushed feature/issue-24-usage-display from c880882f17 to 40737426e2 2026-06-08 14:36:33 +00:00 Compare
Replace 100vh with 100dvh on .app-layout so the UI adapts to mobile
browser address bar show/hide and keyboard appearance without content
being clipped or overlapped. 100vh kept as fallback for older browsers.
ph merged commit 7babe7eaa9 into master 2026-06-08 14:48:01 +00:00
ph deleted branch feature/issue-24-usage-display 2026-06-08 14:48:01 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ph/agentic!48
No description provided.