Wesley Liddick
2dff7af0f9
Merge pull request #6954 from feeeei/fix/quota
...
fix(quota): 修复仪表盘默认会给所有人分配显示所有平台卡片的问题
2026-09-11 16:34:18 +08:00
Wesley Liddick
7145484fde
Merge pull request #6971 from ouchihao/codex/issue-1890-ttft-request-details
...
fix(ops): show first-token latency in TTFT request details
2026-09-11 13:58:37 +08:00
Wesley Liddick
87e01596b7
Merge pull request #6850 from reallyfeishi/fix/channel-monitor-utc-buckets
...
fix: anchor channel monitor date_bin buckets to UTC
2026-09-11 09:31:22 +08:00
chihao.ou
b112805ffa
test(ops): align query matcher formatting with gofmt
2026-09-10 21:21:08 +08:00
chihao.ou
e9f5add97c
fix(ops): show first-token latency in TTFT request details
2026-09-10 21:13:17 +08:00
feeeei
4a4b50d807
fix(quota): 平台限额表只保存已配置限额的记录,仪表盘按用量与限额展示平台
...
user_platform_quotas 只保存至少配置了一档限额的记录;不存在的行等价于不限额。
- 注册播种只为配置了限额的平台建行,一个都没有时不写入
- IncrementUsageWithReset 无行时不再 fail-open 建行
- BatchSnapshotUsage 改为只更新既有活跃行,不再插入无限额的新行
- 仓储 BulkInsertInitial/UpsertForUser 把三档全空的记录视为未配置;
管理员全量替换接口同样剔除,清空限额即软删并放弃累计用量
- 迁移 238 删除三档全 NULL 的历史行
- 用户仪表盘平台卡片 = 有用量的平台 ∪ 配置了限额的平台,计数改为卡片数
- 管理员限额弹窗对未保存限额的平台禁用"重置窗口"
2026-09-10 16:41:58 +08:00
wangjunwei
de76baaa0d
fix(scheduler): preserve Anthropic threshold metadata
2026-09-09 17:13:37 +08:00
reallyfeishi
f180fbb884
fix: anchor channel monitor buckets to UTC
2026-09-08 23:02:06 +08:00
Wesley Liddick
233f3dffe6
Merge pull request #6281 from wuji-labs/feat/http2-long-stream-keepalive
...
feat(upstream): add HTTP/2 PING keepalive for long LLM generation streams
2026-09-08 20:47:07 +08:00
Wesley Liddick
c54897a59d
Merge pull request #6815 from Pluviobyte/codex/fix-directed-proxy-backups
...
fix(proxies): make backup references directed and shareable
2026-09-08 20:46:32 +08:00
Wesley Liddick
15557e7796
Merge pull request #6235 from StarryKira/codex/fix-6232-channel-cache-invalidation
...
fix: broadcast channel cache invalidations across instances
2026-09-08 20:42:45 +08:00
Wesley Liddick
1923d1c27d
Merge pull request #6814 from feeeei/fix/go-redis-pool-nil-ctx-panic
...
fix(redis): 升级 go-redis 至 v9.22.0,修复连接池 nil-ctx panic 竞态
2026-09-08 20:09:59 +08:00
Wesley Liddick
28b807a735
Merge pull request #6816 from Pluviobyte/codex/fix-repeated-proxy-fallback
...
fix(proxies): allow repeated expiry fallback and preserve origin
2026-09-08 20:07:08 +08:00
Wesley Liddick
dbe92a1c24
Merge pull request #6758 from DuskLin/feat/minimax-platform
...
feat(minimax): 增加 MiniMax 平台支持
2026-09-08 18:50:06 +08:00
Rain
7137fae2a6
test(proxies): preserve incoming references when editing backups
2026-09-08 13:58:34 +08:00
Rain
859de4c8fd
fix(proxies): allow repeated expiry fallback and preserve origin
2026-09-08 13:56:20 +08:00
Rain
e835f79819
fix(proxies): make backup references directed and shareable
2026-09-08 13:56:19 +08:00
feeeei
99eba19ffc
fix: 升级 go-redis 至 v9.22.0 修复连接池 nil-ctx panic
...
上游竞态:调用方超时后 wantConn.ctx 被置 nil,拨号 goroutine 用 nil ctx
创建超时上下文触发 panic(go-redis#3630,v9.18.0 起修复)。
生产环境在连接池饥饿 + 请求超时风暴下每秒触发上万次。
同步将 ZRangeByScore 迁移至 ZRangeArgs:v9.22.0 将其标记为 deprecated,
golangci-lint staticcheck 拦截(SA1019)。ZRangeArgs{ByScore: true} 与原
调用发出的 Redis 命令参数完全等价(LIMIT 编码逻辑相同)。
2026-09-08 13:46:59 +08:00
shaw
4a7739acdf
fix(db): converge groups.model_allowlist on upgrade
...
235 只在「models_list_config 存在且 model_allowlist 不存在」时重命名,而迁移一旦
写入 schema_migrations 就会按「文件名 + checksum」整份跳过,不再重跑。因此只要数据库
在 235 之后回到旧结构(为回滚旧版本镜像手工改回列名、或按旧结构做了部分恢复),
应用依旧能正常启动,但每个关联 groups 的查询都会失败:
pq: column groups.model_allowlist does not exist
表现为「API 密钥」「我的订阅」「管理端订阅列表」等页面加载失败。
新增可重放的收敛迁移 236,升级即自愈:只有旧列则重命名(数据原样保留);两列并存
则在新列仍为默认空值时回填旧列配置;两列都没有则按默认值补建。收尾统一把
model_allowlist 归一成 NOT NULL DEFAULT '{}',与 ent schema 对齐。
判定列是否存在改用 attrelid = 'groups'::regclass(跟随 search_path),
不再写死 table_schema = 'public',避免与 ALTER TABLE 的解析路径分叉。
Fixes #6780
2026-09-08 09:15:23 +08:00
shaw
2031c1d5ad
fix(groups): merge main and resolve model allowlist conflicts
...
Resolve three conflicts from main's #6680 (supplementUnmappedOpenAIModels):
1. gateway_handler.go — keep PR's allowlist refactoring (ModelAllowlistEnabled,
writeAllowlistedModelsList, modelListingSource); main's OpenAI branch in
writeModelsList was auto-merged.
2. group_models_list.go (modify/delete) — delete file per PR intent; relocate
supplementUnmappedOpenAIModels to group_model_allowlist.go where gateway_service
and openai_codex_models_service can still call it.
3. openai_codex_models_service.go — combine main's supplementUnmappedOpenAIModels
wrapping with PR's ModelAllowlistEnabled() guard.
Also fix two auto-merged test files that still referenced the old
GroupModelsListConfig / ModelsListConfig types.
2026-09-07 19:44:03 +08:00
Wesley Liddick
abf70750fd
Merge pull request #6669 from ssharkkky/fix/redeem-fixed-failure-window
...
fix(redeem): use a fixed 10-minute failure window
2026-09-07 18:49:51 +08:00
Wesley Liddick
88b697d5df
Merge pull request #6673 from ssharkkky/fix/backup-migrations-advisory-lock
...
fix(backup): serialize pg_dump/psql with the migrations advisory lock
2026-09-07 18:49:34 +08:00
Zero Clover
81ff9384cb
fix(groups): merge main and resolve model allowlist conflicts
2026-09-07 18:33:39 +08:00
刘佳林
19382f275e
feat(minimax): 增加 MiniMax 平台支持
...
把 MiniMax 做成与 Kimi / 智谱 / DeepSeek 同级的国产供应商平台:账号创建/编辑、分组、Composite 路由、原生 Token Plan / Coding Plan 额度,以及 OpenAI 兼容模型列表。
额度走 GET api.minimaxi.com|io /v1/api/openplatform/coding_plan/remains(Bearer)。只解析 model_name=general 的 remaining percent;周窗口仅在 current_weekly_status=1 时计入。
Related to #6742
2026-09-07 18:22:56 +08:00
wucm667
b59f3bf46c
fix(simple-mode): enforce basic group boundaries
2026-09-07 09:20:48 +08:00
wucm667
4a4fd35e0c
fix(simple-mode): guard non-empty group deletion
2026-09-06 08:11:23 +08:00
TT
95023e7d49
fix(backup): serialize pg_dump/psql with the migrations advisory lock
2026-09-06 00:11:56 +08:00
TT
666a5c6f87
fix(redeem): use a fixed 10-minute failure window
...
The redeem failure counter used INCR followed by Expire(24h) on every
attempt, so each failed attempt refreshed the key TTL and the window
never actually closed for a user who kept retrying within 24h.
- Count attempts in a fixed 10-minute window via a small Lua script
(INCR, then PEXPIRE only when the key is created or has no TTL), which
is atomic and also repairs keys that lost their TTL.
- Move the counter to the redeem:ratelimit:v2: key space so pre-existing
24h counters do not seed the new window.
- Rename the service threshold to redeemMaxFailedAttempts (30) to reflect
that it bounds attempts per window, not per hour.
Public redeem behavior is unchanged apart from the window semantics:
the check fails open when the counter read fails, and a failed
increment never masks the underlying domain error.
2026-09-05 23:38:50 +08:00
Wesley Liddick
d2f87c612e
Merge pull request #6638 from feeeei/feat/images-url-to-b64json-backfill
...
feat(images): 账户开关将生图结果 url 下载回填为 b64_json
2026-09-05 16:24:40 +08:00
Wesley Liddick
fb44e2dd09
Merge pull request #6514 from StarryKira/codex/anthropic-reasoning-pricing
...
feat: add Anthropic reasoning effort and Fable 5.1 max pricing
2026-09-05 16:19:18 +08:00
Zero Clover
55c5eed9fc
test(repository): persist model allowlists in group fixtures
2026-09-05 16:11:46 +08:00
Zero Clover
cff3f89850
feat(groups)!: enforce model allowlists across gateway endpoints
2026-09-05 16:05:17 +08:00
Wesley Liddick
9517f12cdd
Merge pull request #6510 from wall-wxk/fix/release-session-slot-on-forward-failure
...
fix(gateway): 转发失败的请求立即释放会话槽,不再占用整个空闲超时窗口
2026-09-05 16:05:06 +08:00
feeeei
c227863d51
fix(images): 生图 url 回填下载拒绝私网目的地并只信字节嗅探
...
账户开关 images_url_to_b64_json 下载的图片 url 来自上游响应,是不可信输入。此前沿用
base_url 的 security.url_allowlist 策略,默认配置下只做格式校验,上游返回
localhost:8080 之类地址时网关会真的去请求内网。
- 下载 URL 主机为 localhost、回环、私网、链路本地、未指定地址的字面量时直接拒绝,
不受 security.url_allowlist 配置影响(urlvalidator 导出 IsBlockedHost)
- 新增 ctx 标记 WithHTTPUpstreamPublicHostsOnly:共享上游客户端对带标记的请求无视配置
校验解析后 IP,并为其克隆客户端挂 redirectChecker,重定向保持跟随但每一跳都校验
- 下载内容改为只信 http.DetectContentType 嗅探结果且限 png/jpeg/webp/gif,
响应头不再作为依据
- 下载失败仍只记日志并保留原样;超时与端口策略不变
2026-09-05 15:50:56 +08:00
Wesley Liddick
570bd084c2
Merge pull request #6594 from wucm667/fix/issue-6592-preserve-zero-system-metrics
...
fix(ops): preserve zero-valued system metrics
2026-09-05 15:02:40 +08:00
Wesley Liddick
c4e6dcfd80
Merge pull request #6602 from ZeroClover/feat/codex-manifest-pinned-accounts
...
feat(codex): pinned-accounts Codex model manifest for OpenAI groups
2026-09-05 14:51:17 +08:00
Zero Clover
1e28ef5942
feat(codex): pinned-accounts Codex model manifest for OpenAI groups
2026-09-05 00:10:24 +08:00
wucm667
9ddf69698d
fix(ops): preserve zero-valued system metrics
2026-09-04 18:51:24 +08:00
feeeei
de27905e88
feat(usage): 用量记录落库上游请求标识并支持按账户配置响应头名
...
- usage_logs 新增 upstream_request_id 列(迁移 232)与仅索引非空行的 CONCURRENTLY 部分索引(迁移 233,runner 登记失效索引清理)
- 账户 extra.upstream_request_id_header 指定要读取的上游响应头,只读该头;留空不记录;创建/更新/批量入口校验头名合法且不超过 64 字节
- ForwardResult/OpenAIForwardResult 携带 UpstreamHeaders,中央计费按账户解析落库,WS 轮次保持 NULL
- 管理端用量明细新增默认隐藏的"上游ID"列,带与请求ID列一致的复制按钮,并同步导出
- 创建/编辑账户弹窗新增"上游ID"输入(UpstreamRequestIdHeaderField),提示按接入类型与平台分条列出常见头名
- HelpTooltip 悬停模式下指针移入提示框时保持打开,便于选中复制提示内容
2026-09-03 18:02:15 +08:00
haruka
8249ab37db
feat: add Anthropic reasoning effort pricing controls
2026-09-02 20:16:57 +08:00
wall-wxk and Claude Opus 4.6
9be9c0b68c
fix(gateway): 转发失败的请求立即释放会话槽,不再占用整个空闲超时窗口
...
会话数量限制(max_sessions)此前只有空闲超时自动过期,没有任何主动释放
机制:请求在选号阶段注册会话后,即使转发失败(上游错误/客户端断开/换号
耗尽),该 session hash 也会占住槽位直到空闲超时(默认 5 分钟),导致
max_sessions 受限的账号在窗口内拒绝所有新会话。
修复:
- SessionLimitCache 新增 UnregisterSession(Redis ZREM),立即移除会话注册
- GatewayService 新增 ReleaseAccountSession,适用条件与 checkAndRegisterSession 对齐
- Messages 主路径:记录 failover 链上注册过会话槽的账号,请求最终失败时
统一释放;failover continue / profit veto / 兜底分组切换时按次即时释放;
成功及"上游已计量部分结果"(#5148)保持既有空闲超时语义
- CountTokens:转发失败时同样释放选号时注册的会话槽
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-09-02 18:45:20 +08:00
WUJI-Labs
9dc4c40bff
test(upstream): align HTTP/2 keepalive tests with long-stream profile API
2026-09-02 12:28:37 +08:00
WUJI-Labs
81fd853005
feat(upstream): add HTTP/2 PING keepalive for long LLM generation streams
...
Long-running LLM inferences (such as high-thinking Gemini models) may experience
silent TCP disconnections across intermediate proxies, NAT gateways, or firewalls
when no data frames are emitted for tens of seconds to minutes.
Go's default http2.Transport sets ReadIdleTimeout=0 (disabling active PING checks).
This commit introduces HTTPUpstreamProfileLongStream with:
- ReadIdleTimeout = 10s
- PingTimeout = 5s
When a pooled H2 connection stays idle for 10s during long streams, active PING frames
are dispatched. Dead connections failing to respond within 5s are proactively evicted,
preventing client generation requests from hanging on dead sockets or failing with EOF/502.
Signed-off-by: WUJI-Labs <zoujincool@gmail.com >
2026-09-02 12:11:17 +08:00
Wesley Liddick
f2804eb2c8
Merge pull request #6444 from Ritel-T/pr/group-free-openai-fast
...
Add group-level Standard billing for OpenAI Fast requests
2026-09-02 09:23:49 +08:00
Wesley Liddick
559960865a
Merge pull request #6447 from DuskLin/feat/openai-reasoning-effort-over-limit
...
feat(groups): 推理强度上限增加超限自动降档与拒绝访问
2026-09-02 09:07:53 +08:00
Wesley Liddick
a4fb58e428
Merge pull request #6443 from Ritel-T/pr/group-openai-fast
...
Add group-level OpenAI Fast enforcement
2026-09-02 09:07:05 +08:00
Wesley Liddick
8d0b5ede28
Merge pull request #6458 from HuntercodeT/fix/scheduler-projection-keeps-openai-passthrough
...
fix(scheduler): keep OpenAI passthrough flag in the scheduler snapshot projection
2026-09-02 09:05:51 +08:00
haruka
34b8bf1a6e
feat: support Claude Fable 5.1
2026-09-02 05:47:01 +08:00
Ritel-T
52c7d88340
chore: merge upstream v0.1.185
2026-09-02 03:29:52 +09:00
Ritel-T
9e2d97f250
chore: merge upstream v0.1.185
2026-09-02 03:28:24 +09:00