7.4 KiB
REMOTE-1674: Tech Spec — Agent view entry for web-started 3p harness shared sessions
Context
REMOTE-1674 makes live shared-session viewers enter agent view for third-party harness conversations started outside the Warp desktop flow, such as from the web. This extends the REMOTE-1459 viewer-entry work to cases where the desktop viewer may not have an AmbientAgentViewModel with a resolved harness yet.
Linear: https://linear.app/warpdotdev/issue/REMOTE-1674/make-sure-that-we-enter-the-agent-view-for-3p-harness-conversations
Current relevant flow:
app/src/terminal/shared_session/shared_handlers.rs (356-435)applies remoteCLIAgentSessionState. It creates a pane-scopedCLIAgentSession, shows the CLI agent footer, manages rich input, and now has enough signal to infer a 3p harness even without an ambient model.app/src/terminal/shared_session/viewer/event_loop.rs (184-259)processes ordered viewer terminal events.CommandExecutionStartedinserts the remote command into the viewer terminal model, then the viewer can sync agent view around that newly started block.app/src/terminal/shared_session/viewer/terminal_manager.rs (686-766)applies the initialuniversal_developer_input_contextbefore callingenter_viewing_existing_session, so CLI-agent state can arrive before the ambient model has the task harness.app/src/terminal/view/ambient_agent/model.rs (816-861)fetches the ambient task, readsagent_config_snapshot.harness, callsset_harness, and emitsViewerHarnessUpdatedafter the server-resolved harness is applied.app/src/terminal/view/ambient_agent/view_impl.rs (291-315)handlesViewerHarnessUpdatedby syncing agent view, updating pane configuration, and notifying the view.app/src/terminal/view/ambient_agent/view_impl.rs (489-565)owns the shared 3p viewer sync helper. It checksis_third_party_cloud_agent_viewer, enters agent view withAgentViewEntryOrigin::ThirdPartyCloudAgentonly if not already active, then retags existing blocks and rich content onto the vehicle conversation.app/src/terminal/model/terminal_model.rs (1426-1444)identifies shared ambient-agent sessions viaSessionSourceType::AmbientAgent.app/src/terminal/cli_agent_sessions/mod.rs (289-315)stores pane-scoped CLI agent sessions. A session on a shared ambient viewer is the fallback signal for a web-started 3p harness.app/src/terminal/model/block.rs (1405-1435)hides blocks in fullscreen agent view unless theirAgentViewVisibilityincludes the active conversation.app/src/terminal/model/blocks.rs (1586-1621)tags the current unfinished block when agent view activates,app/src/terminal/model/blocks.rs (1666-1694)attaches existing non-startup blocks to a conversation, andapp/src/terminal/model/blocks.rs (2545-2588)tags newly-created blocks with the active conversation.app/src/terminal/view/agent_view.rs (374-396)retags rich content with an agent-view conversation id.
Implementation
Shared 3p viewer entry is centralized in TerminalView::sync_agent_view_for_shared_third_party_viewer.
The helper:
- Detect a 3p harness with
is_third_party_cloud_agent_viewer. This checks bothAmbientAgentViewModel::is_third_party_harness()andCLIAgentSessionsModel::session(view_id).is_some()to determine if we are in a 3p harness convo. The former gets set when we receive task data from the server, the latter is set when we receive join info in a shared session that contains an actively running CLIAgent. - Require
is_shared_ambient_agent_session()so local harness picker changes do not enter agent view. - Enter agent view only when not already active, using
AgentViewEntryOrigin::ThirdPartyCloudAgent. - Return immediately with the active conversation id if the viewer is already in agent view. This keeps duplicate sync calls cheap.
- Return the active vehicle conversation id for tests and idempotency checks.
- On first entry, retag non-startup terminal blocks via
attach_non_startup_blocks_to_conversation. - On first entry, retag terminal-mode rich content with no conversation id via
set_rich_content_agent_view_conversation_id.
Call the helper from three signal points:
ViewerHarnessUpdatedinapp/src/terminal/view/ambient_agent/view_impl.rs (305-315)for the desktop live-viewer path where the ambient model resolves the harness asynchronously. This event fires afterenter_viewing_existing_sessionfetches task config, even whenset_harnessis a no-op because the local harness already matches the server harness.apply_cli_agent_state_updateinapp/src/terminal/shared_session/shared_handlers.rs (356-435)for web-started or otherwise pre-harness viewer paths where the remote side broadcasts a CLI agent session.CommandExecutionStartedinapp/src/terminal/shared_session/viewer/event_loop.rs (184-259)after the viewer model starts the block, so late-arriving command blocks are attached to the vehicle conversation immediately.
This keeps the implementation local to viewer synchronization. It does not change transcript viewer entry, Oz harness behavior, CLI agent serialization, or shared-session protocol fields.
Testing and validation
Unit tests in app/src/terminal/view_tests.rs (922-1139) cover the important invariants:
shared_third_party_viewer_sync_enters_agent_view_and_retags_existing_blockverifies a shared ambient viewer with an ambient model andHarness::Claudeenters agent view, is idempotent, usesThirdPartyCloudAgent, and keeps the existing harness block visible.shared_third_party_viewer_syncs_from_viewer_harness_updated_when_harness_unchangedverifiesViewerHarnessUpdatedenters agent view and retags the harness block even whenset_harnessdoes not emitHarnessSelectedbecause the harness is unchanged.shared_third_party_viewer_syncs_from_cli_agent_state_without_ambient_modelverifies a plain terminal viewer with shared ambient session metadata enters agent view afterapply_cli_agent_state_update, even with no ambient model. Additional validation:cargo test -p warp shared_third_party_viewer_sync --libpasses.- Manually start a Claude/Codex/Gemini cloud task from web, open the desktop shared-session viewer, and confirm it lands in agent view with the harness block visible.
- Repeat a desktop-started 3p shared-session viewer to ensure the
ViewerHarnessUpdatedpath works. - Repeat an Oz shared-session viewer to confirm no new 3p sync path activates.
- Confirm a non-shared local harness picker change does not enter agent view.
Risks and mitigations
CLIAgentSessionsModel::session(view_id).is_some()is broader than an explicit harness enum. The shared ambient-session guard andAgentHarnessflag keep the fallback scoped to 3p shared viewer contexts.apply_cli_agent_state_updatecan run beforeenter_viewing_existing_sessionfinishes fetching task config and settingAmbientAgentViewModel.harness. The CLI-session fallback covers that race.set_harnessintentionally no-ops when the harness is already selected.ViewerHarnessUpdatedis the viewer-specific signal that still runs shared-viewer sync after server task hydration.- Sync can run before and after command blocks exist. First entry retags existing blocks. Later calls are cheap if agent view is already active, and subsequent blocks inherit the active conversation from
BlockList::create_new_block. - Fullscreen agent view filtering is strict. Tests assert both
should_hide_blockandAgentViewVisibility::Terminal.conversation_idsso regressions are visible.