已开启
feat(web): 沙箱不可用时界面区分「计算就绪」状态并显著提示(Issue #91) #160
feat(web): 沙箱不可用时界面区分「计算就绪」状态并显著提示(Issue #91) #160
已开启
hugoxk创建于 25 天前
hugoxk
25 天前

What type of PR is this?

/kind feature


What does this PR do / why do we need it:

修复 Issue #91:沙箱不可用时启动仍报 ready、界面绿灯仅代表连通,缺少真实计算就绪提示。

问题分析:

  • Launcher 的 runPreflight 已探测 sandboxUsable,但 serve() 丢弃结果,照常打印 "ScienceDiscovery is ready";
  • Runner 的 startRunnerServer 用 detectSandboxCapability 探测到沙箱不可用时只打一行 WARNING,/health 不暴露该结果;
  • Web 右上角绿灯只代表前端↔本地 API 连通(Connection OK),不代表沙箱可用、科学计算环境完备或模型额度有效;
  • 用户投入时间写提示词、上传数据后才在运行中失败,且错误常是底层原文。

实现(9 files,把启动链路已有的探测结果透出到 Web 界面,不改底层配置结构):

  1. Schema:RunnerHealth 新增 sandboxUsable: boolean(必填)+ sandboxDetail?: string(沙箱不可用时给出原因)。
  2. Runner:createRunnerServer 新增 sandboxUsable/sandboxDetail 参数;startRunnerServer 捕获 detectSandboxCapability 的结果(含 seatbelt 不可用时的 detail),透传到 /health 响应。既有的降级警告(--disable-userns 缺失、/proc 回退等)语义不变。
  3. API 测试:3 个 mock RunnerHealth 对象补 sandboxUsable: true 满足新必填字段。
  4. Web API:ApiHealthResponse 类型 + getApiHealth() 方法,返回完整 /api/health(含 runner 沙箱状态)。
  5. Web UI:
    • App.tsx 每 30s 轮询 health,computeUnavailable 状态由 runner.sandboxUsable === false 驱动;
    • 连接指示器在「已连接但计算不可用」时变琥珀色(.connection.degraded),tooltip 带原因,chip 文案「计算不可用」,与「前端连通(绿)」/「需要处理(红)」区分开;
    • 消息区上方新增 .compute-unavailable-notice 警告横幅(role="alert"):「当前环境无法执行分析任务。沙箱环境未就绪。你仍可浏览历史会话与产物。」+ 具体 detail。
  6. i18n / CSS:3 组 en/zh-CN 文案 + 琥珀色圆点/横幅样式。

范围说明:Issue 中「计算不可用时应整站阻止发起分析,还是允许只读浏览」标注为待产品拍板的待定项,本 PR 采用「提示不阻断」策略——横幅警告但 composer 仍可操作,留给后续决策单独实现。


Which issue(s) this PR fixes:

Fixes #91


Test Plan and Test result:What scenarios were tested, and what were the verification results(Function, performance, reliability, etc.):

验证提交:f52c81a(9 files, +73/-3,单 commit,基于最新 upstream/main 13fce1a)

  • schema / runner / api / web 四个受影响包 typecheck 全部通过,0 错误
  • Web 单元测试:796 passed / 0 failed / 0 skipped
  • Web vite build:通过
  • API run-cancel.test.js:通过(含 mock health 更新)
  • 行为核对:
    • sandboxUsable: false 且带 sandboxDetail → 绿灯变琥珀、chip 显示「计算不可用」、横幅出现并附原因
    • 沙箱正常(sandboxUsable: true 或缺省)→ 保持绿色,无横幅,不误报
    • API 不可达 → setComputeUnavailable(false),维持既有红灯逻辑
  • E2E:CodeArts 将在 MR 上按既有流程运行。新增横幅/指示器状态不影响既有 e2e 断言(现有规格断言的「绿色连接」仅在前端可达时断言,不检查 .connection class 计数)。

Self-checklist:(请自检,在[ ]内打上x,我们将检视你的完成情况,否则会导致pr无法合入)

likedislike
合并受阻
Hhugoxk
25 天前 关联了issue:[Feature]: 沙箱不可用时启动仍报 ready、界面绿灯仅代表连通,缺少真实计算就绪提示
atomgit-bot
atomgit-bot
25 天前 评论:

变更摘要

本 PR 修复 Issue #91:沙箱不可用时启动仍报 ready、界面绿灯仅代表前端与本地 API 连通的问题。变更将启动链路已有的沙箱探测结果透出到 /health,并在 Web 界面新增「计算就绪」状态区分。packages/schema 的 RunnerHealth 新增必填字段 sandboxUsable 与可选 sandboxDetail;services/runner 的 createRunnerServer 接收 sandboxUsable/sandboxDetail 参数并在 /health 响应中返回,startRunnerServer 捕获 detectSandboxCapability 结果并透传;apps/web 通过新增的 ApiHealthResponse 类型与 getApiHealth() 方法轮询 health,在沙箱不可用时以琥珀色连接指示器与警告横幅提示,但 composer 仍可操作(提示不阻断)。

主要改动

  • 健康状态字段扩展: RunnerHealth 新增必填 sandboxUsable: boolean 与可选 sandboxDetail?: string,用于表达沙箱能否创建隔离执行环境及不可用原因。
  • Runner 探测结果透传: createRunnerServer 新增 sandboxUsable/sandboxDetail 参数并写入 /health 响应,startRunnerServer 将 detectSandboxCapability 的 sandboxUsable 与 detail 透传下去,既有降级警告语义不变。
  • Web 健康轮询与状态派生: apps/web/src/App.tsx 新增每 30s 轮询 getApiHealth(),由 runner.sandboxUsable === false 驱动 computeUnavailable 与 computeUnavailableDetail 状态,请求异常时回落为不可用状态为 false。
  • 连接指示器与警告横幅: 连接指示器在已连接但计算不可用时切换为 connection degraded(琥珀色)并显示「计算不可用」chip,消息区上方新增 compute-unavailable-notice 横幅(role="alert")提示沙箱未就绪、仍可浏览历史。
  • API 客户端与文案样式: ArtifactsApiClient 新增 ApiHealthResponse 类型与 getApiHealth() 方法读取完整 /api/health;i18n/messages.ts 补充 en/zh-CN 三组文案,styles/shell.css 新增琥珀色圆点与横幅样式。

(注:services/api 的三个测试文件中 3 处 mock RunnerHealth 补 sandboxUsable: true 属测试适配,未单列。)

likedislike
不准确?
atomgit-bot
atomgit-bot
25 天前 评论:

代码审查

✅ 未发现问题

likedislike
不准确?
openJiuwen-bot成员
25 天前 评论:

欢迎来到 openJiuwen 社区

Hey @hugoxk , 感谢你对社区的贡献.

机器人使用手册

有关指令的使用,可以点击 此处 查看详情。开发人员可以在每个PR或Issue下方评论特定指令来触发机器人任务。

likedislike
OopenJiuwen-bot成员
25 天前 添加了label:openJiuwen-cla/yes
openJiuwen-bot成员
25 天前 评论:

The pipeline(pipeline number:160) is running. Please wait a moment...

likedislike
OopenJiuwen-bot成员
25 天前 添加了label:ci-running
Hhugoxk
25 天前 修改了pull request 的描述
wang_cheng_zhao成员
25 天前 评论:

AI 自动检视,仅供参考,问题都需要人工评估分析.

变更摘要

对应 Issue #91:Runner 启动探针已能发现 bubblewrap/Seatbelt 建不出沙箱,但结果从未进 UI,绿灯只表示「前端↔API 可达」。本 PR 把 detectSandboxCapability 的结论经 Runner /health → API /api/health 透传到 Web,用琥珀色连接指示 + 顶部 banner 标出「计算不可用」,composer 仍可操作(提示不阻断)。

相对 origin/main 仅 1 commit / 9 文件:RunnerHealth 增 sandboxUsable(必填)与 sandboxDetail?;startRunnerServer 把探测结果传入 createRunnerServer;API 侧若干 mock 补字段;Web 每 30s 轮询 getApiHealth(),并补 en/zh-CN 与 CSS。

做法是否合理

链路与兼容处理整体对齐问题描述:

  • 缺省→绿灯:Web 用 "sandboxUsable" in runner 再判 === false,旧 Runner 无该字段、或 runner: { status: "unavailable" } 时不会误报琥珀色;API 请求失败在 catch 里清掉 computeUnavailable,避免 API 不可达时假阳性。
  • 透传:API /api/health 直接把 runnerClient.health() 结果(或 { status: "unavailable" })塞进响应,不剥字段;Runner /health 在 sandboxUsable === false 时仍报 status: "ok"(进程健康但算力不可用),UI 明确按 sandboxUsable 区分,合理。
  • 提示不阻断:computeUnavailable 只驱动 chip/banner,未改 composer 的 disabled 条件,与 commit 说明一致。
  • 测试:API mock 已跟上必填字段;本地未跑完整 typecheck/单测(工作树无依赖安装),按 diff 看 schema/satisfies RunnerHealth 与 mock 补齐方向正确。若后续想加固,可补一条「sandboxUsable: false → 健康聚合仍含字段」或 Web 轮询分支的轻量断言,非合入阻塞。

可合

likedislike
openJiuwen-bot成员
25 天前 评论:

✅ 流水线 96607d632507461390d7fe9d38808543 执行成功。

可在 https://gitcode.com/openJiuwen/sciencediscovery/pull/160/check 查看完整构建日志。

在 PR 评论中发送 rerun 可重新触发 CI 流水线。

任务名称子任务状态详情
代码检查SCA(开源合规)PASSED点此跳转
Anti-poison(防投毒)PASSED点此跳转
CodeCheck(静态检查)PASSED点此跳转
Blacklist(禁用词)PASSED点此跳转
UThost tierPASSED公开日志
guest tier (QEMU TCG sandbox)PASSED公开日志
ST-PASSED公开日志
Binaryx86_64 debug packagePASSEDbinary · SHA256SUMS
aarch64 debug packagePASSEDbinary · SHA256SUMS
likedislike
OopenJiuwen-bot成员
25 天前 添加了label:ci-successful
OopenJiuwen-bot成员
25 天前 删除了label:ci-running
atomgit-bot
atomgit-bot
24 天前 评论:

AtomGit AI 助手使用指南

在 PR 评论中使用命令即可触发。支持在普通评论和代码行评论中使用。

功能 命令 说明
代码审查 /ai review 检查代码质量、潜在问题、安全风险
PR 摘要 /ai summary 生成 PR 变更内容的结构化摘要
代码解释 /ai explain 解释代码变更的逻辑和意图
自由提问 @atomgit-bot <问题> 询问关于本 PR 的任何问题
帮助 /ai help 显示此帮助信息

免责声明

AI 助手可能存在误判,请结合自身判断。可以对评论点 👍 或 👎 帮助我们改进。

likedislike
不准确?
Hhugoxk
24 天前 审查状态已重置,审查人: hong-ye-zhou,yi-zhang95,wang_cheng_zhao
Hhugoxk
24 天前 强制推送  10 个提交:3cb35700-9 commits from branch main,48147184-feat(web): surface sandbox unavailability through the runner health and web UI
OopenJiuwen-bot成员
24 天前 删除了label:ci-successful
OopenJiuwen-bot成员
24 天前 删除了label:openJiuwen-cla/yes
openJiuwen-bot成员
24 天前 评论:

Notification

This pull request has been changed(code update) or closed, so removes the following label(s): ci-successful.

likedislike
OopenJiuwen-bot成员
24 天前 添加了label:openJiuwen-cla/yes
openJiuwen-bot成员
24 天前 评论:

CLA 签署成功

hugoxk, 感谢您的代码贡献。 所有的代码贡献者都已完成了 CLA 签署。 👍

likedislike
openJiuwen-bot成员
24 天前 评论:

The pipeline(pipeline number:160) is running. Please wait a moment...

likedislike
OopenJiuwen-bot成员
24 天前 添加了label:ci-running
wang_cheng_zhao成员
24 天前 评论:

上一轮检视:https://gitcode.com/openJiuwen/sciencediscovery/pull/160?ref=&did=8c81d0916a953aad7232955c2beaccb7e5327b5c#tid-190607292

AI 自动检视,仅供参考,问题都需要人工评估分析.

相对上轮的变化

相对已检视 HEAD f52c81a1,本轮为 rebase 到较新基线后的 force-push:git range-diff / patch-id 与上一轮完全一致,Issue #91 的 9 文件改动(Runner 探针 → /health → API → Web 轮询、琥珀指示与 banner、缺省不误报)本身无新增逻辑。相对当前 origin/main(73015b2e,fix(web) i18n 清残留)仍 behind 1 / ahead 1;merge-tree 显示 App 等与 main 有重叠但无冲突标记,合入前再 rebase 一次即可,不挡审。

上轮结论仍成立:缺省/API 失败不误报 amber、提示不阻断与 Issue 一致。

可合

likedislike
openJiuwen-bot成员
24 天前 评论:

✅ 流水线 adc75682da7041b798e8273b652c473b 执行成功。

可在 https://gitcode.com/openJiuwen/sciencediscovery/pull/160/check 查看完整构建日志。

在 PR 评论中发送 rerun 可重新触发 CI 流水线。

任务名称子任务状态详情
代码检查SCA(开源合规)PASSED点此跳转
Anti-poison(防投毒)PASSED点此跳转
CodeCheck(静态检查)PASSED点此跳转
Blacklist(禁用词)PASSED点此跳转
UThost tierPASSED公开日志
guest tier (QEMU TCG sandbox)PASSED公开日志
ST-PASSED公开日志
Binaryx86_64 debug packagePASSEDbinary · SHA256SUMS
aarch64 debug packagePASSEDbinary · SHA256SUMS
likedislike
OopenJiuwen-bot成员
24 天前 添加了label:ci-successful
OopenJiuwen-bot成员
24 天前 删除了label:ci-running
hsliu_ustc
hsliu_ustc成员
19 天前 评论:

评审意见(基于 main 分支实测核查)

一句话结论

建议小改(approve-with-nits):实现本身正确、防御性好,但新增 UI 状态零测试覆盖,且描述中关于 seatbelt 的声明与代码不符。

描述核查

  • 文件数/行数/单 commit 属实:9 files、+73/-3、1 commit(实际 head 为 4814718,非描述所称 f52c81a,base 也非 13fce1a,描述里的验证提交信息已过期)。
  • “含 seatbelt 不可用时的 detail 透传到 /health”不属实:diff 只在 bwrap 分支(server.ts @@ -1114 处)赋值 sandboxUsable/sandboxDetail;seatbelt 分支(@@ -1086 上下文,startRunnerServer 内)不可用时仍直接 throw,runner 根本不会起来,/health 永远不可能在 macOS 上报 sandboxUsable:false。琥珀态实际仅 Linux/bwrap 可达。
  • “既有降级警告语义不变”属实:--disable-userns 缺失、/proc 回退两条 WARNING 分支未被改动,仅在前面加了赋值。
  • “API 不可达 → setComputeUnavailable(false),维持红灯逻辑”属实:catch 分支已验证;红灯由独立 error state 驱动。e2e 声明也属实:现有规格只断言 .connection.bad 计数为 0(test/journey-local-token-onboarding.spec.ts:204),.connection.degraded 不匹配。
  • “3 个 mock 补字段”:实际是 3 个文件里的 4 处字面量(run-cancel.test.ts、model-usage-api.test.ts、server.test.ts ×2),且全部只写 sandboxUsable: true,没有任何用例走到 false 分支。

问题清单

  • [主要] 全 PR 无任何新测试。mock 只是满足必填字段;sandboxUsable:false → 琥珀点 + 横幅、轮询 catch、旧 runner 无字段保持绿色等新逻辑(apps/web/src/App.tsx diff @@ -1425,33 与 @@ -4404 处)完全无覆盖,与自检清单“已有 UT 充分覆盖”不符。建议补:web 测试 mock getApiHealth 断言 .connection.degraded/.compute-unavailable-notice 渲染与否;runner 侧断言 /health 含 sandboxUsable。
  • [次要] runner 进程不可达时(runner.status === "unavailable",App.tsx 轮询处)UI 仍显绿色。结合 seatbelt 分支直接 throw,Issue #91 的 macOS 场景依旧看不到“计算不可用”。建议把 runner === undefined/status==="unavailable" 也并入 computeUnavailable,或至少修正描述并留 issue。
  • [次要] services/api/src/server.test.ts diff @@ -526,7 处替换行丢失缩进:runnerVersion: "test", sandbox: "bubblewrap", sandboxUsable: true, 顶格,破坏该文件既有对齐(第二处 @@ -3020 缩进正常)。纯格式问题。
  • [建议] apps/web/src/styles/shell.css 新增 .connection.degraded i { background: #d4a017 } 硬编码色值,而 token 表已有 --warning-accent: #d19a32(styles/tokens.css:72)且横幅其余部分用的就是 warning 变量;建议改用 var(--warning-accent) 保持主题一致。
  • [建议] App.tsx catch 分支未清空 computeUnavailableDetail(残留旧值,因横幅被 computeUnavailable 门控而无实害);tooltip 的 {detail} 缺省时回退整句 banner 文案,略冗长。

亮点

  • "sandboxUsable" in runner 的 in-guard 让前端对不含新字段的旧 runner 保持绿色,向后兼容干净。
  • 轮询 effect 取消安全(active 标志 + clearInterval,client 经 memo 稳定不会重订阅),横幅与 tooltip 均以 React 文本节点/title 渲染 runner 侧 detail,无注入风险,role="alert" 可被读屏播报。

VERDICT: approve-with-nits

likedislike
Wwang_cheng_zhao成员
6 天前 审查状态已重置,审查人: hong-ye-zhou,yi-zhang95,wang_cheng_zhao