ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Warp 云到云(Cloud-to-Cloud)继续会话:TUI 终端中的「Continue」续跑机制解析

Warp 云到云(Cloud-to-Cloud)继续会话:TUI 终端中的「Continue」续跑机制解析 桌面应用开发者工具人工智能AI 应用AI Agent代码智能体【免费下载链接】warpWarp is an agentic development environment, born out of the terminal.项目地址https://gitcode.com/GitHub_Trending/wa/warp点击查看免费下载导读本文以 Warp 开源仓库中的技术规格 specs/APP-4364/TECH.md 为主体系统讲解 PR 3 如何把「云 Agent 会话结束后在同一终端窗格内继续追问」这一能力接入终端 UI从功能开关HandoffCloudCloud、会话结束墓碑tombstone卡片上的Continue按钮到AmbientAgentViewModel::submit_cloud_followup的提交链路、乐观渲染与共享会话热切换hotswap的完整闭环。读完本文你将理解这套「云到云 handoff」在 Warp 桌面端 TUI 中的端到端实现原理以及围绕它的测试、风险与验收标准。背景为什么需要「云到云」续跑Warp 的 Cloud Mode云模式中Agent 的每次运行都运行在一台临时云 VM 上并通过一个共享会话shared session将输出流式渲染到本地终端窗格。当一次执行结束、共享会话断开后若用户想在同一个终端窗格里对同一任务继续追问就面临一个关键问题已结束的共享会话网络Network不再存在普通的「viewer 提交提示词 → 转发给 sharer」路径已经走不通。PR 1 引入了默认关闭的HandoffCloudCloud功能开关、类型化的 follow-up API 客户端以及带执行状态的任务访问器PR 2 在模型层实现了 follow-up 编排AmbientAgentViewModel::submit_cloud_followup提交提示词、等待新会话、发出FollowupSessionReady事件。PR 3即本文所依据的技术规格在此基础上把这条链路接入终端 UI、共享会话结束路径、任务活性模型、回放过滤与针对性测试实现了第一个用户可见的云到云 follow-up 入口。功能开关与前置条件整个云到云续跑能力由编译特性与运行开关共同控制HandoffCloudCloud核心开关。PR 3 不负责开启该开关的默认启用rollout相关测试通过FeatureFlag::HandoffCloudCloud.override_enabled(true/false)模拟开/关两种状态见 app/src/terminal/view/shared_session/view_impl_tests.rs。CloudModeSetupV2Cloud Mode 的 setup-v2 UI启动进度与错误展示开关follow-up 的加载 UI 复用该模式。相关特性定义见 app/src/features.rs。AI 可用性AI enabled与桌面端编译非 wasmContinue云按钮的渲染还要求 AI 功能启用且仅存在于桌面端。验证命令规格中指定的针对性验证cargo check -p warp --features handoff_cloud_cloud注意仓库规则要求提交前按仓库规范运行格式化与 clippy但不要使用cargo fmt --all或针对单个文件的cargo fmt。会话结束路径按所有权分流PR 3 的关键设计之一是「按会话所有权」拆分结束处理逻辑避免用通用清理逻辑破坏可恢复的 ambient 执行通用路径不变TerminalView::on_session_share_ended仍负责普通共享会话的宽泛清理清空 presence manager、处理 sharer 的 inactivity 定时器等仅当处于CloudModeSetupV2且是「非 owner 的 ambient viewer 会话」时才会在结束 share 之前插入一个墓碑卡片见 app/src/terminal/view/shared_session/view_impl.rs。专用路径新增on_ambient_agent_execution_ended与on_ambient_agent_session_ended二者统一委托给handle_non_running_ambient_agent_task见 app/src/terminal/view/shared_session/view_impl.rs。该 helper 会在AgentConversationsModel中标记任务执行结束mark_task_execution_ended刷新详情面板以HandoffCloudCloud、CloudModeSetupV2、尚无墓碑、无 pending follow-up 为门控条件更新 UIowner 的 ambient 窗格不插墓碑若没有存活的共享会话调用enable_cloud_followup_input_after_conversation_end(task_id, ctx)让用户直接在现有输入框继续打字非 owner 的 viewer 窗格插入单个被跟踪的墓碑卡片。在 viewer manager 侧TerminalManager处理 ambientSessionEnded时同样区分 owner 与非 ownerowner 的会话状态被置为SharedSessionStatus::NotShared保持可编辑非 owner 保持FinishedViewer只读 viewer并且不将窗格标记为「已完成的 viewer」随后调用terminal_view.on_ambient_agent_execution_ended(ctx)并记录record_ambient_execution_ended(session_id, ctx)见 app/src/terminal/shared_session/viewer/terminal_manager.rs。单个被跟踪的墓碑每个终端视图只维护一个墓碑卡片 IDconversation_ended_tombstone_view_idinsert_conversation_ended_tombstone_with_cta是幂等的——若已有墓碑则先移除再插入插入位置放在 pending user query 之后避免被钉在底部的 cloud-mode queued prompt 遮挡见 app/src/terminal/view/shared_session/view_impl.rs用户点击云续跑后remove_conversation_ended_tombstone移除卡片当任务状态在空闲时变化导致墓碑过期时只跟踪一个 ID 点击时校验 task_id 归属的策略保证了 UI 聚焦于当前可恢复的边界。墓碑卡片上的Continue云按钮ConversationEndedTombstoneView在桌面端会创建一个可选的Continue云按钮条件为墓碑携带 ambienttask_id且HandoffCloudCloud开启渲染还要求 AI 可用且为桌面端编译见 app/src/terminal/view/shared_session/conversation_ended_tombstone_view.rs。按钮动作定义为pub enum ConversationEndedTombstoneAction { ContinueInCloud { task_id: AmbientAgentTaskId }, // 桌面端本地续跑 ContinueLocally(AIConversationId), // wasm 端在 Warp 中打开 OpenInWarp(AIConversationId), }ContinueInCloud被点击后见 conversation_ended_tombstone_view.rs记录遥测事件AgentManagementTelemetryEvent::TombstoneContinueInCloud { task_id }task_id 序列化为稳定字符串发出ConversationEndedTombstoneEvent::ContinueInCloud { task_id }TerminalView::start_cloud_followup_from_tombstone(task_id, ctx)移除墓碑、聚焦现有输入框、设置pending_cloud_followup_task_id见 view_impl.rs。进入 compose 之前会校验当前 ambient view model 仍持有被点击的task_id否则弹出错误 toast。按钮排布规则云Continue按钮渲染在第一位后面才是Continue locallyOz/普通会话保持「本地续跑」入口对于非 Oz harness如claude、gemini的第三方 harness 运行本地续跑被隐藏——因为这些运行无法 fork 成本地 Warp 会话。当HandoffCloudCloud关闭时不创建云按钮墓碑行为与旧版完全一致。follow-up 输入模式与提交路由输入态管理TerminalView持有pending_cloud_followup_task_id: OptionAmbientAgentTaskId。墓碑点击与 owner 执行结束路径都会调用enable_cloud_followup_input(task_id, ctx)见 view_impl.rs它设置 pending task_idinput.reset_after_cloud_followup_submission重置输入、input.set_input_mode_agent(true, ctx)进入 agent 输入模式编辑器设为可编辑InteractionState::Editable更新窗格配置并 notify。这样墓碑只是「揭示/聚焦」入口真正的编辑器仍然是终端既有输入框不会在墓碑里内嵌第二个编辑器。提交拦截绕过已结束的网络终端输入提交原本假定存在存活的共享会话网络Input::submit_viewer_ai_query冻结输入、收集上下文附件并发出InputEvent::SendAgentPrompt见 app/src/terminal/input.rs。但在两次云执行之间故意没有当前网络因此 PR 3 需要独立的 follow-up 提交路由。TerminalView::try_submit_pending_cloud_followup(prompt, ctx)在InputEvent::SendAgentPrompt到达时、于常规TerminalViewEvent::SendAgentPrompt路径之前进行拦截见 app/src/terminal/view.rsfn try_submit_pending_cloud_followup(mut self, prompt: String, ctx) - bool { if !FeatureFlag::HandoffCloudCloud.is_enabled() { return false; // 开关关闭走旧路径 } // 阻止 follow-up 的会话/任务来源检查 let blocks_cloud_followups ...; // blocks_cloud_followups_for_ambient_agent_session_from_model if blocks_cloud_followups { pending None; return false; } let Some(task_id) self.pending_cloud_followup_task_id .or_else(|| self.owned_ambient_agent_task_id(ctx)) else { return false; }; if prompt.trim().is_empty() { // 空提示保持 compose 路由可用恢复 agent 输入并聚焦 input.reset_after_cloud_followup_submission(ctx); input.set_input_mode_agent(true, ctx); update_pane_configuration(ctx); focus_input_box(ctx); ctx.notify(); return true; } let Some(ambient_agent_view_model) self.ambient_agent_view_model.clone() else { self.restore_followup_prompt_after_failed_submission(prompt, ctx); self.show_error_toast(Couldnt continue this cloud task..to_string(), ctx); return true; }; if ambient_agent_view_model.as_ref(ctx).task_id() ! Some(task_id) { self.restore_followup_prompt_after_failed_submission(prompt, ctx); self.show_error_toast(Couldnt continue this cloud task..to_string(), ctx); return true; } ambient_agent_view_model.update(ctx, |model, ctx| { model.submit_cloud_followup(prompt, ctx); // 路由到 follow-up API而非 ended network }); input.reset_after_cloud_followup_submission(ctx); input.set_input_mode_agent(true, ctx); update_pane_configuration(ctx); ctx.notify(); true }要点校验链功能开关 → 会话来源是否允许 follow-up → task_idpending 或 owner 任务→ 非空提示 → ambient model 的 task_id 是否与点击/持有的一致失败恢复校验失败或 model 缺失时restore_followup_prompt_after_failed_submission会把提示词放回输入框、清空 pending 状态、聚焦输入并显示错误 toastslash 命令保持本地行为/fork、/fork-and-compact等仍走Input::submit_viewer_ai_query的本地执行路径slash 命令在 viewer 端本机执行只有/compact、/plan、/orchestrate等作为提示词转发follow-up 路由只处理普通非空 agent 提示词。加载 UI 与乐观渲染复用 setup-v2 加载/错误 UIPR 2 已在模型层把状态置为Status::WaitingForSession { kind: SessionStartupKind::Followup }并发出FollowupDispatched见 app/src/terminal/view/ambient_agent/model.rs。PR 3 复用该状态follow-up 提交后、轮询新执行会话期间终端渲染与初次 Cloud Mode 相同的 setup-v2 加载 UI。submit_cloud_followup(prompt, ctx)先检查HandoffCloudCloud开关关闭则仅告警并返回随后调用submit_run_followup_unchecked读取当前/最近结束的 execution session IDactive_execution_session_id.or(last_ended_execution_session_id)作为previous_session_id调用submit_run_followup(prompt, task_id, previous_session_id, ai_client, None)发起流式请求置pending_followup_prompt、切换状态到WaitingForSession { kind: Followup }并发出FollowupDispatched见 model.rs。执行结束信息由record_ambient_execution_ended(session_id, ctx)记录在last_ended_execution_session_id中见 model.rs使轮询可以等待一个「不同于上一次」的新会话。乐观渲染与去重CloudModeFollowupUserQuery与CloudModeInitialUserQuery共享同一套render_user_query样式。关键区别是插入时机初始运行DispatchedAgent时插入初始用户查询follow-upFollowupDispatched时才插入CloudModeFollowupUserQuery初始运行行为完全不变。AmbientAgentViewModel通过三个新状态支撑乐观渲染与去重pending_followup_prompt: OptionString已提交但尚未挂到新会话的提示词should_show_followup_progress()pending 提示词存在且状态处于WaitingForSession | Failed | NeedsGithubAuth | Cancelled时返回 true见 model.rsoptimistically_rendered_user_queries记录已渲染的提示词共享会话回放时同一提示词不再渲染第二次避免重复。view 侧在收到FollowupDispatched后见 app/src/terminal/view/ambient_agent/view_impl.rs在CloudModeSetupV2下开启新 setup 命令组、把会话状态更新为ConversationStatus::InProgress并把 pending 提示词渲染为 queued user query blockQueuedPromptsV2开启时走enqueue_initial_cloud_mode_prompt否则直接insert_cloud_mode_queued_user_query_block。结束 setup 的终端状态会清空 pending/progress 状态确保被拒绝的提交不会永久追加乐观 UI。错误、重试、回放与状态清理错误与重试API/轮询错误复用既有的AmbientAgentViewModelEvent::Failed、auth、quota、capacity 事件setup 屏与初次 Cloud Mode 显示相同的错误 UI若提交在模型接受之前失败restore_followup_prompt_after_failed_submission将提示词放回输入框、重新进入 agent 输入模式并聚焦输入以便重试若 follow-up 被接受但在会话就绪前失败本地会话保持相同 task/run IDambient 状态进入既有的错误/auth/cancelled UI重试仍走同一条 pending follow-up/输入路径不会分配新的本地会话。回放去重新执行会话 attach 后共享会话回放控制器新增should_skip_current_replayed_response与should_skip_replayed_response_for_existing_conversation状态当某条响应已在本地会话中呈现时回放不再重复追加。viewer 事件循环侧还有对应的「抑制既有 agent 会话回放」机制should_suppress_existing_agent_conversation_replay见 app/src/terminal/shared_session/viewer/event_loop.rs其测试用例见 event_loop_tests.rs。成功热切换当FollowupSessionReady触发时清除 follow-up compose/输入状态与 pending 乐观状态走既有FollowupSessionReady - attach_followup_session热切换路径。viewer manager 侧attach_execution_session(session_id, ctx)会先关闭旧网络若存在再以追加模式append mode连接新共享会话新输出流式进入同一个终端窗格见 app/src/terminal/shared_session/viewer/terminal_manager.rs。create_cloud_mode_viewapp/src/terminal/view/ambient_agent/mod.rs创建的云模式窗格使用「deferred」viewer managerambient 提示词在一个未初始化的会话共享 viewer 窗格中编辑会话就绪后再 joinwire_ambient_agent_session_events订阅模型事件——SessionReady对应初次运行连接ExecutionSessionReady对应 follow-up 新 VM 会话的重新 attach见 mod.rs。端到端流程规格给出的完整闭环如下一次 Cloud Mode 执行结束viewer manager 收到SessionEndedambient_session_ended记录已结束的会话 ID并调用 ambient 执行结束的 terminal-view 方法终端视图标记任务执行结束、刷新任务/详情状态owner 直接启用 follow-up 输入非 owner 插入单个被跟踪的墓碑同时保持窗格/输入可恢复非 owner 的 viewer 点击墓碑上的Continue终端移除墓碑、聚焦既有输入框并把下一个普通 agent 提示词标记为云 follow-up用户提交提示词输入/视图把提示词路由到AmbientAgentViewModel::submit_cloud_followup视图插入一条乐观 follow-up 用户查询、记录为已渲染并展示 setup-v2 加载 UI模型提交 follow-up API 请求并轮询新会话FollowupSessionReady到达create_cloud_mode_view调用attach_followup_sessionviewer manager 以追加模式 join 新共享会话新输出流式进入同一终端窗格。整个过程中终端窗格、本地会话、稳定的 run/task ID 与 hotswap attach 路径均保持不变。测试与验证PR 3 的单元测试覆盖了所有已交付的接缝seams任务 active/joinable 辅助函数与会话展示状态app/src/ai/agent_conversations_model_tests.rs云 follow-up compose 恢复app/src/terminal/view_test.rs墓碑插入/移除、owner follow-up 输入、过期任务拒绝、任务结束处理app/src/terminal/view/shared_session/view_impl_tests.rs例如test_on_ambient_agent_execution_ended_enables_followup_input_without_tombstone_for_owned_task、test_try_submit_pending_cloud_followup_rejects_task_source_that_blocks_followupsambient 会话结束/网络行为与回放处理app/src/terminal/shared_session/viewer/event_loop_tests.rs待补覆盖HandoffCloudCloud开/关、有无task_id、AI 开关下的墓碑按钮可见性以及非 Oz harness 隐藏本地续跑。ambient view 覆盖验证FollowupDispatched独立于DispatchedAgent插入/渲染乐观 follow-up 提示词、记录已渲染提示词、重试时清空/重新启用 follow-up 状态。viewer manager/event-loop 覆盖验证ambientSessionEnded插入或启用 follow-up UI 时不设置SharedSessionStatus::FinishedViewer、不通过过期网络发送提示词、不重复回放响应。规格给出的人工验证清单关闭HandoffCloudCloud完成一次 Cloud Mode 运行验证墓碑不变开启开关完成一次 Cloud Mode 运行点击Continue、提交提示词验证 setup UI 出现、新共享会话在同一个窗格 attach重复上述一次以捕获过期会话 ID、重复墓碑与订阅泄漏验证Continue locally仍从墓碑 fork 本地会话验证普通共享会话 viewer 在会话结束时仍变为只读/已完成。风险与缓解风险缓解措施提示词被路由到过期/缺失的Networkfollow-up compose 模式在 viewer-manager 网络路径之前拦截提交try_submit_pending_cloud_followup优先于TerminalViewEvent::SendAgentPrompt墓碑插入回归通用 viewer 清理执行边界走专用 ambient 方法on_ambient_agent_execution_ended/handle_non_running_ambient_agent_task普通共享会话清理保留在on_session_share_ended乐观提示词/响应重复模型跟踪optimistically_rendered_user_queries 共享会话回放 skip 状态重试状态漂移输入冻结或墓碑隐藏在 ambient 模型失败/cancel/auth 事件上集中清理确保墓碑始终可用墓碑状态过期只跟踪一个墓碑 ID点击时对照当前 ambient 模型校验task_id云续跑开始时移除墓碑完成标准Definition of DoneHandoffCloudCloud关闭时墓碑与共享会话行为完全不变开关开启时合格的 ambient Cloud Mode 墓碑显示云Continue动作Oz/普通会话仍保留Continue locally点击Continue聚焦/揭示既有终端输入提交普通提示词调用AmbientAgentViewModel::submit_cloud_followupfollow-up 提示词不经过已结束的共享会话网络新会话启动期间显示 setup-v2 加载/错误 UI已渲染的回放内容不重复乐观 follow-up 用户查询在 setup 期间渲染不复用初始运行 dispatch UI新会话就绪后既有FollowupSessionReady热切换路径把会话 attach 到同一个窗格针对性测试与cargo check -p warp --features handoff_cloud_cloud全部通过。延伸阅读技术规格原文specs/APP-4364/TECH.md云模式窗格创建与会话事件接线app/src/terminal/view/ambient_agent/mod.rsfollow-up 模型编排submit_cloud_followup、乐观渲染、事件定义app/src/terminal/view/ambient_agent/model.rs会话结束与墓碑插入/移除app/src/terminal/view/shared_session/view_impl.rs墓碑渲染与ContinueInCloud动作app/src/terminal/view/shared_session/conversation_ended_tombstone_view.rsviewer manager 的会话 attach 与结束处理app/src/terminal/shared_session/viewer/terminal_manager.rs回放抑制与事件循环app/src/terminal/shared_session/viewer/event_loop.rs赞分享桌面应用开发者工具人工智能AI 应用AI Agent代码智能体【免费下载链接】warpWarp is an agentic development environment, born out of the terminal.项目地址https://gitcode.com/GitHub_Trending/wa/warp点击查看免费下载相关推荐Warp 的 Cloud-to-Cloud 交接已完成的云对话如何在 Cloud Mode 中恢复并继续可恢复 Transcript 技术方案解析Warp 的 Cloud to Cloud 交接已完成的云对话如何在 Cloud Mode 中恢复并继续可恢复 Transcript 技术方案解析 在 W桌面应用开发者工具人工智能AI 应用AI Agent代码智能体Warp Cloud 到 Cloud 续接Handoff完成态 Cloud 对话在 Cloud Mode 中的可续接 Transcript 实现Warp Cloud 到 Cloud 续接Handoff完成态 Cloud 对话在 Cloud Mode 中的可续接 Transcript 实现 导读 本桌面应用开发者工具人工智能AI 应用AI Agent代码智能体Warp TUI 会话续聊--resume 恢复机制与源码实现解析Warp TUI 会话续聊 resume 恢复机制与源码实现解析 Warp TUI 在退出时会打印一条可续聊指令用户下次启动时携带该指令中的服务器会话令牌桌面应用开发者工具人工智能AI 应用AI Agent代码智能体创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表