Skip to content

About

Magpie社区插件Zen-Free的分支,补全已被官方放弃的免费模型可用性适配,并优化整体实现

Topics

Resources

Stars

9 stars

Watchers

0 watching

Forks

Latest commit

 

History

140 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OpenCode Zen FreeX

在 magpie 里用 OpenCode Zen 的免费模型

共享凭据 public 即用 · 自动发现 · 原生流式协议

简体中文 · English

CI npm License: MIT Runtime: bun

为什么有这个分支

zen-free 是这个插件的前身。先说清楚:上游一直在维护,修 Bug 也很快。问题在于它对免费模型支持这件事,始终缺少一个稳定、明确的态度

免费模型失效时,用户反馈issue,得到的答复却是将不再支持;过一段时间,相关问题又被悄悄修复,免费模型重新恢复可用。支持、放弃、再支持——用户只能跟着上游的态度反复折腾,却始终无法确定这份支持究竟能持续多久

既然有人依赖它,就值得一个明确的答案,而不是反复摇摆,这就是本项目诞生的原因

UTC 提交 上游说了什么
2026-10-13 23:53 643ef50 README 加上说明:免费层「只在 OpenCode 本体里能用」,this plugin doesn't work around that,请改用 Zen 付费 key 或 OpenCode Go;提交说明里写着 No version bump … The code on main is left as it is
2026-10-14 10:57 a810ee7 0.1.6 把那段说明删掉,改为发 OpenCode 1.19.0 原样的请求头——距加上去 11 小时
2026-10-14 17:59 5fc0a75 0.1.7:free models answer again

上游的后续更新会按需合并,同时保留自己的取舍(比如工具措辞按代从真实 OpenCode 采集,而不是钉死某一个版本)

安装与登录

magpie plugin add opencode-zen-freex
magpie plugin login opencode-zen-free

密钥填 public。这是 Zen 免费层的共享凭据,不需要个人 API key——填别的也会被丢掉。

个人 key 请加到 magpie 内置的 OpenCode Zen provider,那里支持多把 key 的轮换与故障转移。凭据保存在 OpenCode 的 auth.json 或 magpie 的 plugin-auth.json。

模型

模型名写作 opencode-zen-free/<id>,例如 opencode-zen-free/big-pickle。

  • 自动发现:宿主列举模型时读取 Zen 的列表,60 秒内的重复列举复用上一次结果。读到的列表会写进缓存(~/.cache/opencode-zen-freex/discovery.json,Windows 在 %LOCALAPPDATA% 下);列表读不到时由缓存或包内旧表顶替,有缓存时把数据的年龄一并告知宿主。
  • 上限按实测:目录、厂商自述与路由实际执行的墙常有出入。上下文按实测能过的最大值对齐,输出优先取同一网关付费孪生的声明。例如 mimo-v2.6-flash-free 目录写 20 万,实测 37.5 万;glm-5.3-flash-free 的付费孪生声明 100 万,实测 32.3 万;路由自己否掉的上限也照认,deepseek-v4.1-flash-free 的 100 万因此收紧到 32.6 万。依据与复测方法见 MAINTAINING.md 的 “Limits Zen under-reports”。
  • 上限还会从流量里学:插件不额外发请求,只用自己转发的请求向上试探、向下收敛;学到的值重启后仍在,被拒的模型会自动收回到已经证明能过的尺寸。
  • 实测快照不用等发版:仓库每小时做一次增量实测,写入 limits-observed.json 并发布到 main;插件启动后每小时最多后台拉取一次,读不到就用缓存或包内副本。
  • 列表说了算:Zen 列表里的 -free 模型立即提供(本插件不支持的协议除外),不等目录补齐;目录读不到只影响它描述的那部分,不代表列表是回退结果。
  • 不再免费即 404:错误会列出当时可用的免费模型;模型重新免费后,刷新列表即可。可用性与限流归 Zen 管,插件看不到剩余额度。

请求

请求发往 https://opencode.ai/inference/v1,按每个模型的原生协议走(Chat Completions / Responses / Anthropic Messages),流式与普通 JSON 都支持。

  • 只借 OpenCode 的外壳:请求头、User-Agent 与工具集合按同一代 OpenCode 配套,宿主缺的 required 工具会补发描述(背后没有实现)。请求头是刻意挑出的最小集合——不要自行添加,两个各自无害的头组合起来也会被拒。
  • 工具名对不上就原样交给宿主:先精确匹配,再忽略大小写,最后忽略 _/-/./空白,只取唯一结果;对不上或有歧义时不猜、不丢,由宿主回自己的「没有这个工具」,模型据此改名重试。只有没有名字的调用会被略去,并在正文说明。
  • 会话保持稳定:宿主给了 OpenCode 形状的会话 id 就原样传,否则从宿主的会话标识派生并记住,同一会话各轮共用一个 id。
  • 截断与错误如实报告:流提前结束时,Chat 流若有内容且无未完成调用,按截断回答收尾并注明;其余情况一律失败。错误正文只读一小段找 Zen 自陈的上限,其余替换为说明。
请求头与会话 id 的完整规则

