Skip to content

refactor(proxy): remove format converters and enforce same-format routing#709

Merged
ding113 merged 4 commits intodevfrom
feat/proxy-remove-converters
Feb 2, 2026
Merged

refactor(proxy): remove format converters and enforce same-format routing#709
ding113 merged 4 commits intodevfrom
feat/proxy-remove-converters

Conversation

@ding113
Copy link
Owner

@ding113 ding113 commented Feb 2, 2026

Summary

  • Remove all format converters: Delete claude-to-openai, openai-to-claude, codex-*, gemini-cli-* converters (~8800 lines)
  • Remove Codex CLI adapter: Delete instruction injection, request sanitizer, and chat-completions-handler
  • Enforce strict same-format routing: Provider selector now requires matching API formats (no cross-format conversion)
  • Clean up UI: Remove joinClaudePool and codexInstructionsStrategy from provider forms (all 5 languages)
  • Update documentation: README now reflects strict same-format routing policy
  • Add format-compatibility tests: New test suite for provider-selector format matching

Problem

Related Issues:

The codebase contained ~8800 lines of format converter implementations (src/app/v1/_lib/converters/) that were:

  1. Never fully activated: Code existed but was placeholder/experimental
  2. Maintenance burden: Complex cross-format translation requires ongoing adaptation as APIs evolve
  3. False expectations: Users expected format conversion to work, but it was not production-ready
  4. Architectural complexity: Conversion logic in ProxyForwarder, ResponseTransformer, and session handling added unnecessary complexity

Solution

Architectural Decision: Enforce strict same-format routing policy.

Requests must be routed to providers with matching API formats:

  • Claude API requests → Claude-compatible providers only
  • OpenAI API requests → OpenAI-compatible providers only
  • Gemini CLI requests → Gemini CLI-compatible providers only

Rationale:

  • Simplifies proxy architecture by removing transformation layer
  • Reduces maintenance burden (~8800 LOC removed)
  • Eliminates edge cases from format conversion bugs
  • Makes routing logic explicit and predictable
  • Users can use upstream format converters (e.g., CCR) if needed

Changes

