Commit Graph
77 Commits
Author SHA1 Message Date
xiaohei210509andzxh ade5944201 fix(openai): preserve Codex image function tools 2026-07-15 15:10:43 +08:00
superman2003 bc6d9c47d2 fix(openai): normalize Responses Lite tool declarations 2026-07-15 11:37:38 +08:00
Wesley LiddickandGitHub 029e5ce9f9 Merge pull request #4104 from gebdalaoli-arch/codex/fix-image-gen-hosted-tool-conflict
[codex] avoid duplicate hosted image tool injection
2026-07-14 10:13:00 +08:00
gebdalaoli-arch b6bb74b6fa fix(openai): avoid duplicate Codex image tool injection 2026-07-12 22:54:56 +08:00
wucm667andClaude Opus 4.8 4d4ba64bf7 fix(codex): 剥离续链 message item 的非法 item_* id
OpenAI OAuth 转发续链请求时,type=message 的 item 的 id 被客户端以
item_* 形式回放,但上游要求以 msg 开头,返回 400
"Expected an ID that begins with 'msg'",sub2api 随后向客户端返回 502。
客户端自动重试会不断重放同一份坏上下文,导致连续失败。

filterCodexInputWithOptions 在 PreserveReferences=true 路径下为
type=message 增加与 #3785 (fd64d07e6) 平行的 id 前缀检查:非 msg 开头
即删除。合法的 msg* id 原样保留,不改写 item_* 为 msg_*,因为改写出的
id 未必对应真实上游对象。

原 TestFilterCodexInput_NonToolCallItemKeepsID 以 message + item_msg_001
断言"保留 id",该行为已被上游拒绝,改用 web_search_call 覆盖同一意图。

Fixes #3981

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 23:32:34 +08:00
Tassoi d3a1835ed7 fix(image): strip Codex image_gen namespace declarations 2026-07-10 06:37:06 +00:00
li a02700c16f fix(image): 识别 Codex namespace image_gen 工具声明以拦截生图请求
分组 allow_image_generation=false 时,Codex /image 技能通过
namespace 工具声明(type=namespace, name=image_gen)和 Responses
Lite 的 input additional_tools 绕过了现有生图意图检测——现有逻辑
只识别 tools[].type == "image_generation" 这一种形式。

在 gjson 版(openAIJSONToolsContainImageGeneration)和 map 版
(hasOpenAIImageGenerationTool)检测中增加 namespace image_gen
识别;同时扫描 input[].type == "additional_tools" 中嵌套的工具
声明,覆盖 Responses Lite 格式。

Fixes #3608
2026-07-07 16:58:48 +08:00
li fd64d07e61 fix(codex): 剥离续链 function_call item 的非法 item_* id
OpenAI OAuth 转发续链请求时,function_call 等 call-input 类 item 的
id 被客户端以 item_* 形式回放,但上游要求以 fc 开头,返回 400
"Expected an ID that begins with 'fc'",导致工具续链反复失败。

filterCodexInputWithOptions 在 PreserveReferences=true 路径下对
call-input 类 item(function_call/tool_call/local_shell_call 等)
增加 id 前缀检查:非 fc 开头即删除。output 类(function_call_output
等)的 id 无此约束,不动。

Fixes #3785
2026-07-07 15:54:55 +08:00
shaw 6cea1c35bb feat: 适配 OpenAI 新模型 gpt-5.6-sol/terra/luna 2026-07-06 17:34:22 +08:00
Anderson f385cdceb7 feat: add Codex image tool strip policy 2026-07-03 22:36:39 +08:00
bdf7ead157 feat(spark-shadow): OpenAI Spark 链接型影子账号
背景:gpt-5.3-codex-spark 使用独立于 codex 全局(5h/7d)的配额窗口(数据源是
/wham/usage 响应体的 codex_bengalfox,而非 codex 全局用的 x-codex-* 响应头),且
只能挂在已完成 OAuth 授权的 OpenAI 账号下复用其登录态,不能作为独立账号单独接入。
为此新增“链接型影子账号”(spark shadow account):影子账号本身不持有任何凭据,
通过 parent_account_id 指向母账号,凭据/token/代理透传自母账号并共享母账号的刷新
周期,仅在配额维度(quota_dimension=spark)和用量窗口上与母账号完全独立调度、互不
连坐。

