Skip to content

fix(codex): Chat Completions adapter continuity, DeepSeek v4 thinking, streaming state sync#3125

Open
a1461750564 wants to merge 9 commits into
farion1231:mainfrom
a1461750564:codex/chat-completions-enhancement
Open

fix(codex): Chat Completions adapter continuity, DeepSeek v4 thinking, streaming state sync#3125
a1461750564 wants to merge 9 commits into
farion1231:mainfrom
a1461750564:codex/chat-completions-enhancement

Conversation

@a1461750564
Copy link
Copy Markdown

Summary

Codex Chat Completions adapter enhancements for cc-switch proxy layer.

Changes

  • Chat Completions adapter continuity — resolved state inconsistencies in streaming SSE, apiFormat sync, and fallback routing; merged split assistant messages to prevent tool-call loop breakage
  • DeepSeek v4 thinking mode — added reasoning/thinking support for DeepSeek v4 models via Codex Chat Completions path
  • Streaming state sync — fixed call_id empty-overwrite, tool name/id arrival ordering in SSE chunks
  • UI polish — tooltip corrections and i18n across en/ja/zh

Commits

  • fix(codex): streaming state sync, UI tooltip, i18n cleanups
  • fix(codex): fallback openai_chat for custom preset, stream check override, UI polish
  • fix(codex): sync apiFormat from initialData.meta on mount to prevent reset
  • feat: add DeepSeek thinking mode for Codex Chat Completions providers
  • Fix Codex Chat Completions adapter continuity

Files changed (19)

src-tauri/src/proxy/ — Rust proxy layer (adapter continuity, streaming, thinking mode)
src/components/providers/forms/ — React form components
src/i18n/locales/ — en/ja/zh translations
src/utils/ — config utilities
docs/ — adapter notes

JIAYE added 5 commits May 25, 2026 10:15
修复 Responses -> Chat Completions 转换中导致工具调用断节的多个问题:
- assistant 消息合并(content + tool_calls 不再拆成两条消息)
- stream_options 注入(修复 usage=0)
- call_id 保留(防止空值覆盖)
- developer -> system 角色映射
- finish_reason 完整映射
- AGENT_LOOP_HINT 注入
- Responses-only 工具过滤
- Add ProviderMeta.chatCompatibilityMode field ("deepseek_thinking")
- DeepSeek thinking mode preserves reasoning_content merged with tool_calls
  in the same assistant message (fixes DeepSeek "reasoning_content must be
  passed back" error)
- DeepSeek mode: strips sampling params, maps reasoning_effort, injects
  thinking: { type: "enabled" }, filters frequency/presence_penalty
- Add model override from provider TOML config in Responses -> Chat adapter path
- Add "Chat 兼容模式" UI field to Codex provider form (visible when
  app_type=codex && apiFormat=openai_chat)
- Add i18n strings for zh/en/ja
…reset

When editing a saved Codex provider, localCodexApiFormat was initialized
via useState() which only runs once on mount. If initialData.meta.apiFormat
arrives asynchronously (e.g. after liveSettings load), the state stays at
the default value instead of showing the saved format.

Add a useEffect that syncs localCodexApiFormat and
localCodexChatCompatibilityMode from initialData.meta whenever the
initialData reference updates.

Fixes: editing a Codex provider resets "API Format" to default.
…ride, UI polish

- Fix ProviderForm.tsx fallback default from openai_responses to openai_chat (3 locations)
- Add codex_api_format_override to stream check for Codex Chat Completions providers
- Invalidate provider list cache after editing (App.tsx)
- Replace Codex chat compat Select with Switch, add auto-detect via model name
- Fix duplicate usage log dedup for DeepSeek model name mismatch
- Tweak i18n text for clarity
@farion1231
Copy link
Copy Markdown
Owner

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 57ee992d5a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1360 to +1364
appId === "codex" &&
category !== "official" &&
localCodexApiFormat === "openai_chat" &&
localCodexChatCompatibilityMode !== "standard"
? { chatCompatibilityMode: localCodexChatCompatibilityMode }
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Clear chatCompatibilityMode when switching back to standard

nextMeta is built from ...(baseMeta ?? {}), but this branch only writes chatCompatibilityMode when the local mode is non-standard. If a provider previously saved chatCompatibilityMode: "deepseek_thinking", then switching the UI toggle off leaves the old value in baseMeta and resubmits it unchanged, so users cannot actually disable compatibility mode once enabled.

Useful? React with 👍 / 👎.

Comment on lines +549 to +551
.and_then(|m| m.api_format.as_deref())
})
.unwrap_or("openai_chat");
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve legacy Codex apiFormat when meta is missing

