Fix ACP conversation reload message ordering#1353
Conversation
Co-authored-by: openhands <openhands@all-hands.dev>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
✅ Mock-LLM E2E Tests54/54 passed Commit:
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses) |
✅ Mock-LLM Docker E2E Test Results54/54 passed Commit:
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses) |
Co-authored-by: openhands <openhands@all-hands.dev>
|
PR Artifacts Notice This PR contains a
|
✅ Mock-LLM E2E Tests54/54 passed Commit:
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses) |
✅ Mock-LLM Docker E2E Test Results54/54 passed Commit:
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses) |
HUMAN:
AGENT:
This PR was created by an AI agent (OpenHands) on behalf of the user.
Automated verification completed:
npm test -- --run __tests__/stores/use-event-store.test.ts __tests__/contexts/conversation-websocket-context.test.tsxnpm run typechecknpm run lintnpm run buildSCENARIO_OUTPUT=/tmp/acp-reload-main.json npx vitest run .tmp-acp-reload-scenario.test.tsonmainandSCENARIO_OUTPUT=/tmp/acp-reload-fixed.json npx vitest run .tmp-acp-reload-scenario.test.tsonfix-acp-reload-streaming-events; screenshots/GIF generated from those branch outputs and committed under.pr/.Why
Fixes #1352. ACP reloads can lose in-progress assistant text because REST-preloaded history may not include ACP streaming deltas, while the websocket subscription resumed after the latest REST event and skipped those replayable deltas. Separately, rebuilding history by sorting
uiEventsdirectly could move ACP terminal tool-call cards to completion time instead of keeping them where the started card originally appeared.Summary
uiEvents, preserving reducer semantics for ACP tool-call replacement and final-message reconciliation.Issue Number
Fixes #1352
How to Test
Run:
npm test -- --run __tests__/stores/use-event-store.test.ts __tests__/contexts/conversation-websocket-context.test.tsx npm run typecheck npm run lint npm run buildI do not have a live Codex/ACP credentialed session in this environment, so I verified the reload behavior with targeted store/provider regressions plus typecheck, lint, and production build.
Video/Screenshots
Live branch replay evidence (generated from the event store running once on
mainand once on this fixed branch):Before on
main— partial streamed ACP text appears above the tool and the full final message moves below it:After on
fix-acp-reload-streaming-events— the final suffix is reconciled back into the original streamed message, preserving the tool position:Type
Notes
The ACP websocket replay may resend already-preloaded events from the latest user message; the event store de-duplicates persisted event IDs and re-derives UI events after out-of-order backfill.
🐳 Docker images for this PR
• GHCR package: https://github.com/OpenHands/agent-canvas/pkgs/container/agent-canvas
ghcr.io/openhands/agent-canvasghcr.io/openhands/agent-server:1.28.1-pythonopenhands-automation==1.0.0a97f16ea8f0787df9223abe665dbd1c6ede061178bPull (multi-arch manifest)
# Multi-arch manifest — Docker automatically pulls the correct architecture docker pull ghcr.io/openhands/agent-canvas:sha-7f16ea8Run
All tags pushed for this build
About Multi-Architecture Support
sha-7f16ea8) is a multi-arch manifest supporting both amd64 and arm64sha-7f16ea8-amd64) are also available if needed