实现:
- 数据模型:migration 154(+154a)给 accounts 表加 parent_account_id /
  quota_dimension 列 + 4 条约束(维度合法 / parent⟺非 global 维度一致 / 禁自指 /
  FK)+ 2 个 CONCURRENTLY 索引(母账号索引 + 每母账号至多一个影子的唯一索引)。
- 创建:POST /api/v1/admin/accounts/:id/shadow(CreateShadow)—— 一母一影(唯一
  索引兜底并发竞态),继承母账号 proxy/分组/并发/优先级(显式传参可覆盖),默认
  model_mapping 恒等映射到 spark(拒绝非 spark 模型),母账号必须是真实的 OpenAI
  OAuth 账号(非影子)。
- 凭据透传:resolveCredentialAccount 把影子解析回母账号,GetAccessToken / 请求头
  / WS 三条路径统一走此函数;影子自身 Credentials 恒为空(仅允许写 model_mapping),
  凭据写入的汇聚点 persistAccountCredentials 对影子早返 no-op,防止误写。
- 调度:parentHealthyForShadow 只看母账号是否仍是 OpenAI OAuth + 凭据/传输是否
  可用(active、token 未过期、未处于 401/刷新失败/传输故障导致的临时不可调度冷却),
  刻意不看母账号的 global 限流窗口——两条 429 道互不连坐。
- 用量:影子的 codex_5h/7d 走 OpenAIQuotaService.QueryUsage(/wham/usage 的
  codex_bengalfox),与母账号走的 WSv2 探测(/responses 头)完全独立的数据源、
  刷新节流与 staleness 判定。
- 备份:ExportData 显式排除影子账号(影子不持凭据,通用凭据型导入强制
  credentials 非空、无法表达父子链接),按 skipped_shadows 计数提示前端。
- 前端:账号操作菜单新增“创建 Spark 影子”入口,影子行展示回填的母账号信息
  (邮箱 / plan / 隐私模式 / 订阅到期 / chatgpt_account_id),批量操作自动跳过
  影子账号。

说明:migrations 目录用完整文件名(而非纯数字前缀)标识迁移,故本次新增的
154_account_spark_shadow.sql / 154a_..._notx.sql 与已有的
154_add_ops_system_logs_api_key_id.sql 按序号共存,与目录里 145/151 已有的
先例一致。

测试:新增约 20 个测试文件,覆盖 handler(CreateShadow 校验 / 母账号信息回填)、
repository(影子 round-trip / 一母一影唯一索引 / 迁移 schema)、service(凭据
透传三路径 / 调度母健康门 / 用量窗口来源与刷新节流 / CRS 母账号不变量 / 各类
早返与 fail-closed 场景)及前端组件(账号列表 / 操作菜单 / 用量重置)。

验证(镜像 CI;golangci-lint 首次全量分析耗时过长被跳过,其余全部实测):
- gofmt -l:干净
- go build ./... / go vet ./...:通过
- go test ./... -count=1:全绿(全部包 ok,含 internal/service、
  internal/repository、migrations)
- go test -tags integration ./internal/repository/... ./internal/service/...
  (真实 Postgres,testcontainers):全绿,含迁移幂等性
  (TestMigrationsRunner_IsIdempotent_AndSchemaIsUpToDate)与影子相关全部用例
- pnpm lint:check / pnpm typecheck / pnpm build(真实 vite 构建)/
  pnpm vitest run:全绿(124 文件 760 用例)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-01 12:21:45 +08:00
Wesley LiddickandGitHub e2d21c35af Merge pull request #3587 from alfadb/fix/openai-gpt-55-pro-codex-model
fix(openai): 保留 GPT-5.5 Pro Codex 模型名
2026-07-01 10:54:51 +08:00
alfadb b28a223337 fix(openai): 保留 GPT-5.5 Pro Codex 模型名
避免 Codex OAuth 模型归一化把 gpt-5.5-pro 降级为 gpt-5.5。\n\n同时补充 GPT-5.5 Pro 的计费回退与长上下文计费策略,保证保留上游模型名后仍使用现有 GPT-5.5/GPT-5.4 计费规则。\n\n验证:\n- go test ./internal/service/...\n- go build ./cmd/server/
2026-07-01 01:30:42 +08:00
Oganneson 73de2ea7f0 fix(openai): preserve encrypted reasoning across turns on codex OAuth path
PR #2068 dropped every reasoning item from input[] on the OAuth/codex path
(store=false). That silently discards encrypted_content -- the out-of-band
channel that carries reasoning context across turns under store=false --
degrading multi-turn agent reasoning with no visible error. Reported by
@neteroster on PR #2068.

