feat: add Trae CLI client support (bili trae) - #669
Conversation
Trae CLI (ByteDance) is a closed Go binary with no base-URL override, so /bili/ rewrites cannot reach it — cert-MITM is the only route (the Go runtime honors HTTPS_PROXY; the CA rides SSL_CERT_FILE, the combined bundle, since it replaces Go's system trust store). - client-config: TraeConfig, resolveTraeHome (~/.trae), readTraeConfig (TRAE_CLI_API_HOST), TRAE_DEFAULT_MODEL_HOSTS - launcher: bili trae (proxy mode) — HTTPS_PROXY + SSL_CERT_FILE + BILLION_CONTEXT_PROXY, default model hosts whitelisted for MITM (or the TRAE_CLI_API_HOST override), traecli/trae-cli/trae binary resolution - server: recognize the proprietary /api/ide/v2/llm_raw_chat wire as OpenAI (OpenAI-shaped body per decompilation); an unparseable body falls to verbatim passthrough (no compression, no breakage) - discover: trae hosts in MITM domain auto-discovery - cli/README/AGENTS/CONFIGURATION: help + docs (en + zh-CN) Residual risk (needs a real-machine capture): the wire body may carry a signed/encrypted field (chatmodel.decryptMessage); if so the proxy forwards it unchanged rather than compressing. Fixes #655
📦 Built Package ArtifactBranch: Option A — Install from npm PR tag (recommended)npm install -g billion-context@pr-669Each push to this PR publishes a new version under the Option B — Download artifact
tar xzf billion-context-pr669.tgz
npm install -g packageThis comment is automatically updated on each push. |
[bot] 🏷 Reviewing PR #669 (
One small inconsistency I'm fixing directly: in Full review + the fix coming shortly. |
[bot] 🏷 Review complete — full assessment of PR #669 ( Verdict: ✅ Approve — ready to merge (merge stays human-only)Diff hygieneClean and focused: 12 files, +240/−17. No unrelated churn, no whitespace/reformat noise, no lockfile drift. Every line serves the stated purpose. Correctness — verified against the source, not just the description
Pre-flight (ran on this branch)
One small inconsistency — fixed directly on the branchPushed commit
It was masked in practice by the server-side auto-discovery fallback ( Residual risk (unchanged — needs a real-machine capture)Your decompilation-based assessment holds. The only outcome this PR produces on an encrypted body is "forward unchanged" (no breakage). A real 中文摘要:修复了 |
|
解决冲突 |
Resolve launcher.ts import/re-export conflict: union of master's resolveCodexHome and the PR's trae symbols (resolveTraeHome, readTraeConfig, TRAE_DEFAULT_MODEL_HOSTS, type TraeConfig). All other files auto-merged. Verified on merged tree: typecheck clean, build ok, 1334 tests pass / 0 fail.
已解决冲突并推回 PR 分支。 冲突来源:自本 PR 分叉后 master 前进了约 40 个提交(含 acp-kernel 版本升级、Windows 启动/spawn 修复、turn-integrity、release v0.1.98–v0.1.102 等)。把 master 合入 PR 分支后,只有 解决方式:取两者并集——同时保留 master 的 合并后验证(在合并后的完整树上重跑,非仅冲突文件):
推送:fast-forward 推到 PR 分支 另外说明:未改动 一句话:把 master 合入 PR 分支,解决了 |
Adds a
bili traelauncher for Trae CLI (ByteDance's closedtraecliagent). Trae CLI is a locally-signed-in agent that carries its own model quota (the issue's use case: a company only provides a traecli quota).Why cert-MITM (not
/bili/rewrites)Trae CLI is a stripped Go binary with no base-URL override — its model host is baked in, so the
/bili/path-rewrite mechanism (used by pi/omp/opencode) cannot reach it. The one route that works is cert-MITM: the Go runtime honorsHTTPS_PROXY, so the launcher routes its model traffic through the bili proxy and injects the bili CA.Verified by decompiling
traecliv0.120.52 (see #655): honorsHTTPS_PROXY(Gonet/http.ProxyFromEnvironment); CA via the Go system trust store →SSL_CERT_FILE; model host overridable viaTRAE_CLI_API_HOST; wire is the proprietaryPOST /api/ide/v2/llm_raw_chat(SSE, OpenAI-shaped body).What changed
src/client-config.ts—TraeConfig,resolveTraeHome(~/.trae),readTraeConfig(readsTRAE_CLI_API_HOST),TRAE_DEFAULT_MODEL_HOSTS(console.enterprise.trae.cn,www.trae.cn).src/launcher.ts—bili trae(proxy mode):buildTraeEnvsetsHTTPS_PROXY+SSL_CERT_FILE(the combined CA bundle, since it replaces Go's system trust store — same shape as codex) +BILLION_CONTEXT_PROXY; whitelists the model host(s) for MITM (default hosts, or theTRAE_CLI_API_HOSToverride); resolves thetraecli/trae-cli/traebinary. No budget/transport env (Trae manages its own context window internally).src/server.ts— recognizes the proprietary/api/ide/v2/llm_raw_chatwire as OpenAI (per decompilation the body is OpenAI-shaped). Safe: if the body is unparseable (non-JSON/encrypted), the existing gate falls through to verbatim passthrough — no compression, no breakage.src/discover.ts— trae hosts in MITM domain auto-discovery.src/cli.ts+ README/AGENTS/CONFIGURATION (en + zh-CN) — help + docs.Residual risk (needs a real-machine capture)
Decompilation shows
chatmodel.decryptMessage/decryptAKexist. The evidence (an OpenAI-response converter + a community bridge that reads the SSE directly) indicates the conversation body is plaintext, sodecryptMessagemost likely covers a signed-metadata field, not the whole body. If the body is encrypted, the proxy forwards it unchanged (no compression, no breakage) — so the worst case is "no value", not "broken". A realbili traerun against a company traecli confirms it.The default MITM hosts are best-effort from the binary; if the company tenant is on a different host, set
TRAE_CLI_API_HOSTor--mitm-domain.Verification
npm run typecheck— cleannpm test— 1242 pass (1 pre-existing sandbox failure in the codex/clauderesolveClientCommandtest, unrelated to this change — it hardcodesPATH=/usr/binassuming codex is absent, but this sandbox has it; passes in CI)npm run build— successFixes #655