github.com/MAX-API-Next/MAX-API
v1.0.5
MAX-API-Next/MAX-API
What this package is like to depend on
Last release 13 days ago
11 Aug 2026
Ships on a steady schedule
a new release about every 1 weeks
Some releases are documented
notes for 2 of 6 stable releases
Nothing withdrawn
no release was ever pulled
2 months old
23 releases · first in 2026
23 releases in the last 12 months
see the full history below
Release timeline
23 releases · Jun 2026 to Aug 2026Releases
latest 23-
v1.0.511 Aug 2026Release notes
Open source →Important
v1.0.5 是一次围绕路由能力、计费可靠性、安全边界和渠道兼容性的正式更新。版本整合了 v1.0.5-preview.1 至 v1.0.5-preview.4 的主要成果,并将预览阶段的零散改动归并为面向用户的功能与稳定性说明。
本版本包含数据库结构变更。生产升级前请备份主库与日志库,确认数据库账号具备 AutoMigrate 所需权限,并在同版本数据副本或测试环境完成迁移与核心计费流程验证。前端资源也必须重新构建后再重启服务。
Release Notes
GitHub 地址
https://github.com/MAX-API-Next/MAX-API/releases/tag/v1.0.5
Highlights
- Token 路由策略升级:API Key 可选择系统自动路线,或配置最多 8 个有序手工分组,并控制失败后是否跨分组重试;模型目录、Affinity、实际选组和重试流程现在使用同一份路由计划。
- 计费与退款更加可靠:钱包、订阅、Token、Realtime 和异步任务结算引入持久化幂等记录与后台恢复机制,降低重复扣费、重复退款、进程中断和并发回调造成账务不一致的风险。
- OpenAI Alpha Search 正式接入:新增
POST /v1/alpha/search,支持 Codex 与 Advanced Custom 直通渠道,并纳入模型映射、Param Override、渠道选择和 Web Search 计费。 - 视频与异步任务能力增强:DoubaoVideo / Seedance 支持完成态差额结算控制和实际 usage 结算;通用视频任务可配置创建、更新时间字段,Midjourney 提交、轮询、回调和退款统一进入持久化账务流程。
- 缓存与限流可靠性提升:用户和 Token 缓存增加版本栅栏、持久失效任务和跨进程恢复;Redis 限流异常时会回退到本机同策略限流,避免缓存故障导致保护整体失效。
- 安全边界全面收紧:OAuth 一次性 state、SSRF 防护、支付回调校验、删号二次验证、Midjourney 签名图片地址、敏感凭据隐藏、上游响应头过滤和日志脱敏得到统一加强。
- 模型与渠道兼容性扩展:新增 DeepSeek Responses,保留 Qwen/QwQ
thinking_budget,完善 OpenAI Realtime、Alpha Search、状态码映射及多家渠道显式0/false参数转发。 - 管理端体验与可观测性优化:新增 API Key 路由编辑器、Playground 参数面板、离线实例批量清理和健康检查端点,并改善移动端表格、渠道编辑、模型定价和错误提示。
New Features
- API Key 新增可持久化路由策略,支持自动路线、手工分组排序和跨分组重试,同时兼容旧 Token 的
group配置。 - 新增
/v1/alpha/search中继能力,以及/health、/health/live、/health/ready编排探针。 - Playground 新增温度、Top P、频率惩罚、存在惩罚、最大 Token 和随机种子等可视化参数配置。
- DoubaoVideo 渠道新增视频任务差额结算开关;通用视频任务新增创建时间和更新时间路径配置。
- DeepSeek 渠道新增 Responses API 支持;Qwen/QwQ 请求支持
enable_thinking与thinking_budget,并保留显式零值。 - 系统实例面板新增一键清理离线实例,模型详情页补充 Responses Compact 与 Alpha Search 调用样例。
Performance and Reliability
- 计费预扣、最终结算、退款、账单日志和 usage 写入使用稳定 operation key 与数据库事务,服务重启后可继续处理未完成副作用。
- 用户与 Token 缓存失效改为版本化、可恢复流程;待处理失效任务同时阻止旧数据重新写回 Redis。
- Redis 限流采用原子滚动窗口,并提供标准 429 重试信息;Redis 异常时使用有界超时和本机降级策略。
- 多分组模型去重、Affinity 正则和计费表达式缓存采用有界索引或淘汰策略,减少大规模模型、渠道与表达式场景下的重复扫描和全量缓存清空。
- Realtime、Bedrock、Cohere、PaLM、智谱、Gemini 等链路补齐取消、心跳、超时和资源释放,降低异常断连后的连接与 goroutine 滞留。
- 前端构建增加 Tailwind 产物守卫,DataTable、移动端列表和长标签布局得到优化,减少源码与发布静态资源不一致及窄屏溢出。
Bug Fixes
- 修复重复请求、并发 worker、支付回调或进程中断可能造成重复扣费、重复退款、Token 与资金账本不一致以及账单日志重复的问题。
- 修复 Stripe、Creem、易支付和 Waffo 等支付回调只验签但未完整核对订单渠道、金额或币种的问题。
- 修复异步任务失败退款不可恢复、Midjourney 重复任务归属、Seedance usage 未进入差额结算,以及临时渠道故障被误判为任务失败的问题。
- 修复 OAuth 回调重复兑换、外部跳转、私网 discovery、旧会话继续授权,以及用户删除后 OAuth、access token、API Token 或订阅残留的问题。
- 修复 Token 多分组模型目录不完整、Affinity 从错误分组开始重试、Playground 显式分组被覆盖,以及显式关闭跨分组重试未生效的问题。
- 修复渠道更新可能覆盖运行时字段、状态码映射保存后丢失、多密钥并发更新冲突,以及部分渠道丢弃显式
0、空字符串或false的问题。 - 修复 OpenAI Realtime、DeepSeek、Qwen、AWS Nova、讯飞、Vertex、Gemini、Baidu、Zhipu 等渠道的协议、流式断连、空响应、配置异常和资源释放问题。
- 修复敏感上游错误、凭据、Cookie、控制字符或超长正文进入客户端响应与业务日志,以及图片、视频和动态 HTML/CSS 内容校验不足的问题。
- 修复模型与供应商同名并发创建、定价配置被异步表单误清空、负数或非有限价格写入,以及账单汇率无效时仍展示不可信金额的问题。
Compatibility Notes
- 本版本会新增或调整 Token 路由、持久化结算、缓存失效、账单日志回执、OAuth 流程、Midjourney 账务归属、quota_data 聚合及模型/供应商唯一键等数据库结构;请确保 AutoMigrate 可执行并提前演练。
- 既有 Token 无需立即回填路由 JSON,会继续根据旧
group和cross_group_retry生成兼容策略;新客户端建议优先使用routing字段。 - OAuth state 接口改为
POST /api/oauth/state,并要求携带 provider 与 intent;删号接口现在要求account_delete二次验证,旧 Midjourney 裸图片地址不再可用。 - 渠道更新接口改为显式字段补丁,未提交字段会保留,余额、累计用量、内部状态和时间戳等运行时字段不能再通过普通编辑接口修改。
tiered_expr的header()/param()读取范围进一步收紧;Midjourney、Suno 和换脸任务不再使用未配置价格的隐式兜底,升级前应复核表达式、任务费率和 Alpha Search 工具价格。TRUSTED_PROXIES、SSRF、防护抓取、PassThrough 字段权限、视频 data URL 和上游响应头转发采用更严格的失败关闭规则;非标准代理或自定义渠道需要复核配置。- Redis 故障时的本机限流按实例分别计数,不能替代多实例部署中的全局 Redis 窗口;应继续监控 Redis 可用性。
- 发布前必须进入
web/default执行bun install与bun run build,再重启 Go 服务;直接复用旧dist不会包含新的路由编辑、Alpha Search 样例和前端修复。
Upgrade Checklist
- 备份主库、日志库和关键配置,并在数据副本上完成 AutoMigrate 演练。
- 核对钱包、订阅、Token、Realtime、视频任务、Midjourney 和支付回调的预扣、结算与退款结果。
- 复核 Token 路由、渠道状态码映射、任务价格、Alpha Search 工具价格和 tiered billing 表达式。
- 检查 OAuth/OIDC、反向代理、Redis、SSRF allowlist、通知凭据和自定义 PassThrough 集成。
- 使用 Bun 安装最新前端依赖并重新构建静态资源,再执行滚动升级和健康探针验证。
Verification
- preview 阶段已完成后端全量测试、
go vet、JSON wrapper 检查及计费、认证、路由、支付、任务和数据库兼容性定向回归。 - 前端已完成类型检查、生产构建、Tailwind 产物检查及路由编辑、Playground、OAuth、渠道配置和安全渲染等测试。
- 正式发布前仍建议在实际 MySQL/PostgreSQL、Redis 多实例、支付 sandbox、真实 OAuth/IdP 和常用上游渠道环境执行部署级回归。
Full Changelog: v1.0.4...v1.0.5
-
v1.0.5-preview.4.0.20260811070430-74a7ed3e4e2911 Aug 2026 pre-releaseNothing published for this version
-
v1.0.5-preview.410 Aug 2026 pre-releaseRelease notes
Open source →Warning
v1.0.5-preview.4为预览版本,新增 Token 路由策略存储、API Key 路由编辑、OpenAI Alpha Search 中继和健康检查端点,并继续收紧支付回调、Midjourney 异步账务、渠道更新、日志持久化、认证会话和上游 HTTP 边界。升级前请确认生产环境会执行项目 AutoMigrate、重新构建管理端资源,并在测试环境验证自动路线、手工分组顺序、跨分组重试、旧 Token 兼容、Alpha Search 渠道与价格配置、支付金额与币种、Midjourney 提交/失败/回调、渠道多密钥更新以及代理和响应头策略。新版本会在tokens表增加routing_policy文本字段,创建midjourney_billing_claims账务归属表和auth_flows一次性认证流程表;既有 Token 不要求立即回填。TRUSTED_PROXIES、定价 JSON、视频 data URL、OAuth discovery 抓取和上游响应头转发均增加更严格的失败关闭规则。依赖全网可信代理、环境代理访问私网 discovery、超大定价配置、非视频 data URL,或直接透传上游Set-Cookie/ hop-by-hop header 的部署需要在升级前调整配置与集成。Release Notes
GitHub 地址
https://github.com/MAX-API-Next/MAX-API/releases/tag/v1.0.5-preview.4
Highlights
- Token 路由从单一分组投影升级为可持久化策略:每个 Token 可以选择系统定义的自动路线,或配置最多 8 个有序手工分组,并独立控制失败后的跨分组重试。
- 认证、渠道选择和模型目录使用同一份路由计划:请求进入运行时后,路由策略会被规范化为有序分组计划,普通中继、Affinity 选择、重试和
/v1/models返回不再各自推导分组。 - 管理端 API Key 支持可视化路由编辑:可以查看自动路线包含的分组、切换到手工模式,通过拖拽、方向键或按钮调整分组顺序,并配置跨分组重试;已有但当前不可供新选择的路由会被标记并保留。
- 渠道更新改为显式字段补丁:更新接口只接受允许修改的配置字段,省略字段会保留原值,余额、累计用量、测试时间和内部多密钥状态等运行时数据不能再通过普通渠道编辑请求覆盖。
- 旧 Token 不需要迁移即可继续工作:旧的
group和cross_group_retry字段仍作为兼容投影,未携带新路由字段的旧客户端仍可创建和更新 Token。 - 多分组模型目录与实际选组保持一致:手工路由下来自所有有序分组的可用模型都会返回,并按模型名去重,同时保留优先 owner 信息。
- 随机选择与安全令牌统一使用系统安全随机源:OAuth state、通用随机 key、渠道权重选择、多密钥随机选择、签到随机奖励和模型同步退避抖动不再依赖
math/rand。 - 支付回调以订单真值为准:Stripe、Creem、易支付、Waffo 和 Waffo Pancake 的充值/订阅完成路径会在入账前核对支付渠道和金额,并在供应商提供币种时校验币种;不匹配回调不会把订单标记成功或增加额度。
- Midjourney 接入持久化异步账务归属:上游任务 ID 按渠道绑定到唯一的本地账务任务,提交重放、重复 provider ID、明确失败退款、未知提交结果和回调/轮询竞争统一进入 CAS 与持久结算流程。
- 日志和上游 HTTP 边界统一收口:持久日志会清理控制字符、无效 UTF-8 并限制总长度;任务错误不再暴露任意原始上游响应,响应头转发会过滤 cookie、hop-by-hop、畸形值及
Connection动态声明的字段。 - 认证与敏感设置使用服务端当前状态:被禁用、删除或降权的用户不能继续依赖旧会话或 Token owner 状态访问;Webhook、Gotify 等通知凭据不会再通过当前用户接口回显,更新时省略凭据会安全保留原值。
- OpenAI Alpha Search 成为独立中继能力:新增
POST /v1/alpha/search,支持 Codex 原生路径和 Advanced Custom 直通路线,统一纳入渠道选择、模型映射、Param Override、请求体保留和 Web Search 计费。 - 健康检查面向编排系统补齐:新增
/health、/health/live和/health/ready,readiness 会执行数据库探测,失败时返回503和通用错误消息,便于 Kubernetes/负载均衡探针接入。
New Features
- 新增版本为
1的 Token 路由策略对象,支持smart和manual两种模式、自动路线 key、手工分组数组及retry_on_failure配置。 - Token 管理接口现在返回
routing与routing_legacy信息;分组接口同时返回可供当前用户选择的auto_routes,前端可以显示系统定义的路线名称和分组链。 - API Key 管理抽屉新增路由编辑器,支持六种前端语言的路由说明、可用性提示、手工分组搜索、顺序调整、键盘移动和数量上限反馈。
- 新增
openai-alpha-searchendpoint 类型、RelayModeAlphaSearch和AlphaSearchRequestDTO;请求解析会保留原始 JSON,模型映射后仍把未知字段转发给上游,避免新参数在网关层丢失。 /v1/alpha/search已接入 Relay 路由和渠道测试流程:Codex 渠道走/backend-api/codex/alpha/search,Advanced Custom 只在配置了同名 incoming route 且 converter 为 none 时参与选择。- 模型详情页新增 Responses Compact 与 Alpha Search 的
curl、Python、TypeScript、JavaScript 调用样例;JS/TS 样例会先检查response.ok,避免错误响应被当作成功 JSON 展示。 - 新增公开健康检查端点
/health、/health/live、/health/ready,readiness 检查复用数据库连接探测并保持错误消息脱敏。
Improvements
- 路由策略保存前会统一校验版本、模式、自动路线可选择性、手工分组权限、分组倍率、重复项和最大数量;不合法策略在进入中继前会失败关闭。
- 运行时路由计划会按配置顺序选择分组,并在允许跨分组重试时推进到下一分组;重试参数会排除已经失败的渠道,避免同一请求重复命中已知失败渠道。
- Affinity 渠道命中时会按路线顺序查找首个可使用该渠道和模型的分组,并从实际匹配位置初始化后续重试状态;
/pg/chat/completions中显式指定的分组仍优先于 Token 的存储策略。 - 已保存但后来不可用的手工分组会在运行时跳过;如果策略中已经没有任何可用分组,请求会明确拒绝,而不是随机落入用户默认分组。
- 新建和更新 Token 会同时维护新策略与旧
group/cross_group_retry投影;更新时省略路由字段会保留原有策略,单独提交cross_group_retry: false也会作为明确变更生效。 - API Key 编辑抽屉会等待分组数据加载完成后再初始化表单,并忽略抽屉关闭、目标切换或旧请求晚到后的过期响应;加载失败统一进入现有错误提示路径,后台刷新分组数据不会再清空编辑中的内容。
- 手工分组选择器收敛为单个全宽、带可访问名称和展开状态的 combobox;已选分组在触发器内统一展示,删除、排序和不可用状态在独立列表中处理,并补充 React Testing Library 交互回归。
- 多分组模型去重改为集合索引,避免模型数量增加时反复线性扫描;渠道写入则通过
UpdateFields只持久化本次实际变更的配置和多密钥字段。 - OAuth state、渠道权重选择、多密钥随机选择、签到奖励和同步退避抖动改用
crypto/rand;底层随机源失败时,安全敏感路径返回错误或采取明确降级,不再继续使用可预测伪随机结果。 - 支付完成逻辑新增统一
PaymentValidation,金额按最小货币单位精确比较,币种大小写归一化;订单状态迁移、额度增加、订阅激活和缓存失效保持在对应数据库事务或持久失效任务中。 - Midjourney 提交、轮询和通知回调共享账务任务更新服务;明确拒绝会原子写入失败状态与退款意图,未知是否已发送的请求保留为人工复核,重复任务归属不会再次扣费或误退首个请求。
- 用户邀请奖励与新用户创建改为同一事务提交,管理员额度覆盖和批量 Token 删除也会在业务事务中登记持久缓存失效,避免数据库成功后缓存或奖励状态脱节。
- 渠道更新现在持有与轮询一致的渠道锁,并在单个事务内提交字段变化和能力索引;能力重建失败会回滚渠道配置,多密钥数量、禁用时间和禁用原因会随密钥增删同步裁剪。
- 持久日志内容统一限制为 4096 个字符并规范化控制字符;异步任务失败原因、结算 effect payload、消费日志和审计日志复用同一清理路径。历史日志清理继续保留管理审计日志,并同步分批清理过期账单 receipt。
- 上游响应头复制收敛为共享 helper,音频、MiniMax TTS、视频代理和普通中继采用同一过滤规则;本地 request ID 不会被上游覆盖,上游 request ID 只在通过安全校验后记录到请求上下文。
- 自定义 OAuth discovery 使用项目 SSRF 防护和受保护拨号器;开启 SSRF 防护时直接连接已验证目标,不再让环境代理绕过 DNS/IP 绑定校验。
- 内存限流器和系统监控支持有界停止,服务关闭时会等待后台 goroutine 退出;SMTP 连接/操作增加 30 秒截止时间,Turnstile 校验增加 10 秒请求超时和 HTTP 状态检查。
- 渠道 Affinity 正则缓存改为容量 4096 的 LRU;计费表达式拒绝
NaN/Infinity,结算表达式失败时使用冻结的预扣值与分组后估算值中较高者并记录可观测错误。 - 模型倍率与 completion ratio 保存前会规范化模型别名并拒绝冲突键;所有定价映射增加大小、条目数、键长度、空键、空值和非有限数检查,加载失败不会替换正在使用的映射。
- 管理端代码高亮结果会在写入
innerHTML前再次净化;图表 ID、CSS 变量名和颜色值会过滤样式逃逸、URL、@import和可执行表达式,降低服务端配置或动态内容触发 XSS/CSS 注入的风险。 - OAuth state 改为 32 字节安全随机的一次性流程凭据,只在数据库保存 HMAC,并绑定 provider、login/bind 用途和绑定用户;并发回调只能有一个成功消费,过期记录由后台任务定期清理。
- OIDC 和 Generic OAuth 的 token/userinfo 请求复用项目 SSRF 防护、DNS/dial 与 redirect 校验,并增加请求超时;调试日志不再记录授权码片段、endpoint、token/userinfo 正文或用户 PII。
- access token 重生成和邀请额度转移在原 IP 限流之外增加用户维度敏感操作限流,同一账号切换来源 IP 也不能绕过低频限制。
- Alpha Search 渠道选择按请求路径做显式过滤:普通 OpenAI 渠道不会误接
/v1/alpha/search,Codex 和匹配 incoming route 的 Advanced Custom 才会进入直连与缓存选择路径。 - Alpha Search 预消费在普通模型估算外追加确定性的单次 Web Search 附加费用,并校验基础 quota、分组倍率和工具价格的有限非负约束;只有上游成功返回后才记录工具用量,失败请求走既有退款路径。
- Dashboard 账单展示在金额换算前校验
QuotaPerUnit与 CNYUSDExchangeRate,查价失败对外统一返回billing information unavailable,原始错误仅写入服务端日志。 - 删除用户现在在同一事务中清理 OAuth 绑定、取消 active 订阅、失效用户 access token,并按软删除/硬删除分别禁用或移除 API Token,同时登记持久缓存失效。
- 安全随机 helper 不再因可恢复的熵源读取错误触发 panic;access token、邀请码、邮件 Message-ID、充值/订阅订单号和系统任务 runner ID 会显式失败或使用不承载安全语义的唯一性降级。渠道加权选择会传播随机源错误,并修正零基随机区间对首个渠道的额外偏置。
- Relay JSON 热路径继续迁移到
common.Marshal/common.Unmarshal/common.DecodeJson,覆盖 DTO value、OpenAI message、Ali、Baidu、Coze、SiliconFlow、Vertex 和 Zhipu;JSON policy allowlist 从 158 条收敛到 121 条。 - Ali、Baidu、Coze 和 SiliconFlow 的可选 provider 参数改为指针字段,缺省值继续省略,客户端显式提交的
0、空字符串或false会保留到上游 payload。
Bug Fixes
- 修复手工多分组 Token 的
/v1/models只读取第一个 owner group,导致后续分组独有模型不出现在模型目录的问题。 - 修复已有运行时专用自动路线无法在 API Key 编辑器中保存其他基础字段的问题;未改变路由时现在保留原值,真正修改路由时才要求选择可用路线。
- 修复路由计划选择过程中没有可用 priority 时的边界处理,避免空候选集合进入负索引或错误选择路径。
- 修复 Playground 显式 group 与 Token 路由计划同时存在时的优先级问题;显式请求分组不会再被保存的 Token 计划覆盖。
- 修复仅更新
cross_group_retry时请求被当作“未修改路由”的问题,特别是显式关闭重试的false值现在不会被零值语义吞掉。 - 修复 Affinity 渠道只在路线首组检查、导致本可用于后续分组的固定渠道被错误放弃,以及重试索引从错误位置开始的问题。
- 修复旧 Token 的空分组在缺少用户分组上下文时生成空手工策略的问题;现在优先使用认证用户分组,否则回退到系统默认自动路线。异常类型或空指针形式的上下文策略也会继续按 legacy 路径处理。
- 修复旧 Token
group为空时 API Key 表单保留空手工分组并阻止保存的问题;表单会使用当前可用默认分组,同时限制默认列表不超过 8 项。 - 修复 API Key 编辑期间分组查询完成或重新获取后重置用户输入、并发详情请求晚到覆盖新目标,以及详情加载失败产生未处理 Promise 的问题。
- 修复手工路由最大选择状态下触发器被拆成多个交互区域、删除按钮混入 combobox,以及长路由标签无法正确截断的问题;相关测试改为按角色、可访问名称和真实删除行为断言。
- 修复渠道更新接口直接绑定完整
Channel模型造成的批量赋值风险;伪造的余额、用量、创建/测试时间、内部状态和channel_info不再写入数据库。 - 修复只更新渠道状态时其他配置可能被零值清空、未知状态值可以进入持久层,以及多密钥管理操作写回无关字段的问题。
- 修复充值与订阅回调只验签、不核对订单金额或币种的问题;低金额、超额、错误币种、错误支付 provider 和非正额度会在订单完成前失败,易支付的订单完成与用户入账也改为原子事务。
- 修复 Creem 回调重复写入相同客户邮箱、Waffo Pancake 创建 checkout 失败后订单状态处理不一致,以及订阅完成重放可能重复产生副作用的问题。
- 修复
/api/user/self回显 Webhook secret、Gotify token 等通知凭据,以及编辑设置时因前端收到脱敏值而清空已有凭据的问题;通知邮箱现在使用标准地址解析校验。 - 修复旧会话中的管理员角色、用户状态或 Token owner 状态与数据库不一致时仍可继续授权的问题;除 enabled 外的用户状态统一拒绝,已删除 Token owner 返回明确禁止响应。
- 修复邀请注册中受邀者和邀请人奖励分步提交、任一步失败后可能只完成一侧的问题;奖励、邀请计数、新用户额度和缓存失效现在随用户创建一起提交或回滚。
- 修复渠道更新和后台轮询并发写多密钥状态、能力索引重建失败后配置已提交,以及清空最后一个密钥时旧多密钥元数据残留的问题。
- 修复 Midjourney 同一 provider task ID 被重复提交时可能重复扣费或错误退款、跨渠道同名任务被错误认领,以及通知回调无法完成本地 shadow task 的问题。
- 修复 Midjourney/视频/Suno 轮询因临时获取渠道缓存失败就把已计费任务标记失败并触发退款的问题;临时基础设施错误现在保留任务状态等待后续轮询。
- 修复异步任务明确提交失败时任务状态与退款操作分开写入、进程中断可能遗留已扣额度的问题;失败状态、展示 quota 和持久退款意图现在原子提交。
- 修复任务失败原因、无结构上游错误体和调试日志可能持久化敏感 URL、IP、密钥、控制字符或超长正文的问题;对外错误只保留可解析的安全消息,原始读取上限为 1 MiB。
- 修复上游
Set-Cookie、Transfer-Encoding、CR/LF 注入值和Connection声明的临时 header 被转发,以及被动态声明的 request ID 仍被错误捕获的问题。 - 修复 OAuth discovery 管理接口可直接访问私网/本机地址、且受保护请求可能经环境代理在代理侧重新解析目标的问题。
- 修复视频代理接受任意 MIME 的 data URL 和无限制解码的问题;现在仅接受 MP4、WebM、QuickTime、Matroska,解码后最大 100 MiB,并复用安全响应头复制。
- 修复未配置价格的
mj_*、suno_*和swap_face任务模型继续使用隐式兜底价格的问题;只有明确模型价格、默认价格或 rate card 可用时才允许继续计费。 - 修复智谱流式读取 panic、scanner 错误或客户端取消后仍可能伪装成正常
[DONE]的问题;Gemini 图片响应超过 OpenAI 兼容上限时也会明确拒绝。 - 修复前端代码高亮 HTML 和图表动态 CSS 可越过标签/样式边界的问题,恶意事件属性、脚本、外链 URL 和样式注入不再进入最终 DOM。
- 修复 HTTP/2 transport 重放请求时
GetBody复用同一个可变 seeker、并发 retry 可能共享 cursor 或发送错误内容的问题;内存和磁盘 body 现在都会为每次重放创建独立 reader。 - 修复 Ali 渠道在客户端省略
top_p时仍注入最小值的问题;缺省值保持不发送,仅对显式越界值按 Ali 范围钳制。 - 修复 Compatible、Responses 和 Claude 的 PassThrough 原始 JSON 绕过渠道字段权限、默认可透传
service_tier、speed等可能增加成本字段的问题;只有渠道显式允许的受控字段才会保留。 - 修复 Zhipu 和 Vertex token 缓存出现非预期值类型时直接断言导致 relay panic 的问题;无效缓存会被清理并重新获取。Zhipu 密钥格式错误现在直接返回失败,且日志不再包含密钥原文;Vertex 的畸形 PEM 会稳定返回解析错误。
- 修复
GetRandomInt、GetRandomString和 CPU profile 监控在随机源、CPU 采样、目录或文件错误时终止进程的问题;GenerateRandomKey改用可返回读取错误的 reader 路径,避免 Go 新版本crypto/rand.Read的不可恢复 fatal 行为。 - 修复 SiliconFlow 图片参数、Coze
stream/历史保存、Baidu 搜索/引用开关及 Ali provider 参数的显式零值被omitempty丢弃;相关请求现在区分“未提交”和“明确提交零/false”。 - 修复 2FA 统计和备用码查询在 SQL 字符串中硬编码布尔字面量的问题,统一改为 GORM 绑定参数,保持 SQLite、MySQL 和 PostgreSQL 方言兼容。
- 修复 Alpha Search 未作为独立 endpoint/relay mode 进入路由、渠道测试和模型详情样例的问题;现在 Codex 与 Advanced Custom 路径可被正确识别,普通 OpenAI 渠道不会错误承接。
- 修复 Alpha Search 请求体重建可能丢失未来字段的问题;原始 JSON 会在模型替换后保留未知字段,避免前端或上游新增参数被中继层静默裁剪。
- 修复 Alpha Search 写回客户端前未完成成功结算的风险;当前路径会在复制响应体前记录 Web Search 用量并结算,写响应失败不会把已成功的上游调用当成未计费请求。
- 修复 Alpha Search 前端 JS/TS 样例先解析 JSON、后检查 HTTP 状态的误导;错误响应现在会先触发状态检查。
- 修复 Midjourney plus action
custom_id对空分片、缺失索引、非正索引和未知*_variation后缀处理不完整的问题,避免 malformed custom ID 导致 panic 或被错误转换为合法动作。 - 修复软删除用户后 OAuth 绑定、access token、已启用 API Token 与 active 订阅仍可残留的问题;硬删除用户现在同时移除 Token 并取消订阅,已取消订阅记录保留历史状态。
- 修复软删除路径试图更新 Token 表不存在的
updated_at字段而导致清理失败的问题。 - 修复账单展示在
QuotaPerUnit为0、负数、NaN、Infinity或 CNY 汇率无效时可能除零/产生非有限金额的问题;token 展示和 unlimited token 路径保持兼容。 - 修复账单查价错误把内部模型或配置失败细节暴露给客户端的问题;对外错误消息统一,便于监控和客户端稳定处理。
Compatibility Notes
tokens表新增routing_policy文本字段,由 GORM AutoMigrate 创建,SQLite、MySQL 和 PostgreSQL 均使用通用文本类型。升级前请确认数据库账号具备迁移权限,并在副本上先演练启动迁移。- 既有 Token 的空
routing_policy会根据原group、用户分组和cross_group_retry在运行时合成兼容策略;不会自动把历史 Token 批量改写为新 JSON。旧字段仍保存首个投影分组和重试开关,供旧客户端继续使用。 - 新 API 客户端应优先发送
routing。只发送旧group时仍按兼容路径处理;更新请求省略routing和group时会保留当前存储策略。显式提交新策略时,自动路线必须是当前用户可选择的路线,手工模式只能使用真实可用分组,最多 8 个且不能重复。 cross_group_retry现在按可选布尔值处理:省略表示保持现状,显式false表示关闭重试。自定义客户端不应再依赖布尔零值等同于“未提交”的旧行为。- 管理端允许展示并保留已经存储、但当前不再出现在新选择列表中的路由。若用户实际切换路由或编辑手工分组,应先移除不可用项,后端不会接受新的不可用策略。
/api/group响应新增auto_routes字段;自定义客户端应忽略未知响应字段,并继续兼容原有分组字典。Token 详情响应新增路由字段,routing_legacy可用于区分兼容合成结果和实际存储策略。PUT /api/channel/现在是显式允许字段的局部更新:未提交字段保持原值,空白密钥不会清除已有密钥,未知渠道状态会被拒绝,余额、用量、时间戳、内部状态和客户端提交的原始channel_info会被忽略。依赖该接口直接改写运行时字段的非标准客户端需要迁移到专用管理流程。- 源码构建新增开发依赖
@testing-library/[email protected]。从源码升级时应在web/default使用 Bun 按最新web/bun.lock安装依赖,不要复用旧node_modules。 - 安全随机数依赖操作系统熵源。极少数熵源不可用场景下,OAuth state、签到奖励或渠道选择可能返回明确错误;
RandomSleep的抖动会降级为零延迟,而不会切回可预测的伪随机实现。 - 自定义 Relay 或审计中间件若曾依赖 Ali、Baidu、Coze、SiliconFlow 显式零值被省略,需要同步调整:缺省字段仍不发送,但显式
0、空字符串和false现在属于有意上游参数。 - AutoMigrate 会新增
midjourney_billing_claims,以(channel_id, mj_id)唯一索引绑定上游任务与本地账务任务。数据库账号需要具备建表和索引权限;历史同名 Midjourney 任务不会自动合并,无法唯一判定时会失败关闭并要求人工复核。 - 支付 webhook 现在必须与本地订单的 provider 和实际支付金额一致,并在供应商返回币种时同时匹配币种。自定义支付适配器应传递可靠的支付证据;允许折扣的渠道只能少付且不能超出订单金额,无法确认金额的回调不应伪造校验值。
TRUSTED_PROXIES只接受具体 IP 或受限 CIDR;0.0.0.0/0、::/0、可组合覆盖整个地址空间或无效条目会使进程启动失败。未配置时仍只信任默认 loopback,反向代理部署应显式填写真实代理网段。- 开启 SSRF 防护后,受保护抓取不会使用
HTTP_PROXY/HTTPS_PROXY,以确保连接目标与已验证 DNS/IP 一致。必须经代理访问的内部 discovery 地址需要通过明确的 SSRF allowlist 和受控网络方案处理,不能依赖环境代理绕过校验。 - 上游响应不再向客户端转发
Set-Cookie、hop-by-hop header、畸形名称/值,以及Connection中动态列出的字段。依赖这些非端到端 header 的自定义渠道应改用专用响应处理;安全的多值端到端 header 仍会保留。 - 持久日志
content与任务失败原因现在最多保留 4096 个 Unicode 字符,换行和制表会规范化为空格,并在截断时追加标记。依赖完整原始上游正文排障的部署应改用受控 debug 日志或外部追踪,不能再从业务日志读取无限正文。 - 定价 JSON 上限为 2 MiB、20000 项、单个模型键 256 个 Unicode 字符;
ModelRatio和CompletionRatio会按模型匹配规则规范化键并拒绝别名冲突。升级前应检查自动生成的大型配置和只在大小写/后缀上不同的重复键。 - Midjourney、Suno 和换脸任务不再接受未配置价格的隐式通用兜底。升级前应为实际任务模型配置固定价格、默认价格或 task rate card,否则请求会返回价格未配置错误。
- 视频代理 data URL 仅接受
video/mp4、video/webm、video/quicktime、video/x-matroska,解码后上限为 100 MiB。返回其他媒体类型或超大内联视频的自定义适配器需要改为受控视频 URL 或调整上游输出。 - 当前用户接口中的 Webhook secret 和 Gotify token 会返回空值。客户端更新通知设置时应省略未修改的凭据;服务端仅在通知类型与已保存配置匹配时保留旧值,不能再依赖读回明文后原样提交。
- AutoMigrate 会新增
auth_flows表和唯一 token HMAC 索引。OAuth state 接口由GET /api/oauth/state改为POST,请求必须携带provider和intent;自定义前端或客户端需要同步升级,绑定流程还必须携带有效用户会话。 - OIDC/Generic OAuth 的私网 IdP 在启用 SSRF 防护时默认会被拒绝;确有需要的部署应通过现有域名/IP/端口 allowlist 精确放行,不能依赖环境代理或全局关闭保护。
- PassThrough 不再自动绕过渠道字段权限。需要
service_tier、speed、inference_geo等能力的渠道必须显式启用对应允许项,并同步确认本地倍率或计费表达式覆盖真实上游价格。 - 前端路由编辑器属于管理端构建产物。发布前必须执行
cd web/default && bun run build生成最新资源,再重启 Go 进程;直接使用旧dist不会包含本版路由配置入口。 /v1/alpha/search使用新的openai-alpha-searchendpoint 类型。自定义渠道若要承接该路径,需要使用 Codex 渠道类型,或在 Advanced Custom 中配置incoming_path: /v1/alpha/search、无转换器的直通路线。- Alpha Search 会在模型基础预消费外追加单次 Web Search 附加费用,并受工具价格、分组倍率和 tiered billing fallback 影响;升级前应检查相关模型、分组和工具价格配置,避免生产请求因价格无效被失败关闭。
- 模型详情页新增 Alpha Search/Responses Compact 样例属于前端构建产物;发布包仍需要重新执行
web/default构建,直接复用旧静态资源不会显示新的 endpoint 样例。 /health/ready在数据库探测失败时返回 HTTP503与通用"database connection failed"消息;部署探针应优先使用该 readiness 端点,不应继续依赖管理后台状态接口解析。- 删除用户会立即使 OAuth 绑定、系统 access token 和 API Token 失效,并取消 active 订阅。外部集成不应依赖“删除用户后 Token/OAuth 仍可短期可用”的旧残留行为。
- Dashboard CNY 金额展示现在要求
USDExchangeRate为正且有限;配置为0、负数、NaN或Infinity会返回通用账单不可用错误,而不会继续输出不可信金额。
Verification
- 主体变更延续此前对
1e8e5cf6..06b82459范围执行的集中门禁结果;本次补充基于当前09654cc5干净源码树重新核查06b82459..09654cc5的实际差异。 - 后端全量
go test ./... -count=1通过,覆盖 Controller、Model、Service、Relay、计费表达式、认证、支付、Midjourney、任务轮询、渠道更新和数据库兼容回归;资源独占时relay/helper时间敏感用例连续 3 次通过。 - 前端全量 Bun 测试通过:143 项通过、0 项失败,共 37 个测试文件;新增覆盖代码高亮 HTML 净化和图表 CSS 注入,同时保留 Token 路由、Playground、OAuth、通知和既有安全回归。
go vet ./...、go run ./tools/jsonwrapcheck和bun run typecheck通过;JSON wrapper 检查报告为 121 条 allowlisted direct calls。- 当前提交额外通过
bun run build:check,包含tsc -b、Rsbuild 生产构建和 Tailwind 产物校验;构建生成 2 个 CSS 文件并通过 Tailwind 检查。 - 当前补充通过
go test ./relay ./service ./model ./controller ./router -run "TestAlphaSearch|TestAlphaSearchSelectionUsesOnlySupportedChannelTypes|TestBuildTestRequestAlphaSearch|TestRelayRouterRegistersAlphaSearch|TestBilling(QuotaDisplayAmount|SubscriptionDisplayAmount)|TestCoverPlusActionToNormalActionRejectsMalformedCustomID|TestHealth|TestGetHealth|TestUserSoftDelete|TestUserHardDelete" -count=1 -p=1,覆盖 Alpha Search、账单展示、Midjourney custom ID、健康检查、路由注册和用户删除清理。 - 当前补充通过
bun.cmd test src/features/pricing/components/model-details-api.test.ts:8 项通过、0 项失败,覆盖 Responses Compact 与 Alpha Search 的四种 API 样例。 .test已同步并复核 222 个测试源和 2 个 workflow 文件,当前无镜像漂移。git diff --check通过,当前可见源码差异没有空白错误。- 本草稿已直接 UTF-8 读回校验:
replacement_chars=0、trailing_whitespace=0,并用关键词检查确认09654cc5、06b82459..09654cc5、Alpha Search、/health/ready、billing information unavailable和222 个测试源均已落入文稿。 - 路由与渠道回归覆盖自动/手工路线顺序、跨分组重试、Affinity、旧 Token 合成、多 owner 模型列表、渠道更新锁、能力事务回滚以及多密钥元数据清理。
- 支付与账务回归覆盖金额/币种/provider 不匹配、易支付原子入账、订阅幂等、余额不足、邀请奖励原子提交、Midjourney 重复归属、失败退款、未知提交结果和轮询/回调竞争。
- 安全与可靠性回归覆盖 OAuth discovery 私网拦截、通知凭据脱敏与保留、禁用/删除用户授权、日志清理和截断、上游错误遮蔽、动态
Connectionheader 过滤、视频 data URL 限制、受保护抓取禁用环境代理、Turnstile/SMTP 超时及后台 runner 停止。 - 本轮新增回归覆盖内存/磁盘请求体独立重放、Ali
top_p缺省和边界、OAuth state 生成/绑定/过期/并发消费/重放、OIDC/Generic 私网 endpoint 拒绝和敏感日志、用户级跨 IP 限流,以及 PassThrough 默认过滤和显式允许。 - Relay/运行时补充回归覆盖 Zhipu/Vertex 非预期缓存类型、Vertex 畸形 PEM、随机源失败、CPU 采样失败,以及 Ali/Baidu/Coze/SiliconFlow 显式零值保留。
- 集中
fullprofile 在进入 frontend lint 前的测试、vet、JSON policy 和 typecheck 均通过,随后因全仓既有 81 项 lint 基线问题(75 errors / 6 warnings)停止;production build 已通过单独执行的bun run build:check。当前 OAuth 前端差异只触及 state API 参数,变更文件中的唯一 lint 命中是use-oauth-login.ts:50既有的set-state-in-effect,该行不在本轮差异内。 - 本文件位于 Git 忽略的
.tmp/。v1.0.5-preview.3本地标签仍未检出,下面的 compare URL 按计划发布标签名称生成,正式发布前请确认远端标签与目标提交。 - 本轮未连接独立 MySQL/PostgreSQL 实例执行真实迁移矩阵,也未运行 Redis 多实例故障演练、支付平台 sandbox webhook、浏览器 E2E、真实 OAuth/IdP、真实 provider HTTP/2 reset/GOAWAY 或显式高价 PassThrough 字段账单对账;本机
CGO_ENABLED=0且没有 GCC/Clang,Go race detector 也未执行。这些环境级验证仍应在正式发布前完成。
Full Changelog: v1.0.5-preview.3...v1.0.5-preview.4
-
v1.0.5-preview.3.0.20260806043957-923aaaddba4c06 Aug 2026 pre-releaseNothing published for this version
-
v1.0.5-preview.304 Aug 2026 pre-releaseRelease notes
Open source →Warning
v1.0.5-preview.3为预览版本,包含计费结算、订阅预扣、异步任务退款、缓存失效、日志幂等以及模型/供应商名称唯一键相关数据库结构变更。升级前请备份主库与日志库,并在测试环境验证钱包/订阅计费、Realtime 长会话、异步任务成功/失败/超时、Redis 故障恢复、渠道状态码映射、模型元数据迁移和 Midjourney 图片转发。日志幂等使用独立小型 receipt 表,不会在大体量logs表上创建新的唯一索引。Note
本稿只描述
v1.0.5-preview.2之后需要对外说明的变化。preview.2 已覆盖的 generation fence、进程内缓存重试、BillingSession 补偿状态、quota_data 刷盘、OAuth/Turnstile 收口和管理端基础优化不在这里重复;本版仅描述这些机制在持久化恢复、原子结算、Redis 限流降级、渠道协议兼容和具体缺陷修复上的新增增量。Release Notes
GitHub 地址
https://github.com/MAX-API-Next/MAX-API/releases/tag/v1.0.5-preview.3
Highlights
- 计费结算进入持久化幂等阶段:钱包、订阅、Token 和异步任务额度调整使用稳定 operation key 与数据库结算记录,相关账本变更在同一事务内提交;瞬时失败保留为可恢复状态,参数冲突、跨订阅周期等不安全重放会失败关闭或进入人工处理。
- 异步任务退款与差额结算可恢复:任务最终结算、失败退款、任务 quota 更新、账单日志和 usage 统计建立持久化关联;CAS 竞争只允许获胜者触发计费,进程重启后可继续恢复未完成退款及日志副作用。
- 缓存失效支持跨进程恢复:preview.2 的进程内有限重试进一步增加数据库持久任务;用户资料/绑定/删除、Token 更新/删除及钱包/订阅额度变更会在业务事务内同时登记失效任务,Redis 抖动期间的待处理工作不会因进程退出直接丢失,并继续使用 revision 防止旧任务覆盖新状态。
- Redis 限流故障保留本机保护:Redis 不能给出有效判定时不再直接放行,自动降级到进程内限流器;Redis 恢复后继续使用原子滚动窗口。
- 渠道状态码映射形成保存到运行时闭环:修复表单更新后映射消失、未写入数据库的问题,补齐后端严格校验,并将映射扩展到通用异步任务和 Midjourney;重试判断仍以原始上游状态为准,避免把不可重试提交错误映射成 5xx 后重复创建任务。
- 渠道适配器可靠性加固:AWS Bedrock 请求跟随客户端取消,讯飞 WebSocket 握手和上游业务错误不再挂起或伪装成功,Nova/Vertex 异常配置与空响应改为受控错误;Cohere、PaLM、智谱流式请求会随客户端断开退出,Gemini 等响应资源在失败路径也会正确释放。
- 高风险账号与图片访问收口:删号必须完成 2FA、Passkey 或密码二次验证;Midjourney 图片转发改为绑定任务、用户和 15 分钟有效期的 HMAC URL,旧的匿名裸 URL 不再可用。
- 前端会话恢复与复核收口:认证状态只保存在内存中,页面冷启动通过服务端 cookie session 恢复;会话按有界窗口重新校验,401 会清理状态,并防止切换用户时复用旧的并发校验结果。
- Realtime 与模型配置兼容性修复:OpenAI Realtime 按 preview/正式模型决定是否发送旧 beta 协议头,双向 Ping/Pong 与读超时会回收异常断线会话,累计 usage 改为按会话目标额度预留;模型定价抽屉和共享 JSON 编辑器修复异步回填、模式切换及误清空配置问题。
- 支付回调、订阅权限和渠道故障转移收口:Stripe 入账遇到可重试错误时会返回 500 交由上游重放;高等级订阅取消或到期后会按仍有效订阅的实际授权分组回落;单次中继重试会排除已经失败的渠道,避免重复消耗重试预算。
- 模型目录与定价管理一致性增强:模型/供应商活跃名称使用非空唯一键约束,上游元数据同步失败会明确中止;Anthropic 空模型列表、供应商引用保护和表达式计费模型切换后的旧价格残留问题一并修复。
New Features
- 通用视频任务协议新增
created_at_path与updated_at_path可视化配置,可从不同供应商响应中提取任务创建和更新时间;相关字段已同步到中、英、法、日、俄、越六种前端语言。 - 计费结算与缓存失效新增后台恢复任务:服务启动后会继续处理数据库中待完成的结算、账单日志/usage 副作用及 Redis 缓存失效记录。
Improvements
- 新增
BillingSettlement持久化结算记录,operation key 会绑定资金来源、用户、订阅、Token、任务、额度参数和日志副作用;重复调用返回既有结果,参数变化或身份不一致不会再次扣费/退款。 - 新增
BillingPreConsumeSelection,同一 request ID 首次选定钱包或订阅后不可在重试中切换资金来源,避免余额变化或并发回放把一次请求结算到两个来源。 - 钱包/订阅预扣与 Token 预扣收敛到原子事务;订阅记录绑定用户、Token、模型、额度和
last_reset_time,跨重置周期的延迟结算或退款会失败关闭。 - Realtime 追加预留使用递增 revision 和累计目标额度,每个 reserve 操作可幂等重放,不再把累计 usage 当作互相独立的扣费片段。
- 任务最终结算与退款通过任务主键和旧 quota 做 CAS,资金、Token、任务 quota 和结算状态在同一事务中更新;日志以结算 operation key 去重,提交节点归属不会被后续轮询节点覆盖。
- 任务轮询新增失败退款恢复扫描;Suno 响应按旧状态 CAS 更新,未知 task ID 会被忽略并记录,竞争失败的轮询实例不再继续执行计费。
- 任务账单日志使用独立
BillingLogReceipt表完成幂等声明和日志同事务写入,避免给高容量logs表增加唯一索引;receipt 通过随机 claim token 判断本次归属,不依赖 MySQLRowsAffected的连接参数语义。 - 用户/Token 缓存失效写入
CacheInvalidationTask;用户资料、OAuth 绑定、用户删除、Token 更新/删除及钱包/订阅结算会在同一数据库事务中登记任务,提交后由持久 runner 执行,成功处理时按 revision 删除,较旧 worker 不会误删更新后的任务。 - 待处理的持久缓存失效任务同时构成读侧栅栏:任务未处理前不会命中或回填该用户/Token 的 Redis 缓存;签到、兑换码和直接用户额度调整也统一接入这一事务性失效路径。
- Redis 限流返回错误、异常类型或非法判定时自动使用进程内同策略限流器,避免 Redis 短暂故障使登录、关键操作和全局 API 限流整体失效。
- tiered billing 表达式和异步任务费率卡的运行时配置改为带读写锁的映射;管理员同步计价配置时不会与并发请求读取同一 Go map 发生数据竞争。
- Realtime 连接会在关闭时终止 reader、Ping worker 和上下游 WebSocket;usage 累计与预扣序列化,避免异常断线长期占用 goroutine、上游连接或会话额度。
- 渠道故障转移会在同一次普通中继或未锁定渠道的任务提交中记录已失败渠道,并在内存缓存与数据库选择路径中排除这些候选;优先级、权重、自动分组和新请求之间的选择语义保持不变。
- 多密钥轮询索引在渠道缓存刷新时复用同一渠道锁进行读取和迁移,避免后台缓存重建与并发取 Key 使用不同锁访问同一状态。
max_tokens/max_completion_tokens的解析收敛为共享规则,显式0在没有旧字段时仍会保留;AWS Nova、Baidu、Ollama、智谱、讯飞和阿里任务适配器也会保留客户端显式传入的0/false。- 渠道多密钥操作在同一渠道锁内重新读取完整配置;无效渠道 ID 在建立锁之前拒绝,避免无效管理请求长期占用锁表条目。
- 系统配置更新会在落库前拒绝 pointer-backed JSON 配置字段的
null,避免运行时配置被空值意外置空。 - 状态码映射只接受规范的
100..599源/目标状态码,拒绝0429等别名、重复规范化 key、null、非对象和越界值;运行时遇到无效配置会保持原状态码。 - 通用异步任务和 Midjourney 返回现在复用统一状态码映射函数,同时保留原始上游状态用于任务重试分类。
- 通用视频任务协议回写配置时保留未知厂商扩展字段,新增时间路径不会覆盖
vendor_extension等自定义内容。 - 前端 session verifier 合并并发
getSelf(),默认 30 秒内复用同一身份的验证结果;身份变化时会等待并重新验证,不应用旧用户的在途响应。 - OpenAI Realtime 正式模型不再发送已废弃的
openai-beta: realtime=v1/openai-beta.realtime-v1,*-realtime-preview模型继续保留旧协议兼容。 - 模型定价抽屉将定价读取逻辑独立出来,系统设置异步到达后可正确回填固定价格/倍率/高级倍率;固定价格优先于残留倍率,并避免“同名新建”流程误删其他模型配置。
- 模型固定价格和各类倍率在前后端统一要求有限且非负,拒绝负数、
NaN、Infinity、null和非对象配置,避免产生负计费或静默写入无效 JSON。 - 渠道模型多选不再只显示前 6 个标签,管理员可直接核对全部已选模型。
- OAuth 已存在身份查询失败统一包装为安全业务错误,避免将数据库主机等内部细节返回给客户端。
- 模型和供应商使用独立的非空
name_key建立活跃名称唯一性;软删除时原子切换为记录专属保留键,使三种数据库都能阻止并发创建同名活跃记录,同时允许删除后重新使用原名称。 - 模型元数据同步会同时校验供应商与模型数据源的 HTTP/业务结果,不再在供应商拉取失败时继续创建无归属模型;上游显式
status: 0也会按禁用状态保留。 - 系统 Option 写接口只接受已初始化注册表中的配置 key,并将
DataExportInterval规范为1..1440分钟,避免任意配置落库和零/负间隔触发导出忙循环。 - HTTPS
ServerAddress在未显式设置SESSION_COOKIE_SECURE时会自动启用 Secure cookie;显式环境变量仍保持最高优先级,纯 HTTP 部署继续兼容并输出风险日志。 - 删除未被生产路径使用的旧
PreConsumeQuota/ReturnPreConsumedQuota入口及重复 operation-key 命名空间,避免新代码绕开持久化幂等结算;同时移除需手工同步迁移列表的死代码migrateDBFast()。
Bug Fixes
- 修复渠道
status_code_mapping在编辑抽屉中填入后,保存时被表单转换遗漏,导致更新后内容消失且数据库字段未写入的问题。 - 修复共享
JsonEditor首次渲染已有 JSON 时可视行为空、切换“可视化/JSON”模式会回写空值,以及外部 value 更新后表格未同步的问题。 - 修复异步任务提交和 Midjourney 接口未应用渠道状态码映射的问题。
- 修复映射后的 5xx/429 可能改变原始任务错误的重试语义,进而把本应不可重试的非幂等提交再次发送到上游的问题。
- 修复通用视频任务协议编辑后丢失
created_at_path、updated_at_path和未知扩展字段的问题。 - 修复 AWS Bedrock 使用
context.Background()导致客户端断开后仍继续调用上游的问题;无全局 Relay timeout 时也保留显式取消能力。 - 修复 Redis 限流依赖异常时所有策略只记录日志后直接放行的问题;现在自动回退本机限流,而不会将 Redis 波动扩大为登录与关键接口防护失效。
- 修复
SumUsedToken使用 MySQL 专用ifnull(),导致 PostgreSQL 日志统计查询报错的问题;现在使用三种数据库均支持的COALESCE()。 - 修复 AWS Nova、Baidu、Ollama、智谱、讯飞和阿里任务请求在 JSON 重编码时丢失显式
0、false的问题;同时修复讯飞将n错写为top_k,以及max_completion_tokens与max_tokens的优先级在渠道间不一致的问题。 - 修复 Baidu access token 接口的非 2xx HTTP 响应仍按成功 JSON 解析的问题;修复 Cohere、PaLM、智谱流式客户端提前断开时 producer goroutine 可能阻塞泄漏的问题。
- 修复 OpenAI Realtime 对异常网络断线没有读超时与心跳,造成上下游 WebSocket、worker 和预扣额度长期滞留的问题;并消除并发使用量累计的读写竞争。
- 修复 Hailuo 任务在视频文件 URL 尚不可用时过早标记成功并结算的问题;修复即梦顶层错误响应没有立即进入失败/退款路径的问题。
- 修复管理员并发启用、禁用或删除同一渠道多个密钥时,较旧
ChannelInfo快照可能覆盖较新修改的问题。 - 修复管理员一次提交 Token 重新启用和新过期时间/余额时仍按旧值拒绝的问题,并拒绝非法 Token 状态值。
- 修复 MySQL/PostgreSQL 旧
subscription_plans.price_amount类型迁移失败只记录日志后继续启动的问题;迁移现在在核心表创建后执行,并向上返回失败。 - 修复 AWS Nova 在 guardrail 等场景返回空
content时访问Content[0]引发 panic 的问题。 - 修复讯飞 WebSocket 非 101 握手可能返回 nil 错误和 nil channel 并永久阻塞,以及未检查
Header.Code导致上游业务错误被当作 200 成功的问题;读取、发送和客户端取消现在共享同一事件生命周期。 - 修复 Vertex 渠道区域配置不是字符串时直接类型断言 panic 的问题;无效模型项会回退有效默认区域或
global。 - 修复模型价格/倍率允许负数或非有限数的问题,防止负计费增加余额或
Infinity序列化为null后破坏配置。 - 修复 Midjourney 图片代理只按可猜测的
mj_id查询且无需身份凭据造成的跨用户读取问题;签名校验失败、过期或用户不匹配统一返回 403。 - 修复账号删除只比较前端用户名、后端仅凭现有 session 即永久删号的问题;删除接口现在要求
account_delete作用域的短期二次验证。 - 修复 BillingSession、旧 post-consume 路径和异步任务在重复回调、并发 worker、进程中断或错误结果不明确时可能重复执行资金/Token 调整的问题。
- 修复同一请求重放时可能因当前余额或订阅状态变化,从钱包切换到订阅或从订阅切换到钱包的问题。
- 修复订阅退款被额度下限截断后,Token 仍按请求值全额回退而造成两个账本不一致的问题;现在使用资金侧实际应用的 signed delta 同步 Token。
- 修复订阅重置后仍可能重放旧周期预扣/退款,以及相同 request ID 用不同用户、Token、模型或额度参数再次执行的问题。
- 修复异步任务失败退款只依赖当次轮询,数据库或日志写入短暂失败后进入终态便不再恢复的问题。
- 修复任务结算成功但账单日志/usage 写入失败后无法恢复,或并发恢复产生重复日志的问题。
- 修复 Token 已删除时异步任务终态退款无法返还用户钱包/订阅额度的问题;终态退款允许跳过已不存在的 Token 镜像,但仍校验用户和资金来源。
- 修复 Realtime 会话累计用量传参错误,导致后续 usage 未按累计目标正确预留和结算的问题。
- 修复正式 OpenAI Realtime 模型仍携带 preview beta header,可能被新版上游拒绝的问题。
- 修复前端“仅验证一次”的 session 标记在用户被封禁、会话过期或用户切换后仍可能继续信任旧状态的问题。
- 修复认证 store 将完整用户对象写入
localStorage,以及登出/删号路径仍操作该持久缓存的问题。 - 修复
User.Edit、邮箱/OAuth 绑定清理、GitHub 身份迁移和用户设置更新在数据库提交后才清理缓存,进程中断或 Redis 故障可能长期保留旧身份/分组/设置的问题;outbox 不可写时相关业务事务现在会整体回滚。 - 修复软删除/硬删除用户与其 Token 缓存清理分散在 model/controller 两阶段执行的问题;用户删除、user cache 和该用户全部 Token cache 失效任务现在同事务提交,不再存在中途退出后遗漏 Token 失效的窗口。
- 修复模型抽屉在系统定价设置尚未加载时初始化空字段,随后保存可能清除已有价格;同时修复同名模型创建流程误删既有价格配置的问题。
- 修复 OAuth provider 身份回填查询失败时可能把底层数据库错误详情直接暴露给客户端的问题。
- 修复 Gemini Chat/Image 在
io.ReadAll失败路径未关闭上游响应体的问题;Baidu、Zhipu、Cohere 写客户端响应失败现在会记录错误而不再静默丢弃。 - 修复 SQLite 日志库兜底分支错误修改主库类型标志的问题,并移除两套 AutoMigrate 列表长期漂移的维护隐患。
- 修复 Stripe checkout 完成或异步支付成功事件在订阅/充值入账遇到临时数据库错误时仍返回 200、导致 Stripe 不再重试的问题;已完成订单、永久状态不匹配和并发完成事件仍会安全确认,避免重复入账。
- 修复高等级订阅取消、替换或到期时,只要还有任意低等级活跃订阅就跳过用户分组回落的问题;现在只有仍授予当前相同分组的其他订阅才会保留该权限。
- 修复渠道缓存刷新和多密钥轮询并发访问
MultiKeyPollingIndex的数据竞争,以及故障转移可能反复选中本次请求中已经失败渠道的问题。 - 修复 OpenAI、Replicate 和 Sora multipart 转发将客户端文件名直接拼入
Content-Disposition,可能破坏 part 头的问题;文件名现在通过标准媒体类型编码安全生成。 - 修复 OpenAI 图片编辑仅按文件扩展名判断 MIME 类型的问题;图片和 mask 现在按实际内容识别并转发 JPEG、PNG 或 WebP,空文件和伪装内容会被拒绝。
- 修复 Anthropic 格式
/v1/models在可见模型列表为空时读取首尾元素导致 panic 的问题;空列表现在返回data: []和has_more: false。 - 修复模型/供应商原联合唯一索引无法在 MySQL、PostgreSQL 的
NULL deleted_at语义下阻止并发同名创建的问题;同时阻止删除仍被模型引用的供应商,并让模型软删除中的保留键更新与删除动作同事务回滚。 - 修复上游模型/供应商元数据拉取失败被静默吞掉,以及上游显式
status: 0被当作未提供而回退启用的问题。 - 修复表达式计费模型之间切换时编辑器只更新模型名、仍显示首次打开模型价格的问题;编辑器现在按所选模型的完整定价快照重建状态,并同步刷新输入/输出等表达式价格。
Compatibility Notes
- 本版新增
billing_settlements、billing_pre_consume_selections、billing_log_receipts、cache_invalidation_tasks四张表;subscription_pre_consume_records新增 Token 和订阅重置周期绑定字段。SQLite、MySQL、PostgreSQL 部署均需先完成项目 AutoMigrate,生产升级前应在同版本数据副本上演练。 models与vendors新增非空name_key列和单列唯一索引,并移除原(name, deleted_at)/(model_name, deleted_at)联合唯一索引。迁移会保留 ID 最小的同名活跃记录作为名称占用者,其他历史重复记录改写为记录专属保留键;软删除后的名称可重新创建。生产升级前应先检查重复元数据并在三种数据库的同版本副本上演练。- MySQL/PostgreSQL 的既有
subscription_plans.price_amount会在核心 schema 就绪后迁移为decimal(10,6);元数据查询或ALTER TABLE失败会阻止启动,升级前应先在数据副本演练,不应依赖原先的仅日志告警行为。 - 任务账单日志幂等信息写入小型
billing_log_receipts表,不再修改logs表索引;独立日志库同样需要允许 AutoMigrate 创建该 receipt 表。receipt 会随幂等记录长期保留,未建立安全保留期前不要手工删除。 - 结算和预扣幂等记录当前不会按固定 TTL 清理;这是为了覆盖长时间异步任务、延迟回调和重启恢复。请将相关表增长纳入数据库容量与归档监控,未建立安全保留期前不要手工清理。
- 需要修改余额的兼容路径现在要求稳定
request_id;缺少 request ID 时会失败关闭,不再退回非幂等直接扣减。自定义 relay/插件若调用旧PostConsumeQuota路径,应确保整个请求生命周期复用同一 ID。 - 2025-02-22 00:00:00 UTC 之前提交的旧失败任务仍按历史策略不自动退款;新恢复扫描只处理 cutoff 之后且仍有 quota 的失败任务。本版只修正注释和发布说明日期,不改变原有退款资格边界。
- 状态码映射保存现在执行严格校验:key/value 必须是规范的
100..599状态码。此前可保存但不规范的0429、小数、越界值、null或非对象配置需要先修正。 - 模型固定价格及 prompt/completion/cache/image/audio 倍率现在必须是有限非负数;已有负数、
NaN、Infinity、null或非对象设置在再次保存前需要修正。 - 旧的裸
/mj/image/:id地址现在返回 403。客户端应重新查询任务并使用带uid、expires、signature的 15 分钟签名 URL;不要长期缓存或持久化该临时地址。 DELETE /api/user/self现在要求先完成account_delete安全验证。启用 2FA/Passkey 的账号必须使用已配置的强验证方式;未配置时可回退当前密码。自定义客户端需按更新后的 OpenAPI 流程调用。- 未显式设置
SESSION_COOKIE_SECURE且ServerAddress为有效 HTTPS URL 时,session cookie 现在自动标记 Secure;显式配置仍优先。HTTP 部署不会被强制开启,但会记录明文传输风险提示。 - Redis 限流故障现在改为回退进程内同策略限流。多实例部署在 Redis 故障期间只能按实例分别计数,不能替代 Redis 恢复后的全局窗口;仍应监控 Redis 可用性和对应错误日志。
- OpenAI
*-realtime-preview模型继续发送 beta header;正式 Realtime 模型改用当前协议。使用自定义模型别名时,应确认别名是否仍包含-realtime-preview并与实际上游协议一致。 - 管理 API 对已注册、使用 pointer-backed JSON 字段的配置不再接受字符串
null;自动化配置脚本应发送有效 JSON 值,或省略未修改的字段。 - Option 更新接口现在拒绝未注册 key,
DataExportInterval仅接受1..1440的整数分钟值;依赖写入自定义 options 行或零/负导出间隔的自动化脚本需要调整。 - 仍被模型引用的供应商现在不能删除,需先重新分配或删除关联模型。OpenAI 图片编辑上传会按文件内容校验,且仅接受 JPEG、PNG、WebP;仅修改扩展名不再能绕过类型限制。
- 上游适配器现在会将客户端显式传入的
0、0.0和false转发给相关供应商;此前依赖网关静默省略这些零值以使用供应商默认值的调用方,需要改为省略字段。 - 前端不再从
localStorage.user恢复登录状态,升级后以 HttpOnly cookie session 为准,并默认每 30 秒重新确认一次;依赖读取该非公开 localStorage 项的自定义脚本需要调整。 - 发布前必须执行
cd web/default && bun run build生成最新嵌入资源,再重启 Go 进程;直接运行旧dist会缺少状态码映射、视频时间路径和会话校验修复。
Verification
- 后端全量测试通过:
go test -p 1 ./... -count=1 -timeout=120s;静态检查通过:go vet ./...。串行包执行用于隔离各包共享 SQLite 测试资源,避免测试进程并发争用。 - JSON wrapper 规则检查通过:
go run ./tools/jsonwrapcheck;本轮触及的 AWS/讯飞 JSON 调用已迁移到commonwrapper,其余历史调用仍由既有 allowlist 管理。 - 前端类型检查与生产构建通过:
cd web/default && bun run typecheck、bun run build:check;Rsbuild 与 Tailwind 构建校验通过。 - 前端全量 Bun 测试通过:118 项通过、0 项失败,覆盖 JsonEditor、session verifier、auth store、渠道表单 round trip、模型定价、渠道模型展示、删号流程及表达式计费模型切换后的价格刷新。
- 本次涉及的前端文件定向 ESLint 通过;全仓
bun run lint仍有本次范围外的 75 个 error 和 6 个 warning,主要是既有 React 19 Hooks 规则债务,因此不列为全量通过项。 - 后端测试覆盖重复/并发结算、资金来源竞争、实际退款 delta、任务 quota CAS、跨订阅重置周期、身份/参数冲突、进程重启恢复、Token 删除退款、账单日志幂等、状态码映射与任务重试语义。
- 本稿补充范围的后端定向测试通过:
controller、middleware、model、dto、setting/config、计费/任务费率设置,以及 OpenAI、AWS、Baidu、Cohere、Ollama、PaLM、Ali、Hailuo、Jimeng、讯飞和智谱渠道包均以-count=1通过。 - 本轮新增范围另行通过
controller、model、service、relay/helper、OpenAI、Replicate 和 Sora 包测试,覆盖 Stripe webhook 重试/幂等、订阅分组回落、渠道排除与轮询并发、multipart 文件名编码、图片内容识别、Anthropic 空列表、元数据唯一键迁移、供应商引用保护、上游同步错误和 Option 边界。 - 当前工作树的
go vet ./...与go run ./tools/jsonwrapcheck通过。 - AWS context/Nova、讯飞握手与业务错误、Vertex 配置、Midjourney 签名 URL、删号验证 scope、价格有限值、Cookie Secure 推导和日志 receipt claim 均有聚焦回归测试。
.test已同步 173 个测试源和 2 个 workflow 文件,sync-tests.ps1 -Mode Check通过。git diff --check通过,未发现新增尾随空白或补丁格式错误。- 本轮未连接独立 MySQL/PostgreSQL 实例执行迁移/事务矩阵,也未运行真实 Redis 故障、多实例集成、浏览器 E2E 或外部渠道 canary;正式发布前仍需补齐这些环境级验证。
Full Changelog: v1.0.5-preview.2...v1.0.5-preview.3
-
v1.0.5-preview.225 Jul 2026 pre-releaseRelease notes
Open source →Warning
v1.0.5-preview.2为预览版本,重点是安全、计费一致性、缓存一致性、限流策略和管理端细节修复。升级前建议先在测试环境验证 OAuth 登录/绑定、系统访问令牌生成、用户/Token 缓存、BillingSession、quota_data 看板刷盘、登录/关键接口限流和渠道编辑器。Note
本稿只描述
v1.0.5-preview.1之后需要对外说明的变化。v1.0.5-preview.1已经覆盖的 Playground 参数、DoubaoVideo/Seedance 差额结算、系统实例面板基础能力等内容不在这里重复;已有的 tiered pricing 表达式变量和可视化编辑能力也只按本轮安全/结构优化描述。Release Notes
GitHub 地址
https://github.com/MAX-API-Next/MAX-API/releases/tag/v1.0.5-preview.2
Highlights
- 缓存一致性加固:用户缓存和 Token 缓存引入 Redis generation fence,DB 回填必须匹配当前版本;删除、禁用、额度变更和 Token 删除后的缓存失效增加有限重试,降低旧缓存继续授权或旧额度继续命中的风险。
- 计费与看板一致性修复:BillingSession 对资金差额、Token 调整失败和部分补偿状态做更明确建模;quota_data 刷盘改为快照化、幂等聚合和失败重试,减少异常退出、重放或并发刷盘导致的重复/丢失。
- 限流策略隔离与可观察性增强:全局 API、SPA 回退页、公共状态接口、关键操作和账号登录使用更明确的独立策略;Redis 限流改为原子滚动窗口,429 响应补齐重试信息,Redis 异常时采用有界超时、记录错误并放行请求,避免限流依赖故障放大为站点 500。
- 账号与 OAuth 安全收口:OAuth 身份写入增加串行化和长度约束,身份占用查询错误会被显式处理;OAuth 回调只允许站内 redirect,绑定回调不再只依赖
window.opener判断。 - 系统访问令牌路径防回归:access-token-only 更新从通用 OAuth 身份锁路径中剥离,普通用户资料更新也不会再从旧快照回写
access_token,避免生成后的系统访问令牌被并发资料更新覆盖。 - 管理端可用性修正:渠道编辑器、模型映射、Pricing 侧边筛选、系统实例清理、移动端表格和状态徽章继续修复长内容、状态同步和错误提示细节。
New Features
- 新增
QUOTA_DATA_AGGREGATE_MIGRATION_ENABLED环境开关,默认不自动整理历史大表,需要时可在低峰期单主节点手动开启。 - 新增 Turnstile token header 传递方式:前端默认发送
X-Turnstile-Token,后端保留 query 参数兼容。
Improvements
- tiered pricing 表达式编译缓存从整表清空改为有序淘汰,避免达到缓存上限时丢弃所有已编译表达式。
- tiered pricing 的
header()/param()改为正向白名单,只暴露定价所需的 provider feature header 和少量 request metadata path,避免表达式读取 prompt、工具定义、凭据或任意 payload。 - tiered pricing 前端编辑器拆分为主编辑器、可视化阶梯编辑器和请求规则编辑器,降低单文件复杂度,并补充运行时测试。
- BillingSession 结算失败后会区分已确认资金差额、部分补偿残差和补偿结果不明,后续重试不会盲目重复非幂等资金操作。
- quota_data 启动迁移增加操作锁、心跳和释放重试,历史聚合键整理默认跳过并写入明确日志,避免多节点启动时抢跑重活。
- 用户状态、角色、分组、设置、签到和 Token 额度等缓存相关路径统一向版本化失效模型收敛,Redis 短暂异常时保留可恢复窗口。
- 全局 API、SPA HTML 回退、
/api/status//api/setup、关键操作聚合、关键路由和密码登录限流拆分独立策略;登录桶按规范化账号哈希,减少共享出口 IP 下不同账号相互挤占登录额度。 - Redis 限流改为 Lua + 有序集合实现的原子滚动窗口;内存与 Redis 路径统一返回
Retry-After、X-RateLimit-*和结构化rate_limit_exceeded错误,前端查询不会再自动重试 429。 - Redis 限流调用增加 500ms 有界超时和明确错误日志;Redis 不可用或返回异常时限流故障开放,避免缓存故障阻断正常请求。
- OAuth provider 身份占用判断和绑定/注册错误处理更严格,数据库错误不会被当作“未占用”继续放行。
- 登录、注册、邮箱验证和密码重置的 Turnstile 传参方式统一,后端 JSON 解析继续走项目
common.DecodeJson包装。 - 渠道编辑器拆分状态逻辑,渠道测试结果会更稳定地回写列表缓存;模型映射预检会拒绝非字符串目标模型。
- Pricing 侧边栏、AUTO_GROUP/auto route 展示、渠道能力矩阵和长标签展示继续细化,减少管理员误读配置状态。
- 系统实例批量清理流程改为统一 mutation/hook 和 query key 失效,批量操作期间会禁用刷新和单实例删除,减少重复提交。
- DataTable、移动端卡片列表、StatusBadge 和表格 skeleton 支持更精细的 header/cell/mobile class,长模型名或长标签不再轻易撑破布局。
- Footer 自定义 HTML 改用统一 HtmlContent 渲染;OAuth、支付和公共外链打开时补齐
noopener,noreferrer。 handleServerError在生产环境只展示安全业务信息,调试详情限制在开发环境输出。
Bug Fixes
- 修复 access-token-only 用户更新可能被新增 OAuth 身份锁阻塞的问题,避免系统访问令牌生成受到邮箱/OAuth 身份写锁释放异常影响。
- 修复普通用户资料更新会从旧快照默认复制
access_token,从而覆盖并发生成的新系统访问令牌的问题。 - 修复用户资料更新可能把旧的 quota、used_quota、request_count 等账务字段写回数据库的问题。
- 修复用户/Token 缓存缺少版本栅栏时,删除或失效后的旧 DB 快照仍可能异步回填 Redis 的问题。
- 修复用户删除后缓存清理失败可能中断后续 Token 缓存失效的问题。
- 修复用户状态/角色等管理操作只记录缓存失效失败、没有重试窗口的问题。
- 修复 BillingSession 在资金结算成功但 Token 调整失败后可能留下资金、Token 和日志状态不一致的问题。
- 修复 BillingSession 部分补偿返回残差或结果不明确时,后续自动重试可能重复执行资金补偿的问题。
- 修复 quota dashboard 缓存刷盘失败静默丢失、重放同一快照可能重复累计、旧数据缺少聚合键时无法安全创建唯一索引的问题。
- 修复静态资源请求消耗全局 Web 限流额度、公共状态接口与普通 API 共用同一桶、关键操作只使用单一聚合桶,以及 Redis 限流多命令并发竞态可能造成额度判断不准确的问题。
- 修复 Redis 限流异常直接返回 500 或长时间阻塞请求、429 响应缺少可操作重试信息的问题。
- 修复 OAuth 回调
redirect可携带外部 URL、协议相对 URL 或非法路径导致跳转不受控的问题。 - 修复 OAuth 绑定页在
noopener或浏览器限制下可能被误判为登录回调的问题。 - 修复 Turnstile token 混用 body/query 导致前后端保护接口口径不一致的问题。
- 修复渠道模型映射预检忽略非字符串 target 的问题。
- 修复长模型名、长渠道标签、多语言状态徽章和移动端表格内容在窄屏下溢出的问题。
- 修复 OpenAI Responses/audio、Claude cache creation、Gemini thought/candidate/modality token、MiniMax TTS 和部分任务 usage 解析边界,降低实际计费与日志展示不一致风险。
Compatibility Notes
v1.0.5-preview.2会新增或更新quota_data相关结构,包括aggregate_key、snapshot marker、retry marker 和操作锁表;SQLite、MySQL、PostgreSQL 均应走项目迁移流程。- 历史
quota_data.aggregate_key整理默认不会自动执行。需要整理旧大表时,请在低峰期、单主节点下显式设置QUOTA_DATA_AGGREGATE_MIGRATION_ENABLED=true,并预留迁移时间。 - Redis 用户/Token 缓存会新增 generation key;升级后旧缓存可自然过期,新读写路径会逐步按版本化规则刷新。
- Token 缓存重试队列是进程内有限重试,不是跨进程持久队列;进程退出后未完成的缓存重试不会自动恢复。
- tiered pricing 的
header()/param()读取范围比 preview.1 更严格;若已有表达式依赖非白名单 header/path,需要改成受支持的定价 metadata。 X-Turnstile-Token是新的前端默认传递方式;后端仍保留?turnstile=查询参数兼容旧调用方。- OAuth 回调
redirect现在只能是站内相对路径;外部 URL、//host和非法路径会回退到/dashboard。 - 新增
CRITICAL_ROUTE_RATE_LIMIT、CRITICAL_ROUTE_RATE_LIMIT_DURATION、LOGIN_RATE_LIMIT_ENABLE、LOGIN_RATE_LIMIT和LOGIN_RATE_LIMIT_DURATION环境变量;默认分别为每路由 20 次/1200 秒、每账号 10 次/900 秒。关键路由桶仍受CRITICAL_RATE_LIMIT_ENABLE总开关控制,账号桶只用于密码登录并可独立关闭。 GLOBAL_WEB_RATE_LIMIT现在只统计 SPA HTML 回退请求,不再统计已命中的静态资源;GET /api/status和GET /api/setup使用独立的公共状态桶,但仍沿用GLOBAL_API_RATE_LIMIT及其 duration 配置。- Redis 限流 key 和存储结构已切换为按 policy 区分的有序集合,升级时旧计数不会延续到新桶并会按原 TTL 自然过期。Redis 限流故障现在会记录日志并放行请求;对安全边界要求更高的部署应同时监控 Redis 可用性和对应错误日志。
- 429 响应现在返回结构化 JSON 及
Retry-After、X-RateLimit-Limit、X-RateLimit-Remaining、X-RateLimit-Reset、X-RateLimit-Policy;自定义客户端应优先遵循Retry-After,不要立即重试。 - 发布前仍需要先执行
cd web/default && bun run build生成前端产物,再重启 Go 进程;直接go run main.go不会自动重建嵌入资源。
Verification
- 后端建议执行:
go test ./...、go vet ./...、go run ./tools/jsonwrapcheck。 - 系统访问令牌生成入口新增锁隔离回归测试,验证该路径不会重新等待 OAuth 身份写锁。
- 限流定向测试通过:
go test ./middleware -run "Test(CriticalRateLimit|LoginRateLimit|RateLimitResponse|BootstrapStatus|RedisRateLimit)" -count=1,覆盖关键路由/聚合桶、账号登录桶、公共状态桶、429 元数据、Redis 原子并发和故障开放。 - 定向后端验证应覆盖:Redis versioned hash、user cache、token cache、用户字段更新、access token 并发更新、BillingSession、tiered settle、quota_data snapshot/aggregate migration、OAuth lookup、Turnstile header。
- 前端建议执行:
cd web/default && bun run typecheck、bun run i18n:sync,并对渠道编辑、Pricing、System Info、safe redirect、handle-server-error、StatusBadge 和 DataTable 相关文件做 ESLint / Prettier 定向检查。 - 前端定向测试应覆盖:channel editor state/actions、model mapping guardrail、pricing sidebar、tiered pricing runtime、safe redirect、handle-server-error、status badge 和系统实例批量清理。
- Seedance Fast 端到端验证通过:上游完成响应返回
usage.total_tokens=50638后,通用media.task轮询链路能够进入 token 重算,并在测试费率下从预扣 ¥8.325000 调整为 ¥1.686244、退款 ¥6.638756。 - 发布草稿写入后应使用 UTF-8 直接读回检查标题、链接、关键字和乱码;
.tmp文件为 gitignored,不依赖git status/git diff验收。 - 变更空白检查建议执行:
git diff --check。
Full Changelog: v1.0.5-preview.1...v1.0.5-preview.2
-
v1.0.5-preview.123 Jul 2026 pre-releaseRelease notes
Open source →Warning
v1.0.5-preview.1为预览版本,建议先在测试环境验证前端构建、渠道配置保存、异步任务轮询和计费日志后再用于生产。Release Notes
GitHub 地址
https://github.com/MAX-API-Next/MAX-API/releases/tag/v1.0.5-preview.1
Highlights
- 本地前端构建完整性收口:修复完整仓库检出时根
.gitignore的裸home规则误排除web/default/src/features/home,导致 Tailwind 未生成首页桌面栅格 CSS、go run main.go嵌入后宽屏首页仍显示单列的问题。 - 构建产物增加回归守卫:前端构建会检查首页 Hero 桌面双列规则是否写入 CSS;缺失时
bun run build与bun run build:check直接失败,避免本地构建与 Docker 构建产物出现静默差异。 - 游乐场模型参数可视化配置:新增温度、Top P、频率惩罚、存在惩罚、最大 Token 和随机种子设置,让开发者可以在发送请求前直接调整生成行为。
- Seedance / DoubaoVideo 任务计费可控化:完成态差额结算现在支持按 DoubaoVideo 渠道单独开关,兼容 Seedance 类上游按
usage.total_tokens返回实际 token 的任务结果,同时允许运营侧在费率调整或上游结算策略不匹配时关闭差额补退。 - 系统实例清理补齐:管理员控制台的
系统信息 -> 实例增加删除所有离线实例操作,后端批量接口只清理超过离线判定阈值的实例记录,并返回实际删除数量。
New Features
- 新增 Tailwind CSS 产物验证脚本,聚合检查已生成的 CSS 文件,并验证首页 Hero 的关键响应式栅格规则。
- 游乐场输入区新增参数设置面板:桌面端使用 Popover,移动端使用底部 Sheet;参数开关数量通过工具栏角标显示。
- 参数面板提供滑块和数字输入两类控件,并为每个参数显示当前值、范围和用途说明。
- 管理员控制台的 DoubaoVideo 渠道编辑页新增
Video Task Billing模块,可在高级设置中开启或关闭Completion delta settlement。 - DoubaoVideo 渠道新增
disable_task_delta_settlement设置项。默认保持完成态差额结算开启;仅当管理员显式关闭时,保存为渠道级关闭配置。 - 异步任务提交时会记录差额结算开关快照,轮询完成后的结算按提交时的渠道策略执行,避免任务执行过程中渠道设置变化影响已提交任务。
系统信息 -> 实例新增删除所有离线按钮和确认弹窗;按钮仅在存在离线实例时展示,执行后自动刷新实例列表。- 新增
DELETE /api/system-info/stale-instancesRoot 管理接口,用于一次性删除所有超过心跳离线判定阈值的实例记录。
Improvements
- 根忽略规则收窄为仅匹配仓库根目录的
/home,不再影响前端源码扫描。 - Tailwind 入口显式纳入
features/home,即使上层工作区后续增加宽泛忽略规则,首页 utility 仍会进入构建产物。 - 游乐场参数偏好会自动保存在浏览器本地,下次打开时继续使用上次配置。
- 仅启用的参数会进入请求;显式
0等有效值会保留,随机种子为空时不会发送seed,避免把“未设置”误解为固定种子。 - 参数输入会按控件范围和步进值规范化,降低负数、超范围值或小数精度对请求的影响;中、英、法、日、俄、越六种语言均补齐对应文案。
- 通用
media.task结果解析补充读取usage.completion_tokens和usage.total_tokens,Seedance 兼容接口返回实际 token 后可进入统一任务计费链路。 - DoubaoVideo 差额结算开关在新轮询链路和旧视频任务更新链路中保持一致判定;非 DoubaoVideo 渠道会忽略该设置,避免误伤其他视频渠道。
- DoubaoVideo 渠道编辑时会自动展开高级设置导航并展示视频任务计费入口,减少管理员找不到差额结算开关的情况。
- 前端渠道设置表单在读取、保存和重新编辑时保持开关语义一致:关闭开关才写入
disable_task_delta_settlement: true,重新开启会移除该字段。 - 系统实例删除流程改用 React Query mutation,并在删除成功后通过统一 query key 失效实例列表,避免组件内手动维护删除 loading 状态和成功后直接
refetch()。 - 系统实例批量删除期间会禁用刷新和单实例删除操作,避免管理员重复提交或在列表刷新中产生误操作。
Bug Fixes
- 修复 Windows 本地构建中首页 JSX 已带响应式类名、CSS 却缺少对应规则的问题;Docker 与本地构建现在遵循同一首页扫描契约。
- 修复俄语界面中
+{{count}} more mapping(s)的映射计数文案不自然问题。 - 修复 DoubaoVideo 渠道缺少前端差额结算配置入口的问题;管理员现在可在
渠道 -> 编辑 -> 高级设置 -> Video Task Billing中直接调整。 - 修复 Seedance 兼容任务结果中的 usage token 未被通用视频任务协议解析的问题,降低完成态无法按真实 token 调整计费的风险。
- 修复完成态差额结算策略没有随任务提交持久化的问题,避免长时间异步任务在轮询完成时读取到与提交时不同的渠道策略。
- 修复渠道模型映射预检会把非字符串目标模型强制转成字符串的问题;前端现在与保存 schema 一致,将数字、对象等非字符串映射目标标记为无效配置。
- 修复通用视频任务 usage token 解析测试中
completion_tokens与total_tokens使用相同值的问题,避免错误的共享字段映射被测试漏过。 - 修正法语、日语和俄语界面中的若干术语翻译,覆盖
Completion delta settlement、新建渠道 API Key 提示、订单完成、兼容 API 支持、embeddings 和 Seed 等文案。 - 统一系统实例清理流程中的中文“离线”和日文「オフライン」术语,避免同一面板内批量删除与单实例删除使用不同表达。
Compatibility Notes
go run main.go仍只嵌入已有的web/default/dist。从源码启动前应先执行cd web/default && bun run build,再重启 Go 进程;Docker 构建已自动执行此前端步骤。- 自定义前端构建若绕过
bun run build/bun run build:check,不会自动执行 CSS 产物守卫;发布流水线应继续使用项目脚本。 - 游乐场参数沿用现有聊天补全请求字段,不新增数据库迁移;不支持某个参数的上游模型仍可能由上游接口返回参数校验错误。
- DoubaoVideo 完成态差额结算默认仍为开启;关闭后任务会按提交时预扣/固定计费结果保留,不再按完成回调的
total_tokens自动补扣或退款。 - 旧任务记录没有提交时开关快照时,会回退读取当前 DoubaoVideo 渠道设置;升级后如需改变历史未完成任务的结算方式,应先评估该回退行为。
disable_task_delta_settlement存储在渠道settingsJSON 中,不需要数据库迁移;该字段只对 DoubaoVideo 渠道生效。- Seedance 费率仍需在
ModelRatio/ 任务计费配置中按实际上游成本单独校准;本版本提供结算开关和 usage 解析,不自动改写生产费率。 - 批量删除离线实例只删除
last_seen_at早于当前时间SystemInstanceStaleAfterSeconds的记录;在线实例和正好处于阈值边界的实例不会被删除。 DELETE /api/system-info/stale-instances复用现有system_instances表,不新增数据库迁移;响应中的deleted_count仅用于管理端提示。
Verification
- 前端构建输出
Tailwind build verification passed,确认新增产物守卫已执行。 - 单独运行
node scripts/verify-tailwind-build.mjs,确认生成的 CSS 包含首页 Hero 桌面双列规则。 - 从本地 Go 服务回读嵌入的 CSS,确认其包含同一桌面栅格规则。
- Playground 定向测试:23 项通过,覆盖参数范围裁剪、
seed空值处理、显式零值发送和禁用参数过滤。 bun run typecheck、bun run lint、定向 Prettier 检查及bun run i18n:sync通过。- DoubaoVideo 计费定向测试通过:
go test ./service ./controller ./relay/channel/task/taskcommon ./relay/channel/task/doubao。 - 系统实例删除定向测试通过:
go test ./model -run "TestDeleteStaleSystemInstance|TestDeleteStaleSystemInstances" -count=1。 - 系统实例面板定向前端验证通过:
bun run typecheck、bunx eslint src/features/system-info/components/system-instances-panel.tsx src/features/system-info/hooks/use-stale-instance-cleanup.ts、对应文件 Prettier 检查。 - 通用视频任务 usage 解析定向测试通过:
go test ./relay/channel/task/taskcommon -run TestParseConfiguredTaskResultReadsUsageTokens -count=1。 - 渠道编辑状态定向测试通过:
bun test src/features/channels/components/drawers/channel-editor-state.test.ts。 - 后端全量验证通过:
go test ./...、go vet ./...、go run ./tools/jsonwrapcheck。 - 前端表单与 i18n 验证通过:
bun run typecheck、相关渠道编辑文件的 ESLint / Prettier 定向检查、bun run i18n:sync。 - 变更空白检查通过:
git diff --check。
Full Changelog: v1.0.4...v1.0.5-preview.1
- 本地前端构建完整性收口:修复完整仓库检出时根
-
v1.0.418 Jul 2026Release notes
Open source →Important
Claude/Anthropic 流式输出 token 计费回归已修复。 v1.0.4 曾在 Claude/Anthropic 流结束时正确解析顶层
CompletionTokens,但生成最终BillingUsage快照时遗漏OutputTokens,导致用量日志中的completion_tokens可能为0,输出 token 也可能未进入实际结算。当前版本已补齐最终快照回填,并加入完整流式事件链回归测试。该问题按响应处理器而不是模型名称划分:Anthropic 原生、AWS Bedrock Claude、Vertex Claude 模式、Advanced Custom Anthropic Messages,以及通过
/v1/messages复用 Claude 流式处理器的兼容渠道都可能受影响。Claude 非流式请求以及原生 OpenAI Chat、OpenAI Responses、Gemini 路径未发现同类问题。历史受影响请求无法仅凭本地
completion_tokens=0恢复精确输出量,应优先结合上游 usage 或账单记录进行对账;根据响应文本重新分词只能作为估算。额度并发与结算一致性已完成正式版加固。 发布前复核确认并修复了用户/token 额度在 Redis 与数据库之间异步更新、并发扣减缺少余额条件、邀请奖励全字段覆盖,以及资金结算成功但 token 调整失败后被错误标记为已完成等问题。额度扣减现在以数据库条件写为最终判定;旧版预扣路径会在同一数据库事务中同时扣减用户与 token;Redis 通过共享单调代次、条件回填、实体删除清理和持续失效重试阻断旧快照或已撤销 token;结算会分别处理已确认的部分补偿与结果不明的补偿错误,后者不会自动重复非幂等资金操作。
v1.0.4 涉及计费结算、分阶段计费、GPT-5.6 缓存写入、异步任务、Responses 兼容、安全验证、数据库迁移和项目授权说明等关键变化。升级前建议在测试环境核对常用模型、缓存创建价格、任务类渠道、用户额度、反向代理和 access token 相关流程,并阅读最新版 README 中的授权要求。
生产数据库提醒:正式环境不建议使用 SQLite。 SQLite 仅适合本地体验、开发和小规模测试;并发请求、多实例部署、大量日志与用量数据、数据库迁移、备份恢复和长事务可能引发锁等待、写入阻塞、迁移耗时或失败,以及可用性和数据维护问题。正式环境请使用 MySQL ≥ 5.7.8 或 PostgreSQL ≥ 9.6,并配置可靠的备份与恢复方案。
Note
本正式版草稿汇总 v1.0.4-preview.1 至 v1.0.4-preview.4 的主要更新,并补充正式发布前确认的授权政策、前端体验更新和 Claude/Anthropic 流式计费关键修复。
MAX API V1.0.4 Release Notes
GitHub 地址
https://github.com/MAX-API-Next/MAX-API/releases/tag/v1.0.4
Highlights
- Responses 跨协议兼容全面增强:完善 OpenAI Responses 与 Chat Completions 双向转换,覆盖普通响应、流式事件、工具调用、reasoning、usage 聚合,并新增 Gemini Responses 与 Advanced Custom 转换能力。
- 计费精度与表达能力升级:引入语义化
BillingUsage、tiered_expr分阶段计费和统一 quota 转换策略,扩展 OpenAI、Claude、Gemini 的缓存、图片、音频、reasoning 等细分用量,并补齐 GPT-5.6cache_write_tokens的跨协议结算以及 Claude/Anthropic 流式输出 token 的最终快照映射。 - 额度与结算并发安全补强:用户和 token 扣减改为数据库条件写,旧版预扣路径改为同库事务,Redis 使用跨节点单调版本栅栏拒绝旧快照回填,并为 token 撤销增加去重、指数退避和缓存 TTL 截止边界;BillingSession 分开处理已确认的部分补偿与结果不明的资金操作,避免自动重放非幂等补偿。
- 配置、缓存与身份约束继续收口:分组倍率注册配置与旧
GroupRatio入口共享同一运行时RWMap;指针型配置会在原对象上安全更新,坏 JSON 不会污染现值;用户缓存失效/删除、token 缓存删除、quota_data聚合键和 OAuth 身份唯一性都有更明确的迁移与重试边界。 - 异步任务进入通用计费阶段:新增任务 rate card 与通用计费框架,可按时长、分辨率、音频、媒体输入、图片数量和最终请求体进行预扣费与结算。
- 视频与多模态任务能力扩展:集中完善 Doubao Seedance、Ali/Kling/Wan、Gemini、Vertex、Vidu、Hailuo、Jimeng、Sora 等任务渠道的请求透传、动态计费、轮询和结果解析。
- 渠道与自动路由管理升级:支持
auto、auto:fast、auto:cheap等多条具名自动链路,并优化渠道抽屉、模型/分组倍率编辑、模型广场链路展示和 OAuth 回调配置提示。 - 账户敏感操作进一步加固:access token 改为 POST 生成并接入二次验证、禁缓存和双重限流;验证状态绑定当前用户,并支持 Passkey、2FA 或限定作用域的密码验证。
- 生产运行可靠性提升:完善优雅关闭、流式连接保护、Redis 原子更新、多节点任务归因、日志审计以及 SQLite、MySQL、PostgreSQL 老库兼容。
- 二次开发与授权说明完善:多语言 README 新增项目来源/社区鸣谢要求及临时商用授权说明,同时明确 One API MIT、New API AGPLv3 和本项目 AGPLv3 等既有开源义务仍需分别遵守。
New Features
- 新增
service/openaicompat兼容层和 Gemini Responses adaptor,支持 Responses 请求接入 Chat Completions 或 Gemini 上游。 - 新增
dto.BillingUsage协议用量快照,并在InputTokenDetails中支持cache_write_tokens,为格式转换后的原始协议语义、缓存写入量及 Claude/Anthropic 流式输出量结算提供统一载体。 - 新增
tiered_expr分阶段计费及可视化/表达式编辑能力,可按上下文长度、输入输出、缓存、图片、音频、请求参数、header 和时间条件组合价格规则。 - 新增通用任务请求构造、路径配置、结果解析和 rate card 计费模块;
Pass Through Body、模型映射与Param Override可组合使用。 - 豆包 Seedance 2.0 支持官方
content[]请求及safety_identifier、priority、generate_audio、ratio、resolution等参数,并按分辨率和视频输入动态计费。 - 新增多自动链路配置,每条链路可独立设置名称、启用状态、用户可见性和真实分组顺序。
- 用量聚合新增分组、令牌、渠道和节点维度,并补充 retry、empty retry、quota 区间等筛选能力。
- 管理端新增订阅重置、安全验证方式发现、OAuth 回调提示和更完整的渠道高级设置入口。
- Dashboard 新增运行状态摘要、真实加载失败提示和失败项重试入口,密钥、可用模型、额度与请求量状态更容易确认。
- 前端新增统一的安全富文本渲染链路,并为新增设置、日志、订阅和计费能力补齐多语言文案。
Major Improvements
- 任务提交会先生成最终上游请求,再执行计费;
Param Override修改后的时长、尺寸、媒体输入和 header 会同时作用于实际请求与费用计算。 - Playground 改善模型与分组选项恢复、聊天历史清理、选区处理、长文本输入和窄屏布局;
auto/auto:*自动链路会从用户完整模型集合加载选项,避免使用虚拟分组过滤后得到空列表。 - 服务关闭时会等待在途请求完成,超时后主动关闭连接,再执行 quota cache 落库与退出清理,降低重启期间的流式中断和数据丢失风险。
- 渠道表单、倍率编辑器和自动路由展示进一步统一校验与状态管理,复杂配置更易维护,也减少旧字段残留。
- 配置加载和导出路径进一步统一:
group_ratio_setting.group_ratio与旧GroupRatio指向同一运行时倍率表,UpdateConfigFromMap会原地更新指针型子配置,坏 JSON 会在校验失败后返回错误且不污染现有RWMap。 - 用户、token、订阅和兑换码的局部更新加强零值与并发保护;额度列升级为
bigint,管理端操作保持在 JavaScript 安全整数范围内。 - Redis 通用计数增量继续通过 Lua 保留 TTL 语义;用户/token 可用额度不再依赖 Redis 增量,而是以数据库条件更新为最终结果,并通过版本化失效重建缓存。用量日志和异步任务结算同时增强写入、回填与多节点归因。
- GPT-5.6
cache_write_tokens可在 Responses 非流式、流式、compact 和 Responses/Chat 转换中完整保留;结算时归一为缓存创建 token,并写入用量日志便于对账。 - 前端数据表改为按实际容器宽度切换桌面/移动布局,移动端支持批量操作;公共头部集中收纳 GitHub、语言和主题工具,并补充更多无障碍与多语言状态提示。
- 上游协议兼容性进一步扩展,完善 Claude/Gemini 工具调用、Ollama 非流式
tool_calls和 Wan2.7 图生视频input.media等请求响应格式。 - 上游错误响应、流式扫描、SSE ping、任务轮询和回调结算得到集中优化,异常请求对内存、连接和后台任务的影响更可控。
- 控制台与管理接口的全局 API 限流默认值由 180 秒内 180 次提升为 180 秒内 720 次,为管理端并发加载和连续操作保留更多余量;该调整只覆盖
/api/*及旧版 Dashboard 账单接口,模型中继/v1/*、Gemini/v1beta/*继续使用独立的模型请求限流。 - 管理端渠道测试补齐响应时间反馈:直接测试按钮与测试弹窗都会显示测试耗时,并把最新
response_time/test_time同步回渠道列表,便于管理员即时判断上游连通性和延迟。 - 模型定价图形化编辑器现在会区分保存快照与草稿快照;删除已保存模型时不会再被旧保存值回填,删除动作会立即从图形列表中生效,待保存后再落到配置。
- 用户/token 额度更新不再进入延迟批量落库路径;普通 token 通过
remain_quota >= amount条件保护并发下界,无限额度 token 继续保留原有不受余额限制的使用语义。 - Token 的
remain_quota/used_quota与用户额度统一为 64 位整数,并为 MySQL、PostgreSQL 老库补充bigint NOT NULL DEFAULT 0迁移;SQLite 继续使用兼容的类型亲和性与 AutoMigrate 路径。 - 数据看板 quota 缓存改为锁内快照、锁外落库;每批聚合数据会携带稳定快照 ID,并在
quota_data_snapshots中与累计更新同事务去重。数据库失败会保留原快照 ID 重新入队,提交结果不明确时重复执行也不会再次累加;看板刷盘和聚合键迁移现在共用跨数据库 operation lock,并使用短租约 heartbeat 持续续租,避免启动迁移扫描后被并发写入覆盖。 quota_data.aggregate_key迁移改为在保留唯一索引约束的前提下清理 stale key、合并旧 NULL/空聚合键记录、删除重复行并回填 survivor;迁移使用有界批量扫描、bigintscratch 表和跨库 set-based apply,后续 upsert 会命中迁移后的累计行,避免同一统计维度拆出并行记录。- 看板 flush 现在贯穿调用方
context与截止时间:关机保存不再仅停止等待一个仍在后台运行的 goroutine,本地 flush 串行锁、数据库 operation lock 获取和单条持久化事务都会响应取消;截止时间到达时,已摘取 snapshot 会在函数返回前按原SnapshotID重入队。单条持久化失败也会在保留失败项重试的同时向调用方返回非空错误,不再把“仅存在于内存中的待重试数据”报告为保存成功。 quota_data_operation_locks的创建、过期抢占和 heartbeat 续租统一使用数据库服务器时钟,并在同一 SQL 语句中计算当前时间与新过期时间;SQLite 使用strftime、MySQL 使用UNIX_TIMESTAMP()、PostgreSQL 使用CURRENT_TIMESTAMP,避免多节点主机时钟偏差导致仍有效的租约被提前抢占。tiered_expr编译缓存达到上限时只淘汰最早条目,不再全量清空;订阅资金源也改为严格使用调用方传入的预扣额度。- 用户/token 缓存回填增加 Redis 共享单调 generation 与
WATCH条件写;用户 group、status、role、name、setting 等窄字段也会在 DB 查询前捕获 generation。实体删除会同时清理 hash 与专属版本键;token 撤销删除失败后会按 HMAC 缓存键去重并在缓存 TTL 窗口内指数退避重试,执行中的旧任务也不能吞掉同一 token 的新删除请求。 - 用户设置保存、用户删除和 token 撤销的 Redis 缓存处理共用有界重试语义;用户删除的数据库事务已提交后,缓存删除失败会写入日志并登记删除重试,不再把已完成的删除操作返回为失败。
- 有限额度 token 的信任判断统一读取 Gin 中的
int64上下文值,避免 64 位额度升级后被误读为0并触发错误预扣。
Stability and Security
- 管理端模型拉取统一执行 SSRF 校验,默认可信代理范围收紧为 loopback,并加强真实客户端 IP 与关键验证接口的限流边界。
- 注册、邮箱绑定、充值回调和通知邮箱统一采用更严格的邮箱规范化与唯一性检查;验证码和密码重置流程强化一次性使用与并发占用语义。
- 富文本和 HTML 内容统一经过 sanitizer,公告、首页、关于页、法律文档等用户可见内容采用一致的安全渲染策略。
- MySQL 命名锁、老库字段迁移及 SQLite/PostgreSQL 差异路径得到补强,root 用户删除保护下沉到 model 层。
- 计费、日志审计和用户更新路径增加边界保护,降低异常数据、旧快照或极端额度对账务字段的影响。
- 渠道测试成功和失败提示统一携带渠道/模型上下文,多语言界面会明确区分“测试失败”和“未执行/未完成”状态;失败场景会保留上游错误码与错误摘要,减少管理员排查连接问题时的二次定位成本。
- 自定义 Footer HTML 复用统一 sanitizer,OAuth 登录回跳只接受同源站内路径;外部支付、预览和 OAuth 绑定窗口统一隔离
window.opener,并通过短时 OAuth state 标记维持绑定流程。 - Turnstile token 改由
X-Turnstile-Token请求头传递,避免进入 URL、浏览器历史和常规 query 日志;后端暂时保留 query 回退以兼容旧客户端。 - 浏览器端价格预估移除
new Function,改用受限表达式解释器;服务端header()/param()改用正向白名单,只开放明确的计价元数据,并拒绝整个请求、GJSON 查询/修饰符/通配符、未知 body 根和伪装认证 header。 - Setup 完成状态不再永久写入 localStorage,后端重置后刷新页面即可重新进入初始化流程;流式 Playground 状态改为响应式 state,未收到
[DONE]时即使 SSE 已关闭也会进入错误收尾,生产错误处理不再输出包含请求头的完整 Axios 对象。 - GitHub、Discord、OIDC、WeChat、Telegram 和 Linux DO 身份占用检查改为“存在任意匹配即占用”;即使老库中已经存在重复 OAuth 标识,也不会因为匹配行数大于 1 而错误放行新的绑定。唯一性查询的数据库错误会写入服务端日志,公开登录/绑定响应只返回本地化通用错误,不再暴露连接地址、表名或驱动信息。
- OAuth 身份唯一性现在同时由数据库迁移层兜底:启动时会把空字符串归一为 NULL,清理重复 GitHub、Discord、OIDC、WeChat、Telegram 和 LinuxDO 标识,并在支持的数据库上建立非空唯一约束,减少检查通过后并发写入重复身份的窗口。
- Redis 缓存失效/删除失败会进入带截止时间的进程内重试,并在到期后写入终态日志;用户删除已提交后,缓存删除失败只登记重试,不再把已完成的数据库删除包装成接口失败。
- 清理了 token 与用户缓存中已无调用的逐字段写入 helper,包括旧 token hash 字段写入入口和用户 group/role/email/name/setting/status setter;当前保留的窄字段回填均继续走 version fence,降低后续误接回旧 Redis 写法的风险。
Critical Fixes
- P0 — 修复 Claude/Anthropic 流式输出 token 未进入日志与结算:最终构造 Claude
BillingUsage时,会在上游快照缺少输出量的情况下,从已解析的CompletionTokens回填ClaudeUsage.OutputTokens;若上游已提供非零OutputTokens,则继续保留上游原值。 - 覆盖范围:所有最终由 Claude 流式响应处理器完成 usage 快照的请求,包括 Anthropic、AWS Bedrock Claude、Vertex Claude 模式、Advanced Custom Anthropic Messages,以及部分通过 Claude 协议接入的 Ali、DeepSeek、Moonshot、MiniMax、VolcEngine、Zhipu 等兼容路径。模型名称本身不是判断依据。
- 其他模型核查:Claude 非流式、OpenAI Chat、OpenAI Responses、Chat/Responses 双向转换、Gemini 原生流式/非流式及 Gemini 本地 usage 估算路径未发现同类问题。
- 历史对账:修复前已产生的异常日志无法仅凭本地
completion_tokens=0恢复精确输出量,应优先使用上游 usage/账单记录;根据响应文本重新分词只能作为估算。 - HIGH — 修复并发扣减突破余额下界:用户和普通 token 的扣减在同一条更新语句中校验剩余额度,只有实际更新一行才视为成功;并发请求不能再同时通过旧余额检查后把额度打成负数。
- HIGH — 修复 Redis/DB 更新顺序、旧快照回填与结算部分失败:额度变更先提交数据库,再以共享单调 generation 原子推进并失效缓存;旧 DB 读取只能在 generation 未变化时写回。BillingSession 的 token 调整失败时会尝试反向补偿:返回成功但仅部分应用时记录已确认残差,并在再次调整 token 前补齐;补偿调用报错时视为结果不明,不采用返回额度推断结果,也不会自动再次调用同一笔非幂等补偿。
- 持续失败边界:单次结算最多尝试 3 次。若 token 对账仍失败,错误会继续返回并写入结算错误日志;补偿结果不明时后续只允许 token 对账重试,不能视为资金已自动恢复完成。运维侧仍需依据 user/token/request 标识和上游账单人工对账。
- HIGH — 修复 token 撤销后旧缓存继续鉴权:单个和批量删除会在数据库提交后同步登记缓存删除任务;Redis 长故障不再于 350ms 后放弃,而是在缓存 TTL 窗口内按缓存键去重、指数退避并持续重试,到期仍失败会写入终态日志并清理队列。任务代次会阻止执行中的旧成功结果覆盖后到的新删除请求。
- HIGH — 修复预扣失败遗留 token 扣减:旧版钱包预扣不再先扣 token、再依赖失败后补偿;用户额度与 token 额度在同一数据库事务中执行条件扣减,任一步骤失败都会整体回滚。
- HIGH — 修复数据看板快照重试重复累计:新增持久化快照去重记录,快照登记与
quota_data累计更新在同一事务中完成;数据库已提交但客户端收到错误时,携带同一快照 ID 的重试不会再次增加 count、quota 或 token_used。 - HIGH — 修复邀请奖励覆盖并发字段:邀请次数、可转额度和历史额度改为原子增量,不再用旧用户快照覆盖 quota、status、role 等并发修改。
- HIGH — 修复配置别名与指针配置更新脱节:
group_ratio_setting.group_ratio不再在旧入口更新后提前返回,注册配置导出和运行时倍率读取会保持一致;指针型配置优先复用已有UnmarshalJSON对象,避免替换掉被其他包持有的运行时实例。 - HIGH — 修复旧
quota_data聚合键迁移后重复建行与迁移竞态:迁移会在保持正式唯一索引在线时清理 stale key、合并同维度历史行、回填aggregate_key并删除重复记录;跨实例迁移和看板刷盘通过数据库 operation lock 串行化,短租约由 heartbeat 全程续租,失去 owner 会中止后续写入,避免全局 scratch 表互相覆盖,或用旧扫描汇总覆盖迁移期间的新 quota 写入。 - HIGH — 修复关机 quota flush 超时后 snapshot 滞留后台 goroutine:
QUOTA_DATA_CACHE_SAVE_TIMEOUT_SECONDS现在会形成真实的取消 deadline,而不是只让 main goroutine 停止等待;锁获取被取消或截止时间到达时,已脱离全局缓存的 snapshot 会先重入队再返回。单条数据库写入失败会继续处理同批其他数据、只重入队失败项,并把首个持久化错误返回给关机调用方。 - HIGH — 修复分布式 quota operation lock 使用主机时间造成的租约误抢占:锁插入、过期判断、owner 抢占和 heartbeat 续租全部改用数据库时钟原子计算,时钟较快的应用节点不能再仅凭本机时间提前接管仍由其他节点持有的迁移或看板刷盘锁。
- HIGH — 修复用户缓存失效/删除失败造成的状态漂移:用户设置更新失败清缓存时会登记失效重试;软删除/硬删除用户提交成功后,Redis 删除失败会转为日志和删除重试,不再把数据库已完成的删除误报为接口失败。
- HIGH — 修复 OAuth 身份检查与写入之间的并发窗口:GitHub、Discord、OIDC、WeChat、Telegram 和 LinuxDO 标识会在清理旧数据后建立唯一约束;重复旧值优先保留未软删除、ID 更小的用户,其余重复绑定会被清空。
- 安全边界修复:补齐 Footer 存储型 XSS、OAuth 协议相对地址跳转、价格预估任意 JavaScript 执行、Turnstile URL 泄露和新窗口反向标签页控制等路径。
- 错误与数据可靠性修复:
FillUserBy*返回真实数据库错误,并通过ErrUserDeleted明确区分 OAuth 软删除账户;内置和通用 OAuth 流程都返回“用户已注销”域错误。OAuth 身份唯一性查询失败会记录 provider 与内部错误,但客户端只收到本地化通用信息。配置反序列化失败改为向上返回,group_ratio_setting.group_ratio会与旧GroupRatio入口更新同一运行时倍率映射,兑换码前缀搜索正确转义_/%,数据看板刷盘失败会保留待重试数据。
Compatibility Notes
- access token 生成接口已由
GET /api/user/token改为POST /api/user/token,依赖旧接口的脚本、SDK 和自动化客户端需要同步调整。 - 默认
TrustedProxies不再信任私网网段;使用 Nginx、Cloudflare Tunnel、内网负载均衡或容器代理时,请显式配置TRUSTED_PROXIES。如果后端未信任代理的实际来源地址,多名公网用户可能被识别为同一个代理 IP,进而共享登录、OAuth、支付、令牌明文读取等关键接口的限流桶并统一返回 429。请仅信任精确代理地址或最小 CIDR,并确认代理转发X-Real-IP/X-Forwarded-For,不要直接信任整个私网地址段。 GLOBAL_API_RATE_LIMIT的未配置默认值调整为 720 次、窗口仍为 180 秒;显式环境变量继续优先。该配置不改变CRITICAL_RATE_LIMIT的默认 20 分钟 20 次,也不改变默认关闭、按用户/分组独立配置的模型请求限流。- 任务
Param Override现在会在计费前生效,header override 会在 adaptor 默认 header 之后应用;请复核已有任务渠道的改写规则和价格配置。 - 通用 rate card 可能使过去未精确计费的任务按最终请求参数结算,建议升级前核对常用视频、图像和音频模型的费率表。
- MySQL/PostgreSQL 老库会迁移部分用户额度字段到
bigint;升级前请备份数据库,并先在测试环境验证启动迁移。 - MySQL/PostgreSQL 老库还会把 token 的
remain_quota/used_quota迁移为bigint。大规模tokens表执行 DDL 可能持有元数据锁或触发表重写,建议安排低峰窗口,必要时提前使用在线 DDL。 BATCH_UPDATE_ENABLED=true不再延迟聚合用户/token 可用额度变更;这些账务写入会直接落库以保证条件扣减和错误传播,批量模式仍可用于非余额类统计。高吞吐部署应观察数据库写入负载。- 启用 Redis 的部署需要允许
GET、SET、WATCH、MULTI/EXEC、EVAL/EVALSHA、INCR、DEL、HSET和过期时间相关命令;额度缓存 generation 由共享 Redis 的cache-version:sequence单调序列协调,不能用仅存在于单个进程的本地计数替代。专属版本键只在对应用户/token 删除时清理,不应手工设置普通 TTL。token 撤销和用户缓存失效/删除重试队列位于应用进程内,进程存活时会在各自缓存 TTL 窗口内持续重试;若故障期间同时重启全部实例,未完成任务不会跨进程持久化,旧 hash 仍以缓存 TTL 为最终上界。 - 数据库迁移会新增
quota_data_snapshots去重表,用于保证看板聚合快照重试幂等;SQLite、MySQL 5.7.8+ 和 PostgreSQL 9.6+ 均通过 GORM 自动迁移创建,数据库账号需要具备建表和索引权限。 - 数据库启动迁移还会整理
quota_data.aggregate_key:老库中的 NULL/空键会按统计维度合并、清理重复行并回填 survivor。迁移会额外创建quota_data_operation_locks和短生命周期 scratch 表/索引,需数据库账号具备建表、建索引、更新和删除权限;多实例启动时其他实例或看板刷盘会等待该 operation lock。锁使用短租约和 heartbeat,持有实例异常退出后不会长期阻塞,长迁移也会持续续租;大表建议低峰升级并保留升级前备份。 QUOTA_DATA_CACHE_SAVE_TIMEOUT_SECONDS现在同时限制本进程 flush 串行等待和数据库 operation lock 获取;超时会返回context deadline exceeded并重新入队未确认完成的 snapshot。运维日志中出现 quota cache save failure 或待重试数量大于 0 时,应视为本次关机保存未完全落库,不能仅依据进程已退出判断保存成功。- SQLite 继续作为受支持的本地体验和测试数据库,但不建议用于正式/生产环境。正式环境,尤其是多实例、高并发、大量日志/用量数据或频繁迁移场景,应迁移到 MySQL ≥ 5.7.8 或 PostgreSQL ≥ 9.6,并配置数据库备份、恢复演练和升级窗口。
users表会为 GitHub、Discord、OIDC、WeChat、Telegram 和 LinuxDO 身份字段建立非空唯一约束;升级时空字符串会归一为 NULL,重复值会保留排序最靠前的一个账户(优先未软删除用户)并清空其他重复绑定。MySQL 通过生成列实现可空唯一语义,需 MySQL 5.7.8+ 与 DDL 权限。- GPT-5.6 的
input_tokens_details.cache_write_tokens会按缓存创建 token 计费:ratio 模式使用CacheCreationRatio,表达式模式使用cc;请根据实际上游价格检查对应配置。 - 如果上游同时返回
cached_creation_tokens和cache_write_tokens,系统取两者中的较大值作为缓存创建总量,不会相加,外部对账工具应采用相同口径。 tiered_expr系数表示每 100 万 token 的实际美元价格,不包含旧倍率表的隐式换算;未启用该模式的模型继续使用原有ModelRatio/ModelPrice。tiered_expr的header()仅开放anthropic-beta/openai-beta,param()仅开放文档列出的计价元数据、数组计数和 role/type 路径;其他路径、@this、查询、修饰符、通配符与未知 header 均返回空字符串或nil。旧规则需要按新白名单调整。- Responses 兼容路径会保留更完整的 usage 明细;读取用量的外部系统应兼容
prompt_tokens_details、input_tokens_details、cache_write_tokens和billing_usage。 /v1/messages或其他 Anthropic Messages 兼容入口可能把非claude-*模型也交给 Claude 流式响应处理器;升级验证和对账应按实际响应适配器检查,不能只按模型名称筛选。- 新版前端通过
X-Turnstile-Token发送验证 token;后端仍接受旧 query 参数作为过渡兼容,但自定义前端、SDK 和网关应尽快迁移到请求头。 - 数据库中的注册配置如果包含无法解析的布尔、数值或 JSON 子配置,加载过程现在会返回错误而不是跳过坏值继续运行。升级前请清理损坏或手工编辑错误的 option 值。
- 二次开发、社区鸣谢和临时商用授权以各语言最新版 README 公告为准;临时授权不替代或免除上游项目及 AGPLv3 的开源许可义务,长期商用授权需另行联系项目方。
Upgrade Checklist
- 升级前备份数据库和关键配置,尤其是用户额度、渠道配置、分组倍率、模型价格、任务 rate card、
Param Override、TrustedProxies和 access token 自动化脚本。 - 在重建或重启容器前核对实际生效的
TRUSTED_PROXIES、GLOBAL_API_RATE_LIMIT*和CRITICAL_RATE_LIMIT*环境变量。反向代理部署应从不同公网网络分别执行状态页与登录探针,确认后端识别到各自真实客户端 IP,普通控制台请求与关键操作不会因共享代理 IP 限流桶而同时返回 429。 - 对大规模
users/tokens表预估 bigint 迁移时间,并在升级窗口观察数据库锁等待、启动日志和额度字段默认值。 - 老库升级前用只读查询排查重复 OAuth 标识和
quota_data同维度多行;在测试环境启动一次迁移,确认清理日志、回填结果和唯一索引创建完成。 - 先在测试环境验证常用 OpenAI Responses、Chat Completions、Claude/Anthropic Messages、Gemini、视频任务和
auto:*自动链路,确认路由、流式响应、usage 明细和结算日志符合预期。 - 对 Claude/Anthropic 流式历史日志进行风险筛查:若修复前存在
completion_tokens=0但响应有实际输出的记录,应结合上游 usage 或账单记录进行人工对账。 - 复核 GPT-5.6 与其他缓存写入模型的
CacheCreationRatio/cc配置;外部报表请采用“缓存创建 token 取最大值而非相加”的同一口径。 - 检查现有
tiered_expr是否读取敏感 header 或请求内容;将这类条件迁移到明确、非敏感的计价元数据,并在图形预估器和真实请求上分别验证结果。 - 检查 Redis ACL、代理层和集群模式是否允许版本栅栏所需的事务与 Lua 命令;升级后执行一次有限 token 请求并确认数据库额度、Redis 缓存重建值和日志扣费一致。建议在测试环境模拟超过 350ms 的 Redis 故障,撤销 token 后恢复 Redis,确认对应 hash 与专属版本键最终被清理且旧 token 无法继续鉴权。
- 确认启动迁移成功创建
quota_data_snapshots;升级后连续触发两次看板刷盘并抽查 count、quota、token_used 未因重试重复累计。 - 确认启动迁移可创建、续租并释放
quota_data_operation_locks,quota_data.aggregate_key唯一索引在旧数据合并期间保持存在;大表或多实例部署应观察启动日志、heartbeat 和锁等待时间,避免在迁移窗口内误判看板刷盘延迟为数据丢失。 - 在测试环境占用
quota_data_operation_locks后触发关机 flush,确认QUOTA_DATA_CACHE_SAVE_TIMEOUT_SECONDS到期时调用会返回、snapshot 仍保留相同 ID 等待重试,释放锁后再次刷盘只累计一次;同时模拟单条持久化失败,确认关机日志收到非空错误而失败项仍在缓存中。 - 如果当前正式环境仍使用 SQLite,升级前应先完成数据备份并规划迁移到 MySQL 或 PostgreSQL;至少应避免多实例共享 SQLite 文件,并评估现有
quota_data、日志和任务表规模、迁移耗时、写锁等待及恢复流程。 - 升级后抽查
group_ratio_setting.group_ratio的导出值和运行时倍率是否一致;模拟用户设置更新和用户删除期间 Redis 短故障,确认恢复后缓存会被失效或删除,接口不把已提交的数据库删除误报为失败。 - 为
billing settlement failed after 3 attempts、error adjusting token quota after funding settled和资金补偿失败日志配置告警;出现后按 request/user/token 维度对照上游 usage,不要仅依赖本地预扣值判断最终费用。 - 对软删除且曾绑定 GitHub、Discord、OIDC、WeChat、Telegram、LinuxDO 或自定义 OAuth 的账户执行登录探针,确认统一返回“用户已注销”;再模拟一次 OAuth 唯一性查询故障,确认服务端保留内部错误日志而客户端响应不包含数据库地址、表名或驱动详情。
- 自定义登录/注册/邮箱验证/签到前端应改用
X-Turnstile-Token,并确认反向代理允许该请求头通过。 - 复核任务类渠道的最终请求体计费结果,重点检查视频时长、分辨率、音频、图片数量、媒体输入和 header override 是否与实际调用一致。
- 更新依赖旧
GET /api/user/token的脚本或 SDK,改用POST /api/user/token,并准备 Passkey、2FA 或限定作用域密码验证流程。 - 升级后在管理端执行渠道连接测试,确认响应时间会回写到渠道列表;同时抽查模型定价图形化编辑器的新增、删除和保存流程,确保草稿与最终配置一致。
Verification
- Claude 完整流式序列回归通过:上游/顶层
CompletionTokens = 53,最终BillingUsage.ClaudeUsage.OutputTokens = 53。 - 上游值保留回归通过:当上游已提供非零
OutputTokens时,不会被本地回填值覆盖。 - Claude 非流式、OpenAI Chat、OpenAI Responses、Chat/Responses 转换、Gemini 原生 usage、Gemini 估算 usage 和 Gemini prompt-only 快照替换探针均通过。
- 跨适配器验证通过:
go test ./relay/channel/claude ./relay/channel/aws ./relay/channel/vertex ./relay/channel/advancedcustom ./service -count=1。 - 全仓测试验证通过:
go test ./... -count=1;本轮涉及的 model、service、billingexpr、config、middleware、controller 定向测试与go vet ./...通过,go run ./tools/jsonwrapcheck和git diff --check通过。 - 管理端前端补充验证通过:
bun run typecheck、bun test src/features/channels/lib/channel-actions.test.ts、针对渠道测试与模型定价编辑器变更文件的bunx eslint、bunx prettier --check、bun run i18n:sync与git diff --check。 - 本轮前端维护复核通过:
bun run typecheck、bunx eslint --no-warn-ignored src/features/system-settings/models/model-ratio-visual-editor.tsx、bunx prettier --check src/features/system-settings/models/model-ratio-visual-editor.tsx src/i18n/locales/ru.json与bun run i18n:sync。 - 本轮额度/安全复核通过:并发用户/token 扣减、无限 token、DB 失败不触碰缓存、邀请奖励原子更新、用户/token 同事务预扣、BillingSession 完整/失败/部分补偿及结果不明补偿、数据看板失败重入队与快照幂等、兑换码转义、配置错误传播、表达式敏感字段隔离和有界缓存等回归测试全部通过。
- 二次一致性复核通过:单次 BillingSession 瞬时故障恢复、用户/token 旧异步快照跨失效回填、有限 token
int64信任判断、计费表达式全请求/查询绕过、OAuth 软删除域错误和 SSE 未完成关闭均有定向回归覆盖。 - Redis 竞态测试使用内存 Redis、Lua 单调代次和真实
WATCH/事务交错,主动阻塞旧用户/token DB 快照及用户 group 窄字段回填;同时验证实体删除后 hash/版本键释放、删除前快照被拒绝且重建 generation 大于旧值。 - 本轮核心回归可复现执行:
go test ./common -run "TestVersionedHashDeletionRejectsStaleRefillsAndReleasesEntityKeys" -count=1、go test ./service -run "TestBillingSession|TestPreConsume" -count=1、go test ./model -run "TestSaveQuotaData|TestUserQuotaInvalidation|TestUserGroupInvalidation|TestTokenQuotaInvalidation|TestTokenDeleteRetries|TestTokenCacheRetry|TestIsOidcIdAlreadyTaken|TestAtomicTokenAndUserPreConsume|TestUpdateOption" -count=1、go test ./controller -run "TestOAuthBindMasksUniquenessLookupDatabaseError|TestFindOrCreateOAuthUser" -count=1。 - token 撤销重试覆盖 Redis 连续失败超过旧三次短重试窗口后恢复,以及旧任务执行期间叠加同 token 新删除请求的确定性交错;
go test ./... -count=1、go vet ./...、jsonwrapcheck和git diff --check均通过。race 模式因验证环境CGO_ENABLED=0未执行。 - GitHub Backend checks 中的
TestUpdateOptionFiltersAutoRouteGroupRatioNamesBeforePersistence和TestUpdateOptionMapFiltersAutoRouteGroupRatioNames已修复;分层键group_ratio_setting.group_ratio现在会更新实际运行时RWMap。完整go test ./model -count=1与go test ./... -count=1均通过。 - 本轮配置/缓存/迁移回归覆盖
TestUpdateConfigFromMap_PointerUnmarshalerUpdatesInPlace、TestLoadFromDBReturnsInvalidSubConfigError、TestTokenCacheDeleteRetryGetsBoundedDeadline、TestQuotaDataMigrationBackfillsAndMergesLegacyRows、TestUpdateUserSettingRetriesCacheInvalidation、TestUserDeletesRetryCacheDeletionAfterDatabaseCommit和TestMigrateUserOAuthIdentityConstraintsBackfillsAndEnforcesUniqueness。 - 本轮后端全量复核通过:
go test ./model -count=1、go test ./setting/config ./types -count=1、go test ./... -count=1、go vet ./...与git diff --check。 - 本轮前端安全复核通过:11 个 OAuth redirect、Turnstile header、受限表达式求值和脱敏错误摘要测试,以及 3 个 HTML sanitizer 测试通过;
bun run typecheck、bun run build:check与变更文件 Prettier 检查通过。 - 限流配置与路由边界复核通过:
go test ./common ./middleware ./router;控制台/api/*、关键操作和模型中继分别使用全局 API、Critical 与 Model Request 三套独立限流配置。 - 本轮
quota_data迁移补强通过:保留正式唯一索引、stale key 修复、row B 计数保真、bigintscratch schema、迁移 operation lock 等待、quota 写入等待锁、锁竞争测试先观察到真实抢锁尝试再断言阻塞、短租约 heartbeat 续租、失去 owner 中止和 release 失败重试均有回归覆盖;同时确认旧 token/user 逐字段缓存 setter 已无残留符号。 - 最新后端复核通过:
go test ./model -count=1、go test ./... -count=1、go vet ./...、go run ./tools/jsonwrapcheck与git diff --check。 - 最新 quota flush / operation lock 回归覆盖
TestSaveQuotaDataCacheRequeuesSnapshotWhenCallerStopsWaiting、TestSaveQuotaDataCacheReturnsIndividualPersistenceFailure和TestQuotaDataOperationLockUsesDatabaseClockForLeaseSQL;单条失败错误传播、超时重入队、后续幂等落库,以及 SQLite/MySQL/PostgreSQL 数据库时钟 SQL 均已验证。聚焦回归连续 10 次、go test ./model -count=1、go test ./... -count=1、go vet ./...、go run ./tools/jsonwrapcheck与git diff --check通过。 - 发布状态:计费阻断已解除。 Claude/Anthropic 流式输出 token 映射已修复并由持久化回归测试覆盖。
Full Changelog: v1.0.3...v1.0.4
-
v1.0.4-preview.5.0.20260718193239-75ab64a3ef9318 Jul 2026 pre-releaseNothing published for this version
-
v1.0.4-preview.515 Jul 2026 pre-releaseRelease notes
Open source →Warning
v1.0.4 正式版发布继续阻断
正式发布前进一步核查发现,Claude Messages、OpenAI Responses、Gemini、Realtime、OpenAI 音频和 MiniMax TTS 的 usage 归一化与最终结算存在多类同源缺陷,可能导致输出 token、缓存、图片、音频或精确字符用量未进入日志、普通倍率计费或
tiered_expr结算。由于这些问题直接影响账务准确性,v1.0.4 暂不进入正式版,先发布 v1.0.4-preview.5 完成验证。本预览版同时合并原计划进入 v1.0.5-preview.1 的 Dashboard、统一表格、移动导航、系统设置、渠道编辑、Tiered Billing、Ollama 模型管理、Playground、多语言和 README 更新,避免已确认修复继续滞留在下一版本分支。
升级前请在测试环境重点核对 Claude/Anthropic 流式输出、Responses 多模态 usage、Gemini 图片/音频生成、Realtime 音频表达式、TTS/STT、MiniMax 字符计费,以及移动端表格、Dashboard、系统设置、渠道编辑和 Playground 自动分组。
Important
修复前已经产生的异常日志无法始终仅凭本地记录恢复精确用量。Claude
completion_tokens=0、丢失的 Responses modality 明细或异常 Gemini fallback 应优先结合上游 usage、供应商账单和原始响应进行对账;根据响应文本或媒体数量重新估算只能作为辅助依据。Note
v1.0.4-preview.5 是正式版前的计费阻断修复与前端体验集中验证版本。该版本没有新增数据库迁移,但会改变部分模型在异常 usage、音频路由和分阶段计费下的最终结算结果;发布前请以最终 tag、构建产物、上游官方价格和实际部署验证结果为准。
Release Notes
GitHub 地址
https://github.com/MAX-API-Next/MAX-API/releases/tag/v1.0.4-preview.5
Highlights
- 多协议 usage 与实际结算完成系统性补强:修复 Claude、Responses、Gemini、Realtime、TTS/STT 和 MiniMax 在最终 usage、BillingUsage 或细分 token 归一化中的缺口。
- Claude/Anthropic 流式输出恢复完整:
message_delta缺少output_tokens时会从累计CompletionTokens回填,并同步写回客户端 JSON;上游已有非零值继续优先保留。 - Responses 多模态明细完整保留:非流式、流式和 Compact 统一复制缓存创建、文本、图片、音频及 reasoning 等输入输出明细,并支持官方
output_tokens_details。 - Gemini fallback 支持混合模态:候选总量为零时可同时恢复 reasoning、文本、图片和音频明细,保留上游已有 modality 数据,并避免把流式
audio/*inline data 错算成图片。 - Realtime 与音频计费语义对齐:Realtime
tiered_expr可读取cr、ai、ao,OpenAI TTS/STT 会归一化音频明细,Responses 音频路由覆盖gpt-4o-audio*、gpt-4o-mini-audio*、gpt-audio*和带音频 usage 的模型别名。 - MiniMax TTS 使用精确字符用量:上游
usage_characters会直接进入输入 token、日志和倍率结算,缺失时才回退本地估算。 - Dashboard 首页由固定装饰横幅升级为真实运营摘要,集中展示请求、额度、模型与密钥状态,让异常和风险更容易在首屏识别。
- 统一 DataTable 改为根据内容容器宽度切换布局,不再只依赖浏览器视口;移动端支持行选择、批量操作和更安全的长内容展示。
- 应用端与公开页面 Header 完善响应式导航,将语言、主题、配置和 GitHub 等低频入口收进紧凑工具菜单,并保留移动端通知入口。
- 全局查询错误策略完成收敛:Dashboard、API Key、模型等普通请求失败时保留当前页面、筛选和操作上下文,通过局部错误状态提供重试,不再因任意 HTTP 500 直接跳转
/500。 - 设置页增加结构化加载骨架、局部错误恢复和更完整的表单语义,Switch 标签、说明、错误信息与禁用状态可被键盘和辅助技术正确识别。
- 修复公开首页 Hero 在窄屏下横向扩展和内容裁切的问题,390px 等移动视口下页面宽度保持在可视区域内。
- 修复 Playground 选择
auto或auto:*模型分组后无法选择模型的问题,自动分组现在会正确加载用户模型集合。 - 渠道编辑、Param Override 和 Tiered Billing 等大型交互模块完成分层整理,并补齐异步状态、表单关联和关键工具函数测试,降低后续维护与回归风险。
- 法语、日语、俄语和越南语翻译继续补齐,修复日语插值与越南语 Tiered Billing 文案,并完善相关屏幕阅读器文本。
- 六种公开 README 语言新增二次开发、社区鸣谢和授权边界说明,进一步明确 AGPLv3、临时商用授权及上游项目许可之间的关系。
Critical Billing Fixes
- P0 — Claude
message_delta输出 token 清零:最终事件或上游快照缺少OutputTokens时,从已累计的CompletionTokens恢复;修复值同时进入BillingUsage、日志、结算和客户端usage.output_tokens。 - P1 — OpenAI Responses 丢失多模态 usage:非流式、流式和 Compact 不再只保留总量与部分缓存字段,输入侧
cached_creation_tokens、text/image/audio 和输出侧 reasoning/text/image/audio 明细均可进入内部结算。 - P1 — Gemini fallback 覆盖或漏算 modality 明细:fallback 改为按候选 token 而非包含 reasoning 的 completion 判断;原始缓存、工具和 modality metadata 会被保留,图片估算写入
ImageTokens。 - P1 — Gemini 混合文本与图片只记录一种输出:文本估算和
imageCount * 1400可同时进入候选总量与CandidatesTokensDetails;已有非零 IMAGE/AUDIO/TEXT 明细不会被本地估算覆盖。 - P1 — Gemini 流式音频误判为图片:inline data 仅在 MIME 为
image/*时计入图片数量,audio/*不再产生错误的 1400 图片 token。 - P1 — Realtime
tiered_expr缺少音频和缓存变量:结算参数现包含缓存读取、音频输入与音频输出,并继续按表达式实际使用的变量从基础p/c中自动排除,避免重复或遗漏计费。 - P1 — OpenAI TTS/STT usage 和音频路由不完整:流式 TTS 与 STT 的
input_tokens_details/output_tokens_details会映射到统一 usage;Responses 可按模型家族或实际音频明细进入音频结算。 - P2 — MiniMax 精确字符数未参与结算:
usage_characters现在作为PromptTokens、TotalTokens和文本明细参与日志及倍率结算;生产代码统一使用项目 JSON wrapper。 - 视频任务核查:未发现 Claude 式最终 usage 快照清零问题;按次任务保留预扣额度,其他任务仍依次使用 adaptor 实际额度、
TotalTokens重算或原预扣额度。
New Features
- 统一表格新增容器宽度响应能力,可在侧栏展开或内容区变窄时自动切换为移动卡片布局。
- 移动表格新增可配置的行选择与批量操作支持,并允许列通过元数据定义移动端标题、内容布局和换行策略。
- 新增 Header 工具菜单,统一承载语言切换、主题切换、界面配置和 GitHub 等入口,减少窄屏顶部空间占用。
- Dashboard 新增运营状态摘要和查询状态工具,支持独立处理加载、成功、空数据与失败重试状态。
- 设置页新增结构化 Skeleton 和局部错误恢复入口,加载或请求失败时仍保持稳定页面几何。
- Param Override 新增专用编辑器工具函数与测试,强化特殊字段类型、空键和同步字段的状态处理。
- Tiered Billing 编辑器补充本地化 token 提示、价格字段辅助组件和计算工具测试。
- README 新增多语言二次开发与社区鸣谢说明,公开自用二开项目适用的显示条件、临时授权范围和上游许可边界。
Improvements
- 统一 Responses usage 复制入口,避免非流式、流式和 Compact 在新增 token 明细时再次发生字段漂移。
- Gemini 候选 token 恢复改为汇总 TEXT、IMAGE、AUDIO 明细,并将 reasoning 独立计入 completion;原始 BillingUsage metadata 在估算过程中保持可追溯。
- Gemini 流式和非流式图片识别共用严格 MIME 判断,减少不同 handler 对同一媒体类型产生不同结算语义。
- Realtime 通过统一
BuildTieredTokenParams进入分阶段结算,缓存与音频变量遵循和文本请求相同的自动排除规则。 - OpenAI 音频接口通过统一归一化函数映射总量和细分 usage,降低 TTS/STT、流式/非流式之间的分支差异。
- DataTable 的桌面/移动判断从 viewport media query 调整为容器尺寸观察,侧栏、抽屉和中等宽度内容区中的表格更符合实际可用空间。
- 表格单元格不再依赖全局强制不换行;模型名、标签和其他长内容可按列契约换行,减少横向撑宽和内容裁切。
- 移动卡片列表完善选择状态、操作区和字段展示,分页与批量操作在窄屏下保持可用。
- 公开 Header 和应用 Header 统一移动端导航逻辑,语言、主题、配置、GitHub 与通知入口在不同断点下保持一致。
- 移动菜单在切换回桌面布局时会主动清理页面滚动锁,避免响应式切换后页面仍无法滚动。
- Dashboard 概览信息改用当前主题的语义色和现有卡片体系,减少固定深色、装饰网格和静态文案对首屏空间的占用。
- Dashboard 查询状态改由明确的辅助函数描述,替代复杂嵌套条件,加载、失败和局部数据状态更容易维护。
- 系统设置 Switch 行补齐
id、Label 关联、aria-describedby、错误提示和禁用原因,点击标签和键盘操作更加可靠。 - 设置页面在加载、失败和恢复过程中保留主要布局结构,减少内容跳动和整页空白。
- Ollama 模型对话框会取消过期请求、隔离不同渠道的异步响应,并在切换渠道或重新打开时重置删除状态。
- Param Override 专用编辑器拆分为更清晰的字段组件;输入 Label 与控件建立关联,
sync_fields在键为空时仍保留已选类型。 - 渠道编辑抽屉的导航、表单状态和转换逻辑进一步分离,减少大型组件内部的隐式状态耦合。
- Tiered Billing 编辑器将字段、辅助展示和计算逻辑分层,保留原有配置契约并改善后续扩展与测试能力。
- Markdown、分页、对话框、菜单、侧栏、Spinner 等共享组件统一部分可访问性和样式细节。
- 修正多个无效的
text-xsst样式类和零散的响应式样式问题,避免构建后样式静默失效。 - 多语言同步报告更新,减少法语、日语、俄语和越南语中直接回退英文的新增文案。
- Dashboard 查询工具测试改用 TypeScript 与 CI 均可识别的测试方式,避免
bun:test类型声明导致 GitHub Frontend checks 失败。 - 六种 README 的项目定位、二次开发说明和授权表述保持同步,明确临时授权只覆盖项目方有权授权的新增与修改部分。
Bug Fixes
- 修复 Claude 流式最终快照和
message_deltaJSON 未携带累计输出 token,导致日志、结算或客户端 usage 中output_tokens=0的问题。 - 修复 Responses 重新构造 usage 时丢失缓存创建、图片、音频、文本及输出 reasoning 明细的问题。
- 修复 Responses DTO 未接收官方
output_tokens_details,导致部分输出明细在反序列化阶段消失的问题。 - 修复 Gemini 仅因 reasoning 非零就跳过候选 token fallback,以及重建 BillingUsage 时丢失缓存、工具和 modality metadata 的问题。
- 修复 Gemini 图片 fallback 未标记
ImageTokens、混合文本图片漏算图片、已有细分值被估算覆盖和音频 inline data 被误识别为图片的问题。 - 修复 Realtime 分阶段表达式中的
cr、ai、ao永远为零,音频 token 也无法按表达式变量从p/c自动排除的问题。 - 修复 OpenAI 流式 TTS 只复制总 token、STT 未映射输入音频明细,以及 Responses 音频模型家族识别不完整的问题。
- 修复 MiniMax TTS 上游精确字符数只写入
TotalTokens、实际倍率结算仍使用本地估算的问题。 - 修复公开首页 Hero 网格在 320px、390px 等窄屏下被内容撑到视口之外,导致标题、说明和标签被横向裁切的问题。
- 修复任意 React Query 请求返回 HTTP 500 时全局跳转
/500,导致表单、筛选、分页和任务上下文丢失的问题。 - 修复 Dashboard 查询失败时缺少局部错误展示与重试入口的问题。
- 修复应用 Header 在移动端直接隐藏 TopNav,导致已实现的移动导航无法显示的问题。
- 修复移动菜单打开后切换到桌面宽度,
body滚动锁可能残留的问题。 - 修复表格只按视口宽度切换布局,侧栏展开后内容区已经过窄却仍渲染桌面表格的问题。
- 修复表格默认
whitespace-nowrap使长模型名、标签或描述撑宽容器的问题。 - 修复移动表格统一隐藏选择和批量操作,管理员在手机上无法完成批处理的问题。
- 修复设置 Switch 的可见 Label 未与控件关联,点击标签和辅助技术导航不可靠的问题。
- 修复设置页加载时只显示单行文字,导致页面结构大幅跳动且失败后缺少局部恢复的问题。
- 修复 Playground 将
auto/auto:*作为真实group参数请求模型,导致自动分组下模型列表为空、无法选择模型的问题。 - 修复 Ollama 模型对话框中旧渠道请求晚返回后覆盖当前渠道数据、删除状态未正确复位等异步竞态问题。
- 修复 Param Override 中部分专用字段的 Label 未关联控件,以及
sync_fields在 key 暂时为空时丢失所选类型的问题。 - 修复 Tiered Billing token 提示未完整本地化、部分状态计算在空值场景下不稳定的问题。
- 修复日语翻译插值格式异常和越南语
Save tiered billing、Tiered Billing、保存成功提示及 JSON 标签仍显示英文的问题。 - 修复 Dashboard 测试直接导入
bun:test,导致 GitHub Actions 执行tsc -b时找不到模块类型声明的问题。
Compatibility Notes
- 本预览版会改变部分异常 usage 的最终结算结果:修复后此前为零或被当作普通文本的输出、缓存、图片、音频和字符用量可能产生正确费用,请在升级前核对模型价格与表达式配置。
- Claude/Anthropic 流式客户端现在可能在最终
message_delta.usage.output_tokens中收到本地累计回填值;已有非零上游值不会被覆盖。 - Responses 内部日志和结算会保留更多
input_tokens_details、output_tokens_details和completion_tokens_details;依赖旧零值行为的对账脚本应同步更新。 - Gemini 在上游候选总量为零但存在可见输出时会使用本地估算;图片仍按每张 1400 token 估算。混合文本和图片会分别记录,最终候选总量为各 modality 之和。
- Gemini 上游已提供的非零 TEXT、IMAGE 或 AUDIO 明细优先于本地估算;音频 inline data 不会在缺少音频计量依据时被错误改按图片计费。
- Realtime
tiered_expr现在可使用cr、ai、ao,引用这些变量时会改变p/c的归一化结果;升级前应复核实时音频模型表达式。 gpt-4o-audio*、gpt-4o-mini-audio*、gpt-audio*或返回音频 token 明细的 Responses 请求会进入音频结算路径。- MiniMax TTS 的倍率结算改用上游
usage_characters;上游精确字符数与历史本地 token 估算存在差异时,升级后费用可能变化。 - 本预览版没有新增数据库字段或迁移要求,也没有改变上述前端模块使用的后端 API 数据格式。
- 普通 React Query 请求返回 HTTP 500 时不再自动跳转
/500;页面会保留当前上下文并显示局部错误与重试。依赖旧跳转行为的自动化测试需要更新。 - Playground 选择
auto或auto:*分组时会省略模型列表请求中的group参数,这是自动分组的预期行为;显式分组仍按原有参数请求。 - DataTable 的移动布局现在取决于表格容器宽度,而不是只看浏览器视口;侧栏、嵌套页面或窄内容区可能比以前更早切换为卡片列表。
- 移动表格可按页面配置暴露行选择和批量操作;请检查高风险批量操作的确认流程、权限和触控可用性。
- Header 的语言、主题、配置和 GitHub 入口在窄屏下会进入统一工具菜单;通知入口仍保留在应用 Header。
- Ollama 模型请求支持取消过期加载;快速切换渠道时,旧请求结果不会再更新当前对话框。
- Param Override、渠道编辑和 Tiered Billing 的内部组件结构已调整,但现有配置数据格式与后端接口保持不变。
- README 已增加二次开发、社区鸣谢与临时商用授权说明。使用、分发或二次开发前,请同时核对 AGPLv3、显示条件、临时授权适用范围以及 One API、New API 等上游项目的许可要求。
- 正式环境升级前建议重点复核 usage 对账、模型倍率、分阶段计费、Dashboard、系统设置、渠道编辑、Tiered Billing、Ollama、Playground、移动导航以及移动表格的失败重试和批量操作流程。
Verification
本预览版已完成以下针对性验证;正式发布前仍建议在最终 tag 和发布构建上重新执行:
go test ./relay/channel/gemini -count=1go test ./dto ./service -count=1go test ./relay/channel/claude ./relay/channel/openai ./relay/channel/minimax ./relay -count=1go vet ./relay/channel/claude ./relay/channel/openai ./relay/channel/gemini ./relay/channel/minimax ./dto ./service ./relay- Claude
OutputTokens缺失回填、上游非零值保留和message_delta.usage.output_tokensJSON 写回回归测试 - Responses 非流式、流式、Compact 多模态 usage 与官方
output_tokens_details回归测试 - Gemini reasoning+文本、纯图片、文本+图片、已有图片明细、已有音频明细和流式音频 MIME 分类回归测试
- Realtime
cr/ai/ao参数与p/c自动排除回归测试 - OpenAI 流式 TTS、STT 输入明细、Responses 音频模型家族及模型别名回归测试
- MiniMax 上游字符用量与本地估算 fallback 回归测试
cd web/default && bun run typecheckcd web/default && bun run build:check- Dashboard、Playground、Param Override 与 Tiered Billing 共 17 项针对性前端测试
cd web/default && bun run i18n:sync- 相关变更文件的 ESLint 与 Prettier 定向检查
git diff --check- 390px 与 1280px 浏览器视口回归检查
- 390px 首页验证
scrollWidth === innerWidth,确认无横向溢出 - 移动菜单打开后切换到桌面宽度,验证页面滚动锁可以正确清理
说明:当前仓库的全量
bun run lint与全量格式检查仍存在与本版本无关的历史基线问题,因此本稿不将其列为已通过项。正式版发布前仍建议在最终分支执行完整后端、前端和部署回归。Full Changelog: v1.0.4-preview.4...v1.0.4-preview.5
-
v1.0.4-preview.413 Jul 2026 pre-releaseRelease notes
Open source →[!WARNING] 发布阻断:Claude/Anthropic 流式输出 token 计费回归。 截至 2026-07-16,v1.0.4-preview.4 当前代码在 Claude/Anthropic 流结束时会正确解析顶层 CompletionTokens,但生成最终 BillingUsage 快照时遗漏 OutputTokens,导致用量日志中的 completion_tokens 可能为 0,输出 token 也可能未进入实际结算。
该问题按响应处理器而不是模型名称划分:Anthropic 原生、AWS Bedrock Claude、Vertex Claude 模式、Advanced Custom Anthropic Messages,以及通过 /v1/messages 复用 Claude 流式处理器的兼容渠道都可能受影响。Claude 非流式请求以及原生 OpenAI Chat、OpenAI Responses、Gemini 路径未发现同类问题。
在修复和完整回归通过前,不应将当前 v1.0.4-preview.4 用于需要准确计费的 Claude/Anthropic 流式生产请求;临时可强制 stream: false,历史受影响请求应结合上游 usage 记录进行对账。
重要升级说明
v1.0.4-preview.4 覆盖计费结算、GPT-5.6
cache_write_tokens缓存写入计费、Responses/Chat 跨协议转换、异步任务计费、渠道请求改写、日志审计、access token 生成与二次验证、前端富文本渲染、登录注册合规和多数据库兼容等关键路径。升级前建议先在测试环境验证主要模型调用、缓存创建价格、分阶段计费表达式、任务类渠道、用户额度变更、用量日志筛选、Playground、OAuth/注册登录、access token 重新生成、订阅重置和管理端渠道配置。如果部署使用 GPT-5.6、Responses API、缓存创建倍率或自定义计费表达式,请重点检查
cache_write_tokens是否按预期进入缓存创建费用;同时复核 Param Override、自动分组/自动路由、Redis 配额缓存、旧 MySQL/PostgreSQL 数据库和反向代理真实 IP 配置。Note
v1.0.4-preview.4 是预览版草稿,整理自当前分支中已合入的 v1.0.4 系列变更,并补充最近确认的 GPT-5.6 缓存写入计费、分阶段计费、日志审计、额度安全、密码重置和 access token 安全验证更新。发布前请以最终 tag、上游官方价格和实际验证结果为准。
Release Notes
GitHub 地址
https://github.com/MAX-API-Next/MAX-API/releases/tag/v1.0.4-preview.4
Highlights
- 补强 OpenAI Responses 与 Chat Completions 的双向兼容转换,覆盖普通响应、流式事件、工具调用、reasoning 文本、usage 聚合和跨协议 billing usage 恢复。
- 完善 OpenAI / Claude / Gemini 语义化
BillingUsage,结算时优先使用原始协议 usage,并保留 cache、cache write、image、audio、reasoning 等细分 token。 - 补齐 GPT-5.6 Responses usage 中
input_tokens_details.cache_write_tokens的计费链路,非流式、流式、compact 和 Responses/Chat 转换均会保留缓存写入 token,不再在跨协议后退化为普通输入 token 或被遗漏。 cache_write_tokens会归一为缓存创建 token:ratio 模式使用CacheCreationRatio,tiered_expr模式进入cc变量,并从基础输入 token 中扣除后单独计价,避免漏计或重复计费。- 引入统一 quota 饱和转换策略,避免超大计费结果发生 int32 wraparound;严格预扣费路径只拒绝真正越界值,允许精确
MaxInt32/MinInt32边界。 - 异步任务渠道新增更通用的 rate-card / generic billing 框架,支持按输入、输出、图片数量、时长、任务结果和渠道元数据计算费用。
- 任务类渠道 Param Override 在计费前生效,header override 会在 adaptor 默认值之后写入上游请求,局部配置错误保持本地失败而不触发无意义重试。
- Doubao、Ali/Kling/Wan、Gemini、Vidu、Vertex、Hailuo、Jimeng、Sora 等任务渠道补齐请求体构造、参数透传、计费和回调结果处理细节。
- 管理端渠道抽屉、模型/分组倍率编辑器、自动路由展示、OAuth 回调提示、订阅重置和用量日志筛选得到集中优化。
- Playground 增强选项持久化、清理历史、长输入和选区处理,减少常见交互中的状态丢失与布局问题。
- 富文本与 HTML 渲染路径继续收紧安全边界,统一用户可见内容展示并降低异常 Markdown/HTML 输入导致的前端崩溃风险。
- 日志审计字段写入更稳健,quota saturation 和 billing path 只在有效
admin_info容器中追加,不再覆盖异常字段或在 nil 目标上记录误导性 warning。 - 用户额度管理和密码重置流程补强安全边界:管理端额度保持在 JavaScript 可精确表示的整数范围内,密码写入失败时重置令牌仍可重试。
- access token 生成改为 POST 敏感操作并强制执行二次验证、禁缓存和关键操作限流;验证状态绑定当前用户,避免同一浏览器切换账号后继承旧验证结果。
- 无 2FA 或 Passkey 的普通用户可在
access_token专用作用域内使用账户密码完成重验证,同时继续优先使用已启用的 Passkey 或 2FA。
New Features
- 新增
service/openaicompat兼容层,用于 Responses request/response 与 Chat Completions request/response 互转。 - 新增 Gemini Responses adaptor,支持 Gemini 通道参与 Responses API 兼容路径。
- 新增
dto.BillingUsage协议快照结构,支持 OpenAI、Claude、Gemini usage 在跨协议转换后仍按原始语义结算。 InputTokenDetails新增cache_write_tokens字段和共享复制逻辑,支持在input_tokens_details、prompt_tokens_details与BillingUsage之间完整传递 GPT-5.6 缓存写入用量。- 新增
tiered_expr分阶段计费模式,单条表达式即可描述模型的基础价格、长上下文阶梯、缓存价格、媒体 token 价格和请求条件倍率。 - 新增分阶段计费可视化编辑器与表达式编辑器,支持价格档位、兜底档位、请求体/header/时间规则、实时费用预估、命中档位展示和 JSON 批量配置。
- 新增 GPT-5.4 Priority/Flex、Claude 长上下文与 Fast Mode、多模态和时段折扣等模板,管理员也可按实际上游价格创建其他模型表达式。
- 计费表达式支持
p、c、len、cr、cc、cc1h、img、img_o、ai、ao等变量,以及param()、header()和时间函数,可覆盖文本、缓存、多模态和请求级价格规则。 - 新增 quota math helper 和测试,统一 float、decimal、rounding 到 quota 的饱和处理。
- 新增 protected fetch client 与管理端模型拉取防护测试,用于统一 SSRF 边界和响应体关闭行为。
- 新增任务通用请求体构造、路径配置和协议配置工具,减少各任务 adaptor 重复实现。
- 新增任务通用计费模块和覆盖测试,用于图像、视频、音频等异步任务统一结算。
- 新增订阅重置入口和管理端对话框,便于管理员批量处理用户订阅状态。
- 新增用量日志 quota 区间筛选控件,普通日志和任务日志筛选栏都可按额度状态过滤。
- 新增自动路由/自动分组前端展示工具,模型价格页可解释自动链路的实际分组来源。
- 新增 OAuth 回调地址提示组件,帮助管理员检查第三方登录回调配置。
- 新增安全验证方式发现接口和作用域化密码重验证,前端可根据当前账户实际可用的 Passkey、2FA 或密码方式打开对应验证界面。
- 新增多语言文案,覆盖新增设置项、日志筛选、订阅操作、渠道表单和计费说明。
Improvements
- Responses 转 Chat 后会把
input_tokens_details映射回prompt_tokens_details,并在 BillingUsage 恢复时保留细分 input token,避免 cache write、cached、image、audio input 在结算中丢失;六类 input token 字段改由 DTO 共享映射统一维护,降低后续新增字段时跨路径漏同步的风险。 - Chat 转 Responses 会保留 usage 细节和 billing usage 快照,跨协议返回后仍能走统一计费入口。
- Claude / Gemini usage 恢复逻辑补齐 cache creation、cache read、thoughts/reasoning 和 modality token 映射。
- OpenAI
BillingUsage恢复会从input_tokens_details补齐prompt_tokens_details.cache_write_tokens,保证 GPT-5.6 Responses 转 Chat 后仍使用原始缓存写入数据结算。 cached_creation_tokens与cache_write_tokens作为同类缓存创建统计进行兼容归一化;两者同时存在时取较大值,不直接相加,避免同一批缓存写入被重复收费。- 分阶段计费使用
len判断上下文档位;len始终表示包含缓存 token 在内的完整输入长度,避免大量缓存命中后误进入较低的长上下文价格档位。 - 表达式会根据实际引用的变量自动从
p/c中排除已单独计价的缓存、图片和音频 token,减少基础 token 与细分类 token 重复计费。 - 预扣费会冻结模型名、表达式、请求条件、分组倍率和预计命中档位;结算时使用同一快照与实际 usage 重新计算,避免请求处理中途修改配置导致前后价格不一致。
- 用量日志会写入归一化后的
cache_write_tokens,分阶段计费结果还会记录 billing mode、表达式和命中档位,便于管理员核对缓存创建费用。 - 计费表达式 rounding 增加 quota 专用转换,降低浮点乘法和极端金额输入带来的边界风险。
- quota saturation 会写入日志
admin_info.quota_saturation,便于管理员追踪被截断的原始值和 clamp 类型。 - 预扣费和结算路径统一使用 quota helper,超大价格、倍率或 token 数不会因为整数溢出变成反向扣费。
- BillingSession 预扣费和 legacy 预扣费入口共用同一套 QuotaClamp / 负数 quota 校验,保持模型价格错误的状态码、错误码和 skip-retry 语义一致。
- 上游错误处理限制本地日志体积,保留排障信息同时减少异常响应占用内存。
- 流式扫描器和 ping 处理逻辑得到重构,减少空 chunk、ping frame 和异常 EOF 对流式 relay 的影响。
- API request 构造逻辑补充上下文、参数和 header 合并测试,降低高级自定义渠道回归风险。
- 渠道表单抽屉拆分更多字段状态和转换逻辑,复杂通道配置更容易维护。
- 分组倍率和模型倍率编辑器优化输入、验证和视觉反馈,减少配置错误。
- 模型价格可视化编辑器的空状态文案改为显式条件计算,搜索、未设置价格和默认空列表状态更容易维护。
- 自动路由显示会过滤不可见分组和重复分组,并保留旧配置 fallback。
- 用量日志 retry / empty-retry / quota 筛选逻辑更清晰,前端过滤和后端聚合语义保持一致。
- 用户、token、订阅和兑换码相关模型更新路径增加零值安全处理,避免局部更新意外覆盖会计字段。
- 管理端用户额度对话框增加安全整数校验、行内错误提示和多语言文案,增加、扣减或覆盖操作在提交前会检查输入值与计算结果。
- 密码重置验证码增加并发占用和提交语义:密码更新成功后才消费验证码,数据库写入失败或异常退出时释放占用并允许在有效期内重试。
- access token 对话框接入统一安全验证流程,并按实际可用性选择默认方式;仅启用 2FA 的用户不会再进入不可用的 Passkey 状态。
/api/verify同时按客户端 IP 和已认证用户 ID 限制关键验证请求,降低通过代理轮换扩大密码或验证码尝试次数的风险。- OpenAPI 补齐
POST /api/user/token、POST /api/verify请求体以及GET /api/verify/methods?scope=access_token的参数与验证方式枚举。 - 订阅、任务和日志模型增加 CAS / row-lock / 异步落库测试,降低并发状态回退风险。
- README 和多语言 README 调整为新的产品定位和能力描述,保持各语言文档同步。
Bug Fixes
- 修复 GPT-5.6 Responses 返回
cache_write_tokens时,部分非流式、流式、compact 或 Responses → Chat 路径没有把该字段带入最终PromptTokensDetails,导致缓存写入 token 可能按普通输入价格结算或未按缓存创建倍率计费的问题。 - 修复跨协议
BillingUsage恢复只保留 input token 总数和部分明细、遗漏cache_write_tokens,导致转换后的实际结算与上游原始 usage 不一致的问题。 - 修复 Responses 转 Chat / 跨协议后
BillingUsage恢复只保留 token 总数,导致 input token 细分项从结算视角消失的问题。 - 修复 strict quota 把精确
2147483647和-2147483648误判为 clamp 错误的问题。 - 修复
attachQuotaSaturationToOther在admin_info已存在但不是 map 时覆盖原值的问题。 - 修复
attachQuotaSaturation在other == nil时仍输出“已写入审计信息”语义 warning 的问题。 - 修复部分 OpenAI Responses / Chat 转换路径中 tool call id、reasoning、finish reason、usage 聚合和流式 done event 不一致的问题。
- 修复 Gemini 非 function tool、Responses relay 和 usage metadata 在跨协议路径中的兼容问题。
- 修复 Doubao 任务可选标量字段使用非指针类型时,显式
0/false可能在转发时被omitempty丢弃的问题。 - 修复任务 Param Override 在计费后才生效,导致实际上游请求与本地计费参数可能不一致的问题。
- 修复 task header override 不能稳定覆盖 adaptor 默认 header 的问题。
- 修复本地 Param Override 配置错误被当作可重试上游错误的问题。
- 修复异步任务回调和轮询结算中部分任务状态、费用、结果字段缺失或类型不一致的问题。
- 修复用量日志 retry 筛选、任务日志 quota 筛选和聚合读路径中的类型/边界问题。
- 修复富文本 HTML 渲染和 sanitizer 在部分异常输入下的展示或安全边界问题。
- 修复 Playground 清空历史、长文本输入、选项恢复和请求参数同步中的前端状态问题。
- 修复管理端用户设置、用户资料、余额调整和 token 更新中零值字段无法正确保存或可能被误覆盖的问题。
- 修复管理员可把用户额度设置到
int64上限,导致超过Number.MAX_SAFE_INTEGER后前端展示和回传值发生精度丢失的问题。 - 修复密码重置先销毁验证码再更新密码,导致密码哈希或数据库写入失败后重置链接提前失效的问题。
- 修复 access token 通过 GET 生成且缺少禁缓存与二次验证,可能被缓存、预取或误重放的问题。
- 修复安全验证 session 只记录时间戳,账号 A 验证后在同一浏览器会话登录账号 B 时,账号 B 可能继承验证状态的问题。
- 修复未启用 2FA 或 Passkey 的普通用户无法生成 access token,以及仅启用 2FA 时前端仍默认选择 Passkey 的问题。
- 修复
/api/verify仅按 IP 限流,攻击者可通过切换代理地址扩大同一账户验证尝试次数的问题。 - 修复管理用户接口收到非正用户 ID 时可能形成空条件查询并错误命中首条用户记录的问题。
- 修复订阅重置、订阅弹窗和订阅 delta 返回值在管理端交互中的状态同步问题。
- 修复模型列表、分组显示和自动链路价格页在自动分组配置缺失或别名分组存在时的展示问题。
- 修复部分数据库迁移、命名锁、quota bigint 和老库兼容路径在 MySQL/PostgreSQL/SQLite 上的差异问题。
- 修复日志审计写入在异常
admin_info结构下可能丢失已有审计元数据的问题。 - 修复
jsonwrapcheckallowlist 与当前代码不一致,减少业务代码直接调用标准 JSON marshal/unmarshal 的回归空间。
Compatibility Notes
- 任务类渠道如果依赖 Param Override,请注意本版本会在计费前应用最终请求参数;升级后计费结果会更贴近实际发送给上游的 payload。
- header override 现在会在 adaptor 默认 header 后生效;如果旧配置依赖默认值覆盖自定义值,需要重新检查渠道配置。
- 本地 Param Override 配置错误不再进入重试链路;这类错误应作为配置问题修正,而不是依赖自动重试。
- Responses API 兼容路径会尽量保留原始协议 usage;如果外部系统读取 usage 字段,请同时关注
prompt_tokens_details、input_tokens_details和billing_usage。 - GPT-5.6 上游可能在
input_tokens_details.cache_write_tokens返回缓存写入量;该值会按缓存创建 token 处理。ratio 模式需要正确配置CacheCreationRatio,表达式模式应使用cc为缓存写入单独定价。 - 如果上游同时返回
cached_creation_tokens和cache_write_tokens,系统会取两者中的较大值作为归一化缓存创建总量,不会相加;外部账单对账工具应采用相同口径。 - 计费表达式中的系数是每 100 万 token 的实际美元价格,不再隐含旧倍率表的
/2、completion multiplier 或其他换算;从 ratio 模式迁移时不能直接复制旧倍率数值。 - 未显式把模型切换为
tiered_expr时,现有模型继续使用ModelRatio/ModelPrice计费;启用后该模型的预扣费与实际结算以表达式和请求条件为准。 - GPT/OpenAI usage 的
prompt_tokens通常包含缓存和媒体 token;表达式只有在引用cr、img、ai等变量时才会自动拆分对应 token。长上下文条件应使用len,不要使用拆分后的p。 - strict quota 只拒绝超出 int32 可表示范围的值;精确边界值不再记录 saturation 或返回错误。
- 管理端用户额度调整接口只接受不超过
9007199254740991的正整数变更量,加减结果必须保持在 JavaScript 安全整数区间,覆盖值必须位于0..9007199254740991。历史超范围额度可通过覆盖操作恢复到安全范围,依赖更大int64额度的外部管理脚本需要同步调整。 - 预扣费入口遇到 quota clamp 或负数预扣费时仍返回
model_price_error、HTTP 400 和 skip-retry;本次只是统一校验来源,不改变外部错误契约。 - quota saturation 审计只会写入 map 形态的
admin_info;如果调用方传入了异常类型,已有值会被保留但不会追加 saturation 详情。 - 异步任务通用计费会让部分历史上未精确计费的任务按 rate-card 细则结算;建议先在测试环境核对常用任务模型的价格配置。
- 自动路由展示更贴近实际配置,但只展示当前可见分组;隐藏分组不会被前端强行暴露。
- 用量日志筛选项更细,旧的 retry 过滤理解应区分普通 retry 与 empty retry 等子类型。
- access token 生成接口已从
GET /api/user/token改为POST /api/user/token;依赖旧接口的脚本、SDK 或自动化客户端必须同步调整请求方法,旧 GET 路由不再可用。 - 密码重验证仅作为
access_token作用域的回退方案,并且只在账户没有启用 2FA 和 Passkey 时提供;密码验证结果不能用于其他敏感操作。 PasswordLoginEnabled=false只禁止新的密码登录,不会使已登录账户现有的密码凭证失效;符合回退条件的用户仍可用当前密码完成 access token 重验证。- 多数据库迁移继续要求 SQLite、MySQL 和 PostgreSQL 同时兼容;升级前建议备份数据库,并在老库上先跑启动迁移验证。
Verification
发布前建议按最终 tag 和发布分支重新执行并更新结果:
go test ./common ./service ./service/openaicompat -count=1go test ./dto ./service ./service/openaicompat ./relay/channel/openai -run "Test(CopyInputTokenDetails|CalculateTextQuotaSummaryPreservesResponsesInputDetailsThroughBillingUsage|CacheWriteTokensTotal|ResponsesResponseToChatCompletionsResponse)" -count=1go test ./pkg/billingexpr -run "Test(Len|Cache|ComputeTieredQuota|RunExpr)" -count=1go test ./relay/helper -run "Test(ModelPriceHelperTiered|ResolveIncomingBillingExprRequestInput)" -count=1go test ./service -run "Test(TryTieredSettle|BuildTieredTokenParams)" -count=1go test ./... -count=1go test ./common ./controller ./model -count=1go test ./relay/helper -count=1go test ./service -run TestAttachQuotaSaturation -count=1go test ./service -run TestPreConsumeValidationSharedByBillingAndQuota -count=1go test ./common -run TestQuotaFromFloatStrictAcceptsExactInt32Boundaries -count=1go test ./service -run TestCalculateTextQuotaSummaryPreservesResponsesInputDetailsThroughBillingUsage -count=1go test ./controller ./model ./middleware ./relay/helpergo test ./controller ./middleware ./router -count=1go test ./router -run 'Test(UniversalVerifyRateLimitFollowsUserAcrossIPs|SecureVerificationOpenAPIIncludesScopeAndRequestBody)' -count=1go test ./router -run TestUniversalVerifyRateLimitFollowsUserAcrossIPs -count=3go test ./relay/channel/openai ./relay/channel/gemini ./relay/channel/claude ./relay/channel/advancedcustomgo test ./relay/channel/task/taskcommon ./relay/channel/task/doubao ./relay/channel/task/aligo run ./tools/jsonwrapcheckcd web/default && bun run typecheckcd web/default && bun test src/features/users/lib/quota-safety.test.tscd web/default && bun test tests/secure-verification-method-selection.test.tscd web/default && bun run i18n:synccd web/default && bun testgit diff --check -- service/billing.go service/pre_consume_quota.go web/default/src/features/system-settings/models/model-ratio-visual-editor.tsxgit diff --check
Full Changelog: v1.0.3...v1.0.4
-
v1.0.4-preview.310 Jul 2026 pre-releaseRelease notes
Open source →Warning
重要安全与稳定性修复
v1.0.4-preview.3 聚焦管理端 fetch、登录态绑定、Redis 配额缓存、验证码消费、代理信任边界、用户余额字段兼容、MySQL 老库注册兼容和用户通知设置的安全边界。受影响部署可能在特定管理操作、OAuth 绑定、密码重置/注册、高并发缓存更新、反向代理配置、用户余额调整或旧库用户注册场景中暴露 SSRF、进程 panic、缓存扣减丢失、验证码复用、IP 限流绕过、余额上限异常、弱邮箱校验或注册失败等风险。
建议升级后重点验证渠道模型拉取、OAuth/第三方账号绑定、密码重置、用户注册、老 MySQL 数据库上的新用户注册、用户通知邮箱保存、管理端用户余额添加/减少/覆盖、充值码兑换并发处理、模型请求限流、站点与品牌顶部导航设置、模型广场自动链路分组展示,以及 Redis 启用时的用户/token 配额缓存更新。
Note
当前 MAX API 分为正式版和 Preview 预览版。Preview 预览版用于提前开放修复和能力,便于在真实环境中验证兼容性、稳定性和安全性;正式版将在对应 Preview 预览版稳定运行后发布。
Release Notes
GitHub 地址
https://github.com/MAX-API-Next/MAX-API/releases/tag/v1.0.4-preview.3
Highlights
- 加固管理端渠道模型拉取接口,
/api/channel/fetch_models会按系统 fetch setting 执行 SSRF URL 校验,并通过受保护 HTTP client 发送请求。 - 修复 OAuth、GitHub、Discord、OIDC、WeChat、LinuxDo、Telegram 和邮箱绑定路径中直接
id.(int)的 panic 风险,兼容 JSON session 后端反序列化出的数值类型。 - 将 Redis 普通计数和用户/token 配额 hash 增量更新改为 Lua 原子脚本,避免 TTL 检查和增量写入之间的 TOCTOU 窗口。
- 收紧通知邮箱格式校验,拒绝
a@、@b、@.、无点域名和带展示名的非纯邮箱输入。 - 优化充值码兑换的用户级锁生命周期,锁在无引用后会从内存 map 清理,避免长期运行中按 user id 持续增长。
- 清理
controller/channel.go中已迁移到common.*JSON wrapper 的历史 allowlist 条目,保持jsonwrapcheck基线与当前代码一致。 - 将“排行榜”可见性和登录要求设置合并到“站点与品牌 - 顶部导航”,让顶部导航相关入口在同一个设置区维护。
- 模型广场价格页会展示管理员配置的自动链路分组,以及自动路由别名到真实计费分组的处理顺序。
- 加固验证码一次性消费语义,密码重置 token 会在校验通过时原子删除,注册成功后也会消费邮箱验证码,避免同一验证码在有效期内重复提交。
- 收紧默认 trusted proxy 范围,仅默认信任 loopback;真实反向代理地址需要通过
TRUSTED_PROXIES显式配置,降低伪造X-Forwarded-For绕过 IP 限流的风险。 - 将用户余额、已用额度和邀请额度相关列升级为
bigint,并放宽管理端 quota 覆盖和增加操作的 32-bit 上限,解除约 4295 显示余额的人工操作天花板。 - 修复 MySQL 老数据库用户注册时命名锁结果扫描可能访问不存在的
null_int64表,导致注册失败的问题。 - 补强 MySQL 用户注册命名锁释放校验,
RELEASE_LOCK()返回0或NULL时会明确报错,不再被误判为释放成功。 - 修正内存模式下的模型成功率限流,失败请求不再消耗“成功请求”预算。
- 限制上游错误响应体读取大小,避免异常 upstream 返回超大错误体时占用过多内存。
- 在 model 层拒绝删除 root 用户,避免未来绕过 controller 角色检查的调用路径误删最高权限账号。
New Features
- 新增 controller 层 session id 解析 helper,统一处理
int、int64、float64和字符串形式的 session user id。 - 为管理端模型拉取 SSRF 防护新增回归测试,覆盖私网
base_url被拒绝的场景。 - 为 session 数值兼容、通知邮箱格式和充值锁清理补充聚焦测试。
- 新增验证码“验证并删除”原子 helper,供密码重置等一次性凭证场景复用。
- 新增内存限流器只读检查能力,用于先判断成功率预算、成功后再记录。
- 新增
sql.NullInt64底层 SQL 行扫描回归测试,覆盖 MySQL 注册写锁结果使用的1和NULL返回值。 - 新增 MySQL 命名锁成功状态判断测试,覆盖
1、0和NULL三类返回值。 - 顶部导航设置同屏管理“模型广场”和“排行榜”的展示与登录要求,保存时分别更新
HeaderNavModules与RankingsModule。 - 模型广场分组筛选新增自动链路说明卡片,帮助管理员和用户理解
auto_routes的真实计费分组链路。 - 为 trusted proxy 默认值、验证码一次性消费、模型成功率限流、root 用户删除保护和上游错误体截断补充回归测试。
Improvements
FetchModels拼接/v1/models前会裁剪base_url末尾斜杠,避免生成重复斜杠路径。FetchModels在读取响应前提前注册defer response.Body.Close(),错误状态码也会释放响应体。- Redis 增量脚本保留原有语义:只有仍存在且带 TTL 的缓存 key 才会更新,并在同一 Redis 脚本中保留剩余 TTL。
- OAuth 绑定类接口在 session id 缺失或格式异常时返回 API 错误,不再让类型断言 panic 影响进程稳定性。
- 通知邮箱保存会先裁剪首尾空白,再以标准邮箱地址入库,减少用户输入差异。
- 密码重置 token 在密码写库前完成消费,即使后续 DB 操作失败,也不会留下可被并发复用的重置凭证。
- 注册流程在用户创建成功后消费邮箱验证码,保持验证码与实际注册结果一致。
- 访问旧的
/system-settings/site/rankings设置路径会自动跳转到/system-settings/site/header-navigation,避免历史书签进入无效设置页。 - 顶部导航保存现在并行提交普通导航模块和排行榜模块,并统一走设置页错误处理。
- 模型广场自动链路展示会过滤空分组、重复分组和当前列表不可见分组,并在没有
auto_routes配置时继续使用 legacyauto_groupsfallback。 - MySQL 邮箱归一化写锁改为通过
database/sql的Row().Scan接收GET_LOCK/RELEASE_LOCK结果,避免 GORM 将sql.NullInt64误当作模型表解析。 - MySQL 命名锁获取和释放共用同一个成功状态判断,只有返回有效的
1才视为锁操作成功。 - 模型成功率限流不再使用临时计数 key 试探容量,避免失败请求污染成功预算。
- MySQL/PostgreSQL 启动迁移会检查用户余额相关列的现有类型,只在仍为非
bigint时执行列类型调整;SQLite 保持原有兼容路径。 - root 用户删除保护下沉到
model.User.Delete/HardDelete,调用方只传 user id 时会先读取现有角色再判断。 - 上游错误响应超过 1 MiB 时会截断并在错误信息中标记,保留排障上下文同时控制内存占用。
Bug Fixes
- 修复管理端
FetchModels接收请求体base_url后使用裸http.Client{}直接请求,绕过项目 SSRF 防护的问题。 - 修复
FetchModels使用直接json.NewDecoder,以及渠道密钥处理和 Ollama 拉取流中直接json.Marshal/json.Unmarshal的项目规范偏离问题。 - 修复第三方账号绑定路径中 session id 如果由 JSON 后端恢复为
float64会触发 panic 的问题。 - 修复邮箱绑定路径同样直接断言 session id,可能在异常 session 类型下 panic 的问题。
- 修复 Redis
RedisIncr在 TTL 读取后 key 状态变化时可能静默跳过计数更新的问题。 - 修复用户/token 配额缓存使用的
RedisHIncrBy存在同类 TTL TOCTOU 竞态的问题。 - 修复通知邮箱只检查是否包含
@,导致明显非法邮箱也能保存的问题。 - 修复
topUpLocks按 user id 缓存锁对象且不清理,长期运行后可能持续增长的问题。 - 修复密码重置 token 先校验、后删除导致两个并发请求可能同时通过校验并写入不同新密码的问题。
- 修复注册成功后邮箱验证码仍保留到过期时间,可能被同一邮箱在窗口期内重复提交的问题。
- 修复“排行榜”设置与顶部导航设置分散在不同站点子页,导致管理员配置顶部导航入口时需要跨区维护的问题。
- 修复模型广场把缺失的
auto_routes当成空数组后,旧版auto_groups自动分组 fallback 可能不再展示的问题。 - 修复使用老 MySQL 数据库注册用户时,GORM 扫描
sql.NullInt64可能生成null_int64表查询并返回Error 1146 (42S02): Table '...null_int64' doesn't exist的问题。 - 修复 MySQL
RELEASE_LOCK()返回0或NULL时仍被当作释放成功的问题,避免锁状态异常被静默吞掉。 - 修复管理端用户余额在数据库列仍为
INT时,最终 quota 可能受2147483647quota units(约 4295 显示余额)限制的问题。 - 修复用户余额、已用额度和邀请额度相关字段在 MySQL/PostgreSQL 老库中仍保留
INT类型,导致高额度用户可能被截断、溢出或写入失败的问题。 - 修复默认 trusted proxy 包含 RFC-1918 / link-local 私网段时,处在受信任私网来源的请求可伪造
X-Forwarded-For绕过 IP 限流的问题。 - 修复内存模式下模型成功率限流把失败请求也计入成功请求预算的问题。
- 修复上游错误响应体直接
io.ReadAll,异常 upstream 返回超大错误体时可能放大内存占用的问题。 - 修复
model.Delete/HardDelete只依赖 controller 层保护,未来直接调用 model 方法时可能误删 root 用户的问题。
Compatibility Notes
- 管理端模型拉取现在受全局 fetch setting 约束。若部署确实需要从私网地址或非默认端口拉取模型列表,需要在 fetch setting 中显式允许对应私网 IP、IP 白名单或端口。
- Redis 配额缓存更新仍只作用于带 TTL 的缓存 key;无 TTL 或不存在的 key 继续保持不更新,避免改变缓存写入边界。
- OAuth/session id 解析现在接受 JSON session 常见的
float64数值,但仍拒绝空值、零值和无法解析的类型。 - 通知邮箱现在要求纯邮箱地址;带展示名的
Name <[email protected]>不再接受,用户应保存[email protected]。 - 充值码兑换仍保持同一用户并发互斥;锁清理只发生在当前引用全部释放后,不改变并发拒绝语义。
- 验证码和密码重置 token 现在是一旦成功校验即消费;用户重复提交同一验证码或重复打开同一重置链接会得到无效结果,需要重新发起验证码或重置邮件。
- MySQL 部署不需要、也不应新增
null_int64表;该错误来自注册写锁结果扫描方式,升级代码并重启后即可消除对应假表查询。 - 如果 MySQL 报告命名锁未被当前连接持有或锁状态不可确认,注册写锁释放会返回显式错误;这类情况应按连接或数据库锁状态异常排查,而不是忽略。
- 默认
TrustedProxies不再包含私网网段。部署在 Nginx、Cloudflare Tunnel、内网 LB 或容器网络后方时,应通过TRUSTED_PROXIES配置真实代理 IP/CIDR,否则ClientIP()会回退到直接连接来源。 - “站点与品牌 - 排行榜”旧 section 会重定向到“站点与品牌 - 顶部导航”;外部脚本或书签若直接打开旧 URL,建议更新到
/system-settings/site/header-navigation。底层RankingsModuleoption 仍独立保存。 - 模型广场只展示当前可见分组内的自动链路;未配置
auto_routes的部署继续使用旧auto_groupsfallback。 - 管理端 quota 覆盖仍拒绝负数,quota 增加仍必须为正数;MySQL/PostgreSQL 老库会在启动迁移中把
users.quota、users.used_quota、users.aff_quota和users.aff_history转为bigint,不再以2147483647quota units 作为业务上限。升级前建议备份数据库,并确认这些列没有自定义类型约束。 - 内存模式的模型成功率限制现在只统计 HTTP 状态码小于 400 的请求;如果部署依赖失败请求也消耗成功预算,需要改用总请求数限制表达该策略。
- 上游错误响应体超过 1 MiB 时不会完整保留在错误信息和调试日志中,排查异常 upstream 时可结合上游日志查看完整错误体。
- root 用户无法通过 model 层软删除或硬删除;需要处理最高权限账号时应先降级或迁移 root 身份。
Verification
go test ./controller -run "Test(FetchModelsRejectsPrivateBaseURL|SessionUserID|NormalizeNotificationEmail|TopUpLock|UpdateUserSettingPreservesUnrelatedSettings|AdminReset.*RequiresPaymentCompliance)$"go test ./controller -run TestQuotaBoundsValidation -count=1go test ./model -run "TestScanNullableInt64UsesSQLRow|TestMySQLNamedLockResultSuccessRequiresOne|TestInsertRejectsConcurrentDuplicateEmailMySQL" -vgo test ./model -run "Test(UserUpdateDoesNotOverwriteAccountingFields|UserUpdatePersistsZeroValueProfileFields|UserUpdateDoesNotClearEmailFromLoadedPartialUpdate|UpdateUserSettingOnlyUpdatesSetting)$" -count=1go test ./model -run "Test(WaitPendingLogQuotaDataDrainsEnqueuedWork|EnqueueLogQuotaDataAfterShutdownPersistsSynchronously|Record.*QuotaDataAsync)$"go test ./relay/helper -run "TestStreamScanner|TestNewStreamScanner|Test.*Ping"cd web/default && bun run typecheckgo test ./commongo test ./middlewarego test ./servicego test ./modelgo test ./controllergo test ./common ./controller ./model ./relay/helpergo run ./tools/jsonwrapcheckgit diff --check
Full Changelog: v1.0.4-preview.2...v1.0.4-preview.3
- 加固管理端渠道模型拉取接口,
-
v1.0.4-preview.207 Jul 2026 pre-releaseRelease notes
Open source →Warning
⚠️ 严重安全与计费风险警示
本次 v1.0.4-preview.2 优先处理 new-api 近期暴露和修复的一组高危问题,并补齐 MAX API 二次开发路径中的本地扩展风险。受影响部署可能出现账号归属异常、邮箱重复或密码重置歧义、极端参数下 quota 溢出或错误扣费、SSRF 防护绕过、客户端断流后继续消耗上游流量,以及异步任务结算记录不一致等问题。生产环境建议优先升级,并在升级后重点验证账号注册/邮箱绑定/找回密码、充值回调、文本/工具/视频计费、受保护下载/代理、流式响应和异步任务退款/结算。
/\ /!!\ /____\ SECURITY / BILLING本预览版重点覆盖:账号、邮箱和密码安全硬化;计费数量溢出和 quota 饱和转换;SSRF protected fetch、重定向和拨号链路校验;流式断连后的 stale write 与 goroutine 清理;异步任务差额结算 quota 持久化;以及 Go 安全依赖升级。若基于当前开发分支自行构建,请先确认前端 typecheck、后端目标测试和
jsonwrapcheck均通过后再发布。Note
当前 MAX API 分为正式版和 Preview 预览版。Preview 预览版用于提前开放新能力和修复,便于在真实环境中验证兼容性、稳定性和安全性;正式版将在对应 Preview 预览版稳定运行 1 周后正式发布,以保障系统安全性和可靠性。
Release Notes
GitHub 地址
https://github.com/MAX-API-Next/MAX-API/releases/tag/v1.0.4-preview.2
Highlights
- 优化 Playground 输入区在窄屏、长提示词和长模型名场景下的布局稳定性,减少底部工具栏、模型选择器和发送按钮挤压或溢出。
- 增强通用视频任务结果 URL 解析能力,兼容 OpenAI Video 风格的
metadata.url返回结构,避免已完成任务被误回退为本机/content代理地址。 - 增加服务优雅关闭,收到
SIGINT/SIGTERM后会等待正在处理的请求结束;如果等待超时会强制关闭活跃连接,再继续看板 quota cache 落库和退出清理,降低重启时 SSE 中断、看板数据丢失和清理阶段并发残留风险。 - 加固用户资料和个人设置更新路径,避免高并发下旧用户快照覆盖
quota、used_quota、request_count等计费字段。 - 提升上游兼容性:补齐 Ollama 非流式
tool_calls响应、Wan2.7 i2vinput.media请求格式,以及认证守卫 401-only 会话失效处理。 - 进一步加固视频任务请求解析和计费判定,保留显式
duration: 0、修正seconds/duration、size/aspect_ratio、model/model_name的优先级,并避免视频输入漏判。 - 同步 new-api rc.18 账号安全、SSRF、quota 溢出、流式断连和异步任务差额结算等高危修复,补齐 MAX API 自有任务计费和 rate card 扩展路径的防护。
- 本预览版也包含此前已覆盖的 new-api 风险修复:用户资料/设置更新不再覆盖计费字段、优雅关闭超时会强制关闭活跃连接、认证守卫只在 401 时清理登录态、Ollama/Wan2.7 兼容路径和视频任务零值字段处理继续保持生效。
- 优化渠道编辑抽屉,高级设置导航可定位到真实配置区;新建渠道切换类型时会清理不属于新类型的
base_url/other默认字段,编辑已有渠道时保留已保存配置。 - 引入多自动链路配置,管理员可在同一分组配置
auto、auto:fast、auto:cheap等多条具名自动链路,并为每条链路独立设置展示名称、启用状态、用户可选状态和真实分组顺序。 - 加固自动链路权限边界:用户只能在新建/更新令牌时选择可见且可用的自动链路,默认自动链路必须保持启用,已签发的隐藏链路令牌仍按运行时兼容策略继续解析。
- 继续加固账号邮箱安全边界:MySQL 注册/绑定路径改用可索引标准化邮箱和连接级命名锁,Creem 充值回调也不再绕过邮箱标准化、唯一性检查和事务保护。
- 强化流式、任务 header 和使用日志统计路径:SSE ping 写入恢复超时保护,任务请求
{api_key}占位符在直接调用路径也能初始化渠道密钥,重试用量统计不会再混入充值或系统日志 quota。 - 补齐本轮 review follow-up:任务时长解析、图片
n校验、流式 helper 空上下文保护、quota filter 路由枚举和分组倍率查询统一走共享/归一化路径,减少前后端校验漂移。
New Features
- 通用视频任务默认结果 URL 路径新增
metadata.url、metadata.video_url、metadata.output_url以及data.metadata.*兼容路径。 - Playground 输入组件补充更严格的宽度约束和自动换行能力,长文本、长模型名或长分组名不会再撑开输入面板。
- 阿里万相任务新增
wan2.7-i2v、wan2.7-t2v模型入口;wan2.7-i2v会自动将image、images、input_reference或显式input.media映射为新协议input.media。 - Ollama 非流式响应现在会把上游
tool_calls转换为 OpenAI 兼容的message.tool_calls,并返回finish_reason: "tool_calls"。 - 服务关闭超时时间可通过
SHUTDOWN_TIMEOUT_SECONDS配置,默认 120 秒。 - 看板 quota cache 退出前保存等待时间可通过
QUOTA_DATA_CACHE_SAVE_TIMEOUT_SECONDS配置,默认 30 秒,避免缓存落库无限阻塞进程退出。 - 渠道编辑高级设置增加左侧子区域定位体验,可快速跳转到路由策略、覆盖规则、视频任务协议、响应映射、字段透传、额外设置和上游模型检测等配置区域。
- 分组倍率设置新增
AutoGroupRoutes自动链路配置,支持default_route、routes[].enabled、routes[].user_selectable和每条链路的真实分组顺序。 - 用户分组、令牌、定价详情和性能统计接口支持返回和识别多条自动链路;定价详情页会展示每条可用自动链路实际命中的分组链。
- 使用日志新增 quota 筛选维度,支持按全部、异常、零扣费和负扣费过滤普通日志与任务日志,并同步到 URL 查询参数和后端统计接口。
Improvements
- Prompt 输入框和通用输入组增加
min-width: 0、最大宽度约束和长词换行策略,提升复杂文本输入时的响应式表现。 - Playground 底部工具区支持换行,附件、联网搜索、清空历史、模型/分组选择和发送/停止按钮在较窄宽度下会更稳定排列。
- 模型和分组选择按钮增加桌面端最大宽度限制,保留移动端图标式入口,同时避免长名称影响右侧操作按钮。
- 通用视频任务完成结果优先读取上游或代理返回的实际媒体 URL;只有确实没有直接结果 URL 时,才继续使用
/v1/videos/{task_id}/content兜底地址。 - 看板 quota logging 改为同步写入内存聚合缓存,配合退出前 flush,减少进程关闭前日志聚合丢失的窗口。
- 用户设置更新新增独立的
UpdateUserSetting路径,只更新setting字段和对应缓存;资料更新后的 Redis 用户缓存只刷新非 quota 字段,并同步刷新Role,避免权限缓存滞后。 - 通知偏好保存现在以现有
setting为基底,只覆盖通知相关字段,保留语言、侧边栏模块和扣费偏好等其它用户设置。 - 认证路由守卫仅在
getSelf返回 401 时清理本地登录态;网络错误、超时或 5xx 不再直接踢出登录,也不会继续用本地旧登录态静默放行。 - 通用视频任务默认结果 URL 路径生成逻辑收敛为共享 leaf/prefix 组合,降低后续维护时漏加路径的风险,同时保持当前默认路径顺序不变。
- 用户和 Ollama 相关 JSON 编解码继续迁移到项目统一
common.*wrapper,并清理对应jsonwrapcheckallowlist。 - 任务请求 DTO 的可选
duration改为指针字段,客户端显式传入duration: 0时不会被omitempty静默丢弃。 - 通用任务请求解析统一字段优先级:显式
model优先于model_name、size优先于aspect_ratio、seconds优先于duration,嵌套parameters.duration会同步补齐秒数字段以保持行为一致。 - 用户资料和设置更新后的 Redis 写入改为 best-effort;数据库更新成功后,临时缓存写入失败只记录系统日志,不再让调用方误以为 DB 更新失败。
- 管理员覆盖用户 quota 后会主动失效用户缓存;缓存失效失败只记录日志并继续返回成功,避免 Redis 短暂异常影响已提交的 quota 覆盖操作。
- 主 HTTP 服务启动时会先完成端口绑定,再打印启动成功日志;如果端口被占用,会直接报告绑定失败,减少运维日志误判。
- 主 HTTP 服务优雅关闭超时后会调用强制关闭,确保活跃连接先结束,再进入 quota cache 保存和后续资源清理。
- Playground 在模型或分组不可发送时,重新生成和编辑后提交会给出明确提示,而不是静默无响应。
- Wan2.7 i2v 的
input.media归一化会按媒体类型补齐缺失的首帧、尾帧和驱动音频;即使请求已显式携带部分media,也不会丢弃同时提供的last_frame_url或audio_url。 - 新建渠道时切换类型会按新类型重置
base_url/other的类型专属默认值,避免 Vertex、Coze、讯飞、火山等类型之间切换时残留旧字段。 - 高级设置滚动监听不再被动展开折叠面板,也不会把滚动触发的状态写入本地偏好;只有用户点击导航、校验错误或手动开关时才改变展开状态。
Channel Extra Settings子导航的已配置状态和滚动锚点现在覆盖代理地址、系统提示词和系统提示词拼接模式等真实额外设置字段,避免只配置这些字段时导航提示和定位不一致。AutoGroups继续作为默认自动链路的兼容字段保留;保存AutoGroupRoutes时会自动派生默认链路分组,旧数组格式也会自动归一化为auto默认链路。- 运行时路由、模型列表、渠道选择、跨分组重试和性能统计统一识别
auto:<name>形式的自动链路键,不再只特殊处理硬编码auto。 - 令牌创建表单在启用默认自动分组时会使用当前配置的默认自动链路,而不是固定使用
auto。 - 自动链路编辑器新增重复 key、无效 key、空分组和禁用默认链路的即时提示,避免保存按钮无反馈或产生不可用配置。
- 自动链路相关前端文案已补齐到 zh/en/fr/ja/ru/vi;新增法语文案同步补齐重音和撇号。
- option 批量保存会在写入数据库前预校验会影响运行时状态的配置项,包括
AutoGroups、AutoGroupRoutes、ModelRatio、PayMethods、状态码规则和任务计费 rate cards,避免提交后才发现运行时刷新失败。 - 账号安全路径会统一裁剪用户名、标准化邮箱大小写,并在注册、OAuth 创建、邮箱绑定和密码重置入口做唯一性/歧义检查,降低历史重复邮箱或大小写邮箱造成的账号归属风险。
- 计费 quota 计算新增饱和转换,覆盖文本计费、工具调用计费、图片数量、音频估算、视频任务
seconds/duration、Kling 任务结果、通用 rate card 和 tiered billing 取整路径,避免极端输入下出现 int 溢出、负 quota 或错误扣费。 - SSRF 保护扩展到受保护 fetch 客户端的重定向和拨号阶段;启用域名 IP 过滤时,会校验 DNS 解析结果并直连已验证 IP,避免重定向或 DNS rebinding 绕过 URL 级校验。
- 流式响应写入增加 write deadline,客户端断开后会优先关闭 upstream body 并停止 ping/data/scanner goroutine,减少 stale write、长时间阻塞和上游流量继续消耗。
- 异步任务差额结算后会把实际
quota回写任务记录,避免退款、列表展示或重复结算继续读取旧预扣 quota。 - Go 安全依赖升级到 upstream rc.18 对应版本并额外补齐
x/crypto安全更新:golang.org/x/crypto v0.52.0、golang.org/x/image v0.41.0、golang.org/x/net v0.55.0,并同步更新相关x/sys、x/text依赖。 - 邮箱查询改为使用
normalized_email索引列,避免 MySQL 上LOWER(email)谓词导致全表扫描和过大锁范围;写入路径会自动维护标准化邮箱。 - MySQL 邮箱写入使用同一底层连接持有
GET_LOCK,直到事务提交或回滚后才释放,覆盖普通注册、OAuth 注册、邮箱绑定和 Creem 充值邮箱回填。 - Creem 充值回调在用户邮箱为空时只会写入标准化且未被占用的邮箱;如果支付邮箱已被其它账号使用,充值仍可成功,但不会绑定该邮箱。
- 密码重置相关日志会记录脱敏邮箱,避免把完整邮箱地址写入错误或告警日志。
- tiered text quota 的错误 fallback 会对“预扣 quota + 工具调用附加费”的最终和做饱和转换,保持极端值下的 quota 上限策略一致。
- 分组倍率配置保存时会先裁剪普通分组 key 的首尾空白,再持久化和校验,避免配置项保存后无法通过正常分组名命中。
- 模型分组选择器会把字符串倍率转换为数值后判断是否展示,
"0.0"、"0.00"等零值格式不会再显示误导性的倍率标签。 - 任务请求时长读取收敛到
TaskSubmitReq.ResolvedSeconds/ResolvedSecondsOrDefault,验证、Sora 默认值和阿里请求转换共享同一套解析、错误处理和默认时长逻辑。 - 图片
n数量上限校验收敛到共享dto.ValidateImageN,OpenAI 图片请求和阿里parameters.n使用同一上限与错误文案模板。 - 使用日志 quota filter 的路由枚举现在从 UI filter values 派生,避免
isQuotaFilterValue和z.enum(QUOTA_FILTER_SEARCH_VALUES)后续手动维护时漂移。
Bug Fixes
- 修复 Playground 输入区在长模型名、长分组名或较窄容器中可能出现控件互相挤压、按钮被顶出或文本溢出的问题。
- 修复长提示词在输入框中可能撑开父容器、影响输入区整体布局的问题。
- 修复通用视频任务上游已在
metadata.url返回视频地址时,MAX API 未能保存该结果 URL,导致查询结果只返回本机/content代理地址的问题。 - 修复部分 Seedance 兼容代理完成态采用 OpenAI Video
metadata.url结构时,任务结果 URL 解析不到的问题。 - 修复用户个人设置、语言、侧边栏配置和订阅偏好更新时,可能用旧用户对象覆盖最新 quota/used quota/request count 的并发风险。
- 修复邮箱未标准化导致
[email protected]和[email protected]可被不同账号重复占用,进而影响注册、OAuth 创建、邮箱绑定和密码重置归属的问题。 - 修复密码重置在历史重复邮箱场景下可能更新多个账号的问题;现在仅允许单一匹配账号重置,重复或缺失邮箱统一视为无效重置链接。
- 修复无密码账号可能通过密码登录或首次改密绕过原密码校验的问题;空密码账号不能用于密码登录,改密时也不会把空原密码当作有效密码。
- 修复保存通知偏好时会用新建
setting覆盖整份设置,导致语言、侧边栏模块、扣费偏好等无关设置被清空的问题。 - 修复用户资料更新后 Redis 用户缓存未同步刷新
Role,可能让旧角色权限继续生效到缓存失效的问题。 - 修复 Ollama 非流式工具调用响应未返回 OpenAI 兼容
tool_calls的问题,并保留工具参数中的显式零值。 - 修复 Wan2.7 i2v 请求仍按旧版
img_url发送图片的问题;Wan2.7 i2v 现在使用input.media,Wan2.5 等旧模型仍保留原有img_url行为。 - 修复 Wan2.7 i2v 已显式提供部分
input.media时,同时提供的last_frame_url、audio_url会被清空而没有合并进media的问题。 - 修复 JSON 任务请求只传
image而未传images时,通用 task action 和后续适配器可能无法识别为图生视频的问题。 - 修复认证页在
getSelf网络错误或服务端 5xx 时误判 session 失效、清空本地登录态的问题;非 401 校验错误现在会交给路由错误边界处理,避免旧登录态静默通过。 - 修复
TaskSubmitReq.Duration使用非指针omitempty导致显式duration: 0无法继续透传给上游的问题。 - 修复通用任务请求解析中
model_name覆盖model、aspect_ratio覆盖size、duration覆盖seconds的优先级不一致问题。 - 修复嵌套
parameters.generateAudio被错误写入WithAudio,导致下游生成音频开关含义错位的问题。 - 修复内容数组中第一个
video_url条目为空时,后续有效视频输入不会继续扫描,可能影响has_video_input计费判定的问题。 - 修复 Wan2.7 i2v 同时传
input_reference和images时,第二帧/尾帧图片可能被跳过或错位的问题。 - 修复基础任务请求从单图
image回填images时未裁剪空白,导致不同入口对空白 URL 处理不一致的问题。 - 修复
input_reference只有空白字符时仍会生成images: [""]并被误判为图生视频输入的问题;空白input_reference现在会被视为未提供,并可回退到image。 - 修复工具调用参数为字面量
null时,Claude / Gemini 转换路径可能把参数序列化为null而不是空对象{}的问题。 - 修复管理员覆盖用户 quota 后 Redis 失效失败会把已成功提交的 DB 更新返回成失败的问题。
- 修复极端
n、max_tokens、视频时长、rate card quantity 或表达式结果可能导致 quota 计算溢出、转负数或错误扣费的问题。 - 修复任务差额结算只更新内存对象、没有把实际
quota持久化到数据库的问题。 - 修复阿里视频任务
seconds <= 0时未稳定回退默认时长,可能影响请求体和计费倍率一致性的问题。 - 修复任务请求
seconds为非数字字符串时会被静默当作 0 通过校验的问题;非法seconds现在返回invalid_seconds,边界提示也与实际允许的0..3600范围一致。 - 修复受保护 fetch 的重定向目标、域名解析结果或拨号地址未在同一保护链路内校验,可能留下 SSRF 绕过窗口的问题。
- 修复流式客户端断开后仍可能继续向已失效连接写入、等待 goroutine 退出时未先关闭 upstream body,导致上游流量继续消耗或退出清理变慢的问题。
- 修复 Claude / Responses 流式 helper 在收到 nil
gin.Context或缺失 writer 时仍继续Render,可能触发 panic 的问题。 - 修复主服务端口绑定失败时仍可能先打印启动成功日志的问题。
- 修复优雅关闭超时后活跃请求仍可能继续运行,而进程已经开始 quota cache 保存和 DB 清理的问题。
- 修复渠道编辑抽屉点击 “Channel Extra Settings” 时滚动到视频任务协议等更早区域的问题;只配置代理地址或系统提示词时,也会定位到实际配置字段。
- 修复滚动到高级设置区域时可能被动展开 Advanced Settings,并意外覆盖用户折叠偏好的问题。
- 修复新建渠道时切换渠道类型不会清理旧类型
base_url/other字段,可能把旧类型配置误提交到新类型的问题。 - 修复编辑已有渠道时切换类型会静默清空已保存
base_url/other的问题;自动重置仅用于新建渠道。 - 修复 Playground 重新生成或编辑后重新提交时,模型/分组无效会静默失败、没有用户反馈的问题。
- 修复新增自动链路时使用已有 key 会静默覆盖原链路配置的问题;新增模式会拒绝重复 key,编辑模式才允许替换当前链路。
- 修复默认自动链路可被禁用,导致启用
DefaultUseAutoGroup后新注册用户默认令牌指向不可用链路的问题。 - 修复
user_selectable=false的隐藏自动链路仍可被普通用户通过令牌创建/更新接口手动指定的问题。 - 修复关闭阶段
runWithTimeout内部任务 panic 时可能直接终止进程,绕过后续清理流程的问题;panic 现在会记录日志并结束等待流程。 - 修复批量更新 option 时部分格式错误的配置可能先提交到数据库、再在内存运行时刷新阶段失败,导致持久化配置与运行时状态不一致的问题。
- 修复 MySQL 下两个并发请求注册同一全新邮箱时,
SELECT ... FOR UPDATE无法锁住不存在行,可能落到底层唯一索引错误而不是返回友好邮箱占用错误的问题。 - 修复 Creem 充值 webhook 直接写入 customer email,可能绕过邮箱标准化、唯一性检查和事务保护的问题。
- 修复密码重置邮件发送失败或跳过时日志输出原始邮箱地址的 PII 风险。
- 修复 SSE ping 写入直接持锁调用
PingData,当底层 writer 不支持 deadline 且写入阻塞时,pinger 退出等待可能被永久挂住的问题。 - 修复直接调用任务请求发送路径且
ChannelMeta为空时,runtime header override 中的{api_key}可能被替换为空字符串的问题。 - 修复使用日志重试筛选统计在
logType=Unknown时丢失LogTypeConsume限制,可能把充值或系统日志 quota 计入用量统计的问题。 - 修复使用日志 quota filter 的 readonly tuple 类型断言导致
bun run typecheck报 TS2352、阻塞前端构建的问题。 - 修复使用日志 quota filter 的 UI 值列表和路由搜索参数枚举重复维护,后续新增筛选值时可能导致 URL round-trip 与筛选栏校验不一致的问题。
- 修复空白包裹的普通分组倍率 key 会被原样保存或查询时不裁剪,导致
GetGroupRatio/ContainsGroupRatio按正常分组名或带空白入参查询不到并静默回退默认倍率的问题。 - 修复后端或 API 返回
"0.0"、"0.00"等字符串零倍率时,模型分组选择器仍显示Ratio: 0.00的问题。 - 修复 tiered text quota fallback 只饱和工具附加费、没有饱和最终 quota 和的问题。
Compatibility Notes
- 已配置
generic_video_task的视频渠道,如果上游或中间代理在完成态返回metadata.url,现在无需额外配置结果路径即可被默认解析。 - 如果渠道自定义了
task_protocol_config.result_url_paths,自定义列表会覆盖默认路径;需要兼容metadata.url的自定义渠道应将该路径显式加入配置。 /v1/videos/{task_id}/content兜底行为仍然保留,用于没有直接结果 URL 或需要本机内容代理的任务。- Playground 选择器在移动端仍保持紧凑图标入口;桌面端长名称会截断显示,不影响实际选择值。
- 如果请求处理超过
SHUTDOWN_TIMEOUT_SECONDS,主 HTTP 服务会强制关闭活跃连接;长连接、SSE 或慢请求应按连接关闭语义处理重连或重试。 - 启用数据看板导出时,进程优雅关闭会尝试保存内存中的 quota data cache;保存等待受
QUOTA_DATA_CACHE_SAVE_TIMEOUT_SECONDS限制,异常强杀仍可能绕过该流程。 - quota data logging 改为同步聚合,会优先保证退出前数据一致性;高吞吐环境建议结合实际日志吞吐观察延迟。
wan2.7-i2v使用input.media新协议;显式metadata.input.media会被保留,缺失的last_frame/driving_audio会从旧字段补齐,旧 Wan i2v 模型继续使用原有img_url。- 空白
input_reference现在按未提供处理;如果同一请求还提供了image,会继续走单图 fallback。 - 保存通知偏好会清空旧通知渠道的地址和密钥字段,避免切换通知类型后残留旧配置;语言、侧边栏模块和扣费偏好会保留。
- Ollama 工具调用客户端可能开始收到
finish_reason: "tool_calls"和message.tool_calls,这是对 OpenAI 响应格式的兼容修复。 - 认证守卫现在只把 HTTP 401 视为 session 失效;临时网络或服务端错误不会清空本地登录态,但会继续抛给路由错误边界,便于用户和运维看到真实故障。
- 对依赖任务请求原始字段的自定义渠道,
model、size、seconds的显式值现在会优先保留;如果历史配置依赖model_name、aspect_ratio或duration覆盖同级字段,需要按新优先级检查配置。 duration作为可选字段会保留显式 0;自定义适配器读取时应使用DurationValue()或判空指针,避免重新引入零值丢失问题。- 任务请求中的
seconds如果是非数字字符串,现在会被拒绝而不是按 0 处理;duration: 0和seconds <= 0的默认时长 fallback 语义仍保留在需要默认值的适配器路径中。 - 邮箱会按裁剪空白并转小写后的标准值参与唯一性判断;如果历史数据库中存在大小写不同但标准化后相同的重复邮箱,注册、邮箱绑定和密码重置会更早失败,需要先清理重复账号数据。
- 密码重置现在要求邮箱只匹配一个有效账号;历史重复邮箱不会再被批量重置,用户会收到无效链接结果以避免账号归属泄露。
- 计费数量、视频时长和 rate card quantity 会被校验或限制;超过边界的请求可能被拒绝或按安全上限处理,避免继续产生溢出后的异常 quota。
- SSRF 防护启用时,受保护下载、视频代理、MJ 代理和通知/webhook 等 fetch 路径会校验重定向和解析后的目标 IP;如果部署依赖私网地址或代理解析私网域名,需要显式配置允许私网 IP、IP 白名单或关闭对应域名 IP 过滤。
- 流式客户端断开后会更快关闭上游响应体;依赖“客户端已断开但上游仍继续跑完”的外部观察逻辑需要按连接关闭语义调整。
- 异步任务完成后的差额结算会更新任务表中的
quota;后续任务列表、退款和重复结算判断会看到实际扣费值,而不是历史预扣值。 - Go 依赖升级后建议重新构建镜像/二进制并刷新模块缓存;安全补丁不改变公开 API,但可能改变底层 TLS、HTTP/2、图片解析和加密库行为。
- 渠道编辑器在新建渠道时切换类型会清理不属于新类型的
base_url/other类型专属字段;编辑已有渠道时不会自动覆盖已保存的字段。 - Advanced Settings 的展开偏好只在用户手动开关折叠面板时持久化;导航点击和校验失败触发的自动展开只影响当前编辑流程。
- 自动链路配置不需要新增数据库表;新配置写入现有 option 体系中的
AutoGroupRoutes,旧AutoGroups数组仍作为默认链路兼容字段保留。 - 旧版
AutoGroups数组会被解释为auto默认链路;管理员保存新配置后,AutoGroups会同步为当前default_route对应的真实分组列表。 - 自动链路 key 仅支持
auto或auto:<name>,其中自定义部分允许字母、数字、点、下划线和短横线;链路中的groups必须是真实计费分组,不能再嵌套其它自动链路 key。 default_route必须指向存在且启用的自动链路;否则系统设置保存会被拒绝,避免默认令牌生成不可用。user_selectable=false的链路不会出现在普通用户可选分组中,令牌新建/更新也不能主动选择;已存在的隐藏链路令牌仍会按运行时可用性解析,用于兼容历史配置或管理员预置令牌。- 启用
DefaultUseAutoGroup时,新注册用户默认令牌会使用当前default_route,不再假设默认 key 一定是auto。 - 管理员批量保存设置时,格式错误或语义无效的运行时配置会在数据库提交前被拒绝;这会更早暴露无效 JSON、无效自动链路、非法状态码范围或无效任务计费 rate cards,但不会改变合法配置的保存格式。
- MySQL 部署会使用连接级邮箱命名锁串行化同一标准化邮箱的注册和绑定;锁等待超时会返回失败,建议在高并发注册场景下观察数据库连接池和锁等待指标。
- Creem 回调不再保证把支付邮箱写入空邮箱账号;当支付邮箱已被其它账号占用时,仅完成充值,不做邮箱绑定,避免破坏后续密码找回唯一性假设。
- 历史分组倍率配置中如果存在
" vip "这类带首尾空白的 key,重新保存后会归一化为"vip";依赖空白 key 的异常配置需要改为正常分组名。 - 调用分组倍率查询时传入首尾空白也会按裁剪后的分组名查询;这会让
" vip "和"vip"走同一倍率配置。 - 使用日志 quota filter 只在传入
quota_filter时生效;默认all不会发送该参数,保持旧查询结果不变。
Verification
bunx eslint src\components\ai-elements\prompt-input.tsx src\components\model-group-selector.tsx src\components\ui\input-group.tsx src\features\playground\components\playground-input.tsx --no-warn-ignoredbunx eslint src/features/channels/components/drawers/channel-mutate-drawer.tsxbunx eslint src/routes/_authenticated/route.tsxbun test tests/channel-form.test.tsgo test ./relay/channel/task/taskcommon ./relay/channel/task/doubao ./relay/channel -count=1go test . ./controller ./model ./relay/channel/ollama ./relay/channel/task/ali ./relay/commongo test . -run "TestRunWithTimeout|TestShutdownHTTPServerClosesActiveHandlersAfterTimeout" -count=5go test ./controller -run TestUpdateUserSettingPreservesUnrelatedSettings -count=1go test ./model -run "TestUserUpdateIgnoresCacheWriteFailure|TestUpdateUserSettingOnlyUpdatesSetting|TestUpdateUserSettingIgnoresCacheWriteFailure|TestUpdateUserSettingMissingUserReturnsError" -count=1go test ./relay/channel/task/ali -run TestConvertToAliRequestWan27I2VMergesLegacyMediaFieldsIntoPartialMedia -count=1go test ./relay/common -run TestValidateMultipartDirectIgnoresBlankInputReference -count=1go test ./relay/channel/task/taskcommon ./relay/channel/task/ali ./relay/common ./service ./model ./controllergo test ./relay/channel/task/taskcommon ./relay/channel/task/doubaogo test . ./setting ./service ./controller -run "TestRunWithTimeoutRecoversPanic|TestParseAutoGroupRoutes|TestHiddenAutoRouteRuntimeUsableButNotUserSelectable|TestAddTokenRejectsNonSelectableAutoRoute|TestUpdateTokenRejectsNonSelectableAutoRoute" -count=1go test ./model ./settinggo test ./setting/...go test ./common ./pkg/billingexpr ./relay/common ./relay/helper ./service ./setting/task_billing_setting ./model ./controller ./relay/channel/openai ./relay/channel/gemini ./relay/channel/ali ./relay/channel/task/ali ./relay/channel/task/gemini ./relay/channel/task/klinggo test ./model ./servicego test ./model ./service ./setting/ratio_setting ./relay/channel ./controllergo test ./model -run "Test(UpdateUserSettingOnlyUpdatesSettingMySQL|InsertRejectsConcurrentDuplicateEmailMySQL)$" -count=1 -v(未设置TEST_MYSQL_DSN时会跳过 MySQL 外部库覆盖)go test ./dto ./relay/helper ./relay/channel/aligo test ./relay/common ./relay/channel/task/aligo test ./relay/helpergo test ./setting/ratio_settinggo test ./...go vet ./...bun test src/features/usage-logs/lib/utils.test.tsbun test src/lib/auto-routes.test.tsgo run ./tools/jsonwrapcheckbun run typecheckgit diff --check
Full Changelog: v1.0.4-preview.1...v1.0.4-preview.2
-
v1.0.4-preview.103 Jul 2026 pre-releaseNothing published for this version
-
v1.0.330 Jun 2026Nothing published for this version
-
v1.0.3-preview.2.0.20260627015122-0412b5758ad427 Jun 2026 pre-releaseNothing published for this version
-
v1.0.3-preview.227 Jun 2026 pre-releaseNothing published for this version
-
v1.0.3-preview24 Jun 2026 pre-releaseNothing published for this version
-
v1.0.3-0.20260623090928-bfb3d29d591023 Jun 2026 pre-releaseNothing published for this version
-
v1.0.222 Jun 2026Nothing published for this version
-
v1.0.2-0.20260620182521-43f976f4ff4320 Jun 2026 pre-releaseNothing published for this version
-
v1.0.120 Jun 2026Nothing published for this version
-
v1.0.019 Jun 2026Nothing published for this version