Conversation
1. harden OpenAI compatibility forwarding 2. reject usage-only non-stream responses
Manual Grok connection tests previously surfaced upstream HTTP 402 errors without changing account availability. Persist the same 30-minute payment-required cooldown used by the live forwarding path so refreshed account lists no longer present the account as schedulable. Constraint: Keep manual-test HTTP 402 handling aligned with existing Grok forwarding semantics. Rejected: Mark the account permanently error | payment state can recover and the forwarding path intentionally uses a bounded cooldown. Confidence: high Scope-risk: narrow Directive: Keep the manual-test cooldown reason and duration aligned with handleGrokAccountUpstreamError. Tested: go test -tags=unit ./internal/service -count=1; go vet -tags=unit ./internal/service; production package compile check Not-tested: Live xAI account with an exhausted subscription Related: #4794
…prompt cache When an upstream API gateway (e.g. new-api) relays real Claude Code requests, the User-Agent becomes Go-http-client while the body retains the full Claude Code fingerprint (billing attribution block + metadata.user_id + cache_control breakpoints). Previously, the OAuth mimicry path relied solely on UA matching to detect Claude Code clients. Without a matching UA, the gateway would rewrite the system prompt — replacing the client's carefully structured system blocks and cache_control breakpoints with its own injection. This breaks Anthropic's prefix-based prompt cache: since the cache key evaluates tools → system → messages in order, a changed system invalidates all downstream message caching. Symptoms observed: - cache_read permanently locked at ~25K (only system prompt cached) - cache_creation growing monotonically every turn (full messages rewrite) - Single-request costs $17-27 instead of normal $1-2 Fix: when UA does not match but the body contains a valid billing attribution block (x-anthropic-billing-header with cc_entrypoint=), treat the request as proxied Claude Code traffic and skip mimicry. This preserves the client's original system structure and cache_control breakpoints, allowing Anthropic's prompt cache to function correctly.
Make CONFIG_FILE select an explicit config for both full loading and lightweight address lookup, with regression tests.
Namespace tool flatten/restore, array function_call_output, omit empty input_schema for native tools, lift additional_tools; scoped to ForwardAsResponses.
MonitorTimeline 每根柱子设置了 min-w-[3px],60 根柱子加 2px 间距的 最小总宽度为 298px。当卡片内容区宽度低于该值时(如 100% 缩放下的 部分布局),时间线整体溢出卡片边缘。改为 min-w-0 让柱子随容器等分 压缩,任意宽度下均不再溢出。
fix(grok): pause accounts after manual test payment failure
…-overlap fix: show optional affiliate code on registration
fix: show routed user in usage filters
…-channels fix(frontend): adapt available channels for mobile
…fig-load fix(security-audit): reject unavailable prompt config
…fering fix(deploy): prevent Caddy compression from buffering SSE
fix(openai): track WebSocket models per turn
fix(frontend): 修复渠道监控时间线在窄卡片下溢出
…-2.1.220 fix(claude): 伪装的 Claude Code CLI 版本号升级到 2.1.220
…break fix(gateway): 识别被代理的 Claude Code 流量,避免 mimicry 重写破坏 prompt cache
fix(admin): filter usage logs by request id
fix(config): honor explicit CONFIG_FILE path
fix(oauth): use claude.com/cai authorize endpoint
fix(grok): bump pinned Grok CLI version to 0.2.114
fix(model-plaza): Model Plaza image model price display is inconsistent with the actual price
fix(openai-ws): preserve terminal event on lease loss
…n-renewal fix(subscription): serialize concurrent renewals
…raffic The account+model transient breaker reset its failure streak whenever the gap since the previous failure exceeded a one-minute window. That made the breaker's sensitivity a function of request rate rather than upstream health: a gateway called less often than once a minute never advanced past streak 1, where the cooldown is zero, so a consistently broken account was never blocked. Every request re-selected it, paid a full upstream attempt, and only then failed over to a healthy account. Observed on a low-traffic deployment: two accounts returning 500 and 503 stayed in rotation indefinitely, logging `failure_streak: 1, cooldown_ms: 0` on every request and adding ~750ms to each one before a working account was reached. The streak is already cleared on success — recordSuccess deletes the entry, and every OpenAI handler reports the schedule result — so the time-based reset is not needed to recover a healthy account. Keep a TTL purely to bound the map for account+model pairs that stopped being used, and raise it well above the cooldowns so it no longer doubles as a streak reset. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
#5261 added a captcha check to POST /auth/oauth/pending/create-account, but the shared create-account form only gates its send-code button on the Turnstile token — the submit button's disabled condition never included it. Turnstile tokens are single-use, so handleSendCode resets the widget in its finally block and clears the token. Submitting inside the window before the widget re-solves omits turnstile_token from the payload, and the backend answers ErrTurnstileVerificationFailed (turnstile_service.go:65). With an interaction-required challenge the widget does not re-solve on its own, so the failure persists until the user notices and verifies again — while the button stays enabled and says nothing. Gate the submit button on the token, mirroring the send-code button and EmailVerifyView, which already gates its pending-OAuth submit the same way. handleSubmit repeats the check because implicit form submission (Enter in a text input) bypasses the button's disabled state. The Tencent path is unaffected: handleSubmit already acquires a fresh proof per submit, and turnstile_enabled is false in that configuration. Verified with the component spec (11 passed) and vue-tsc --noEmit (clean).
…it-gate fix(auth-ui): 第三方 OAuth 建号提交前必须持有验证码票据
沿用腾讯天御验证码引入的多服务商模型:aliyun_captcha_enabled 作为独立 开关,与 Cloudflare Turnstile、腾讯天御三方互斥(保存校验 + 运行时 CAPTCHA_PROVIDER_CONFLICT)。后台「安全与认证」合并为单张人机验证卡片: 总开关 + 服务商单选(Turnstile / 腾讯天御 / 阿里云),选中即启用该家并 关闭其它,落库仍是三个独立开关键,由前端映射保证互斥。 阿里云侧同时支持 aliyun 中国站与国际站(alibabacloud.com):两站前端脚本、 region 取值与服务端 API 完全一致,仅账号与 AccessKey 相互独立,因此由 「服务地域」决定线路即可——中国内地走 captcha.cn-shanghai.aliyuncs.com, 非中国内地(新加坡)走 captcha.ap-southeast-1.aliyuncs.com,AccessKey 取自持有该实例的账号,无需在配置中区分站点。 - AliyunCaptchaService 对称 TencentCaptchaService:服务端校验走官方 SDK VerifyIntelligentCaptcha,调用异常按 fail-closed 拦截,与 Turnstile 网络错误行为对称;保存设置时真实探测 AK/SK 有效性 - 保护面对齐腾讯扩展入口:VerifyTencentCaptchaIfEnabled 通用化为 VerifyActionCaptchaIfEnabled,OAuth 登录启动、passkey 登录在阿里云 启用时同样拦截;Turnstile 维持既有覆盖不扩大 - 前端 AliyunCaptchaWidget 为表单内预验证按钮(popup 模式),同时暴露 verify() 供 OAuth 启动、passkey 等动作入口程序化弹窗;未预验证直接 提交时弹窗兜底。SDK 按钮绑定异步完成,弹窗未出现前按 tick 重试触发, 并轮询弹窗可见性识别用户关闭 - captchaVerifyParam 复用 turnstile_token 请求字段提交;公开设置下发 aliyun_captcha_enabled / scene_id / prefix / region - CSP 放行验证码 CDN:script-src/style-src 加 *.alicdn.com
feat(aliyun-captcha): 人机验证增加阿里云验证码 2.0
…ary-scale fix(billing): quantize usage billing amounts to the NUMERIC(20,8) scale
fix(payment): preserve UTF-8 in EasyPay errors
…dence fix(openai): keep transient failure streak from resetting on sparse traffic
修复国内站和国际站 SDK 构造、验证容器、票据重置及动态资源加载问题,并补充认证流程回归测试。
修复腾讯验证码区域适配、重置与 CSP 加载
fix(openai): default OAuth identity to codex-tui
chore(sync): sync upstream v0.1.171 into develop
- sync upstream changes through sub2api v0.1.171 - preserve ModuRelay custom features and branding - update dependencies, lockfile, tests, and build assets - resolve all upstream merge conflicts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概述
本 PR 将
sync-upstream分支中已经完成三方语义合并的官方最新代码,同步合并到develop。本次上游同步范围:
Wei-Shaw/sub2apiv0.1.17193367b6db43315abe4f9fd9b09cbfc971b1f5ad0upstream-mainsync-upstreamv0.1.164 → v0.1.171合并策略
本次不是简单采用
ours/theirs,而是在sync-upstream分支完成生产级三方语义合并。核心原则:
冲突处理
本次共处理 15 个显式冲突文件,主要包括:
frontend/package.jsonpnpm-lock.yamlAccountBulkActionsBar.vueAnnouncementPopup.vueAppHeader.vueHomeView.vueAccountsView.vueEmailVerifyView.vueRegisterView.vue另外审计了双方共同修改但 Git 自动合并的文件,确认未发现明显的二开功能静默丢失。
ModuRelay 保留内容
本次同步继续保留:
包括以下设置链路:
AllowUserViewErrorRequestsUsageDetailShowUnitPricesUsageDetailShowRateMultiplierUsageDetailShowOriginalCost吸收的官方能力
本次同步吸收官方 v0.1.171 的主要更新,包括但不限于:
验证结果
已完成:
gofmtgo test ./...pnpm run lint:checkpnpm run typecheckpnpm run buildgit diff --checkgit diff --cached --check前端构建仅存在既有的 chunk 大小及动态/静态 import 警告,不影响构建通过。
尚未进行的生产环境验证
以下能力需要合并至
develop后继续进行实际环境冒烟测试:Merge Commit
本次上游三方合并提交:
34d59982d7bdd8582b10086cad264aaa0251bfea3其两个 parent 分别对应:
sub2api v0.1.171确保 Git 保留完整上游同步历史,便于后续继续增量同步官方代码。