Skip to content

Conversation

@xingyaoww
Copy link
Collaborator

@xingyaoww xingyaoww commented Nov 24, 2025

Description

Fixes #1228

This PR fixes a bug where conversation stats (including context_window) were being reset to 0 when ConversationStatusUpdateEvent (full_state) was sent after resuming a conversation.

Root Cause

In ConversationState.create(), line 189 was resetting stats after loading them from persisted storage. The sequence was:

  1. Stats were properly deserialized from base_state.json
  2. But then immediately overwritten with ConversationStats() (empty)
  3. This triggered autosave, storing empty stats back to disk

When the full_state event was later sent, it included these empty stats, causing context_window and all other metrics to show as 0.

Solution

Removed the line that resets stats on conversation resume. Stats loaded from persistence are now preserved, maintaining all accumulated metrics including:

  • context_window
  • prompt_tokens
  • completion_tokens
  • accumulated_cost
  • All other usage metrics

Testing

Added comprehensive tests in test_stats_persist_on_resume.py to verify:

  • ✅ Stats are properly persisted when manually saved
  • ✅ Stats are correctly restored on conversation resume
  • ✅ Full_state events include stats with correct context_window values
  • ✅ Token usage and costs are preserved across resume

All existing tests continue to pass.

Changes

  • Modified: openhands-sdk/openhands/sdk/conversation/state.py
    • Removed stats reset on line 189 (resume path)
    • Added explanatory comment about why stats should not be reset
  • Added: tests/sdk/conversation/local/test_stats_persist_on_resume.py
    • 3 comprehensive tests covering stats persistence and resume scenarios

Co-authored-by: openhands openhands@all-hands.dev

@xingyaoww can click here to continue refining the PR


Agent Server images for this PR

GHCR package: https://github.com/OpenHands/agent-sdk/pkgs/container/agent-server

Variants & Base Images

Variant Architectures Base Image Docs / Tags
java amd64, arm64 eclipse-temurin:17-jdk Link
python amd64, arm64 nikolaik/python-nodejs:python3.12-nodejs22 Link
golang amd64, arm64 golang:1.21-bookworm Link

Pull (multi-arch manifest)

# Each variant is a multi-arch manifest supporting both amd64 and arm64
docker pull ghcr.io/openhands/agent-server:cc5d761-python

Run

docker run -it --rm \
  -p 8000:8000 \
  --name agent-server-cc5d761-python \
  ghcr.io/openhands/agent-server:cc5d761-python

All tags pushed for this build

ghcr.io/openhands/agent-server:cc5d761-golang-amd64
ghcr.io/openhands/agent-server:cc5d761-golang_tag_1.21-bookworm-amd64
ghcr.io/openhands/agent-server:cc5d761-golang-arm64
ghcr.io/openhands/agent-server:cc5d761-golang_tag_1.21-bookworm-arm64
ghcr.io/openhands/agent-server:cc5d761-java-amd64
ghcr.io/openhands/agent-server:cc5d761-eclipse-temurin_tag_17-jdk-amd64
ghcr.io/openhands/agent-server:cc5d761-java-arm64
ghcr.io/openhands/agent-server:cc5d761-eclipse-temurin_tag_17-jdk-arm64
ghcr.io/openhands/agent-server:cc5d761-python-amd64
ghcr.io/openhands/agent-server:cc5d761-nikolaik_s_python-nodejs_tag_python3.12-nodejs22-amd64
ghcr.io/openhands/agent-server:cc5d761-python-arm64
ghcr.io/openhands/agent-server:cc5d761-nikolaik_s_python-nodejs_tag_python3.12-nodejs22-arm64
ghcr.io/openhands/agent-server:cc5d761-golang
ghcr.io/openhands/agent-server:cc5d761-java
ghcr.io/openhands/agent-server:cc5d761-python

About Multi-Architecture Support

  • Each variant tag (e.g., cc5d761-python) is a multi-arch manifest supporting both amd64 and arm64
  • Docker automatically pulls the correct architecture for your platform
  • Individual architecture tags (e.g., cc5d761-python-amd64) are also available if needed

This fixes issue #1228 where conversation stats (including context_window)
were being reset to 0 when ConversationStatusUpdateEvent (full_state) was sent
after resuming a conversation.

Root cause: In ConversationState.create(), line 189 was resetting stats after
loading them from persisted storage. This happened because:
1. Stats were properly deserialized from base_state.json
2. But then immediately overwritten with empty ConversationStats()
3. This triggered autosave, storing empty stats back to disk

The fix removes the line that resets stats on resume, preserving all
accumulated metrics including context_window, prompt_tokens, costs, etc.

Added comprehensive tests to verify:
- Stats are properly persisted when manually saved
- Stats are correctly restored on conversation resume
- Full_state events include stats with correct context_window values

Co-authored-by: openhands <openhands@all-hands.dev>
@openhands-ai
Copy link

openhands-ai bot commented Nov 25, 2025

Looks like there are a few issues preventing this PR from being merged!

  • GitHub Actions are failing:
    • Run tests

If you'd like me to help, just leave a comment, like

@OpenHands please fix the failing actions on PR #1244 at branch `openhands/fix-context-window-on-resume`

Feel free to include any additional details that might help me get this PR into a better state.

You can manage your notification settings

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.

Context Window Displays as 0 When Sending ConversationStatusUpdateEvent (Full State)

4 participants