The 404 that #2068 worked around ("Item with id 'rs_...' not found") is
triggered by the rs_* id lookup under store=false, not by the reasoning item
itself -- so the correct fix is to strip the id, not delete the item.

Verified end-to-end against the live chatgpt.com codex backend (gpt-5.5) and
a real OpenClaw container (api: openai-responses):
  - bare rs_ id, no encrypted_content  -> 404
  - id stripped                        -> 200
  - encrypted_content + id stripped    -> 200, reasoning context preserved
  - reasoning items require a summary field (missing -> 400)
  - real OpenClaw multi-turn agent loop -> all /v1/responses 200, zero 404

Fix: keep the reasoning item, strip only the rs_* id (always, independent of
PreserveReferences), preserve encrypted_content/content/summary verbatim, and
backfill an empty summary when absent. Tool-call call_id pairing is untouched.

Also verified compaction_summary items (cmp_*, the other encrypted_content
carrier): they require encrypted_content (missing -> 400) and their id does not
404 when present (kept or stripped), so the existing generic path already
handles them safely -- no special-casing needed.

Adds regression tests for each verified reasoning contract.

Refs #1957, #2068
2026-06-30 21:08:40 +08:00
Wesley LiddickandGitHub 61f735a667 Merge pull request #3498 from liuaho6-commits/fix/codex-image-bridge-tool-choice
fix(openai): set tool_choice auto for Codex image bridge
2026-06-29 09:21:25 +08:00
Wesley LiddickandGitHub b105cc0fd5 Merge pull request #3337 from ddnio/codex/openai-json-mode-developer-input
fix(openai): preserve JSON instructions in Codex OAuth input
2026-06-29 09:21:05 +08:00
Hao Liu e5f7836bf3 fix(openai): set tool_choice auto for Codex image bridge 2026-06-26 19:10:37 +08:00
DaydreamCodingandClaude Opus 4.8 0112782049 fix(gateway-openai): codex spark 剥离 image_generation 工具,修复 502
gpt-5.3-codex-spark 为 text-only,不支持 image_generation 工具;codex CLI 默认
在 /responses 的 tools[] 携带该工具,导致 ChatGPT 后端返回 400
invalid_request_error(param=tools),被 mapUpstreamError 兜底成 502
"Upstream request failed"(真实 400 见 ops_error_logs.upstream_errors)。

新增 stripCodexSparkImageGenerationTools,对 spark 剥离客户端携带的
image_generation 工具(tools 清空则删键),接入三条路径:
- applyCodexOAuthTransformWithOptions:OAuth 全入口(responses/messages/chat-completions)
- buildUpstreamRequestOpenAIPassthrough 无条件 spark 块:覆盖 OAuth+APIKey
  /responses,不受 image-generation 开关影响
- WS stripCodexSparkImageGenerationToolFromRawPayload:覆盖 WebSocket /responses

bridge 注入(ensureOpenAIResponsesImageGenerationTool)本就跳过 spark;真正的缺口
在 normalizeOpenAIResponsesImageGenerationTools 会规范化并保留客户端工具。
临时绕过=换非 spark 模型;关 bridge/allow_image_generation 无效(工具是客户端带的)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 17:27:19 +08:00
欧阳丹 df51edfb06 Preserve OAuth instructions while keeping developer input 2026-06-18 03:15:31 +08:00
eyre 5e6effd79c feat: 模型感知 Codex prompt / client_metadata / anthropic SSE 补全
- 模型感知 instructions:刷新 instructions.txt 至最新 GPT-5-Codex prompt,新增
  GPT-5.1 / GPT-5.2 真实 Codex 编码 agent prompt;新增 openai.CodexBaseInstructionsForModel
  按模型选用(codex 系→GPT-5-Codex,gpt-5.2→GPT-5.2,gpt-5.1/gpt-5→GPT-5.1),
  defaultCodexSynthInstructions 改为按 model 选择
- client_metadata:OAuth /responses 请求用账号真实 openai_device_id 注入
  client_metadata["x-codex-installation-id"];加法式、幂等、不覆盖既有项,
  无 device_id(非 OAuth 账号)则不写入、不伪造
