3559 Commits
Author SHA1 Message Date
shaw 4e4ce440b3 fix(test): align duplicate account test with new NewAccountHandler signature 2026-07-15 16:13:22 +08:00
shaw bdb5be1c42 Merge remote-tracking branch 'origin/main' into pr4241-fix 2026-07-15 16:11:28 +08:00
Wesley Liddick 0de768e8be Merge pull request #4221 from heathermhuang/codex/fix-grok-oauth-pool-health
fix(grok): refresh OAuth pools proactively
2026-07-15 16:07:09 +08:00
Wesley Liddick d348193179 Merge pull request #4262 from wucm667/fix/issue-4245-root-models-alias
fix(codex): add root models compatibility alias
2026-07-15 16:06:59 +08:00
Wesley Liddick 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 Liddick 651bb019d5 Merge pull request #4346 from xiaohei210509/agent/handle-codex-image-function-tool
fix(openai): preserve Codex image function tools during bridge injection
2026-07-15 15:35:07 +08:00
Wesley Liddick 4de53b61b8 Merge pull request #4339 from wp-a/codex/read-tool-stream-finalization
fix(apicompat): sanitize complete Read tool argument streams
2026-07-15 15:16:24 +08:00
Wesley Liddick dba6cefb6b Merge pull request #4340 from wp-a/codex/anthropic-incomplete-finalization
fix(apicompat): preserve incomplete stream finalization
2026-07-15 15:16:12 +08:00
Wesley Liddick 80560e48d2 Merge pull request #4341 from wp-a/codex/additional-tools-discriminator
fix(apicompat): scope additional tools parsing
2026-07-15 15:15:58 +08:00
xiaohei210509 ade5944201 fix(openai): preserve Codex image function tools 2026-07-15 15:10:43 +08:00
Wesley Liddick 44452d4a9d Merge pull request #4334 from lenzhang/fix/grok-vision-image-bridge
fix(grok): bridge image_url content parts through Responses API for vision models
2026-07-15 14:43:44 +08:00
Wesley Liddick 8e84071f21 Merge pull request #4307 from wp-a/fix/openai-first-output-timeout
fix(openai): bound native responses first output wait
2026-07-15 14:41:11 +08:00
Wesley Liddick 788b1cebf1 Merge pull request #4333 from superman2003/fix/grok-free-messages-function-cache
fix(grok): cache Free Messages function tools
2026-07-15 14:40:14 +08:00
王鹏 9b4a7d5d47 fix(apicompat): sanitize complete Read tool argument streams 2026-07-15 14:31:26 +08:00
王鹏 d6d9f6ea4f fix(apicompat): preserve incomplete stream finalization 2026-07-15 14:31:26 +08:00
王鹏 c3a425837c fix(apicompat): scope additional tools parsing 2026-07-15 14:31:26 +08:00
shaw 986310d0bd fix(lint): apply De Morgan's law to grok vision bridge gate (QF1001) 2026-07-15 14:30:47 +08:00
Wesley Liddick 2d218fbe61 Merge pull request #4317 from yan9651688/feat/account-one-click-copy
feat(accounts): add safe one-click account duplication
2026-07-15 14:23:35 +08:00
Wesley Liddick 9d1b44e6a0 Merge pull request #4324 from superman2003/fix/responses-lite-tool-compat
fix(openai): normalize Responses Lite tool declarations
2026-07-15 14:22:15 +08:00
Wesley Liddick 601a1d1662 Merge pull request #4305 from wp-a/fix/outbox-degraded-rebuild-latch
fix(scheduler): latch degraded outbox rebuilds
2026-07-15 14:22:03 +08:00
Wesley Liddick 83ef20bf8b Merge pull request #4299 from wp-a/fix/xai-oauth-unsafe-base-url-components
fix(xai): reject empty base URL queries
2026-07-15 14:21:42 +08:00
superman2003 3170c110a0 fix(openai): surface Messages stream error events 2026-07-15 14:07:01 +08:00
superman2003 08ea29428d fix(grok): recognize probed Free cache accounts 2026-07-15 14:07:01 +08:00
Wesley Liddick 156cabd260 Merge pull request #4316 from fengshao1227/fix/grok-image-model-responses-reject
fix(grok): 拦截图片模型发往 Responses 端点,返回明确错误
2026-07-15 13:49:25 +08:00
Wesley Liddick 3e30862ddd Merge pull request #4295 from caigee-cmd/perf/direct-anthropic-chatcompletions-bridge
perf(apicompat): force-chat 路径直转 Anthropic↔ChatCompletions,跳过 Responses 中间层
2026-07-15 13:46:56 +08:00
王鹏 9950f4a2e2 fix(scheduler): latch degraded outbox rebuilds 2026-07-15 13:24:08 +08:00
lenzhang d5bc576b4f fix(grok): bridge image_url content parts through Responses API for vision models
The eligibility gate in grokChatResponsesBridgeEligibility rejected any
structured content (arrays), including standard OpenAI image_url parts.
This forced image-bearing requests to fall back to raw Chat Completions
forwarding, where non-Composer models have no image bridge — silently
dropping the images or causing upstream errors.