This fallback defaults to openai_chat whenever meta.apiFormat is absent, but many existing providers may only encode wire mode in TOML (wire_api = "responses") and have no meta field yet. In that case stream check will hit Chat Completions (/v1/chat/completions) instead of Responses (/v1/responses), producing false health-check failures for otherwise working Responses-only endpoints.

Useful? React with 👍 / 👎.

@a1461750564
Copy link
Copy Markdown
Author

Update pushed: 6e000117 fix(codex): add responses passthrough model override

What changed in this follow-up:

  • Added Codex responses_passthrough API format for native Responses passthrough through the local proxy.
  • Kept Codex config.toml wire_api = "responses"; responses_passthrough is only a cc-switch provider meta value.
  • In passthrough mode, cc-switch overrides stale Codex request model with the current provider-configured model before forwarding to upstream /v1/responses.
  • Kept Chat adapter behavior unchanged.
  • Renamed the Codex DeepSeek UI switch to “DeepSeek compatibility” and aligned UI/save cleanup detection for deepseek / deep-seek.

Manual verification:

  • Old Codex conversation kept sending request model deepseek-v4-flash.
  • With Responses passthrough enabled, usage log showed billing/forwarded model qwen3.7-max and request model deepseek-v4-flash; upstream returned 200.

Verification run locally:

  • git diff --check
  • pnpm typecheck
  • pnpm test:unit (241 passed)
  • cargo test --lib (1248 passed)

JIAYE added 2 commits May 26, 2026 00:08
Preserve existing PR behavior:
- openai_chat still converts Codex Responses -> Chat Completions
- DeepSeek Thinking mode still preserves/returns reasoning_content and merges with tool_calls
- responses_passthrough remains a Codex provider meta mode only
- responses_passthrough writes TOML wire_api = responses, not responses_passthrough
- responses_passthrough forwards native /v1/responses without Chat conversion
- responses_passthrough overrides stale Codex request model with provider-configured model
- stream check falls back to TOML wire_api when meta is missing
- DeepSeek compatibility switch uses unified isDeepSeekModelForCompatCheck helper
- Use dedicated passthrough model override instead of chat adapter path
- Restore chat_error_to_response_error lost during merge
- Remove duplicate should_convert_codex_responses_to_chat export
- Fix unused variable warning in stream_check.rs
- Clean up CodexFormFields props (remove unused shouldShowModelField/onModelNameChange)
- Simplify modelName prop to derive from extractCodexModelName in ProviderForm
@a1461750564
Copy link
Copy Markdown
Author

Follow-up pushed: dd0cc365 fix(codex): finalize responses passthrough follow-up

This finalizes the Responses passthrough path after syncing with main.

Key fixes:

  • responses_passthrough now uses the dedicated passthrough model override path instead of the Chat adapter override path.
  • The mode remains Codex provider meta only; config.toml still writes wire_api = "responses".
  • Native Responses passthrough does not trigger the Chat Completions adapter.
  • DeepSeek compatibility switch detection and save/cleanup behavior remain aligned.
  • Plugin unlock / launcher code remains fully removed.

Verification:

  • pnpm typecheck
  • pnpm test:unit — 252/252 passed
  • cargo test --lib -- codex — 237/237 passed
  • cargo test --lib -- passthrough — 11/11 passed
  • plugin unlock residual scan — 0 matches

@a1461750564
Copy link
Copy Markdown
Author

@codex review

The PR has been updated to dd0cc365 after resolving main conflicts and finalizing the Responses passthrough follow-up. Please review the latest head.

@chatgpt-codex-connector
Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants