fix(replay): unify step indexing, dual-index entity deduplication, and prevent step-4 start bug
- Backend: maintain _step_number_cache in DataEngine and include step_number in all step_updated SSE events (summary, thinking, execution result) - Admin console: query unassigned trace step_ids in stepless_rows to prevent orphan traces from being lost - Showcase UI: implement dual-indexed entity deduplication (by step_id and step_number) in extractStepReplayFrames to eliminate phantom ghost steps - Showcase UI: filter visual screenshot steps before generating sequential 1-based frame numbers, preventing step-4 start and index shift bugs - Showcase UI: add rawStepNumber and summary properties to StepReplayFrame - Showcase UI: update FloatingVideoPlayerComponent session reset effect to only reset playback on sessionId change rather than on every stepFrames mutation - Showcase UI: add stepSeekRequest signal and stepIndex parameter to AgentService.openVideoPlayer - Unit tests: add Karma and Pytest unit tests verifying step 1 start, dual-indexing, and SSE step_number payloads
This commit is contained in:
1 parent
5f1ee18bc1
commit
60312abbb0
8 files changed
+384
-91
No files matched your search
@@ -326,3 +326,40 @@ def test_resumed_session_monotonic_step_numbering(tmp_path):
|
||||
assert len(steps) == 3
|
||||
assert [s.step_number for s in steps] == [1, 2, 3]
|
||||
|
||||
|
||||
def test_update_step_summary_includes_step_number_in_sse(tmp_path):
|
||||
mock_ctx = MagicMock(spec=ArtemisContext)
|
||||
mock_execution_setup = MagicMock()
|
||||
mock_execution_setup.traces_path = str(tmp_path)
|
||||
mock_ctx.execution_setup = mock_execution_setup
|
||||
mock_ctx.device = None
|
||||
|
||||
published_events = []
|
||||
|
||||
def mock_subscriber(event_type, data):
|
||||
published_events.append((event_type, data))
|
||||
|
||||
engine = DataEngine(mock_ctx)
|
||||
engine.subscribe(mock_subscriber)
|
||||
sid = engine.start_session("SSE step_number verification")
|
||||
|
||||
step_id = engine.record_step(summary="Initial step 1")
|
||||
for t in list(engine._pending_threads):
|
||||
t.join()
|
||||
|
||||
assert engine.get_step_number(step_id) == 1
|
||||
|
||||
# Call update_step_summary
|
||||
engine.update_step_summary(step_id, "Updated concise summary for Step 1")
|
||||
for t in list(engine._pending_threads):
|
||||
t.join()
|
||||
|
||||
# Find the published step_updated event
|
||||
step_updated_events = [e for e in published_events if e[0] == "step_updated"]
|
||||
assert len(step_updated_events) >= 1
|
||||
last_update = step_updated_events[-1][1]
|
||||
assert last_update["step_id"] == str(step_id)
|
||||
assert last_update["summary"] == "Updated concise summary for Step 1"
|
||||
assert last_update["step_number"] == 1
|
||||
|
||||
|
||||
Reference in new issue
Block a user