Show a run's execution timeline, and follow it live - #21
Merged
Merged
Conversation
A host that advertises agents.history records what a run did as it ran -- observation start and end, turns, model and tool calls with their timing, tool outcomes by status and size, and the sequences the collector did not see -- and the console showed none of it. Every opened run now carries an Execution timeline below its results, one numbered entry per retained position, read the way the standalone SDK reads it: every field checked, positions contiguous, the cursor naming its page, the model binding matching the saved plan, and an entry that carries any field beyond metadata withheld with an alert rather than shown. Positions removed by retention are named. Load more reads the next page from the host's cursor. Follow live opens the text/event-stream route from the last cursor, sending it as the query and as Last-Event-ID; a page is accepted only when the frame's id names it; the host's end frame closes an observation window, and the console reconnects from the cursor while the run is active, stopping and saying so after three windows without a new event, when the run is no longer active, or when the collector records that observation finished. An error frame is a refusal with the host's fixed reason. Nothing here restarts a run or calls a model. history.ts holds the page and event parsers and the plain-words description of each entry; history-stream.ts reads frames; the API client gains historyStream with the same secure request shape as the conversation stream; the capability is agents.history. Nine unit tests cover the parsers, descriptions, refusals, retention disclosure, frame reading and resumption; the API client test checks the headers, cursor validation and non-SSE refusal; four browser journeys (desktop and mobile) show the timeline, follow it to the collector's end, withhold a leaking entry, and offer no timeline without the capability. 28 native journeys and 519 unit tests pass; typecheck and build are clean. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012aNJobunWMPFEa8mjsFQqY
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
When the host advertises
agents.history(native PR #94's replay + SSE routes), every opened run shows an Execution timeline below its results: one numbered entry per retained position — observation start/end, turns, model and tool calls with timing, tool outcomes by status and size, and the sequences the collector did not see. Prompts, tool arguments, answers and reasoning are never in these events; an entry carrying any other field is withheld with an alert, not shown. Retention-removed positions are named./v1/agent-runs/{id}/history?limit=50&after=)./history/streamfrom the last cursor (query +Last-Event-ID), accepts a page only when the SSEidnames it, reconnects from the cursor while the run is active when the host closes an observation window, and stops — saying so — after three windows without a new event, when the run is no longer active, or when the collector records observation finished.errorframes surface the host's fixed reason. Nothing restarts a run or calls a model.Files:
src/agents/history.ts(parsers +describeEntry),src/agents/history-stream.ts(frame reader),src/agents/HistoryTimeline.tsx,ApiClient.historyStream, capabilityagents.history, README.Verification
tests/agent-history.test.ts(9): page reading and descriptions; operations/tool outcomes described without content; refusals (space/run, continuity, extra field, binding, digest, route, collection identity, unavailable, cursor); unavailable page; retention disclosure (omitted exactness, generation); frames page-by-page with keep-alives toend; id mismatch, error frame, cut mid-frame, foreign page, unknown event; resume continuity; capability parsing. Five rules mutation-checked (id names page, retention continuity, binding, position continuity, generation) — each flips the suite to failing.tests/api.test.ts(+1): cursor both ways, noLast-Event-IDwithout a cursor, bad ids/cursor/limits rejected before any request, non-SSE and redirect refused, 401 expires the session.scripts/test-agents.cjs(+4 journeys, desktop + mobile): timeline renders three recorded entries, Follow live resumes from position 3 and reaches the collector's end with no private text on the page and no horizontal scroll; a leaking entry is withheld; no capability → no timeline. 28/28 native journeys (Playwright 1.57, cached Chromium 1200), 519 unit tests,tscandvite buildclean.🤖 Generated with Claude Code
https://claude.ai/code/session_012aNJobunWMPFEa8mjsFQqY