v1.0.4-preview.2
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 的并发风险。
- 修复邮箱未标准化导致
User@Example.com和user@example.com可被不同账号重复占用,进而影响注册、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