Commit Graph
77 Commits
Author SHA1 Message Date
Ritel-T 0681aa2566 Cover Group Fast in native Responses 2026-09-01 04:34:06 +09:00
Wesley Liddick d24de611f8 Merge branch 'main' into fix/openai-reasoning-replay 2026-08-28 11:27:39 +08:00
Wesley Liddick ee2c8b97bb Merge branch 'main' into fix/apikey-namespace-roundtrip 2026-08-28 11:16:48 +08:00
zhaotao1 00b7c855cc fix(openai): preserve declared API-key namespace calls 2026-08-27 15:22:43 +08:00
feeeei d881bfc0de fix(openai): 避免 pool 两跳重复计算 system 提示词 2026-08-26 19:55:49 +08:00
shaw 8ba81615e0 merge: resolve conflict with main (upstream endpoint observability)
Merge origin/main into contrib/routed-codex-model-catalog.

Single conflict in openai_gateway_forward.go: main added
ClearActualOpenAIUpstreamEndpoint + SetActualOpenAIUpstreamEndpoint
(commit 4795650d2) at the same insertion point where the PR added
filterOpenAIResponsesNoneReasoningEffortForAccount. Both changes
are independent — endpoint observability first, then body filtering.
2026-08-26 15:29:01 +08:00
shaw 4795650d21 fix(openai): record actual upstream endpoint on errors 2026-08-26 09:42:28 +08:00
Long LiandCursor 77b6c5bb0c merge: sync contrib/routed-codex-model-catalog with upstream v0.1.182
Keep catalog membership on schedulable accounts and intersect advertised
capabilities across all active group members that map an alias. Preserve
upstream plugin, service-tier, and models-list body-limit changes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-25 21:28:57 +09:00
hank 32064d39e7 fix(openai): normalize cross-provider reasoning replay 2026-08-25 17:04:38 +08:00
shaw 095b525360 fix(openai): pin Responses Lite parallel tool calls 2026-08-25 12:14:52 +08:00
Jiao Ziang 53d76ad800 fix(openai): enforce Responses Lite tool call mode 2026-08-25 00:21:29 +08:00
Wesley Liddick 7bb9c0ed7d Merge pull request #6079 from okbexx/fix/codex-analytics-account-affinity
fix(openai): scope Codex identity to OAuth account
2026-08-24 14:54:05 +08:00
Wesley Liddick 5f43696a9a Merge pull request #6121 from creamtea47/codex/feat-openai-auto-reset-credit
feat: OpenAI 重置卡按用量阈值自动使用
2026-08-24 14:39:59 +08:00
NellPoi 6f972145b7 feat: 支持 OpenAI 重置卡按用量阈值自动使用 2026-08-24 13:28:33 +08:00
alfadb f06bf181d2 feat(openai): support Fast mode service_tier across responses/chat/WS paths
- Accept fast|priority (canonical priority), flex|auto|default|scale on
  /v1/responses and /v1/chat/completions; reject unknown/empty/non-string
  with HTTP 400; omitted and null stay compatible.
- Propagate service_tier through JSON/SSE, Responses<->Chat conversions,
  fallback paths and HTTP->upstream WebSocket bridge.
- Billing prefers the upstream terminal tier; the outbound (policy-
  transformed) tier is used only when upstream omits the field.
  Explicit upstream default bills Standard even when Fast was requested.
- Pricing: Fast premium 2x Standard for gpt-5.6-sol/terra/luna and
  gpt-5.4; 2.5x for gpt-5.5; channel FastMultiplier stays authoritative.
- Live verification (official Codex 0.149.0 + gateway, HTTP & WS):
  upstream ChatGPT backend may return terminal default even when the
  account catalog advertises priority; billing follows the actual tier.
2026-08-24 11:52:48 +08:00
Wesley Liddick c416467882 Merge pull request #6084 from wucm667/fix/issue-6057-responses-lite-parallel-tools
fix(openai): enforce serial tool calls for Responses Lite
2026-08-24 11:24:17 +08:00
Wesley Liddick 3b8a148bcf Merge pull request #6111 from feeeei/fix/request_billing
fix(billing): bill fast mode by the tier upstream actually served
2026-08-24 10:43:17 +08:00
shaw 40ea3aebad feat: add OAuth outbound transport plugin system 2026-08-24 09:03:37 +08:00
feeeei 75faedda95 计费:fast/priority 按上游响应实际档位只降不升计费
此前 OpenAI service_tier 与 Anthropic speed 的计费档位只看请求侧,上游
因容量把 priority/fast 静默降为 default/standard 时仍按 2x 收费。现在:

- upstreamResponseModelObserver 同时观察响应侧档位:OpenAI 只信终止事件
  与无类型 body 里的 service_tier(response.created 为请求回显,忽略),
  Anthropic 读 usage.speed;查找仅在带 model 的帧上触发
- ResolveBillingServiceTier 只降不升:响应档位比请求便宜才采纳,更贵、
  未知或缺失一律沿用请求侧,与图片尺寸归并、response_model 计费的
  "不得更贵"不变式一致
- usage_logs.service_tier 记录实际计费档位,降级写
  billing.service_tier_downgraded 审计日志;HTTP、WS 及 ws_v2 relay 全覆盖
2026-08-23 16:53:28 +08:00
wucm667 7498d8fdc8 fix(openai): enforce serial tool calls for Responses Lite 2026-08-22 19:40:19 +08:00
Jarl d493ce0bb2 fix(openai): scope codex identity to oauth account 2026-08-22 16:06:04 +08:00
Long Li e39fce270d fix(codex): sync routed capabilities from upstream
Account model mappings decide availability, but generated Codex catalogs previously inferred capabilities from local model-name tables. Compatible upstreams can expose unknown models such as OpenCode x-preview-f-free, so reasoning levels, image input, and context limits were missing or wrong.

Sync capability metadata from the account model endpoint, enrich incomplete lists from the Models.dev provider matching the account base URL, and persist only complete snapshots. Mixed groups consume the safe intersection across schedulable accounts. When IDs sync without complete metadata, return an explicit warning and preserve the previous snapshot.

Third-party Responses providers often omit /models. If that endpoint returns 404 or 405 and the account already has concrete model mappings, use those configured upstream IDs for capability enrichment. Authentication, rate-limit, server, and network failures remain hard errors, and metadata is never guessed across providers by model name alone.

Advertise a single none choice for non-reasoning models so current Codex can select them, then omit that catalog placeholder when forwarding to compatible Responses upstreams while preserving official OpenAI request semantics.
2026-08-22 15:33:12 +09:00
xuhaihan cef18b4ad3 fix(deepseek): route client tools through native responses 2026-08-22 01:04:11 +08:00
IanShaw b2b2adcf8d 修复 PR 5888 审查发现的兼容性与竞态问题 2026-08-20 21:06:48 -07:00
IanShaw 48615d5d1f Merge remote-tracking branch 'upstream/main' into fix/openai-responses-compatibility
# Conflicts:
#	backend/internal/handler/ops_error_logger.go
2026-08-20 00:31:12 -07:00
IanShaw acce29af27 补齐 OpenAI 与 Grok 协议兼容处理 2026-08-19 23:13:29 -07:00
SavitarC b3092145db fix(accounts): harden adaptive protocol compatibility 2026-08-20 13:57:25 +08:00
SavitarC 85051616f9 feat(accounts): add adaptive API protocol routing 2026-08-20 11:52:05 +08:00
IanShaw cf3577a3c5 fix(openai): harden Responses compatibility 2026-08-19 09:03:37 -07:00
Wesley Liddick 58ea46e894 Merge pull request #5661 from wucm667/fix/issue-5659-openai-custom-tools
fix(openai): restore API-key custom tool calls
2026-08-18 15:47:50 +08:00
spongehah bb6c3b4f6a fix: unify Codex OAuth outbound identity onto the inference resolver
Token exchange, PAT whoami, models, probes, and pre-writes now follow
the same UA/version chain as Codex inference instead of hardcoded
codex-cli/0.91.0 or compile-time constants.
2026-08-18 13:03:22 +08:00
Jarl 6793d5ac85 fix(openai): make Codex convergence identity consistent 2026-08-17 20:25:28 +08:00
Randark 901a0439f1 feat: 国产供应商一等支持(Kimi/Zhipu/DeepSeek 多协议 + 配额/余额监控)
后端:
- 协议凭证维度 credentials[api_protocol] ∈ chat_completions(默认)/anthropic/responses(deepseek)
- /v1/messages 零转换直通原生 Anthropic 端点(kimi/zhipu/deepseek),CC/Responses
  入站交叉组合走 apicompat 双向转换链(responses/chat_completions anthropic-native 转发器)
