github-actions[bot]
b7dba62678
chore: sync VERSION to 0.2.2 [skip ci]
2026-09-07 13:01:57 +00: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
wucm667
b59f3bf46c
fix(simple-mode): enforce basic group boundaries
2026-09-07 09:20:48 +08:00
wucm667
f46038820b
fix(simple-mode): enforce group capability allowlist
2026-09-06 08:11:23 +08:00
wucm667
a3675552bd
feat(simple-mode): allow basic account grouping
2026-09-06 08:10:41 +08:00
TT
95023e7d49
fix(backup): serialize pg_dump/psql with the migrations advisory lock
2026-09-06 00:11:56 +08:00
github-actions[bot]
ab99d56e96
chore: sync VERSION to 0.2.1 [skip ci]
2026-09-05 09:45:17 +00:00
github-actions[bot]
5097b31457
chore: sync VERSION to 0.2.0 [skip ci]
2026-09-02 03:24:57 +00:00
github-actions[bot]
a2fb09260a
chore: sync VERSION to 0.1.185 [skip ci]
2026-09-01 02:52:28 +00:00
github-actions[bot]
52374af940
chore: sync VERSION to 0.1.184 [skip ci]
2026-08-31 09:28:15 +00:00
wucm667
a3bbf33c05
fix(monitor): scope groups by user access
2026-08-30 09:28:40 +08:00
github-actions[bot]
7634e3c23b
chore: sync VERSION to 0.1.183 [skip ci]
2026-08-25 13:53:14 +00:00
github-actions[bot]
aa2c4e8d13
chore: sync VERSION to 0.1.182 [skip ci]
2026-08-25 04:47:52 +00:00
github-actions[bot]
e2d9b823f6
chore: sync VERSION to 0.1.181 [skip ci]
2026-08-24 14:35:57 +00:00
github-actions[bot]
03e8ab4134
chore: sync VERSION to 0.1.180 [skip ci]
2026-08-24 07:30:34 +00:00
Wesley Liddick
c40edb4070
Merge pull request #6139 from xz-dev/fix/configurable-model-list-read-limit
...
feat(gateway): configure model list read limit
2026-08-24 15:04:50 +08:00
Wesley Liddick
5f43696a9a
Merge pull request #6121 from creamtea47/codex/feat-openai-auto-reset-credit
...
feat: OpenAI 重置卡按用量阈值自动使用
2026-08-24 14:39:59 +08:00
Xiangzhe
847c0c4526
feat(gateway): configure model list read limit
...
Add gateway.models_list_read_max_bytes with the existing 8 MiB behavior as its default, and apply it consistently to generic, Codex, and Antigravity model-list reads.
Read one sentinel byte for Codex manifests so oversized responses return an explicit bounded upstream error instead of malformed JSON.
2026-08-24 14:20:18 +08:00
NellPoi
6f972145b7
feat: 支持 OpenAI 重置卡按用量阈值自动使用
2026-08-24 13:28:33 +08:00
feeeei
377d1230fc
模型广场:按计费阶梯单价表展示长上下文档位
...
- 新建 ModelPlazaService(持计费服务与定价解析器)承接广场聚合,
token 模型的单价与档位全部取自 ResolveContextPricingSchedule,
渠道选择与计费同源;图片/按次模型沿用原档位合成
- 官方参考价改走计费目录(LiteLLM → 内置兜底 → 模型策略),带官方阶梯
- DTO 增加 long_context_pricing_enabled / long_context_basis /
official_pricing.intervals
- 前端实付与官方三列按档分行(标签只在首列,其余列按行对齐),
缓存列按档展示写/读价,边际计价以徽章与 tooltip 标注,
分组关闭阶梯时在头部说明
2026-08-24 10:50:52 +08:00
shaw
40ea3aebad
feat: add OAuth outbound transport plugin system
2026-08-24 09:03:37 +08:00
github-actions[bot]
2bc139ab52
chore: sync VERSION to 0.1.179 [skip ci]
2026-08-20 07:06:50 +00:00
Randark
1128df2592
fix(monitor): align quota-fetcher credential/balance semantics with scheduler
...
P2-1/P2-3 from review:
- fetchCNQuota: credential-invalid now judged by StatusCode 401/403
(aligned with fetchCNBalance) instead of `!Success && !CredentialValid` —
CN quota service only sets CredentialValid=true on the success path, so
500/429/zhipu business errors were all misclassified as failed instead
of error.
- fetchCNBalance: snapshot carries new BalanceLow flag computed with the
scheduler's exact criterion (`!Available || allCNBalancesBelowThreshold`)
against Gateway.CNProviders.BalanceThreshold (ctor now takes cfg; wire
regenerated). quotaDegradedHint reports "balance low" instead of the old
`<=0` check, so an account already paused by the scheduler (balance 5 /
threshold 10) no longer shows green in the monitor.
- threshold helper falls back to viper default 0.5 for nil/<=0 config to
avoid a zero-threshold regression where balance=0 stops alerting.
Tests: CN quota status-code matrix (rewrites the test that cemented the
old behavior), balance-low matrix (below-threshold / unavailable /
multi-currency healthy), threshold-from-config; PayG stubs now set
Available explicitly (zero-value trap).
2026-08-18 10:28:28 +00:00
github-actions[bot]
49504adc98
chore: sync VERSION to 0.1.178 [skip ci]
2026-08-18 10:03:19 +00:00
Randark
41344c20ff
feat(monitor): wire quota fetcher & expose check_mode in handlers
...
- handler DTO: create/update 接收 check_mode/account_id,provider oneof 扩至 8 家,
endpoint/api_key 改为 omitempty(条件必填下沉 service 校验);
monitor/checkResult/historyItem 响应透传 check_mode/account_id/quota
- 用户端 latest_quota 由 channel_monitor_show_quota 控制,关闭时服务端剥离
- wire: NewChannelMonitorQuotaFetcher 以具体服务类型收参(窄接口包内保留供
stub),ProvideChannelMonitorRunner 注入后 SetQuotaFetcher
2026-08-18 04:14:15 +00:00
Wesley Liddick
e330c243a8
Merge pull request #5666 from Randark-JMT/feat/cn-providers-kimi-zhipu-deepseek
...
feat: 国产供应商多协议支持(Kimi/Zhipu/DeepSeek 原生 Anthropic 直通 + DeepSeek Responses)与配额/余额监控
2026-08-17 14:55:20 +08:00
github-actions[bot]
baeac1f3de
chore: sync VERSION to 0.1.177 [skip ci]
2026-08-15 13:40:21 +00:00
Randark
901a0439f1
feat: 国产供应商一等支持(Kimi/Zhipu/DeepSeek 多协议 + 配额/余额监控)
...
后端:
- 协议凭证维度 credentials[api_protocol] ∈ chat_completions(默认)/anthropic/responses(deepseek)
- /v1/messages 零转换直通原生 Anthropic 端点(kimi/zhipu/deepseek),CC/Responses
入站交叉组合走 apicompat 双向转换链(responses/chat_completions anthropic-native 转发器)
- count_tokens:anthropic 协议透传原生端点;其余 CN 协议本地 tiktoken 估算
- Coding Plan 额度探测(5h/weekly 滚动窗口)+ payg 余额探测(kimi/deepseek),
deepseek 双币种 CNY+USD 明细,任一币种达标不停调
- 周期任务 [CNBalance] 并发探测 + 预算随工作量放大;响应式 429 冷却到最早窗口
重置点;余额不足可恢复临时停调;智谱 CREDIT_LIMIT 不污染窗口解析
- CC→anthropic 流式客户端断开后继续排水上游保住 usage 计量
前端:
- 创建/编辑弹窗 account_mode + api_protocol + base_url 联动预设(含 watcher 竞态防护)
- 用量单元格:kimi/zhipu coding 显示 5h/weekly 窗口,kimi/deepseek payg 显示余额,
多币种并列展示;探测失败保留快照;挂载自动探测 5min 去抖
- 调度阈值设置面板补 kimi/zhipu 平台(对齐后端 AllowedSchedulingThresholdPlatforms)
2026-08-15 10:37:51 +00:00
github-actions[bot]
0e82efe489
chore: sync VERSION to 0.1.176 [skip ci]
2026-08-13 01:46:47 +00:00
Wesley Liddick
e803e3851c
Merge pull request #5559 from seng1e/fix/scheduled-backup-leader-lock
...
fix(backup): 定时备份加 leader 锁,避免多实例重复备份
2026-08-13 09:24:11 +08:00
Wesley Liddick
5912ae960c
Merge pull request #5543 from luckydududu/fix/invalidate-channel-cache-on-group-platform-change
...
fix(group): 改分组 platform 后失效渠道缓存(否则最长 10 分钟按旧平台计价)
2026-08-13 09:24:00 +08:00
seng1e and Claude Opus 4.8
bba6a55e0f
fix(backup): 定时备份加 leader 锁,避免多实例重复备份
...
仓库里所有周期任务都用 tryAcquireSingletonLeaderLock 选主、只让一个实例跑
(ops:*、dashboard:aggregation、subscription:expiry、payment:order:expiry 等),
唯独定时备份 runScheduledBackup 没接这套锁,每个实例都自己跑一遍。
多实例部署下同一时刻:
- 同一个库被 N 次 pg_dump;
- 内存峰值 ×N —— 归档整个读进内存再上传,内存吃紧的节点会直接 OOM;
- 上传的是同一个带时间戳的 key,N 份互相覆盖,白干一场连多余副本都留不下。
实测 3 节点:每天 backup_records 里三条一模一样的记录(同 key、同大小)。
改动:把 BackupService 接进和其它任务一样的 tryAcquireSingletonLeaderLock
(key=backup:scheduled:leader)。只锁定时备份,手动备份(CreateBackup/
StartBackup)不锁;无协调后端(cache/db 均 nil)时不加锁照常跑,单机/单测
行为不变;锁 TTL 35m > 备份自身 30m context 上限,防止大库 dump 中途锁过期。
wire_gen.go 由 wire 重新生成。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-08-12 21:36:41 +08:00
github-actions[bot]
ef4f99f292
chore: sync VERSION to 0.1.175 [skip ci]
2026-08-12 11:07:43 +00:00
Lucky
814ecfba7c
fix(group): invalidate the channel cache when a group's platform changes
...
The channel cache holds a groupID -> platform map with a 10 minute TTL, and
only channel Create/Update/Delete call invalidateCache(). Changing a group's
platform through the admin API therefore leaves the cache pointing at the old
platform for up to 10 minutes.
Channel pricing, model mapping and the model whitelist are all matched per
platform, so during that window the lookups silently miss: pricing falls back
to the global LiteLLM price list, renames stop applying and the whitelist
stops restricting. Nothing is logged.
Inject a narrow ChannelCacheInvalidator into the admin service (same shape as
the existing APIKeyAuthCacheInvalidator) and call it from UpdateGroup only when
the platform actually changed. The dependency is optional -- when it is nil the
cache simply rebuilds on TTL expiry, as before.
2026-08-12 03:22:06 +00:00
github-actions[bot]
48eb3766d2
chore: sync VERSION to 0.1.173 [skip ci]
2026-08-09 08:26:22 +00:00
shaw
d92edc01be
Merge origin/main into feat/channel-monitor-v2-ops-ui
...
Resolves three conflicts, all of the "both branches appended to the same
block" shape. Every one is resolved as a union of both sides; nothing from
either parent is dropped.
- handler/admin/setting_handler_update.go: keep ChannelMonitorHideThroughput
(V2) alongside GrokDefaultTextModel / GrokCrossClientModelMapEnabled /
GrokDefaultBaseURLMode (#5408 ). UpdateSettings writes every key on each
save, so dropping either side would reset those settings to zero values.
- service/domain_constants.go: keep SettingKeyChannelMonitorHideThroughput
and the three SettingKeyGrok* constants.
- repository/migrations_runner.go: keep the 195 checksum rule (V2) and the
218/219/220 rules (#5408 ).
2026-08-09 12:11:35 +08:00
IanShaw027
1f58e25ab3
Merge upstream/main into feat/grok-complete-integration
...
冲突集中在 chat completions / messages 两条 Responses 转发路径:
upstream 给 OpenAIForwardResult 增加了 UpstreamResponseModel 与
UpstreamResponseModelConflict(配套 beginUpstreamResponseModelObservation
观测器),本分支在同样位置把返回值改成了具名变量以便挂 Grok 原生搜索计数。
两侧不互斥,合并结果同时保留上游的响应模型观测字段与 Grok SearchCount 逻辑。
frontend/pnpm-lock.yaml 取 upstream 版本:package.json 与 upstream 完全一致,
本地差异只是 pnpm install 的重解析噪音。
2026-08-08 11:12:56 +08:00
IanShaw027
68faeac837
fix(grok): restore base URL resolution and operator settings wiring
...
Honor account GetGrokBaseURLOr policy for official vs custom endpoints,
and wire settings resolution used by responses/chat URL builders.
2026-08-08 01:07:19 +08:00
github-actions[bot]
68d8f122e4
chore: sync VERSION to 0.1.172 [skip ci]
2026-08-07 15:39:12 +00:00
IanShaw027
25d2b03e90
fix(grok): 加固 OAuth 会话共享与一次性消费
2026-08-07 16:29:48 +08:00
IanShaw027
d0930c4bdb
fix(grok): 完善密码与SSO授权能力控制
2026-08-07 14:13:07 +08:00
IanShaw027
a5beecb92a
feat(channel-monitor-v2): 接入模式开关、路由门控与依赖注入
...
注册 admin/user 路由与 feature/mode 守卫,串联 Wire DI 与设置读写,
公开 channel_monitor_mode 与 hide_throughput 等运行时标志。
2026-08-07 11:05:32 +08:00
github-actions[bot]
aac53afe0e
chore: sync VERSION to 0.1.171 [skip ci]
2026-08-04 13:41:47 +00:00
feeeei
26e0a89323
人机验证增加阿里云验证码 2.0
...
沿用腾讯天御验证码引入的多服务商模型:aliyun_captcha_enabled 作为独立
开关,与 Cloudflare Turnstile、腾讯天御三方互斥(保存校验 + 运行时
CAPTCHA_PROVIDER_CONFLICT)。后台「安全与认证」合并为单张人机验证卡片:
总开关 + 服务商单选(Turnstile / 腾讯天御 / 阿里云),选中即启用该家并
关闭其它,落库仍是三个独立开关键,由前端映射保证互斥。
阿里云侧同时支持 aliyun 中国站与国际站(alibabacloud.com):两站前端脚本、
region 取值与服务端 API 完全一致,仅账号与 AccessKey 相互独立,因此由
「服务地域」决定线路即可——中国内地走 captcha.cn-shanghai.aliyuncs.com,
非中国内地(新加坡)走 captcha.ap-southeast-1.aliyuncs.com,AccessKey
取自持有该实例的账号,无需在配置中区分站点。
- AliyunCaptchaService 对称 TencentCaptchaService:服务端校验走官方 SDK
VerifyIntelligentCaptcha,调用异常按 fail-closed 拦截,与 Turnstile
网络错误行为对称;保存设置时真实探测 AK/SK 有效性
- 保护面对齐腾讯扩展入口:VerifyTencentCaptchaIfEnabled 通用化为
VerifyActionCaptchaIfEnabled,OAuth 登录启动、passkey 登录在阿里云
启用时同样拦截;Turnstile 维持既有覆盖不扩大
- 前端 AliyunCaptchaWidget 为表单内预验证按钮(popup 模式),同时暴露
verify() 供 OAuth 启动、passkey 等动作入口程序化弹窗;未预验证直接
提交时弹窗兜底。SDK 按钮绑定异步完成,弹窗未出现前按 tick 重试触发,
并轮询弹窗可见性识别用户关闭
- captchaVerifyParam 复用 turnstile_token 请求字段提交;公开设置下发
aliyun_captcha_enabled / scene_id / prefix / region
- CSP 放行验证码 CDN:script-src/style-src 加 *.alicdn.com
2026-08-04 20:57:15 +08:00
Wesley Liddick
8b3fe664dc
Merge pull request #5261 from lyen1688/feat/tencent-captcha-gate
...
新增腾讯天御验证码认证门禁
2026-08-04 16:39:55 +08:00
lyen1688
e592c5f9e0
新增腾讯天御验证码认证门禁
2026-08-04 15:09:29 +08:00
zhiyu
2eb24814fe
fix(codex): 强制统一出站身份并让客户端版本号跟随官方发布
...
上游 /backend-api/codex 在容量紧张时按客户端身份分优先级降载,被降载的请求
HTTP 200 后立刻推流内 server_is_overloaded。此前网关对配不出官方身份的客户端
整体回退到硬编码的 codex_cli_rs/0.144.1(落后官方 4 个发布),这些请求稳定
落在被优先丢弃的一侧。
- 强制统一出口:所有 OAuth 出站的 User-Agent / originator / version 一律改写
为网关规范身份,客户端自报身份不参与构造;HTTP / 透传 / WS / alpha-search /
探针全覆盖。compat 桥接故意删除 originator 的路径保持 no-op。
- 版本号收敛为单一来源,运行时优先级为面板覆写 → 自动同步值 → 内置常量;
UA 与 version 头同源派生,不再各自硬编码。
- 新增 3 小时自动同步官方客户端最新稳定版,面板可关闭,无需为跟版本而发版。
- 流内 server_is_overloaded / slow_down 改为先在同账号有界重试再切号,并标记为
请求级瞬时故障,不再据此临时封禁账号。
- 移除被取代的降载身份黑名单、浏览器 UA 兜底及其辅助函数。
2026-08-03 20:14:58 +08:00
rick147
a0802f00b6
feat: cache OpenAI reset credit details
2026-08-02 21:32:31 +08:00
github-actions[bot]
7e2e9ba050
chore: sync VERSION to 0.1.170 [skip ci]
2026-08-02 10:46:21 +00:00
shaw
dec47e8fae
fix(profit-control): stop leaking profit policy, close veto livelock, restore passthrough turn pricing
...
审计修复,逐条如下。
H1 利润策略泄露给所有普通用户
profit_control_enabled / profit_min_margin / profit_safety_buffer 从
dto.Group 移到 dto.AdminGroup(后者内嵌前者),赋值相应从
groupFromServiceBase 移到 GroupFromServiceAdmin;前端 TS 同步从 Group 移到
AdminGroup。dto.Group 是 GET /api/v1/groups/available 的响应体,该响应本就带
rate_multiplier,相乘即可反推运营方上游采购成本上限。
api_contract_test.go 的 /groups/available golden JSON 回滚这三个字段,并把
fixture 改成非零值(require.JSONEq 是精确比对,缺字段即失败)。
新增 dto 层边界测试:普通用户 DTO 不含三字段、管理员 DTO 仍含。
M1 利润终检 continue 与 failover 503 退避互动产生活锁
FailoverState 新增 profitVetoedAccountIDs / profitVetoCount 与
RecordProfitVeto():加入排除集 + 计数,达 maxProfitVetoAttempts(10) 返回
FailoverExhausted。HandleSelectionExhausted 的 503 清空分支改为清空后把利润
否决的账号放回排除集;若排除集已全部由利润否决贡献,清空不会带来任何新候选,
直接判定耗尽(否则 SwitchCount 永不前进、退避条件永远成立,每 2s 空转一轮)。
五个 handler 否决点(gateway_handler ×2 / responses / chat_completions /
gemini_v1beta)改为经 RecordProfitVeto 决策,耗尽时按无可用账号终止。
回归测试钉死:503 之后持续利润否决必须有限步终止且不 spin;未启用利润控制的
请求退避语义完全不变。
M2 排队等槽后才终检,延迟可放大到 N × WaitPlan.Timeout
OpenAI 侧选号循环(自有 failedAccountIDs map,非 FailoverState)新增
recordOpenAIProfitVeto + handleOpenAIProfitVetoExhausted,共用同一上限语义。
覆盖 responses / messages-dispatch / chat_completions / alpha_search /
embeddings / images / grok_media 七处,以及 WS 两处否决分支。
M4 ws_v2 透传 ingress 绕过 per-turn 重定价(选方案 B:最小止血)
透传 relay 只回调 AfterTurn、没有任何 turn 起始回调,hooks.BeforeTurn 永远
不触发,而 handler 把 turnPricingAt 初始化成建连时刻 ⇒ 透传连接全部 turn 按
建连时刻的高峰因子结算,客户端峰前建连保活即可全程谷价——正是本 PR 想堵的
漏洞。改为 openAIWSTurnPricing 零值起步、只由 BeforeTurn 冻结;透传路径保持
零值,RecordUsage 回退记录时刻,与引入利润控制前的基线一致。
未选方案 A(给透传补 turn 起始回调):passthrough_relay.go 是 #5167 刚修过的
取消传播/close frame 时序敏感区;且 BeforeTurn 还承担 turn>1 的并发槽位抢占,
接进去等于给透传连接引入 per-turn 抢槽,风险远超本次修复范围。透传仍有建连时
的准入门,只是没有 turn 级复核,已在两处注释写明。
测试:service 层钉死透传 ingress 不触发 BeforeTurn(含失败时的复核指引),
handler 层钉死零值语义与逐 turn 覆盖。
M5 装门读分组走了带账号计数聚合的 GetByID
SchedulerSnapshotService 新增 GetGroupByIDLite,openai/gateway 两处装门改用
之。门只需要平台/倍率/利润/高峰字段,且该查询发生在「是否启用利润控制」判定
之前,未启用的分组同样付代价。两个测试 stub 的 GetByID 改成 panic 守卫。
M6 认证快照注释与真实读取路径相反
门解析优先取 ctxkey.Group,而它就是本快照物化出来的对象,直连流量走的正是这
条路。改正注释,与 api_key_repo.go 投影处的说明对齐,避免后人照旧注释删列。
M3 rate_multiplier 为 nil 时利润门 fail-closed(不改行为,加护栏)
保留 fail-closed。补 repository 层测试钉死账号调度快照的 full/metadata 两份
payload 都必须保留 RateMultiplier(含 0 值),漏列在 CI 就红。
L1 迁移号注释 191 / 191-192 改为实际的 192/193。
L2 admin group Create 的利润配置预校验改用与 CreateGroup 一致的归一化平台
(新增 service.NormalizeGroupPlatform,两边共用)。保留预校验而非删除:
service 层返回的是无类型 error,经 ErrorFrom 会变成 500,删掉会把合法的
400 降级成 500。
L3 前端利润校验的上界改为判定换算后的小数(后端按小数校验 [0,1)),
99.999% 会四舍五入进位成 1.0 而被后端 400;i18n en/zh 同步改为 0-99.99。
L4 clampProfitControlThreshold / profitControlOverThreshold 抽为共用函数,
线上装门/否决点与 profit-preview 不再各自实现,附边界语义测试。
L5 profit-preview 补「默认 D 有账号但最低有效 D 归零」的告警(两档都为 0 由
既有告警覆盖,不重复)。
2026-08-01 22:39:33 +08:00