superman2003
f8445a241b
fix(grok): round-trip Codex client tools on Responses
2026-07-22 12:15:48 +08:00
Wesley Liddick
ebfaf2496b
Merge pull request #4674 from AdrianZhaoDev/main
...
feat(groups): add OpenAI reasoning policy
2026-07-22 09:37:06 +08:00
Wesley Liddick
a185705d19
Merge pull request #4684 from superman2003/fix/opencode-codebuddy-cache
...
fix(grok): preserve OpenCode and CodeBuddy cache sessions
2026-07-22 09:36:41 +08:00
Wesley Liddick
003deac540
Merge pull request #4696 from tylzh97/fix/issue-4694-codex-relay
...
fix(codex): 保留级联中继的客户端指纹
2026-07-22 09:36:28 +08:00
Chenhao
8ffa2a31ff
fix(codex): 保留级联中继的客户端指纹
2026-07-21 05:02:30 -07:00
superman2003
e31783e443
fix(grok): preserve OpenCode and CodeBuddy cache sessions
2026-07-21 15:22:12 +08:00
superman2003
bd62c6f66c
fix(monitor): stop scheduling after API key decryption failure
2026-07-21 11:55:38 +08:00
zhaozewu
6c93f01c97
fix(groups): tighten reasoning policy
...
Remove unsupported none handling, align the auth cache version with the current baseline, consolidate the unshipped migrations, and update the public API contract.
2026-07-21 11:16:04 +08:00
zhaozewu
6af622c340
feat(groups): add OpenAI reasoning policy
...
Persist reasoning ceilings and exact mappings for OpenAI groups, enforce them across HTTP and WebSocket forwarding, and invalidate cached auth snapshots.
2026-07-21 11:02:43 +08:00
Wesley Liddick
04a61ee6ad
Merge pull request #4667 from jianjianai/new/perf-scheduler-snapshot-id-members-upstream
...
优化快照发布临时分配
2026-07-21 10:43:37 +08:00
Wesley Liddick
1f9eac4fbd
Merge pull request #4660 from superman2003/fix/openai-scheduler-exclusion-observability-20260720
...
fix(scheduler): 高级调度器无可用账号错误补充排除原因统计,可自诊断静默剔除 (#4599 )
2026-07-21 10:43:21 +08:00
Wesley Liddick
0b9d44545b
Merge pull request #4641 from abbzbb/pr/grok-responses-compact
...
feat(grok): 基于 Grok Responses 实现 /responses/compact 适配 (#4554 )
2026-07-21 10:43:04 +08:00
Wesley Liddick
927fcbc1e3
Merge pull request #4645 from fengshao1227/fix/responses-hosted-image-gen-billing
...
fix(billing): 合并 hosted image_generation 工具的图片 token 到 /responses 计费
2026-07-21 10:42:46 +08:00
Wesley Liddick
14701ff070
Merge pull request #4664 from wucm667/fix/issue-4656-sync-cache-billing
...
fix: align sync cache billing after failover
2026-07-21 10:42:07 +08:00
Wesley Liddick
e85878624a
Merge pull request #4657 from suuuuuu-1/fix/sse-field-parsing-compatibility
...
fix(gateway): support compact SSE format in Anthropic /responses bridge
2026-07-21 10:41:50 +08:00
Wesley Liddick
8b4c8823d9
Merge pull request #4658 from superman2003/fix/cc-bridge-compact-sse
...
fix(gateway): Chat Completions 桥接受 Anthropic 上游的 SSE 紧凑格式
2026-07-21 10:41:33 +08:00
jjaw
af3b6bbd68
优化快照发布临时分配
2026-07-21 03:07:01 +08:00
wucm667
addd5ef1dc
[verified] fix: align sync cache billing after failover
2026-07-20 22:43:11 +08:00
superman2003 and Cursor
a319333161
fix(lint): summary 检查 strings.Builder WriteString 返回值 (errcheck)
...
Co-authored-by: Cursor <cursoragent@cursor.com >
2026-07-20 21:52:46 +08:00
superman2003 and Cursor
29bea0a758
fix(scheduler): 高级调度器无可用账号错误补充排除原因统计
...
问题背景(Refs #4599):OpenAI OAuth 账号请求 /v1/responses 全模型 503,
日志仅有 no available OpenAI accounts supporting model 且
excluded_account_count=0。selectByLoadBalance 初筛循环的每个过滤分支
(配额自动暂停、渠道上游模型限制、运行时熔断等)都是静默 continue,
最多只有 Debug 级日志,用户与维护者都无法定位候选账号被哪个隐式
过滤点剔除。
修改:
- selectByLoadBalance 初筛循环为每个 continue 分支记录原因计数
(excluded/not_schedulable/platform_mismatch/runtime_blocked/
privacy_not_set/transport_incompatible 及请求兼容性细分原因)
- isAccountRequestCompatible 新增 isAccountRequestCompatibleReason
变体,细分 runtime_blocked/quota_auto_pause_<窗口>/
shadow_parent_unhealthy/model_not_supported/
channel_upstream_restricted/capability_mismatch;原 bool 函数改为
包装变体,其余调用点行为不变
- noAvailableOpenAISelectionError 增加 details 参数,初筛全灭时输出
如 (pool=3, filtered: excluded=1 model_not_supported=1
quota_auto_pause_7d=1),原因按字典序排序保证输出确定;快照池为空
时输出 (pool=0);选择序列耗尽路径追加 selection_order_exhausted
标注;legacy 调用点传空保持原消息不变
兼容性:错误仍通过 Unwrap 匹配 ErrNoAvailableAccounts,分类与 ops
标记逻辑不变;客户端可见错误仍为通用分类消息,统计仅进服务端日志;
happy path 原因 map 惰性分配,无额外开销。
Refs #4599
Co-authored-by: Cursor <cursoragent@cursor.com >
2026-07-20 21:44:42 +08:00
superman2003
2707f2793d
fix(gateway): CC 桥接受 Anthropic 上游的 SSE 紧凑格式
...
SSE 规范允许字段冒号后省略空格(event:message_start / data:{...})。
Kimi 等 Anthropic 兼容上游返回紧凑格式时,Anthropic → Chat Completions
桥按 "event: " / "data: " 严格匹配会丢弃全部事件,且 dataLine[6:] 按带
空格前缀硬切载荷,最终流式/缓冲两条路径都报 "Upstream stream ended
without a response"(与 #4653 同根因;#4657 只修了 /v1/responses 桥,
本补丁补齐对称的 /v1/chat/completions 桥)。
复用 OpenAI 链路既有的 extractOpenAISSEEventLine / extractOpenAISSEDataLine
(正确处理可选空格/tab),流式与缓冲两处统一替换;补充紧凑格式的
缓冲/流式回归测试,原带空格格式用例保持通过。
2026-07-20 21:00:29 +08:00
suuuuuu-1
e5ad287843
fix(gateway): support compact SSE format in Anthropic /responses bridge
...
Fixes #4653
## Problem
The /v1/responses endpoint (Responses → Anthropic bridge) failed when
upstream providers returned SSE events in compact format without spaces
after colons (e.g. 'event:message_start' instead of 'event: message_start').
This affected Kimi API (api.kimi.com) and potentially other upstreams,
causing 'Upstream stream ended without a response' errors.
## Root Cause
The SSE parser in gateway_forward_as_responses.go used strict prefix
matching with hardcoded spaces:
if !strings.HasPrefix(line, "event: ") { ... }
if !strings.HasPrefix(dataLine, "data: ") { ... }
According to the SSE spec
(https://html.spec.whatwg.org/multipage/server-sent-events.html ),
the space after the colon is optional. Both formats are valid:
event: message_start ✓
event:message_start ✓
## Solution
Introduced parseAnthropicSSEField() helper that:
- Accepts both 'field: value' and 'field:value' formats
- Uses TrimSpace() to handle optional/multiple spaces
- Returns (value, ok) for consistent error handling
Applied to both streaming handlers:
- handleResponsesBufferedStreamingResponse
- handleResponsesStreamingResponse
## Testing
Added comprehensive unit tests:
- TestParseAnthropicSSEField: validates parser with 8 edge cases
- TestHandleResponsesBufferedStreamingResponse_CompactSSEFormat
- TestHandleResponsesStreamingResponse_CompactSSEFormat
All existing tests pass, confirming backward compatibility.
2026-07-20 20:40:08 +08:00
superman2003 and Cursor
c401595e01
fix(openai): preserve 路径 call_id 超长时压缩至 64 字符上限
...
生产环境真实报错:客户端走 /v1/messages(Anthropic Messages 格式)入站,
OAuth 账号转发上游 OpenAI /v1/responses 时(PreserveToolCallIDs=true),
客户端历史中出现超长工具 ID(如嵌套代理拼接产生的 78 字符 srvtoolu_ ID)
会被原样透传,上游 400 拒绝:
"Invalid 'input[614].call_id': string too long. Expected a string with
maximum length 64, but got a string with length 78 instead."
#4612 为非 preserve 路径增加了 call_id 归一化与压缩,但有意将
PreserveToolCallIDs=true 的路径排除在外。本次在 preserve 路径补上长度护栏:
- len(id) <= 64 时仍原样透传,保持 #4612 承诺的"保持原样"语义;
- 超过 64 时复用已有的 compactCodexCallID 做确定性 SHA-256 压缩。
由于压缩是确定性的,同一逻辑 ID 在 function_call 与 function_call_output
两侧结果一致,tool_use/tool_result 配对不破坏;OAuth 路径 store=false
每轮全量重放历史,跨轮结果亦一致。改写点 fixCallIDPrefix 是
filterCodexInputWithOptions 内所有 call_id 修正的单一入口(含 item_reference
的 call_* 引用),同时覆盖 Messages 桥接(openai_gateway_messages.go)与
/v1/responses 透传(openai_gateway_forward.go)两条 preserve 路径。
Co-authored-by: Cursor <cursoragent@cursor.com >
2026-07-20 18:49:24 +08:00
li
865128998c
fix(billing): 合并 hosted image_generation 工具的图片 token 到 /responses 计费
...
/v1/responses 端点使用 hosted image_generation 工具时,上游在
response.tool_usage.image_gen 返回图片 token 用量,但
extractOpenAIUsageFromJSONBytes 只读 response.usage,导致
image_output_tokens 和 image_output_cost 始终为 0。
在 extractOpenAIUsageFromJSONBytes 提取完 base usage 后,合并
tool_usage.image_gen 的 image tokens 维度(仅补充不覆盖),
覆盖 SSE 流式、非流式和 WebSocket 三条路径。
2026-07-20 16:29:12 +08:00
Wesley Liddick
27f094e096
Merge pull request #4638 from superman2003/fix/s3-secret-ephemeral-encryption-key
...
fix(backup): 拒绝用自动生成的临时密钥持久化 S3 SecretAccessKey,修复重启后解密失败
2026-07-20 16:21:46 +08:00
abbzbb
2ae61f3da0
fix(grok): Codex compact 适配与链式视频 content 代理
...
- #4223/#4554: Grok 模拟 /responses/compact,调度允许 Grok 账号
- #4494/#4626: 支持链式中继的受保护视频 /content 下载
2026-07-20 16:12:56 +08:00
Wesley Liddick
c4a8878f1f
Merge pull request #4626 from put-go/fix/grok-chained-video-content
...
fix(grok): support chained video content proxies
2026-07-20 15:30:46 +08:00
Wesley Liddick
ce9e70d5cf
Merge pull request #4569 from Astrenix/fix/codex-models-openai-list-envelope
...
fix(openai): accept standard OpenAI model list for Codex model discovery
2026-07-20 15:30:31 +08:00
Wesley Liddick
78f85583ea
Merge pull request #4630 from feitianbubu/fix/api-key-update-ip-list-clear
...
fix: 部分更新 API Key 时不再静默清空 IP 白/黑名单
2026-07-20 15:28:51 +08:00
superman2003
7a7f51a534
fix(backup): 拒绝用自动生成的临时密钥持久化 S3 SecretAccessKey
...
totp.encryption_key 未配置时,加密密钥每次进程启动都会随机重新生成。
备份/图床把 S3 SecretAccessKey 用这把临时密钥加密落库后,重启或升级
即无法解密(decrypt: cipher: message authentication failed),S3 备份
与图床静默失效(#4524)。
对齐支付(payment.ProvideEncryptionKey)与 TOTP 启用已有的护栏:在
持久化新 secret 之前,若密钥非固定配置则返回可操作的
SECRET_ENCRYPTION_KEY_NOT_CONFIGURED(400),提示配置固定
TOTP_ENCRYPTION_KEY。不带 secret 的更新(沿用已存值)与
ReuseBackupS3 模式不受影响;已配置固定密钥的部署无感。
2026-07-20 15:20:51 +08:00
shaw
04617cc0ff
Merge branch 'main' into fix/grok-claude-messages-prompt-cache
...
Resolve const-block conflict in openai_gateway_grok_cache.go:
keep #4590 client tool cache constants and #4585 xai-package limit
(grokFreeRolling24hTokenLimit removed), add claudeCodeSessionHeader.
2026-07-20 11:39:37 +08:00
shaw
a90c18cbea
Merge branch 'main' into fix/issues-4561-4562-4566-4582
...
Resolve const-block conflict in openai_gateway_grok_cache.go:
keep #4590 's client tool cache constants, drop grokFreeRolling24hTokenLimit
(moved to pkg/xai as IsGrokFreeRolling24hTokenLimit with legacy 2M support).
2026-07-20 11:25:11 +08:00
feitianbubu
e502766170
fix: 部分更新 API Key 时不再静默清空 IP 白/黑名单
2026-07-20 11:15:37 +08:00
Wesley Liddick
b8e844f4ee
Merge pull request #4612 from catoncat/fix/codex-call-id-length
...
fix(openai): 限制 Codex call_id 归一化后的长度
2026-07-20 11:05:18 +08:00
Wesley Liddick
80a533c890
Merge pull request #4606 from orchief/codex/issue-4603-dedupe-oauth-system-prompt
...
fix(openai): 避免 OAuth Chat 转译重复 system 前缀
2026-07-20 11:03:00 +08:00
Wesley Liddick
6d152893ff
Merge pull request #4590 from superman2003/fix/grok-client-cache-codex-trae
...
fix(grok): cache client tools from Codex, Trae, and Claude Desktop
2026-07-20 10:47:05 +08:00
shaw
97afb4089c
fix(lint): check strings.Builder WriteString return value (errcheck)
2026-07-20 10:46:37 +08:00
put-go
48fad26433
fix(grok): support chained video content proxies
2026-07-20 10:40:18 +08:00
Wesley Liddick
1b4029b050
Merge pull request #4595 from kinsolee/fix/http-bridge-failover-terminal-safety
...
fix(openai): make HTTP bridge failover safe
2026-07-20 10:29:00 +08:00
Wesley Liddick
139a3d4346
Merge pull request #4589 from huangjunsen0406/fix/anthropic-message-start-stop-reason-null
...
fix(apicompat): emit null stop_reason on Anthropic message_start
2026-07-20 10:28:52 +08:00
Wesley Liddick
8c9cda1803
Merge pull request #4583 from BenjaminAaron196/codex/ops-report-email-template
...
(feat) 运维定时报表支持可编辑摘要模板与多语言展示
2026-07-20 10:28:44 +08:00
Wesley Liddick
0a8831777b
Merge pull request #4619 from superman2003/fix/grok-manual-test-scheduling-gate
...
fix(grok): let manual connection tests bypass the scheduling gate
2026-07-20 10:26:55 +08:00
Wesley Liddick
e311d368d3
Merge pull request #4611 from superman2003/fix/codex-models-manifest-401-unschedulable
...
fix(openai): mark OAuth accounts unschedulable on Codex models manifest 401
2026-07-20 10:26:39 +08:00
Wesley Liddick
c0b8f6b0a8
Merge pull request #4601 from jianjianai/new/perf-responses-sse-type
...
perf(openai): 复用 Responses SSE 事件类型解析
2026-07-20 10:26:23 +08:00
Wesley Liddick
032001598a
Merge pull request #4617 from wucm667/fix/issue-4610-anthropic-json-content-type
...
fix(openai): correct buffered messages content type
2026-07-20 10:24:22 +08:00
Wesley Liddick
6def36a171
Merge pull request #4614 from cugxuan/codex/fix-subscription-expiry-days
...
fix(subscription): round remaining days up
2026-07-20 10:24:14 +08:00
Wesley Liddick
bfabfe60c8
Merge pull request #4593 from StarryKira/fix/image-storage-env-unreachable
...
fix: 异步生图开关配了却不生效(环境变量被静默丢弃 + 迁移到后台开关)
2026-07-20 09:20:15 +08:00
Jlypx and Sisyphus
f72958d530
feat: 持久化客户端 IP 请求头设置
...
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent )
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai >
2026-07-20 00:09:11 +08:00
Jlypx and Sisyphus
8b8b6b3132
feat: 定义客户端 IP 请求头系统设置
...
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent )
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai >
2026-07-20 00:09:00 +08:00
superman2003
4a97491be6
fix(grok): let manual connection tests bypass the scheduling gate
...
Grok OAuth 'test connection' reused the production GrokTokenProvider
request path, whose eligibility gate rejects any account that is not
currently schedulable (manual switch off, rate limited, overloaded,
temporarily cooled down). Every such test failed before reaching xAI
with the generic 'oauth refresh account state changed', while
Codex/OpenAI account tests read credentials regardless of scheduling
state (#4598 ).
Add GetAccessTokenForManualTest and use it from the account test
service:
- skips the request-path scheduling eligibility gate so admins can
probe excluded accounts; credential integrity checks (configured
proxy present, refresh token present) still apply
- refreshes expired tokens through the shared OAuthRefreshAPI without
the request-path marker, so the lock protocol and DB re-read keep
working while scheduling state no longer blocks the refresh;
credential rotation for non-active accounts stays blocked inside
RefreshIfNeeded
- falls back to the still-valid current token when a refresh attempt
fails or another worker holds the refresh lock, and otherwise
surfaces the concrete refresh error instead of the generic message
Fixes #4598
2026-07-19 22:40:58 +08:00