- anthropic 转换补全 SSE 事件 reasoning_text.delta 与 custom_tool_call_input.delta
  (含 custom_tool_call item 注册为 tool_use),与 chat completions 路径对齐
- 新增单元测试覆盖以上行为(apicompat / openai / service)

承接上一提交,仍为加法式改进,不改动既有可工作的请求头。
2026-06-06 00:59:27 +08:00
eyre baf078fdb7 feat: 提升 Codex 行为模拟保真度(仅加法式改进)
- ForceCodexCLI 兜底 User-Agent 补全为完整结构 {originator}/{ver} ({OS} {ver}; {arch}) {terminal},
  与真实 codex_cli_rs UA 对齐,避免被上游指纹识别为非官方客户端
- 合成路径默认 instructions 改用内嵌的真实 Codex base prompt(openai.DefaultInstructions,
  "You are Codex, based on GPT-5..."),替换通用占位符;transform 与 hotpath 两处统一走
  defaultCodexSynthInstructions()
- /responses→chat 转换补全 SSE 事件 reasoning_text.delta 与 custom_tool_call_input.delta
  (流式 ResponsesEventToChatChunks 与缓冲 BufferedResponseAccumulator 两条路径),
  并将 custom_tool_call item 一并注册以正确映射工具索引
- OAuth /responses 请求带 reasoning 时补齐 include:["reasoning.encrypted_content"],
  幂等且加法式,不改动已有 include

保持旧稳定版兼容:不改动现有可工作的请求头(session_id/conversation_id/originator/
OpenAI-Beta 维持原样)。client_metadata(installation-id) 属最新版特征,会与旧稳定版
头指纹混搭冲突,本次未加。
2026-06-06 00:44:49 +08:00
Wesley LiddickandGitHub 2ec9b0d7ba Merge pull request #2412 from gaoren002/fix/codex-auto-review-gpt55
fix(openai): add codex auto review model pricing
2026-05-19 15:14:36 +08:00
yetone 348a487739 fix(codex-transform): preserve underscore when rewriting call_* tool-call ids
`fixCallIDPrefix` builds malformed ids when the input has the standard
OpenAI `call_<nanoid>` prefix:

  input:  call_YYen1qxDejd2myJwcTCf7Nyp
  output: fcYYen1qxDejd2myJwcTCf7Nyp   ← no underscore between 'fc' and the nanoid

ChatGPT's codex backend then rejects the replayed item with:

  400 Invalid 'input[N].id': 'fcYYen1qxDejd2myJwcTCf7Nyp'.
       Expected an ID that contains letters, numbers, underscores, or
       dashes, but this value contained additional characters.

Sub2api wraps that into 502 to the client. Clients using the OpenAI SDK
on the OAuth/codex path see every multi-hop turn (after the first tool
call) fail because the item_reference rewritten this way gets sent on
every subsequent hop.

The other two branches of the same function correctly emit `fc_`
(line 1029: pass-through when already `fc*`; line 1035 fallback:
`fc_" + id`). Only the `call_` → `fc_` rewrite was missing the
underscore — looks like a copy-paste slip during the original commit.

Fix: change `"fc"` to `"fc_"` on the call_ branch. One character.

Repro:
  client (OpenAI SDK) sends a function_call_output whose call_id is
  `call_<nanoid>` (default OpenAI format). The sub2api request body
  also contains an item_reference whose id mirrors the call_id (also
  `call_<nanoid>`). On the codex OAuth path, this rewrite fires for
  the item_reference's id, producing the malformed value.

Affects: `platform=openai type=oauth` accounts whose clients use the
official OpenAI SDK / Responses API conventions (id prefix `call_`).
API-key accounts and bridge-mode requests are untouched.
2026-05-15 23:29:56 +08:00
gaoren002 32a79be962 fix(openai): add codex auto review model pricing 2026-05-12 09:26:53 +00:00
lyen1688 0584305e5a feat: improve OpenAI messages compatibility for Claude Code 2026-05-05 19:36:33 +08:00
2ue 6faa344916 feat: add OpenAI image generation controls 2026-05-05 03:26:54 +08:00
shaw df722c9a6e fix: remove OpenAI unknown model fallback 2026-05-04 11:43:00 +08:00
Wesley LiddickandGitHub 55a7fa1e07 Merge pull request #2005 from gaoren002/pr/openai-strip-passthrough-fields
fix(openai): strip unsupported passthrough fields
2026-04-29 21:46:19 +08:00
Wesley LiddickandGitHub 8d6d31545f Merge pull request #2068 from Ogannesson/fix/openai-drop-reasoning-items-from-input
fix(openai): drop reasoning items from /v1/responses input on OAuth path
2026-04-29 21:32:52 +08:00
Oganneson 7452fad820 fix(openai): drop reasoning items from /v1/responses input on OAuth path
Closes #1957

