Commit Graph
3203 Commits
Author SHA1 Message Date
shaw bb5d2e84a1 refactor(handler): 纯移动拆分 setting_handler.go(3957→468行) 2026-07-08 08:49:22 +08:00
shaw f013bc1141 refactor(service): 纯移动拆分 admin_service.go(4409→642行) 2026-07-08 08:49:22 +08:00
shaw 2a4c28e8f5 refactor(service): 纯移动拆分 antigravity_gateway_service.go(4664→639行) 2026-07-08 08:49:22 +08:00
shaw d0f669338b refactor(service): 纯移动拆分 openai_ws_forwarder.go(4675→399行) 2026-07-08 08:49:21 +08:00
shaw db3bd9971e refactor(repository): 纯移动拆分 usage_log_repo.go(4701→212行) 2026-07-08 08:49:21 +08:00
shaw 4d23ad4bac refactor(service): 纯移动拆分 openai_gateway_service.go(4872→1095行) 2026-07-08 08:49:21 +08:00
shaw 50043b1176 refactor(service): 纯移动拆分 setting_service.go(5471→263行) 2026-07-08 08:49:20 +08:00
shaw 084d26cbd2 refactor(service): 纯移动拆分 gateway_service.go(7294→1289行) 2026-07-08 08:49:20 +08:00
shaw a4f942d8a9 fix(deps): 升级 AWS SDK 修复 govulncheck 报告的 GO-2026-5764
eventstream v1.7.5→v1.7.8、service/s3 v1.96.2→v1.97.3(含关联 internal 模块),
修复 EventStream 解码器 DoS 漏洞,恢复 backend-security CI。
2026-07-08 08:37:29 +08:00
shaw d754be0d8e refactor(gateway): 抽取 CC forwarder 公共管线并拆分两大 service 文件
PR #3802 遗留项:三个 CC forwarder(raw 直转 / responses 回退 / messages
回退)间约 85% 重复的 HTTP 管线与 SSE 循环骨架收敛到新文件
openai_gateway_cc_pipeline.go,messages / chat_completions 两条主路径中
逐字相同的错误处理块一并接入。各路径有意保留的行为差异(GLM effort
归一化、fast policy 适用范围、ClientDisconnect 语义、Grok 分支等)留在
调用方,未强行统一。

同时对两个最臃肿的网关文件做纯移动拆分(零语义变化,逐字节校验):

- openai_gateway_service.go 7821→4872 行:
  调度 → openai_gateway_scheduling.go
  passthrough → openai_gateway_passthrough.go
  用量/计费/codex 快照 → openai_gateway_usage.go
- gateway_service.go 10912→7294 行:
  调度 → gateway_scheduling.go
  Anthropic APIKey 直通 → gateway_anthropic_passthrough.go
  Bedrock → gateway_bedrock.go

回归保障:全部搬迁块与 HEAD 逐字节 diff 一致;留存文件经"HEAD 减去搬迁
范围"重构比对,差异仅为 goimports 移除的孤儿 import;定向单测
(fallback/raw/cyber/grok/transport/调度/用量/广域 Forward-Handle 扫描)
全绿;另经独立对抗审计确认零行为差异。
2026-07-07 22:14:46 +08:00
shaw dad92488e5 fix(messages): 修复 /v1/messages CC 回退的错误处理旁路并补齐流式测试
针对 #3795 合并后审计发现的问题:

- 非 failover 上游错误分支改走共享 handleAnthropicErrorResponse:恢复
  ops 上游错误记录、错误透传规则、cyber_policy 检测与按状态码映射的
  错误 type(400→invalid_request_error 等);删除随之失效的
  mapUpstreamStatusToAnthropicStatus
- 流式读错误对齐 forwardResponsesViaRawChatCompletions:scanner 出错时
  不再 finalize(不再补发 message_stop 把截断伪装成正常完成),返回
  stream usage incomplete 错误
