docs: migrate master server ops reference

This commit is contained in:
Codex
2026-06-12 01:32:40 +00:00
parent 54ce2e8bf0
commit 95eec5b773
4 changed files with 92 additions and 2 deletions
+1 -1
View File
@@ -34,7 +34,7 @@ Compose v2 安装后仍然必须遵守 UniDesk 的服务控制入口:全栈生
## Host Codex Profiles
主 server 上的 `codex``mycx``mxcx` 都是人工/Codex 运维入口,不属于 UniDesk Compose 服务、Code Queue runner、AgentRun runtime 或发布流水线。`mxcx` 只用于快速以 MiniMax-M3 provider 启动同一套 Codex CLI必须复用系统 `codex` 二进制,不安装第二套 Codex,不替换 `/usr/bin/codex`,也不改变 `mycx` 指向的默认 Codex 启动方式。`mxcx` 的长期运维细节以 `/root/docs/reference/master-server-ops.md` 为准;UniDesk 仓库文档只记录部署边界和与服务运行面相关的约束。
主 server 上的 `codex``mycx``mxcx``acx` 都是人工/Codex 运维入口,不属于 UniDesk Compose 服务、Code Queue runner、AgentRun runtime 或发布流水线。`mxcx` 只用于快速以 MiniMax-M3 provider 启动同一套 Codex CLI`acx` 是主 server 统一多模型 Codex profile 入口,默认使用 `gpt-5.5-only`,并允许通过 `/model``-m` 切换到 OpenCode Zen Go 与 Sub2API GPT aliases。它们必须复用系统 `codex` 二进制,不安装第二套 Codex,不替换 `/usr/bin/codex`,也不改变 `mycx` 指向的默认 Codex 启动方式。主机 Codex profile 的长期运维细节以 `docs/reference/master-server-ops.md` 为准;UniDesk 仓库文档只记录部署边界和与服务运行面相关的约束。
MiniMax-M3 配置必须保持 profile/provider 级隔离。当前 `mxcx` 的稳定形态是 `CODEX_HOME=/root/.codex-minimax-m3``model=MiniMax-M3``model_provider=minimax``wire_api=responses`,通过本机 Moon Bridge loopback endpoint 转换到 MiniMax 上游;profile config 中的 Codex `base_url` 应指向本机 bridgeMoon Bridge runtime config 再持有 MiniMax upstream `https://api.minimaxi.com`。密钥通过 profile `auth.json` 或环境中的 `OPENAI_API_KEY`/`MINIMAX_API_KEY` 注入,文件只能由 root 读取,权限应为 `0600` 或更严;不得提交到 Git、写入 `AGENTS.md`/`docs/reference`、进入 Docker image、Compose env、GitOps manifest、issue/PR 评论、CLI 输出或任务 trace。
+89
View File
@@ -0,0 +1,89 @@
# Master Server Ops
This document records master-server architecture and decision rules. **Operations commands (Moon Bridge management, profile smoke tests, MiniMax session recovery) have moved to the `unidesk-ops` skill** (`~/.agents/skills/unidesk-ops/SKILL.md`). Do not place secrets, one-off incident logs, or dated changelog notes here.
## Execution Boundary
- The master server is the production entry point and control plane. Default work on this host is limited to light source edits, Git operations, status checks, health checks, logs, diagnostics, JSON CLI control actions, and local profile wrapper maintenance.
- Heavy builds and repository-wide checks should run on an external execution surface such as G14, D601, CI/CD, or the target runtime.
- The local UniDesk checkout at `/root/unidesk` can be used for lightweight UniDesk CLI/trans/tran/helper changes.
## Codex Provider Profiles
`dscx`, `mxcx`, and `acx` are local Codex profile wrappers under `/root/.local/bin/`. They are host-level tools, not UniDesk service code. `acx` is the unified multi-model entry; `gocx` remains the OpenCode Zen Go compatibility entry, and older single-model `dscx-go`, `dfcx-go`, and `glcx-go` wrappers are compatibility entries. Usage commands are in `unidesk-ops` skill.
- `dscx` uses `CODEX_HOME=/root/.codex-deepseek-v4-pro`, model `deepseek-v4-pro`, Codex custom provider `deepseek`, and local Moon Bridge at `http://127.0.0.1:38440/v1`.
- `mxcx` uses `CODEX_HOME=/root/.codex-minimax-m3`, model `MiniMax-M3`, Codex custom provider `minimax`, and local Moon Bridge at `http://127.0.0.1:38441/v1`.
- `acx` uses `CODEX_HOME=/root/.codex-acx`, default model `gpt-5.5-only`, Codex custom provider `acx`, and local ACX router at `http://127.0.0.1:38448/v1`.
- `gocx` uses `CODEX_HOME=/root/.codex-opencode-go-all`, default model `glm-5.1`, Codex custom provider `opencode`, and local Moon Bridge at `http://127.0.0.1:38447/v1`.
- `dscx-go` uses `CODEX_HOME=/root/.codex-opencode-go`, model `deepseek-v4-pro`, Codex custom provider `opencode`, and local Moon Bridge at `http://127.0.0.1:38443/v1`.
- `dfcx-go` uses `CODEX_HOME=/root/.codex-opencode-flash`, model `deepseek-v4-flash`, Codex custom provider `opencode`, and local Moon Bridge at `http://127.0.0.1:38444/v1`.
- `glcx-go` uses `CODEX_HOME=/root/.codex-opencode-glm`, model `glm-5.1`, Codex custom provider `opencode`, and local Moon Bridge at `http://127.0.0.1:38446/v1`.
- `acx` includes all OpenCode Zen Go upstream slugs plus `gpt-5.5-only` and `gpt-5.5-sub2api` in one `model-catalog.json` so Codex can use `/model` or `-m <model>` within the same profile.
- `acx` routes OpenCode Zen Go models to the existing `gocx` Moon Bridge, but GPT models do not go through Moon Bridge: `gpt-5.5-only` uses the direct `only` OpenAI-compatible Responses endpoint and `gpt-5.5-sub2api` uses the Sub2API pool endpoint. The ACX router rewrites both GPT model aliases to upstream model `gpt-5.5` before forwarding.
- All wrappers read the upstream API key from the profile `auth.json`; generated Moon Bridge runtime configs live under the profile `.tmp/` directory with mode `0600`. Do not copy upstream keys into documentation.
- Each profile must include `model_catalog_json` in `config.toml` pointing to a profile-local `model-catalog.json` entry for its active model. Missing catalog metadata causes Codex to fall back to default metadata, which lowers the effective context window and prints `Model metadata ... not found`.
- Profile context metadata must match the intended upstream limit closely enough for Codex auto-compact to fire before provider rejection. Keep the local profile metadata in sync with the actual model family you are routing to.
- Current master-server profile baselines:
- `deepseek-v4-pro`, `deepseek-v4-flash`, and GPT profiles exposed through `acx` use `model_context_window = 1000000` and `model_auto_compact_token_limit = 900000`.
- Other local Moon Bridge profiles, including `glm-5.1`, `MiniMax-M3`, and the non-DeepSeek OpenCode models exposed through `acx`/`gocx`, use `model_context_window = 200000` and `model_auto_compact_token_limit = 180000`.
- Keep the wrapper-generated Moon Bridge `models.<slug>.context_window` aligned with the profile `config.toml` and `model-catalog.json`. If those three diverge, Codex and Moon Bridge may disagree about compaction and admission behavior.
- `hyueapi.com` / `.hyueapi.com` must remain in `NO_PROXY` / `no_proxy` for Codex API channels.
## Moon Bridge
Moon Bridge is installed as `/root/.local/bin/moonbridge`. The binary exposes OpenAI Responses endpoints and bridges Codex to provider-specific upstream APIs. Operations commands are in `unidesk-ops` skill.
The local source copy for the installed patched build is `/root/src/moon-bridge-sanitize`. When changing Moon Bridge, keep the change narrow, run package-level tests, build a replacement binary, back up the previous binary, then restart affected profile bridges. Default master-server build restrictions still apply.
Profile architecture:
- `dscx bridge-start` renders profile config and starts Moon Bridge on `127.0.0.1:38440`.
- `mxcx bridge-start` renders profile config and starts Moon Bridge on `127.0.0.1:38441`.
- `acx route-start` renders the ACX router config and starts the local routing service on `127.0.0.1:38448`.
- `gocx bridge-start` renders multi-model OpenCode Zen Go profile config and starts Moon Bridge on `127.0.0.1:38447`.
- `dscx-go bridge-start` renders profile config and starts Moon Bridge on `127.0.0.1:38443`.
- `dfcx-go bridge-start` renders profile config and starts Moon Bridge on `127.0.0.1:38444`.
- `glcx-go bridge-start` renders profile config and starts Moon Bridge on `127.0.0.1:38446`.
- The wrappers start Moon Bridge with `setsid` and a profile-local PID file.
- Logs are written under `<CODEX_HOME>/logs/moonbridge/`.
- `dscx` routes DeepSeek through Moon Bridge using Anthropic-compatible upstream + `deepseek_v4` extension.
- `mxcx` routes MiniMax through Moon Bridge using `openai-response` upstream passthrough.
- `acx` routes OpenCode Zen Go models to `gocx`/Moon Bridge. `gocx`, `dscx-go`, `dfcx-go`, and `glcx-go` route OpenCode Zen Go through Moon Bridge using `openai-chat` upstream at `https://opencode.ai/zen/go/v1/chat/completions`. The Codex side remains `wire_api = "responses"` against the local Moon Bridge URL.
- `acx` routes GPT aliases directly to OpenAI-compatible Responses endpoints and must not send GPT traffic through Moon Bridge.
- OpenCode Zen Go model IDs must use the upstream slug, such as `glm-5.1`; display names such as `GLM-5.1` are not profile model identifiers.
- Do not keep local handwritten bridge scripts, static alternate `moonbridge.config.yml` files, or other sidecar proxy paths for OpenCode Zen Go profiles. The only supported runtime path is wrapper-generated `.tmp/moonbridge.generated.yml` plus `/root/.local/bin/moonbridge`.
- For OpenCode Zen Go profiles, set an explicit `user_agent` in the generated Moon Bridge provider config. The upstream may reject default client signatures.
- Moon Bridge now performs a local context-window admission check on the Responses path before forwarding oversized requests upstream. The expected failure shape for an oversized prompt is local HTTP `400` with `invalid_request_error` and code `context_length_exceeded`, not an upstream-translated `502 Bad Gateway`.
- Do not switch MiniMax to `openai-chat` for Codex CLI unless tool-enabled smoke proves it works.
Profile validation:
- `*-go raw-smoke` verifies the upstream OpenCode Zen Go Chat Completions API directly.
- `*-go bridge-smoke` verifies local Moon Bridge's `/v1/responses` translation path.
- `*-go exec '在吗'` verifies the actual Codex profile. Passing output must not contain `Model metadata ... not found`; latest session records should show `model_context_window` derived from the profile catalog, not fallback metadata.
- `acx doctor`, `acx route-status`, `acx models`, and `acx -m <model> exec '在吗'` verify the unified ACX profile. Use a small real Responses request through `http://127.0.0.1:38448/v1/responses` to verify a GPT alias because GPT traffic intentionally bypasses Moon Bridge.
- `gocx raw-smoke [model]`, `gocx bridge-smoke [model]`, and `gocx -m <model> exec '在吗'` verify specific OpenCode Zen Go models. Omitting `[model]` uses the default `glm-5.1`.
- `ReasoningSummaryDelta without active item` in Codex stderr is a separate adapter noise from reasoning summary events. It is not the same failure as missing model metadata and does not by itself prove the profile is unusable.
### OpenAI Responses Tool Argument Sanitizer
Moon Bridge owns the online sanitizer for MiniMax-style bad tool argument JSON on the `openai-response` passthrough path. This is the first line of defense; wrapper-level session cleanup is only for JSONL that was already corrupted before the sanitizer was installed.
Sanitizer rules: recursively scans `ResponsesRequest.input`, repairs tool-call `arguments` before upstream, repairs response-side `arguments` in completed events (not delta chunks), falls back to `{}` on unrecoverable input. Response rewriting drops upstream `Content-Length`.
## MiniMax Session Recovery
`mxcx` includes a cleanup and guard layer for corrupted MiniMax-backed session JSONL. **Recovery operations commands are in `unidesk-ops` skill.** This section only documents behavioral rules.
- `mxcx resume` auto-runs `session-clean` + `session-guard` before invoking Codex. Uses `CODEX_HOME=/root/.codex-minimax-m3` profile.
- `session-clean` is strictly scoped to invalid tool-call `arguments`: malformed JSON, MiniMax sentinel text, and schema-invalid cases. Must preserve line order, non-tool messages, reasoning, outputs, token records, and session metadata. Must not compact/summarize/truncate/reorder transcript.
- New invalid `arguments` should be prevented online by Moon Bridge sanitizer. Use `session-clean` only to recover already-written sessions.
- `session-guard` injects `mxcx-minimax-tool-and-apply-patch-guard-v2`, avoiding duplicates.
## MiniMax Apply-Patch Operations
MiniMax-backed sessions must use the same UniDesk remote text patch contract as other agents: route first, operation second, and `apply-patch` v2 by default. The stable write shape is `trans <provider>:/absolute/workspace apply-patch < patch.diff`; read-only inspection may use `trans <provider>:/absolute/workspace script -- 'nl -ba file'` or equivalent bounded commands.
- If `apply-patch` reports `failed to find expected lines`, first read the exact current target block, then retry with a smaller `Update File` hunk, an `@@ <unique anchor>` hint, or multiple small hunks. This is normal stale-context recovery, not a reason to switch tools.
- Do not recover text patch failures by using `download` / `upload`, remote Python/Perl/sed heredocs, `cat >` / `tee` whole-file rewrites, or `apply-patch-v1`, unless `apply-patch` itself is unavailable or the target is non-text / bulk mechanical generated content.