ARTICLE DETAIL

资讯详情

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

Warp 云 Agent 运行 Tombstone 元数据改造:以 AmbientAgentTask 为准的数据源统一与 Continue locally 门控

Warp 云 Agent 运行 Tombstone 元数据改造:以 AmbientAgentTask 为准的数据源统一与 Continue locally 门控 桌面应用开发者工具人工智能AI 应用AI Agent代码智能体【免费下载链接】warpWarp is an agentic development environment, born out of the terminal.项目地址https://gitcode.com/GitHub_Trending/wa/warp点击查看免费下载导读当 Warp 中的云 Agent 任务Oz 或 Claude Code / Gemini 等非 Oz 第三方 harness运行结束时终端内会渲染一张 会话结束墓碑页tombstone展示运行时长、消耗的 Credits 以及计划、分支、PR、文件、截图等产物按钮。本文基于仓库中的两份规格文档PRODUCT.md 与 TECH.md深入讲解本次改造如何将 tombstone 的元数据来源从内存中的AIConversation迁移到服务端返回的AmbientAgentTask实现与会话详情面板conversation details panel在数字与产物上的完全对齐并引入基于 harness 类型的Continue locally按钮隐藏规则。读完本文你将理解该数据管线的完整调用链、关键字段的取舍逻辑、异步刷新机制、测试覆盖范围以及已知风险与后续规划。背景非 Oz 云运行为何会渲染出空墓碑问题一非 Oz 任务根本没有AIConversation在 Warp 的架构中云 Agent 任务可以由两类 harness 执行OzWarp 自研的多 Agent 编排基础设施是默认 harness非 Oz委托给第三方 CLI 的 harness如claude、gemini、opencode、codex。Harness枚举定义在 crates/warp_cli/src/agent.rs包含Oz、Claude、OpenCode、Gemini、Codex以及用于向前兼容的Unknown变体#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Default, Serialize, Deserialize)] #[serde(rename_all lowercase)] pub enum Harness { /// Use Warps built-in MAA infrastructure (default). #[default] Oz, /// Delegate to the claude CLI. Claude, /// Delegate to the opencode CLI. OpenCode, /// Delegate to the gemini CLI. Gemini, /// Delegate to the codex CLI. Codex, /// A harness produced by a newer client/server that this client doesnt recognize. Unknown, }改造前的ConversationEndedTombstoneView只从内存中的AIConversation读取运行时长、Credits 和产物。但非 Oz 云运行不会在客户端实例化AIConversation——它们产生的是CLIAgentConversation。因此非 Oz 运行结束后tombstone 上这三项数据全部渲染为空用户看不到任何成本与时长信息。问题二Oz 云运行的数据与详情面板不一致即使是 Oz 云运行从AIConversation派生的值也存在三处偏差字段从AIConversation派生的问题从AmbientAgentTask派生的效果运行时长基于 exchange 首末时间差计算不含排队queue与沙箱sandbox生命周期AmbientAgentTask::run_time()直接使用服务端上报的run_time字段包含完整生命周期Creditscredits_spent()不含计算compute成本AmbientAgentTask::credits_used()聚合inference compute platform全量成本产物会话侧产物列表可能滞后于任务侧副本直接采用task.artifacts与详情面板一致问题三Continue locally在非 Oz 任务是死按钮ContinueConversationLocally只会 fork Oz-harness 的会话但改造前 tombstone 与ConversationDetailsPanel都会对非 transcript 运行无条件展示Continue locally按钮。对非 Oz 任务而言这是一个点了没反应的死 UI。目标与非目标目标Goals非 Oz 云 tombstone 的Run time、Credits used、产物按钮行全部由AmbientAgentTask填充Oz 云 tombstone 收敛到与ConversationDetailsData::from_task数值、产物完全一致对 harness 为非 Oz 的任务在 tombstone 与详情面板同时隐藏Continue locally按钮纯客户端改动不涉及 harness、服务端、schema 或 endpoint 的任何改动。非目标Non-goals不在非 Oz tombstone 上渲染Directory:/Branch:段留作后续端点工作不为第三方 harness 实现Continue locally按钮直接隐藏不接线不把 Credits 拆分成 Inference / Compute 子行tombstone 的•分隔单行没有空间保持单一聚合值。行为规则数据源优先级核心设计是让 tombstone 的元数据规则镜像ConversationDetailsData::from_task即任务有值任务赢任务没值保留会话兜底值。Run time云运行任务存在使用AmbientAgentTask::run_time()若started_at缺失则省略该段本地运行无任务行为不变仍由 exchange 时间差派生。Credits used云运行任务存在使用AmbientAgentTask::credits_used()即inference compute聚合经format_credits格式化若request_usage缺失则省略本地运行无任务行为不变使用conversation.credits_spent()。Source / Skill保持不变——Source任务来源如 Linear、Slack与Skill原本就已从任务 enrich本次不动。Working directoryOz不变使用AIConversation::initial_working_directory()非 Oz不渲染。Artifacts 行plan / branch / PR / screenshot / file 按钮云运行且task.artifacts非空采用task.artifacts优先于会话产物云运行但task.artifacts为空回落到from_conversation设置的值避免任务部分填充时把 Oz 已有的产物清空本地运行不变使用conversation.artifacts()。Continue locally按钮tombstone 桌面端 详情面板隐藏规则纯粹基于 harnesshide iff harness Some(非 Oz)None未知 / 尚未加载 / 普通会话与Some(Oz)都展示按钮本地运行无任务harness 恒为NoneAI 启用时展示Oz 云任务任务加载前后都展示非 Oz 云任务Claude、Gemini任务 fetch 解析前短暂展示解析后隐藏Webwasm端的Open in Warp按钮不变它只负责把同一会话在桌面端打开桌面端再套用同一套隐藏规则。空行、错误态与快照/transcript 查看器的行为均保持不变。源码实现enrich_from_task 与异步刷新数据结构TombstoneDisplayData定义于 conversation_ended_tombstone_view.rs聚合了展示所需的全部元数据#[derive(Default)] struct TombstoneDisplayData { title: OptionString, is_error: bool, error_message: OptionString, conversation_is_transcript: bool, source: OptionString, // 仅 ambient agent 任务有Linear、Slack 等 skill_name: OptionString, // 技能/配置名仅 ambient agent 任务有 run_time: OptionString, // 已格式化的运行时长字符串 credits: OptionString, // 已格式化的 Credits 字符串 working_directory: OptionString, artifacts: VecArtifact, // 会话产物 }from_conversation负责从BlocklistAIHistoryModel中按conversation_id找到AIConversation派生标题、错误态、exchange 推导的运行时长、credits_spent()格式化结果、初始工作目录与产物列表。核心改动enrich_from_task规格文档给出的核心实现如下它扩展了原有enrich_from_task在任务有值时覆盖run_time、credits、artifacts三个字段#[cfg(not(target_family wasm))] fn enrich_from_task(mut self, task: AmbientAgentTask) { // existing: title / source / skill / error ... if let Some(d) task.run_time() { self.run_time Some(human_readable_precise_duration(d)); } if let Some(c) task.credits_used() { self.credits Some(format_credits(c)); } if !task.artifacts.is_empty() { self.artifacts task.artifacts; } }在实际源码中可以看到这段逻辑已经落地于 conversation_ended_tombstone_view.rs与文档给出的骨架一致并保留了原有的标题兜底、source、skill_name与错误态 enrich 逻辑。三个字段的覆盖都是无条件的unguarded任务有值则任务赢任务没有值时from_conversation填充的值或非 Oz 的默认空值继续存活。这正是与详情面板数值一致的关键——本地 Oz 运行没有task_idenrich_from_task永远不会执行因此from_conversation仍是唯一来源不存在回归。产物按钮行的生命周期修复规格文档还指出一个结构性缺陷artifact 按钮行在构造函数中就被急切构建且从不刷新导致异步任务 fetch 完成后没有地方可灌入新的产物。改造方案构造函数总是物化artifact_buttons_view传入display_data.artifacts的初始值可能为空任务 fetch 的 spawn 回调在enrich_from_task之后调用update_artifacts(me.display_data.artifacts, ctx)刷新按钮行渲染层以display_data.artifacts.is_empty()为门控空列表时不渲染整行避免包住空行的 margin 容器。源码中的任务 fetch 逻辑conversation_ended_tombstone_view.rsif let Some(task_id) task_id { let ai_client ServerApiProvider::handle(ctx).as_ref(ctx).get_ai_client(); ctx.spawn( async move { ai_client.get_ambient_agent_task(task_id).await }, |me, result, ctx| match result { Ok(task) { me.display_data.enrich_from_task(task); me.artifact_buttons_view.update(ctx, |row, ctx| { row.update_artifacts(me.display_data.artifacts, ctx); }); ctx.notify(); } Err(err) { log::warn!(Failed to fetch AmbientAgentTask for tombstone metadata: {err}); } }, ); }元数据行的渲染render_metadata_row将非空段以•分隔拼成单行文本Directory、Source、Skill、Run time、Credits used依序拼接全部为空时返回Empty。渲染层还会对产物行与按钮行分别做is_empty门控避免出现空白容器。Continue locally 的 harness 门控字段与提取规则TombstoneDisplayData新增一个字段harness: OptionHarness默认None。enrich_from_task从task.agent_config_snapshot提取snapshot 存在且显式携带 harness →Some(harness)snapshot 存在但未显式携带 harness →Some(Oz)默认值snapshot 缺失 → 保持None。详情面板侧无需额外接线ConversationDetailsData::from_task位于 conversation_details_panel.rs已经填充了harness字段其提取规则为agent_config_snapshot → harness → harness_type缺失时兜底为Some(Harness::Oz)。统一的隐藏规则render_action_buttons非 wasm 编译分支与ConversationDetailsPanel::continue_locally_conversation_id应用同一条门控!matches!(harness, Some(h) if h ! Harness::Oz)None与Some(Oz)→ 展示按钮仅确认的非 Oz → 隐藏按钮。不需要is_task标志普通会话与加载前的任务天然落入None桶。门控对None是宽容的因此非 Oz 云任务在 fetch 解析之前会短暂展示按钮随后切换为Some(非Oz)并隐藏——这是文档明确接受的权衡若急切隐藏会把本地会话和 Oz 云运行此时尚不知 harness的按钮一并误杀代价更糟。AmbientAgentTask的credits_used()与run_time()实现位于 app/src/ai/ambient_agents/task.rs/// Total credits used (inference compute platform). pub fn credits_used(self) - Optionf32 { self.active_run_execution().request_usage.map(|u| { (u.inference_cost.unwrap_or(0.0) u.compute_cost.unwrap_or(0.0) u.platform_cost.unwrap_or(0.0)) as f32 }) } /// Server-reported run duration. pub fn run_time(self) - OptionChronoDuration { self.run_time.and_then(|run_time| run_time.to_chrono()) }其中credits_used依赖request_usage缺失则返回None对应行为规则中的省略run_time依赖服务端上报的run_time字段Iso8601Duration缺失时同样返回None。两个格式化函数值得一提format_creditsapp/src/ai/blocklist/view_util.rs将 f32 格式化为带正确复数credit/credits的字符串非零但低于显示精度0.0 credits 0.1时显示为0.1 credits避免四舍五入成零误导用户human_readable_precise_durationapp/src/util/time_format.rs将chrono::Duration转为人类可读的精确时长字符串tombstone 与详情面板共用同一套格式化器这也是两边字符串天然一致的基础。成功标准验收口径规格文档定义了六条可验证的成功标准任何携带AmbientAgentTask的云运行Oz 或非 Oztombstone 的Run time与Credits used字符串等于同一任务的ConversationDetailsData::from_task输出task.artifacts已填充的非 Oz 云 tombstone渲染出与详情面板相同的产物按钮Oz 云 tombstone 的数字会可见地变大时长与 Credits 都涨且与详情面板及 Oz 任务列表一致非 Oz 云 tombstone 与详情面板在任务加载后都不渲染Continue locallyOz 云 tombstone 与详情面板仍然渲染Continue locally本地 Oz tombstone 行为不变非 Oz tombstone 继续由FeatureFlag::AgentHarness特性开关控制。测试策略tombstone 侧单元测试enrich_from_task的测试紧邻 conversation_ended_tombstone_view.rs 的同名测试模块覆盖两类场景共 9 个用例字段覆盖与兜底Oz 带任务run time / credits 被任务值覆盖Oz 任务缺字段保留from_conversation的值非 Oz 正常路径全量任务数据填充空默认值任务产物填充空默认值任务产物覆盖会话产物空的task.artifacts保留会话产物。harness 提取任务无agent_config_snapshot→harness Nonesnapshot 无显式 harness → 默认Some(Harness::Oz)snapshot 带显式 harness → 各变体均传播Some(harness)。详情面板侧测试conversation_details_panel_tests.rs已覆盖from_task为各 harness 变体填充harness、以及from_conversation_metadata的透传这正是新门控continue_locally_conversation_id的输入。无需跨面测试的原因规格文档明确解释测试 1 和 3 已断言 tombstone 输出等于human_readable_precise_duration(task.run_time())与format_credits(task.credits_used())这与面板喂给ConversationDetailsData::from_task的数据路径完全相同。做一次字面的面板 vs tombstone字符串对比只是重跑同一套格式化器还要扩大面板私有内部的可见性收益有限。手动验证云 Claude Code 运行Run time、Credits used与产物按钮非空且与详情面板一致两个界面都隐藏Continue locally云 Oz 运行数字更新后与详情面板一致Continue locally可见本地 Oz 运行行为完全不变。提交前按仓库惯例运行./script/presubmit。风险与权衡RisksOz 云数字可见变化双双上浮这是有意的目标是贴合详情面板与任务列表。文档说明该项未做 flag 门控若 dogfood 中发现突兀可在事后用FeatureFlag::AgentHarness隐藏。短暂闪烁from_conversation的值会在异步任务 fetch 解析前先渲染、随后被覆盖。这与详情面板今日已有的竞态相同可接受。非 Oz tombstone 上Continue locally短暂闪现fetch 解析前按钮会短暂可见。这是刻意的取舍——急切隐藏会连带误杀本地会话与 Oz 云运行此时尚不知 harness代价更大。snapshot 缺失 harness 时的误判若非 Oz 运行的服务端 snapshot 没有 harness 字段Some(snapshot) harness None会兜底为Some(Oz)导致错误展示Continue locally。实践上服务端在派发非 Oz 运行时会始终填充harness若将来改变门控会变得过于宽松。Wasm 侧不受影响enrich_from_task是#[cfg(not(target_family wasm))]Web 端云 tombstone 保持现状与面板共享的既有缺口。Wasm 的Open in Warp按钮保持可见因为它只是把用户导向桌面端 tombstone由桌面端执行门控。任务数据部分缺失run_time()或credits_used()返回None时保留from_conversation已设的值避免任务部分填充时清空 Oz 的已有展示。后续规划Follow-upsWasm 对齐Web 端云 tombstone 目前不 fetch 任务既有缺口未来可在 Web 上 fetch 任务并执行enrich_from_task与面板的 wasm 路径共享非 Oz 的Directory:/Branch:计划通过未来的POST /harness-support/report-context姊妹端点实现与现有 transcript 上传在try_join!下并行携带共享 helper若未来出现第三个需要展示的界面抽取一个把AmbientAgentTask翻译为展示字符串的共享函数门控反转如果将来ContinueConversationLocally学会了 fork 非 Oz 运行可以去掉 harness 门控或按新约束反转规则。小结本次改造的实质是确立AmbientAgentTask作为云运行 tombstone 元数据的唯一权威来源source of truth并让 tombstone 与详情面板共用同一套提取与格式化路径从根本上消除了非 Oz 空白与Oz 数值低估/滞后两类不一致。enrich_from_task的任务有值即赢、无值即回落策略、产物按钮行的异步刷新以及基于 harness 的Continue locally门控共同构成了一个纯客户端、可独立验证的改动闭环。感兴趣的读者可以继续阅读 PRODUCT.md、TECH.md 两份规格原文以及 conversation_ended_tombstone_view.rs、conversation_details_panel.rs、task.rs 的实现与测试代码。赞分享桌面应用开发者工具人工智能AI 应用AI Agent代码智能体【免费下载链接】warpWarp is an agentic development environment, born out of the terminal.项目地址https://gitcode.com/GitHub_Trending/wa/warp点击查看免费下载相关推荐BepuPhysics2实战案例集锦从简单刚体到复杂机械系统的完整实现BepuPhysics2实战案例集锦从简单刚体到复杂机械系统的完整实现 BepuPhysics2是一款纯C 编写的3D实时物理模拟库它以高效的性能和灵活的架游戏开发Warp 云端 Agent 会话结束态行为基于 Harness 与对话编辑权限的 Tombstone / 续聊设计APP-4483Warp 云端 Agent 会话结束态行为基于 Harness 与对话编辑权限的 Tombstone / 续聊设计APP 4483 本指南以仓库内 spe桌面应用开发者工具人工智能AI 应用AI Agent代码智能体CKEditor 4 插件到 CKEditor 5 迁移对照指南120 插件的替代方案与实现路径CKEditor 4 插件到 CKEditor 5 迁移对照指南120 插件的替代方案与实现路径 本文是 CKEditor 4 老项目升级到 CKEdito桌面应用开发者工具人工智能AI 应用AI Agent代码智能体上一篇qwen-code 仓库“过剩表面积”扫描指南find-simplifications Survey 阶段的六类候选与八步证据协议下一篇OpenMontage 前端性能优化实战深入解析 JS 函数提前返回Early Return规则创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表