Core Proxy Changes

  • Deleted: src/app/v1/_lib/converters/** (all converter implementations: ~8800 lines)
    • claude-to-openai, openai-to-claude
    • codex-to-claude, codex-to-openai, claude-to-codex, openai-to-codex
    • gemini-cli-to-claude, gemini-cli-to-openai
    • registry.ts, tool-name-mapper.ts, converter types
  • Deleted: Codex CLI adapter components
    • chat-completions-handler.ts (214 lines)
    • codex-cli-adapter.ts (92 lines)
    • constants/codex-cli-instructions.ts (354 lines)
    • constants/codex-instructions.ts (193 lines)
    • utils/request-sanitizer.ts (137 lines)
  • Simplified: ProxyForwarder - removed format transformation logic (src/app/v1/_lib/proxy/forwarder.ts:~98 lines removed)
  • Simplified: ProxyResponseHandler - removed ResponseTransformer conversion (src/app/v1/_lib/proxy/response-handler.ts:~93 lines removed)
  • Simplified: format-mapper.ts - reduced from ~78 to ~5 effective lines (src/app/v1/_lib/proxy/format-mapper.ts)
  • Updated: provider-selector.ts - enforces format compatibility (src/app/v1/_lib/proxy/provider-selector.ts)
  • Cleaned: session-extractor.ts - removed Codex-specific handling

UI Changes

  • Removed from provider forms (all 5 languages):
    • joinClaudePool field (legacy pool joining feature)
    • codexInstructionsStrategy field (Codex instruction injection strategy)
  • Updated: Provider form types, context, reducer, actions
  • Cleaned: i18n messages for removed fields (en/zh-CN/zh-TW/ja/ru)

Documentation

  • Updated: README.en.md and README.md to reflect strict same-format routing
  • Removed: References to format conversion and Codex CLI injection

Tests

  • Added: tests/unit/proxy/provider-selector-format-compatibility.test.ts (289 lines) - validates format matching
  • Deleted: Obsolete converter tests
    • chat-completions-handler-guard-pipeline.test.ts (545 lines)
    • codex-request-sanitizer.test.ts (50 lines)
    • converters-tool-result-nonstream.test.ts (86 lines)
    • openai-to-codex-request.test.ts (50 lines)
  • Updated: session-extractor.test.ts - removed Codex-specific test cases

Breaking Changes

Cross-format conversion is no longer supported.

Requests must be routed to providers with matching API formats:

  • Claude API requests → Claude-compatible providers only
  • OpenAI API requests → OpenAI-compatible providers only
  • Gemini CLI requests → Gemini CLI-compatible providers only

Migration Path:

  1. Ensure your providers' providerType matches the API format you're sending
  2. If you need format conversion, use an upstream converter (e.g., CCR) before CCH
  3. Review provider routing configuration - mismatched formats will now be rejected

Removed Features:

  • joinClaudePool provider configuration option
  • codexInstructionsStrategy provider configuration option
  • All format converters (claude↔openai, codex↔*, gemini-cli↔*)

Files Changed

Summary: 82 files changed (+357/-9807 lines)

Category Files
Converters deleted 24 files (~6800 lines)
Codex adapter deleted 6 files (~990 lines)
Core proxy simplified 4 files (-290 lines)
UI/i18n cleanup 30 files (-251 lines)
Tests deleted/updated 6 files (-731 lines)
Tests added 1 file (+289 lines)
Docs updated 2 files

Checklist

  • Code follows project conventions (Biome formatting, no emoji)
  • Self-review completed
  • Tests added for format compatibility enforcement
  • All tests pass locally
  • Documentation updated (README reflects new routing policy)
  • i18n complete (all 5 languages updated for removed UI fields)
  • Breaking changes clearly documented

Description enhanced by Claude AI

ding113 and others added 4 commits February 3, 2026 02:41
…ting

BREAKING CHANGE: Cross-format conversion is no longer supported.
Requests must be routed to providers with matching API formats.

- Delete all converters (claude-to-openai, openai-to-claude, codex-*, gemini-cli-*)
- Remove Codex CLI adapter, instruction injection, and request sanitizer
- Simplify ProxyForwarder to pass-through without format transformation
- Update provider-selector to enforce format compatibility
- Remove ResponseTransformer conversion logic from response-handler
- Clean up session-extractor to remove Codex-specific handling
- Delete related test files for removed functionality

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…rovider forms

- Remove legacy pool joining and instruction strategy UI controls
- Clean up i18n messages for removed provider form fields (all 5 languages)
- Update provider actions and form context/types
- Remove unused routing section options
- Update related test mocks

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
- Remove outdated claims about format conversion and Codex CLI injection
- Clarify that proxy enforces same-format routing with no cross-format conversion
- Add format-compatibility unit tests for provider-selector

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@coderabbitai
Copy link

coderabbitai bot commented Feb 2, 2026

📝 Walkthrough

总体概述

本 PR 移除了对 Codex 功能和 Claude 调度池的支持,包括删除相关格式转换器、CLI 适配器和配置选项,同时更新了多语言文档和简化了代理转发逻辑。

变更内容

分组 / 文件 摘要
文档和国际化
README.en.md, README.md, messages/*/settings/providers/form/*, messages/providers-i18n-additions.json
移除了 Codex 策略配置和 Claude 调度池相关的本地化字符串,更新了 OpenAI 兼容端点和转发/响应处理的文档描述。
数据类型和 API 定义
src/types/provider.ts, src/lib/validation/schemas.ts, src/actions/providers.ts, src/repository/*
从 Provider、CreateProviderData、UpdateProviderData 中移除 join_claude_poolcodex_instructions_strategy 字段,删除 CodexInstructionsStrategy 类型定义。
代理转发和响应处理
src/app/v1/[...route]/route.ts, src/app/v1/_lib/proxy/forwarder.ts, src/app/v1/_lib/proxy/response-handler.ts, src/app/v1/_lib/proxy/format-mapper.ts, src/app/v1/_lib/proxy/provider-selector.ts
移除了 Codex 请求清理逻辑和跨格式转换映射,简化了提供商选择路径,移除了格式映射工具函数。
Codex 相关模块
src/app/v1/_lib/codex/*
删除了整个 Codex CLI 适配器、指令常量、会话提取器的相关字段,以及支持 Codex 的聊天完成处理器。
格式转换器
src/app/v1/_lib/converters/*
移除了所有转换器注册逻辑、转换器类型定义、工具名称映射器,以及 Codex/Claude/Gemini CLI/OpenAI 格式的各向转换器实现(包括请求和响应转换)。
UI 组件和表单
src/app/[locale]/settings/providers/_components/forms/*, src/app/[locale]/dashboard/availability/_components/*/
移除了提供商表单中的 Claude 调度池选项和 Codex 策略配置,清理了未使用的导入(RefreshCw、Trash2、XCircle、Power 等)。
测试文件
tests/unit/proxy/*, tests/unit/settings/providers/*
删除了 Codex 请求清理、聊天完成处理器守卫管道、格式转换器相关的单元测试,移除了测试数据中的 joinClaudePool 和 codexInstructionsStrategy 字段。
其他
src/app/v1/_lib/codex/session-extractor.test.ts, src/lib/session-manager.ts, scripts/audit-settings-placeholders.allowlist.json
更新了会话管理器以移除 userAgent 参数的使用,移除了占位符审计白名单条目。

预估代码审查工作量

🎯 3 (中等) | ⏱️ ~25 分钟

可能相关的 PR

  • PR #576:修改代理转发器和响应处理代码的转换/响应分支,与本 PR 的代理层变更相关。
  • PR #689:修改代理转发器和提供商偏好处理,涉及 Codex 清理逻辑和提供商级别覆写,直接相关于本 PR 简化的转发器流程。
  • PR #633:编辑 Claude-to-Codex 和 OpenAI-to-Claude 响应转换器模块,与本 PR 删除这些转换器文件的变更直接重叠。
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 46.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed PR标题清晰地总结了主要变更:删除格式转换器并实施严格的同格式路由,与changeset内容完全吻合。
Description check ✅ Passed PR描述清晰详细地说明了变更的目的、问题背景、解决方案和具体改动,与代码变更相关。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/proxy-remove-converters

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @ding113, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly refactors the proxy's architecture by removing all cross-format conversion logic and enforcing a strict same-format routing policy. The change streamlines the system by eliminating complex conversion layers and their associated configurations, ensuring that client requests are routed only to providers that natively support their API format. This simplifies maintenance, reduces potential points of failure, and clarifies the expected behavior for API consumers.

Highlights

  • Removed all format converters: Eliminated approximately 8800 lines of code by deleting all format converters, including claude-to-openai, openai-to-claude, codex-*, and gemini-cli-* implementations.
  • Removed Codex CLI adapter and related logic: The Codex CLI adapter, instruction injection, request sanitizer, and chat-completions-handler have been removed, simplifying the proxy's handling of Codex requests.
  • Enforced strict same-format routing: The provider selector now strictly requires matching API formats between the client request and the selected provider, eliminating cross-format conversion capabilities.
  • Cleaned up Provider Form UI: Removed joinClaudePool and codexInstructionsStrategy options from the provider configuration forms across all five supported languages.
  • Updated documentation and added new tests: The README files have been updated to reflect the new strict same-format routing policy, and a new test suite (provider-selector-format-compatibility.test.ts) has been added to validate format matching.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 2, 2026

🧪 测试结果

测试类型 状态
代码质量
单元测试
集成测试
API 测试

总体结果: ✅ 所有测试通过

@github-actions github-actions bot added enhancement New feature or request area:core area:provider area:i18n size/XL Extra Large PR (> 1000 lines) labels Feb 2, 2026
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This is an excellent and significant refactoring that greatly simplifies the proxy's architecture by removing the complex API format conversion layer. The changes are consistently applied across the entire codebase, from backend logic and database schemas to UI components and internationalization files. Removing thousands of lines of code is a major win for maintainability and reduces the surface area for bugs.

The core logic change to enforce strict same-format routing is implemented cleanly in the ProxyProviderResolver, and the new test suite for format compatibility provides strong confidence in this new behavior. The extensive cleanup of related code, including UI elements, configuration options, and unused variables, is also well-executed.

Overall, this is a high-quality pull request that makes a substantial improvement to the project. I have no specific change requests.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/app/v1/_lib/proxy/provider-selector.ts (1)

747-756: ⚠️ Potential issue | 🟠 Major

会话复用路径缺少格式兼容校验,可能绕过“同格式路由”。
这里新增了格式过滤,但 findReusable 未复用同一规则,旧会话绑定可能导致跨格式复用。建议在复用前补充 checkFormatProviderTypeCompatibility 检查。

建议补丁
@@
     // 检查模型支持(使用新的模型匹配逻辑)
     const requestedModel = session.getOriginalModel();
+    if (
+      session.originalFormat &&
+      !checkFormatProviderTypeCompatibility(session.originalFormat, provider.providerType)
+    ) {
+      logger.debug("ProviderSelector: Session provider format mismatch, reject reuse", {
+        sessionId: session.sessionId,
+        providerId: provider.id,
+        providerType: provider.providerType,
+        originalFormat: session.originalFormat,
+      });
+      return null;
+    }
     if (requestedModel && !providerSupportsModel(provider, requestedModel)) {
       logger.debug("ProviderSelector: Session provider does not support requested model", {
         sessionId: session.sessionId,
🤖 Fix all issues with AI agents
In `@src/app/v1/_lib/codex/__tests__/session-extractor.test.ts`:
- Around line 18-22: The test uses UUID-like strings for prompt_cache_key which
trigger gitleaks; update the test to replace those values with a clear
non-secret placeholder constant (e.g., TEST_PROMPT_CACHE_KEY) and reuse that
constant across all affected cases (lines around the other occurrences) so
extractCodexSessionId is exercised the same way without using UUID-like keys;
locate and modify the usages in the session-extractor tests that call
extractCodexSessionId and replace prompt_cache_key values with the shared
placeholder constant.
🧹 Nitpick comments (5)
src/app/[locale]/dashboard/logs/_components/error-details-dialog/components/LogicTraceTab.tsx (1)

51-58: 考虑移除未使用的 statusCode 透传
目前仅改名为 _statusCode 以规避未使用提示,但该 prop 在组件内完全未用到。若上游不再需要,建议从 LogicTraceTabProps 与调用处移除,减少无效数据传递与接口噪音。

src/app/[locale]/dashboard/availability/_components/endpoint/probe-terminal.tsx (2)

4-4: 导入了未使用的图标组件

CheckCircle2XCircleAlertCircle 已导入,并在 levelConfig 中分配给 icon 属性,但这些图标从未在 JSX 中渲染。这似乎是移除动态 Icon 渲染后遗留的未清理代码。

♻️ 建议移除未使用的导入
-import { AlertCircle, CheckCircle2, Download, XCircle } from "lucide-react";
+import { Download } from "lucide-react";

43-65: levelConfig 中的 icon 属性已成为死代码

每个级别配置中的 icon 属性不再被使用,因为日志行渲染中已移除了动态 Icon 组件的使用。建议移除这些未使用的属性以保持代码整洁。

♻️ 建议移除未使用的 icon 属性
 const levelConfig = {
   success: {
-    icon: CheckCircle2,
     label: "OK",
     color: "text-emerald-500",
     bgColor: "bg-emerald-500/5",
     borderColor: "border-l-emerald-500",
   },
   error: {
-    icon: XCircle,
     label: "FAIL",
     color: "text-rose-500",
     bgColor: "bg-rose-500/5",
     borderColor: "border-l-rose-500",
   },
   warn: {
-    icon: AlertCircle,
     label: "WARN",
     color: "text-amber-500",
     bgColor: "bg-amber-500/5",
     borderColor: "border-l-amber-500",
   },
 };
src/app/[locale]/settings/prices/_components/price-list.tsx (1)

71-74: 移除未使用的 locale hook 以减少无效依赖

_locale 未被使用,保留 useLocale() 会增加无意义的 hook 调用与依赖。建议直接移除该 hook 与导入。

建议修改(移除未使用的 useLocale)
-import { useLocale, useTimeZone, useTranslations } from "next-intl";
+import { useTimeZone, useTranslations } from "next-intl";
@@
-  const _locale = useLocale();
src/app/v1/_lib/codex/__tests__/session-extractor.test.ts (1)

1-3: 测试文件位置与源码相邻约定不一致
当前测试位于 tests 目录,建议移动到 src/app/v1/_lib/codex/session-extractor.test.ts 以满足源文件旁边放置的约定。

As per coding guidelines, 源码相邻测试应放在 src/**/*.test.ts 旁边.