- sawDone 由死变量改为与兄弟一致的无 [DONE] 哨兵 debug 日志
- 补充 fast policy 在本路径有意省略的说明注释
- 新增 8 个单测:流式收尾闭块、tool_call 分片聚合、length→max_tokens、
  空流补帧、非 failover 400 走共享处理器、读错误不伪造收尾、
  Responses 账号门控回归、非流式转换
2026-07-07 20:59:41 +08:00
Wesley Liddick 4bcb13f77f Merge pull request #3786 from creamtea47/codex/openai-fast-force-priority
add force priority fast policy action
2026-07-07 20:45:45 +08:00
Wesley Liddick 9643382bd3 Merge pull request #3795 from fengshao1227/fix/messages-inbound-chat-completions-fallback
fix(messages): /v1/messages 入站支持不兼容 Responses API 的 OpenAI 上游
2026-07-07 20:45:14 +08:00
Wesley Liddick af4b75a77c Merge pull request #3794 from fengshao1227/fix/image-gen-namespace-permission-bypass
fix(image): 识别 Codex namespace image_gen 工具声明以拦截生图请求
2026-07-07 20:42:43 +08:00
Wesley Liddick c7249a54ac Merge pull request #3793 from heathermhuang/codex/grok-video-text-fallback
fix: route text-only Grok video 1.5 requests
2026-07-07 20:22:44 +08:00
shaw b5604afd3d test(batch-image): 集成测试适配 ReplaceBatchImageItemsForJob 的 indexing 状态守卫
守卫要求 job 处于 indexing 状态才允许重建 item 表;原测试在 created
状态下直接调用被 409 拒绝。改为先断言非 indexing 状态的冲突行为,
再经 created→submitted→indexing 合法链推进后执行原有断言。
2026-07-07 20:13:28 +08:00
shaw 80a229bce5 fix(batch-image): 修复审计发现的计费死锁、状态机与队列原子性缺陷
修复 PR #3768 批量图像 MVP 合并后审计报告中的全部问题:

结算与计费(高危):
- 所有 SETTLEMENT_* 失败(超冻结/计数非法/manifest 冲突/定价缺失/扣费失败)
  统一计入 retry_count 并在耗尽时释放冻结转 failed,消灭 settling 无限
  requeue 导致的冻结余额永久锁死
- 耗尽出口的释放指纹统一为 RequestHash,与 processor/Cancel/recovery 一致;
  release 遇同 request id 指纹冲突视为幂等成功,治愈历史毒消息
- 管理端校验 hold_multiplier >= discount_multiplier,定价快照对存量脏数据钳制
- 释放前校验 per-job hold claim(dedup+归档表),杜绝幻影释放

索引对账(高危):
- provider 输出与提交 custom_id 集对账:未知条目丢弃并记事件,
  漏项补 PROVIDER_RESULT_MISSING 失败行,保证 success+fail == item_count

提交与恢复(高危):
- 提交前转 uploading 并在 provider.Submit 期间心跳刷新 updated_at;
  恢复扫描改为原子复核(FailStaleUnsubmittedBatchImageJob),
  消灭慢提交被误杀退款而上游任务照常计费的孤儿场景
- 上游任务创建成功但本地状态推进失败时,尽力取消上游并清理输入
- recovery 释放失败时入队交由 worker releaseTerminalHold 兜底重试

队列与并发(中危):
- Enqueue(SetNX+LPush)与 Reserve(BRPop+ZAdd)均改为 Lua 原子脚本,
  消灭崩溃窗口导致 job 脱离队列、被 7 天 inflight 键锁死
- 锁冲突按 LockConflictDelay 重新入队(原直接丢弃需等 10 分钟 stale 恢复)
- 处理期间心跳:active zset 续期(ZAddXX 防幽灵成员)+ 锁 TTL 续期
- ReplaceBatchImageItemsForJob 增加 indexing 状态守卫,防掉队 worker 重写账目

