Commit Graph
54 Commits
Author SHA1 Message Date
IanShaw b2b2adcf8d 修复 PR 5888 审查发现的兼容性与竞态问题 2026-08-20 21:06:48 -07:00
IanShaw027 7c53a842e4 合并上游 main,保留 5925 的 Grok 重试上限与 5888 的协议兼容修复
同账号重试采用次数上限加 deadline;畸形 tools 在出站前删除;compaction 422 与结构化错误扫描一并保留。
2026-08-21 08:49:44 +08:00
IanShaw 3243983b72 完善 Grok Realtime 与默认映射测试 2026-08-20 04:26:24 -07:00
IanShaw c374ff2951 完善 OpenAI 网关切换与运维错误语义 2026-08-19 23:13:40 -07:00
shaw 499a8ee423 fix(composite): exempt resolved grok/CN targets from messages dispatch gate
sanitizeGroupMessagesDispatchFields forces AllowMessagesDispatch=false for
every non-openai platform including composite, and the gate checked only the
group platform — so composite requests resolved to grok/CN targets were
rejected 403 on /v1/messages and /v1/messages/count_tokens before reaching
the composite target whitelist, leaving the CN rollout unusable for
Claude-protocol clients.

- allowOpenAICompatibleMessagesDispatch: composite groups resolved to a
  grok/CN target get the same exemption as the standalone platforms;
  openai-resolved and unresolved targets keep requiring the switch
- resolveOpenAIMessagesDispatchMappedModel: skip the group-level dispatch
  model mapping (openai-specific gpt defaults) for composite grok/CN
  targets — model rewriting stays with account-level model_mapping
2026-08-19 15:24:26 +08:00
shaw a3bbf35cbd Merge branch 'main' into fix/issue-5029-openai-passthrough-pool-auth-retry
Resolve conflict in backend/internal/handler/openai_gateway_handler_test.go.

main and this branch each appended a passthrough upstream stub plus a test at
the same two insertion points:

  main   openAIHTTPPassthroughSSERateLimitUpstream
         TestOpenAIResponses_APIKeyPassthroughSSERateLimitUsesConfiguredPoolRetry
  branch openAIHTTPPassthroughAuthFailoverUpstream
         TestOpenAIResponses_APIKeyPassthroughPoolAuthFailureRetriesThenSwitchesToHealthyAccount

Both sides are kept verbatim; the only edit is giving each stub its own
calls() body instead of sharing the trailing one. No assertion was changed.

openai_gateway_passthrough.go and openai_oauth_passthrough_test.go merged
automatically.
2026-08-11 14:09:07 +08:00
Wesley LiddickandGitHub f3c7a1a8c4 Merge pull request #5295 from wucm667/fix/issue-5289-streaming-upstream-error
fix: emit response.failed when compact keepalive commits headers but no SSE payload
2026-08-10 10:52:49 +08:00
IanShaw027 61b975b5dd test(grok): 对齐跨客户端映射与路由审计契约 2026-08-07 16:45:25 +08:00
wucm667 2f109e74ca fix: emit response.failed when compact keepalive commits headers but no SSE payload
When OpenAI Responses streaming has compact keepalive commit 200 headers
but no semantic SSE event has been written, upstream 4xx errors were
silently swallowed, causing clients to hang until timeout.

The fix distinguishes between 'headers committed' and 'meaningful SSE
output written'. Compact keepalive may commit headers for heartbeat
purposes without writing actual SSE events. In that case, the Responses
stream still needs its protocol-correct terminal response.failed event.

Preserves existing behavior when a complete upstream response or
meaningful SSE payload was already communicated, and preserves image
keepalive semantics.

Fixes #5289
2026-08-05 16:28:16 +08:00
feeeei 85a27fae39 fix(openai): retry SSE rate limits as HTTP 429
OpenAI Responses may return code=rate_limit_exceeded in a response.failed SSE event while the HTTP status remains 200. Classify these failures as 429 so configured pool-mode retries and account failover are applied. No account-level rate-limit state is written on this path: the 200-stream response headers carry normal quota snapshots, and retry semantics stay owned by the failover engine.

Ignore compact keepalive bytes when determining whether semantic output has started, preserving safe retries before real output.
2026-08-01 10:01:47 +08:00
shaw 948b63c9ca feat(moderation): route content moderation through configurable proxy server
Implements #2646: the risk-control content audit can now send OpenAI
Moderations requests through a proxy from IP Management - Proxy Servers.

Backend:
- ContentModerationConfig gains proxy_id (nil = direct, unchanged default)
- update semantics: null keeps, 0 clears, >0 selects (validated to exist)
- moderation calls build the client via the shared httpclient pool; proxy
  resolution failure surfaces as a moderation error and never silently
  falls back to direct connection
- proxy_id -> URL resolution cached 60s (single-entry, invalidated on
  config save) so the pre-block hot path does not hit the DB per request
