Skip to content

fix(wework): correct processing duration timer and header interactivity - #1329

Merged
qdaxb merged 3 commits into
wecode-ai:mainfrom
icycrystal4:fix/wework-processing-duration
Jun 10, 2026
Merged

qdaxb merged 3 commits into
wecode-ai:mainfrom
icycrystal4:fix/wework-processing-duration

Conversation

@icycrystal4

@icycrystal4 icycrystal4 commented Jun 10, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Fixes three issues with the chat "已处理 Xs 时间了" turn-duration display:

  • Timer froze during pure-thinking phases (no tool output). getDuration now counts against the live clock while the turn isRunning instead of locking to the last block timestamp, so the elapsed time advances every second even when there is no new tool output.
  • A completed turn showed "已处理 0s 时间了" after page refresh. The backend add_block fallback stamped blocks with the event loop's monotonic clock — a small non-epoch value the client rejects as invalid (getBlockTimestamp requires > 1e12), collapsing the rendered duration to 0s. It now uses wall-clock epoch milliseconds (time.time).
  • Running header showed a not-allowed cursor. It was a disabled button. While running it now renders as plain, non-interactive text; the collapsible button only appears once the turn finishes.

Changes

  • wework/src/components/chat/blocks/ToolBlocksDisplay.tsx — live-clock duration while running; plain text vs. button header.
  • backend/app/services/chat/storage/session.py — add_block uses time.time() for both the generated id and timestamp fallback.
  • Tests added in both ToolBlocksDisplay.test.tsx and test_session_blocks.py.

Test plan

  • wework: ToolBlocksDisplay tests pass (live tick while streaming with all blocks done; header renders as plain text while running)
  • wework: theme-token-guard, tsc --noEmit, eslint clean
  • backend: black --check / isort --check-only clean on changed files
  • backend: test_add_block_fills_wall_clock_epoch_timestamp regression test (runs in CI; local run blocked by network/env)
  • Manual: verify timer advances during thinking-only phase and a completed turn keeps its duration after refresh

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Elapsed activity timer can be anchored to the original turn start (prop) so durations persist after refresh; timer keeps updating during active processing and shows a non-clickable running header.
  • Bug Fixes

    • Block timestamps and auto-generated IDs now use wall-clock epoch milliseconds for accurate duration display after reloads.
  • Tests

    • Added regression tests for timestamp/ID generation and streaming-duration display/behavior.

Fixes three issues with the "已处理 Xs 时间了" turn-duration display:

1. Timer froze during pure-thinking phases. getDuration now counts
   against the live clock while the turn isRunning instead of locking
   to the last block timestamp, so the elapsed time advances every
   second even when there is no new tool output.

2. A completed turn showed "已处理 0s 时间了" after a page refresh.
   The backend add_block fallback stamped blocks with the event loop's
   monotonic clock (a small non-epoch value the client rejects as
   invalid), collapsing the rendered duration to 0s. It now uses
   wall-clock epoch milliseconds (time.time).

3. Hovering the running header showed a not-allowed cursor because it
   was a disabled button. While running it now renders as plain,
   non-interactive text; the collapsible button only appears once the
   turn finishes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 10, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ecc06b23-d0ad-4b7a-a76b-e56b3f421da1

📥 Commits

Reviewing files that changed from the base of the PR and between 9f7769b and 171a5ba.

📒 Files selected for processing (3)
  • wework/src/components/chat/MessageList.tsx
  • wework/src/components/chat/blocks/ToolBlocksDisplay.test.tsx
  • wework/src/components/chat/blocks/ToolBlocksDisplay.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • wework/src/components/chat/MessageList.tsx
  • wework/src/components/chat/blocks/ToolBlocksDisplay.tsx
  • wework/src/components/chat/blocks/ToolBlocksDisplay.test.tsx

📝 Walkthrough

Walkthrough

Backend now generates block IDs and timestamps using wall-clock epoch milliseconds; frontend anchors turn start and computes live durations using an explicit isRunning flag, updating UI rendering and adding tests for ticking, anchoring after refresh, and non-interactive running state.

Changes

Duration Timer Fix: Wall-Clock Timestamps and Live Display

Layer / File(s) Summary
Backend wall-clock timestamp generation
backend/app/services/chat/storage/session.py, backend/tests/services/chat/storage/test_session_blocks.py
SessionManager.add_block generates block IDs and timestamps using wall-clock epoch milliseconds (time.time()), replacing event-loop monotonic time; adds a regression test asserting epoch-ms timestamps (> 1e12) and block- IDs with matching numeric suffixes.
Frontend timer display and duration calculation
wework/src/components/chat/MessageList.tsx, wework/src/components/chat/blocks/ToolBlocksDisplay.tsx, wework/src/components/chat/blocks/ToolBlocksDisplay.test.tsx
ToolBlocksDisplay accepts an optional startedAt prop (wired from message createdAt), reanchors duration to the turn start, uses isRunning to decide live vs. locked end times, renders non-interactive summary while running and a toggle when idle, and includes tests verifying timer advancement, anchoring after refresh, and non-interactive running UI.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • wecode-ai/Wegent#1285: Both PRs change backend block timestamp generation from monotonic to wall-clock time.time() to align epoch-milliseconds timing with client duration calculations.

Suggested reviewers

  • qdaxb

Poem

🐰 I nibble ticks taken from the sun,
No more frozen seconds when refresh is done.
Start time held fast, the counter hums true,
Backend writes epoch, frontend counts through.
Hooray — the little timer hops anew!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.22% 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 directly and clearly summarizes the main fixes: correcting the processing duration timer and fixing header interactivity issues in the wework component.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

sifang and others added 2 commits June 10, 2026 12:44
…resh

When a page is refreshed mid-turn, the in-progress blocks live only in
Redis and are not yet persisted to subtask.result, so the DB-restored
turn starts with empty blocks and the resumed stream re-creates thinking
blocks with fresh client timestamps. Anchoring the elapsed time to the
first block therefore restarted the timer from the refresh moment
("已处理 2s 时间了").

Anchor the duration to the assistant subtask's created_at (passed via a
new startedAt prop), which is restored from the backend and preserved by
assistant_started across the reconnect. The timer now reflects the true
elapsed time after a refresh, both while running and once completed.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Resolve conflict in ToolBlocksDisplay: combine the refresh-surviving
duration anchor (startedAt prop -> turnStartedAt) and non-interactive
running header from this branch with main's improved Chinese duration
copy (getDurationText + formatDuration). Reconcile the merged tests to
the unified behavior.
@qdaxb
qdaxb merged commit 7b18516 into wecode-ai:main Jun 10, 2026
22 checks passed
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.

2 participants