feat: release v1.0.2 LeKiwi 语言控制与网站嵌入
web-platform-ci / Standalone decision service (no cloud credentials) (push) Has been cancelled
web-platform-ci / TypeScript, lint, unit, build (push) Has been cancelled
web-platform-ci / Playwright E2E (push) Has been cancelled
lekiwi-compatibility / cpu-compatibility (push) Has been cancelled
web-platform-ci / Standalone decision service (no cloud credentials) (push) Has been cancelled
web-platform-ci / TypeScript, lint, unit, build (push) Has been cancelled
web-platform-ci / Playwright E2E (push) Has been cancelled
lekiwi-compatibility / cpu-compatibility (push) Has been cancelled
集成服务器托管模型、自然语言移动与有界抓放、内置 LeKiwi URL 导入和双摄像头;同步部署契约与指定域名 iframe 白名单,保留原有物理安全、会话及调用预算防护。 更新 npm 包及锁文件版本、CHANGELOG 与发布文档。提交前 typecheck、120 项定向前端测试和 44 项后端测试通过(3 项可选跳过);真实 v2 云模型抓放仍待单独验收,不包含运行密钥或构建产物。
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
# 内置机器人与 URL 自动导入
|
||||
|
||||
## 给接入方的链接
|
||||
|
||||
```text
|
||||
https://cadworld-sim.robotquan.com/?robot=lekiwi-v1
|
||||
```
|
||||
|
||||
- 参数名:`robot`;当前唯一值:`lekiwi-v1`,区分大小写。
|
||||
- 如果链接已有查询参数,使用 `&robot=lekiwi-v1`。其他参数不影响加载。
|
||||
- 打开页面后自动下载、校验、解压,选择 `URDF/LeKiwi.urdf` 和 `lekiwi-v1` profile,转换 MJCF 并加载进当前浏览器仿真;不再弹出入口/URDF 配置确认框。
|
||||
- 默认暂停,可点击播放或在「控制台 → 机器人语言控制」输入指令。URL 本身不触发机器人运动、付费模型、Python/ONNX 或外控授权。
|
||||
- 无 `robot` 参数:保持空白工作台,不下载 ZIP。未知、空值、重复参数:明确报错,不加载默认机器人,也不访问参数中的任意 URL/文件路径。
|
||||
- 刷新页面会重新导入;删除工程或手动换模型不会被参数反复覆盖。参数只在页面启动时读取,改变浏览器地址后需导航/刷新。
|
||||
- 下载或校验失败时显示错误,可刷新重试,也可直接手动导入;不自动重试。下载等待上限 120 秒,离开页面取消下载。
|
||||
|
||||
## LeKiwi 双摄像头
|
||||
|
||||
自动导入同时创建前置与腕部两台独立相机,不再用通用的“首个 camera/head 名称 + 10 cm 偏移 + 局部 +X”规则。原先误挂到 `Camera-Mount-v8` 支架且侧向取景,是位置和方向错误的原因。
|
||||
|
||||
左下角画面顶部的「摄像头视角」下拉框可切换「前置摄像头」和「腕部摄像头」,默认前置。一次渲染选中的一路,避免完整 CAD 多视口的额外开销。切换只改变查看器使用的相机 ID,不重新加载模型、不推进物理、不改变控制权;隐藏/显示保留所选相机,同名相机在场景重编译后保持选择,刷新页面默认前置。
|
||||
|
||||
### 前置摄像头
|
||||
|
||||
- 固连 Body:`Camera-Model-v3`,MJCF 名称 `__platform_camera__`。
|
||||
- 局部光心(米):`[-0.012161199990, 0.024589244440, -0.012071624890]`。
|
||||
- 局部旋转四元数(MuJoCo wxyz):`[0.413175911167, 0.492403876506, 0.492403876506, -0.586824088833]`。
|
||||
- 参数由原始 URDF 的视觉原点和 STL 镜头坐标推导:STL 光轴为 +Z,镜头最前端 z=21.5 mm,虚拟光心放在其前方 1 mm,避免模型遮挡自身画面。MuJoCo 使用 -Z 看向前方、+Y 图像向上,不能直接套用 Body +X。
|
||||
- 经 profile 的 CAD -90° 转向后,镜头朝机器人前方 +X,保留 CAD 安装的向上 10° 倾角,图像不侧转/倒置,随底盘运动。初始世界光心约 `[0.130956, 0, 0.062079]` m。
|
||||
|
||||
### 腕部摄像头
|
||||
|
||||
- 固连 Body:`Camera-Model-v3-1`,MJCF 名称 `__platform_camera__wrist`。
|
||||
- 局部光心(米):`[0.024189561811, -0.017694392834, -0.000153127430]`。
|
||||
- 局部旋转四元数(wxyz):`[0.459991520356, -0.040244043349, -0.883635489162, -0.077308087991]`。
|
||||
- 使用腕部相机自己的 URDF 视觉原点推导光心与光轴,同样位于 STL 镜头前方 1 mm,不能照搬前置的局部姿态。初始世界光心约 `[0.215392, 0.004250, 0.168290]` m,初始前向约 `[-0.173648, 0, -0.984808]`,朝夹爪作业区;随腕部/手臂运动实时更新。
|
||||
- 两相机都由 MuJoCo 的 `cam_xpos/cam_xmat` 驱动画面;真实 WASM 运动学回归验证腕部运动不改变前置相机、转动底盘时两者同步跟随。
|
||||
|
||||
两路都是 CAD 对齐的仿真视点,不是实机内外参标定;保持 45° 垂直视场角/640×480 配置。不增加控制桥相机 API,也不改原 ZIP/网格、动力学或手动 profile 的“无相机”行为。
|
||||
|
||||
## 资产与部署
|
||||
|
||||
用户指定的原文件:`build/lekiwi/lekiwi-v1.zip`。
|
||||
|
||||
发布源文件:`web_platform/assets/robots/lekiwi-v1.zip`,与原文件逐字节一致。该副本作为正式内置资产保存,不依赖被 Git 忽略的 `build/`,也不需要访问者拥有本地文件。
|
||||
|
||||
- 大小:22,040,277 字节(约 22 MB)。
|
||||
- SHA-256:`a10ac577ea49cdf87f324f3f6e9a7a887a1e3c0254ae638059711fef9e385b04`。
|
||||
- 51 个文件;包含 URDF、完整 STL 网格、许可、引用、来源清单及仿真用途说明。
|
||||
- 原始来源:SIGRobotics-UIUC/LeKiwi,固定 revision `efa608d7ee5a495a4803b1d28cd0c955b4f1e033`,Apache-2.0。未改动用户指定的 ZIP。
|
||||
|
||||
注册表位于 `web_platform/src/project/builtinRobots.ts`。Vite `?url` 导入将 ZIP 输出为带内容哈希的独立 `/assets/lekiwi-v1-*.zip` 文件,不塞进 JavaScript,也不会在普通首页预下载整个 ZIP。网站与本地两种构建均支持,同样兼容静态子目录部署。构建后必须发布完整静态目录,不要只复制 JS/HTML;不要对外发送带哈希的 ZIP 路径,接入方只使用稳定的 `robot=lekiwi-v1`。
|
||||
|
||||
新增机器人时需明确增加内置资产和注册项,并验证入口/profile;不开放 URL 任意远程下载。替换 ZIP 时同步更新大小、SHA256 并重新跑门禁;如果机械模型/profile 语义变化,应使用新的机器人 ID。下载流有大小上限、SHA256 校验,随后仍走原 ZIP 路径/文件数量/解压预算校验和 profile 来源校验。
|
||||
|
||||
## 发布与验收记录(2026-09-24)
|
||||
|
||||
### 双摄像头补齐
|
||||
|
||||
已发布 `20260924T052730Z-dual-camera`,上一版本 `20260924T050135Z-camera-fix`。前置和腕部相机分别固连用户指定的两个 Body,后端打包逐文件无变化,原 ZIP 哈希不变。
|
||||
|
||||
- 655 项单测、TypeScript、ESLint、变更文件格式检查、本地/网站双构建通过。
|
||||
- 浏览器自动导入与双视角切换:生产构建 6/6、开发 StrictMode 6/6、公网 HTTPS 6/6。实际导出两台相机并校验各自光心、光轴和图像向上方向;确认切换/隐藏不重新下载模型,刷新恢复前置视角。
|
||||
- 独立真实 WASM 运动学回归 1/1:腕部屈曲 0.35 rad 时仅腕部相机随动,底盘旋转 90° 时两相机共同旋转;测试在开发夹具独立实例中执行,不增加产品的位姿直写接口。
|
||||
- 原网站假上游物理回归 3/3、公网非付费功能/安全回归 2/2;未调用真实付费模型。
|
||||
- 证据:`build/website-deployment/dual-camera-*`,含两路截图、`dual-cameras.json` 和 `dual-camera-kinematics.json`。
|
||||
|
||||
### 摄像头修正
|
||||
|
||||
已发布 `20260924T050135Z-camera-fix`,上一版本 `20260924T043358Z-builtin-robot`。修复只改变前端自动导入的相机预设及转换器对四元数的支持;后端打包逐文件无变化,ZIP 哈希不变。
|
||||
|
||||
- 648 项单测、TypeScript、ESLint、格式检查与本地/网站双构建通过。
|
||||
- 自动导入回归:开发 StrictMode 6/6、生产构建 6/6、公网 HTTPS 6/6;另有原网站假上游物理回归 3/3、公网非付费回归 2/2。
|
||||
- 公网真实 WASM 导出的相机光心约 `[0.13095586, 0.000000036, 0.06207925]` m,前向约 `[0.98480779, 0, 0.17364796]`,向上约 `[-0.17364796, 0, 0.98480779]`,与源 CAD 推导值误差小于 2e-6。确认镜头位置、朝前与图像上下方向,而非仅检查模型成功加载。
|
||||
- 证据:`build/website-deployment/camera-fix-*`,含 `front-camera.json` 与实际浏览器截图。未调用真实付费模型。
|
||||
|
||||
### 首次 URL 自动导入
|
||||
|
||||
已发布 `20260924T043358Z-builtin-robot`,上一版本 `20260924T035108Z-hosted`。通过既有成对发布/回滚流程,后端打包内容逐文件比较无变化,密钥和调用额度配置未改动。
|
||||
|
||||
- TypeScript、ESLint、变更文件格式检查及网站/本地双构建通过。
|
||||
- Vitest:133 文件、640 项通过;后端 unittest:43 项中 40 通过、3 项可选门禁跳过。
|
||||
- 自动导入浏览器回归:生产构建 6/6、开发 StrictMode 6/6、公网 HTTPS 6/6。
|
||||
- 原网站假上游+真实 WASM 动作/抓放/停止回归 3/3;公网非付费功能与安全回归 2/2。
|
||||
- 公网实际下载 ZIP 的 SHA256 与指定原包一致;真实浏览器确认模型显示、LeKiwi profile 生效、默认暂停、刷新可重新导入。未进行真实付费模型调用。
|
||||
- 本地证据:`build/website-deployment/robot-url-*`(日志、发布校验和浏览器截图)。
|
||||
|
||||
## 验证命令
|
||||
|
||||
```bash
|
||||
npm run typecheck
|
||||
npm run lint
|
||||
npm test
|
||||
npm run build:website
|
||||
npm run test:e2e:builtin
|
||||
# 开发态 React StrictMode:
|
||||
CADWORLD_BUILTIN_DEV=1 npm run test:e2e:builtin
|
||||
# 独立真实 WASM 双摄像头随动回归,不接控制桥/付费模型:
|
||||
npx playwright test -c web_platform/playwright.lekiwi.config.ts lekiwi.cameras.spec.ts
|
||||
# 显式对真实网站执行,无付费模型调用;故障测试仅在本浏览器拦截资源:
|
||||
CADWORLD_PRODUCTION_TEST=1 npm run test:e2e:builtin
|
||||
```
|
||||
|
||||
覆盖真实 ZIP 校验、无效参数/任意 URL 拒绝、HTTP 错误、损坏/超大文件、取消;浏览器覆盖真实 WASM 自动加载/profile、双相机位置/朝向与视角切换、暂停、刷新、无参数不下载、重复/未知参数及失败后手动导入。开发态仅把 ZIP 字节请求计为下载,Vite 的 `.zip?import&url` 是小型 JS 地址模块,不能误计或拦截它。
|
||||
+32
-2
@@ -1,6 +1,36 @@
|
||||
# LeKiwi 智能抓放:实施进度与物理基线
|
||||
# LeKiwi 语言控制与物理基线
|
||||
|
||||
当前计划 **10/10 已完成**。自动回归、物理故障与真实双 API 回合已通过;用户明确确认以 **DeepSeek `deepseek-flash` + OpenRouter `typesafe/jev-1.13` 的主工作台真实抓放**作为最终验收,不再要求本次订阅推理回合。仅仿真,不控制实机。
|
||||
## 当前版本:语言控制 v2(已部署,真实模型待验收)
|
||||
|
||||
网站已发布 `20260924T065821Z-language-v2`,公网非付费验证 3/3 通过;没有将部署/加载成功视为真实模型推理成功。[发布及回滚记录](lekiwi-language-v2-release.md)。
|
||||
|
||||
本地/网站统一为「控制台 → 机器人语言控制」,只保留预设、指令、执行/停止与简短状态。先点击**载入预设场景**,再输入:
|
||||
|
||||
- `把方块搬到 B 区`(A `[0.257,0.45,0.128]`,B `[0.257,0.75,0.128]`)。
|
||||
- `把方块搬到 (0.25,0.50) 米`,或 `搬到 X=0.25 Y=0.50 Z=0.128`。
|
||||
- 仍支持 `前进0.5米`、`左转90度`、`停止`。停止无需模型。
|
||||
|
||||
**坐标约定**:世界坐标、米、Z 向上;XY 根据真实支撑面补 Z,XYZ 的 Z 是方块中心而非台面。目标台允许输入的连续范围(不代表每个点都已做物理成功率评估)X `[0.237,0.277]`、Y `[0.365,0.865]`,Z `0.128`;另保留源台支撑区域。支持米/厘米/毫米,但不接受任意空间点、悬空目标、未知对象或相对坐标。单次持物搬运距离 `0.08–1 m`。底盘需处于预设净空走廊 X `[-0.06,0.04]` / Y `[-0.12,0.95]`、初始航向误差 ≤0.15 rad,超出时明确拒绝而非通用导航。
|
||||
|
||||
只有“载入预设”会重建场景;执行不重置方块、不移动支撑台,支持从上次放置后的实测位置再次搬运。空工作台点击加载可校验并导入内置机器人;替换其他工程需确认。地图/RL 和双摄像头保留。旧面板的配置、mock、单技能/导出按钮已移除;诊断通过只读 `robot-task-result` 事件采集,不提供仿真写句柄。旧 v1 物理/API 夹具保留,不代表旧产品界面仍存在。
|
||||
|
||||
### 分层实现
|
||||
|
||||
- **LLM 任务层**:`/command` 解析受限意图与目标,`/plan` 给出带前置条件的合法技能链。两次请求共用 run/scene 身份与预算;后端配置模型,见 [本地启动](../decision_server/README.md)。没有服务时明确报错,不转 mock。
|
||||
- **Jev 监督层**:`TaskSupervisor` 消费一次多问题请求中的 Choice(合法切换)、Noul(allow/deny/uncertain)、Score(离散等级)。等级 poor/partial/good/excellent 映射 0/25/75/100,unavailable 不评分;它是**最近技能边界**的模型意见,不是概率或终局物理成功。为减少调用,本轮不增加可选终局评分请求。
|
||||
- **执行层**:`TaskPlanner` 根据实测状态计算停靠位并以 scratch IK 预检;`PickPlaceExecutor` 复用限速伺服/技能与物理证据,添加收臂/接近阶段。正常夹爪—台面接触仅在指定抓放阶段、底盘速度 ≤0.03 m/s、总力 ≤20 N 时允许;其他外部碰撞停止。这是仿真阈值,不是实机安全认证。
|
||||
- **底层**:原 MuJoCo 位置/速度伺服与唯一 `SimulationSession` 时钟,不引入 ROS2/MoveIt2,不瞬移物体、不焊接吸附。等待模型冻结物理,迟到响应、取消和硬安全不能被模型覆盖。
|
||||
|
||||
### 本轮精简验收
|
||||
|
||||
- 主工作台真实 WASM+同源网关+**假 HTTP 模型上游**连续两次成功:B 区有效搬运 **0.728882 m**、误差 **7.54 mm**;自由坐标有效搬运 **0.241201 m**、误差 **8.92 mm**。每任务 2 次 LLM / 14 次 Jev(含意图审核),Score=75 来自明确假上游,不是真实模型能力证明。证据:`build/e2e/lekiwi-language/`。
|
||||
- 20 个停靠位/高度 scratch IK 检查与真实夹爪锁开失败用例通过;锁开为 `empty_grasp`、搬运 0、成功 false。证据:`build/e2e/lekiwi-language-safety/`。
|
||||
- 原 v1 种子 0 基线通过,搬运 0.593793 m;网站构建移动/转向/停止两用例通过。证据:`build/e2e/lekiwi-language-v1-regression/`、`build/e2e/lekiwi-language-website-smoke/`。
|
||||
- 定向前端 13 文件 / 83 测试通过;Python 29 项中 28 通过、1 个既有可选项跳过;typecheck、定向 lint、双构建通过(保留大 chunk 提示);未跑全仓/训练/多种子耐久。实现验收未读取真实密钥、未调用真实 LLM/Jev;随后已按用户要求部署,沿用服务器凭据,公网仅做非付费验证。真实模型需后续用服务器配置明确授权验收,不能引用下方历史结果当作 v2 通过。
|
||||
|
||||
## 以下为 v1 历史记录(旧界面与旧验收)
|
||||
|
||||
当时计划 **10/10 已完成**。自动回归、物理故障与真实双 API 回合已通过;用户明确确认以 **DeepSeek `deepseek-flash` + OpenRouter `typesafe/jev-1.13` 的主工作台真实抓放**作为最终验收,不再要求本次订阅推理回合。仅仿真,不控制实机。
|
||||
|
||||
ChatGPT 隔离官方登录已确认成功,未发现隔离 HOME 中的 `auth.json`,没有读取全局登录。订阅浏览器用例在模型请求前因选择器未匹配而中止(已为协议/型号下拉框补充显式可访问名称);用户随后要求结束验收,因此**未运行订阅推理**,不能宣称订阅抓放成功。该临时会话已关闭,LLM/Jev 请求均为 0。记录:`build/lekiwi-agent/subscription-login-only.json`;失败用例保留于 `build/e2e/lekiwi-agent-subscription-first/`。
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
# LeKiwi 语言控制 v2 网站发布
|
||||
|
||||
- 网站:<https://cadworld-sim.robotquan.com>
|
||||
- 版本:`20260924T065821Z-language-v2`;已于 2026-09-24 发布前后端。
|
||||
- 上一版本/回滚目标:`20260924T052730Z-dual-camera`。
|
||||
- 部署时按工作树白名单打包,未同时创建 Git 提交或标签;随后连同 iframe 响应头更新归档为 `v1.0.2`。
|
||||
|
||||
## 在线功能
|
||||
|
||||
打开「控制台 → 机器人语言控制」,点击「载入预设场景」,输入 `把方块搬到 B 区` 或 `把方块搬到 (0.25,0.50) 米`。无机器人时加载内置 LeKiwi;初始暂停,不自动执行或调用模型。
|
||||
|
||||
文字坐标限定为预设中真实可达支撑区域,不是任意空间点。LLM 解析/规划、Jev Choice/Noul/Score、本地物理安全与抓放评估均在当前版本中接通;**公网真实模型 v2 推理尚未验收**,不可把以下部署检查说成真实模型抓放成功。
|
||||
|
||||
## 发布检查
|
||||
|
||||
1. 修复旧打包脚本/Dockerfile 只携带 v1 schema 的遗漏,显式包含 v2 task schema 与 scene 配置。
|
||||
2. 本地 typecheck、部署脚本语法、定向 lint、网站构建与打包后后端导入通过;发布包 86 个 manifest 文件,逐文件 SHA-256 校验通过。
|
||||
3. 服务器复用锁定基础镜像与离线 wheels;镜像构建完成后,在无网络、无密钥/预算挂载的容器中验证后端导入及 B 区目标解析,再切换线上。
|
||||
4. 新服务健康、OpenResty 配置检查/reload 和公网 HTTPS 均通过。静态首页哈希匹配本地构建产物。
|
||||
5. 公网 Playwright **3/3**:Python 运行及精简界面;从空工作台加载 v2 预设、文字坐标输入/本地停止与双相机;会话创建/销毁、配置保护、订阅关闭及敏感路径不可访问。新增 v2 用例阻断所有推理请求并断言请求数为 0。
|
||||
6. 既有密钥文件和预算 SQLite 的 inode、权限与所有者保持不变,未轮换/复制密钥,未清空预算。发布重启会使旧访客会话失效,下次操作重新建立会话。
|
||||
|
||||
验证命令:
|
||||
|
||||
```bash
|
||||
CADWORLD_PRODUCTION_TEST=1 npx playwright test \
|
||||
-c web_platform/playwright.production.config.ts \
|
||||
--output=build/website-deployment/language-v2-production
|
||||
```
|
||||
|
||||
发布包 SHA-256:`02bf93c5933c483c95aaa7d24c8b321a3305061cf192003e46fdde9ef3b8ccc8`。
|
||||
|
||||
公网首页 SHA-256:`ae38f2d803cd89ac9e9b95a32b10dc7e470c875337071d67db0942b710468c41`。
|
||||
|
||||
证据位于 `build/website-deployment/language-v2-{baseline/,build.txt,bundle.txt,publish.txt,production/,final-health.txt,verification.json}`。本次发布验证付费推理调用数为 **0**;先前真实 WASM+假上游抓放结果见 [控制与验收说明](lekiwi-agent.md)。
|
||||
|
||||
## 回滚
|
||||
|
||||
在目标主机执行旧版本自带的发布脚本,使前后端成对恢复:
|
||||
|
||||
```bash
|
||||
bash /opt/cadworld-sim/releases/20260924T052730Z-dual-camera/deploy/publish.sh \
|
||||
20260924T052730Z-dual-camera
|
||||
```
|
||||
|
||||
不得删除 `/opt/cadworld-sim/secrets` 或 `/opt/cadworld-sim/budget`。本次未额外执行回滚演练,旧发布包与镜像仍保留。
|
||||
@@ -0,0 +1,69 @@
|
||||
# 公网 API 受控验收与能力边界修补 · 2026-09-24
|
||||
|
||||
> 本文是当天较早 BYOK 阶段的历史证据。用户随后改为服务器内置固定模型并要求语言移动/转向;当前实现与验收以 [最新记录](website-hosted-control-2026-09-24.md) 为准。
|
||||
|
||||
## 实际授权与付费调用
|
||||
|
||||
用户明确批准使用项目 `.env` 的 DeepSeek、Jev 两项测试密钥,仅按变量名通过既有凭据加载器读取,不 source 文件,不打印值,不使用全局 Codex 账号。
|
||||
|
||||
仅运行一次公网 HTTPS 真实回合:
|
||||
|
||||
- 服务器:`cadworld-sim.robotquan.com`,当时发布 `20260923T130923Z-web`。
|
||||
- 真实上游:DeepSeek `deepseek-flash`(Responses)与 OpenRouter `typesafe/jev-1.13`(decisions)。
|
||||
- 限额:最多 1 次规划/12 次判定;禁用重试、连接测试和提供方/型号切换。
|
||||
- 实际:**1 次规划+11 次判定,12 份服务回执,物理验收成功**。
|
||||
- 仿真 `47.220 s`、有效搬运 `0.5937274002 m`,最终目标支撑成立,两指力均为 0。
|
||||
- DeepSeek 报告输入 912、输出 814、合计 1726 token,**未报告费用**。
|
||||
- Jev 报告输入 15,307、输出 2,196 token,合计费用 **$0.000642894**。该数不包含 DeepSeek,也不是完整账号账单。
|
||||
- 测试结束 DELETE 会话成功;浏览器关闭,没有保存 Cookie/storage state/trace/HAR,输入框保存后清空,导出通过凭据泄漏检查。
|
||||
|
||||
这只证明**固定单方块抓放场景**的真实双 API 闭环,不能证明任意中文指令可控制机器人。
|
||||
|
||||
证据:`build/website-deployment/live-20260924/` 下的 `website-live-summary.json`、`website-live-physical-evidence.json` 和成功截图。
|
||||
|
||||
## 两个问题的原因与处理
|
||||
|
||||
### 订阅点击后不打开网页
|
||||
|
||||
当前设计是官方设备码登录:服务器先申请设备码与验证地址,再由用户点击官方链接;不是按钮直接自动弹窗。服务器实测 `auth.openai.com` 返回 403,ChatGPT 推理地址连接被拒绝;真实设备码请求仍返回 502 / `codex_rpc_failed`,没有生成可使用的设备码/链接。
|
||||
|
||||
已将状态和错误移到登录按钮旁,明确申请步骤及没有验证链接的情况。未改用非官方中转,未借用全局账号,未自动切付费 API。服务器网络/官方资格问题未解决,订阅仍不可用。最终容器内活动 Codex 进程数为 0。
|
||||
|
||||
### 编辑中文指令但动作不变
|
||||
|
||||
`MockDecisionProvider.plan()` 不读取指令;真实规划契约也强制固定物体、固定技能顺序,动作目标由场景坐标决定。原界面允许任意编辑会造成“指令已生效”的错误预期。
|
||||
|
||||
本次网站防误执行保护:
|
||||
|
||||
- 明确标注“固定单方块抓放,非自由中文任务控制”。
|
||||
- mock 模式禁用无效的指令编辑。
|
||||
- 自定义指令在开始前被拦截,不加载旧任务、不调用模型,并提供恢复标准指令按钮。
|
||||
- 放置目标仍通过已有受限坐标修改,安全门禁不变;本地模式行为保留。
|
||||
|
||||
**尚未实现把任意中文转换为新任务。** 待用户提供具体希望执行的指令后,才能确定所需技能、任务约束与验收;不能用取消安全顺序验证来假装支持。
|
||||
|
||||
## 修补发布与非付费回归
|
||||
|
||||
- 新发布:`20260924T023534Z-web`;可回滚:`20260923T130923Z-web`。
|
||||
- 后台代码未改变,镜像仍为 `sha256:f3375d42b54f6bbdb65d31ba275d6fd6c415917b71a2f01f4cdb6893d9f1678c`,healthy。
|
||||
- `v1.0.1` Git 标签保持不动;本次修补未另行提交 Git。
|
||||
- TypeScript/ESLint、615 项 Vitest、local/website 双生产构建通过。
|
||||
- 网站生产资源+真实网关/假上游 E2E 2/2;公网订阅边界与 mock 物理回合通过。
|
||||
- 公网设置/新指令拦截/Pyodide用例首次因 `getByLabel(exact)` 对包裹 textarea 的 label 文本匹配失败;改用可访问 `textbox` 角色后单独复测通过,未修改业务代码来放宽断言,失败证据保留。
|
||||
- 未重复付费验收;新发布只更改前端提示/启动保护,标准任务及后台推理代码未变。
|
||||
|
||||
部署/非付费证据:`build/website-deployment/{publish-20260924.txt,production-20260924,production-guards-recheck-20260924,website-guards-20260924}/`。
|
||||
|
||||
## 第 9 步剩余项
|
||||
|
||||
DeepSeek+Jev 完整回合与订阅受限状态已验证。原计划另要求一个 **OpenRouter 主规划模型**的单次真实结构化输出;本次批准的是 Jev 角色密钥,没有将其静默挪作其他模型用途。因此该项仍待用户确认独立角色/具体模型及单次调用许可,第 9 步不虚假标记全部完成。
|
||||
|
||||
## 显式重跑命令(会计费,需重新获准)
|
||||
|
||||
```bash
|
||||
CADWORLD_LIVE_API=1 npx playwright test \
|
||||
-c web_platform/playwright.website-live.config.ts \
|
||||
--output build/website-deployment/live-<日期>
|
||||
```
|
||||
|
||||
不要开启 trace、录屏、storageState、自动重试或调试日志,不要把真实密钥写在命令行。普通测试不会自动执行该用例。
|
||||
+22
-2
@@ -2,6 +2,26 @@
|
||||
|
||||
网站模式与原本机 Bearer 模式分别启动,不自动降级。前缀 `/api/decision/v1`。
|
||||
|
||||
当前生产启用服务器内置固定配置,不接收前端密钥。`/configuration`、`/models`、`/test`、`/codex/*` 在此模式统一返回 403;表中这些接口只保留给非共享兼容模式。会话返回 `configurationManaged:true`、`keyStorage:"server-managed"`,不会返回密钥。
|
||||
|
||||
### 新源码 v2 语言任务(需前后端一同部署)
|
||||
|
||||
URL 前缀仍为 `/api/decision/v1`(传输 API),数据版本为 `lekiwi-language-v2`;旧 v1 校验保留,不接受跨版本混用。
|
||||
|
||||
`POST /command` 可输入 `{instruction,stamp,sceneContext}`。sceneContext 包含 `version`、固定 `sceneId:lekiwi-language-scene-v2`、`source:mujoco-ground-truth`、`units:SI`、`frame:world-z-up`、实测 `object:[x,y,z]`、`base:[x,y,z]` 与 `yaw`。台面/命名区来自服务端固定预设,不接受模型生成新场景。
|
||||
|
||||
返回 value 固定字段 `{version,action,value,summary,objectId,targetId,position,supportId}`。抓放 objectId=block,targetId 为 A/B(position=[])或 coordinates(position=XY/XYZ),supportId 为 source/table;其他动作三个 ID 为 none、position=[]。坐标统一米、Z 为物体中心;单位/明确数值与原始指令独立交叉校验,未知目标/无支撑/越界/高度不符拒绝。抓取→搬运→释放是一项合法任务,不等于允许任意多指令串联。
|
||||
|
||||
`/plan`、`/decide` 按 observation.version 分派 schema。v2 增加 stow/approach 两个前置阶段;Jev 同一请求返回 choice、grasp、diagnosis、recovery 和 noul/score/reason。noul 为 allow/deny/uncertain;score 是 poor/partial/good/excellent/unavailable 离散等级,不能代替物理验收。v2 仅支持服务端 API 模型,不通过新版面板发起订阅登录;旧 v1 程序化订阅接口不删除。
|
||||
|
||||
指令和后续技能闭环共享 runId/sceneRevision,LLM 初始调用共 2 次,Jev 包括 1 次意图审核及技能边界审核;预算不重置。浏览器不自动重载场景、不静默转 mock。最终脱敏只读事件为 `robot-task-result`,含 snapshot、commandReceipt 和本任务 receipts,不含密钥。
|
||||
|
||||
### 旧指令兼容
|
||||
|
||||
`POST /command` 不带 sceneContext 时输入 `{instruction,stamp}`,返回标准 stamped 回执:`value:{action,value,summary}`,`usage:{llm,jev?}`。动作枚举为 `move`(有符号米,正前负后,绝对值 0.01–1)、`turn`(有符号度,正左负右,1–180)、`pick_place`、`stop`、`clarify`(后三者 value=0)。单次不接受复合动作,不猜缺失方向;具体单位/数值/输出字段由代码再验证,模型只给受限意图,不能写执行器或宣布成功。
|
||||
|
||||
DeepSeek 理解后,运动/抓放意图再经 Jev 选择 allow/stop;同一取消标识覆盖两个调用。浏览器等待期间暂停物理,响应到达后重新核对会话、场景、位姿/控制目标、取消代次,过期响应不执行。运动使用现有单一物理时钟、闭环速度与角度控制、碰撞/姿态/时间上限和实际误差验收。旧 v1 `/plan` 仍仅供原固定抓放技能链;新版按上述版本分派。
|
||||
|
||||
| 路径 | 方法 | 语义 |
|
||||
| ----------------------------------------------- | ------ | --------------------------------------------------------------------- |
|
||||
| `/session` | POST | 同源 JSON 空对象建立/恢复会话,返回 CSRF、版本、设置状态;不调用模型 |
|
||||
@@ -15,6 +35,6 @@
|
||||
|
||||
生产 Cookie 为 `__Host-cadworld-session; Secure; HttpOnly; SameSite=Strict; Path=/`,无 Domain。修改/推理携带 `X-CSRF-Token` 和 `X-Config-Version`,精确 Origin/Host 校验。开发 HTTP 只接受显式 `--website-dev` 与回环来源,用不同 Cookie 名,不改变生产要求。代理只信任配置的来源 IP,覆盖外来转发头。
|
||||
|
||||
省略 apiKey 表示同提供方保留内存密钥,换提供方必须重填;清除通过销毁整个会话完成。配置草稿不改变后台,保存不推理。并发标签页以配置版本拒绝旧配置。错误只返回稳定错误码,不回显上游文本。
|
||||
以下配置语义适用于非共享兼容模式:省略 apiKey 表示同提供方保留内存密钥,换提供方必须重填;清除通过销毁整个会话完成。配置草稿不改变后台,保存不推理。并发标签页以配置版本拒绝旧配置。错误只返回稳定错误码,不回显上游文本。
|
||||
|
||||
会话空闲 30 分钟、最长 8 小时,状态轮询不续期。最多 128 会话,单会话 1 推理、全局 8 推理、2 Codex 账号;会话/IP/全局限流分别生效。浏览器模型 ZIP 不上传。真实 API/订阅验收必须由用户显式授权,不加载仓库 `.env`。
|
||||
会话空闲 30 分钟、最长 8 小时,状态轮询不续期。默认最多 128 会话,单会话 1 推理;非共享模式默认全局 8 推理、2 Codex 账号,生产共享模式覆盖为全局 2 推理且不开放 Codex;会话/IP/全局限流分别生效。浏览器模型 ZIP 不上传。服务不自动发现仓库 `.env`;共享模式通过显式 `--website-key-file` 读取受保护服务器文件。另有跨会话、跨进程的 60 次/小时、600 次/24h 上游调用预留限额(持久 SQLite,`/command` 每次预留 2,其他推理 1;失败不退款),生产并行上限为 2。用户后续要求固定 DeepSeek+Jev,故不再把 Jev Key 用于其他 OpenRouter 主规划模型。当前结果与限制见 [内置模型/语言控制记录](website-hosted-control-2026-09-24.md);此前 BYOK 阶段的实测保留于 [历史受控验收](website-acceptance-2026-09-24.md)。
|
||||
|
||||
+15
-10
@@ -2,13 +2,17 @@
|
||||
|
||||
目标:`https://cadworld-sim.robotquan.com`,主机 `root@47.93.31.109`。复用 1Panel 的 OpenResty,独立容器仅发布 `127.0.0.1:8768`。不安装训练/GPU 服务,不改系统 Python,不需要访问者开启终端。
|
||||
|
||||
当前在线版本:`20260924T065821Z-language-v2`,上一版本 `20260924T052730Z-dual-camera`。前后端共同发布,公网非付费检查通过;详见 [发布记录](lekiwi-language-v2-release.md)。
|
||||
|
||||
iframe 嵌入已通过响应头热更新放行 `https://cadworld.robotquan.com`,未重启应用;接入示例、验证范围与配置回滚见 [嵌入说明](website-embedding.md)。重新发布旧包会覆盖该热更新,应从当前源码重新构建。
|
||||
|
||||
## 产品边界
|
||||
|
||||
- 网站公开、无需注册。LLM 选择 DeepSeek/OpenRouter 并填写自己的 API_KEY;Jev 单独填写 OpenRouter API_KEY,型号固定 `typesafe/jev-1.13`。
|
||||
- 保留 ChatGPT 官方设备码登录。当前主机对官方订阅端点的连通性不稳定,入口会诚实显示失败;订阅资格、额度和真实推理需要用户验证,不自动转收费 API。
|
||||
- 密钥经 HTTPS 到后端,只在会话内存;浏览器输入保存后清空,不进入 URL/存储/日志。空闲 30 分钟或最长 8 小时销毁。关页不保证立即销毁,可点击“清除本次凭据”。同浏览器标签页共享会话,配置版本隔离旧任务;其他浏览器独立。
|
||||
- ZIP/URDF/地图/物理仿真仍在浏览器。网站隐藏训练、调参和外控,浏览器 Python/ONNX 保留;本地 `npm run dev` 的旧功能不变。
|
||||
- 容量:128 会话、每会话 1 推理/120 次每小时、全站 8 推理和 2 个订阅账号;按 IP 另有限额。匿名限制不是无限防滥用承诺,需持续观察负载。
|
||||
- 网站公开、无需注册或前端输入密钥。按用户新要求固定服务器 DeepSeek `deepseek-flash` 和 OpenRouter Jev `typesafe/jev-1.13`,费用由站长承担;前端移除模型/密钥/订阅配置。
|
||||
- 官方订阅仍在旧本地/非共享服务实现中保留,但当前共享密钥网站关闭其接口(403),没有绕过官方网络限制或登录其他账号。
|
||||
- 仅两项授权密钥存于 `/opt/cadworld-sim/secrets/model-keys.env`(0400、UID 10001,父目录 root/0700),只读挂载;不进入镜像、静态目录、发布包、浏览器或日志。每访客任务状态独立,空闲 30 分钟/最长 8 小时销毁;删除会话不会删除站长的服务器配置。
|
||||
- ZIP/URDF/地图/物理仿真仍在浏览器。网站隐藏训练、调参和外控,浏览器 Python/ONNX 保留;本地训练/外控功能保留,语言面板与网站统一精简并使用同源模型后端。
|
||||
- 容量:128 会话、每会话 1 推理/120 次每小时,生产全站并行上限 2。共享 SQLite 限额为每小时 60、滚动 24h 600 次上游调用;`/command` 保守预留 2 次,失败不退款,不自动重试。预算在 `/opt/cadworld-sim/budget`,不得在重启/发布时删除。匿名访问仍可能耗尽公共额度;建议供应商侧另设金额上限,当前不是货币金额硬预算。
|
||||
- 备案已由站长确认;正式备案/公安备案展示号码由站长提供,不能编造。TLS 证书首次无邮箱注册,自动续期由 systemd timer 负责,建议管理员另行设置证书到期监控。
|
||||
|
||||
## 本地开发与测试
|
||||
@@ -22,17 +26,18 @@ npm run build:website # 输出 website-dist/,不含 tuning.html
|
||||
npm run test:e2e:website # 真实后端 + 假 HTTP 上游,无 API 额度消耗
|
||||
```
|
||||
|
||||
生产必须 HTTPS,不能携带 `--website-dev`。前后端 Origin 要一致;本机 Bearer 模式仍使用 `npm run decision-server`,两种模式不自动回退。契约见 [website-api.md](website-api.md)。
|
||||
上述不带密钥启动方式只调试界面,执行会提示服务未就绪;真实开发需另显式提供 `--website-key-file` 和 `--website-budget-file`,不自动读取仓库 `.env`。生产必须 HTTPS,不能携带 `--website-dev`。前后端 Origin 要一致;本机 Bearer 模式仍使用 `npm run decision-server`,两种模式不自动回退。契约见 [website-api.md](website-api.md)。
|
||||
|
||||
## 构建、传输与首次发布
|
||||
|
||||
1. 保留工作树变更基线,运行 TS/Vitest/Python/Playwright 门禁。`build/website-deployment/baseline/` 保存部署前工作树摘要,不包含 `.env`。
|
||||
2. 使用 [官方 crane v0.20.6](https://github.com/google/go-containerregistry/releases/tag/v0.20.6),校验 release checksums。将 `deploy/cadworld/images.lock.json` 中的 linux/amd64 digest 拉为 docker archive(`crane pull --platform linux/amd64 REF FILE`);不需要本机 Docker daemon,也不让服务器访问不明镜像源。
|
||||
3. 为 Python 3.12 下载 `requirements.lock.txt` 指定 wheels,验证 hash;从官方 npm `@openai/codex@0.147.0-linux-x64` 包验证 registry 的 integrity 后提取二进制。文件放在 `build/website-deployment/vendor/{wheels/,codex,codex-origin.json}`。不复制任何用户的 Codex HOME/auth.json。
|
||||
4. `npm run build:website` 后运行 `python3 deploy/cadworld/prepare_bundle.py RELEASE`。脚本只打包显式白名单、生成每文件 SHA-256,并输出归档 SHA-256;不打包 `.env/.git/.venv/build/`、测试代码或个人模型。
|
||||
4. `npm run build:website` 后运行 `python3 deploy/cadworld/prepare_bundle.py RELEASE`。脚本只打包显式白名单(含 v1 schema、v2 task schema、v2 scene 三个运行契约)、生成每文件 SHA-256,并输出归档 SHA-256;不打包 `.env/.git/.venv/build/`、测试代码或未批准的个人模型。明确内置的 `web_platform/assets/robots/lekiwi-v1.zip` 随 Vite 生成带哈希的静态资产,必须连同整个 `website-dist/` 发布;`/?robot=lekiwi-v1` 即可自动导入,详见 [内置机器人](builtin-robots.md)。
|
||||
5. SSH 传送归档、两份镜像 tar 和 SHA-256 到 `/opt/cadworld-sim/uploads/`。核验 SHA-256 后解压到 `/opt/cadworld-sim/releases/RELEASE/`,运行该版本的 `deploy/import-images.sh IMAGE_DIRECTORY`。先确认 `172.30.88.0/24` 不与现有 Docker 网络冲突。
|
||||
6. 首次运行 `bash /opt/cadworld-sim/releases/RELEASE/deploy/bootstrap-tls.sh`:备份原 OpenResty conf,创建独立 HTTP challenge vhost,签发域名证书,安装 HTTPS vhost 与续期 timer。不修改默认站点/1Panel账号;已存在同域名配置则拒绝覆盖。
|
||||
7. `bash /opt/cadworld-sim/releases/RELEASE/deploy/publish.sh RELEASE`:逐文件验 hash、离线构建、启动最小权限容器、健康检查、原子切换静态目录、`nginx -t`、reload。失败恢复上一版本,首次失败撤下新 vhost 恢复默认站点。成功生成 `current.txt/previous.txt/image-id.txt`。
|
||||
7. 站长明确授权后,在本机执行 `source .venv/bin/activate && python deploy/cadworld/install-model-keys.py --confirm-server-keys`,只选取项目 `.env` 的两项固定变量,经 SSH 标准输入传输;同时扫描静态资源避免密钥泄漏。不会把整个 `.env` 复制过去;若既有值不同则拒绝覆盖,轮换须单独授权。该步骤在共享模式首次发布前完成。
|
||||
8. `bash /opt/cadworld-sim/releases/RELEASE/deploy/publish.sh RELEASE`:逐文件验 hash、离线构建、无网络/无密钥挂载的运行时导入与 v2 契约预检、启动最小权限容器、健康检查、原子切换静态目录、`nginx -t`、reload。失败恢复上一版本,首次失败撤下新 vhost 恢复默认站点。成功生成 `current.txt/previous.txt/image-id.txt`。
|
||||
|
||||
只有 80/443 提供网站流量;8768 绑定回环。不挂载 Docker socket、SSH key、宿主 HOME;应用非 root、只读根、tmpfs、2 GiB/2 CPU/128 PID 限制。证书在已有 OpenResty www 挂载下独立 `ssl/`,不在站点 document root 内。
|
||||
|
||||
@@ -45,7 +50,7 @@ docker compose --env-file release.env -f compose.yaml logs --tail 100 decision
|
||||
curl -H 'Host: cadworld-sim.robotquan.com' http://127.0.0.1:8768/healthz
|
||||
systemctl status cadworld-certificate.timer
|
||||
bash /opt/cadworld-sim/renew-certificate.sh --dry-run
|
||||
# 后台更新/重启会销毁所有临时凭据,用户需要重新输入/登录:
|
||||
# 后台更新/重启会销毁访客会话;固定密钥和共享限额保留,用户再次执行建立新会话:
|
||||
docker compose --env-file release.env -f compose.yaml restart decision
|
||||
# 回滚:取 previous.txt 中的具体版本,调用那个版本的发布脚本,前后端一起恢复。
|
||||
bash /opt/cadworld-sim/releases/PREVIOUS/deploy/publish.sh PREVIOUS
|
||||
@@ -55,4 +60,4 @@ bash /opt/cadworld-sim/releases/PREVIOUS/deploy/publish.sh PREVIOUS
|
||||
|
||||
## 验证边界
|
||||
|
||||
普通测试使用假上游,不证明云端模型可用;mock 抓放使用真实 WASM 物理,不证明真实 LLM/Jev 被调用。真实 API 测试必须由用户明确提供密钥并触发,订阅登录须在官方页面交互。`HEAD` 的 200/401/403/404 只作为连通性证据,不是 POST 推理成功。生产证书、重启/回滚及浏览器验证结果另见实际发布记录。
|
||||
普通测试使用假上游,不证明云端模型可用;mock 抓放使用真实 WASM 物理,不证明真实 LLM/Jev 被调用。真实 API 测试必须经站长授权并限定调用数:`CADWORLD_LIVE_API=1 npx playwright test -c web_platform/playwright.website-live.config.ts --output build/website-deployment/本次目录`。当前 v2 用例最多 4 次 DeepSeek/16 次 Jev,不读取浏览器凭据、不自动重试,任何安全停止如实记录。`HEAD` 的 200/401/403/404 只作为连通性证据,不是 POST 推理成功。生产证书、重启/回滚及浏览器验证结果另见实际发布记录。当前发布、调用费用和未完成的抓放复验见 [服务器内置与语言控制记录](website-hosted-control-2026-09-24.md)。回滚到此前 BYOK 版本会恢复旧界面;受保护密钥文件和预算目录保留但旧服务不使用它们。
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
# 网站 iframe 嵌入
|
||||
|
||||
2026-09-24 已为 `https://cadworld.robotquan.com` 开放嵌入。
|
||||
|
||||
## 同事网站接入
|
||||
|
||||
```html
|
||||
<iframe
|
||||
src="https://cadworld-sim.robotquan.com/"
|
||||
title="CADWorld Sim"
|
||||
style="width: 100%; height: 900px; border: 0;"
|
||||
allow="fullscreen"
|
||||
allowfullscreen
|
||||
></iframe>
|
||||
```
|
||||
|
||||
如需自动加载内置机器人,可使用 `https://cadworld-sim.robotquan.com/?robot=lekiwi-v1`。加载不会自动发起模型推理。
|
||||
|
||||
- 若父页面自身有 CSP,须在其 `frame-src` 中允许 `https://cadworld-sim.robotquan.com`。
|
||||
- 默认不用 `sandbox`。若同事必须使用 sandbox,请至少评估 `allow-scripts allow-same-origin`:缺少脚本权限无法运行应用,缺少真实来源会导致同源请求/会话失效;下载等能力需按实际需求额外授权。
|
||||
- 白名单仅包含精确 HTTPS 来源,不包含 HTTP、非默认端口、其他子域名或任意 `www` 前缀。多层嵌套时,每一层祖先都必须匹配白名单。
|
||||
- 此设置允许展示和在 iframe 内操作,不授权父页面直接读取 iframe DOM 或调用模型 API。父子页面消息接口未实现。
|
||||
|
||||
## 响应头与会话
|
||||
|
||||
已移除 `X-Frame-Options: DENY`,未改成仍会阻止跨来源嵌入的 `SAMEORIGIN`,也不使用已废弃的 `ALLOW-FROM`。CSP 的其他指令不变,仅调整为:
|
||||
|
||||
```text
|
||||
frame-ancestors 'self' https://cadworld.robotquan.com;
|
||||
```
|
||||
|
||||
两个 HTTPS 站点属于相同 schemeful site `https://robotquan.com`,因此沿用 host-only、Secure、HttpOnly、SameSite=Strict 会话 Cookie。API Origin、Fetch Metadata、CSRF 和 CORS 限制不放宽。iframe 自身发出的同源请求通过,父页面直接访问 API 仍被拒绝。
|
||||
|
||||
## 发布与验证
|
||||
|
||||
本次为 **OpenResty 响应头热更新**,标识 `20260924T071933Z-iframe`。未重启后端,前后容器 ID 和启动时间相同;应用版本仍为 `20260924T065821Z-language-v2`。
|
||||
|
||||
- 本地 `deploy/cadworld/openresty.conf` 同步更新,未来新发布包会保留该白名单。
|
||||
- 更新前后配置与备份位于服务器 `/opt/cadworld-sim/config-updates/20260924T071933Z-iframe/`,旧配置为 `previous.conf`。
|
||||
- 已执行 `nginx -t`、reload、公网响应头与浏览器测试。**3/3 通过**:精确允许来源及安全头;允许来源内加载真实线上应用、会话建立/读取/销毁和 CSRF 防护;未授权同站子域名被 CSP 拒绝。
|
||||
- 浏览器测试只合成指定来源的父页面 HTML,iframe 及 API 均访问真实网站;没有修改同事网站,也不代表已经验证其实际页面的 CSP/sandbox 等设置。
|
||||
- 未触发付费推理。证据:`build/website-deployment/iframe-20260924T071933Z/`。
|
||||
|
||||
```bash
|
||||
CADWORLD_PRODUCTION_TEST=1 npx playwright test \
|
||||
-c web_platform/playwright.production.config.ts website.embed.production.spec.ts \
|
||||
--output=build/website-deployment/iframe-20260924T071933Z/browser
|
||||
```
|
||||
|
||||
旧发布包及其 manifest 没有被修改。重新发布原始旧包会覆盖热更新的头设置;应使用更新后的源码重新构建发布,或重新应用已验证的头配置。
|
||||
|
||||
仅回滚本次响应头(目标主机):
|
||||
|
||||
```bash
|
||||
cp -p /opt/cadworld-sim/config-updates/20260924T071933Z-iframe/previous.conf \
|
||||
/opt/1panel/apps/openresty/openresty/conf/conf.d/cadworld-sim.robotquan.com.conf
|
||||
docker exec 1Panel-openresty-m72w nginx -t && \
|
||||
docker exec 1Panel-openresty-m72w nginx -s reload
|
||||
```
|
||||
@@ -0,0 +1,76 @@
|
||||
# 服务器内置模型与语言控制 · 2026-09-24
|
||||
|
||||
## 用户最新要求及安全实现
|
||||
|
||||
用户要求网站使用项目 `.env` 中的密钥,不再让前端填写 API,默认 DeepSeek flash / Jev 1.13,并支持“前进0.5m”“转动90度”等语言控制。
|
||||
|
||||
已采用**服务器配置**而非把秘密编入网页:
|
||||
|
||||
- 只读取授权的 `Deepseek_API_KEY` 与 `OPENROUTER_API_KEY`。没有整份上传 `.env`,没有读取其他凭据或全局 Codex 登录。
|
||||
- 固定 `deepseek-flash` / Responses 与 `typesafe/jev-1.13` / OpenRouter Decisions,不改模型或使用其他 OpenRouter 主规划模型。
|
||||
- 密钥通过 SSH 标准输入传输,不进命令参数或日志。服务器文件 `/opt/cadworld-sim/secrets/model-keys.env` 为 0400 / 10001:10001,父目录 root/0700;仅文件只读挂入应用容器。
|
||||
- 网页/静态包/镜像/Git 均无密钥。上线前对静态构建扫描两项真实密钥;公网 `/.env` 和 `/run/secrets/model-keys.env` 返回 404。
|
||||
- 前端无模型、密钥、BYOK 或订阅设置;公开配置、模型目录、付费连接测试和订阅接口在共享模式返回 403。本地旧界面和官方订阅实现不删除。
|
||||
- 全站共享**60 次/小时、600 次/滚动24小时**的上游调用预留限额,生产并行 2;`/command` 预留 2 次,其他推理 1 次。失败不退款,SQLite 留在宿主预算目录;换会话/部署不会清零。
|
||||
- 这是调用次数限制,不是美元硬预算。公开用户可能耗尽公共额度,费用由站长承担;建议供应商侧另设金额上限。
|
||||
|
||||
## 当前支持
|
||||
|
||||
路径:**控制台 → 机器人语言控制**,先导入并选择 LeKiwi v1 profile。
|
||||
|
||||
- 前进/后退:0.01–1 米,沿当前机器人朝向。
|
||||
- 左转/右转:1–180 度;逆时针为左转,顺时针为右转。
|
||||
- 一次一个动作;“转动90度”方向不明则询问,不默认左/右,不执行原抓放任务。
|
||||
- 可输入“把方块搬到支撑台”请求固定台面抓放演示;该动作会重载演示场景。移动与转向不重载模型。
|
||||
- 停止按钮、文本“停止”、隐藏、卸载、换场景/控制权可取消。已运行其他控制器时在付费请求之前拒绝,需用户先停止它。
|
||||
|
||||
DeepSeek 只返回受限结构化意图,Jev 检查是否匹配单个请求。浏览器保留单一物理时钟与写入票据,使用实际底盘位姿闭环,而非修改 qpos/瞬移;完成要求误差稳定 0.3 s,位置 <8 mm、角度 <0.015 rad,且实际速度已降低。速度/加速度、倾斜/高度、障碍接触、时钟异常、30 s 仿真/60 s 墙钟上限均可停止动作。
|
||||
|
||||
范围仅为**模拟 LeKiwi、空旷平地**;没有任意机器人泛化、避障规划、任意物体或复合动作承诺。
|
||||
|
||||
## 实际验收(区分证据)
|
||||
|
||||
### 免费门禁
|
||||
|
||||
- TypeScript、ESLint、Ruff、625 项 Vitest(132 文件)、43 项后端测试含原生 Codex 无工具门禁通过。
|
||||
- local / website 生产构建通过;原本地工作台导入、mock 抓放、暂停继续与导出回归通过。
|
||||
- 网站生产资源+真实网关/假 HTTP 上游:前进、左转、沿新朝向前进、右转、后退、方向含糊拒绝、运动中停止、完整抓放均通过(3 个 E2E 用例)。
|
||||
- 公网非付费检查 2/2:Pyodide、无密钥输入、未配置机器人零推理、只读模型配置、订阅关闭、秘密路径 404、会话销毁。
|
||||
- 第一次假上游抓放测试失败是 fixture 总选第一候选、错误报告已夹紧导致;修正 fixture 按观测生成判断后通过,没有放松生产的物理校验。
|
||||
|
||||
### 一轮真实付费验证(未重试)
|
||||
|
||||
固定上游、没有前端填写密钥,最多批准 4 次 DeepSeek / 14 次 Jev;实际 **4 次 DeepSeek+13 次 Jev**,17 次预留。
|
||||
|
||||
| 指令 | 结果 | 真实物理证据 |
|
||||
| ---------------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 前进0.5米 | 成功 | 实际 `0.4966307933 m`,无重载/瞬移 |
|
||||
| 左转90度 | 成功 | 实际 `89.8288865163°`,从上一个动作结束位置开始 |
|
||||
| 把方块搬到支撑台 | **安全停止,未完整通过** | 搬运 `0.5937274002 m`,42.218 s 时已在目标支撑、双指力 0、夹爪 opening≈0.999685;松开后 Jev 对下一步选择 `stop`,未执行最后撤离/稳定验收 |
|
||||
|
||||
抓放末尾 Jev 同时报告 `grasp=empty, diagnosis=none, recovery=continue, choice=stop`。系统遵从 stop,不覆盖其判断、不伪报成功,也没有自动重试。此前 BYOK 阶段有完整真实抓放成功记录,但**不能将本轮停止改写成通过**。
|
||||
|
||||
- DeepSeek 报告合计 2709 token,未报告费用。
|
||||
- Jev 本轮合计报告 **$0.000644154**,不含 DeepSeek,不等于完整账单。
|
||||
- 测试会话已销毁;没有 trace/HAR、浏览器凭据输入或存储状态保存。
|
||||
- 真实动作测试发生在首次 hosted 发布;后续只加“其他控制器占用时先拒绝、避免无效付费”的预检及文档,未改动作算法/模型请求,未再次消费真实模型额度。
|
||||
|
||||
## 发布与运维
|
||||
|
||||
- 当前:`20260924T035108Z-hosted`。
|
||||
- 上一版/回滚:`20260924T032955Z-hosted`(同为服务器内置配置)。
|
||||
- 当前镜像:`sha256:ad1333475d46ae86776f05210c53b71891a31a9fd407d48a86917a8c6c9c3f3a`,healthy。
|
||||
- 应用 10001:10001、只读根、宿主仅回环端口;未重启 1Panel/Docker 等无关服务。
|
||||
- 第二次发布替换容器后实际查询预算仍为 **17**,证实未重置。未删除密钥或预算目录。
|
||||
- `v1.0.1` 标签保持不变,本轮代码未另行 commit/push。
|
||||
|
||||
证据(本地,不随站点发布):
|
||||
|
||||
- `build/website-deployment/hosted-live/`:两项运动成功、抓放停止 JSON 与调用汇总。
|
||||
- `hosted-fixture-final/`、`hosted-motion-final/`、`hosted-local-regression/`:免费物理回归。
|
||||
- `hosted-production-final/`:公网非付费 2/2。
|
||||
- `hosted-security.txt`、`hosted-final-health.txt`:权限、镜像、健康、跨容器预算持久化。
|
||||
|
||||
## 计划剩余
|
||||
|
||||
用户已改为固定 DeepSeek+Jev,因此不再安排其他 OpenRouter 主规划模型收费测试。语言控制与服务器内置配置已交付;本次完整抓放复验未全部通过,**第 9 步暂不标记完成**。若继续,需要用户批准一次额外受控复验或明确接受该安全停止边界;不能静默增加调用、替换模型或绕过 Jev。
|
||||
Reference in New Issue
Block a user