存量回归(中危):
- image-only 定价条目(仅图片价无 token 价)恢复 token 计费 fail-closed,
  不再按 $0 计费;图片计费路径不受影响
- 鉴权余额门槛恢复 balance <= 0 语义,MinimumBalanceReserve 不再作硬 403

加固:
- ZIP max_items 钳制到管理员上限;Submit 补齐 Platform==Gemini 校验;
  gemini downloadUri 跟随前做 host 白名单校验
- 批量客户端改用共享 httpclient(拨号/TLS/响应头超时有界)
- 审计点名的忽略错误(MarkDownloaded/SettlementFailed/AppendEvent 等)改为记日志
2026-07-07 18:53:56 +08:00
li 69d02d2036 fix: 补齐 failover 路径的 appendOpsUpstreamError 日志
审查发现 error 路径缺少 appendOpsUpstreamError 和 upstreamDetail
记录,与 forwardResponsesViaRawChatCompletions 不对称。
2026-07-07 17:35:09 +08:00
li 5c0e580fbe fix(messages): /v1/messages 入站支持不兼容 Responses API 的 OpenAI 上游
ForwardAsAnthropic 此前无条件把 Anthropic Messages 转为 Responses
格式发往 /v1/responses,导致只支持 /v1/chat/completions 的第三方
OpenAI 兼容上游(京东云、DeepSeek、Kimi、GLM 等)全部 400。

在入口增加与 ForwardAsChatCompletions 对称的 ShouldUseResponsesAPI
分流:APIKey 账号 + 上游不支持 Responses 时,改走新建的
forwardAnthropicViaRawChatCompletions,链式复用全部已有转换桥
(Anthropic→Responses→CC 请求,CC→Responses→Anthropic 响应),
不新建转换函数。

Fixes #3735
2026-07-07 17:23:18 +08:00
li a02700c16f fix(image): 识别 Codex namespace image_gen 工具声明以拦截生图请求
分组 allow_image_generation=false 时,Codex /image 技能通过
namespace 工具声明(type=namespace, name=image_gen)和 Responses
Lite 的 input additional_tools 绕过了现有生图意图检测——现有逻辑
只识别 tools[].type == "image_generation" 这一种形式。

在 gjson 版(openAIJSONToolsContainImageGeneration)和 map 版
(hasOpenAIImageGenerationTool)检测中增加 namespace image_gen
识别;同时扫描 input[].type == "additional_tools" 中嵌套的工具
声明,覆盖 Responses Lite 格式。

Fixes #3608
2026-07-07 16:58:48 +08:00
Heatherm Huang 3b2099350e fix: route text-only grok video requests 2026-07-07 16:44:20 +08:00
Wesley Liddick 44ab690a01 Merge pull request #3768 from Turtle-Li/feature/batch-image-foundation
feat: add batch image generation MVP
2026-07-07 16:32:45 +08:00
li fd64d07e61 fix(codex): 剥离续链 function_call item 的非法 item_* id
OpenAI OAuth 转发续链请求时,function_call 等 call-input 类 item 的
id 被客户端以 item_* 形式回放,但上游要求以 fc 开头,返回 400
"Expected an ID that begins with 'fc'",导致工具续链反复失败。

filterCodexInputWithOptions 在 PreserveReferences=true 路径下对
call-input 类 item(function_call/tool_call/local_shell_call 等)
增加 id 前缀检查:非 fc 开头即删除。output 类(function_call_output
等)的 id 无此约束,不动。