Changes:
- Allow content arrays containing only text and image_url parts to pass
  eligibility, so ChatCompletionsToResponses can convert them to
  input_image parts that Grok vision models natively support.
- Force image-bearing requests to use Responses even when no prompt
  cache identity is available, since the raw path cannot forward images
  for non-Composer models.
- Add grokChatStructuredContentBridgeable helper with conservative
  validation: unknown part types (e.g. input_audio) still fall back.
- Update tests: image_url content is now bridgeable; add cases for
  text+image, text-only arrays, unknown parts, and empty arrays.
2026-07-14 22:24:03 -07:00
superman2003 f041b5cf0a fix(grok): cache Free Messages function tools 2026-07-15 13:05:13 +08:00
王鹏 fc4089f292 fix(openai): bound native responses first output wait
Add an opt-in first semantic output budget for native HTTP Responses, including response-header wait. Keep preamble and keepalive bytes non-semantic so a stalled account can fail over once without replaying its response IDs. Defaults remain disabled.

Related to #4201, #4185, and #4248. Complements the HTTP/2 dead-connection fix in #4207.
2026-07-15 13:01:16 +08:00
王鹏 e8e360c802 fix(xai): reject unsafe base URL components 2026-07-15 12:50:15 +08:00
shaw 7b51271a84 fix(apicompat): default stop_reason for empty-choices responses
Adversarial re-verification found one more divergence from the
double-conversion chain: an upstream 200 with empty choices (or a nil
response) left stop_reason as an empty string, while the old chain
reports end_turn. Derive the fallback from the content blocks — the
guard never fires when choices exist, since every finish_reason maps to
a non-empty stop_reason.

Also strengthen the equivalence tests: compare tool_use Content[].Input
and tool_call Function.Arguments across bridges, and add an
empty-choices stop_reason parity case.
2026-07-15 11:44:47 +08:00
superman2003 bc6d9c47d2 fix(openai): normalize Responses Lite tool declarations 2026-07-15 11:37:38 +08:00
shaw 430fd8f20a fix(apicompat): align direct bridge edge semantics with double conversion
Adversarial review of the direct bridge found divergences from the
double-conversion chain it replaces; all are now aligned and covered by
tests that fail against the previous implementation:

- flush argument fragments buffered before a deferred tool announcement,
  and announce name-less tools at finalize, so no tool arguments are lost
  when upstreams stream arguments before the name
- fold text-only user array content into a single string; parts form only
  when an image requires it (strict chat upstreams reject array content)
- drop tool_choice pointing at undeclared tools and unknown choice types
- treat cache_write_tokens/cache_creation_tokens as alternate spellings
  (prefer write), not additive
- generate a response id when the upstream omits one
- derive stop_reason from blocks for content_filter/unknown finish reasons
- emit input_json_delta "{}" when a tool block closes without argument
  deltas
2026-07-15 11:29:22 +08:00
li 6a61b2daca fix(grok): 拦截图片模型发往 Responses 端点,返回明确错误
Fixes #4301
2026-07-15 11:16:07 +08:00
Wesley Liddick 3f605c3543 Merge pull request #4303 from wp-a/fix/web-fingerprinted-asset-caching
fix(web): limit immutable caching to fingerprinted assets
2026-07-15 11:12:50 +08:00
Wesley Liddick 23796a1b34 Merge pull request #4291 from bestony/agent/user-server-timing/bes-26
feat: extend Server-Timing to authenticated user web APIs
2026-07-15 11:12:37 +08:00
Wesley Liddick 5b5e41450c Merge pull request #4310 from jianjianai/codex/perf-scheduler-final
perf(scheduler): 完善缓存桶生命周期并复用重建批次查询
2026-07-15 11:09:47 +08:00
Wesley Liddick 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
Wesley Liddick 6460b9895c Merge pull request #4297 from wp-a/fix/openai-reset-credit-malformed-details
fix(openai): preserve reset count on malformed details
2026-07-15 11:08:25 +08:00
yan9651688 f7da6e2bc6 fix(accounts): prevent duplicate retries from crossing admins
Ambiguous idempotency-store failures can occur after the account transaction commits. Scope durable recovery markers to the authenticated admin, retain the operation key across reloads, and recover only an already committed copy without rerunning active work.

Constraint: Generic idempotent handlers may legitimately remain active while a recovery lookup is attempted

Rejected: Reclaim or rerun an in-progress duplicate request | can execute account creation concurrently

Rejected: Recover by source account and key alone | allows another admin to observe the committed copy

Confidence: high

Scope-risk: narrow

Reversibility: clean

Directive: Keep ambiguous-response recovery read-only and bind durable operation markers to the authenticated actor

Tested: Full Go unit suite, go vet, server build, integration-test compilation; frontend lint, typecheck, 1,030 Vitest tests, and production build

Not-tested: Docker-backed PostgreSQL integration runtime because Docker is unavailable

Related: Wei-Shaw/sub2api#1379

Related: Wei-Shaw/sub2api#2928
2026-07-15 10:51:13 +08:00
yan9651688 60ff61132d feat(accounts): make repeated static account setup safer
Admins often need another account with the same provider and routing configuration. Duplicate on the server so credentials never return to the browser, preserve exact group priorities atomically, start the copy paused, and recover the same copy after ambiguous idempotency-store failures.

Constraint: Admin account responses redact credentials, so duplication must remain server-side

Constraint: OAuth and setup-token credentials rotate and must not be shared across account rows

Rejected: Copy raw account JSON to the clipboard | exposes credentials outside the server

Rejected: Duplicate rotating credentials | account-scoped refresh locks can race token rotation

Confidence: high

Scope-risk: moderate

Reversibility: clean

Directive: Keep copies paused, avoid automatic upstream probes, and exclude rotating credential types unless token ownership is redesigned

Tested: Targeted Go tests, Go vet, server build; frontend lint, typecheck, Vitest suite, production build; integration test compiled

Not-tested: Docker-backed PostgreSQL execution because Docker is unavailable

Related: Wei-Shaw/sub2api#1379

Related: Wei-Shaw/sub2api#2928
2026-07-15 10:51:13 +08:00
shaw cf6aa1a5c3 fix(openai): 和解 #4304 与 #4306 的透传错误语义冲突
两个 PR 分别合并后在 main 上语义相撞(文本无冲突,CI 才暴露):
- #4306 把所有非 failover 透传错误重建为通用净化信封;
- #4304 要求确定性 context-window 错误不切号且文案对客户端可见
  (如触发客户端自动压缩),其测试断言原文可达。

和解方案(保留双方意图):
- 净化器拆出 writeOpenAIPassthroughErrorEnvelope;context-window 错误
  仍走本地 JSON 信封 + 净化头策略,但 message 使用脱敏后的上游消息,
  不再抹成通用文案;其余错误净化行为不变。
- RebuildsUpstreamErrors 的两个 5xx 用例改用非瞬时状态码(530/501):
  瞬时 5xx 对 API-key 账号已按 #4304 契约走 failover(由
  APIKeyPassthrough_Transient5xxTriggersFailover 覆盖),净化重建
  路径的 5xx 覆盖由非瞬时状态码继续承担。
2026-07-15 10:40:14 +08:00
Wesley Liddick 40a59c9e86 Merge pull request #4275 from jianjianai/codex/perf-u17-response-sse-flush
优化 Responses 流式事件边界刷新
2026-07-15 10:30:31 +08:00
Wesley Liddick 65d744d0e1 Merge pull request #4294 from caigee-cmd/fix/parallel-tool-use-ghost-delta
fix(apicompat): 并行 tool_use 幽灵 content_block_delta(index 错误)
2026-07-15 10:26:02 +08:00
Wesley Liddick 2381b6c104 Merge pull request #4304 from wp-a/fix/openai-passthrough-5xx-failover
fix(openai): fail over API-key passthrough 5xx
2026-07-15 10:20:44 +08:00
shaw a38220ebdc Merge origin/main into fix/openai-passthrough-5xx-failover (resolve #4269 conflicts)
# Conflicts:
#	backend/internal/service/openai_gateway_passthrough.go
2026-07-15 10:18:55 +08:00
Wesley Liddick 2ceaa4783c Merge pull request #4311 from jianjianai/codex/perf-openai-forwarding-final
perf(openai): 优化 Responses 图片意图判定与透传流式刷新
2026-07-15 10:12:05 +08:00
Wesley Liddick 9b86585909 Merge pull request #4296 from wp-a/fix/openai-responses-sse-json-boundaries
fix(openai): repair concatenated Responses stream events
2026-07-15 10:11:55 +08:00
Wesley Liddick 42d1bf298d Merge pull request #4306 from wp-a/fix/openai-passthrough-error-sanitization
fix(openai): sanitize passthrough upstream errors
2026-07-15 10:11:41 +08:00
shaw eb7933af4c fix(openai): 移除 #4269 合并时复活的旧版 Grok 错误路径处理
#4269 分支基于 #4212 之前的 main(merge-base da85cc7e),合并后把
ForwardAsAnthropic 错误路径上已被 #4212 重构移除的 Grok 块带了回来:
- xai.ParseQuotaHeaders 的 import 已被 main 删除,导致 main 编译失败;
- 该块与 failoverOpenAIUpstreamHTTPError 内部的 handleGrokAccountUpstreamError
  重复(后者第一步就用新解析器 parseGrokQuotaSnapshot 更新配额快照),
  保留会造成 Grok 错误双重处置。

删除整块,恢复 #4212 语义;#4269 的 agent identity 恢复逻辑保留不动。
2026-07-15 10:01:31 +08:00