The OAuth path forwards client requests to chatgpt.com/backend-api/codex/responses,
where applyCodexOAuthTransform forces store=false (chatgpt.com's codex backend
rejects store=true). Reasoning items emitted under store=false are NEVER
persisted upstream, so any rs_* reference that a client carries forward in a
subsequent input[] array triggers a guaranteed upstream 404:

    Item with id 'rs_...' not found. Items are not persisted when `store` is
    set to false. Try again with `store` set to true, or remove this item
    from your input.

sub2api wraps this as 502 "Upstream request failed" and the conversation
breaks on every multi-turn /v1/responses request that uses reasoning + tools
(reproducible with gpt-5.5; gpt-5.4 happens to dodge it because the upstream
does not emit reasoning items for that model).

Affected clients include any that follow the OpenAI Responses API spec and
replay prior assistant items verbatim — in practice this hit OpenClaw and
similar agent harnesses on every turn ≥2 with tool use.

The fix: in filterCodexInput, drop input items with type == "reasoning"
entirely. The model never reads reasoning summary text from input (only
encrypted_content can carry reasoning context across turns, and chatgpt.com
under store=false does not emit it), so this is a no-op for the model itself
and a clean removal of unreachable upstream lookups.

Scope is intentionally narrow:
  * Only OAuth account requests (account.Type == AccountTypeOAuth) reach
    applyCodexOAuthTransform / filterCodexInput.
  * API-key accounts going to api.openai.com/v1/responses are unaffected
    (store=true works there, rs_* persists, multi-turn already works).
  * Anthropic / Gemini platform groups go through different transforms and
    are unaffected.
  * /v1/chat/completions is unaffected (no reasoning items).
  * item_reference items (different type) are unaffected — only type ==
    "reasoning" is dropped.

Verification:
  * Existing tests pass: go test ./internal/service/ -run Codex|Tool|OAuth
  * New regression test asserts reasoning items are dropped under both
    preserveReferences=true and preserveReferences=false.
  * End-to-end repro on gpt-5.5 multi-turn + tools: pre-patch 502, post-patch
    200. Repro on gpt-5.4 unchanged. Three-turn deep loop on gpt-5.5 passes.
2026-04-28 20:36:50 +08:00
ivanvolt 04b2866f65 fix: use Responses-compatible function tool_choice format 2026-04-28 16:26:09 +08:00
gaoren002 9fe02bba7e fix(openai): strip unsupported passthrough fields 2026-04-27 00:39:06 +00:00
gaoren002 27ee141c1e fix(openai): preserve mcp tool call ids 2026-04-24 13:24:21 +00:00
gaoren002 e65574dea9 fix(openai): normalize codex responses payloads 2026-04-24 12:03:19 +00:00
Wesley LiddickandGitHub 1ce9dc03f9 Merge pull request #1895 from gaoren002/fix/codex-spark-limitations
fix(openai): handle codex spark model limitations
2026-04-24 19:57:42 +08:00
song 959af1c8f6 fix(openai): preserve codex tool call ids 2026-04-24 19:31:49 +08:00
gaoren002 c4d496da18 fix(openai): handle codex spark model limitations 2026-04-24 07:42:31 +00:00
gaoren002 5f41899705 fix: bridge codex image generation over responses 2026-04-23 15:13:57 +00:00
shaw 3fe4fd4c35 chore: add model gpt-5.5 2026-04-23 17:28:01 +08:00
meteor041 00778dca31 fix openai image request handling 2026-04-23 09:53:57 +08:00
erio bbc4aed3d9 fix(openai): 移除已下线 Codex 模型并修复归一化兜底副作用
- backend: 删除 gpt-5 / 5.1 / 5.1-codex / 5.1-codex-max / 5.1-codex-mini / 5.2-codex / 5.4-nano 的内置映射与 DefaultModels 条目
- backend: normalizeCodexModel 默认兜底由 gpt-5.1 改为 gpt-5.4,gpt-5.3-codex-spark 独立保留映射
- backend: 修复 isOpenAIGPT54Model 与 shouldAutoInjectPromptCacheKeyForCompat 对 claude / gpt-4o 的误判(之前依赖 gpt-5.1 作为非 GPT 族的隐式 sentinel,改后需要显式前缀守卫)
- backend: 清理 billing_service 中已不可达的 fallback 价格与 switch 分支
- frontend: 从白名单、OpenCode 配置、预设映射中移除已下线模型
- 同步更新所有相关单测

