feat(agent_panel): unified agent panel 2b — view shell (merged list + transcript + composer)#209
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Implements sub-phase 2b of the unified agent panel by adding a new feature-flagged AgentPanelView surface that combines a merged conversation list (CLI + migrated daemon conversations), the shared agent_transcript renderer, and a composer shell, with workspace wiring (action, keybinding, menu item) to toggle it.
Changes:
- Add
FeatureFlag::UnifiedAgentPanelplusagent_panel::feature_flag::is_enabled()gating. - Introduce
app/src/agent_panel/AgentPanelViewwith split render helpers (header / list / transcript / composer) and basic layout-safety tests. - Wire workspace registration (panel handle + toggle action + keybinding + menu item), and hook daemon stream-history migration into
ChatModel::newbootstrap.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| script/check_cli_chat_boundary | Extends fork-local boundary checks to include app/src/agent_panel. |
| crates/warp_features/src/lib.rs | Adds FeatureFlag::UnifiedAgentPanel. |
| app/src/lib.rs | Registers the new agent_panel module (non-wasm). |
| app/src/app_menus.rs | Adds menu item to toggle the unified agent panel when enabled. |
| app/src/util/bindings.rs | Adds CustomAction::ToggleUnifiedAgentPanel default keystroke mapping (cmd/ctrl-shift-U). |
| app/src/workspace/action.rs | Adds WorkspaceAction::ToggleUnifiedAgentPanel and marks it as non-blocking for restart flows. |
| app/src/workspace/mod.rs | Registers the editable binding/action for toggling the unified agent panel (flag-gated). |
| app/src/workspace/util.rs | Adds persisted workspace state bit is_agent_panel_open. |
| app/src/workspace/view.rs | Constructs/renders the unified agent panel in the right dock and handles the toggle action. |
| app/src/cli_chat/model.rs | Runs daemon stream-history.json migration at ChatModel bootstrap before loading history. |
| app/src/cli_chat/model_tests.rs | Adds test ensuring migrated daemon conversations surface on model bootstrap. |
| app/src/agent_panel/feature_flag.rs | Adds convenience accessor for UnifiedAgentPanel enablement. |
| app/src/agent_panel/mod.rs | Adds AgentPanelView (holds ChatModel + composer input) and panel layout composition. |
| app/src/agent_panel/strings.rs | Adds user-facing strings for the unified agent panel and backend badges. |
| app/src/agent_panel/view/mod.rs | Declares render helper modules for the unified agent panel. |
| app/src/agent_panel/view/header.rs | Implements header label + “New chat” button. |
| app/src/agent_panel/view/conversation_list.rs | Implements merged conversation list with backend badges and row click behavior. |
| app/src/agent_panel/view/transcript.rs | Renders transcript via agent_transcript, with empty-state + skipped-event hinting. |
| app/src/agent_panel/view/composer.rs | Implements composer shell (active only for live CLI binding in 2b). |
| app/src/agent_panel/view_tests.rs | Adds basic tests (badge mapping + layout non-panicking render). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+111
to
+115
| .on_click(move |ctx, _, _| { | ||
| ctx.dispatch_typed_action(WorkspaceAction::OpenChatSession { | ||
| session_id: session_id.clone(), | ||
| }); | ||
| }) |
Comment on lines
+63
to
+70
| if let Some(conv) = conv { | ||
| let agent_name = conv.backend.display_name(); | ||
| let model_name = conv | ||
| .last_model | ||
| .as_deref() | ||
| .unwrap_or(conv.backend.agent_kind().curated_models()[0].display_name); | ||
| format!("{} \u{2014} {}", agent_name, model_name) | ||
| } else { |
Comment on lines
+99
to
+112
| impl View for AgentPanelView { | ||
| fn ui_name() -> &'static str { | ||
| "AgentPanelView" | ||
| } | ||
|
|
||
| fn render(&self, app: &AppContext) -> Box<dyn Element> { | ||
| let header = view::header::render(self, app); | ||
| let list = view::conversation_list::render_list(self, app); | ||
| let transcript = view::transcript::render_panel(self, app); | ||
| let composer = view::composer::render_composer(self, app); | ||
|
|
||
| // Right column: transcript (flex-expanded) + composer pinned at bottom. | ||
| let right_column = Flex::column() | ||
| .with_main_axis_size(MainAxisSize::Max) |
This was referenced Jul 18, 2026
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.
Description
What: Implements sub-phase 2b of the unified agent panel (plan in #206) — a new, feature-flagged
app/src/agent_panel/AgentPanelView: a merged conversation list (CLI + Coven-daemon, each badged) + the sharedagent_transcripttranscript + a composer shell — reachable viacmd-shift-U/ctrl-shift-U. The two existing panels are left untouched.Why: After 2a (#205) unified the conversation data model, this gives it a single surface. It's the view shell that 2c (composer routing + live daemon source) and 2d (default entry point + deprecation) build on.
How:
FeatureFlag::UnifiedAgentPanel+agent_panel::feature_flag::is_enabled.AgentPanelView(mirrorscli_chat::ChatPanelView: holds the singletonChatModel+ aSubmittableTextInput), with self-contained render helpers (view/{header,conversation_list,transcript,composer}.rs) that depend only on thecli_chatmodel layer + the sharedagent_transcriptrenderer — nevercli_chat::view(which 2d deletes). List rows carry a backend badge (CLI/Coven).migrate_stream_history_file(from 2a) is wired intoChatModel::newbootstrap, so migratedcoven-codedaemon conversations join the merged list.ToggleUnifiedAgentPanelaction + handler, keybinding, and menu item.check_cli_chat_boundaryextended to coverapp/src/agent_panel.Scope boundary (deferred): the composer is a shell — active for a live CLI conversation (submits via the existing
WorkspaceAction::SubmitChatPrompt→ terminal PTY), disabled placeholder otherwise. Per-backend routing + the live daemon send/stream + the daemon conversation source are 2c; deleting the old panels / making this the default is 2d.Linked Issue
Implements the 2b plan (#206). Continues the reconciliation roadmap (design #204; 2a #205; Phase 1 #201).
Testing
cargo nextest run -p warp-app --features cast-agent— newagent_paneltests (backend badge;AgentPanelViewlayout-safety viawith_model+ an unwired in-memory model) + acli_chatbootstrap test (migrated daemon conversation surfaces in the model), plus the full pre-existingcli_chat/agent_transcriptsuites unchanged.cargo check -p warp-app --bin cast-codes --features gui,cast-agentlinks (full workspace/menu/keybinding wiring).cargo clippy -p warp-app --features cast-agent --all-targets -- -D warningsclean;cargo fmt -- --checkclean../script/check_cli_chat_boundary(now coveringagent_panel),./script/check_ai_attribution,./script/check_rebrandpass.Agent Mode