100 Commits
Author SHA1 Message Date
tbphp b517f71320 feat(home): add channel icons to account panels (#691)
* feat(home): add channel icons to account panels

* fix(modern-ui): 优化渠道图标提示信息
2026-09-18 19:33:36 +08:00
tbphp fe8cc17835 chore(release): 将验证任务迁回自托管 (#690) 2026-09-18 18:26:59 +08:00
tbphp e9a10bb509 test(ci): reduce race gate overhead (#688) 2026-09-18 13:05:49 +08:00
tbphp f6e3a15c40 fix(ui): restore classic contracts and usage trend buckets (#687)
* fix(ui): 修复新旧界面的共享接口兼容回归

* fix(usage): 修正五分钟趋势的请求时间归桶
2026-09-18 12:46:18 +08:00
tbphp 37cd99fb01 feat(logs): complete modern log metrics and filters (#686)
* feat(logs): complete modern log metrics and filters

* fix(release): use GitHub-hosted runners (#685)

* feat(logs): complete modern log metrics and filters

* fix(logs): validate index ordering and tooltips
2026-09-18 10:24:55 +08:00
tbphp 47e3838e0b fix(release): use GitHub-hosted runners (#685) 2026-09-18 09:57:18 +08:00
tbphp d79180fda2 feat(subscriptions): refine credential trend insights (#684)
* feat(subscriptions): refine credential trend insights

* fix(classic): accept health identity fields (#682)

* fix(ui): standardize English unit abbreviations (#683)

* feat(subscriptions): refine credential trend insights

* fix(subscriptions): address trend review findings
2026-09-17 23:34:56 +08:00
tbphp 76d383a4f9 fix(ui): standardize English unit abbreviations (#683) 2026-09-17 23:08:51 +08:00
tbphp 982e3d3ab7 fix(classic): accept health identity fields (#682) 2026-09-17 23:02:20 +08:00
tbphp aa558e2ee2 fix(docker): include modern route metadata (#681)
* fix(docker): include modern route metadata and git

* fix(docker): remove unneeded builder git
2026-09-17 22:17:40 +08:00
tbphp d9eea22f1d fix(credentials): align trend tooltips (#680) 2026-09-17 22:02:57 +08:00
tbphp 50ac12b003 feat(credentials): add compact usage and quota trends (#678)
* feat(credentials): add usage and subscription quota history

* fix(credentials): simplify subscription quota chart

* fix(credentials): restore compact usage trend

* fix(credentials): restore existing window usage

* fix(credentials): simplify compact trend charts

* fix(credentials): use view details icon and tooltip

* fix(credentials): clean quota history and chart leftovers

* feat(credentials): filter short quota windows and reuse trends

* fix(credentials): space quota trend points and connect gaps

* fix(subscription): sample quota history hourly and retain rebounds

* feat(credentials): overlay usage trend metrics

* fix(credentials): replace purple cost trend with teal

* feat(credentials): arrange linked trends in a compact grid

* fix(credentials): unify chart styling and scope tooltips

* fix(credentials): shorten quota trend heading

* fix(credentials): compact trends into a unified stats block

* fix(credentials): place three usage charts in one row

* fix(web): keep chart tooltips stable across data points

* fix(credentials): place lower chart tooltips below grid

* fix(credentials): preserve quota observations across transports

* fix(subscription): preserve quota history across transports

* fix(subscription): normalize quota observations before sampling

* fix(subscription): defer history until quota sources resolve
2026-09-17 21:12:12 +08:00
tbphp c0365fc03b chore(deps): upgrade CPA SDK to v7.3.6 (#677) 2026-09-17 19:32:00 +08:00
tbphp 5d98e41cc4 chore(deps): upgrade Bifrost Core to v1.9.0 (#676) 2026-09-17 18:38:41 +08:00
tbphp a2f0c141b7 feat(logs): add model consistency filter (#675) 2026-09-17 17:13:46 +08:00
tbphp dad1f05016 feat(codex): support standalone search (#674)
* feat(codex): 支持订阅渠道独立搜索

* fix(codex): 保留搜索读体失败的响应状态

* feat(logs): 添加独立搜索请求图标
2026-09-17 16:58:58 +08:00
tbphp 311c388c3a fix(groups): add missing gateway protocol probes (#673)
* fix(groups): add missing gateway protocol probes

* fix(groups): avoid typed gateway probe cancellation races

* fix(probes): validate gateway response array elements

* fix(probes): validate required native response payloads

* fix(probes): enforce exclusive Gemini part payloads
2026-09-17 16:24:24 +08:00
tbphp 72b7b6b0ca feat(auth): add login mascot interaction (#672)
* feat(auth): 完善登录页吉祥物交互与背景动效

* refactor(auth): 移除登录页背景动效
2026-09-17 12:18:04 +08:00
tbphp 853bc16d3a feat(web): add identity-based group filters (#671)
* feat(web): add credential and protocol group filters

* fix(web): unify expanded filter styles

* fix(web): match credentials by stable account identity

* fix(web): persist group filter expansion in URL

* fix(web): isolate group list and detail filters
2026-09-17 09:38:50 +08:00
tbphp 42b4a338ae fix(logs): preserve historical references for unavailable resources (#669)
* fix(logs): 修正历史记录关联的删除状态判断

* fix(logs): 保留历史日志接口响应兼容性
2026-09-17 08:48:56 +08:00
tbphp 08172b9e88 feat(web): implement the modern management frontend (#668)
* feat(web): 搭建新旧前端独立架构与界面切换

* feat(web): 设计珊瑚主题新版工作区框架

* refactor(web): 精调新版框架并移除预览占位内容

* fix(web): 隔离新版页面路由并恢复经典版启动

* fix(web): 修复页头菜单定位并精简导航提示

* feat(web): 优化导航布局并接入侧栏版本检查

* refactor(web): 精调侧栏底部外链与版本展示

* refactor(web): 整理侧栏外链并增加赞助入口

* refactor(web): 调整路由检查菜单与版本栏对齐

* Codex worktree snapshot: archive-cleanup

Co-authored-by: Codex

* fix(web): 恢复新版浮层组件样式

* feat(web): 完成新版登录认证与会话管理

* feat(web): 增加登录记忆选项并精简登录页

* fix(web): 独立展示访问密钥身份标识

* fix(modern): 调整快速导航触发器高度

* refactor(modern): 统一页面标题与设计令牌规范

* feat(modern): 完善分组工作区与公共框架

* feat(modern): 完善分组列表与公共组件

* feat(modern): 完成 API 密钥分组创建与模型批量选择

* feat(modern): 完善订阅分组创建与并行账号接入

* feat(modern): 完善分组详情与凭据管理

* feat(modern): 完善凭据卡片与高级配置交互

* feat(modern): 完善分组筛选并校正凭据统计

* feat(modern): 完善分组操作并统一消息与路由状态

* fix(modern): 统一凭据卡片底栏文字对齐

* feat(modern): 完善访问密钥管理与公共表单组件

* fix(modern): 区分页面与局部操作的加载反馈

* feat(modern): 完善请求日志页面与筛选展示

* refactor(modern): 精简日志表格字段与排版并降低渲染开销

表格只有单一字号、两档色阶,且每个配对单元格重复渲染表头已有的标签。
建立五档字号与三档色阶,数字列改等宽右对齐,删除格内标签。

字段配对从 7 组扩到 17 组并覆盖全部字段,避免非默认列各占一列;
细分缓存写入与两个完整性状态移出表格,仅保留在详情面板;
思考模式、强度、预算合并为一列,按强度、预算、开关的优先级取一,
等级保留上游原值不作翻译。列宽按内容与表头重排,全展开总宽减少约 480px。

表头与内容原先分属两个滚动容器、靠 JS 同步 scrollLeft,横向滚动有延迟,
改为同一容器内 sticky;行右内边距归零,固定列不再随滚动露出缝隙。

渲染上,AppOverflowText 仅在文字溢出时才创建 AppTooltip,
溢出检测共用一个 ResizeObserver,AppTooltip 的作用域属性改为缓存计算。

* refactor(modern): 重排日志高级筛选并精简筛选标签

* feat(modern): 统一协议标签并优化日志详情

* feat(modern): 完善请求日志展示与脱敏复制

* perf(modern): 减少页面切换等待与重复渲染开销

* fix(modern): 精简分页提示并缩小日期弹层

* feat(modern): 完善用量统计页面

* feat(modern): 支持日志字段快捷筛选

* feat(modern): 完善健康状态页面

* fix(health): 返回全部异常账号

* refactor(modern): 精简健康页并统一监控交互

* fix(brand): 统一品牌图形并修复刷新位置跳动

* feat(modern): 实现模型管理页面

* feat(modern): 完善全局设置页面

* fix(modern): 统一原生协议展示与弹窗确认焦点

* fix(modern): 优化全局滚动条体验

* refactor(modern): 模型卡片改为来源价格表格式并支持分组跳转

- 来源行改为与表头共用同一套列定义(来源/分组/4 项价格/计价方式/操作),
  多来源时价格上下对齐可比
- 协议折成一行中性摘要,悬浮查看完整列表,不再占用卡片最强的颜色
- 分组徽章对管理员改为可点击跳转到分组详情,非管理员保持纯展示
- 计价方式按常见程度分级:自动匹配为默认灰字,待计价才用警示徽章
- 卡片列表最小宽度从 320px 提到 620px 以容纳价格表;表格内容超宽时整体横向滚动

* fix(modern): 修正模型卡片价格溢出、行高不齐与列错位

- 价格列宽改为按本卡最长价格计算的共享变量:原先写死 52px,9 位小数的
  单价会溢出压到隔壁列;用 max-content 则表头与来源行各算各的导致列错位
- 来源单元格由 flex-wrap 改为网格:长渠道名原先会把图标、名称、档位各自
  甩到新行,单元格高度从 24px 涨到 87px
- 分组只展开第一个并禁止换行,超出交给 +N 提示,行高不再被撑乱
- 行内容压进 40px 下限,有无上游模型的行等高
- 溢出时行宽跟随内容,底色与分隔线不再在容器右边缘断掉
- 分组标签常态加描边,亮色下 subtle 几乎等于卡片白底、看不出可点

* feat(modern): 模型卡改多列排布并重做卡头视觉

- 网格改为 CSS 多列:来源数不同导致卡高不一,网格按行内最高的卡留空洞,
  实测同一批数据容器高从 616px 降到 576px 且无空洞
- 卡头加冷色渐变,自右上向左下淡出,左侧留白给模型名
- 新增 --modern-model-card-tint,沿用账号卡那套 info 蓝调,避开主色的橙
- 模型名靠左独占一端,协议/来源/分组三项统计右对齐

* refactor(modern): 精简模型详情侧边栏

- 去掉「全部来源」中间页:多来源靠顶部下拉切换即可,进面板直接落到
  第一个来源,随之移除返回箭头与只服务于该页的 ModelSourcePreview
- 面板宽度 sheet(660px) 改回 default(540px),与日志详情、访问密钥面板一致
- 价格由每档重复四个标签的块改为表格:表头只写一次,标准档与各阶梯档、
  各模式上下对齐可比,极端价格不再撑破容器
- 模型资料标签列定宽右对齐,原先 auto 会让每行按各自内容算宽而行间错位
- 关联分组去掉 AppButton>RouterLink>AppBadge 三层嵌套,改用与模型卡共用的
  可点标签样式(新增 model-group-chip.css)
- 清理随视图作废的样式与导入

* fix(modern): 换掉卡头底色并重排侧边栏价格表

- 卡头 tint 换成冷灰蓝 #e4ebf5/#2c3340,渐变两端都保留色:原先淡出到
  纯白,左下角与内容底色无差,所以区分不出卡头
- 修正上一轮未生效的改动:tint 仍混着 8% accent-soft(橙),当时单行
  replace 没匹配上已被格式化成多行的定义,且漏了断言
- 价格表单位说明移入表头首列,消掉标签列 225px 空白(占表宽 44%)
- 去掉价格表外框与表头底色,540px 侧栏里原先过重
- 价格四列收紧靠右(各 64px),数字挨在一起才便于比较
- 计价方式徽章移到「计价规则」分段标题行

* fix(modern): 卡头改用右上角径向晕染

照搬用量统计顶部卡片的手法:radial-gradient(ellipse at top right) 配低比例
混色,基色取成功绿。原先用线性渐变方向一直不对——to bottom left 会按盒子
比例换算,卡头宽高比约 15:1 时算出来接近 86°,等于水平色带;即便改成固定
225deg,扁盒子里的线性渐变也只是一条生硬的斜带,做不出角落发散的效果。

* feat(modern): 模型卡卡头晕染定为蓝调

基色改用 --modern-chart-input,与用量统计里 Token 卡同一支蓝,两页同源。

* fix(modern): 阶梯价入口仅保留标准档,Fast/Ultrafast 不再翻译

- Fast、Ultrafast 是计价档位专名(对应 OpenAI service_tier),三语一律不译
- 阶梯价的新增入口收窄到标准档:后端 NormalizeModePriceSchedules 直接驳回
  Fast 带阶梯,此前编辑器对所有档位都给了按钮,加完保存必然失败;
  Ultrafast 后端虽未拦截,按约定前端统一不做
- 非标准档改为提示「仅标准档支持阶梯价」,已存在的阶梯仍可见可删,
  避免静默隐藏却在保存时原样回传

* fix(modern): Fast 与 Ultrafast 档位行为对齐

后端对两档一视同仁:validPricingModeKey 只排除 standard,没有模型级限制;
计费同走 quote.go 查 ModeSchedules,仅触发参数不同(service_tier 取
fast/priority 与 ultrafast)。此前前端只给 Ultrafast 添加入口、删除按钮也
只对 Ultrafast 开放,目录同步来的 Fast 档因此无法删除。

- 添加入口改为按 optionalModes 渲染,两档对称
- 删除按钮放开到所有非标准档
- 阶梯价仍只在标准档提供(Fast 后端驳回,Ultrafast 按约定统一不做)

* fix(modern): 修正价格表头下方的边框重叠

选择器 .row + .row:not(--head) 把紧跟表头的第一个数据行也匹配进去了,
它的上边框与表头的下边框落在同一像素,叠出一条明显更粗的线。改为要求
前一项也是数据行。

* fix(frontend): 限制经典版入口为管理员

* refactor(modern): 精调全局设置页排版

- 状态徽章只在有状态时出现:17 个里 14 个是「默认」,等于反复声明
  「这里没什么特别的」,现仅剩已配置/已修改/环境锁定 3 个
- 设置项控件列由 auto 改为定宽,右边缘从 4 种位置收敛到 1 种
- 表单限宽 760px:内容区近 1000px,撑满会把标签与控件拉得过开
- 分区之间加细线隔断,功能边界不再只靠留白区分
- 子分组标题原先比它统领的设置项标签还小还淡,层级倒置;改用组标签
  质感(caption + 字距 + 延伸线)
- 移除「显示模式 / 界面语言」:右上角已有同样入口,此处重复
- 新版界面预览改用概念图:原先是 24KB 真实截图,与经典版的抽象示意
  图风格割裂;仓库里原有的 modern.svg 实为带虚线框的加号占位图,
  已按 classic.svg 的色板与抽象度重画为「左侧栏 + 卡片」
- 系统信息标签列定宽右对齐:原先 dt 用 flex:none 按各自文字宽度收缩,
  「数据库」与「管理员密钥来源」差近一倍,取值起点全部错开;
  三种更新状态也合并为一行

* refactor(modern): 梳理设置页布局与交互细节

* feat(modern): 完善吉祥物彩蛋与版本更新提示

* feat(modern): 补全总览与路由检查页面

* refactor(modern): 精简首页并整合路由检查

* feat(modern): 重做首页为接入优先布局

首页原本只展示分组、模型、凭据、密钥四个库存计数,这些数字一周不变,
且每个都对应侧边栏的一个导航项。真正回答「现在跑得怎么样」的
/api/home/statistics 接口后端早已实现,经典版在用,新版一直没接。

- 顶部换成一行状态条:服务状态 + 库存事实 + 版本与运行时长
- 接入客户端重做成左目录 + 按客户端类型分化的配置输出:
  CLI 客户端给可一次粘贴执行的终端命令(Codex 的 toml 改写成 heredoc),
  图形客户端给设置界面示意图与编号字段对照,可深链的把一键导入置顶
- 修掉 Cline 的缺口:它需要模型名但输出形态返回空块,
  界面上选了模型却没有任何地方显示,现在模型名是字段表的一行
- 协议不匹配改为选择前就在目录里禁用,提示里点名具体协议
- 路由检查折叠成工具条,不再以完整工作台占据首页
- 右栏依次为订阅账号、需要处理、24 小时请求趋势、访问密钥;
  需要处理由已有的分组数据推出,不额外请求健康接口,
  额度预警不重复(订阅账号已按账号画了额度条)

* refactor(modern): 精调首页接入面板与侧栏排版

上一版实现丢了设计稿里的若干排版细节,逐条补回:

- 客户端目录恢复协议标签。协议枚举全称有 16 个字符放不下,
  给 AppProtocolTag 加 short 模式取短名(Responses / Completions),
  颜色仍由同一处定义,不另写一套
- 界面示意图补上窗口标题栏文字,此前只画了三个点
- 没登记字段原文的客户端补两行无标签占位,示意图要读起来像一个设置表单,
  而不是「这个界面只有三个框」;不替没核实过的客户端编字段名
- 补上「把右边的值按编号填到左图对应的位置」的引导语
- 一键导入横幅不再复用确认对话框的文案(那句带问号),改用常驻横幅的说法
- 整段配置块的标题从裸的 JSON 改成「也可以直接复制完整配置」
- 状态条加入待办入口,与右栏面板共用 collectAttention 的同一份计数
- 订阅账号卡去掉「更新于」(页头已有整页刷新时间)、重置券并进页脚,
  并限制为前 3 个:账号多时这块会把下面三块全顶到折叠线以下

* fix(modern): 修正首页待办取材与侧栏面板的溢出

- 需要处理改读 /api/health。此前只按分组凭据计数判定,推不出额度将尽、
  充值卡临期、访问密钥被费用额度挡住这几类,健康实例上永远是空的,
  看起来就像坏了。现在覆盖无可用凭据、凭据被拉黑、额度将尽、
  充值卡临期、密钥受限五类,状态条计数与面板读同一份结果
- 订阅账号按设计改成一个账号一条进度条,取剩余最少的那个窗口;
  额度宽裕时不写重置时刻,可用是常态不出徽章
- 访问密钥不再溢出:grid 与 flex 子项的 min-width:auto 会让长密钥名
  把徽章顶出卡片,链路上每层都要显式解开;徽章与结论数字不参与压缩
- 补回 HomeAccounts 漏掉的 AppPanel 导入。Vue 对未注册组件不报错,
  整块面板被渲染成 <apppanel> 字面标签,标题与边框全部丢失
- 「还有 N 项」不再套用条目行的三列栅格,此前文字被挤进 14px 的
  图标列,一个字一行
- 待办条目以分组名优先收缩,说明文字先被截断;说明文字同时收短
- 接入面板去掉无用的副标题

* refactor(modern): 精调首页布局与接入交互

* fix(modern): 收紧首页布局并移除客户端协议限制

* fix(modern): 优化首页接入对齐与侧栏密度

* fix(modern): 记住客户端接入选择并修正订阅额度展示

* fix(modern): 统一客户端接入输入尺寸并精简说明

* fix(modern): 优化分组排序与订阅账号周期及并行同步

* fix(modern): 优化订阅额度周期与同步反馈

* fix(modern): 完善首页健康提醒与独立路由检查

* feat(modern): 增加额度窗口满额预估

* refactor(modern): decouple shared frontend utilities

* docs(readme): refresh localized screenshots

* fix(web): harden startup fallback and Group ID parsing
2026-09-16 21:56:51 +08:00
tbphp 16aec0437c fix(control): 修复 MySQL 保留字查询 (#664) 2026-09-16 13:49:25 +08:00
tbphp df72bbb446 fix(codex): 修复 WebSocket 普通账号额度停滞 (#656)
* fix(codex): 修复 WebSocket 普通账号额度停滞

* fix(codex): 支持 WS 额度跨周期重锚

* fix(codex): 改用当前 WS 事件匹配额度来源

* fix(codex): 隔离解析 WS 额度窗口

* fix(codex): 统一额度比较时基并恢复事件预检查
2026-09-15 19:54:57 +08:00
tbphp cb05e16742 docs(readme): 增加赞助展示 (#659)
* docs(readme): 增加 PackyCode 赞助展示

* fix(readme): 适配 PackyCode 深浅色 Logo
2026-09-15 16:08:33 +08:00
tbphp fbefb458dd docs(readme): 添加赞助展示 (#657) 2026-09-15 12:49:34 +08:00
tbphp 91df89efed fix(bifrost): 恢复兼容渠道的工具降级转发 (#653)
* fix(execution): 保留跨协议工具调用约束

* fix(cpa): 修正工具白名单兼容边界

* fix(bifrost): 拒绝丢失压缩上下文

* fix(execution): 保持计数请求工具约束

* fix(bifrost): 恢复兼容渠道的工具降级转发
2026-09-14 22:21:59 +08:00
tbphp 0a19e80d26 fix(gateway): 支持已绑定 WebSocket 通知客户端重连 (#652)
* fix(gateway): 支持已绑定 WebSocket 通知重连

* fix(gateway): 修复 WebSocket 冻结与收尾竞态

* fix(gateway): 保留超限请求登记直到错误交付完成

* fix(gateway): 修正读取失败时的关闭与注销顺序

* fix(gateway): 将二进制消息纳入关闭前登记
2026-09-14 16:32:37 +08:00
tbphp 47a5e124fc fix(gateway): 修复 WebSocket 首错重试与故障转移 (#646) 2026-09-13 22:55:35 +08:00
tbphp fbb99067cc fix(health): 放宽上游错误重试并保留健康边界 (#643)
* fix(health): 放宽上游错误重试并保留健康边界

* fix(health): 补齐资源操作重放与上下文拒绝规则

* fix(execution): 保留明确请求拒绝的分类优先级

* fix(health): 补齐流内 HTTP 错误重试判断
2026-09-13 18:06:37 +08:00
tbphp 5f11d8bdd4 test(cpa): 修复替换连接测试的时序误报 (#644) 2026-09-13 17:41:11 +08:00
tbphp 9605ed208b fix(subscription): 修正 Codex 与 Claude 凭据身份判重 (#639)
* fix(subscription): 修正订阅凭据身份与刷新校验

* docs: 撤回 README 中的凭据身份说明

* fix(subscription): 校验令牌身份冲突并补齐刷新后判重

* fix(subscription): 防止刷新丢失已确认身份

* fix(subscription): 延后批量导入身份判重
2026-09-13 12:26:46 +08:00
tbphp f8a04df46d fix(deepseek): 补齐原生协议字段兼容 (#638)
* fix(deepseek): 补齐原生协议字段兼容

* fix(deepseek): 兼容强制工具调用与默认思考

* fix(deepseek): 跳过空思考字段别名
2026-09-13 11:42:46 +08:00
tbphp d01656a1d8 perf(ci): 迁移自托管运行器并优化并行验收 (#634)
* perf(ci): 切换现有自托管运行器并复用本机缓存

* perf(ci): 将主要 Linux 任务迁至 Mac ARM64 运行器

* fix(ci): 使用动态端口执行 Windows 安装验收

* test(cpa): 等待异步处理完成后校验 WebSocket 行为

* perf(ci): 并行数据库测试并隔离容器验收端口

* ci: 为数据库合同测试启用内存盘

* test(cpa): 固定断连日志脱敏测试的执行顺序

* fix(ci): 修复自托管验收中断和架构兼容问题

* fix(ci): 原子准备 Windows 安装验收配置
2026-09-13 08:31:56 +08:00
tbphp 9d38793dd0 fix(affinity): 统一缓存标识亲和并补齐 Codex 缓存分组 (#635) 2026-09-13 01:25:45 +08:00
tbphp 426bde9a38 fix(cpa): 保留 Codex 和 Grok 的中途系统指令 (#633)
* fix(cpa): 保留 Codex 和 Grok 的中途系统指令

在 Anthropic 转换入口将 system 映射为 developer,保留消息内容和位置,并继续拒绝其他渠道的有损转换。

验证:make check;third_party/cpaembedded 中 go test -count=1 ./...。新增出站回归测试已在修复前复现拒绝,在修复后通过。

用户实测确认:Claude Code 使用 Anthropic 协议请求 Codex 账号的 GPT 模型正常。

* fix(cpa): 对齐计数和执行的系统指令转换

让 Codex/Grok 的 Anthropic 本地计数复用执行请求的指令角色映射,保持其他渠道计数行为不变。补充计数一致性回归测试和工具结果内容断言。

验证:计数回归测试先复现差异,修复后通过;make check 和 CPA embedded 全套测试通过。
2026-09-12 21:01:54 +08:00
tbphp 5b03d29db9 fix(codex): 补齐 WebSocket 额度观测并约束来源匹配 (#632)
* fix(codex): 补齐 WebSocket 被动额度更新

* test(codex): 补充 WS 额度窗口完整性断言

* fix(codex): 保留握手与事件额度的独立观测时间
2026-09-12 19:21:35 +08:00
tbphp c4c8452e6c fix(execution): 保留原生消息前缀并保护转换语义 (#631)
* fix(execution): 补齐原生消息透传并保留对话结构

* fix(execution): 保护转换请求的指令和执行约束

* fix(execution): 补齐无角色历史后的系统指令保护
2026-09-12 17:55:22 +08:00
tbphp 1b50c77673 fix(usage): 统一修正 Anthropic 流式输入与缓存用量 (#630)
* fix(cpa): 修正 Anthropic 流式转换的输入用量统计

* fix(usage): 统一 Anthropic 流式用量修正

* fix(usage): 保留原生流未采集时的执行层用量
2026-09-12 17:08:44 +08:00
tbphp 33ec668550 fix(monitor): 统一筛选操作与跳转的快捷时间行为 (#625)
* fix(monitor): 统一筛选操作与跳转的快捷时间行为

* fix(monitor): 避免应用筛选时重复请求
2026-09-11 14:13:51 +08:00
tbphp b64a389823 feat(ultrafast): 支持请求层级转发与独立计价 (#624)
* fix(codex): 统一快速模式出站参数为 fast

* feat(ultrafast): 支持请求层级转发与独立计价
2026-09-11 13:10:29 +08:00
tbphp c55312e155 feat(groups): 支持选择测试协议和模型并修复禁用分组测试 (#623)
* feat(groups): 支持配置和选择密钥测试协议

* fix(groups): 完善测试模型选择并遵循渠道协议声明

* fix(groups): 修复禁用分组测试并统一测试设置布局

* fix(groups): 统一测试控件样式并复用模型输入
2026-09-11 12:59:01 +08:00
tbphp a895ba25bf fix(execution): 统一普通渠道出站 UA 规则 (#622) 2026-09-11 11:59:15 +08:00
tbphp a628fe82bf fix(monitor): 更新日志筛选快捷时间 (#621) 2026-09-11 08:55:40 +08:00
tbphp 8688dc80b3 fix(gateway): 兼容 WS 请求中的 stream 布尔参数 (#620) 2026-09-11 07:34:02 +08:00
tbphp abc6483d0e fix(codex): 升级 CPA 并固定上游版本声明 (#619) 2026-09-11 00:08:04 +08:00
tbphp f091528bdb feat(gateway): 接入原生 Responses WebSocket 与逐轮治理 (#616)
* feat(gateway): 接入原生 Responses WebSocket 与逐轮治理

* feat(gateway): 增加 WS 分层开关并修复连接治理

* fix(gateway): 关闭停用或删除分组的 WS 连接
2026-09-10 21:18:41 +08:00
tbphp 0c9d188892 fix(codex): 修正请求身份头覆盖与会话兼容 (#617)
* fix(codex): 修正请求身份头覆盖与会话兼容

* fix(codex): 保留显式空值身份请求头
2026-09-10 20:04:23 +08:00
tbphp eecef9f4a8 docs(readme): 添加 OfoxAI 赞助展示 (#614)
* docs(readme): 添加 OfoxAI 精选赞助商

* fix(readme): 恢复 OfoxAI 英文标题原始标点
2026-09-10 16:24:25 +08:00
tbphp 7d80a981d1 feat(codex): 添加独立上游 WebSocket Session 封装 (#612)
* feat(codex): 添加独立上游 WebSocket 会话封装

* fix(codex): 放开 SOCKS5 代理并修正超时分类

* fix(codex): 修正 WS 终态并脱敏断连日志

* fix(codex): 保留失败终态的上游错误码

* fix(codex): 提前注册 WebSocket 日志脱敏
2026-09-10 14:18:36 +08:00
tbphp 7cbd2e672d feat(responses): 实现响应状态续接路由 (#609)
* feat(responses): 实现响应状态续接路由

* fix(responses): 限制响应 ID 长度并兼容缺失字段删除

* fix(responses): 按协议存储能力匹配续接路由
2026-09-09 23:13:41 +08:00
tbphp de6d2d44fc feat(access-keys): 支持自定义密钥并统一编辑与生成交互 (#611)
* feat(access-keys): 支持自定义密钥与强度提示

* fix(access-keys): 恢复默认掩码并按密钥长度分档

* feat(access-keys): 统一密钥编辑与随机生成交互

* style(access-keys): 改用骰子图标生成密钥

* fix(access-keys): 修复筛选幂等判定与恢复状态提示

* fix(access-keys): 统一编辑请求的幂等摘要
2026-09-09 23:05:09 +08:00
tbphp d417b7de04 feat(monitor): 统一日志与用量的时间筛选交互 (#608)
* feat(monitor): 统一日志与用量时间筛选交互

* feat(monitor): 精简快捷时间展示与地址参数

* fix(monitor): 修复日期弹层并统一搜索控件高度

* fix(monitor): 修正时间筛选交互并整理筛选布局

* fix(monitor): 对齐访问密钥筛选下拉框样式

* refactor(monitor): 清理时间与日志筛选冗余代码
2026-09-09 18:10:47 +08:00
tbphp fb18dc9e87 refactor(cooldown): 精简模型冷却展示与管理接口 (#606)
* fix(web): 精调模型冷却展示与筛选样式

* refactor(cooldown): 精简模型冷却展示与管理接口
2026-09-09 15:50:02 +08:00
tbphp fe4b6ac159 feat(gateway): 接入原生文本重排序协议 (#607) 2026-09-09 15:06:50 +08:00
tbphp 7ed01e668b feat(images): 支持 Antigravity 与 Gemini 共享生图转换 (#605)
* feat(antigravity): 支持 Images 单向生图转换

* feat(images): 复用转换并支持 Gemini 渠道生图

* fix(images): 修正生图转换失败分类并恢复候选回退
2026-09-09 13:20:10 +08:00
tbphp 1898d8ee64 fix(gateway): 修复协议查询参数与零输出边界 (#603) 2026-09-09 11:18:20 +08:00
tbphp f0bd09b31a fix(web): 兼容 HTTP 密钥复制并统一失败弹窗 (#602)
* fix(web): 统一复制失败的明文弹窗兜底

* fix(web): 将复制兜底内容改为只读单行输入框
2026-09-09 09:51:31 +08:00
tbphp d4699dd2b1 feat(health): 支持凭据按模型冷却与统一恢复 (#599)
* feat(health): 支持凭据按模型冷却与统一恢复

* fix(health): 修复模型冷却的错误契约与恢复边界

* fix(web): 修复模型冷却展示与重置反馈

* fix(web): 保持分组健康与恢复反馈一致

* fix(health): 修复停用分组的模型冷却身份展示
2026-09-09 08:05:43 +08:00
tbphp a42555469a feat(gateway): 统一全局请求重试预算 (#598) 2026-09-08 20:43:25 +08:00
tbphp 96d3e0d5c7 feat(subscription): 支持多格式订阅凭据导入 (#596)
* feat(subscription): 支持多格式订阅凭据导入

* fix(subscription): 修复批量导入请求边界

* fix(subscription): 保留批量导入超时语义
2026-09-08 20:05:22 +08:00
tbphp e0bfa07ec4 feat(scheduler): 统一凭据权重并调整模型错误重试 (#597)
* feat(scheduler): 统一凭据权重并调整错误重试

* docs: 更新三语配置权重说明
2026-09-08 17:18:08 +08:00
tbphp 175949e20a feat(usage): 支持自定义时间统计并统一时间筛选 (#594)
* feat(usage): 统一时间区间统计与快捷筛选

* fix(usage): 精简时间筛选与趋势提示布局

* fix(usage): 保留未修改时间端点的原始时刻
2026-09-08 13:33:06 +08:00
tbphp a97578fe9b feat(access-keys): 完善访问密钥分发与用量管理 (#590)
* feat(access-keys): 完善访问密钥分发与用量管理

* fix(web): 保留监控上下文并同步复制草稿

* fix(web): 补全发放联系信息并保留排行密钥标识

* fix(monitor): 修复日志入口与用量时间边界

* feat(access-keys): 优化分发界面并精简发放流程

* fix(access-keys): 收紧列表排版并精简发放弹窗
2026-09-08 12:52:42 +08:00
tbphp 9cb3f98688 feat(scheduler): 实现全局加权轮询与连续分配限制 (#591)
* feat(scheduler): 实现全局加权轮询与连续分配限制

* fix(scheduler): 补齐初始停用分组的入场校准

* fix(scheduler): 统一分组恢复校准并修正检查说明
2026-09-08 09:15:47 +08:00
tbphp 2bdc105835 chore(deps): 升级官方 fasthttp 并移除临时替换 (#589)
* chore(deps): 升级官方 fasthttp 并移除临时替换

* docs(licenses): 同步 fasthttp 升级后的第三方声明
2026-09-07 22:18:12 +08:00
tbphp e888fe6035 feat(credentials): 统一全量操作并支持五千条密钥导入 (#587)
* feat(credentials): 统一全量操作并支持五千条密钥导入

* fix(web): 明确恢复全部的凭据范围

* fix(web): 同步密钥导入错误位置上限

* test(requestlog): 修正延迟刷盘测试的同步时序
2026-09-07 21:21:16 +08:00
tbphp 33fb54bfe6 fix(monitor): 修正最近一小时用量与成本统计 (#588) 2026-09-07 20:20:06 +08:00
tbphp 0ddc41d8b7 fix(web): 完善 Claude Code 自定义模型接入示例 (#585)
* fix(web): 澄清 Claude Code 模型发现接入说明

* fix(web): 引导通过环境变量配置 Claude Code 模型
2026-09-07 13:14:48 +08:00
tbphp 25061d6579 feat(pricing): 支持分组与访问密钥价格倍率 (#584)
* feat(pricing): 增加分组与访问密钥价格倍率

* fix(pricing): 在原始总费用计算后应用倍率
2026-09-07 12:41:48 +08:00
tbphp 16be863ea5 fix(subscription): 允许手动刷新恢复异常订阅凭据 (#580)
* fix(subscription): 允许手动刷新恢复异常订阅凭据

订阅凭据刷新遇到网络故障后落入 outcome_unknown,此后所有刷新入口
全部关闭,重启也不恢复,只能重新连接账号或重新导入。

新增 RefreshForManualRecovery 作为唯一允许恢复异常认证状态的入口,
仅由管理面「刷新凭据」使用;数据面自动刷新、模型发现与额度观测继续
沿用原有门禁。放开后原代码「只有 ready 能进入刷新」的前提失效,同步
修正三处连带问题:

- 临时失败与启动失败不再无条件写回 ready,改为写回进锁时的原状态,
  避免一次 503 把状态未知的凭据洗白并放回调度
- 残留 refreshing 归一为 outcome_unknown 再参与恢复,避免界面长期
  显示正在刷新
- 版本复用分支增加认证状态与运行时一致性确认,版本变大不再单独作为
  刷新成功的依据

调度排除、状态展示、失败分类与额度同步入口均保持不变。

Closes #571

* fix(subscription): 修正手动恢复的运行时确认与错误归属

Review 发现放开人工恢复后遗留两处边界:

- ensureRuntimeMatchesDurableSecret 依赖 ReconcileGroup 修复运行时,
  但后者只比较持久化配置,不含 auth_state。运行时版本已是最新、仅
  认证状态落后时会被判定为无需变更并返回成功,账号实际仍不可调度。
  改为先定向同步认证状态,并在返回成功前重新确认版本与状态一致
- 失败分支把用于持久化的历史错误码直接用于 API evidence,异常账号
  重试遇到网络失败时会报告旧的认证问题,残留 refreshing 的
  refresh_interrupted 还会落到需要重新授权的兜底映射。持久化继续
  沿用原状态与原错误码,evidence 改为依据本次失败分类生成

新增两个用例:版本相同仅认证状态落后时经真实 ReconcileGroup 修复;
原状态明确失效或残留 refreshing 时本次网络失败报告为结果未知。
2026-09-07 09:49:55 +08:00
tbphp b621d09a8f fix(i18n): 修正订阅凭据刷新拒绝文案硬编码 Codex 品牌名 (#581) 2026-09-07 09:07:20 +08:00
tbphp 18079996f0 refactor(settings): 重构设置页分区并统一分组设置的覆盖交互 (#576)
* refactor(settings): 按业务语义重排配置分区,收敛默认态展示密度

- 路由策略并入亲和分区(路由与调度),validation_interval 移出超时分组并入重试/凭据健康,
  models_dev_auto_sync_enabled 从请求转发移至数据与维护,header_rules 与 inject_usage_options
  合并为上游请求改写;6 个分区拆为 7 个语义更清晰的分区。
- 新增 SettingRow 承载默认态单行展示、覆盖态才展开控件与说明文字,默认态徽标与操作按钮收敛,
  避免逐字段重复常驻的说明文案。

* refactor(settings): 抽取 SettingRow 为共享组件并同步分组设置页展示密度

- SettingRow 从设置页移至 components/config,替换分组设置页运行时区块里的
  RuntimeOverrideRow,行为对齐:默认态收敛徽标/按钮、覆盖态才展开控件与说明。
- RuntimeOverrideRow 无剩余引用,一并删除。
- 顺带修正分组页 inject_usage_options 折叠态展示 help 文案而非当前值的问题,
  改为展示已启用/已禁用,说明文字移入 help 提示。
- 请求亲和沿用原有 SegmentedControl 三态控件,未纳入本次迁移。

* fix(settings): 按反馈调整 SettingRow 交互细节

- 提示统一用已有 AppTooltip 组件,替换原生 title;且不论是否覆盖,说明都只在
  标签旁以 tooltip 展示,不再于覆盖态额外常驻一份。
- 覆盖/恢复默认按钮从行尾移到值后面,改回可见的按钮样式,不再靠悬停淡入。
- 覆盖态不再叠加“显式覆盖”徽标,仅保留左侧强调色与底色区分;待恢复/环境变量
  锁定两种状态的徽标保留。
- 路由策略改用 SegmentedControl 二选一切换,替换下拉选择,和代理等控件观感一致。
- 各分区行列表之间补上小间距,避免行与行贴在一起。

* fix(settings): 覆盖/恢复默认按钮改为图标 + tooltip

文字按钮换成小方形图标按钮:覆盖用 PencilLine,恢复默认用 RotateCcw,配色沿用
原有 action/warning 两种 tone;按钮不再显示文字,改为 hover/聚焦时通过
AppTooltip 展示对应文案,无障碍上保留 aria-label。

* fix(settings): 覆盖/恢复默认图标去掉按钮底色,仅悬停反馈

去掉常驻边框和背景色,图标默认裸露显示,与旁边的说明提示图标风格保持一致;
悬停/聚焦时才出现对应 tone 的浅色背景。

* fix(settings): 覆盖图标恢复悬停显示

未覆盖态(含待恢复默认)的“覆盖”图标恢复为鼠标悬停/键盘聚焦到该行才显示,
平时隐藏;已覆盖态的“恢复默认”图标保持常驻可见,因为该行本身已有强调色和
底色区分,不需要靠图标常驻来提示。窄屏和纯触屏环境下始终显示,避免无法触发。

* refactor(settings): 移除 inject_usage_options 并统一设置页控件尺寸

移除 inject_usage_options 配置,改为始终注入:
- 该开关只在「OpenAI Completions + 原生透传 + 流式」这一条路径生效(转换路径的
  usage 来自 SDK,Anthropic/Gemini 原生流自带 usage),默认即为开启,暴露为用户
  配置的收益远低于理解成本。
- 后端删除设置键、分组覆盖与渠道约束校验,IncludeUsage 固定为 ObserveUsage;
  新增迁移 0008 清理 system_settings 行与分组 overrides 中的历史键,否则解析器
  会以 "unknown runtime setting" 拒绝整份配置。
- 前端删除两处设置行、资源投影字段与三语文案。

设置页与分组设置页的控件:
- 新增 --setting-control-height,并在 .setting-row/.setting-block 上覆盖
  --control-compact/xs/sm,让输入框、切换控件、下拉统一小一档;变量继承进子组件,
  不需要和组件自身 scoped 样式比优先级。
- 固定行内容高度,折叠态与覆盖态不再有高度差,点开编辑时行不会跳动。
- 块级说明(CORS 策略、下游响应头规则)从常驻小字改为标签旁 tooltip,与设置行一致。

分组设置页删除只读的渠道展示:顶部已有渠道信息,此处重复且不可编辑。

* fix(storage): 修复迁移 0008 在 PostgreSQL 上的两处方言问题

- 反引号是 MySQL/SQLite 语法,PostgreSQL 解析 `key` = ? 直接报 syntax error,
  导致启动中断。改用 GORM 结构体条件,由驱动按方言自行加引号。
- 往 json 列写 []byte 时 PostgreSQL 驱动按 bytea 处理,报 invalid input syntax
  for type json。改为写字符串。

已在 SQLite / PostgreSQL 16 / MySQL 8 三种方言上实跑升级路径:注入历史的
system_settings 行与分组 overrides 后启动,确认键被清除、分组只剩其余覆盖、
迁移正常记账。

* refactor(settings): 合并上游 Header 到跨域分区,统一控件尺寸与请求头/响应头命名

- 分组页控件尺寸未跟着变小,是因为上一轮的尺寸变量覆盖只挂在 .setting-row/
  .setting-block 上;分组页的姓名/验活模型输入框、权重与请求亲和的 SegmentedControl
  都不在这两个类名内。改为挂在 .settings__content/.group-settings__content 内容区
  (不含侧边导航与保存栏),覆盖 --control-compact/xs/sm/md 四个尺寸变量,让设置页
  和分组页的所有交互控件统一收敛到 26px。

- "上游请求改写"分区被删除,header_rules 合并进浏览器访问分区,与 CORS、
  下游响应头规则放在一起(顺序:CORS → 上游请求头规则 → 下游响应头规则);
  该分区原本只剩 header_rules 一项(inject_usage_options 上一轮已删除),
  单独占一个侧边菜单已经没有意义。

- 请求头/响应头命名统一:全局设置页"全局 Header Rules"改名"上游请求头规则",
  与已有的"下游响应头规则"对称;分组页"HeaderRules"同步改名"上游请求头规则"。
  新分区标题定为"Header 与跨域"。

- 清理合并后失效的 settings.headers.* 键(title/currentPublishedRuleCount/
  defaultSource/overrideSource/pendingRestoreSource/override/restoreDefault/
  inherited/resetPending/replacementWarning/securityNotice),改用已有的
  settings.runtime.* 通用状态词汇,与 CORS、下游响应头规则保持一致。

已用真实浏览器验证:分区合并后的顺序与文案、校验横幅跳转到正确分区并定位到
非法输入框、分组页控件高度与设置页一致。

* refactor(group-settings): 统一请求亲和与上游请求头规则的覆盖交互

请求亲和由三态 SegmentedControl 改为 SettingRow 覆盖/恢复默认模式;
上游请求头规则由 details 折叠改为 SettingBlock,并补上独立的覆盖开关,
与设置页的交互模式完全一致;同步移除废弃的展开态路由状态与文案。

* fix(group-settings): 恢复默认时不再回显未保存的旧覆盖值

分组已保存覆盖值后,草稿中点击恢复默认会读到仍是旧覆盖值的 effective
快照,导致视觉上"看起来没变"。为出站代理、超时/次数类、请求亲和、
上游请求头规则补充待恢复态:展示占位文案与徽标,保存后才回填真实的
全局生效值,与设置页面的重置反馈保持一致。

* feat(group-settings): 验活模型改为可搜索候选输入

复用参数覆盖规则里模型输入的 datalist 模式,把分组当前模型作为候选,
输入即过滤;候选取上游模型 ID(验活按该值请求上游),别名作为副标题
展示。后端不限制该值,仍保留自由输入。

* fix(settings): 按 review 处理迁移账本断言与三处设置项细节

- 外部数据库契约里的迁移账本断言硬编码到 0007,只在 PostgreSQL/MySQL 下
  执行,本地 SQLite 会跳过,导致 0008 落库后仅 CI 报错
- 下游响应头规则的待恢复态未取草稿值,取消覆盖后仍回显旧规则,与同区的
  上游请求头规则表现不一致
- 连接与可靠性分区的数字输入清空后写入 0,其中重试次数与拉黑阈值的 0 合法,
  会被静默保存;改为与路由分区一致按 NaN 处理
- 修正 pendingRestoreSource 的英文文案
2026-09-06 22:54:21 +08:00
tbphp 4a99ab1496 fix(subscription): 修复被动额度契约缺失与来源误归属 (#575)
* fix(ui): 接受订阅额度窗口的 source_id 字段

修复 #574 新增 source_id 后前端严格投影拒绝成功响应的问题。补齐可选 DTO 字段、白名单及字符串投影,保持其他未知字段校验,不修改后端额度匹配或限流行为。

新增前后端额度字段契约回归测试,避免后端新增字段却遗漏前端白名单和 DTO。

* chore(ui): 移除额度字段修复中的跨语言契约测试

* fix(subscription): 按 Active-Limit 判定被动额度通用组的归属

上游的 X-Codex-Primary/Secondary-* 报告的是本次请求实际计费到的额度,
而不是固定的普通账号额度。请求 Spark 等专属额度时这一组装的是该额度的
副本,按 codex 收下会用它覆盖同周期的普通窗口,把用尽的 7d 刷成满额。

改为由 X-Codex-Active-Limit 决定该组归属:premium/codex 归普通额度,
指向专属额度时改绑到该来源,上游已单独报告该来源则让位避免歧义。
缺少该头且响应里已有别的来源时按副本丢弃。

* fix(subscription): 按窗口去重被动额度副本而非丢弃整组

Active-Limit 指向专属额度时,通用组只有与独立命名空间来源和周期都相同
的窗口才是重复报告。原先只要该来源存在任意窗口就丢掉整组,会漏掉另一
个周期的刷新。改为解析后按来源加周期逐窗口去重。

* fix(subscription): 限定被动额度去重只比较独立命名空间

通用组内部的 primary 与 secondary 是两份数据而非互为副本,周期相同时
原实现让它们互相判定为重复并双双丢弃。去重范围收窄为通用窗口与独立
命名空间窗口之间。
2026-09-06 11:55:18 +08:00
tbphp 2aa5002a45 fix(subscription): 按来源和周期匹配 Codex 被动额度窗口 (#574)
* fix(subscription): 拒绝跨周期的被动额度覆盖

被动额度合并前校验已有窗口与样本的周期;同 ID 但周期冲突时丢弃整个窗口补丁,避免 7d 被改成 5h,同时污染用量、重置时间及健康摘要。

保留兼容窗口与缺少周期字段的增量更新行为;补充合并与持久化回归测试,不改变限流、额度池或路由调度。

* fix(subscription): 按来源和周期匹配 Codex 被动额度

主动同步保留 metered_feature,响应头按命名空间生成相同来源标识;不依赖模型名称或 Limit-Name。
按同一账号内的来源与实际周期唯一匹配已有窗口,允许 primary/secondary 槽位变化,但保留卡片 ID 与展示元数据。缺少来源/周期或存在歧义时不覆盖;其他渠道继续使用原有 ID 匹配。
补充解析、跨槽位合并、来源隔离、控制面序列化及持久化健康投影测试。无 429、路由或调度改动;旧快照需主动同步一次补齐来源。

* docs(subscription): 修正被动额度快照合并的注释说明

明确无变化时保持原始字节,仅在窗口数据变化时重新编码;不修改任何运行逻辑。
2026-09-06 09:29:35 +08:00
tbphp 2b23d8a62a feat(ui): 补齐权重、分组启停与日志路由入口 (#572)
* feat(ui): 补齐权重、分组启停与日志路由入口

订阅账号卡片支持调度权重(#535):徽章行只在手动权重时露出 chip,
点击一次完成展开并进入编辑;权重面板落在展开区代理面板之上,两块上下堆叠。
自动权重等同代理的继承态,不在折叠态制造视觉噪音。

代理模式改用分段控件,三个模式直接可见;表单不再折行,地址栏独自吸收
剩余宽度。分段控件新增 xs 尺寸,与同排输入框、按钮统一 26px,
顺带修掉密钥列表权重编辑器原本 30px 与 26px 不齐的问题。

分组列表支持快速启停(#554):开关并入状态列,与徽章相邻以区分
「我关的」和「凭据不可用」。集合项新增 enabled 字段——status 还叠加了
weight_manual 为 0 的历史数据,拿它当开关会出现点击后状态不变的假故障。
追加凭据改为纯图标,省下的宽度抵掉状态列扩宽,总表宽反而更窄。

模型列表展示归属分组(#555):上游行挂分组 chip,最多两枚、其余折叠为 +N,
数据本就随列表返回,此前未被消费。

请求日志路由拆成访问密钥与路由两列(#555):路由列首行渠道图标加分组名、
次行凭据编号,分组名可点击就地筛选。按各列实际内容重算宽度,
压出的空间正好装下新列,总宽与拆列前持平。

* fix(ui): 修正开关反馈延迟、按钮内边距与列举分隔符

分组开关此前绑查询数据,而 AppSwitch 是纯受控组件,点击后要等请求与
refetch 走完才翻转,看起来是个卡住的开关。改为本地乐观置位,请求结束
(成功交还 refetch 结果、失败回滚原值)后再交还查询数据。

代理指示器的按钮形态补上 padding/font 复位:容器是固定 22×22 的
border-box,UA 默认内边距会把 13px 图标挤变形。

模型分组折叠提示原先硬编码中文顿号,会漏进英文与日文界面,改用
Intl.ListFormat 按当前语言格式化。实测须用 conjunction + narrow:
narrow 去掉「和 / and」只留分隔符,而 unit 类型在中日文下根本不插
分隔符,会把名字连成一串。

* fix(monitor): 修正日志骨架屏列数

路由列拆成访问密钥与路由两列后,非访问密钥视图的列头与 grid 都是 9 列,
骨架屏仍按 8 列渲染,加载时与表头错位。两处 SkeletonSurface 一并修正。

* refactor(ui): 撤除分组集合 enabled 字段并精简注释

开关改由 status 派生:weight_manual 为 0 虽然也判定 disabled,但该值经
接口限定在 1~100,只有直接改库才能触发,为此新增响应字段与两个测试
超出了本次 UI 补齐的范围。后端与测试恢复原状,本 PR 回到纯前端改动。

同时精简全部新增注释,只保留解释非显然决策的部分,去掉代码本身已经
说清楚的描述。

* feat(monitor): 日志显示凭据掩码并补齐交互细节

日志响应新增 credential_name:按 ID 从凭据注册表取密文解密后算掩码,
订阅账号给邮箱掩码、API 密钥给密钥掩码。密文常驻内存,整个过程不读
数据库,一页内重复出现的凭据只解密一次;注册表里没有的凭据留空,
前端据此显示「已删除 · #id」,与访问密钥、分组共用同一套回退。

分组开关改走设置页同一条缓存失效链路,切换后进入详情页不再需要刷新。

日志中可点击就地筛选的值扩展到访问密钥、分组、凭据、模型四处,样式
提取为全局 filterable-value,此前两个组件各维护一套雷同规则。

订阅卡片的权重徽标与代理徽标统一改用 AppTooltip 并提示可点击编辑;
模型页的分组 chip 直达该分组的模型 tab;日志详情的凭据后增加复制按钮,
与 request_id 的复制控件同尺寸同图标。

* fix(models): 详情抽屉的分组链接直达模型 tab

与模型列表的分组 chip 保持一致,从模型上下文点进分组不再落到凭据 tab。

* fix: 修复样式

* fix: 访问密钥模型页面修复
2026-09-05 21:41:41 +08:00
tbphp 7eb1e3726d fix(web): 补齐 sub2api 图标缺失的 svg 尺寸属性 (#573) 2026-09-05 20:05:20 +08:00
tbphp c86a9ad1da feat(scheduler): 支持原生与转换路由混合权重调度 (#570)
* feat(scheduler): 支持原生与转换路由混合权重调度

* fix(settings): 补齐路由策略当前有效值提示
2026-09-05 12:58:22 +08:00
tbphp ad8be749e3 feat(gateway): 增加分组参数覆盖规则 (#546)
* feat(gateway): 增加分组参数覆盖规则

* fix(gateway): 收紧参数覆盖安全边界

* refactor(web): 优化参数覆盖编辑器样式

* fix(web): 修正参数覆盖编辑器实现

* fix: 修正参数覆盖空键与输入推断

* fix: 拒绝参数覆盖中的负零

* fix(gateway): 纳入覆盖后兼容的候选

* fix(gateway): 固定参数覆盖前的路由上下文

* fix(control): 保留参数覆盖数字字面量

* fix(gateway): 统一参数覆盖请求体限制

* fix(gateway): 避免参数覆盖的 HTML 转义膨胀

* fix(gateway): 限制请求内参数覆盖缓存

* fix(parameteroverride): 避免请求整树解码膨胀

* fix(parameteroverride): 避免深层请求重复扫描
2026-09-05 12:09:14 +08:00
tbphp 559ed2dc88 feat(gateway): 支持数据面 CORS 与响应头规则 (#568)
* feat(gateway): 支持数据面 CORS 与响应头规则

* fix(cors): 修正来源缓存与禁用校验

* fix(cors): 规范化允许来源
2026-09-05 10:34:47 +08:00
tbphp 1c81b69223 chore(deps): 更新 CPA 至 v7.2.151 (#569) 2026-09-05 09:04:22 +08:00
tbphp ae59a0ae85 feat(channel): 增加 Sub2API 渠道 (#567) 2026-09-04 22:55:55 +08:00
tbphp c4cefc0655 chore(ci): 收敛主分支检查与命名 (#564)
* chore(ci): 收敛主分支检查与命名

* test(ci): 加强工作流合同断言
2026-09-04 19:51:00 +08:00
tbphp 1c30bf6ba7 ci: 删除重复依赖漏洞检查 (#562)
* ci: 删除重复依赖漏洞检查

* ci: 禁用 pnpm 安装时的隐式审计
2026-09-04 18:27:51 +08:00
tbphp 1953ae83e6 feat(web): 增加首次额度刷新引导 (#557) 2026-09-04 15:55:20 +08:00
tbphp 097029ff09 fix(gateway): 冻结流终态后的观测结果 (#553) 2026-09-04 00:52:22 +08:00
tbphp 1ff3424a7e docs(readme): 优化赞助展示与致谢结构 (#536) 2026-09-03 15:49:36 +08:00
tbphp 21fa526a29 fix(gateway): 统一 Responses store 路由兼容 (#532)
* fix(gateway): 统一 Responses store 路由兼容

* fix(gateway): 收紧 Responses 降级归一化

* fix(channel): 将 DeepSeek 标记为无状态
2026-09-02 19:54:30 +08:00
tbphp 14e8e98c4f fix(settings): 移除 ETag 并简化保存流程 (#530) 2026-09-02 16:29:59 +08:00
tbphp 0b8ee145f6 fix(gateway): 兼容 Responses store 无状态降级 (#527)
* fix(gateway): 兼容 Responses store 无状态降级

* fix(responses): 收紧无状态降级边界
2026-09-02 05:31:56 +08:00
tbphp e6b752b4db feat(channel): 增加 GPT-Load 上游渠道 (#526) 2026-09-01 21:52:38 +08:00
tbphp 1be3587000 feat(channel): 增加 CLIProxyAPI 多协议渠道 (#525) 2026-09-01 21:07:19 +08:00
tbphp d7d28370da feat(channel): 增加 New API 多协议渠道 (#524) 2026-09-01 19:56:40 +08:00
tbphp 91173361a3 fix(import): 无匹配渠道时回退兼容渠道 (#523) 2026-09-01 19:04:52 +08:00
tbphp 182367f4d3 docs(readme): 增加 AxisNow 赞助商 (#522)
* docs(readme): 增加 AxisNow 赞助商

* docs(readme): 加粗 AxisNow CDN 文案
2026-09-01 16:00:14 +08:00
tbphp 718fdae85a feat(group): 增加模型同步与清理 (#518) 2026-09-01 10:40:03 +08:00
tbphp 85b6f79dac fix(home): 同步套餐徽标等级配色 (#517) 2026-09-01 07:39:17 +08:00
tbphp a7d11adf96 重做首页常用订阅账号卡片视觉设计 (#515)
* feat(home): 重做首页常用订阅账号卡片视觉设计

* fix(home): 常用订阅账号容器改为换行网格,去掉横向滚动

* fix(home): 首页常用订阅账号上限改回 4 个,PC 默认单行不换行

* fix(home): 修复 mini card 焦点窗口选择与标签周期丢失问题

* fix(home): 修复迷你订阅卡额度与可用状态显示

* fix(home): 优先展示已耗尽额度窗口
2026-09-01 06:50:29 +08:00
tbphp 30a1bac965 fix(release): 修正 CPA 版本文档漂移与数据库合同测试遗漏 (#514)
* fix(release): 修正 CPA 版本文档漂移与数据库合同测试遗漏

THIRD_PARTY_NOTICES.md 与 cpaembedded/README.md 的 CLIProxyAPI 版本号
未随 #507 依赖升级同步,仍是 v7.2.143(实际 v7.2.144)。

ci.yml 与 release.yml 的数据库合同测试 -run 正则手工维护测试名单,
已产生漂移:ci.yml 含一个不存在的测试名(静默不匹配),两者都缺失
TestExternalDatabaseMySQLRecoversObservationFreshnessCheckDrop,
release.yml 还缺失 TestExternalDatabaseAccessKeyCostLimitPeriodPermutation。
改为按前缀匹配同目录下全部 TestExternal* 测试,避免后续再次漂移。

补上 ja-JP/settings.ts 缺失的 runtime.pendingRestoreSource key,
该 key 在 4 个组件共 8 处引用,此前日文界面回退显示英文文案。

* fix(storage): 修正 0003 迁移恢复对 MySQL 中间态的误判

启用数据库合同测试的完整名单后,
TestExternalDatabaseMySQLRecoversObservationFreshnessCheckDrop
第一次在真实 MySQL 上执行即失败:ValidateCurrent0001 仅凭
fresh_until_ms 列是否存在判断 0003 是否已完成,但 MySQL 上
0003 的 DROP CHECK 与 DropColumn 是两条独立、非事务性 DDL,
崩溃可能停在"约束已删、列还在"的中间态。此时 ValidateCurrent0001
误判为"0003 未开始",转而用要求约束存在的冻结校验器 Validate0001,
导致误报 chk_credential_observation_fresh_until 缺失。

改为以约束是否存在作为判断信号,与同文件 ValidateRecoverable0003
已经正确处理该中间态的逻辑保持一致。已用一次性 MySQL 8.4 与
PostgreSQL 18 容器验证三态恢复路径与完整数据库合同测试套件。
2026-08-31 21:10:42 +08:00
tbphp 70fdd862f2 fix(security): 收紧 OAuth 与数值边界 (#513) 2026-08-31 18:51:59 +08:00
tbphp 3d14c18dcf feat(release): 统一 2.x 镜像标签通道 (#512) 2026-08-31 17:35:12 +08:00