feat(timeline): agent response cards + timeline UI unification - #256
Draft
tyreseluo wants to merge 11 commits into
Draft
feat(timeline): agent response cards + timeline UI unification#256tyreseluo wants to merge 11 commits into
tyreseluo wants to merge 11 commits into
Conversation
Design and implement four Octos/agent response-message UI styles in the room timeline (design: docs/superpowers/specs/2026-07-10-agent-message-response-cards.md): - CodeOutputCard (§4.7): dark RBX_CODE_BG syntax-highlighted panel for fenced bot code, plus the dark syntax token set in design_tokens.rs - ApprovalCard (§4.6): amber RBX_WARNING recipe with Pending/Critical badges and a tool/expiry meta line - Streaming indicator (§7): teal LoadingSpinner shown while a reply is live; removes the trailing U+25CF cursor and keeps live streams redrawing so it animates in full-snapshot markdown mode too - AgentMessageCard v1 (§4.5): parsed status -> active StepChip, RBX_* answer card, "Bot" badge, avatar online dot - agent_render_state scaffold (AgentCardKind) + unit tests Also fixes media downloads: the File/Audio/Video download button now routes through the working DownloadAndSaveFile path (was DownloadMediaToFile via get_media_content, which fails on non-ASCII Content-Disposition headers, so only the inline link worked); the redundant inline mxc link is dropped and the button is retinted to RBX_ACCENT. Note: room_screen.rs also carries its share of the RBX design-token unification (message text/rows/@mention/action buttons/notices/thread summary/read-marker/dividers/scrims), bundled here since it is one file. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Migrate the room-timeline off legacy styles.rs COLOR_* / hardcoded hex to the RBX_* design-token system (teal accent), from a parallel UI audit. styles.rs token re-points (one place, many surfaces): - message/username/timestamp text -> RBX_FG_PRIMARY / RBX_FG_TERTIARY - notice + small-state text -> RBX_FG_SECONDARY / RBX_FG_TERTIARY - link hover -> RBX_ACCENT; unread badge -> RBX_ACCENT - link-preview surfaces -> RBX_BG_SURFACE_SUBTLE / RBX_BG_HOVER Shared widgets: - reaction pills: green self-state / yellow hover -> teal RBX_ACCENT(_SOFT) selection chip + RBX_NEUTRAL_BG / RBX_STROKE_SOFT - jump-to-bottom FAB + unread badge -> teal accent - context menu -> RBX surface/scrim/danger tokens - link preview: raw #0000EE link -> RBX_LINK, card chrome -> RBX - (edited) marker: brand purple -> RBX_FG_TERTIARY - inline code/quote bg, mention pill, image placeholder -> RBX inset tokens - tombstone footer, upload progress, read-receipt count -> RBX Visual-only; no logic changes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The base RobrixIconButton still used legacy blue (COLOR_ACTIVE_PRIMARY), so every icon button that doesn't override its color inherited blue. Retint the base to the teal design-token recipe (mirrors SettingsPrimaryButton): - draw_bg color/hover/down -> RBX_ACCENT / RBX_ACCENT_HOVER / RBX_ACCENT_PRESSED - draw_icon / draw_text -> RBX_FG_ON_ACCENT - border_radius 4.0 -> RBX_RADIUS_SM App-wide: all default icon buttons (settings, modals, timeline) are now teal. The RobrixPositive/Negative derived buttons keep their own green/red overrides. Visual-only; no logic changes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Octos ships a purpose-built agent-to-app card channel over Matrix
(`content["org.octos.app"] = {type, version, initial_state}`, designed
for the robrix2 consumer), but robrix was only handling a nonexistent
`org.octos.splash_card` key and never rendered it.
Add a client-side type registry that renders known app types natively and
falls back to the plain message body for unknown/invalid types:
- mission_room: goal + phase badge + task/agent/pending/decision/blocker
lists (tolerant of free-form item shapes); shared org.octos.actions
buttons render below via the existing action_button_row
- weather: location + condition glyph + temperature
The card uses the RBX design tokens (surface + tight radius + accent
badge). Rendered only for full (non-condensed) messages so a condensed
row without the slot never blanks. Supersedes the dead splash_card path.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Extend the org.octos.app renderer (A1) with eight agent-output card types, each dispatched by `type` into the shared octos_app_card slot: tool_call · diff_view · task_tree · pipeline · run_summary · user_question · plan · goal - Colors come from the RBX_* tokens via a new utils::vec4_to_hex helper (→ HTML <font color>), never hardcoded hex. - diff_view mirrors octos DiffPreview; task_tree/plan mirror the task & plan records; goal shows a token-budget bar; run_summary is a per-turn cost/reasoning footer (cost parsed as number-or-string, since Matrix canonical JSON forbids floats). - user_question styles the prompt; its clickable options reuse the existing org.octos.actions button + action_response loop. - Glyphs are restricted to the message font stack's real coverage (IBMPlexSans + LXGWWenKai + NotoColorEmoji) to avoid tofu. Also fix a latent rendering bug: an org.octos.app message is now detected up-front (bot senders only) and forced into the full Message template, so consecutive bot cards no longer collapse into CondensedMessage and fall back to plain body text. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Capture how octos should project runtime UI-protocol events (tool/*, DiffPreview, task/updated, workflow phases, token_cost_update, user_question/requested, plan/updated, session goal) into org.octos.app Matrix cards via a projection bridge — distinct from the LLM-called send_app_card tool. Includes per-type source→initial_state maps and the Matrix-canonical-JSON no-floats constraint. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add two more agent-output cards to the timeline: - artifact (org.octos.app type=artifact) — a list of agent output files, each with a kind glyph, kind/status tail, and optional path. Mirrors octos UiAgentArtifact / TaskArtifactRecord. - swarm_event — octos's OWN wire key org.octos.swarm_event (envelope schema octos.harness.event.v1), which octos already emits into swarm-supervisor rooms. Renders one harness event styled by kind (progress / phase / artifact / validator_result / retry / failure). Detected up-front alongside org.octos.app so it also renders in the full (non-condensed) Message template. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Update the emitter design doc: robrix now renders octos's already-emitted org.octos.swarm_event key, and the swarm progress field (an f64) must be sent as an integer percent — a fractional value fails Matrix canonical JSON, so octos's own swarm_event send 400s otherwise. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Align the agent-response-cards branch with upstream main (15 commits, including #255 Cherry-style message meta band + the makepad fork switch). Conflicts (all in src/home/room_screen.rs) resolved: - Keep both our AgentCardKind scaffold and main's clipboard_text_for_message_body. - bot_badge background -> RBX_ACCENT_SOFT (main) for contrast with the RBX_ACCENT badge label. - Remove our bot_metadata_footer from both message templates: superseded by main's MessageMetaBand / band_metadata; no Rust references the footer widgets. - Streaming branch: keep both the ① streaming indicator and band_metadata = stream_meta. - Keep both the compute_agent_render_state and invite-result unit tests.
- Visual card: org.octos.app type=image/visual/chart embeds an mxc image in the card frame, reusing the native image pipeline (async fetch + viewer). - tool_activity card: a per-turn LIST of tool calls, rendering octos's coalesced tool_activity instead of one tool_call card per tool. - Render fixes: plan/goal glyphs restricted to the message font stack's real coverage (ballot/shade chars were tofu -> check/half/open circle + blocks); inline <code> now uses a CJK-capable font so Chinese in code isn't tofu; plan items also accept a `description` field (octos update_plan / Codex shape). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ls card Merge the per-turn tool_call / tool_activity / run_summary cards into a single `org.octos.run` run detail, rendered as a collapsible strip BELOW the bot answer (keeping the bot card) instead of as separate replacement cards. The superseded render fns are kept for backward-compat with already-sent messages. - Add expand/collapse toggle + per-event expanded state that survives PortalList virtualization (`expanded_octos_card_event_ids`, `toggle_octos_card_expanded`). - `populate_octos_app_card` gains `collapsible` / `expanded` / `keep_bot_card`. - `render_run_details_app_card`: collapsed "N tools" summary (+ "M failed" badge), expands to per-tool ✓/✗ list with truncated errors and a token/cost footer folded in from run_summary. - Clear a stale typing notice locally once a message row is appended (appservice bots can lag the typing=false EDU). - Robustness: char-boundary slice in `format_approval_expiry`, `saturating_add` on attacker-supplied token totals, depth cap in `count_task_states` to match the rendered tree, independent diff-truncation notices. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
tyreseluo
marked this pull request as draft
August 5, 2026 06:31
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.
Summary
Adds a full agent-response card system to the timeline for Octos AI-agent output, and unifies the timeline widgets onto the
RBX_*design tokens.Octos agent output now renders as native, structured cards instead of plain text bubbles. All cards ride the single
org.octos.appwire channel (dispatched bytypeinrender_octos_app_card), with graceful fallback to body text for unknown types.Card renderers
tool_call/tool_activitydiff_viewtask_treepipelinerun_summaryuser_questionorg.octos.actionsloop)plangoalartifactimage/visual/chartmxc://image + captionweather/mission_roomswarm_eventorg.octos.swarm_eventkey)Card colors come from the
RBX_*tokens via a newutils::vec4_to_hex(→ HTML<font color>); glyphs are restricted to the message font stack's real coverage; costs parse as number-or-string (Matrix canonical JSON forbids floats).UI unification
Migrates the timeline widgets (reactions, link preview, context menu, jump-to-bottom, edited indicator, streaming, tombstone, upload progress,
RobrixIconButton, read receipts) onto the semanticRBX_*design tokens (tealRBX_ACCENTprimary). Adds dark code-syntax tokens.Notable fixes
org.octos.appcard is now detected up-front and forced into the fullMessagetemplate, so consecutive bot cards no longer collapse intoCondensedMessageand fall back to plain body text.<code>: uses a CJK-capable code font so Chinese in code isn't tofu.Docs
Adds the agent-message-response-cards design doc + task spec, and an octos-side emitter design note.
Related
The octos-side emitter (which auto-projects runtime events → these cards over Matrix) is a separate change on the octos repo (branch
feat/matrix-app-card-emitter), auto-emittingtool_activity · plan · run_summary · artifact · diff_view, all coalesced per turn.Testing
Builds green; merged with latest
main(6 conflicts resolved); unit tests pass. Cards verified end-to-end against a local Octos gateway.🤖 Generated with Claude Code