- test-key endpoint accepts proxy_id too (null = saved config's proxy,
  0 = force direct), so input-key/saved-key tests exercise the same path
- proxy usage/inactivity logged (content_moderation.proxy_enabled /
  proxy_not_active) without leaking credentials

Frontend:
- ProxySelector in the risk-control basic settings tab, proxy list loaded
  non-blockingly; save and test payloads carry proxy_id; zh/en i18n
2026-07-31 23:12:22 +08:00
Zven 313121f3f7 test(pricing): update requested Terra cost 2026-07-31 10:02:04 +08:00
Zven 488d3b09ec test(pricing): update Terra billing ratios 2026-07-31 09:55:16 +08:00
wucm667 7045f89de4 fix(openai): retry pool auth failures before failover 2026-07-29 18:47:07 +08:00
KtzeAbyss 7ce6e8d652 fix(openai): track websocket models per turn 2026-07-26 13:43:06 +08:00
jjaw 8fd6f91b7e 优化 Responses 生图意图复用 2026-07-19 18:49:08 +08:00
Wesley LiddickandGitHub b01196a7a8 Merge pull request #4553 from wp-a/fix/openai-ws-turn-lifecycle
[codex] enforce websocket passthrough turn lifecycle
2026-07-18 21:10:48 +08:00
王鹏 f0e0b7e6d8 fix(openai-ws): enforce passthrough turn lifecycle 2026-07-18 19:17:53 +08:00
haruka bd0f2d6405 fix: report chat stream transport failures 2026-07-18 03:24:04 +08:00
Wesley LiddickandGitHub f3138ceb43 Merge pull request #4384 from wp-a/fix/openai-model-scoped-transient-cooldown
[codex] scope OpenAI transient cooldowns by model
2026-07-16 09:33:09 +08:00
Wesley LiddickandGitHub 3fc0336e1d Merge pull request #4377 from wp-a/fix/openai-ws-ingress-lifecycle
[codex] close OpenAI WS ingress reads cleanly
2026-07-16 09:32:50 +08:00
王鹏 40b8f04a6a fix(openai): scope transient cooldowns by model 2026-07-15 22:52:35 +08:00
王鹏 4f641208a0 fix(openai-ws): close ingress reads cleanly 2026-07-15 22:15:44 +08:00
王鹏 716fcc6f3d fix(openai): reject malformed WS v2 events 2026-07-15 21:20:41 +08:00
Wesley LiddickandGitHub bac925624f Merge pull request #4289 from Tiantianr/fix/openai-ws-first-message-timeout
fix(openai-ws): make first-message timeout configurable
2026-07-15 15:45:24 +08:00
Wesley LiddickandGitHub 4344f6afb0 Merge pull request #4298 from wp-a/fix/openai-images-json-completion-boundary
fix(images): preserve JSON completion boundaries
2026-07-15 11:08:47 +08:00
王鹏 91dc31ef39 fix(openai): fail over API-key passthrough 5xx 2026-07-15 04:21:38 +08:00
王鹏 2c13ed32e7 fix(images): preserve JSON completion boundaries 2026-07-15 03:15:47 +08:00
Tiantianr 74e296703a fix(openai-ws): make first-message timeout configurable
Add a dedicated client first-message timeout while preserving the legacy 30-second default.

Use the resolved value for both the WebSocket read deadline and structured timeout logs, and document tuning for large requests or slow links.

Add configuration, validation, handler, and resolver regression coverage.

Refs #4158
2026-07-14 22:40:05 +08:00
zz80900 40ec74b9fc fix(openai): preserve exact messages dispatch mappings
Treat a non-empty messages dispatch model as a caller-approved fallback after account-level mapping, without reclassifying the requested Claude family.\n\nAdd Fable forwarding and endpoint boundary regression coverage.\n\nFixes #4177
2026-07-13 17:57:08 +08:00
Bestony@Homelab c8cfc93632 fix(openai-ws): bound ingress session lifecycle 2026-07-13 15:32:42 +08:00
Heatherm Huang cccba9a82e Add official Grok 4.5 support 2026-07-09 14:26:10 +08:00
Heatherm Huang 10e623f674 fix: allow grok messages compatibility 2026-06-29 18:33:37 +08:00
Heatherm Huang 39be1ec97f feat: add grok subscription support 2026-06-26 10:36:09 +08:00
DaydreamCodingandClaude Opus 4.8 b62b573f7f feat(openai): cyber_policy 硬阻断全链路透传、审计与计费
上游对单次请求下发 error.code=cyber_policy 硬阻断时,网关在所有端点
(/v1/responses、/v1/chat/completions、/v1/messages、WebSocket)及流式/
非流式路径下,将该结果原样透传给客户端,绝不 failover、换号或同步拦截;
命中后异步完成审计与计费:

