Commit Graph
1197 Commits
Author SHA1 Message Date
tbphp ff4e2d0e86 docs(readme): 更新 v2 官网与版本徽章 (#501) 2026-08-31 11:22:01 +08:00
tbphp 922c6e055c fix(subscription): 避免临时刷新失败锁死凭据 (#499) 2026-08-30 18:20:28 +08:00
tbphp 4479553dd8 fix(web): 统一协议显示规范 (#498) 2026-08-30 10:43:08 +08:00
tbphp aee2111290 feat(gateway): 支持 OpenAI Embeddings API (#496)
新增原生 OpenAI Embeddings 端点,覆盖首期 API Key 渠道,并复用现有路由、健康、用量、日志与管理流程。
2026-08-30 00:45:19 +08:00
tbphp 93ab48772e fix(docker): 修复源码镜像构建输入 (#497) 2026-08-30 00:39:34 +08:00
tbphp 5c16ed84b3 feat(windows): 增加原生服务安装包 (#493)
* feat(windows): 增加原生服务安装包

* fix(windows): 收紧服务安装与升级流程

* fix(windows): 固定服务安装路径与语言资源

* fix(windows): 等待安装器进程完成

* fix(windows): 清理首次安装失败残留
2026-08-29 23:26:23 +08:00
tbphp a58de8b1b2 feat(credentials): 增加 API Key 手动测试 (#495) 2026-08-29 22:25:09 +08:00
tbphp eb7e54cf1d feat(access-key): 增加有效期来源限制和密钥轮换 (#494)
* feat(access-key): 增加有效期来源限制和密钥轮换

* fix(access-key): 提交前重新校验有效期

* fix(access-key): 恢复过期提交错误反馈
2026-08-29 21:26:32 +08:00
tbphp 515c958dd1 feat(config): 支持运行策略与数据库连接池配置 (#492)
* feat(config): 增加重试拉黑及数据库连接池配置

* fix(settings): 恢复已提交配置快照
2026-08-29 18:23:34 +08:00
tbphp 4d21d9578c docs(readme): 更新界面预览截图 (#491) 2026-08-29 13:33:17 +08:00
tbphp 0e6afc5b96 chore(deps): 更新 fasthttp 流式关闭修复 (#490) 2026-08-29 00:04:06 +08:00
tbphp a4579900ba docs(readme): 同步二点零说明与品牌素材 (#489) 2026-08-28 22:15:27 +08:00
tbphp 6947edf190 fix(subscription): 跳过并标记重复账号 (#488)
* fix(subscription): 跳过并标记重复账号

* fix(subscription): 修复混合状态连接检查

* fix(subscription): 修复重复账号重新授权
2026-08-28 21:43:43 +08:00
tbphp 1a6e454475 feat(subscription): 接入 Codex/Claude 被动额度信号观察 (#487)
* feat(subscription): 接入 Codex/Claude 被动额度信号观察

从 Codex/Claude 订阅请求的响应 Header 中安全采集额度信号,归一化为与主动观察一致的账号级窗口,
经内存 pending map 合并后由 RequestLog worker 复用现有 quotaWake 异步落库,
自动刷新账号卡的额度窗口与同步时间;额度仅用于管理面展示,不参与路由、调度或健康判定。

同时修复 recordCredentialObservationFailure / invalidateCredentialObservationAfterReset
整行 Save 覆盖并发写入 snapshot_json 的既有问题,改为按列更新。

* fix(subscription): 修正被动额度合并的两处数据错误

丢弃比已存记录更旧的被动采样:手动刷新在 pending 落库前完成时,
旧采样会让 observed_at_ms 倒退并用旧额度覆盖新值;updated_at_ms
条件更新只能拦截读取之后的写入,拦不住这种时间倒退。

MergeQuotaWindow 不再用空字符串覆盖 Label/LabelKey/Scope/Unit:
这些是快照必填字段,被清空后 ApplyQuotaWindows 会跳过该窗口并
清除管理面低额度提示。

* fix(subscription): 落库确认后清空 pending 窗口缓存

ack 此前只清 dirty 标记,不清 entry.windows;下一次响应即使只带
部分字段,也会把已经落库的陈旧字段当作当前观察重新合并进去,
可能覆盖同一时间发生的主动刷新写入的更新值。
现在版本匹配时一并清空窗口缓存,配合已有的 MergeQuotaWindow
字段级保护,落空字段的响应不会再用零值或陈旧值覆盖数据库现值。

* fix(subscription): 通用化 Codex 被动额度解析并修正三处数据错误

Codex 被动解析改为从 Header 自动发现限额命名空间,不再写死
primary/secondary 两个账号级窗口。带 Limit-Name 的附加限额
(如 GPT 5.3 Codex Spark)现在也能被动更新,且窗口 ID 与主动
JSON 路径一致;将来新增的限额类型无需改代码即可识别。缺少
Limit-Name 的命名空间跳过,因为无法生成可匹配的稳定 ID。

同时修正:
- 越界 used-percent、非正或溢出的 reset/window 一律丢弃,
  不再用 0 或回绕值覆盖快照中的有效字段;
- 被动不再输出 Label/LabelKey,避免只带使用率的响应把 7d 窗口
  的标签改写成 Session,与 window_seconds 自相矛盾;
- 主动成功的 observed_at_ms/updated_at_ms 改用响应完成时间
  (last_attempt_at_ms 仍为尝试开始时间),慢速手动刷新不再被
  刷新期间捕获的被动样本反向覆盖,CAS token 也不再可能不变;
- 窗口值未变化但确实观察到时推进 observed_at_ms,低频账号不再
  长期显示数小时前同步。

* refactor(subscription): pending 只保留最新一次响应,不再跨响应合并

pending 条目此前会把多次响应的窗口字段按 ID 合并,却只记录一个
观察时间。混在一起的字段因此可能带着较晚的时间戳落库,反过来
盖掉这期间提交的主动刷新结果。上一轮给 ack 加清缓存只堵住了
"已落库后残留"这一半,尚未落库前合并的那一半仍然存在。

改为每次记录整体替换:一个 pending 条目只承载一次响应,窗口与
观察时间始终描述同一时刻,这类时序覆盖从根上不再可能,ack 也
不需要再清缓存。被丢弃的旧响应不构成数据丢失——快照中该窗口
保持原值,下一次带该窗口的响应会刷新它。

生产代码净减 19 行。

* fix(subscription): 用 observation_version 做被动写入的并发令牌

时间戳不能充当 CAS 令牌:两次写入可能落在同一毫秒,updated_at_ms
数值不变会让已过期的被动写入通过条件更新,盖掉刚提交的主动刷新。
改用 observation_version(主动成功本就递增),并保留 updated_at_ms
比对以覆盖主动失败与重置这两条只改元数据、不动版本的路径。

同时收敛三处局部合同:
- 绝对 reset 无效时继续尝试同一响应中的相对 reset,不再因一个坏
  Header 丢掉可用值;
- 被动输出不再携带 Scope / Unit / IsPrimary(此前只清了 Label),
  贯彻「自动更新只改额度数值与状态」,Codex 与 Claude 两侧一致;
- pending 深拷贝窗口的指针字段,调用方后续修改不会改变待落库内容。

* fix(subscription): ACK 时移除 pending 条目并让同毫秒判给主动结果

ACK 此前只清 dirty 标记,条目连同克隆的窗口一直留在 map 里。凭据
删除后也不会释放,长期运行且凭据有增删的实例会持续增长。改为版本
匹配时直接移除条目——凭据删除本就走「registry 查不到 → ACK」这条
路径,因此不需要再给删除流程挂额外的清理钩子。

被动样本与行内 observed_at_ms 相同时改为丢弃(原为严格小于才丢)。
被动 Header 先捕获、主动刷新稍后完成,两者截断到同一毫秒时,旧的
被动结果会盖掉权威的主动结果,且此时 CAS 不冲突。相同毫秒判给主动
结果即可,不引入更高精度时间戳。该判断收紧后,落库处基于
alreadyObservedAt 的分支成为死代码,一并删除。

顺带移除无生产调用方的 AckPassiveQuotaObservation 导出方法。
2026-08-28 18:26:00 +08:00
tbphp b1a7f373fc fix: 接入首个流错误安全切换 (#486)
* fix(gateway): 接入首个流错误安全切换

* fix(gateway): 保留显式重放安全状态
2026-08-28 08:15:13 +08:00
tbphp d4bbb9193a feat: 升级 Go 与 SDK 版本 (#485)
* feat(gateway): 升级 SDK 并封口兼容合同

* fix: 修正升级后的格式与模型过滤

* fix(ci): 更新 Go 漏洞扫描器

* fix(gateway): 拒绝非标准服务层级字段
2026-08-27 22:48:16 +08:00
tbphp 17dbcb592c fix(compose): 恢复默认数据具名卷 (#484) 2026-08-27 19:30:16 +08:00
tbphp a710acab1e feat(usage): 接入 OpenAI 图片用量计价 (#483)
* feat(usage): 接入 OpenAI 图片用量计价

* fix(usage): 修复图片响应计量采集

* fix(usage): 减少图片流式解析分配

* fix(usage): 收口图片用量解析内存
2026-08-27 18:44:35 +08:00
tbphp 6a71f52f46 fix(subscription): 合并 CPA 模型目录到订阅发现 (#482) 2026-08-27 16:34:09 +08:00
tbphp a6d2e712ac fix(release): 统一使用版本号作为标题 (#481) 2026-08-27 15:53:39 +08:00
tbphp e9e88dce99 feat(images): 接入 OpenAI 图片生成与编辑 (#476)
* feat(images): 接入 OpenAI 图片生成与编辑

* fix(images): 补齐响应容量与边界处理

* fix(images): 修正协议观测与响应上限覆盖

* fix(stream): 保证取消优先于流关闭

* fix(images): 修正空 SSE 错误对象判定

* fix(images): 避免媒体数据触发凭据误判

* fix(images): 阻止流式响应泄漏凭据

* fix(images): 校验完整流事件后再转发

* fix(images): 修正响应模型观测
2026-08-27 15:11:52 +08:00
tbphp 69483c7109 fix(storage): 统一 DATA_DIR 目录准备 (#480)
* fix(storage): 统一 DATA_DIR 目录准备

* docs: 精简 DATA_DIR 部署说明

* fix(compose): 初始化 DATA_DIR 挂载权限

* fix(compose): 安全初始化绑定目录
2026-08-27 14:30:44 +08:00
tbphp 686ef7ba8f fix(groups): 切页时重新获取分组选项 (#475)
* fix(groups): 切页时重新获取分组选项

* fix(monitor): 切换用量页时刷新分组选项
2026-08-26 19:25:36 +08:00
tbphp a6e019b612 fix(release): 修复 Alpine OpenSSL 漏洞扫描阻断 (#474)
* fix(release): 升级 Alpine OpenSSL 运行时依赖

* fix(release): 固定 Alpine OpenSSL 安全补丁版本
2026-08-26 18:10:23 +08:00
tbphp 81780d048f fix(gateway): 放宽请求体大小限制 (#473)
* fix(gateway): 放宽请求体大小限制

* test(gateway): 明确请求体上限测试意图
2026-08-26 11:56:22 +08:00
tbphp 6488be7bd6 fix(groups): 同步模型变更后的关联缓存 (#470)
* fix(groups): 同步模型变更后的关联缓存

* docs(groups): 修正缓存失效注释
2026-08-25 11:24:56 +08:00
tbphp a0c8605c47 fix(monitor): 调整尝试详情自适应布局 (#469)
* fix(monitor): 调整尝试详情自适应布局

* fix(monitor): 精简尝试链诊断字段
2026-08-25 08:53:52 +08:00
tbphp 5dc5304c25 fix(gateway): 完善统一错误规则 (#468)
* fix(gateway): 完善统一错误规则

* fix(gateway): 采纳错误规则审查意见

* fix(gateway): 收紧未发送网络错误判断
2026-08-25 00:20:53 +08:00
tbphp d518b06acc refactor: 统一错误决策与执行链路 (#466)
* refactor: 统一错误决策与执行链路

* fix(gateway): 修正错误来源与候选预算
2026-08-24 23:26:22 +08:00
tbphp 1bc4c7fead perf(release): 镜像复用预编译产物 + GOPROXY 网络容错 (#467)
* fix(ci): GOPROXY 在网络错误时回退到直连源

默认的 GOPROXY=https://proxy.golang.org,direct 用逗号分隔,只在收到
404/410 时才回退到下一个源;proxy.golang.org 的瞬时网络故障(如
HTTP/2 stream INTERNAL_ERROR)会直接让整个 job 失败,默认配置里的
direct 后备源在最需要它的场景下形同虚设。

改用竖线分隔,任何错误(含网络错误)都回退。实验验证:
- 逗号:首个源 EOF -> 直接失败,不尝试第二个源
- 竖线:首个源 EOF -> 成功回退并完成下载

ci.yml、release.yml 以 workflow 级 env 统一设置;Dockerfile 内的
go mod download 走同一问题,一并设置。不引入第三方镜像源,避免为
发布链路增加新的信任方。

* perf(release): 镜像打包复用预编译产物,不再重复编译

publish-images 此前在 Docker 内从 go mod download 开始重新编译 Go 与
Web(两个平台各一次,实测 216s),而 build-binaries 早已交叉编译出
gpt-load-linux-amd64/arm64——正是镜像需要的那两个文件。

Dockerfile 拆出共享的 runtime stage,两条打包路径都以它为基:
- source-build:默认 target,自包含源码构建,供本地与用户自建使用,
  必须保持在文件末尾,否则默认构建会落到 prebuilt 而要求预编译产物
- prebuilt:发布用,直接 COPY 预编译二进制

runtime 配置只定义一次,避免两套配置各自漂移。GitHub artifact 不保留
可执行位,prebuilt 用 COPY --chmod=0755 显式恢复。

发布证据链:新增 prebuilt-image-smoke,在发布前用与 publish-images
完全相同的打包路径做 smoke 与 Trivy 扫描,并加入 publication-preflight
的 needs;docker-smoke 继续覆盖源码自包含路径,两者不可互相替代。
release-docker-smoke.sh 新增 RELEASE_SMOKE_BUILD_TARGET 支持指定 target。

container_contract_test.go 原用「最后一个 FROM」定位 runtime 契约,多
stage 后不再成立,改为定位共享 runtime stage,并新增两条断言:每个可
发布 stage 必须派生自 runtime、除 runtime 外不得再有直接以 alpine 为基
的 stage,防止新增路径绕开全部 runtime 断言。已反向验证两条断言均能
拦截对应的破坏方式。

本地验证:prebuilt 镜像实跑 release-docker-smoke.sh 全流程通过(含
非 root 运行、数据目录权限、健康检查、Web UI、认证边界);删除
release/ 后默认 target 仍能正常源码构建。

* fix(release): prebuilt smoke 覆盖 arm64,补全发布前验证

publish-images 推送 linux/amd64 与 linux/arm64 两个平台,两条 prebuilt
路径 COPY 的是不同的二进制,但此前 prebuilt-image-smoke 只在 x86_64
runner 上验证了 amd64,arm64 打包路径没有发布前验证。

改为双架构矩阵,arm64 使用原生 ubuntu-24.04-arm runner(仓库在
native-artifact-smoke 已有先例)而非 QEMU:QEMU 模拟下的启动行为不能
代表真实 arm64 运行时。同时按架构精确下载单个产物,不再整批拉取。

另外让 RELEASE_SMOKE_BUILD_TARGET 的校验错误信息带上实际传入的值,
便于排查 CI 环境变量配置问题。

本地在 arm64 主机上实跑 prebuilt smoke 全流程通过。
2026-08-24 22:26:58 +08:00
tbphp bd539713da perf: 优化测试性能与 CI/发布流水线耗时 (#465)
* test(control): 消除测试 fixture 中的重复密钥派生

- internal/control:fixture 构造中 388 次重复执行 PBKDF2(10 万轮
  SHA256)密钥派生,改为共享单例,仅派生一次
- 新增 internal/testutil/encryptiontest,提供按 key material 值
  memoize 的共享 encryption.Service,横向覆盖 gateway、subscription、
  execution/cpa 中同样存在的重复派生(PBKDF2 占比最高达 79%)
- aesService 构造后只读,跨 fixture(含并行测试)共享安全;container
  包同类调用经排查确认属于被测装配流程本身,不适用本次改造

* test(state): 迁移测试改用共享 schema 模板

state/loader 中 openMigratedDatabase 被 21 次调用,每次都完整走一遍
迁移注册表;改为复用 sqlitetest.OpenMigrated 的模板缓存,与 control、
requestlog 部分测试已采用的方式一致。app、container、requestlog 中同
类调用点经逐点排查,均属被测对象本身或依赖真实文件/账本状态,不适用。

* ci(release): 消除 CI 与发布流水线中的耗时浪费

- race-tests 独立 setup-go 缓存命名空间,避免与 test/database-contract
  共用 key 导致 race-instrumented GOCACHE 永远无法写回
- 移除 publish-images 中零命中的 GHA buildx image cache,同时消除其
  失败会拖累发布状态判定为 partial/blocked 的关联风险
- 三个只读 job(仅用 buildx imagetools 查询)移除多余的 buildx 初始化
- native-artifact-smoke 改为按需下载单个 binary + 独立 checksums,
  不再下载完整 release-assets

* test(control): 第一批测试标记 t.Parallel(35 个文件)

internal/control 651 个顶层测试里只有 5.8% 标了 t.Parallel(),其余
在包内是排队串行执行的;race-tests 总耗时现在完全由该包的最长执行时
间决定(213s),是唯一剩余的瓶颈。

本批覆盖 35 个文件、299 个函数。排除 18 个不适用的函数:
- 16 个直接操作全局 logrus 状态的测试(catalog_sync_test.go 等 8 个
  文件),继续保持串行;Go 的 t.Parallel() 调度语义保证未标记的测试
  会在所有并行测试开始前完整跑完,两者不会交叉执行
- external_database_integration_test.go 的 2 个测试依赖
  GPT_LOAD_DATABASE_TEST_DSN:race-tests 中因未设置而被 t.Skip,标记
  并行无收益;database-contract job 中会共享同一个外部数据库实例真
  实执行,标记并行有正确性风险(唯一索引冲突/断言假设独占)

已排查确认安全:t.Setenv/os.Setenv 均为 0 处,无硬编码端口占用,每个
fixture 走独立 :memory: 数据库;本地 -count=3 重复验证无 flaky。

剩余约 297 个函数(36 个文件)作为第二批,待本批 CI 实测确认收益后
再决定是否推进。

* test(control): 第二批测试标记 t.Parallel,补齐排除说明(36 个文件)

覆盖剩余 297 个函数、36 个文件,加上第一批的 299 个,internal/control
除 18 个明确排除的函数外全部标记 t.Parallel()。

为 18 个排除函数逐一补充一行注释说明原因,避免日后被误认为遗漏而被
顺手加上 t.Parallel():
- 16 个劫持全局 logrus 状态的测试
- 2 个依赖 GPT_LOAD_DATABASE_TEST_DSN 共享外部数据库的测试

本地 -count=3 重复验证、全量 go test -count=1 . ./internal/...(58
包 ok)均通过。

* fix(release): 采纳 Review 反馈,修正文档措辞与产物保留期

- encryptiontest.Service 的文档注释修正为明确说明缓存仅在单个包的
  测试二进制内有效,不跨包共享(每个包的 go test 是独立进程)
- native-artifact-smoke 依赖的 binary-*、release-checksums 保留期
  从 1 天提高到与 release-assets 一致的 14 天:失败的 release run
  若延迟超过 1 天才重试,此前较短的保留期会导致产物过期、下载失败,
  阻塞发布流程

以下反馈经核实判定为不成立,未采纳:
- validation_test.go 中两个测试被指"竞争全局并发槽位"——经查
  newValidationWorkerForTest 每次调用构造全新独立实例(worker、
  channel、mutation coordinator 等),validationConcurrency 只是
  编译期常量,两个测试之间不存在任何运行时共享状态
2026-08-24 20:07:11 +08:00
tbphp 7f647f7f69 refactor(config): 收敛网络地址配置 (#462) 2026-08-24 11:56:58 +08:00
tbphp 7fcb661626 refactor(ui): 统一额度进度条与社区入口样式 (#461)
* fix(home): 统一额度进度条样式

* refactor(shell): 精简社区入口布局
2026-08-24 11:17:59 +08:00
tbphp 4f9eba5802 feat(proxy): 完成数据面代理与渠道约束 (#459)
* feat(proxy): 实现第一阶段数据面代理

* feat(proxy): 收敛渠道与代理协议支持

* fix(proxy): 修复环境检测与迁移验证

* fix(proxy): 回收旧代理运行时并校验地址

* fix(proxy): 补齐创建链路与前端校验

* fix(proxy): 收口订阅代理与迁移兼容

* fix(proxy): 修复环境代理与运行时回收

* fix(proxy): 为系统外部请求应用全局代理

* docs(config): 精简环境配置说明

* feat(proxy): 重构代理设置的前端交互与样式

设置页与分组设置页:
- 代理设置接入页面统一的草稿态与保存栏,不再独立即时提交
- 计入页面 dirty/valid,参与未保存离开拦截与并发冲突推迟
- 新增 ProxyOverrideRow,用分段控件替代原独立编辑弹层

账号卡片与密钥行:
- ProxyConfigEditor 新增 card 外观:标题在白底面板外,与相邻小节同级
- 修掉按视口宽度判断断点的问题,窄容器内不再挤压错乱
- 编辑态下拉固定宽度,不随所选模式伸缩;整体收进两行
- 新增 ProxyScopeIndicator,凭据配置了独立代理时给出标识与悬停提示

密钥行交互:
- 操作列收成「更多操作」菜单与展开图标,与账号卡片同构
- 折叠区分为权重、出站代理、运行诊断三个带标题小节,设置与诊断不再混放
- 权重编辑从弹层迁入折叠区,权重列的值可点击直达
- 释放的列宽还给凭据、权重与最近调用列

文案精简为继承、直连、自定义,并清理两处无引用的死键

* refactor(proxy): 统一代理设置的覆盖交互并消除样式重复

设置页与分组设置页:
- 代理行改用 RuntimeOverrideRow,与超时等设置项共用同一组件
- inherit 映射为“未覆盖”,direct/custom 映射为“显式覆盖”,因此补齐了
  覆盖/恢复默认按钮、覆盖状态徽章、当前有效值与待恢复默认态
- 分段控件只保留直连与自定义,继承由外层覆盖开关表达
- 删除自造的 ProxyOverrideRow,新增只含编辑控件的 ProxyOverrideControl

已保存的自定义地址:
- 输入框不做回填,统一由 placeholder 展示已存地址
- 同模式下留空或与已存地址逐字相同均视为未改动,顺带挡住掩码被当作
  新密码存回;无改动时保存按钮禁用
- 重新开启覆盖时回到基线已存的覆盖模式,使恢复默认可原路撤销

代码质量:
- 面板外壳(标题 + 白底面板 + 标签/值/编辑图标/操作)抽为全局
  .setting-panel,代理、权重、诊断三处共用,不再各写一份
- 删除 ProxyConfigEditor 已无调用方的 row 外观及随之失效的 props、
  徽章分支与始终隐藏的文案
- 占位地址推导与覆盖开关规则收敛为 proxy.ts 中的共享函数
- 移除代理输入提示文案及其失去引用的 i18n 键

密钥行折叠区诊断值字号对齐上方面板。重构以构建产物 CSS 逐条比对验证,
差异均为已论证的等价改写。

* fix(proxy): 修复代理传输与校验边界
2026-08-24 11:11:22 +08:00
tbphp 414679ef49 feat(group): 默认按最近调用排序 (#460)
* feat(group): 默认按最近调用排序

* fix(group): 优化最近调用排序查询

* fix(group): 兼容 MySQL 分组活动查询
2026-08-23 12:09:03 +08:00
tbphp dd7e7204e2 feat(subscription): 优化凭据导入与账号卡片 (#457)
* feat(subscription): 优化凭据导入与账号卡片

* feat(subscription): 调整额度色彩与加载骨架

* feat(subscription): 优化额度色彩与 JSON 入口

* feat(subscription): 优化额度条样式为淡底 + 左强调 + 底部进度线

将额度条从「整行 34px 铺色」改为「淡色背景 + 3px 语义左竖条 + 3px 行底进度线」,
左竖条改用 inset 阴影避免与进度线的接缝断口。强调色采用在 sRGB 色域内的高饱和值,
同一值同时适配明暗主题。

* fix(subscription): 防止窄卡片操作裁切

* fix(subscription): 优化额度窗口排序

* fix(subscription): 对齐刷新骨架窗口数量

* fix(subscription): 移除重复重置卡到期信息
2026-08-22 18:00:12 +08:00
tbphp 7f64cbbd9e fix(health): 限制异常上游凭据提示数量 (#458) 2026-08-22 17:58:41 +08:00
tbphp 92c52ec265 feat(subscription): 增加账号批量操作 (#455)
* feat(subscription): 增加账号批量操作

* fix(subscription): 统一账号文件导入导出

* fix(subscription): 独立展示批量同步状态

* fix(groups): 优化凭据批量操作交互

* fix(groups): 优化凭据批量操作布局

* feat(groups): 增加凭据全量操作

* fix(groups): 修复凭据批量操作反馈
2026-08-22 13:30:03 +08:00
tbphp b13c06b8bd fix: test release docs 2026-08-22 08:28:40 +08:00
tbphp e19e77ff34 docs: release info 2026-08-22 08:14:32 +08:00
tbphp ed5622f9bd fix(subscription): 移除额度快照时间失效 (#454)
* fix(subscription): 移除额度快照时间失效

* fix(subscription): 完善额度快照与重置卡展示

* fix(subscription): 修复迁移与到期提示

* fix(storage): 修复额度快照迁移恢复

* fix(control): 修复重置卡到期告警

* fix(web): 限制重置卡详情数量
2026-08-22 02:00:23 +08:00
tbphp 986a211fc7 fix(access-key): 收敛模型页只读展示 (#453)
* feat(access-key): 展示日志成本计算

* fix(access-key): 收敛模型页只读展示
2026-08-21 19:03:46 +08:00
tbphp 8898421ee8 refactor(subscription): 分离额度刷新与请求调度 (#449)
* refactor(subscription): 分离额度刷新与请求调度

* fix(subscription): 重置后刷新额度信息

* fix(subscription): 修正重置刷新并发状态

* fix(subscription): 收口重置后额度刷新状态
2026-08-21 17:40:38 +08:00
tbphp e74919e819 fix(stream): 修复订阅流组帧并收口响应头 (#450)
* fix(stream): 修复订阅流组帧并收口响应头

* fix(stream): 修复空流块与部分响应头
2026-08-21 16:08:50 +08:00
tbphp 30f008a724 docs(readme): 增加 APIMart 赞助商 (#452) 2026-08-21 15:05:00 +08:00
tbphp b1fbdcaba4 fix(settings): 复用更新检查缓存 (#448) 2026-08-21 11:52:30 +08:00
tbphp 15c9561a40 fix(access-key): 优化额度编辑交互 (#447)
* fix(access-key): 优化额度编辑交互

* fix(access-key): 修正编辑表单标签
2026-08-21 10:43:40 +08:00
tbphp 8c320360b4 fix(groups): 统一无模型分组可用性 (#446) 2026-08-21 10:11:47 +08:00
tbphp 2570e6b952 fix(web): 修复首页访问密钥额度翻译 (#445) 2026-08-21 10:11:02 +08:00
tbphp 24df87c280 feat(access-key): 优化费用额度管理与提示 (#444) 2026-08-20 23:51:04 +08:00