L494264Tt
6082d02d22
Merge origin/main into fix/deepseek-reasoning-content
2026-05-19 17:00:57 +08:00
Wesley Liddick
2a242aec0f
Merge pull request #2573 from wucm667/feat/redeem-code-expiry
...
feat(redeem): 兑换码支持设置使用有效期
2026-05-19 16:25:12 +08:00
Wesley Liddick
66fca3d598
Merge pull request #2572 from wucm667/fix/openai-silent-refusal-failover
...
fix(openai): 识别上游静默拒绝(空流+finish_reason=stop)并触发 failover
2026-05-19 16:15:54 +08:00
Wesley Liddick
a929e285ce
Merge pull request #2271 from StarryKira/fix/redact-account-credentials
...
fix(security): 屏蔽 admin 账号接口返回的敏感凭证字段
2026-05-19 16:15:36 +08:00
Wesley Liddick
32037cb17b
Merge pull request #2570 from wucm667/fix/ops-sla-exclude-ip-denied
...
fix(ops): 用户 IP 限制导致的 ACCESS_DENIED 不计入 SLA 错误
2026-05-19 16:03:16 +08:00
wucm667
e4aaf0af29
feat(redeem): 兑换码支持设置使用有效期
2026-05-19 15:53:28 +08:00
wucm667
6381f9e37d
fix(openai): 识别上游静默拒绝并触发 failover
2026-05-19 15:48:36 +08:00
wucm667
271aba1abe
fix(ops): exclude IP-denied access from SLA
2026-05-19 15:41:54 +08:00
Wesley Liddick
1b6ed24c33
Merge pull request #2492 from DaydreamCoding/feat/dingtalk-login
...
feat(dingtalk): 钉钉 OAuth 登录接入 + internal_only 用户属性同步
2026-05-19 15:36:13 +08:00
DaydreamCoding
b19da9c7fe
feat(dingtalk): 钉钉 OAuth 登录接入与 internal_only 用户属性同步
...
⚠️ 应用类型约束:当前实现仅支持「钉钉登录-企业内部应用」(DingTalk 开放平台
internal_app 类型)。第三方个人应用、第三方企业应用类型暂不支持——OAuth 流程
相同但 corp 校验、跨企业行为不同。backend 通过 DingTalkAppKind 校验对非
internal_app 类型 fail-closed(硬约束)。
钉钉 OAuth 登录主链
- 4 步 OAuth 链:ExchangeCodeForUserToken / GetUnionIdByUserToken /
GetUserIdByUnionId / GetStaffInfoByUserId;app token 缓存
- pending session 机制持久化 OAuth 中间态;cookie-only token 持久化
- 三种分流:bind_login_required / email_completion / choose_account_action
- corp_restriction_policy 支持 none + internal_only;stale "whitelist" 在
加载层与写入层均静默 coerce 为 none + slog.Warn
- bypass_registration 开关:企业内部模式豁免全局 REGISTRATION_DISABLED
- isReservedEmail / signup_source / canUnbindProvider / OAuth pending flow
等横切点支持 dingtalk provider
- migration 136:4 表 CHECK 约束加入 'dingtalk' provider 值
internal_only 模式同步企业邮箱/姓名/部门到用户属性
- SyncCorpEmail / SyncDisplayName / SyncDept 三个独立开关 + 对应
SyncXxxAttrKey 目标属性 key(默认 dingtalk_email / dingtalk_name /
dingtalk_department);非 internal_only policy 在写入层与加载层均
coerce 为 false,admin handler 与 setting_service 双层兜底
- 同步语义:首次注册写 users.username(昵称优先 → 企业姓名 fallback),
之后每次登录刷新 3 个属性;空值也写入以覆盖旧值
- 邮箱三级 fallback:org_email > email > extension["企业邮箱"]
(钉钉自定义字段 JSON)
- 部门路径递归向上拼接,跳过 dept_id=1 选首个真实子部门,剥离根组织名
- GetUnionIdByUserToken 同时返回 OIDC /contact/users/me 的 nick 字段;
新增 GetDeptInfo 调用 OAPI /topapi/v2/department/get
- AuthHandler 注入 UserAttributeService;OAuth pending flow 在
createPendingOAuthAccount / bindPendingOAuthLogin 分别派发到
AfterRegistration(syncUsername=true)/ AfterLogin
- migration 137 seed dingtalk_email/name/department 三个用户属性定义
附带修复(同集成路径暴露的两个 OAuth 注册回归)
- LoginOrRegisterOAuthWithTokenPair 新建用户分支用 inferLegacySignupSource
覆写 caller 显式传入的 signupSource,导致 dingtalk/linuxdo/oidc/wechat
渠道授权按 email 渠道读取;改为只在 caller 未显式传入时回退邮箱推断
- mergeProviderDefaultGrantSettings 把 parse fallback 默认值
(Concurrency=5 / Balance=0) 当作"未配置"哨兵,admin 显式设 5 时被误判
退回全局默认(复现:全局默认 1 + 渠道默认并发 5 + grant_on_signup → 新
用户实际 concurrency=1);去掉哨兵,admin 任何 >=0 值都覆盖 globalDefaults
前端
- DingTalk Login / Callback / EmailCompletion / ChoiceAccount / Error
视图;router + auth API client
- admin SettingsView:corp policy radio(none / internal_only)+ bypass
注册开关 + i18n;internal_only 下展示三同步开关 + 目标 attr key 下拉
(拉取 user attribute definitions),展示 fieldEmail /
qyapi_get_department_list 钉钉权限申请提示
- Profile:S1 主动绑定 / S5 解绑钉钉按钮 + 合成邮箱防自锁
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 15:27:47 +08:00
DaydreamCoding
664e9fdcd4
feat(usage): 用户用量按平台拆分 + UsersView 列设置可配置 + 用量列排序
...
后端
- BatchUserUsageStats / UserDashboardStats 新增 ByPlatform 字段
复用 ops 路径 COALESCE(g.platform, a.platform) 语义,不冗余 DB 字段
- 抽出 usageLogEffectivePlatformExpr 常量供管理员与用户两路径共用
- GetBatchUsersUsage cacheKey 加 v=2 + 当日日期,修复跨午夜旧缓存兼容新字段
前端
- 新建 PlatformUsageBreakdown:管理员用量列 hover tooltip 展示各平台 today/total
- 新建 PlatformCostCell:单平台 today/total 紧凑单元格
- UsersView 列设置新增 Claude/OpenAI/Gemini/Antigravity 四个平台子列,默认隐藏可手动启用
- 普通用户 Dashboard 新增 Row 3 平台拆分卡片,受 isSimple 控制
- 平台之和 < 总值时显式展示"其他"行,避免数字对不齐
- last_active_at 从 FORCED_VISIBLE_COLUMNS 移除,允许用户隐藏并持久化
- 列设置加 schema 版本号 + 迁移机制,老用户升级时新增默认隐藏列自动应用
- UsersView 用量列(汇总 + 4 平台子列)加入前端单页排序:列头单按钮 + 弹出菜单
切换"今日 / 近30天",三态循环 desc → asc → off;菜单底部备注"仅对本页数据排序"
- sortedUsers computed 在 server-side-sort 结果之上叠加本地排序,缺失值按 0 处理;
usageSort 状态独立 localStorage 持久化,互不干扰后端 sort_by
- i18n 新增 admin.users.sortBy / sortCurrentPageOnly
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 15:25:34 +08:00
shaw
b006e36af9
style(openai-ws): 修复 passthrough_relay gofmt 对齐
...
PR #2444 引入的 activeTurn 字段未按 gofmt 对齐,导致 golangci-lint
报 gofmt 错误。运行 gofmt -w 调整字段类型对齐到与同结构其他字段一致。
2026-05-19 15:20:02 +08:00
Wesley Liddick
2ec9b0d7ba
Merge pull request #2412 from gaoren002/fix/codex-auto-review-gpt55
...
fix(openai): add codex auto review model pricing
2026-05-19 15:14:36 +08:00
shaw
0c34e31881
fix(gemini): 修复 chat completions compat 编译失败
...
PR #2451 引入的 gemini_chat_completions_compat_service.go 调用了
已被 4840194b 删除的 extractImageSize 方法,导致 main 分支自合并
后无法编译,连带 test/golangci-lint/govulncheck 三个 CI 全部失败。
按照 gemini_messages_compat_service.go 的现行模式,改用
extractImageInputSize + normalizeOpenAIImageSizeTier 两步调用,
并补齐 ForwardResult.ImageInputSize 字段以保持行为一致。
2026-05-19 15:10:24 +08:00
Wesley Liddick
548c71c8bb
Merge pull request #2557 from Arron196/fix/issue-2542-daily-card-expiry-mode
...
fix: 修复日卡跨日重复刷新额度
2026-05-19 14:53:22 +08:00
Wesley Liddick
8a9f7ae2f1
Merge pull request #2444 from astro-ge/fix/passthrough-first-token-ms
...
fix(passthrough): 修复WSv2模式下first_token_ms测量错误
2026-05-19 14:52:55 +08:00
Wesley Liddick
902af920b7
Merge pull request #2456 from Evsdrg/fix/unbounded-queries-and-sort
...
fix(repo): 公告查询添加分页上限,优化分组按账户数排序的数据加载方式
2026-05-19 14:51:59 +08:00
Wesley Liddick
8a4ee578cb
Merge pull request #2451 from wucm667/codex/issue-2237-gemini-chat-completions
...
fix(gateway): 修复 Gemini 组 Chat Completions 路由
2026-05-19 14:47:52 +08:00
Wesley Liddick
e365aae450
Merge pull request #2450 from wucm667/codex/issue-2431-responses-api-support
...
feat: 支持后台配置 OpenAI Responses API 路由
2026-05-19 14:47:10 +08:00
Wesley Liddick
ac856633aa
Merge pull request #2449 from wucm667/fix/payment-product-name-affix
...
fix: 修复订阅支付商品名前后缀不生效
2026-05-19 14:46:09 +08:00
Wesley Liddick
36e461e7c9
Merge pull request #2424 from wucm667/fix/openai-versioned-base-url
...
fix(openai): handle versioned compatible base URLs
2026-05-19 14:44:37 +08:00
Wesley Liddick
23e95b77b7
Merge pull request #2528 from wucm667/fix/openai-responses-null-content
...
fix(openai): 修复 chat-completions 转 responses 时 content 为 null 导致上游 400
2026-05-19 14:43:55 +08:00
Wesley Liddick
03473d3ee8
Merge pull request #2554 from Arron196/feature/sync-upstream-models-pr
...
feat: 支持从上游同步账号可用模型列表
2026-05-19 14:42:47 +08:00
Wesley Liddick
ae4c738887
Merge pull request #2457 from wucm667/fix/openai-fast-policy-default-pass
...
fix: 默认透传 OpenAI service_tier
2026-05-19 14:34:37 +08:00
Wesley Liddick
aa1460feb3
Merge pull request #2475 from is7Qin/feat/available-channels-default-pricing
...
feat(channels): 「可用渠道」对未填价的 pricing 条目按 LiteLLM 默认价展示
2026-05-19 14:33:17 +08:00
Wesley Liddick
c65522641d
Merge pull request #2473 from is7Qin/fix/image-tier-validation
...
fix(channels): 按次/图片计费模式下区间校验跳过 token 上下文重叠规则
2026-05-19 14:28:33 +08:00
Wesley Liddick
57603e169e
Merge pull request #2461 from wucm667/fix/image-gen-upstream-context-detach
...
fix(gateway): 修复图片生成上游请求过早取消
2026-05-19 14:14:50 +08:00
Wesley Liddick
be0c857240
Merge pull request #2502 from yangzc2004-bit/codex/gemini-google-one-429-cooldown
...
fix: use tier cooldown for google one gemini 429
2026-05-19 14:07:25 +08:00
Wesley Liddick
a340002c6d
Merge pull request #2401 from 2ue/fix/normalize-image-billing-size
...
修复图片计费尺寸归一化与使用记录展示
2026-05-19 14:00:24 +08:00
name
ddab7de916
Merge branch 'main' into fix/image-tier-validation
2026-05-19 11:06:17 +08:00
name
d70497a669
Merge branch 'main' into feat/available-channels-default-pricing
2026-05-19 11:06:15 +08:00
Wesley Liddick
14f54be03f
Merge pull request #2481 from weak-fox/lyp/fix-issue-2223-capacity-retry
...
fix: 修复 OpenAI 模型容量错误未进入自动重试
2026-05-19 10:24:18 +08:00
Wesley Liddick
f9fec78b70
Merge pull request #2505 from is7Qin/fix/openai-compat-usage-parsing
...
修复 Claude 映射 GPT 后被记为 0 token 的计费漏洞
2026-05-19 09:53:50 +08:00
shaw
a729752de6
test: align codex tool-call id assertions with fc_ prefix
2026-05-19 09:45:05 +08:00
Wesley Liddick
11870cf84f
Merge pull request #2499 from yetone/fix/codex-transform-fc-underscore
...
fix(codex-transform): preserve underscore when rewriting `call_*` tool-call ids
2026-05-19 09:39:25 +08:00
Wesley Liddick
e318376e88
Merge pull request #2548 from Arron196/fix/sla-exclude-capacity-errors
...
fix: 统一 Ops SLA 与请求错误统计口径
2026-05-19 09:29:22 +08:00
Wesley Liddick
d1910751b6
Merge pull request #2541 from DanisJiang/fix/alipay-pagepay-qrcode
...
fix(payment): 修复支付宝官方扫码二维码生成错误
2026-05-19 09:24:23 +08:00
benjamin
a4884b4e75
fix(subscription): 将日卡改为一次性每日配额
...
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent )
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-18 21:09:11 +08:00
benjamin
36c00374d3
feat: expose upstream model sync admin API
...
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent )
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-18 19:01:33 +08:00
benjamin
b9ecf25207
fix: harden Antigravity model list requests
...
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent )
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-18 19:01:23 +08:00
benjamin
ba676e43fd
feat: add upstream model sync service
...
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent )
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-18 19:01:12 +08:00
lyen1688
164e2f610c
fix: add keepalive for Anthropic passthrough streams
2026-05-18 18:41:25 +08:00
benjamin
6acb46c113
fix: 标记通用网关本地调度容量错误
...
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent )
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-18 16:52:32 +08:00
benjamin
429adbc721
fix: 标记 OpenAI 本地调度容量错误
...
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent )
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-18 16:52:20 +08:00
benjamin
ae6ee23e2e
fix: 调整 Ops 错误分类的 SLA 排除逻辑
...
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent )
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-18 16:52:06 +08:00
L494264Tt
1d47fd6300
This preserves DeepSeek reasoning_content across chat compatibility paths.
...
DeepSeek thinking-mode tool-call conversations may require the assistant
reasoning_content from previous turns to be sent back in later requests. Without
preserving it, those conversations can fail or lose reasoning context.
Changes:
- Preserve assistant reasoning_content when converting Chat Completions messages
to Responses input by wrapping it as a thinking block.
- Add regression coverage for non-streaming DeepSeek responses.
- Add regression coverage for streaming DeepSeek deltas.
- Add regression coverage that request-side messages[].reasoning_content is
passed through with tool calls.
Tests:
go test -tags=unit ./internal/pkg/apicompat ./internal/service -run
'TestChatCompletionsToResponses_AssistantReasoningContentPreserved|
TestChatCompletionsToResponses_AssistantThinkingTagPreserved|
TestForwardAsRawChatCompletions_PreservesDeepSeekReasoningContent|
TestForwardAsRawChatCompletions_ForcesStreamUsageUpstreamAndPassesUsageDownstream
2026-05-18 11:22:23 +08:00
Yuhao Jiang
1b03240515
fix(payment): 修复支付宝官方扫码二维码生成错误
...
支付宝官方服务商在 precreate(当面付)不可用回退到 page.pay 时,
错误地把网页跳转 URL 当作可扫码二维码内容返回。前端用 QRCode 库
把这段 URL 渲染成二维码后,支付宝 APP 无法识别(扫到的只是个 HTTP
URL,不是支付二维码),用户必须点"重新打开支付页面"跳转到支付宝
收银台才能扫到真正可用的二维码。
- 后端 alipay.go:createPagePayTrade 不再把 PayURL 塞给 QRCode;
createDesktopTrade 在 paymentMode == "redirect" 时跳过 precreate
直接走 page.pay,避免没开通"当面付"的商户走一次无用的 API 调用
- 前端管理端 PaymentProviderDialog:让支付宝官方实例可在"支付模式"
中选择"跳转",开启后始终在新标签页打开支付宝收银台
- ProviderCard 的 modeLabel 增加 redirect 分支
- 补充 TestCreateTradeRedirectModeSkipsPrecreate 单元测试
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 15:01:17 -05:00
lyen1688
cc5328c491
修复 OpenAI Responses SSE 终止事件识别
2026-05-17 15:33:34 +08:00
wucm667
df82a3bc69
fix(openai): avoid null content when converting chat-completions to responses
...
When a chat-completions message has no usable content parts (empty array,
empty text part, or filtered-out image part), marshalChatInputContent
marshalled a nil slice to JSON null. The upstream Responses API rejects a
null content field with HTTP 400. Fall back to an empty string instead.
Fixes #2515
2026-05-17 11:20:05 +08:00
name
0393bd7c82
Fix OpenAI compat usage parsing
2026-05-16 03:03:43 +08:00