Skip to content

v1.0.1

Choose a tag to compare

@jcleng jcleng released this 13 Oct 12:12
· 14 commits to main since this release

opencode-free-provider v1.0.1

本地 OpenAI 兼容代理,将聊天请求转发到 OpenCode Zen 免费档,无需 API key 即可使用 big-pickle 等免费模型。

本版本重点:指纹改为纯 JS 生成,不再需要安装 / 运行真实的 opencode CLI。 Docker 镜像从约 2.4GB 降到约 245MB。

核心特性

纯 JS 指纹(推翻 v1.0.0 的「无法伪造」结论)

v1.0.0 认为免费档的 x-opencode-session 有服务端校验和、无法伪造,因此必须 spawn 真实 opencode 并用 MITM 拦截抓取。该结论已证伪。

经反编译 opencode 源码 + 对真实端点做逐位 ablation 实测,确认该 id 就是 opencode 普通的 descending 标识符:

ses_ + 12 位小写 hex + 14 位 base62      // 共 30 字符
hex = ~(Date.now() * 0x1000 + counter) 的 48 位

服务端实际只校验:

  • 低 12 bit 编码的计数器 0xfff - counter 必须 counter ≤ 63(64+ → 403);
  • 前 12 位必须为小写 hex;tail 必须恰好 14 位;
  • 时间戳大小 / 新旧不校验(高 36 bit 随便填);
  • x-opencode-session-id 若存在须等于 x-opencode-session。

没有任何校验和。 本版本在 src/fingerprint.js 里直接复刻该算法(counter 超过 63 自动进位到下一毫秒),因此:

  • 不再 spawn opencode,不再 MITM/TLS 拦截,不再需要 openssl 与一次性 CA;
  • 每个请求都生成一个全新合法的 ses_...(默认 ZEN_SESSION_MODE=per-request);
  • 相关文件:src/fingerprint.js(encodeIdentifier() / newSessionId() / newMessageId() / buildFingerprintHeaders()),/__session 暴露 fingerprint.source == "generated"。

Docker 不再需要装 opencode

指纹改为纯 JS 后,镜像不再安装 @opencode/cli(约 200MB 原生二进制)与 openssl:

  • 体积从约 2.4GB → 约 245MB;
  • 基础镜像仍为 node:24-bookworm-slim(Node ≥ 24 才有 NODE_USE_ENV_PROXY)。

模型列表从上游动态发现

GET /v1/models 会实时请求上游 /models,只保留 id 含 big-pickle 或 -free 的模型,并带 TTL 缓存(ZEN_MODELS_TTL_SECONDS,默认 600s),失败时回退到上次良好列表 / 内置 big-pickle。

使用方法

# 本地
npm start            # http://127.0.0.1:8791/v1

# Docker
docker build -t opencode-free-provider .
docker run -d --name opencode-free-provider -p 8791:8791 opencode-free-provider

Agent 配置:

baseURL: http://127.0.0.1:8791/v1
apiKey:  public
model:   opencode-free/big-pickle

验证指纹为纯 JS 生成:

curl http://127.0.0.1:8791/__session        # 期望 fingerprint.source == "generated"

环境变量

变量 默认 说明
ZEN_SESSION_MODE per-request per-request(每次请求新 ses_)或 sticky(进程内复用)
ZEN_SESSION_ROTATE_SECONDS 0 sticky 模式下每隔 N 秒轮换 session
OPENCODE_UA opencode/latest/2.0.22/cli 发给 gate 的 User-Agent
ZEN_MODELS_TTL_SECONDS 600 模型列表缓存时长(秒)
ZEN_MODELS_TIMEOUT_MS 5000 上游 /models 发现超时(毫秒)
NODE_IMAGE node:24-bookworm-slim 仅构建时:Docker 基础镜像

已移除:OPENCODE_FP_DISABLE / OPENCODE_FP_TTL_MS / OPENCODE_FP_TIMEOUT_MS / OPENCODE_VERSION(不再有 CLI 抓取)。

验证

  • 50 个单元测试全部通过(mock upstream,无网络)。
  • 真实端点:纯 JS 生成的指纹直接 POST opencode.ai/zen/v1/chat/completions → HTTP 200。
  • 本地代理端到端:fingerprint.source == "generated",非流式与流式(以 [DONE] 收尾)均正常。
  • 拉取 Actions 构建的镜像实测:容器内同样是 generated,端到端 HTTP 200。
  • GitHub Actions 已成功构建并推送镜像到 ghcr.io/jcleng/opencode-free-provider:latest。

注意

  • 客户端若有 ALL_PROXY(如 socks5://127.0.0.1:20170),curl 会把 localhost 请求也走代理导致空响应,请用 curl --noproxy '*' 测试;Node 的 fetch 默认不读 ALL_PROXY,代理服务端不受影响。

变更

  • feat(fingerprint): generate the OpenCode free-tier fingerprint in pure JS (drop CLI/MITM) (285498c)

完整变更:v1.0.0...v1.0.1