Fixes #3785
2026-07-07 15:54:55 +08:00
NellPoi e979990bf9 add force priority fast policy action 2026-07-07 15:27:23 +08:00
Turtle_Li a6023840f7 Merge remote-tracking branch 'origin/main' into feature/batch-image-foundation
# Conflicts:
#	deploy/Dockerfile
2026-07-07 15:14:37 +08:00
Wesley Liddick b5b0ea3460 Merge pull request #3708 from sweetcornna/fix/antigravity-401-self-heal
fix(antigravity): 网关转发默认走生产端点(修复一请求就 401/502、账号被 benched)
2026-07-07 15:12:29 +08:00
Wesley Liddick 87bdaf8e60 Merge pull request #3780 from fengshao1227/fix/gateway-parse-error-observability
fix(gateway): 记录请求体解析失败的真实原因,不再吞错
2026-07-07 14:37:46 +08:00
Wesley Liddick a98397adbb Merge pull request #3778 from fengshao1227/fix/websearch-emulation-history-blocks
fix(websearch): 剥离历史消息中上游不接受的 web search 块
2026-07-07 14:33:16 +08:00
Wesley Liddick aff87d9497 Merge pull request #3776 from alfadb/fix/openai-compact-usage-sse-detection
fix(openai): 避免 JSON 响应被 SSE 文本误判导致用量丢失
2026-07-07 14:31:52 +08:00
Wesley Liddick 571e0b8132 Merge pull request #3774 from heathermhuang/codex/grok-composer-image-bridge
fix: bridge Grok Composer image inputs
2026-07-07 14:13:28 +08:00
li 40c563c4ae fix(gateway): 记录请求体解析失败的真实原因,不再吞错
400 "Failed to parse request body" 此前丢弃底层错误,无法区分
JSON 真非法、还是 body 被截断/被中间件提前消费。

- 服务层 invalid json 错误增补 len/offset/非法字符信息
  (仅诊断元数据,不含 body 内容,可安全 wrap);
- handler 层新增 logRequestBodyParseFailure,向服务端日志输出
  底层错误 + body 长度 + 转义后的 head/tail 片段(各 256B),
  客户端响应文案保持不变;
- 接入全部 9 处入站解析点(messages/count_tokens/responses/
  chat_completions/embeddings,Anthropic 与 OpenAI 网关)。

Fixes #3715
2026-07-07 13:53:39 +08:00
li 867616fca8 fix(websearch): 剥离历史消息中上游不接受的 web search 块
Web Search 模拟合成的 server_tool_use / web_search_tool_result 块
(srvtoolu_ws_ 前缀)被客户端回传到后续 /v1/messages 历史后,
上游一律 400(GLM 等第三方兼容上游只接受
text/thinking/image/tool_use/tool_result),会话从此卡死。

新增 FilterWebSearchHistoryBlocks 预过滤:
- 模拟伪造块对所有上游无条件剥离;
- 真实 web search 块仅对 passback-required 协议族剥离
  (复用 ResolveThinkingProtocol),不误伤官方 Anthropic 会话;
- 接入 Anthropic 通用转发与 API Key 透传两条路径的既有 pre-filter 区。