- count_tokens:anthropic 协议透传原生端点;其余 CN 协议本地 tiktoken 估算
- Coding Plan 额度探测(5h/weekly 滚动窗口)+ payg 余额探测(kimi/deepseek),
  deepseek 双币种 CNY+USD 明细,任一币种达标不停调
- 周期任务 [CNBalance] 并发探测 + 预算随工作量放大;响应式 429 冷却到最早窗口
  重置点;余额不足可恢复临时停调;智谱 CREDIT_LIMIT 不污染窗口解析
- CC→anthropic 流式客户端断开后继续排水上游保住 usage 计量

前端:
- 创建/编辑弹窗 account_mode + api_protocol + base_url 联动预设(含 watcher 竞态防护)
- 用量单元格:kimi/zhipu coding 显示 5h/weekly 窗口,kimi/deepseek payg 显示余额,
  多币种并列展示;探测失败保留快照;挂载自动探测 5min 去抖
- 调度阈值设置面板补 kimi/zhipu 平台(对齐后端 AllowedSchedulingThresholdPlatforms)
2026-08-15 10:37:51 +00:00
shaw fce41e318f fix(openai): make Codex fingerprint convergence opt-in and cover passthrough
Default codex_fingerprint_mode to off. v0.1.175 treated a missing key as
"session", so upgrading silently rewrote installation/session/thread/turn/
window identifiers for every existing OAuth account that had never configured
this field. The quota regressions in #5555, #5556 and #5582 line up with that
version boundary, with A/B reports that rolling back to v0.1.173 restores
quota. Convergence is now explicit opt-in (#5610).

Only accounts that never set the field change behaviour; explicit off /
device / session / full keep working exactly as configured. That required
flipping the persistence condition in all three account modals from
"!== 'session'" to "!== 'off'": the old rule deleted the key when it equalled
the default, which after the flip would have silently discarded an
administrator's explicit opt-in to session.

Also extend convergence to the passthrough path, which previously left client
identifiers untouched:

- resolve the ids once in forwardOpenAIPassthrough and rewrite
  client_metadata on the raw bytes (gjson extract + sjson splice) because
  passthrough is a hot path that must not fully unmarshal multi-MB bodies;
  a shared core keeps the raw and map variants from drifting
- both request builders apply the staged ids at the same relative position
  (after session isolation, before identity enforcement) so headers and body
  share one id set and turn_id stays consistent
- stage the ids unconditionally, including nil: a failover from a converged
  account to an off account must not leave the previous account's ids behind
2026-08-15 16:35:26 +08:00
wucm667 44ef88f659 fix(openai): restore API-key custom tools 2026-08-15 11:02:59 +08:00
InCerryGit 9662cff2e7 fix(openai): preserve remote compaction v2 responses endpoint 2026-08-14 16:23:52 +08:00
shaw c0ab3a00ea feat: Codex OAuth 设备指纹收敛,减少上游可见的设备数和会话数
多人共享同一 OAuth 账号时,各用户 Codex 客户端携带各自不同的 installation_id/session_id/thread_id,
上游据此判定设备数和会话数并限制配额。本功能将这些标识改写为账号级恒定值。

四档策略(账号级 extra 字段 codex_fingerprint_mode):
- off: 不做任何收敛,原样透传
- device: 仅收敛 installation_id
- session(默认): 收敛 installation_id + session_id,thread_id 按客户端原始 session 派生
- full: 收敛所有标识(installation_id + session_id + thread_id)

改写覆盖 6 个指纹载体:x-codex-turn-metadata 头(JSON 内部字段)、x-codex-window-id、
x-codex-installation-id、x-client-request-id、session-id/session_id/thread-id、
请求体 client_metadata。头和体共享同一份预计算 IDs 确保 turn_id 等随机字段一致。
2026-08-12 17:57:50 +08:00
IanShaw027 1f58e25ab3 Merge upstream/main into feat/grok-complete-integration
冲突集中在 chat completions / messages 两条 Responses 转发路径:
upstream 给 OpenAIForwardResult 增加了 UpstreamResponseModel 与
UpstreamResponseModelConflict(配套 beginUpstreamResponseModelObservation
观测器),本分支在同样位置把返回值改成了具名变量以便挂 Grok 原生搜索计数。
两侧不互斥,合并结果同时保留上游的响应模型观测字段与 Grok SearchCount 逻辑。

frontend/pnpm-lock.yaml 取 upstream 版本:package.json 与 upstream 完全一致,
本地差异只是 pnpm install 的重解析噪音。
2026-08-08 11:12:56 +08:00
Wesley Liddick cc67b1aca1 Merge pull request #5406 from bestony/fix/openai-oauth-routing-hints
fix(openai): forward OAuth routing hints
2026-08-08 10:58:53 +08:00
白宦成 de349187d9 fix(openai): harden priority routing hints 2026-08-07 21:47:54 +08:00
白宦成 815035fcc9 fix(openai): send OAuth routing hints 2026-08-07 21:47:53 +08:00
白宦成 915cc7e7bd fix(openai): stop injecting legacy beta on OAuth responses 2026-08-07 21:47:53 +08:00
Brisbanehuang db0bff82c7 feat(usage): audit upstream response models
(cherry picked from commit 839036224f795c8ee5dc6718a2a14372a45eea44)
2026-08-07 09:40:11 -04:00
li f3c94d2099 fix(openai): 修正 Responses 工具 Schema 中显式为 null 的 parameters.type
Codex Desktop 内置的 automation_update 工具会带 parameters.type = null,
OpenAI 直接回 400 invalid_function_parameters,而网关把该状态归一成可重试的
502 upstream_error。该工具定义还会沉进多轮会话历史,之后每一轮都继续失败,
同一份坏 Schema 在账号池里被反复重放。

在 OpenAIGatewayService.Forward 分流到 passthrough / Codex transform /
原生 ChatCompletions 之前,统一把显式为 null 的 parameters.type 补成
"object",覆盖顶层 tools[] 与多轮历史里 input[].tools[] 的嵌套工具定义。

只修正显式 null:缺失 type 的 Schema 本身合法,补写会收窄客户端语义,
因此保持原样。

Fixes #5364
2026-08-07 20:30:44 +08:00
IanShaw027 ccf7ba3ba7 fix(grok): P2 分层清理、主对话 SearchCount 与调度 7d/30d
- DoGrokNativeResponsesJSON 去 gin.Context,UA 固定 CLI 身份
- GrokOAuthService 去掉 redis 直依赖,session store 由 wire 注入
- 主对话/流式响应统计 web_search_call/x_search/tool_search 写入 SearchCount
- Grok 调度阈值候选并入官方 weekly/monthly billing %
2026-08-07 17:21:01 +08:00
zhiyu 2eb24814fe fix(codex): 强制统一出站身份并让客户端版本号跟随官方发布
上游 /backend-api/codex 在容量紧张时按客户端身份分优先级降载,被降载的请求
HTTP 200 后立刻推流内 server_is_overloaded。此前网关对配不出官方身份的客户端
整体回退到硬编码的 codex_cli_rs/0.144.1(落后官方 4 个发布),这些请求稳定
落在被优先丢弃的一侧。

- 强制统一出口:所有 OAuth 出站的 User-Agent / originator / version 一律改写
  为网关规范身份,客户端自报身份不参与构造;HTTP / 透传 / WS / alpha-search /
  探针全覆盖。compat 桥接故意删除 originator 的路径保持 no-op。
- 版本号收敛为单一来源,运行时优先级为面板覆写 → 自动同步值 → 内置常量;
  UA 与 version 头同源派生,不再各自硬编码。
- 新增 3 小时自动同步官方客户端最新稳定版,面板可关闭,无需为跟版本而发版。
- 流内 server_is_overloaded / slow_down 改为先在同账号有界重试再切号,并标记为
  请求级瞬时故障,不再据此临时封禁账号。
- 移除被取代的降载身份黑名单、浏览器 UA 兜底及其辅助函数。
2026-08-03 20:14:58 +08:00
InkCrow 272735b0a7 fix(openai): preserve Codex namespace tools on OAuth Responses forwarding
Flattening Codex `type:"namespace"` tool declarations into `namespace__name`
renames the tool but cannot rewrite the contract the client already handed the
model: Codex tells it to call `to=functions.collaboration.spawn_agent`. Under
`tool_mode: code_mode_only` (gpt-5.6-*) collaboration tools are the model's only
direct channel, so the rename left it unable to address them — it fell back to
`functions.exec` and looped on meaningless shell commands until the session
collapsed, with no upstream error anywhere. Fixes #4978.

Preserving is what the upstream actually wants. OAuth egress is unconditionally
chatgpt.com/backend-api/codex/responses (base_url is read only for API-key
accounts), i.e. the party that defines the extension; codex-rs builds one
request for both WS and HTTP and falls back WS->HTTP mid-session, so these
declarations already reach that host over HTTP — as they do today via the
responses-lite carrier and the WS/HTTP bridge, neither of which ever flattened.

Namespace names cannot be allowlisted: `features.multi_agent_v2.tool_namespace`
is user-configurable (openai/codex#31864 recommends renaming it to `agents`) and
MCP/connector namespaces are generated at runtime (mcp__codex_apps__gmail).
So the default is inverted rather than extended with more names.

- Preserve namespace declarations by default for OpenAI OAuth; the new
  per-account `extra.openai_responses_flatten_namespaces` restores the previous
  behavior for deployments routing OAuth traffic to a relay that rejects them.
- Keep `input[].namespace` on tool-call items for OAuth non-compact requests.
  The upstream requires the round-trip ("Missing namespace for function_call
  '...'. Round-trip the model's function_call item with its namespace field
  included."), so preserving declarations while stripping the calls would 400 on
  the second turn. The item-type allowlist mirrors the existing reactive strip.
- Keep compact on its current behavior: that endpoint rejects the field outright
  ("Unknown parameter: 'input[894].namespace'", #4761) and there is no evidence
  either way about namespace declarations there, so this change does not widen
  its surface. API-key accounts are untouched — their upstream is a standard
  Responses API and the reactive retry only clears one index per round trip.
- Clear the flatten mapping at the start of each Forward attempt so an account
  reached through failover cannot restore responses with the previous account's
  mapping.

Admin UI gets an OAuth-only toggle (create/edit/bulk) plus zh/en copy noting the
compact exception.
2026-07-28 09:19:13 +08:00
Wesley Liddick 333acde7d1 Merge pull request #4832 from ListenCodes/fix/openai-apikey-responses-item-id-v2
fix(openai): sanitize API-key responses item IDs
2026-07-25 13:42:35 +08:00
ListenCodes c5d9d57940 fix(openai): sanitize API-key responses item IDs 2026-07-24 20:15:58 +08:00
scp-planet 1bdf99109b fix(openai): strip input namespaces for api key accounts 2026-07-24 02:59:32 +08:00