Refs: #1758, parallels upstream #1759 but adds downstream guard fixes
2026-04-20 22:01:41 +08:00
shuanbao0andClaude Opus 4.6 422e25c99f fix(gateway): 剥离 Cursor raw body 透传路径中 Codex 不支持的 Responses API 参数
在前一个 commit 的 isResponsesShape 短路路径基础上,补充对 Cursor 云端
带过来的、Codex 上游统一不支持的顶层 Responses API 参数的剥离:

  - prompt_cache_retention
  - safety_identifier
  - metadata
  - stream_options

根因补充:这条 raw-body 透传路径为了保留 Cursor 的 input 数组整体结构,
不再经过 ChatCompletionsRequest 的反序列化过滤,所以这些 Go 结构体里
没有对应字段的参数会被原样发到上游,上游返回:
    Unsupported parameter: <field>
常规 Chat Completions 转换路径天然通过 ChatCompletionsRequest 丢弃未知字段,
不受影响;此处仅在 isResponsesShape 分支内用 sjson.DeleteBytes 显式过滤,
作用域最小。剥离列表与 openai_gateway_service.go:2034 的
unsupportedFields 语义对齐。

另外在 applyCodexOAuthTransform 的 OAuth 兜底 strip 列表里同步追加
prompt_cache_retention,作为对该函数所有其他 OAuth 调用点的 defense
in depth(当前只有 Cursor 路径的短路已在前面剥过,但保留这一层更稳)。

测试:
- TestCursorMixedShape_StripsUnsupportedFields — 验证所有 4 个字段都被剥
- TestApplyCodexOAuthTransform_StripsPromptCacheRetention — OAuth 兜底路径

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:48:45 +08:00
Alex 7eecc49c3a fix(openai): do not normalize API token based accounts 2026-04-07 11:27:57 +03:00
InCerry 995ef1348a refactor: improve model resolution and normalization logic for OpenAI integration 2026-03-24 19:20:15 +08:00
RemxandInCerry c810cad7c8 feat(openai): 增加 gpt-5.4-mini/nano 模型支持与定价配置
- 接入 gpt-5.4-mini/nano 模型识别与规范化,补充默认模型列表
- 增加 gpt-5.4-mini/nano 输入/缓存命中/输出价格与计费兜底逻辑
- 同步前端模型白名单与 OpenCode 配置
- 补充 service tier(priority/flex) 计费回归测试
2026-03-20 09:53:42 +08:00
ElysiaandClaude Sonnet 4.6 fa2e6188d0 fix(oauth): extract system-role input items into instructions field
OAuth upstreams (ChatGPT) reject requests containing role:"system" in
the input array with HTTP 400 "System messages are not allowed". Extract
such items before forwarding and merge their content into the top-level
instructions field, prepending to any existing value.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 21:20:46 +08:00
ius ca42a45802 fix: stop rewriting native responses input ids 2026-03-14 13:47:01 +08:00
yexueduxing f16910d616 chore: codex transform fixes and feature compatibility 2026-03-12 20:52:35 +08:00
CoolCoolTomato fd8ccaf01a fix: 修复gpt-5.2以上模型映射到gpt-5.2以下时verbosity参数引发的报错 2026-03-11 21:12:07 +08:00
rickylin047 9f1f203b84 fix(openai): convert string input to array for Codex OAuth responses endpoint
The ChatGPT backend-api codex/responses endpoint requires `input` to be
an array, but the OpenAI Responses API spec allows it to be a plain string.
When a client sends a string input, sub2api now converts it to the expected
message array format. Empty/whitespace-only strings become an empty array
to avoid triggering a 400 "Input must be a list" error.
2026-03-10 23:43:52 +08:00