Skip to content

feat(web): store turn trajectories and add a download button - #26

Merged
Rikul merged 2 commits into
mainfrom
claude/brave-allen-wjm7p2
Oct 21, 2026
Merged

Rikul merged 2 commits into
mainfrom
claude/brave-allen-wjm7p2

Conversation

@Rikul

@Rikul Rikul commented Oct 21, 2026

Copy link
Copy Markdown
Owner

Each agent turn (CLI and channel bots) is now saved to a new
trajectories table, keyed by the turn's final assistant message: the
system prompt, the turn's messages (tool calls, tool results, reasoning;
attachment data redacted) and per-call model, latency and token usage.

The web UI shows a "Download trajectory" button under the copy button
on replies that have one, served by GET /api/messages//trajectory.
Live replies get it from a new trajectory WebSocket frame sent after
the turn's last reply. Delete removes trajectories; fork copies them.

Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01B5eEVdQmx7huUwhT375FY7

Each agent turn (CLI and channel bots) is now saved to a new
`trajectories` table, keyed by the turn's final assistant message: the
system prompt, the turn's messages (tool calls, tool results, reasoning;
attachment data redacted) and per-call model, latency and token usage.

The web UI shows a "Download trajectory" button under the copy button
on replies that have one, served by GET /api/messages/<id>/trajectory.
Live replies get it from a new `trajectory` WebSocket frame sent after
the turn's last reply. Delete removes trajectories; fork copies them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B5eEVdQmx7huUwhT375FY7
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review 🔄 Running since 2026-10-21T00:34:06.905631Z 46dfeec PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@Rikul
Rikul requested a balanced review from Copilot October 21, 2026 07:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@Rikul Rikul left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 46dfeec (single commit). I ran the full suite on the PR head: 460 passed. The trajectory frame ordering holds, and the migration is safe for existing databases. I found one live-path bug, reproduced below, plus a few smaller points.

Main finding: a failed save still shows a download button. _save_trajectory swallows its own errors, but BackgroundAgent.agent_loop then sends the trajectory frame unconditionally. I reproduced this with the save mocked to raise RuntimeError("disk full"): the reply is delivered and on_trajectory_saved is still awaited. The browser then attaches a download button, and clicking it gets a 404 from _trajectory_api. Suggested fix: have _save_trajectory return a bool and only call on_trajectory_saved when it returns True.

Comment thread app/core/background_agent.py Resolved
Comment thread app/core/agent.py Resolved
Comment thread app/channels/frontend/app.js Resolved
Comment thread tests/test_web_channel.py Resolved
- _save_trajectory returns whether it stored anything; BackgroundAgent
  only sends the trajectory frame when it did, so a failed save no
  longer shows a button that 404s.
- The turn's reply is sent with metadata "final" (web frames carry
  `final: true`); app.js attaches the trajectory button only to that
  row, so a stopped or empty turn never puts it on a status line.
- Tests run a real turn through BackgroundAgent and WebChannel and check
  the frames a tab receives (reply marked final, trajectory frame after
  it, none after a failed save, no final frame for a stopped turn).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B5eEVdQmx7huUwhT375FY7
@Rikul
Rikul merged commit f1d5019 into main Oct 21, 2026
2 checks passed
@Rikul
Rikul deleted the claude/brave-allen-wjm7p2 branch October 21, 2026 20:48
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.

3 participants