- 风控中心记录 cyber_policy 留痕并发送通知邮件,落库先于发信,SMTP 阻塞
  不影响留痕
- ops 错误请求记录,状态码对齐客户端实际接收(流式 200 / 非流式 400)
- 用量明细标记 request_type=cyber,按上游真实 token 计费,HTTP 与
  WebSocket 计费口径统一,零 token 命中不误扣
- 会话级自动屏蔽(管理员开关,默认关):命中的会话在可配 TTL 内本地拦截
  不再发往上游,仅屏蔽该会话不影响同 Key 其他会话
- 封号计数排除开关:可选让 cyber 命中不计入自动封号,命中当次不判定且
  历史行在违规计数中一并排除

WebSocket 多轮连接下 cyber 标记按 turn 生命周期管理,逐轮独立检测与记录;
透传的错误响应不被兜底逻辑追加内容污染。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 01:47:01 +08:00
jjaw 2c45f91d3c fix openai failover model body replacement 2026-06-09 21:52:04 +08:00
whatIsNextToTheMoon 5bd3d90434 fix(openai): preserve upstream response.failed errors 2026-06-04 11:17:22 +00:00
shaw 6010c3cca9 test: 修复内容审计日志异步断言 2026-05-29 09:57:02 +08:00
lyen1688 1b2d8873b0 feat: 完善前置拦截审核运行态 2026-05-28 20:05:24 +08:00
siyuan 08061717b8 fix: enable account failover for OpenAI WS rate limits 2026-05-26 20:07:00 +08:00
6b39b344d8 feat(quota): 用户 × 平台 USD 配额
为用户在 anthropic/openai/gemini/antigravity 四个平台上提供日/周/月
三个窗口的 USD 配额管控。配额语义:未设置=不限制,0=禁用,>0=美元上限。

两层模型:
- 配置层:系统默认配额,以及 email/linuxdo/oidc/wechat/github/google/
  dingtalk 七个鉴权来源的默认配额,存于 settings,以嵌套 JSON 整体读写
  (系统 1 个 key + 每个来源 1 个 key),整体替换语义。
- 运行时层:user_platform_quota 表按用户记录实际配额,与配置层解耦。

后端:新增 ent schema 与 140_user_platform_quotas.sql 迁移、repository
与 service 端口、计费链路集成、管理端与用户端读写接口。
前端:管理端设置页配额编辑、用户配额管理 Modal、用户 Dashboard 展示、
中英文案。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 10:49:20 +08:00
Jamie WongandClaude Opus 4.7 b34cc71bee fix(openai): also emit response.failed in ensureForwardErrorResponse after Writer.Written
Case B: when a slot wait flushes SSE ping comments first (Writer.Written
becomes true), the previous ensureForwardErrorResponse short-circuited
on `c.Writer.Written()` and returned false without notifying the client.
Subsequent upstream errors (http2 timeout, stream INTERNAL_ERROR, etc.)
produced silent EOF; Codex CLI reported "stream closed before
response.completed" just like the user-slot timeout case.

Remove the Written() early return; coerce streamStarted to true when
Writer has already been written to, and let handleStreamingAwareError
walk the existing logic — which now (thanks to the previous commits)
emits a protocol-compliant response.failed for /responses paths and the
legacy `event: error` for others.

Update tests that previously asserted "do not override written response":
the new contract is to *append* an SSE terminal frame so the client sees
a clean close instead of EOF. recoverResponsesPanic inherits this fix.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 22:00:56 +08:00
shaw fff4a300c6 feat(risk-control): add content moderation audit 2026-05-07 09:14:47 +08:00
lyen1688 0584305e5a feat: improve OpenAI messages compatibility for Claude Code 2026-05-05 19:36:33 +08:00
shaw df722c9a6e fix: remove OpenAI unknown model fallback 2026-05-04 11:43:00 +08:00
deqiying 23555be380 fix(openai): 修复 WS passthrough 使用记录缺失推理强度和 User-Agent
- 为 OpenAI Responses WebSocket v2 passthrough 补齐每轮 reasoning_effort 元数据
- 传递首帧渠道映射前模型,保留模型后缀推理强度推导能力
- 增加 usage log 端到端回归,覆盖入站 User-Agent、显式 effort 和渠道映射场景
2026-05-03 19:33:09 +08:00
IanShaw027 0fcddce69e fix: reject http responses continuation ids 2026-04-21 13:53:12 +08:00
IanShaw027 4de4823a65 feat(openai): 支持messages模型映射与instructions模板注入 2026-04-09 12:29:49 +08:00
Jiahao Luo 4617ef2bb8 Fix OpenAI default model forwarding 2026-03-20 13:36:54 +08:00
yangjianbo bb664d9bbf feat(sync): full code sync from release 2026-02-28 15:01:20 +08:00