haruka and Claude Opus 4.8
06e03f467a
feat(billing): 渠道自定义定价支持图片输入 token 单价 image_input_price
...
渠道 token 计费模式此前无法为图片输入 token 单独定价,gpt-image-2
图片编辑等请求的图像输入被按文本 input_price 计费。新增
channel_model_pricing.image_input_price 列及全链路支持。
后端:
- 迁移 178:channel_model_pricing 新增 image_input_price 列
- ChannelModelPricing 新增 ImageInputPrice 字段,repo 读写、校验补齐
- model_pricing_resolver / GetModelPricingWithChannel 映射到
ImageInputPricePerToken;未配置时归零,由 computeTokenBreakdown
回退文本输入价(向后兼容,与 image_output_price 的渠道权威规则一致)
- admin / 用户侧定价 DTO 与 model-pricing 自动填充接口补充该字段
前端:
- 渠道定价表单新增「图片输入」价格输入(token 模式)
- API 类型、表单模型、form↔API 换算、自动填充、用户侧模型定价卡展示
- zh/en i18n 标签
相关 #4386。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_015wcJTKDddxXSQrepSs3wrU
2026-07-15 09:35:34 -07:00
haruka and Claude Opus 4.8
7c43b7327d
feat(billing): 解析 usage.input_tokens_details 拆分图/文输入 token
...
/v1/images/edits 等带图请求,上游在 input_tokens_details.image_tokens
单独回传图片输入 token,此前被合并进 input_tokens 整体按文本输入价计费。
- openAIUsageFromGJSON 读取 input_tokens_details.image_tokens
(回退 prompt_tokens_details.image_tokens)写入 OpenAIUsage.ImageInputTokens
- mergeOpenAIUsage 补充 ImageInputTokens 的流式合并
配合全局定价的 input_cost_per_image_token,gpt-image-2 图片编辑请求的
图像输入即按独立单价计费。相关 #4386。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_015wcJTKDddxXSQrepSs3wrU
2026-07-15 09:24:44 -07:00
haruka and Claude Opus 4.8
10cb2ca42c
feat(billing): 全局定价解析 input_cost_per_image_token
...
LiteLLM 定价数据中 gpt-image-2 等模型已含 input_cost_per_image_token
(图片输入 token 单价),但此前未被解析,导致图片编辑/图生图请求的
图像输入 token 被按文本输入价计费。
- LiteLLMModelPricing / LiteLLMRawEntry 新增 InputCostPerImageToken 字段并解析
- GetModelPricing 将其映射到 ModelPricing.ImageInputPricePerToken
计费拆分算术(computeTokenBreakdown)已支持图/文输入分价,本提交补齐
全局定价路径的数据来源。相关 #4386。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_015wcJTKDddxXSQrepSs3wrU
2026-07-15 09:23:35 -07:00
Wesley Liddick
be6cd1250c
Merge pull request #4367 from Wei-Shaw/feat/grok-custom-base-url-and-headers
...
feat(grok): 支持账号级自定义上游地址与请求头覆写
2026-07-15 20:55:16 +08:00
Wesley Liddick
34015a1791
Merge pull request #4359 from catoncat/agent/fix-agent-identity-import-expiry
...
fix(openai): make Agent Identity usable end to end
2026-07-15 20:55:05 +08:00
Wesley Liddick
a733e66330
Merge pull request #4358 from DanisJiang/feat/admin-recharge-affiliate-rebate
...
feat(affiliate): support rebates for admin balance deposits
2026-07-15 20:54:48 +08:00
Wesley Liddick
960d1886f3
Merge pull request #4323 from turingcat/feat/plan-currency-label
...
feat(payment): 订阅套餐支持币种标注,区分 $ 符号对应币种
2026-07-15 20:54:34 +08:00
shaw
221581400b
feat(grok): 支持账号级自定义上游地址与请求头覆写
...
将账号级请求头覆写从 anthropic/openai 的 api_key 账号扩展到 Grok 的
api_key 与 oauth 账号,并放开 Grok OAuth 账号的自定义上游地址(仅作用于
转发端点,授权与 token 刷新链路不变)。
后端:
- IsHeaderOverrideEligible 扩展到 Grok(api_key+oauth),禁止名单新增
x-grok-conv-id(逐请求会话路由头)。
- 所有 Grok 上游请求路径接线 ApplyHeaderOverrides(Responses/Chat 桥/
媒体/配额探测/billing 探测/连通性测试),统一置于内置默认头之后。
- GetGrokBaseURL/GetGrokMediaBaseURL 放开 OAuth 自定义地址:官方地址
视同未定制回落官方网关,仅显式第三方 host 改发转发流量。
- 非官方 host 允许任意 path 前缀,官方 host 仍强制 /v1。
- OAuth base_url 校验按 host 判定官方/自定义,自定义 host 恒受运营方
URL 策略约束,不受 XAI_ALLOW_UNSAFE_URL_OVERRIDES 调试开关放宽。
- 给 GrokQuotaService 注入 config,使配额/billing 探测与转发共用同一
URL 策略。
前端:
- Edit 模态为 Grok OAuth 账号新增「自定义上游地址」开关。
- 请求头表单新增 JSON 快速导入与按 JSON 一键复制(复用 useClipboard,
兼容非安全上下文 HTTP 页面)。
- 门控改为平台×类型判定,Bulk 批量 base_url 增加格式校验,zh/en 文案同步。
2026-07-15 20:30:23 +08:00
cat
2147da682b
fix(openai): 修复 Agent Identity 审查问题
2026-07-15 18:30:16 +08:00
cat
12e6e70775
fix(openai): 补全 Agent Identity Codex 能力
2026-07-15 17:52:10 +08:00
Yuhao Jiang
736824dd7a
feat(affiliate): add admin recharge rebate option
2026-07-15 04:28:55 -05: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
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
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
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
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
superman2003
bc6d9c47d2
fix(openai): normalize Responses Lite tool declarations
2026-07-15 11:37:38 +08:00
turingcat and Claude Fable 5
2bbdd47002
feat(payment): 订阅套餐支持币种标注,区分 $ 符号对应币种
...
后台配置与用户端展示的套餐价格统一使用 $ 符号,而实际扣款币种随
支付渠道配置漂移(如 Stripe 配置 NZD 时按新西兰元扣款),用户易
误认为美元。本次为套餐新增可选的展示性币种标注:
- SubscriptionPlan 新增 currency 字段(ISO 4217 三字母码,默认空)
- 空值不展示任何标注,存量套餐行为完全不变
- 非空值复用 payment.NormalizePaymentCurrency 校验并规范化为大写
- 后台套餐编辑弹窗新增可选币种输入,列表价格列展示币种小字
- 用户端套餐卡片价格与划线原价旁展示币种小字
- 纯展示性质,不影响任何支付/扣款逻辑
Closes #4315
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
2026-07-15 11:17:45 +08:00
li
6a61b2daca
fix(grok): 拦截图片模型发往 Responses 端点,返回明确错误
...
Fixes #4301
2026-07-15 11:16:07 +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
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
Wesley Liddick
4355861ef2
Merge pull request #4269 from catoncat/agent/sub2api-agent-identity
...
feat(openai): support Codex Agent Identity authentication
2026-07-15 09:47:00 +08:00
Heatherm Huang
3a3b962de3
fix(grok): normalize refresh errors
2026-07-15 09:40:08 +08:00
Heatherm Huang
b245ab5848
fix(grok): satisfy pool health lint
2026-07-15 09:40:08 +08:00
Heatherm Huang
6a62ea1b1d
test(grok): synchronize refresh candidate fixture
2026-07-15 09:40:08 +08:00
Heatherm Huang
6b25900403
fix(grok): refresh OAuth pools proactively
2026-07-15 09:40:08 +08:00