0d986f60bd
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 云模型抓放仍待单独验收,不包含运行密钥或构建产物。
110 lines
11 KiB
Markdown
110 lines
11 KiB
Markdown
# LeKiwi 本机模型服务
|
||
|
||
独立于训练、控制桥和 MuJoCo;只接收结构化状态并返回经校验的计划/判定,不执行物理步进或模型给出的代码。默认 `127.0.0.1:8768/api/decision/v1`。
|
||
|
||
## 网站模式
|
||
|
||
`python -m decision_server --website-origin https://cadworld-sim.robotquan.com` 启动独立同源网站模式,不打印服务令牌、不自动发现 `.env`。当前生产另显式指定 `--website-key-file /run/secrets/model-keys.env --website-budget-file /var/lib/cadworld/budget.sqlite`,按两项固定变量读取站长授权的 DeepSeek flash/Jev 1.13 密钥;启动不推理。密钥为服务器受保护只读文件,不打包到镜像/静态站点,不发送到浏览器。
|
||
|
||
每访客任务、取消和限额仍独立,只有固定模型凭据由服务器提供;全站 60 次/小时、600 次/24h 的上游调用预留记录持久化,进程重启/换 Cookie 不重置。共享模式禁用公开配置修改、模型目录、连接测试及订阅接口;本地模式与非共享模式的原连接/官方订阅能力保留,无自动回退。
|
||
|
||
新增 `/command`:DeepSeek 结构化理解单个动作、Jev 检查意图;距离/角度/字段/方向与单位再由代码检查。只返回受限语义,不返回代码/执行器写入。实际驱动与物理成功在浏览器判断,取消身份覆盖整条双模型请求。见 [网站 API](../docs/website-api.md)、[部署手册](../docs/website-deployment.md) 和 [当前实测](../docs/website-hosted-control-2026-09-24.md)。
|
||
|
||
## 语言控制面板:本地推荐启动方式
|
||
|
||
本地与网站统一为“机器人语言控制”,界面不再填写 token/密钥或配置模型。使用现有同源会话模式,密钥文件由操作者准备,包含 `DEEPSEEK_API_KEY` 与 `OPENROUTER_API_KEY`,不进入前端:
|
||
|
||
```bash
|
||
source .venv/bin/activate
|
||
python -m decision_server --website-origin http://127.0.0.1:5173 --website-dev \
|
||
--website-key-file /absolute/path/model-keys.env \
|
||
--website-budget-file "$HOME/.local/state/mujoco-decision/language-budget.sqlite"
|
||
# 另一终端;浏览器必须使用与 website-origin 完全一致的地址
|
||
npm run dev -- --host 127.0.0.1
|
||
```
|
||
|
||
Vite 本地/网站模式均代理 `/api/decision/v1`。换端口时同步修改 `--website-origin`;代理目标默认 `127.0.0.1:8768`,可用服务器环境变量 `CADWORLD_DEV_API` 修改。没有可用模型服务会报错,不自动转 mock。旧 Bearer 服务仍供程序化客户端使用,不能直接替代此面板的同源服务。
|
||
|
||
## 旧 Bearer 客户端启动(非新版面板)
|
||
|
||
```bash
|
||
source .venv/bin/activate
|
||
# 当前环境已有 aiohttp 3.14.3,无需升级 MuJoCo/训练依赖。
|
||
# 新环境可单独安装:python -m pip install -r decision_server/requirements.txt
|
||
npm run decision-server
|
||
```
|
||
|
||
控制台打印本进程专用服务令牌。旧程序化客户端需要 Bearer 令牌;它不是模型 API Key。默认仅允许工作台 `localhost/127.0.0.1:5173/4173`,其他本机测试端口通过 `--origin http://127.0.0.1:4176` 显式允许。
|
||
|
||
用户已批准本项目使用 `.env` 中的两项凭据。按需显式启用:
|
||
|
||
```bash
|
||
npm run decision-server -- --openrouter-env .env --deepseek-env .env
|
||
```
|
||
|
||
- OpenRouter:只读取 `OPENROUTER_API_KEY`,仅配置 Jev `typesafe/jev-1.13` / `https://openrouter.ai/api/alpha/decisions`。
|
||
- DeepSeek:只读取 `Deepseek_API_KEY` / `DEEPSEEK_API_KEY`,配置用户再次确认的 `deepseek-flash` / `https://api.deepseek.com`,使用 Responses 协议。
|
||
- 加载器不 source/eval、不展开环境变量、不读取其他变量值作为配置、不接受文件中的 URL/model,不自动发请求。重复目标变量、坏格式或缺密钥明确报错。没有指定参数时不自动扫描 `.env`。
|
||
- 密钥仅服务内存;无 dotenv/云 SDK/系统钥匙串隐式回退。文件本身由用户管理,服务不会改写;`.gitignore` 已排除 `.env`。普通连接也可通过受保护 HTTP 接口配置,不在浏览器持久化。
|
||
|
||
默认非秘密连接元数据在仓库外 `~/.local/state/mujoco-decision/connections.json`(0600)。重启后普通连接需要重新提供密钥;换地址必须重新提供密钥,不携旧密钥跨域。远端只允许 HTTPS,HTTP 仅字面回环地址/localhost;不跟随重定向、不继承代理环境配置。
|
||
|
||
## 协议与限制
|
||
|
||
| 路由 | 方法 | 内容 |
|
||
| ------------------------------------------------- | ---- | ----------------------------------------------------------- |
|
||
| `/status` | GET | 版本、非秘密配置、调用摘要;没有 prompt、响应原文或账号地址 |
|
||
| `/connections` | PUT | `role,protocol,baseUrl,model,apiKey`;role 为 llm/jev |
|
||
| `/test` | POST | `{role}`,显式连接测试;API 会计费,Codex 只做离线能力门禁 |
|
||
| `/plan` | POST | `{observation,instruction,remaining}` |
|
||
| `/decide` | POST | `{observation,candidates,failure?}` |
|
||
| `/cancel` | POST | `{runId,requestId}` |
|
||
| `/codex/status`, `/codex/models`, `/codex/limits` | GET | 官方账号状态、模型目录、原始数值额度窗口 |
|
||
| `/codex/login`, `/codex/cancel`, `/codex/logout` | POST | 空对象;官方登录 URL 仅此响应交给浏览器,不能保存/日志导出 |
|
||
|
||
所有路由均有精确 Host、Origin、Bearer 校验;没有任意 URL/RPC 转发、文件读取或 shell 接口。请求体上限 64 KiB,响应上限 256 KiB;上游 HTTP 45 秒,服务推理 60 秒,必要的进程中断/回收有独立短期限。每服务同一时刻仅一个推理/连接测试;取消、配置变更和断连令旧请求无效。
|
||
|
||
每回合最多 3 次 LLM(初始 + 2 次重规划)、60 次 Jev,最多 20 分钟墙钟;同一服务最多 120 次/小时,最多保留 32 个回合预算记录。失败/取消也计数,重复/过期 requestId 不可重新执行。没有网络自动重试、静默模型替换或规则降级。连接测试使用独立预算桶,也计全局预算。
|
||
|
||
LLM 显式选择 `responses` 或 `chat-completions`。两者都要求结构化 JSON;不兼容时明确报错,不悄悄降级。Jev 显式选择 `typesafe` 或 `openrouter-decisions`,两者均是 `state/questions/answers`,不是聊天接口。保留服务选择,不根据概率私自重排。只返回经过验证的计划/判定及数值 usage;OpenRouter 返回的 cost 是服务报告值,不是硬编码估价。DeepSeek 未返回费用时仅显示 token,不能伪造金额。
|
||
|
||
## 官方 Codex:实验性、逐模型门禁
|
||
|
||
仅支持已验证的 **codex-cli 0.147.0**;不自动安装/升级,不使用私有 ChatGPT 接口,不把订阅凭据传给 API Base URL。
|
||
|
||
- 每进程在仓库外创建独立临时 HOME/CODEX_HOME/cwd,关闭项目指令、shell、code mode、插件、apps、hooks 等;拒绝继承的 MCP/hooks/notify 执行配置。仅会话 OAuth,退出进程即丢失,不读取用户全局登录。
|
||
- 随代码附带匹配版本的模型目录,仅缩减工具能力和替换提示词,保留模型标识/可见性/账号范围。来源和许可见 `THIRD_PARTY_NOTICES.md`。隐藏/退役的 gpt-5.4 不是当前默认或通关替身。
|
||
- 每个选定模型首次使用前运行原生 CLI 离线门禁:仅连接私有回环假 Responses 服务,验证不暴露工具;强行注入 apply_patch、shell_command、exec_command、view_image 必须分别返回 unsupported,并验证未写文件。失败、超时或版本不符立即拒绝规划。
|
||
- 通过 `account/login/start(type=chatgpt)` 登录、`account/read` 确认、`model/list` 选择;模型目录不是实际账号权限/额度的承诺,上游仍可拒绝。真实调用必须已登录且逐模型门禁通过。
|
||
- `thread/start(ephemeral)` + `turn/start(outputSchema)`;只接受当前 thread/turn 的最终合法计划,工具输出/未知项拒绝。取消走精确 `turn/interrupt`;失败则终止进程,结束后 unsubscribe,释放线程资源。
|
||
- `account/rateLimits/read` 只展示官方数值窗口;不推算订阅美元费用。额度不足、登录失效、型号/请求被拒绝均明确错误,不切换付费 API。
|
||
|
||
本机 5 个可见模型的离线门禁、真实 stdio 假推理的结构化计划与 unsubscribe 已通过。**未完成真实 ChatGPT 登录/订阅推理验收**;需要用户浏览器交互。
|
||
|
||
## 测试与已知验证范围
|
||
|
||
```bash
|
||
source .venv/bin/activate
|
||
npm run test:decision-server
|
||
# 额外:本机固定版本 CLI,无账号登录/远端推理
|
||
DECISION_CODEX_SMOKE=1 npm run test:decision-server
|
||
```
|
||
|
||
常规 CI 仅本地假服务和 mock,不需要凭据/CLI/GPU/机器人资产;原生 Codex 用例显式启用。共享 `contracts/lekiwi-agent-v1.schema.json` 的 Python/TS 有限子集校验均拒绝额外字段、非有限数、非法对象/技能和跳前置条件计划。
|
||
|
||
真实单请求证据(输入为**合成契约夹具**,不是实时物理采样,也不是完整抓放闭环):
|
||
|
||
- `build/lekiwi-agent/openrouter-jev-smoke.json`:Jev 初始状态判定通过,服务报告 $0.00004263。
|
||
- `build/lekiwi-agent/deepseek-plan-smoke.json`:最初指定的 `deepseek-v4.1-flash` 未出现在官方模型列表,没有发起该型号推理。
|
||
- 经用户确认改为 `deepseek-flash` 后,`build/lekiwi-agent/deepseek-flash-plan-smoke.json`:11 阶段规划及所有前置条件通过;836 输入 / 1608 输出 token,没有费用字段。
|
||
- Codex 最初门禁把省略的 tools 当作失败,保留 `current-model-first-gate.json`;修正为允许“省略或空数组”(不接受非空工具)后,5 个可见模型及 4 类注入全部通过,见 `build/lekiwi-agent/codex-capability/`。省略 tools 的 API 语义是不提供工具,不是忽略已有工具。
|
||
|
||
后续主工作台已完成两次真实 DeepSeek `deepseek-flash` + OpenRouter Jev 物理回合;最新为 1 次规划、11 次判定、实际持物搬运 0.593727 m,详见 [任务验收](../docs/lekiwi-agent.md)。证据保存在 `build/e2e/lekiwi-agent-final-gates/`。未保存的配置草稿会禁用任务/测试,避免仍调用旧付费配置。真实 ChatGPT 隔离登录已确认,订阅推理未运行;用户已接受以 DeepSeek + Jev 回合完成本次验收。临时登录会话已关闭,不能把登录/离线门禁当成订阅推理资格证明。
|
||
|
||
Sources:
|
||
|
||
- [OpenRouter Decisions 官方协议](https://openrouter.ai/docs/api/api-reference/alphadecisions/submit-a-decisions-questions-and-answers-request)
|
||
- [DeepSeek Responses 兼容说明](https://api-docs.deepseek.com/guides/responses_api)
|
||
- [Codex App Server](https://developers.openai.com/codex/app-server)
|
||
- [Codex 0.147.0 配置 schema](https://raw.githubusercontent.com/openai/codex/rust-v0.147.0/codex-rs/core/config.schema.json)
|