请求头只有这些:content-type、accept、user-agent、x-opencode-project、x-opencode-session 与 x-opencode-session-id(同一个值)、x-opencode-client: cli、authorization: Bearer public;走 Messages 时改用 x-api-key: public 加 anthropic-version。anthropic-beta 插件自己从不设置,宿主发了才原样透传。

会话 id 按顺序取:会话头 x-opencode-session / x-opencode-session-id / x-session-affinity / x-session-id / session_id / conversation-id / conversation_id,body 的 conversation_id,metadata.session_id,或 Claude Code 的 metadata.user_id 里的 _session_<uuid>。都没有时用 system/instructions 与首条用户消息做种子(system 变了就是另一个会话);再没有才看 previous_response_id,仍然没有则每次新生成。空字符串一律不算名字。

免费层不再应答时

插件给出的 403 会写明措辞采集自哪个 OpenCode 版本,先从它查起。下面三条都只在仓库副本里可跑(check:gate 与 capture 不在发布包里),需要 Bun;capture 还需要 PATH 里有 opencode:

bun run check:gate          # 问 Zen 还认哪代指纹;只要有一代 floor 被应答,退出码为 0
bun run capture -- --dry    # floor 全被拒时:取新采集并报告差异,不写入
bun run capture             # 确认差异后才写入

fingerprint.json 缺失或损坏时,capture 会重写一份而不是拒绝。闸门并不稳定:结论只代表此刻,信之前再跑一遍;同一地址反复被拒后还可能进冷却期。逐代结论与失败判读见 MAINTAINING.md 的 “The loop” 与 “Reading a failure”。

排查

现象 处理
每个请求都是 403 FreeTierError,正文没有 IP 封禁文案 指纹措辞过期。在仓库副本里跑 bun run check:gate;全被拒时跑 bun run capture
403 正文是封禁文案(abuse of traffic,或 free models aren't available … from your current network) 免费层封的是当前出口 IP。换网络、换 VPN 出口,或等封禁解除;重试与改请求都无用
426 Upgrade Required 这个包自称的 OpenCode 版本比 Zen 要的旧。升级插件,或在更新的 OpenCode 里运行
404 … not available as an OpenCode Zen free model now 该模型已不再免费。从报错列出的模型里换一个
Model is not an available free model for this protocol 请求发出时列表变了。让宿主刷新模型列表再试
uses the public credential 存的密钥不是 public。用 public 重新登录
不带 FreeTierError 的 403 是 Zen 自己的 403,与本插件无关;按原文处理
400 context_length_exceeded,或 max_tokens 超出范围 路由按模型自己的上限校验。压缩对话或调小 max_tokens;上下文拒绝不报窗口数字,max_tokens 拒绝会给出允许范围
窗口偏小想重学,或新设的环境变量没生效 删掉缓存目录下的 opencode-zen-freex/limits.json(目录规则见环境变量);环境变量只在宿主启动时读,改完要重启
模型被问错了协议 协议文档的端点表没读出来。设 OPENCODE_ZEN_FREE_MODELS_DEBUG=1 看是哪份文档、为什么没读出来
想确认快照是否新鲜、模型是否下线 在仓库副本里跑 bun limits-watch.mjs --status;退出码 0 正常、2 已读但有问题、1 读不到。unavailable 只是历史,不是停用开关
窗口停在旧值,或连不上 raw.githubusercontent.com 远程快照只是优化,失败不影响请求。用环境变量换源或关闭(见环境变量)

环境变量

最常用的几个;完整清单与默认值见 .env.example。缓存目录在 Windows 上是 %LOCALAPPDATA%,其余平台是 $XDG_CACHE_HOME 或 ~/.cache。

变量 作用
OPENCODE_ZEN_FREE_DISCOVERY_CACHE 模型发现缓存路径;空字符串表示只在内存中
OPENCODE_ZEN_FREE_LIMITS_SNAPSHOT 实测快照路径;空字符串表示不读快照
OPENCODE_ZEN_FREE_LIMITS_SNAPSHOT_URL 远程快照地址;空字符串关闭远程
OPENCODE_ZEN_FREE_LIMITS_STATE 学习到的上限状态路径;空字符串表示只在内存中
OPENCODE_ZEN_FREE_LIMITS_DEBUG 1 时把抬高、被拒与路由自报的窗口打到 stderr
OPENCODE_ZEN_FREE_MODELS_DEBUG 1 时打印模型目录的解析细节
OPENCODE_ZEN_FREE_MAX_WINDOW 向上试探的窗口上限,默认 1048576

鸣谢

类别 项目
本插件前身 zen-free
插件载体 magpie
模型提供者 anomalyco/opencode
本仓库常用 Agent deepseek-harness · hermes-agent
灵感来源 9router · opencode2api · zen-gate

许可

MIT。分叉自 zen-free,LICENSE 正文原样未改:版权行同时保留上游作者 xiaozhou26 与本分支的 OpenCode-Zen-FreeX contributors。来源与维护缘由见 NOTICE。

About

Magpie社区插件Zen-Free的分支,补全已被官方放弃的免费模型可用性适配,并优化整体实现

Topics

Resources

Stars

9 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages