Skip to content

feat(seer): add the agent conversation embeds - #123908

Draft
billyvg wants to merge 9 commits into
masterfrom
claude/seer-embed-conversation
Draft

feat(seer): add the agent conversation embeds#123908
billyvg wants to merge 9 commits into
masterfrom
claude/seer-embed-conversation

Conversation

@billyvg

@billyvg billyvg commented Sep 9, 2026

Copy link
Copy Markdown
Member

Adds two Seer markdown embeds for Explore > Agents:

  • conversation — one AI agent conversation. Inline renders a link; block renders the transcript with its LLM call, token, cost and tool totals.
  • conversationsQuery — the conversations list filtered by a search. Inline renders a link; block previews the first five matching rows with duration, message count, errors and cost.

Both are gated on organizations:gen-ai-conversations, which already exists in temporary.py, so neither reaches the agent until an org has it.

The last of four independent branches adding single-resource Seer embeds — see also #123901 (profile), #123905 (event) and #123906 (log). They all touch schemas.ts, index.ts, the stories page and the generated widget JSON, so whichever merges first leaves the rest needing a rebase plus a pnpm gen:embed-widgets re-run.

Notes for review

Both blocks avoid the route-level machinery, because it is URL-coupled and an embed must not touch the host page's history (embeds/README.md):

  • The list block builds its own query rather than using useConversations, which takes no arguments and reads cursor/filters through nuqs.
  • The transcript composes MessagesPanel + ConversationAggregatesBar directly rather than ConversationViewContent, which writes its tab and detail-tab state back to the URL. Message selection is local useState, with a test asserting the router never changes.

Two shape details worth a look:

  • Content flattening. useConversations normalizes firstInput/lastOutput before handing rows out, but the raw endpoint returns string | {type, text}[] | null. Since the block calls the endpoint directly, it flattens them itself, then strips markdown to a single line for the cell.
  • The agent filter lives in two places. The list view keeps it in its own agent URL param and folds it into the span query only when calling the API. The link mirrors the former, the block the latter, so both are filtered identically.

Ordering also differs: the endpoint returns by relevance, and the list view sorts newest-first before rendering, so the preview re-sorts to match.

Testing

10 tests across both embeds — inline hrefs and their padded time windows, the transcript, aggregates, API-title-wins-over-tag-title, selection staying local, the error state, the row preview with ordering and formatting, content-part flattening, and the empty state. The whole seer/markdown suite passes; oxlint and oxfmt are clean, and pnpm gen:embed-widgets produces no diff.

🤖 Generated with Claude Code

https://claude.ai/code/session_016YUmhMZLo8geXJa93daPEQ


Generated by Claude Code

@github-actions github-actions Bot added Scope: Frontend Automatically applied to PRs that change frontend components Scope: Backend Automatically applied to PRs that change backend components labels Sep 9, 2026
The generic `<EmbedStory name="conversation" />` renders the schema's
hardcoded example id, which resolves to nothing in a real org, so the
storybook entry showed an empty transcript.

Fetch a recent conversation from the agents conversations list instead
and feed its id, title and time bounds into the tag -- the same pattern
the monitor, replay, trace and saved issue view embeds already use.

Claude-Session: https://claude.ai/code/session_01DwM6SuBXUTSXciHNCM59iR
@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Story previews

Preview the stories changed in this PR on the Vercel deployment:

Preview deployment: https://sentry-6texhaknz.sentry.dev

Three changes to the conversation embeds:

The conversation block dropped its transcript. The embed renders inside
an agent conversation, so a nested transcript reads as part of the
surrounding answer; the LLM call, token, cost and error totals say what
the reader needs, and the link goes to the full detail view. Message
selection went with it, so the block is no longer interactive at all.

The conversationsQuery rows now link to their conversations, through the
same `getConversationHref` the conversation embed uses. They open in a
new tab so following one cannot replace the page holding the answer.

Layout now matches the other embeds: `conversationsQuery` is flat in
`components/` like every other query embed, `conversation/` keeps the
single-resource embed like `monitor/` and `alert/`, each embed has its
own colocated spec, and sibling imports are relative.

Claude-Session: https://claude.ai/code/session_01DwM6SuBXUTSXciHNCM59iR
knip flagged it as an unused export: only `ConversationsQueryLink`, in
the same file, calls it. `getConversationHref` stays exported -- the
query block imports it for its row links.

Claude-Session: https://claude.ai/code/session_01DwM6SuBXUTSXciHNCM59iR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant