Skip to content

chore: integrate official Sub2API v0.2.20 - #304

Open
HTExplicit wants to merge 114 commits into
mainfrom
sync/upstream-0.2.20
Open

HTExplicit wants to merge 114 commits into
mainfrom
sync/upstream-0.2.20

Conversation

@HTExplicit

Copy link
Copy Markdown
Owner

完整整合官方 v0.2.20(固定提交 dab829a),接入管理 MCP、请求体内存预算和逐次 I/O 超时、图片尺寸路由及协议修复。保留下游固定设备和独立会话、严格传输、管理员原文、账号测试提示词与预算、确认挑选器和异步计费快照;MCP 继续默认关闭。

33 个初始冲突的决议见 .downstream/upstream-review-v0.2.20.md。原 SQL 文件与 checksum 保留,新旧两份 249 按完整文件名并存。按实际变更补齐选择式 CI 的精确测试映射并合并相同包的执行,不增加保护层、fallback 或生产配置调整。

验证:Go 1.27.3 启动包编译、前端冻结安装与类型检查、123 个前端定向测试、请求体预算/超时与协议转换、身份桥接/严格传输、handler/计费/测试提示词定向用例、MCP 默认关闭配置及 CI/upstream 离线契约。隔离 PostgreSQL 验证完整既有迁移升级、新安装与重复启动,旧数据快照保持。实际结果与失败后局部复验均保留在运维交付证据中;无真实模型或支付调用。

ShuminFu and others added 30 commits October 9, 2026 14:29
OAuth passthrough forces stream=true for the ChatGPT internal API and then
overwrote reqStream from the rewritten body, so clients sending
stream=false received the raw upstream SSE stream. Keep the client's
original stream flag (compact requests stay non-streaming) so the
non-streaming branch aggregates SSE into a single Responses object.

Also set Content-Type explicitly when the SSE-to-JSON handlers write the
aggregated body: the upstream text/event-stream header was already
copied into the response and gin's c.Data does not override an existing
Content-Type. Applies to both passthrough and non-passthrough paths.

Fixes Wei-Shaw#7978
When a non-streaming /v1/responses request is aggregated from upstream
SSE and the stream ends with response.incomplete (e.g. max_output_tokens)
or response.cancelled instead of response.completed, the SSE-to-JSON
handlers fell back to relaying the raw SSE body. Use the terminal event's
response object as the final JSON (keeping status/incomplete_details) in
both handlePassthroughSSEToJSON and handleSSEToJSON. Usage is still
recorded. extractCodexFinalResponse is unchanged.

Refs Wei-Shaw#7978
The generated Terra entry copied the API model page into the Codex
catalog: it offered none, omitted ultra, defaulted to medium and fell
back to a 272k window and the GPT-5.5 prompt. Codex publishes a separate
descriptor (openai/codex 126a0ee92ed2, models.json): low by default, low
through ultra, a 500k/872k window, Fast as the only extra tier and its
own instructions. A ChatGPT Plus account's live /backend-api/codex/models
response reports the same reasoning, window and tier values.

Bundle that descriptor like GPT-6.1 Sol, take Terra's base instructions
from it, and give official accounts the same route defaults: API-key
clients stay on full Responses, OAuth keeps Responses Lite and code mode.
Account-supplied manifests remain authoritative, and API requests keep
none through max. The model list now records the 2026-10-26 release
time instead of a 2024 placeholder.
GPT-6.1 Terra publishes none through max; minimal is not on its scale.
Recognize the -minimal spelling so the alias still resolves to Terra,
and reject minimal on the Chat, Messages and Responses compatibility
paths with the same 400 Sol uses for its unsupported levels. none stays
valid for Terra, and Sol keeps its stricter low-through-max checks.

Compatibility requests mapped to Terra also did not receive the derived
prompt_cache_key that other GPT-6 Responses models get, so Chat and
Messages traffic lost its stable cache identity. Include Terra there.
…rcharge

Codex opens GPT-6.1 Terra with a 500k default window, so subscription
requests routinely pass the 272k API long-context threshold. Apply the
existing GPT-6.1 Sol rule: OAuth and setup-token requests whose final
upstream model is Terra skip the model surcharge, while API keys keep
the published 2x input/cache and 1.5x output rates. Also label Terra's
fallback prices with their own release date.
…h non-stream

The ChatGPT OAuth upstream may answer with SSE but omit the Content-Type
header. Fall back to bodyHasSSEFraming for OAuth accounts in
handleNonStreamingResponsePassthrough, matching handleNonStreamingResponse,
and add a regression test covering both passthrough and non-passthrough.

Co-authored-by: SipengXie2024 <184713193+SipengXie2024@users.noreply.github.com>
- Reject JSON-RPC batches and non-object bodies before the SDK; return each
  tool result once as text and bound the encoded payload (H1).
- Enable MCP only when MCP_PUBLIC_URL is set; drop the frontend URL fallback
  and expose a read-only mcp_enabled public setting (M1).
- Expire never-authorized clients after 24h, cap pending registrations
  globally, aggregate MCP IP limits by IPv6 /64, and limit registration
  bodies to 4 KiB (M2).
- Revoke MCP grants with revoke-all-sessions and always require step-up for
  administrator write grants (M3).
- Rate limit /api/v1/mcp per IP before authentication and write last_used_at
  at most once per minute (M4).
- Persistently revoke grants when an account is disabled or demoted, derive
  result redaction from SensitiveCredentialKeys, allowlist browser sessions
  for step-up, audit every MCP read, reject invisible characters in
  client_name, and document site-root-only deployment (L1-L5, L7).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Replace the cube icon with the official MCP logo in the sidebar and on
  the MCP connection and consent pages.
- Show the MCP entry only when the deployment enables MCP (mcp_enabled).
- Explain that administrator write grants always need TOTP verification,
  and add MCP OAuth to the audit log auth-method filter.
- Remove the unreferenced screenshots and their .gitignore exceptions (L6).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…non-stream-7978

fix(openai): return JSON for non-stream OAuth passthrough /v1/responses
Antigravity 上游 (v1internal) 接受 generationConfig.responseJsonSchema 字段但静默忽略,
返回普通文本而非 JSON;只有 responseSchema 能触发结构化输出。@ai-sdk/google >= 4.0.70
等客户端只发送 responseJsonSchema,导致经网关的结构化输出全部失效。

cleanGeminiRequest 现在把 responseJsonSchema / response_json_schema 改写为 responseSchema,
并复用 CleanJSONSchema 清理(去掉 $schema、additionalProperties,约束迁移到 description)。
已有 responseSchema 时以其为准;没有 schema 的请求保持原样。
Registration was capped at 1000 pending clients site-wide while the limit
per IP was 10 per minute, so one address could exhaust the cap and block
every new MCP client.

- Issue client IDs as HMAC-signed tokens carrying the client name,
  redirect URI digests and grant types. Registration writes nothing;
  rows are created only when a user approves a client, so there is no
  shared capacity to exhaust.
- Persist the signing key in security_secrets via the existing
  get-or-create helper, cached lock-free, so instances share it.
- Drop mcp_oauth_clients from migration 249 and keep the client name on
  each grant. Prune expired grants on authorization, before the owner
  row is locked.
- Fix an unchecked type assertion in managementmcp tests flagged by
  golangci-lint v2.14.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed client IDs are now about 200 characters. Show them on one line on
the consent page and in the connection list, with the full value in the
title. The random part leads, so truncated IDs still differ.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	backend/go.mod
#	backend/go.sum
go-sdk v1.4.1 fixes GO-2026-4773 (cross-site tool execution) and
GO-2026-4770 (null Unicode JSON parsing), which fail govulncheck.

v1.4.1 also adds transport-level cross-origin and Content-Type checks
that would reject requests Authenticate already accepts:
- trust the same allowed origins in the SDK's CrossOriginProtection so
  CORS-allowlisted browser clients are not refused with 403;
- accept application/json with parameters (e.g. charset) by normalizing
  the header, while still refusing non-JSON bodies with 415.
feat: add OAuth-authenticated management MCP
Fixes frontend-security on main for two new high advisories:
- GHSA-83rm-6c8r-g728 (vue-i18n / @intlify/* srcdoc XSS): v9 and v10
  are end of life and will not be patched, so move vue-i18n and
  @intlify/message-compiler to 11.4.16.
- GHSA-qr28-fpjm-wq7f (decode-uri-component quadratic DoS): add a
  pnpm override to >=0.5.1; its API and types are unchanged.

vue-i18n 11 requires Node >= 22, so CI and release workflows move from
Node 20 to Node 24, matching the Docker build image.

JIT message compilation is always on since v10, so the obsolete
__INTLIFY_JIT_COMPILATION__ define is removed; the build still has no
new Function. SubscriptionPlanCard spec asserted raw keys that v9's
runtime build returned; it now asserts the rendered test messages.
用户使用记录导出按 100 条/页连续请求 GET /api/v1/usage,该路由计入按用户的
重查询限流(默认 heavy_rpm=60,固定 60 秒窗口)。数据量超过约 5,000 行时,
导出在第 50~60 页收到 429,任一页失败即整体报「导出失败」。

- 导出页大小改为 1000(后端分页上限),请求数降为原来的 1/10。
- API 客户端结构化错误携带 retry_after_seconds(解析整数秒的 Retry-After)。
- 导出遇 429 时提示并按 Retry-After 等待(读不到时按 60 秒,夹在 1~60 秒)
  后重试同一页,每页最多重试 3 次。
cyhhao and others added 26 commits November 7, 2026 01:52
Upstream added WithBodyReadTimeout (gateway.request_body_read_timeout_seconds)
and client-gone handling for body reads. Drop this branch's own server-level
idle-timeout wrapper and server.request_body_idle_timeout setting in favor of
it, and keep the classification and diagnostics on top:

- readRequestBodyChunksWithBudget reports the read error before ctx.Err():
  on HTTP/1 a read deadline also cancels the request context, which turned
  every timeout into context.Canceled. Read errors carry bytes read and
  elapsed time in RequestBodyReadError.
- handleRequestBodyReadError and RejectRequestBodyReadError skip the
  client-gone (empty 499) path for read timeouts, so they are reported as
  408 instead of a client cancellation (HTTP/1) or a generic 400 (HTTP/2).
- Every gateway body read site and both body-reading middlewares log
  payload-free diagnostics, including the client-gone path.
Stalled uploads to /v1/tts, /v1/stt and /v1/custom-voices reach GrokVoice
directly. Its read errors fell through to a 400 carrying err.Error(): with
the read timeout now preserved, that reported a timeout as a malformed
request and returned the raw socket error. Keep the validation message for
a missing body and send every read error through the shared classifier.
…ing-content

fix(apicompat): preserve buffered reasoning content
…content

fix(responses): preserve message content fields in completed responses
…y-test-prompt

fix(antigravity): 账号测试发送管理员输入的提示词并允许模型作答 / Account test sends the admin's prompt and lets the model answer
…y-internal500-scope

fix(antigravity): INTERNAL 500 只冷却出错的图像模型,账号惩罚档位可配置 / Scope INTERNAL 500 penalties to image models; configurable account tiers
…re-body-limit-failover

fix(openai): let error passthrough rules override the built-in body-limit 413
…se-media

fix(gemini): preserve tool media in native function responses
fix(openai): 打通 GPT Image 2.6 原生图片链路
…meout

fix(gateway): report request body read timeouts as 408 and log read failures
…y-quota-summary

feat(antigravity): 按配额分组显示真实的 5 小时与每周窗口 / Show each quota group's real 5-hour and weekly window
…-setup-token-weekly-usage

fix(anthropic): preserve setup-token weekly usage without 5h limits
…ity-direct-response

fix(antigravity): preserve direct Gemini streaming responses
…ount-test-response-format

fix(openai): omit response_format from GPT Image account tests
…probe-forced-mode

fix(openai): skip responses probe when routing mode is forced
…st-token

fix(openai-ws): record first token time for every passthrough turn
…-fingerprint

fix(openai): apply Codex fingerprint convergence in the WebSocket HTTP bridge so multi-turn requests hit the prompt cache
…rmed-key

fix(auth): stop reporting client disconnects and malformed keys as 500
…ponse-json-schema

fix(antigravity): Gemini 原生请求的 responseJsonSchema 改写为 responseSchema
…est-messages-beta

fix(anthropic): omit beta query for Cloudflare REST messages
…tive-tools-export

fix(frontend): improve Codex image and live-search exports
fix(openai): complete GPT-6.1 Terra Codex metadata, validation and billing
@HTExplicit HTExplicit added upstream-review-required Manual upstream review is required upstream-reviewed Human upstream overlap review completed labels Nov 7, 2026
@HTExplicit HTExplicit closed this Nov 7, 2026
@HTExplicit HTExplicit reopened this Nov 7, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

upstream-review-required Manual upstream review is required upstream-reviewed Human upstream overlap review completed

Projects

None yet

Development

Successfully merging this pull request may close these issues.