@ailuntz/minisub
v0.14.3
Published
Lightweight Codex subscription gateway with weekly prorated plans and native-app management API
Downloads
1,579
Readme
MiniSub
Codex 订阅转 API。Node.js 24+,一个常驻进程,内嵌 ws / YAML,零外部运行时依赖。Linux 使用 systemd;macOS 可运行 CLI,原生管理 App 已提供源码。
flowchart LR
API[Responses / Chat / 图片 / 搜索] --> Core[MiniSub] --> OAuth[Codex 订阅]
Admin[本机管理 API] --> YAML[minisub.yaml:服务设置 / 套餐权限]
Admin --> DB[(SQLite:用户 / 账本 / 加密凭据)]
YAML --> Core
DB --> Core安装
npm install -g @ailuntz/minisub
minisub init
minisub serve模型接口 127.0.0.1:8787,管理接口固定绑定 127.0.0.1:8788。公网接 HTTPS 反向代理。默认数据目录 ~/.minisub,支持 --data-dir / MINISUB_DATA_DIR。
另开终端配置账号和用户:
minisub account import --name main --file /path/to/auth.json
# 或浏览器 OAuth:minisub account login --name main
minisub price sync
minisub plan add --name monthly --weekly-quota 1000 --monthly-price 20 \
--concurrency 2
minisub user add --name alice --plan PLAN_ID --months 1
minisub statusPLAN_ID 使用创建套餐返回的 ID。用户只有一个有效 Key,使用哈希验证并加密保存;管理员可在用户弹窗快速复制。旧版 Key 会在下次有效请求时补存,或主动轮换后保存。订阅凭据加密保存。远程 OAuth 登录先建立 ssh -L 1455:127.0.0.1:1455 YOUR_SERVER 回调隧道;同一份 OAuth 凭据应由一个服务刷新。
用户安全拒绝阈值
从 0.14.3 起,Mac App 的用户编辑弹窗可设置“累计多少次后停用”,范围为 1–100 次,默认 3 次。只累计上游错误对象中的 cyber_policy;成功请求不清零,普通回答中的拒绝文字不计数。HTTP、WebSocket 和 Realtime 共用该用户的计数。
管理 API POST users/save 可传 cyberPolicyLimit(整数);省略时保留现值。POST users 创建用户时也可指定,省略默认为 3。快照用户记录返回 cyber_policy_limit,保存仍需原有 expectedVersion。不接受 0、负数、小数或超过 100 的值。
保存时累计次数已达到新阈值,会停用用户并取消其在途请求;提高阈值不会清零计数或恢复已停用用户。现有管理员重置操作保持独立。此设置只决定 MiniSub 的本地停用阈值,上游被拒请求仍然失败,不自动重试或换账号。旧数据升级默认补入 3;数据库版本升级至 8,回退旧程序需同时恢复升级前备份。
用户订阅页
用户弹窗可复制 https://YOUR_DOMAIN/subs/用户Key,也可直接下载配置 ZIP。网页随 npm 包提供,与模型接口共用端口;无需另装前端服务。页面包含绑定订阅账号的上游周用量及重置时间、个人额度、订阅有效期、最近 31 天用量、服务端分页日志和使用说明。上游用量与 App 共用两分钟缓存,由节点后台定期更新;页面及管理刷新直接返回已有数据,不等待 OpenAI,后台查询最多并发 4 个,多人共用时标注“共享账号”;未绑定账号或读取失败时显示“暂未获取”。
ZIP 包含 .env、minisub.config.toml、使用说明.txt。停用或到期用户仍可查看自己的记录;轮换 Key 后旧链接立即失效。订阅链接本身就是凭据,请勿公开分享;反向代理应关闭 /subs/ 的访问日志和缓存,并保留 Host 与 X-Forwarded-Proto。网页不使用第三方资源或追踪脚本,返回 no-store / no-referrer,并禁止嵌入。
后台服务与卸载
minisub service install
minisub service start
minisub service status
# Ubuntu 用户服务退出 SSH 后继续运行:
sudo loginctl enable-linger "$USER"
# 卸载必须先移除服务,再移除 npm 包:
minisub service uninstall --purge
npm uninstall -g @ailuntz/minisub自定义 npm 前缀时,安装和卸载都带相同 --prefix,例如 --prefix ~/.local。系统级服务使用 sudo minisub service install --system --user ubuntu --data-dir /home/ubuntu/.minisub,后续命令带 --system。
卸载会停止进程、取消自启、删除本包服务文件;可重复执行。停止失败会报错并保留文件。加上 --purge 会删除所选 MiniSub 数据目录;不加则保留数据。用户另存的备份、Node/npm、Nginx、证书、DNS 和系统历史日志保留。重新安装后直接 service install → service start;原数据仍在时不用再次 init。服务记录 Node / 包的绝对路径,路径变动后重新安装服务。
Codex 客户端
# ~/.codex/minisub.config.toml
model_provider = "minisub"
[model_providers.minisub]
name = "minisub"
base_url = "https://YOUR_DOMAIN/v1"
env_key = "MINISUB_API_KEY"
wire_api = "responses"
supports_websockets = true# ~/.codex/.env
MINISUB_API_KEY=YOUR_USER_API_KEYcodex --profile minisub
# 可选:codex exec --profile minisub --model MODEL "你好"无需上游 auth.json 或 model_catalog_json。模型由客户端选择,上游决定权限。--profile 不会自动填写模型名;Codex 自带目录也不等于账号完整权限目录。关闭 supports_websockets 使用 HTTP / SSE。
使用 Codex 图片执行器 / 独立搜索的客户端可在提供商配置增加:
supports_standalone_web_search = true
requires_openai_auth = false
http_headers = { "x-openai-actor-authorization" = "local-image-extension" }接口
所有模型接口使用 Authorization: Bearer USER_API_KEY。同时接受省略 /v1 的路径。
| 入口 | 行为 |
|---|---|
| POST /v1/responses | 原生 Codex HTTP / SSE;非流式调用收集 SSE 后返回 JSON |
| GET /v1/responses + Upgrade | Responses WebSocket,同连接响应 ID + 增量 |
| POST /v1/chat/completions | Chat → Responses 转换;文本、图片、文件、函数 / custom 工具、JSON Schema |
| POST /v1/images/generations、/v1/images/edits | Codex 图片执行器 JSON;内联图片返回 |
| POST /v1/alpha/search | 独立搜索 JSON 透传;成功请求按次结算 |
| POST /v1/memories/trace_summarize、/v1/responses/compact | JSON 透传;缺用量进入待核对 |
| /v1/guardian、/v1/guardian-classifier | Responses 风格 HTTP / SSE / WS;要求上游开放 |
| /v1/realtime、POST /v1/realtime/calls | 实验性 WS / WebRTC;默认关闭,真实音频联调未完成 |
| POST /v1/realtime/calls/{id}/hangup | 结束当前用户拥有的通话 |
| GET /v1/models | 上游目录缓存 5 分钟,只返回已核价模型 |
| GET /healthz | 进程健康检查 |
原生 Responses 的工具、未来字段和缓存参数透传,不注册或执行工具。只有会话 / 线程标识按用户、Key、账号隔离。原生 Codex 数组 input、instructions、store=false、stream=true 请求正文保持;简写输入会规范化。上游使用 store=false、stream=true。
HTTP 由客户端携带有效历史;这条订阅 HTTP 路径不支持 previous_response_id。WS 支持同连接、同模型、已完成响应的 ID,不保证跨连接续接。MiniSub 不保存对话正文,不提供后台任务、持久 conversation、文件上传或 store=true。
保留缓存前缀不等于保证命中率;实际还取决于上游账号、模型、路由和缓存有效期。上游 401 只刷新重试一次。Luna 仅在上游明确授权对应备用额度时映射到 gpt-reserve,对外模型名和计价仍为 Luna。
参数兼容边界: 公共 Responses API 与 chatgpt.com/backend-api/codex/responses 订阅入口的参数支持范围不同。2026-09-29 实测订阅上游对 max_tool_calls 返回 Unsupported parameter: max_tool_calls。MiniSub 的 /responses 会把该字段原样交给上游,再将这类上游 400 整理为 unsupported_parameter,并非本地漏转发。MiniSub 不会静默删除调用限制并声称已支持;流式中断也不等价于上游执行次数的硬限制。原生 web_search 配合 tool_choice: "auto" 已在 MiniLink 联调中成功使用,模型可以不搜索直接回答。
Chat 边界
| 能力 | 规则 |
|---|---|
| n=1..8 | 顺序生成、汇总候选;整次请求占一个并发,每个候选独立结算 |
| stop | 转换层截断输出;继续读取上游并按实际 usage 计费;不支持与 logprobs 合用 |
| 结构化输出 / 图片 / 内联文件 | 映射到 Responses 对应格式,上游验证权限和内容 |
| 旧 functions / function_call | 转成函数工具;强制单函数调用 |
| 采样、Token 上限、metadata、logprobs | 交上游校验;订阅不支持的参数明确报错 |
| seed、惩罚项、logit_bias、prediction、命名消息、Chat 音频 | 无等价实现,明确拒绝 |
| 未知 Chat 控制参数 | 明确拒绝;原生 Responses 未知字段仍透传 |
流式用量使用 stream_options: {"include_usage": true}。Chat 客户端自行提供消息历史、执行工具、回传结果;MiniSub 不运行 Agent 循环。文件 ID 必须由上游认识。
额度与并发
flowchart LR
Buy[月付有效期] --> Split[按绑定订阅账号的周锚点拆分]
Split --> Quota[完整周分完整额度<br/>首尾按有效秒数比例分配]
Quota --> Reserve[请求开始锁定周期和价格<br/>预留额度]
Reserve --> Usage[上游真实 usage<br/>结算并释放预留]每期额度独立,不结转;续费只补新增有效时长。更换订阅账号或调整锚点不会重算已分配周期,续费新增时长才采用新锚点。预留是估算,尾单可能超额;缺失 usage、模型或价格不匹配时保留待核对,管理员用 request resolve 处理。
文本 / 图片 / 音频按相应 Token 单价,独立搜索按成功请求次数;Responses web_search_call 按调用 ID 去重。其他内置工具额外费用尚不能保证完整覆盖。套餐额度是 API 等值金额,不代表 Plus 额外扣款,也不等于上游剩余配额。
LiteLLM 原始 JSON 每 6 小时同步,models.dev 辅助核对。冲突保留旧价,辅助源不可用时标记未核对;缺价或自动价格超过 7 天未验证会暂停对应调用。管理员可覆盖价格,历史请求锁定版本不重算。当前仅核价默认服务档位,超出支持上下文区间拒绝调用。
HTTP、WS、Chat、图片、搜索及 Realtime 共用用户并发;账号另有并发上限。Realtime 整段通话占一个名额;挂断未确认会暂停账号。限制属于单进程,不提供多实例集群配额。
上游明确 cyber_policy 按请求去重,用户累计达到个人阈值后停用(默认 3 次,可在用户编辑弹窗设置 1–100 次),等待管理员处理;不审核提示词。已经发出的在途请求可能继续返回拒绝事件。
YAML 与管理
套餐保存在各节点的数据库与 YAML 中;Mac App 创建套餐时选择节点,编辑只影响该节点。新增用户选择订阅账号,再选择同节点的套餐。本机重装后重新连接节点即可恢复管理。
管理 API 固定本机监听 127.0.0.1:8788。可由 Nginx 将同一 HTTPS 入口的 /admin/v1/ 转发到此端口,保留 Authorization 并禁用缓存;与 /subs/、/v1/ 共用外部 443 端口。Mac App 使用 HTTPS,管理员令牌首次经 SSH 获取后保存在本机 App 数据目录的普通文件中,不使用系统钥匙串;SSH 负责部署、重启、备份和清空。域名、TLS 与反向代理由管理员在 App 外配置。
也可通过 SSH 隧道连接:ssh -N -L 8788:127.0.0.1:8788 YOUR_SERVER。CLI 支持 --admin-url 和 --admin-token-file,普通用户 Key 无权管理。
YAML 保存 server / pricing / records / ceiling / policies(每套餐独立权限,无需选模板);SQLite 保存用户、套餐、个人权限覆盖、凭据和账本。有效权限为“套餐权限 + 个人覆盖”再与全局 ceiling 取交集,不能绕过停用、到期、额度或并发限制。
minisub config show
minisub config check --file /path/to/minisub.yaml
minisub config apply --file /path/to/minisub.yaml --revision DISK_REVISION
minisub config reload --revision DISK_REVISION
minisub user policy --id USER_ID
minisub user policy set --id USER_ID --file overrides.json --revision VERSION--revision 来自最新查询。YAML 原子保存并保留 .prev;权限对新请求和 WS 新生成生效,服务参数重启后生效,查询返回 restartRequired。个人覆盖是整体替换;省略 --policy 继承套餐。Chat 单独控制 image_input / file_input / web_search,文件包括 PDF。
独立图片 / 搜索开关不限制原生 Responses 内置工具;只允许受控 Chat 时应同时关闭 Responses HTTP / WS。客户端自己的工具、MCP 和网络不由这些开关控制。
| 管理 API /admin/v1/… | 用途 |
|---|---|
| GET config、POST config/apply、POST config/reload | 查看 / 保存 / 加载 YAML |
| GET users/policy?id=ID、POST users/policy、POST plans/policy | 有效权限 / 个人覆盖 / 套餐权限 |
| GET snapshot | 用户、账号、账本、价格、事件、当前并发与每日用量 |
| POST plans/save、POST users/save、POST accounts/save | 弹窗编辑;版本冲突返回 409 |
| GET requests?endpoint=…&before=…&beforeID=… | 按端点筛选、游标分页的请求日志 |
旧 config.json / 数据库原位迁移,保留 Key 和账本。旧配置迁移保留既有能力;全新初始化默认关闭 Realtime。
备份恢复
minisub service stop
minisub backup --file /path/to/minisub.backup --password-file /path/to/password
minisub service start
minisub restore --file /path/to/minisub.backup --password-file /path/to/password --data-dir /path/to/new-directory密码至少 12 字符,备份使用 AES-256-GCM,包含 YAML、数据库和加密密钥。恢复到新目录并轮换管理 Token,用户 Key 和账本保持。更多命令见 minisub --help。
认证、传输或计费规则变化仍可能需要升级。Mac 原生 App 已提供服务器连接、用户 / 套餐 / 账号管理、用量事件和权限配置;已显示上游每周用量;支付集成尚未提供。