Fixes #3677
2026-07-07 13:41:40 +08:00
alfadb 438f17be5e fix(openai): avoid compact usage loss from json sse heuristic
Replace the substring-based data:/event: SSE heuristic in
handleNonStreamingResponse with bodyHasSSEFraming, a line-level check
that only matches when a physical line starts with the SSE data:/
event: field names. This prevents OAuth compact JSON responses whose
output text merely contains the literal substrings "data:" or
"event:" from being misrouted into handleSSEToJSON, which was
causing usage to be recorded as zero even though the JSON body itself
carries a valid top-level usage object. Content-Type: text/event-stream
detection and genuine SSE body handling are unaffected.
2026-07-07 13:04:28 +08:00
Turtle_Li 83d7b0e440 fix: isolate duplicate item integration test 2026-07-07 11:24:04 +08:00
github-actions[bot] 9d5f1b73ad chore: sync VERSION to 0.1.146 [skip ci] 2026-07-07 03:16:52 +00:00
Heatherm Huang c34db70a88 fix: bridge grok composer image inputs 2026-07-07 10:55:07 +08:00
Turtle_Li 5494261902 Merge remote-tracking branch 'origin/main' into feature/batch-image-foundation
# Conflicts:
#	.github/audit-exceptions.yml
2026-07-07 10:53:17 +08:00
Turtle_Li aff148167c fix: address batch image ci failures 2026-07-07 10:50:36 +08:00
Wesley Liddick baadb22682 Merge pull request #3761 from alfadb/fix/responses-alias-normalization
修复 OpenAI Responses compact 端点归一化
2026-07-07 10:37:08 +08:00
alfadb ddd63a8402 test: cover endpoint wildcard edge cases 2026-07-07 10:20:23 +08:00
alfadb 75e3089496 fix: normalize inbound endpoints from raw request path 2026-07-07 10:20:23 +08:00
alfadb 2fb212b7d6 fix(openai): 区分 responses compact 入站端点
/v1/responses/compact 及其别名路径(/responses/compact、/openai/v1/responses/compact、
/backend-api/codex/responses/compact 等,含嵌套子路径)是独立的客户端端点,
新增 EndpointResponsesCompact 常量并单独归一化,不再与根 /v1/responses 混同。
根 Responses 别名(/responses、/backend-api/codex/responses 等)仍归一到
EndpointResponses。NormalizeInboundEndpoint 优先匹配 compact 分支,避免根路径
前缀提前命中。DeriveUpstreamEndpoint 在 inbound 已为 compact 但原始路径无法
派生后缀时,回退到 compact 而非根 upstream。
2026-07-07 10:20:23 +08:00
shaw 7650cce5a4 fix(redis-index): harden index-driven cleanup introduced in #3762
- 启动清理覆盖 score 已过期的索引成员,并新增 marker 门控的一次性
  遗留 wait 键清扫,消除重启后幻影等待计数挤占 maxWait 的问题
- UMQ 争锁失败路径回填观测到的持有者锁索引(PTTL=-1 异常锁以已到期
  候选入索引),恢复被 SCAN 删除后丢失的孤儿锁兜底完整性
- 后台清理同时回收 account 与 user 两个活跃索引的到期候选,修复
  user 索引过期成员无回收路径导致的无界增长
- acquire/incrementWait Lua 脚本返回 {result, now},索引写复用脚本
  内 Redis 时间,热路径每次操作减少一次 TIME 往返;清理循环外提
  now 并批量写索引
- 删除无生产调用方的 GetActiveAccountLoadMap 及配套死代码
- 索引维护失败增加 warn 日志,不再静默丢弃
- 移除根目录工单文档 REDIS_SCAN_ARCHITECTURE_OPTIMIZATION.md
2026-07-07 10:04:38 +08:00
shaw 7c8e13208b style: replace interface{} with any per golangci-lint gofmt rewrite rules 2026-07-07 09:32:15 +08:00
shaw d37d216f9d Merge remote-tracking branch 'origin/main' into pr-3762
# Conflicts:
#	backend/internal/repository/concurrency_cache.go
#	backend/internal/repository/concurrency_cache_integration_test.go
2026-07-07 09:22:44 +08:00
Wesley Liddick a862eac1d8 Merge pull request #3758 from catoncat/fix/test-oauth-codex-headers
fix: add missing Codex CLI headers for OAuth account test
2026-07-07 08:34:18 +08:00
Wesley Liddick 3828a48752 Merge pull request #3751 from heathermhuang/codex/grok-image-pricing-latest
fix: expose Grok image pricing controls
2026-07-07 08:29:01 +08:00
Wesley Liddick 77b1a0452e Merge pull request #3760 from DaydreamCoding/fix/codex-detect-version-gate-message
fix(codex-detect): codex 版本门拒绝返回带版本号的差异化文案
2026-07-07 08:28:51 +08:00
Wesley Liddick 26b51ccfd3 Merge pull request #3737 from wucm667/fix/sync-models-non-v1-base-url
fix(models): 同步上游模型支持非 /v1 API 版本 base_url(如智谱 /v4)
2026-07-07 08:28:41 +08:00
Turtle_Li 89edba8028 fix: restrict batch image groups to gemini 2026-07-07 04:14:09 +08:00