Repository navigation
v1.0.1
opencode-free-provider v1.0.1
本地 OpenAI 兼容代理,将聊天请求转发到 OpenCode Zen 免费档,无需 API key 即可使用 big-pickle 等免费模型。
本版本重点:指纹改为纯 JS 生成,不再需要安装 / 运行真实的
opencodeCLI。 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-providerAgent 配置:
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