Comment on lines +18 to +22
const result = extractCodexSessionId(new Headers({ "x-session-id": headerSessionId }), {
prompt_cache_key: "019b82ff-08ff-75a3-a203-7e10274fdbd8",
metadata: { session_id: "sess_aaaaaaaaaaaaaaaaaaaaa" },
previous_response_id: "resp_123456789012345678901",
});
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

替换触发 gitleaks 的 prompt_cache_key 测试值
静态扫描已将这些 UUID 样式字符串识别为 generic-api-key,可能导致 CI 阻断或误报。建议改成明显的测试占位值并复用常量。

建议修改
 import { describe, expect, test } from "vitest";
 import { extractCodexSessionId } from "../session-extractor";
 
+const PROMPT_CACHE_KEY = "pcache_test_123456789012345678901";
+
 describe("Codex session extractor", () => {
   test("extracts from header session_id", () => {
     const headerSessionId = "sess_123456789012345678901";
@@
   test("extracts from header x-session-id", () => {
     const headerSessionId = "sess_123456789012345678902";
     const result = extractCodexSessionId(new Headers({ "x-session-id": headerSessionId }), {
-      prompt_cache_key: "019b82ff-08ff-75a3-a203-7e10274fdbd8",
+      prompt_cache_key: PROMPT_CACHE_KEY,
       metadata: { session_id: "sess_aaaaaaaaaaaaaaaaaaaaa" },
       previous_response_id: "resp_123456789012345678901",
     });
@@
   test("extracts from body prompt_cache_key", () => {
-    const promptCacheKey = "019b82ff-08ff-75a3-a203-7e10274fdbd8";
+    const promptCacheKey = PROMPT_CACHE_KEY;
     const result = extractCodexSessionId(new Headers(), { prompt_cache_key: promptCacheKey });
@@
   test("prompt_cache_key has higher priority than metadata.session_id", () => {
-    const promptCacheKey = "019b82ff-08ff-75a3-a203-7e10274fdbd8";
+    const promptCacheKey = PROMPT_CACHE_KEY;
     const metadataSessionId = "sess_123456789012345678903";
     const result = extractCodexSessionId(new Headers(), {
       prompt_cache_key: promptCacheKey,
       metadata: { session_id: metadataSessionId },
     });
@@
     const result = extractCodexSessionId(
       new Headers({
         session_id: sessionIdFromHeader,
         "x-session-id": xSessionIdFromHeader,
       }),
       {
-        prompt_cache_key: "019b82ff-08ff-75a3-a203-7e10274fdbd8",
+        prompt_cache_key: PROMPT_CACHE_KEY,
         metadata: { session_id: sessionIdFromBody },
         previous_response_id: previousResponseId,
       }
     );

Also applies to: 39-41, 49-52, 98-101

🧰 Tools
🪛 Gitleaks (8.30.0)

[high] 19-19: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🤖 Prompt for AI Agents
In `@src/app/v1/_lib/codex/__tests__/session-extractor.test.ts` around lines 18 -
22, The test uses UUID-like strings for prompt_cache_key which trigger gitleaks;
update the test to replace those values with a clear non-secret placeholder
constant (e.g., TEST_PROMPT_CACHE_KEY) and reuse that constant across all
affected cases (lines around the other occurrences) so extractCodexSessionId is
exercised the same way without using UUID-like keys; locate and modify the
usages in the session-extractor tests that call extractCodexSessionId and
replace prompt_cache_key values with the shared placeholder constant.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Code Review Summary

This PR successfully removes ~9000 lines of format converter code and enforces strict same-format routing. The review found no significant issues requiring fixes before merge.

PR Size: XL

  • Lines changed: 9591 (374 additions, 9217 deletions)
  • Files changed: 85

This is an extra-large PR focused on code deletion and architectural simplification.

Issues Found

None - No critical, high, or medium priority issues identified.

All code changes are clean deletions or necessary adaptations to the converter removal. The new test coverage validates format compatibility enforcement.

Review Coverage

  • Logic and correctness - Clean
  • Security (OWASP Top 10) - Clean
  • Error handling - Clean
  • Type safety - Clean
  • Documentation accuracy - Clean
  • Test coverage - Adequate
  • Code clarity - Good

Analysis Summary

What Changed:

  1. Deleted ~8800 lines of format converters (claude↔openai, codex↔*, gemini-cli↔*)
  2. Deleted Codex CLI adapter components (~990 lines)
  3. Simplified ProxyForwarder, ProxyResponseHandler, format-mapper.ts
  4. Added format compatibility enforcement in provider-selector.ts (checkFormatProviderTypeCompatibility function at line 192)
  5. Added comprehensive test coverage for format matching (289 lines)
  6. Updated UI to remove joinClaudePool and codexInstructionsStrategy fields

Architectural Decision:
The PR enforces strict same-format routing where requests must be routed to providers with matching API formats:

  • Claude API → claude/claude-auth providers only
  • OpenAI API → openai-compatible providers only
  • Codex Response API → codex providers only
  • Gemini Direct → gemini providers only
  • Gemini CLI → gemini-cli providers only

Code Quality:

  • Clean deletions with no orphaned references
  • Proper error context in filteredProviders tracking (format_type_mismatch reason added)
  • Comprehensive test coverage validates all format combinations
  • No silent failures - incompatible providers are explicitly filtered and logged

Test Coverage:
New test file validates:

  • All format/providerType compatibility rules
  • Proper rejection of incompatible providers
  • Correct filteredProviders context tracking
  • Edge cases (no compatible providers, multiple incompatibilities)

Automated review by Claude AI

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Code Review Summary

No significant issues identified in this PR.

PR Size: XL

  • Lines changed: 9591
  • Files changed: 85
  • Split suggestions: Consider separating into (1) proxy pipeline refactor (forwarder/response-handler/format-mapper), (2) mass deletions of converters + codex adapter, (3) UI + i18n cleanup, (4) docs + tests.

Review Coverage

  • Logic and correctness - Clean
  • Security (OWASP Top 10) - Clean
  • Error handling - Clean
  • Type safety - Clean
  • Documentation accuracy - Clean
  • Test coverage - Adequate
  • Code clarity - Good

Automated review by Codex AI

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

  • Identified PR #709 (refactor(proxy): remove format converters and enforce same-format routing) from the Actions pull_request_target event payload.
  • Calculated PR size as XL (374 additions + 9217 deletions = 9591 lines changed; 85 files changed) and applied label size/XL.
  • Completed a diff-scoped review across the requested perspectives and submitted a PR review comment with no issues meeting the reporting threshold (no inline review comments posted).

@ding113 ding113 merged commit e6e334c into dev Feb 2, 2026
19 checks passed
@github-project-automation github-project-automation bot moved this from Backlog to Done in Claude Code Hub Roadmap Feb 2, 2026
@github-actions github-actions bot mentioned this pull request Feb 3, 2026
@coderabbitai coderabbitai bot mentioned this pull request Feb 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:core area:i18n area:provider enhancement New feature or request size/XL Extra Large PR (> 1000 lines)

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant