Skip to content

feat: 新增 qoder 客户端支持(bili qoder) #653

Description

@ranxianglei

来源: #640 分析 codebuddy 客户端支持时发现(owner 在 #640 要求立项)

背景

qoder(Qoder CLI,npm 包 @qoder-ai/qodercli 国际版 / @qodercn-ai/qoderclicn 国内版,bin qoder / qodercli,Apache-2.0,阿里出品)是 gemini-cli 的 fork(bundle 里保留 GEMINI_* env 别名和 gemini-cli 的 zod 配置 schema)。和 codebuddy 一样是 Node CLI,但模型端点 scheme 硬编码 https,没有可用的 HTTP base URL 覆盖 env,所以 codebuddy 的 /bili/ rewrite 路线走不通,需要 cert-MITM(dsh/claude 式)。

推荐方案:cert-MITM,proxy mode

  • qoder 尊重 HTTPS_PROXY(内置 undici 带 ProxyAgent,网络管理器 getProxy() 读标准 proxy env)和 NODE_EXTRA_CA_CERTS(无自定义 https.Agent,TLS 走 undici 默认)
  • launcher 注入:HTTPS_PROXY=http://127.0.0.1:PORT + NODE_EXTRA_CA_CERTS=<bili CA> + BILLION_CONTEXT_PROXY
  • 默认 MITM 白名单模型 host(下表);代理看到 POST /model/v1/chat/completions → OpenAI adapter → 压缩
  • 认证 token(Bearer,私有 SSO/PAT 签发)对代理不透明,原样转发
  • 压缩走 proxy mode(wire 注入)。qoder 不是 ACP-native agent(bundle 里有 ACP 协议 schema,见开放问题 feat: persistent + namespaced sessions, multi-tenant session isolation, stream robustness #5,可作未来 plugin mode 方向)

调研确认的配置事实(v1.1.47,从 npm 包 bundle 核实,国际/国内两版)

模型流量

  • wire 是 OpenAI chat completionsPOST https://<host>/model/v1/chat/completions,body = 标准 OpenAI chat + qoder 扩展(顶层 metadata/patches/custom_model,message 级 reasoning_content/reasoning_item);SSE + [DONE],另有配额标记 [EXCEED_QUOTA]/[NOTIFICATIONS]
  • 模型 host 优先级:QODER_MODEL_SERVER_HOST未文档化 env,剥 scheme 和尾部斜杠)> 静态 map {prod: api2-v2.qoder.sh, daily: daily-api2-v2.qoder.sh, test: test-api2-v2.qoder.sh}(国际/国内 bundle 相同)
  • 区域推理 host:api1.qoder.sh(US) / api2.qoder.sh(SG) / api3.qoder.sh(JP);国内版全部走 gateway.qoder.com.cn;center 面 center.qoder.sh / gateway.qoder.com.cn(控制面,不需要 MITM)
  • scheme 硬编码 https/bili/ rewrite 不可行,cert-MITM 是唯一路线
  • transport:QODER_MODEL_TRANSPORThttp|grpc|legacy|http3|sse|off),协议 map {"custom-openai", "custom-openai-responses", "custom-anthropic"};默认由服务端 feature gate 决定,fallback legacy(remoteChatAsk 生命周期,wire 待真机验证)。注意:配置了 proxy 时 grpc 会自动降级为 http(bundle 里有 p7c() 检查)——http 是 proxy 友好路径

认证(私有,已确认)

  • 浏览器 SSO 登录(后台每 30 分钟自动刷新 token)或 PAT(QODER_PERSONAL_ACCESS_TOKEN,qoder.com/account/integrations 创建);token = security_oauth_token ?? access_tokenAuthorization: Bearer 发送
  • 与 codebuddy 同类私有认证;不影响 bili(代理不解析 token,原样转发)

配置

  • 配置根:QODER_CONFIG_DIR / QODERCN_CONFIG_DIR(完整路径)> QODER_CLI_HOME/QODERCN_CLI_HOME+目录名 > ~/.qoder(国际)/ ~/.qoder-cn(国内);QODER_CONFIG_DIR_NAME/QODERCN_CONFIG_DIR_NAME 控制目录名;项目资源在 <cwd>/.qoder
  • settings.json<configDir>/settings.json,gemini-cli 风格 zod schema(mcpServers 等)
  • 站点:QODERCLI_SITE=cnQODERCN_ 前缀;国内包 site 内置
  • 启动 env:QODER_MODEL(-m)、QODER_MCP_CONFIG(--mcp-config,文件或 inline JSON)、QODER_WORKING_DIRQODER_SESSION_IDQODER_SESSION_NAMEQODER_PERMISSION_MODE
  • --list-models 列模型(服务端驱动的 catalog,本地配置里没有模型清单)

预算对齐

MCP

  • QODER_MCP_CONFIG = --mcp-config(文件或 inline JSON),语义与 claude 一致 → MCP 注入可接(首版可选)

接入点清单

  1. src/client-config.tsQoderConfigresolveQoderHome(env)QODER_CONFIG_DIR ?? QODERCN_CONFIG_DIR ?? ~/.qoder)、readQoderConfig()——只读发现 settings.json(model 选择);无本地 models.json(服务端驱动)
  2. src/launcher.tsLAUNCH_CLIENTS"qoder"discoverRoutes qoder 分支——/bili/ rewrite(scheme 硬编码 https),改为返回默认 MITM 域名:api2-v2.qoder.shapi1.qoder.shapi2.qoder.shapi3.qoder.shgateway.qoder.com.cn(daily/test 变体不默认加);buildQoderEnv()(HTTPS_PROXY + NODE_EXTRA_CA_CERTS + BILLION_CONTEXT_PROXY,无 base URL rewrite);resolveQoderBudgetEnv()QODER_AUTOCOMPACT_WINDOW,国内站点用 QODERCN_ 前缀);resolveClientCommandqoderqodercli
  3. src/discover.tsextractHttpsHosts qoder 分支(默认模型 host);configFilePaths<configDir>/settings.json
  4. src/cli.ts:HELP 加一行
  5. 测试仿 launcher.test.ts / dsh 模式
  6. README client 章节和 AGENTS.md 模块表同步更新

开放问题

  1. legacy transport wire:默认 transport 由服务端 feature gate 决定,fallback legacy(remoteChatAsk 生命周期)——其 wire 是否也是 OpenAI 兼容 SSE 待真机验证。建议首版 launcher 注入 QODER_MODEL_TRANSPORT=http 强制走 OpenAI wire 路径,真机验证后再决定是否去掉
  2. qoder body 扩展字段metadata/patches/custom_model):需验证 bili 的 OpenAI adapter 对未知顶层字段的透传行为
  3. 模型窗口:服务端驱动 catalog,bili 的 models.dev registry 大概率没有 qoder 模型名——首版依赖 QODER_AUTOCOMPACT_WINDOW 或 bili configured limit 兜底
  4. 国内站点检测:launcher 如何判定 QODER_ vs QODERCN_ 前缀(QODERCLI_SITE env?安装的 binary 是哪个包?),需要定一个规则
  5. ACP modeQODER_ACP_LOGIN_METHOD_ID 等):bundle 里有 ACP 协议 schema(sampling/createMessage),未来可做 plugin mode(agent 侧压缩),首版不做

首个验证场景

国际版 + PAT 登录(QODER_PERSONAL_ACCESS_TOKEN),跑 bili qoder,确认:模型流量经代理 TLS 终止、/model/v1/chat/completions 走 OpenAI 压缩管线、QODER_AUTOCOMPACT_WINDOW 对齐日志出现、压缩循环正常触发。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions