fix: align DeepSeek canary tool rounds with gate
Memind CI / Test, build, and release guards (pull_request) Successful in 1m32s

This commit is contained in:
john
2026-07-26 23:49:32 +08:00
parent 046704816f
commit fb6865638a
19 changed files with 519 additions and 20 deletions
+22 -7
View File
@@ -11,6 +11,7 @@ Portal 的首个生产动作必须是用户级灰度,不能直接整包替换
| 灰度边缘隧道 | `105 127.0.0.1:19082` | 反向 SSH 到 103 的 18082;不复用已退役的 19081 链路 |
| 候选 Portal | `127.0.0.1:18081` | 独立、无源码 runtime;使用被动运行时模式 |
| 候选 goosed | `127.0.0.1:18015` | 独立容器并挂载候选 runtime,不重建稳定 9 个容器 |
| DeepSeek 兼容代理 | `103 0.0.0.0:18036` | 仅供宿主机和候选容器使用;不接入 105 或公网入口 |
候选 Portal 通过 `MEMIND_PORTAL_H5_ROOT` 共享经审计的持久数据和数据库,但
`MEMIND_RUNTIME_ROLE=candidate` 会禁止重复启动 MindSpace、Plaza、提醒、订阅续期和
@@ -23,6 +24,18 @@ Agent 恢复扫描等单例后台任务。
`Failed to add extension` 和宿主机绝对路径的 `MODULE_NOT_FOUND`,应先核对候选
进程环境与 `/opt/portal` 容器挂载,禁止把宿主机文件复制进容器临时修补。
DeepSeek V4 的工具轮次还必须经过候选 runtime 中的
`deepseek-no-think-proxy.mjs`。候选启动脚本必须强制
`MEMIND_DEEPSEEK_DISABLE_THINKING=1`,并把 goosed 自定义 provider 指向
`http://host.docker.internal:18036/v1`。该代理通过独立 LaunchAgent 管理;
发布必须同时验证 `/health` 的兼容契约和候选容器到该地址的连通性。灰度路由器把
该健康地址纳入候选健康闭包,代理掉线时必须自动回落稳定 Portal。
若日志出现
`The reasoning_content in the thinking mode must be passed back to the API.`
说明 DeepSeek 请求绕过了兼容契约。禁止只在线补环境变量:必须检查 artifact、
LaunchAgent、Portal provider 同步和路由器依赖健康配置是否属于同一 release。
## 身份和回落规则
- `john`:按数据库中的唯一用户名或用户 ID 匹配。
@@ -32,6 +45,7 @@ Agent 恢复扫描等单例后台任务。
- 微信回调通过 `FromUserName``h5_user_wechat_identities` 只读解析到绑定账号,再用唯一账号标识匹配。
- 未命中、无身份、过期/撤销会话、数据库异常:走稳定版本。
- 候选 `/api/status` 不健康:自动走稳定版本。
- DeepSeek 兼容代理不健康:自动走稳定版本。
- SSE、附件、公开页和普通 API 均由同一反向代理转发;微信 XML body 必须原样保留。
## 发布入口
@@ -49,12 +63,13 @@ bash scripts/release-portal-canary-prod.sh --yes
2. 执行 103 只读预检。
3. 上传经过验证的候选包。
4. 创建稳定 live 全量备份、持久目录备份和 105 两份活动 nginx 配置备份,并校验完整性。
5. 启动独立候选 goosed、候选 Portal 和灰度路由器
6. 验证不可变身份配置、稳定/候选健康和路由器诊断
7. 启动独立的 `105:19082 -> 103:18082` 灰度隧道并从 105 验证
8. 短暂阻止新 Agent Run,排空活动任务
9. 逐文件原子替换、验证并 reload 105 nginx,把活动上游从 `58.38.22.103:8081` 切到 `127.0.0.1:19082`
10. 主动停止候选,证明目标身份会自动回落稳定版,再恢复候选
5. 启动独立候选 goosed 和 DeepSeek 兼容代理,验证兼容契约及容器连通性
6. 启动候选 Portal 和灰度路由器。
7. 验证不可变身份配置、稳定/候选/依赖健康和路由器诊断
8. 启动独立的 `105:19082 -> 103:18082` 灰度隧道并从 105 验证
9. 短暂阻止新 Agent Run,排空活动任务
10. 逐文件原子替换、验证并 reload 105 nginx,把活动上游从 `58.38.22.103:8081` 切到 `127.0.0.1:19082`
11. 主动停止候选,证明目标身份会自动回落稳定版,再恢复候选。
任一步失败都会把 105 nginx 恢复到稳定 `58.38.22.103:8081`,停止灰度隧道和候选服务,
并保留候选目录与备份证据。活动 nginx 配置变更只能由已提交的发布脚本执行,禁止在线手改。
@@ -68,7 +83,7 @@ bash scripts/rollback-portal-canary-prod.sh --yes
回滚只执行以下动作:
- 把 105 两份活动 nginx 上游恢复到稳定 Portal `58.38.22.103:8081` 并验证 reload。
- 停止灰度隧道、灰度路由器、候选 Portal候选 goosed。
- 停止灰度隧道、灰度路由器、候选 Portal候选 goosed 和 DeepSeek 兼容代理
- 清除发布排水标记。
- 验证稳定 Portal 和 105 HTTPS 入口健康。
+31
View File
@@ -210,6 +210,37 @@ Provider 'custom_deepseek' is not configured
注意:DeepSeek API key / provider secret 是运行配置,不应该烘焙进镜像。
### 4.7 DeepSeek 工具轮次兼容必须与生产拓扑一致
DeepSeek V4 思考模式在工具调用后的下一轮要求客户端回传上一轮
`reasoning_content`。当前 goosed 工具链不能保证完整回传,因此生产候选必须使用
artifact 内的 `deepseek-no-think-proxy.mjs`,由独立 LaunchAgent 在 `18036`
启动,并强制候选 Portal 设置:
```bash
MEMIND_DEEPSEEK_DISABLE_THINKING=1
MEMIND_DEEPSEEK_NO_THINK_PORT=18036
MEMIND_GOOSED_HOST_GATEWAY=host.docker.internal
```
发布不能只看 Portal `/api/status`。还必须验证:
- `http://127.0.0.1:18036/health` 返回兼容契约版本和
`deepseekThinking=disabled`
- `goosed-prod-canary` 能访问
`http://host.docker.internal:18036/health`
- 灰度路由器把该地址纳入候选健康闭包;
- 失败清理和回滚会停止对应 LaunchAgent。
Gate 本地栈和生产候选必须使用同一组开关与进程依赖。若出现:
```text
The reasoning_content in the thinking mode must be passed back to the API.
```
说明实际生产请求绕过了兼容契约;即使场景 Gate 全部通过,也必须阻断发布并排查
环境漂移。
## 5. goosed-prod 镜像更新必看
当前已验证镜像: