Skip to content

feat: Codex 供应商级覆写 reasoning/text/parallel_tool_calls (#404)#536

Merged
ding113 merged 3 commits intodevfrom
feat/codex-provider-options-404
Jan 4, 2026
Merged

feat: Codex 供应商级覆写 reasoning/text/parallel_tool_calls (#404)#536
ding113 merged 3 commits intodevfrom
feat/codex-provider-options-404

Conversation

@ding113
Copy link
Owner

@ding113 ding113 commented Jan 4, 2026

Summary

Implements provider-level parameter overrides for Codex-type providers, allowing administrators to force-override or inherit client-specified values for reasoning effort, reasoning summary, text verbosity, and parallel tool calls.

实现 Codex 类型供应商的供应商级参数覆写功能,管理员可以强制覆写或跟随客户端指定的推理强度、推理摘要、输出冗长度和并行工具调用设置。

Problem

Codex providers (OpenAI Responses API) support various configuration parameters like reasoning.effort, reasoning.summary, text.verbosity, and parallel_tool_calls. Previously, there was no way for administrators to enforce specific values at the provider level, requiring reliance on client-specified values.

Related Issues:

Solution

Added provider-level override settings that:

  • Default to "inherit" (follow client request)
  • Allow force-overriding to specific values when configured
  • Apply overrides after Codex request sanitization during the forwarding phase
  • Only display in admin UI when provider type is "codex"

Changes

Core Changes

  • src/lib/codex/provider-overrides.ts (+90): New override logic module with applyCodexProviderOverrides() function
  • src/app/v1/_lib/proxy/forwarder.ts (+8): Integrate override application in forwarding phase
  • src/drizzle/schema.ts (+8): Add 4 new columns to providers table

Database Migration

  • drizzle/0045_plain_titania.sql (generated via bun run db:generate): Adds columns:
    • codex_reasoning_effort_preference (varchar(20))
    • codex_reasoning_summary_preference (varchar(20))
    • codex_text_verbosity_preference (varchar(10))
    • codex_parallel_tool_calls_preference (varchar(10))

Admin UI

  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx (+219):
    • 4 new dropdown selects with tooltip help
    • Conditionally rendered only for Codex provider type
    • New FieldLabelWithTooltip helper component (shared TooltipProvider scope)

Supporting Changes

  • src/types/provider.ts (+37): Type definitions for override preferences
  • src/lib/validation/schemas.ts (+25): Zod validation schemas
  • src/actions/providers.ts (+26): Server action updates for CRUD operations
  • src/repository/provider.ts (+34): Repository layer updates
  • src/repository/_shared/transformers.ts (+4): Data transformers
  • src/app/v1/_lib/codex/utils/request-sanitizer.ts (+4/-1): Preserve parallel_tool_calls in sanitization
  • src/app/v1/_lib/converters/openai-to-codex/request.ts (+3/-1): Pass through parallel_tool_calls in conversion

i18n

  • Added translations for all 5 locales (en, ja, ru, zh-CN, zh-TW)
  • Each locale includes labels, help text, and option values for all 4 override settings

Testing

Automated Tests

  • tests/unit/proxy/codex-provider-overrides.test.ts (+124): New test suite for override logic
  • tests/unit/proxy/codex-request-sanitizer.test.ts (+14): Additional tests for parallel_tool_calls preservation
  • tests/unit/proxy/openai-to-codex-request.test.ts (+10): Tests for parallel_tool_calls pass-through in conversion

Manual Testing

  1. Create or edit a Codex-type provider
  2. Verify override dropdowns only appear for Codex providers
  3. Set reasoning effort to a non-inherit value (e.g., "high")
  4. Make a request and verify the override is applied in forwarded request
  5. Test inherit mode passes through client values unchanged

Migration

Run database migration to add the new columns:

bun run db:migrate

Or apply manually:

ALTER TABLE "providers" ADD COLUMN "codex_reasoning_effort_preference" varchar(20);
ALTER TABLE "providers" ADD COLUMN "codex_reasoning_summary_preference" varchar(20);
ALTER TABLE "providers" ADD COLUMN "codex_text_verbosity_preference" varchar(10);
ALTER TABLE "providers" ADD COLUMN "codex_parallel_tool_calls_preference" varchar(10);

Checklist

  • Code follows project conventions
  • Self-review completed
  • Tests added and pass locally
  • i18n translations added for all 5 locales
  • Database migration included

Description enhanced by Claude AI

@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!

此拉取请求为 Codex 类型供应商引入了一项重要增强功能,允许管理员为关键 API 参数(如推理强度、推理摘要、文本详细程度和并行工具调用)定义全局覆写偏好。这提供了对 Codex 模型行为更细粒度的控制,确保无论客户端设置如何,通过特定供应商路由的所有请求都能获得一致的响应或特定的性能特征。这些更改涵盖了数据库架构更新、管理面板的 UI 集成以及在请求处理过程中应用这些覆写的核心逻辑。

Highlights

  • 新增 Codex 供应商级参数覆写: 为 Codex 类型供应商引入了新的可配置选项,包括 reasoning.effort、reasoning.summary、text.verbosity 和 parallel_tool_calls,允许在供应商层面覆写客户端请求的这些参数。
  • 管理界面集成: 在管理端的供应商编辑页面,当供应商类型为 Codex 时,将展示这些新的下拉框配置选项,并提供相应的工具提示说明。
  • 覆写逻辑应用: 在请求转发阶段,经过 Codex 请求清洗后,将应用这些供应商级别的覆写逻辑,确保参数按管理员配置生效。
  • 数据库迁移: 数据库 providers 表新增了四个字段,用于持久化存储这些 Codex 供应商级别的覆写偏好设置。
  • 测试覆盖: 新增了针对覆写逻辑的单元测试,并补充了 sanitizer 和 OpenAI 到 Codex 转换过程中并行工具调用透传的测试,确保功能正确性和稳定性。
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.

@coderabbitai
Copy link

coderabbitai bot commented Jan 4, 2026

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

走查

本 PR 为 Codex 类型的供应商添加了推理等级、推理总结、文本冗余度和并行工具调用的偏好设置功能。在多个层级引入了新的配置选项、数据库字段、类型定义和 UI 组件,允许按供应商覆盖 Codex API 的相关参数。

变更

集群 / 文件 变更摘要
本地化配置文件
messages/en/settings.json, messages/ja/settings.json, messages/ru/settings.json, messages/zh-CN/settings.json, messages/zh-TW/settings.json
在各语言设置中添加 codexOverrides 对象,包含四个新的配置组:reasoningEffort、reasoningSummary、textVerbosity、parallelToolCalls,各配置项包含标签、帮助文本和选项列表
类型定义与验证
src/types/provider.ts, src/lib/validation/schemas.ts
新增四个 Codex 偏好类型定义;扩展 Provider、ProviderDisplay、CreateProviderData、UpdateProviderData 接口,添加四个新的可选 Codex 偏好字段及其验证枚举
数据库架构与迁移
src/drizzle/schema.ts, drizzle/0046_woozy_dark_phoenix.sql, drizzle/meta/_journal.json, drizzle/meta/0046_snapshot.json
向 providers 表新增四个 varchar 类型的列用于存储 Codex 偏好设置;包含对应的迁移脚本和数据库快照
API 操作层
src/actions/providers.ts
扩展 getProviders、addProvider、editProvider 方法的请求/响应签名以支持四个新的 Codex 偏好字段
UI 表单组件
src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
引入 Tooltip 组件用于展示帮助文本;添加四个新的 Codex 偏好状态变量和对应的 Select 控件,仅对 Codex 类型供应商显示
业务逻辑 - 供应商覆盖
src/lib/codex/provider-overrides.ts, src/app/v1/_lib/proxy/forwarder.ts
实现 applyCodexProviderOverrides 函数以条件地应用供应商级别的 Codex 偏好覆盖;在代理转发流程中调用该函数
请求处理
src/app/v1/_lib/codex/utils/request-sanitizer.ts, src/app/v1/_lib/converters/openai-to-codex/request.ts
改进 parallel_tool_calls 的条件处理逻辑,允许客户端显式禁用并行工具调用,而不是无条件默认为 true
仓储层
src/repository/provider.ts, src/repository/_shared/transformers.ts
在供应商数据流中读取和传播四个新的 Codex 偏好字段;扩展 createProvider、updateProvider、findProviderById 等方法的返回对象
测试
tests/unit/proxy/codex-provider-overrides.test.ts, tests/unit/proxy/codex-request-sanitizer.test.ts, tests/unit/proxy/openai-to-codex-request.test.ts
新增单元测试覆盖 Codex 供应商偏好覆盖、请求消毒、显式参数传递等场景

估计代码审查工作量

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

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 47.06% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 标题清晰地概括了主要变更:为Codex供应商级别增加参数覆写功能(reasoning/text/parallel_tool_calls),与代码库改动完全相关。
Description check ✅ Passed 描述详尽地说明了功能需求、解决方案及具体实现,与代码改动完全相关,包括测试、迁移等完整信息。
Linked Issues check ✅ Passed PR完全满足Issue #404的要求。实现了为Codex供应商强制设置推理等级的功能,同时还扩展了reasoning.summary、text.verbosity和parallel_tool_calls的覆写能力。
Out of Scope Changes check ✅ Passed 所有代码改动都在Issue #404所定义的范围内,紧密围绕Codex供应商级参数覆写功能展开,没有发现范围外的改动。
✨ 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/codex-provider-options-404

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to Reviews > Disable Cache setting

📥 Commits

Reviewing files that changed from the base of the PR and between 3f33b353a38edb507034ff94bee9975db53b2d70 and 1dfe79c.

📒 Files selected for processing (22)
  • drizzle/0046_woozy_dark_phoenix.sql
  • drizzle/meta/0046_snapshot.json
  • drizzle/meta/_journal.json
  • messages/en/settings.json
  • messages/ja/settings.json
  • messages/ru/settings.json
  • messages/zh-CN/settings.json
  • messages/zh-TW/settings.json
  • src/actions/providers.ts
  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
  • src/app/v1/_lib/codex/utils/request-sanitizer.ts
  • src/app/v1/_lib/converters/openai-to-codex/request.ts
  • src/app/v1/_lib/proxy/forwarder.ts
  • src/drizzle/schema.ts
  • src/lib/codex/provider-overrides.ts
  • src/lib/validation/schemas.ts
  • src/repository/_shared/transformers.ts
  • src/repository/provider.ts
  • src/types/provider.ts
  • tests/unit/proxy/codex-provider-overrides.test.ts
  • tests/unit/proxy/codex-request-sanitizer.test.ts
  • tests/unit/proxy/openai-to-codex-request.test.ts
✅ Files skipped from review due to trivial changes (1)
  • drizzle/meta/0046_snapshot.json
🚧 Files skipped from review as they are similar to previous changes (12)
  • src/repository/_shared/transformers.ts
  • src/app/v1/_lib/codex/utils/request-sanitizer.ts
  • messages/en/settings.json
  • tests/unit/proxy/openai-to-codex-request.test.ts
  • drizzle/meta/_journal.json
  • messages/zh-CN/settings.json
  • tests/unit/proxy/codex-request-sanitizer.test.ts
  • messages/ru/settings.json
  • src/app/v1/_lib/proxy/forwarder.ts
  • messages/ja/settings.json
  • src/lib/validation/schemas.ts
  • src/app/v1/_lib/converters/openai-to-codex/request.ts
🧰 Additional context used
📓 Path-based instructions (15)
**/*.{ts,tsx,js,jsx,json}

📄 CodeRabbit inference engine (CLAUDE.md)

Use 2-space indentation in all code files

Files:

  • messages/zh-TW/settings.json
  • src/lib/codex/provider-overrides.ts
  • src/types/provider.ts
  • src/actions/providers.ts
  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
  • src/drizzle/schema.ts
  • tests/unit/proxy/codex-provider-overrides.test.ts
  • src/repository/provider.ts
messages/**/*.json

📄 CodeRabbit inference engine (CLAUDE.md)

Support 5 locales via next-intl: en, ja, ru, zh-CN, zh-TW with messages in messages/{locale}/*.json

Store message translations in messages/{locale}/*.json files

Files:

  • messages/zh-TW/settings.json
**/*.{tsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Use next-intl for internationalization with 5 locales: en, ja, ru, zh-CN, zh-TW

Files:

  • messages/zh-TW/settings.json
  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Use double quotes for strings instead of single quotes
Use trailing commas in multi-line structures
Enforce maximum line length of 100 characters
Use path alias @/* to reference files from ./src/* directory

**/*.{ts,tsx,js,jsx}: Use Biome for linting and formatting with 2-space indent, double quotes, trailing commas, and 100 character max line length
Use path alias @/* to reference files in ./src/* directory

Files:

  • src/lib/codex/provider-overrides.ts
  • src/types/provider.ts
  • src/actions/providers.ts
  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
  • src/drizzle/schema.ts
  • tests/unit/proxy/codex-provider-overrides.test.ts
  • src/repository/provider.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use TypeScript strict mode for type safety
Use readonly or const assertions for immutable data structures

Files:

  • src/lib/codex/provider-overrides.ts
  • src/types/provider.ts
  • src/actions/providers.ts
  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
  • src/drizzle/schema.ts
  • tests/unit/proxy/codex-provider-overrides.test.ts
  • src/repository/provider.ts
src/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.ts: Hash API keys using SHA-256 before storing in database, never store plaintext keys
Mask API keys and sensitive data in application logs
Validate required environment variables at startup with clear error messages

Files:

  • src/lib/codex/provider-overrides.ts
  • src/types/provider.ts
  • src/actions/providers.ts
  • src/drizzle/schema.ts
  • src/repository/provider.ts
src/**/*provider*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Set provider circuit breaker failure threshold, open duration, and half-open success threshold in configuration

Files:

  • src/lib/codex/provider-overrides.ts
  • src/types/provider.ts
  • src/actions/providers.ts
  • src/repository/provider.ts
src/lib/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use connection pooling for database and Redis connections

Files:

  • src/lib/codex/provider-overrides.ts
src/actions/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

src/actions/**/*.ts: Validate all user inputs with Zod schemas before processing
Use Server Actions in next-safe-action with OpenAPI generation for admin API endpoints
Use Next.js API Routes and Server Actions for admin operations and REST endpoints

Files:

  • src/actions/providers.ts
src/{repository,actions}/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Avoid N+1 queries by using eager loading and batch queries for statistics

Files:

  • src/actions/providers.ts
  • src/repository/provider.ts
src/**/*.{tsx,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{tsx,jsx}: Use lucide-react for icons, no custom SVGs
Use React's automatic escaping to prevent XSS vulnerabilities

Files:

  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
src/drizzle/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use Drizzle ORM with PostgreSQL for database operations

src/drizzle/**/*.ts: Use Drizzle ORM with parameterized queries to prevent SQL injection
Use soft delete pattern with deletedAt column instead of hard deletes
Use JSON columns in PostgreSQL for flexible data structures (modelRedirects, providerChain, etc.)
Implement proper indexing strategy for common queries and foreign keys

Files:

  • src/drizzle/schema.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use Vitest for unit testing with Node environment, coverage thresholds: 50% lines/functions, 40% branches

Files:

  • tests/unit/proxy/codex-provider-overrides.test.ts
**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

Ensure test database names contain 'test' keyword for safety validation

Files:

  • tests/unit/proxy/codex-provider-overrides.test.ts
src/repository/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use Repository pattern in src/repository/ to wrap Drizzle queries

Files:

  • src/repository/provider.ts
🧠 Learnings (6)
📚 Learning: 2026-01-03T09:08:20.573Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-03T09:08:20.573Z
Learning: Applies to messages/**/*.json : Support 5 locales via next-intl: en, ja, ru, zh-CN, zh-TW with messages in `messages/{locale}/*.json`

Applied to files:

  • messages/zh-TW/settings.json
📚 Learning: 2026-01-03T09:08:20.573Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-03T09:08:20.573Z
Learning: Applies to src/components/**/*.{ts,tsx} : Use `lucide-react` for icons instead of custom SVGs

Applied to files:

  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
📚 Learning: 2026-01-03T09:08:49.019Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-03T09:08:49.019Z
Learning: Applies to src/**/*.{tsx,jsx} : Use `lucide-react` for icons, no custom SVGs

Applied to files:

  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
📚 Learning: 2026-01-03T09:08:49.019Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-03T09:08:49.019Z
Learning: Applies to src/components/**/*.{tsx,jsx} : Use shadcn/ui component library for high-quality, accessible UI components

Applied to files:

  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
📚 Learning: 2026-01-03T09:08:49.019Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-03T09:08:49.019Z
Learning: Applies to src/**/*provider*.ts : Set provider circuit breaker failure threshold, open duration, and half-open success threshold in configuration

Applied to files:

  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
📚 Learning: 2026-01-03T09:08:49.019Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-03T09:08:49.019Z
Learning: Applies to src/drizzle/**/*.ts : Use JSON columns in PostgreSQL for flexible data structures (modelRedirects, providerChain, etc.)

Applied to files:

  • src/drizzle/schema.ts
🧬 Code graph analysis (5)
src/lib/codex/provider-overrides.ts (1)
src/types/provider.ts (4)
  • CodexReasoningEffortPreference (17-24)
  • CodexReasoningSummaryPreference (26-26)
  • CodexTextVerbosityPreference (28-28)
  • CodexParallelToolCallsPreference (31-31)
src/actions/providers.ts (1)
src/types/provider.ts (4)
  • CodexReasoningEffortPreference (17-24)
  • CodexReasoningSummaryPreference (26-26)
  • CodexTextVerbosityPreference (28-28)
  • CodexParallelToolCallsPreference (31-31)
src/app/[locale]/settings/providers/_components/forms/provider-form.tsx (5)
src/components/ui/label.tsx (1)
  • Label (21-21)
src/components/ui/tooltip.tsx (4)
  • Tooltip (57-57)
  • TooltipTrigger (57-57)
  • TooltipContent (57-57)
  • TooltipProvider (57-57)
scripts/sync-settings-keys.js (2)
  • p (102-102)
  • t (72-72)
src/types/provider.ts (4)
  • CodexReasoningEffortPreference (17-24)
  • CodexReasoningSummaryPreference (26-26)
  • CodexTextVerbosityPreference (28-28)
  • CodexParallelToolCallsPreference (31-31)
src/components/ui/select.tsx (5)
  • Select (162-162)
  • SelectTrigger (170-170)
  • SelectValue (171-171)
  • SelectContent (163-163)
  • SelectItem (165-165)
tests/unit/proxy/codex-provider-overrides.test.ts (1)
src/lib/codex/provider-overrides.ts (1)
  • applyCodexProviderOverrides (43-90)
src/repository/provider.ts (1)
src/drizzle/schema.ts (1)
  • providers (129-271)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Docker Build Test
  • GitHub Check: 🌐 API Tests
  • GitHub Check: dev-build-deploy
🔇 Additional comments (25)
drizzle/0046_woozy_dark_phoenix.sql (1)

1-4: LGTM!字段长度设计合理

迁移语句正确添加了 4 个 Codex 偏好字段,列类型和长度选择合理:

  • reasoning_effort_preferencereasoning_summary_preference 使用 20 字符,足以容纳 "xhigh"、"detailed" 等值
  • text_verbosity_preferenceparallel_tool_calls_preference 使用 10 字符,能够容纳 "inherit"、"medium"、"false" 等值
  • 所有字段均为可空,与代码中 "inherit" 语义(默认跟随客户端)一致
src/lib/codex/provider-overrides.ts (8)

16-18: 实现正确

isPlainObject 类型守卫实现准确,正确排除了 null 和数组,并提供了类型收窄能力。


20-23: 逻辑清晰

normalizeStringPreference 正确实现了 "inherit" 语义转换:将 null/undefined/"inherit" 统一规范化为 null,表示不覆写。


25-30: 类型转换正确

normalizeParallelToolCallsPreference 正确处理了字符串到布尔值的转换,并遵循 "inherit" 语义。


47-49: 早期返回优化

对于非 Codex 类型供应商的早期返回处理正确,避免了不必要的计算。


51-56: 惰性克隆机制高效

惰性克隆实现合理:仅在需要修改时才执行浅拷贝,避免不必要的对象创建。由于后续对嵌套对象(reasoningtext)的修改都使用了对象展开,浅拷贝在此场景下足够。


58-64: parallel_tool_calls 覆写逻辑正确

正确处理了 parallel_tool_calls 覆写:仅在规范化结果非 null 时应用,并在修改前确保克隆。


66-79: reasoning 字段覆写保持不可变性

正确实现了 reasoning 字段的覆写:

  • 通过对象展开保留了原有字段(如 extra
  • 仅覆写指定的 effortsummary
  • 自动补齐缺失的父对象结构
  • 保持了不可变性原则

81-87: text 字段覆写逻辑一致

text.verbosity 覆写采用了与 reasoning 一致的模式,正确保留现有字段并维护不可变性。

src/types/provider.ts (5)

14-31: 类型定义完整,注意字符串布尔值的权衡

Codex 偏好类型定义准确涵盖了所有可能的值:

  • CodexReasoningEffortPreference 包含 7 个推理强度等级
  • 所有类型都包含 "inherit" 选项,语义清晰

关于 CodexParallelToolCallsPreference 使用字符串 "true"/"false" 而非布尔值:

  • 优点:与 UI Select 组件兼容,简化表单处理
  • 权衡:需要在运行时转换为布尔值(已在 normalizeParallelToolCallsPreference 中实现)

当前实现合理,但后续如果表单库升级支持布尔值,可考虑重构为更类型安全的方案。


123-127: Provider 接口字段添加正确

新增的 4 个 Codex 偏好字段符合接口设计规范:

  • 使用 camelCase 命名符合 TypeScript 约定
  • 可空类型(| null)与数据库架构一致
  • 字段注释明确说明仅对 Codex 类型供应商有效

197-200: ProviderDisplay 接口保持一致

ProviderDisplay 接口中新增字段与 Provider 接口保持一致,确保前后端数据结构的统一。


269-272: CreateProviderData 接口符合数据库约定

新增字段使用 snake_case 命名,与数据库列名保持一致:

  • 可选字段(?)支持部分数据创建
  • 可空类型允许显式设置为 null
  • 命名准确对应迁移文件中的列名

339-342: UpdateProviderData 接口与创建接口保持一致

更新接口采用与 CreateProviderData 相同的模式,支持部分更新操作。

tests/unit/proxy/codex-provider-overrides.test.ts (6)

5-22: 测试用例覆盖非 Codex 供应商场景

测试正确验证了当 providerType 不是 "codex" 时的早期返回行为:

  • 使用 toBe 验证引用相等性(未创建新对象)
  • 使用 toEqual 验证内容未变更

24-46: 测试正确验证 null/inherit 语义

测试用例正确验证了所有偏好为 null 时的无操作行为:

  • 使用 structuredClone 创建深拷贝快照进行比较
  • 验证输入对象未被修改,确保不可变性

48-70: 测试覆盖字符串 "inherit" 场景

测试用例验证了字符串 "inherit"null 等价的规范化行为,覆盖了配置边界情况。


72-87: 测试验证字符串到布尔值转换

测试用例正确验证了 parallel_tool_calls 覆写和类型转换:

  • 字符串 "false" 被转换为布尔值 false
  • 原始输入对象未被修改

89-105: 测试验证字段保留逻辑

测试用例全面验证了 reasoning 覆写时的字段保留行为:

  • 覆写 effortsummary 字段
  • 保留原有的 extra 字段
  • 确保原始对象不可变性

这是关键的测试用例,确保覆写不会意外删除其他字段。


107-123: 测试覆盖缺失结构自动创建

测试用例验证了当请求缺少 reasoningtext 对象时的结构自动补齐行为,这是重要的边界情况。

messages/zh-TW/settings.json (1)

1157-1199: 多语言 codexOverrides 配置结构完整且一致

新增的 codexOverrides 配置块结构完整,包含了 4 个 Codex 偏好设置的繁体中文翻译:

  • 每个偏好项都有清晰的标签、帮助文本和选项说明
  • 翻译术语准确(如 "推理等級"、"並行工具呼叫")
  • 帮助文本详细说明了各选项的行为和限制

已验证所有 5 种支持的语言(en、ja、ru、zh-CN、zh-TW)的 codexOverrides 结构:

  • 所有语言在相同路径 .providers.form.sections.routing.codexOverrides 下存在该配置
  • 所有 4 个子项(parallelToolCalls、reasoningEffort、reasoningSummary、textVerbosity)在所有语言中一致
  • 每个子项都包含必需字段(label、help、options)
  • 各子项的选项数量保持一致:parallelToolCalls 3 个选项、reasoningEffort 7 个选项、reasoningSummary 3 个选项、textVerbosity 4 个选项

多语言结构验证完毕,无不一致或缺失问题。

src/drizzle/schema.ts (1)

246-252: Codex 覆写字段定义合理,兼容性良好

4 个 Codex 偏好字段命名、长度以及可空设计都和上层 Codex*Preference 类型及注释语义一致("inherit"/null 表示跟随客户端,其它值强制覆写),和现有 providers 表结构也保持风格统一,看不出兼容性或正确性问题。

src/repository/provider.ts (1)

56-59: Codex 偏好字段在 CRUD 流程中的映射完整且一致

  • createProvider 正确从 CreateProviderData 映射 4 个 Codex 偏好字段,并在插入返回投影中一并返回。
  • findProviderList / findAllProviders / findProviderByIdselect 均包含这 4 个字段,保证读路径数据完整。
  • updateProvider 仅在对应字段 !== undefined 时更新,并使用 ?? null 支持显式清空,符合「不传保持原值、传 null/显式值更新」的预期。

整体实现同现有字段风格一致,没有看到类型或持久化层面的遗漏。

Also applies to: 106-109, 167-170, 239-242, 305-308, 405-414, 464-467

src/actions/providers.ts (1)

45-52: Codex 偏好在 Action 层的类型与默认值设计合理

  • 顶部引入的 Codex*Preference 类型在 addProvider/editProvider 参数声明中一致使用,避免魔法字符串。
  • getProviders 将 4 个 Codex 字段直接透传给 ProviderDisplay,便于前端表单回显。
  • 新增时在 payload 中统一将 cache_ttl_preferencecontext_1m_preference 以及 4 个 Codex 偏好默认为 "inherit",与「不配置时跟随客户端」语义一致,也和表单初始状态匹配。
  • 编辑时仅在字段存在时才下发到 updateProvider,保留了 patch 语义,支持从其它值改回 "inherit"

整体逻辑闭环清晰,没有发现类型或默认行为上的明显问题。

Also applies to: 190-244, 372-375, 459-465, 539-542

src/app/[locale]/settings/providers/_components/forms/provider-form.tsx (1)

2-2: Codex 覆写表单与后端数据流对齐良好

  • FieldLabelWithTooltip 复用 Label + Tooltip 并配合顶层单一 TooltipProvider,结构清晰且避免多 Provider 实例。
  • 4 个 Codex 偏好通过独立 useState 管理,初始值从 sourceProvider"inherit" 推导,与 Action 层默认策略一致。
  • 编辑/新增两条分支中都把 codex_*_preference 写入 payload(编辑为 patch 语义、新建默认 "inherit"),与仓储层映射相符。
  • UI 仅在 providerType === "codex" 时展示 Codex 覆写区域,交互符合“仅 Codex 供应商生效”的预期。

整体表单状态与后端模型一一对应,看起来没有明显缺陷。

Also applies to: 34-35, 68-96, 179-195, 404-407, 447-450, 512-515, 600-600, 1069-1213


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

@github-actions github-actions bot added enhancement New feature or request area:provider area:i18n area:UI size/L Large PR (< 1000 lines) labels Jan 4, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Jan 4, 2026

🧪 测试结果

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

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

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

本次 PR 实现了 Codex 类型供应商的供应商级参数覆写功能,新增了 reasoning.effort, reasoning.summary, text.verbosityparallel_tool_calls 四个可选项。整体实现非常完整,涵盖了数据库迁移、后端逻辑、前端 UI 和多语言支持。

主要变更点包括:

  • 数据库:在 providers 表中新增了对应的偏好设定字段。
  • 后端:在请求转发阶段加入了覆写逻辑,并确保了在请求清洗后执行,逻辑清晰。
  • 前端:在供应商编辑页面为 Codex 类型供应商增加了相应的配置项,并提供了 Tooltip 说明,用户体验良好。
  • 测试:新增了覆盖覆写逻辑的单元测试,并补充了对 parallel_tool_calls 透传的测试,保证了代码质量。

代码整体质量很高,逻辑清晰,考虑周全。我只发现一处可以改进的地方,即在前端表单组件中存在一些重复代码,已在具体评论中提出了重构建议,以提高代码的可维护性。

做得很好!

Comment on lines +1061 to +1202
<div className="space-y-2">
<FieldLabelWithTooltip
label={t("sections.routing.codexOverrides.reasoningSummary.label")}
tooltip={t("sections.routing.codexOverrides.reasoningSummary.help")}
/>
<Select
value={codexReasoningSummaryPreference}
onValueChange={(val) =>
setCodexReasoningSummaryPreference(
val as CodexReasoningSummaryPreference
)
}
disabled={isPending}
>
<SelectTrigger className="w-full">
<SelectValue placeholder="inherit" />
</SelectTrigger>
<SelectContent>
<SelectItem value="inherit">
{t(
"sections.routing.codexOverrides.reasoningSummary.options.inherit"
)}
</SelectItem>
<SelectItem value="auto">
{t("sections.routing.codexOverrides.reasoningSummary.options.auto")}
</SelectItem>
<SelectItem value="detailed">
{t(
"sections.routing.codexOverrides.reasoningSummary.options.detailed"
)}
</SelectItem>
</SelectContent>
</Select>
</div>

<div className="space-y-2">
<FieldLabelWithTooltip
label={t("sections.routing.codexOverrides.textVerbosity.label")}
tooltip={t("sections.routing.codexOverrides.textVerbosity.help")}
/>
<Select
value={codexTextVerbosityPreference}
onValueChange={(val) =>
setCodexTextVerbosityPreference(val as CodexTextVerbosityPreference)
}
disabled={isPending}
>
<SelectTrigger className="w-full">
<SelectValue placeholder="inherit" />
</SelectTrigger>
<SelectContent>
<SelectItem value="inherit">
{t("sections.routing.codexOverrides.textVerbosity.options.inherit")}
</SelectItem>
<SelectItem value="low">
{t("sections.routing.codexOverrides.textVerbosity.options.low")}
</SelectItem>
<SelectItem value="medium">
{t("sections.routing.codexOverrides.textVerbosity.options.medium")}
</SelectItem>
<SelectItem value="high">
{t("sections.routing.codexOverrides.textVerbosity.options.high")}
</SelectItem>
</SelectContent>
</Select>
</div>

<div className="space-y-2">
<FieldLabelWithTooltip
label={t("sections.routing.codexOverrides.parallelToolCalls.label")}
tooltip={t("sections.routing.codexOverrides.parallelToolCalls.help")}
/>
<Select
value={codexParallelToolCallsPreference}
onValueChange={(val) =>
setCodexParallelToolCallsPreference(
val as CodexParallelToolCallsPreference
)
}
disabled={isPending}
>
<SelectTrigger className="w-full">
<SelectValue placeholder="inherit" />
</SelectTrigger>
<SelectContent>
<SelectItem value="inherit">
{t(
"sections.routing.codexOverrides.parallelToolCalls.options.inherit"
)}
</SelectItem>
<SelectItem value="true">
{t("sections.routing.codexOverrides.parallelToolCalls.options.true")}
</SelectItem>
<SelectItem value="false">
{t("sections.routing.codexOverrides.parallelToolCalls.options.false")}
</SelectItem>
</SelectContent>
</Select>
</div>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

你好,感谢你的贡献!

我注意到在 provider-form.tsx 文件中,用于 Codex 参数覆写的四个下拉选择框(Select 组件)存在较多重复代码。从 1061 行到 1202 行,每个选择框的结构(div, FieldLabelWithTooltip, Select)都非常相似。

为了提高代码的可读性和可维护性,我建议将这部分逻辑提取为一个可复用的组件,例如 CodexOverrideSelect。这个新组件可以接收 label, tooltip, value, onValueChange, optionsdisabled 等属性。

下面是一个简单的实现示例:

// 定义一个可复用的选择框组件
function CodexOverrideSelect({
  label,
  tooltip,
  value,
  onValueChange,
  options,
  disabled,
}: {
  label: string;
  tooltip: string;
  value: string;
  onValueChange: (value: string) => void;
  options: { value: string; label: string }[];
  disabled: boolean;
}) {
  return (
    <div className="space-y-2">
      <FieldLabelWithTooltip label={label} tooltip={tooltip} />
      <Select value={value} onValueChange={onValueChange} disabled={disabled}>
        <SelectTrigger className="w-full">
          <SelectValue placeholder="inherit" />
        </SelectTrigger>
        <SelectContent>
          {options.map((option) => (
            <SelectItem key={option.value} value={option.value}>
              {option.label}
            </SelectItem>
          ))}
        </SelectContent>
      </Select>
    </div>
  );
}

// 在你的表单中使用它
const reasoningEffortOptions = [
  { value: "inherit", label: t("sections.routing.codexOverrides.reasoningEffort.options.inherit") },
  { value: "minimal", label: t("sections.routing.codexOverrides.reasoningEffort.options.minimal") },
  // ... 其他选项
];

<CodexOverrideSelect
  label={t("sections.routing.codexOverrides.reasoningEffort.label")}
  tooltip={t("sections.routing.codexOverrides.reasoningEffort.help")}
  value={codexReasoningEffortPreference}
  onValueChange={(val) => setCodexReasoningEffortPreference(val as CodexReasoningEffortPreference)}
  options={reasoningEffortOptions}
  disabled={isPending}
/>

这样做可以显著减少重复代码,并使表单的结构更加清晰。

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: 2

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/converters/openai-to-codex/request.ts (1)

17-18: 同步更新注释以匹配 parallel_tool_calls 新语义

  • 代码现在逻辑是:parallel_tool_calls 默认 true,但如果请求体里显式提供布尔值,则尊重客户端设置,这非常合理,也与 Codex 覆写机制兼容。
  • 顶部注释仍写着「强制设置:... parallel_tool_calls=true」,与实际行为不符,容易误导后续维护。

建议把行 17 的说明改成类似:

- * - 强制设置:stream=true, store=false, parallel_tool_calls=true
+ * - 强制设置:stream=true, store=false;parallel_tool_calls 默认 true,可被客户端显式关闭

以保持实现与文档一致。

Also applies to: 129-132

🧹 Nitpick comments (6)
messages/ja/settings.json (1)

1157-1199: 日语翻译结构完整,建议验证术语一致性

新增的 codexOverrides 配置项结构完整,包含了 4 个覆写选项组。以下是几点建议:

  1. 术语一致性:请确保以下术语在所有日语翻译文件中保持一致:

    • "オーバーライド" (override)
    • "クライアントに従う" (inherit/follow client)
    • "強制" (force)
  2. 选项值格式:注意 line 1168 使用了 none(GPT-5.1 のみ),而 line 1167 使用了 xhigh(GPT-5.1-Codex-Max のみ)。建议确认这种括号内的模型限制说明在所有相关选项中格式一致。

  3. 建议添加验证:由于这是面向用户的配置界面,建议与日语母语者确认以下术语的准确性:

    • "推論強度" (reasoning effort)
    • "推論サマリー" (reasoning summary)
    • "出力の詳細度" (text verbosity)
    • "並列ツール呼び出し" (parallel tool calls)

基于 learnings,请确保该翻译与其他 4 个 locale (en, ja, ru, zh-CN, zh-TW) 中的对应配置保持结构一致性。

tests/unit/proxy/codex-request-sanitizer.test.ts (1)

25-37: 测试覆盖不完整,建议补充正向用例

当前测试仅验证了 parallel_tool_calls=false 的场景,建议补充以下测试用例以确保完整覆盖:

  1. 显式设置为 true 的场景:验证当客户端显式设置 parallel_tool_calls=true 时,该值也被保留而不是被重新赋值。

  2. 未定义场景的回归测试:验证当 parallel_tool_calls 未设置时,默认值仍为 true(确保向后兼容)。

🔎 建议的补充测试用例
+  it("当客户端显式设置 parallel_tool_calls=true 时应保留", async () => {
+    const input: Record<string, unknown> = {
+      instructions: "abc",
+      parallel_tool_calls: true,
+    };
+
+    const output = await sanitizeCodexRequest(input, "gpt-5-codex", "auto", 1, {
+      isOfficialClient: false,
+    });
+
+    expect(output.parallel_tool_calls).toBe(true);
+  });
+
+  it("当客户端未设置 parallel_tool_calls 时应默认为 true", async () => {
+    const input: Record<string, unknown> = {
+      instructions: "abc",
+    };
+
+    const output = await sanitizeCodexRequest(input, "gpt-5-codex", "auto", 1, {
+      isOfficialClient: false,
+    });
+
+    expect(output.parallel_tool_calls).toBe(true);
+  });
tests/unit/proxy/openai-to-codex-request.test.ts (1)

41-49: 测试覆盖与前一文件存在相同问题

此测试用例仅验证了 parallel_tool_calls=false 的透传场景,建议补充以下用例:

  1. 显式 true 场景:验证 parallel_tool_calls=true 也被正确透传
  2. 默认值场景:验证未设置时默认为 true
  3. 非布尔值场景:验证传入其他类型(如字符串、数字)时的容错处理

根据相关代码片段,转换器逻辑为:

output.parallel_tool_calls = (typeof req.parallel_tool_calls === "boolean") 
  ? req.parallel_tool_calls 
  : true

建议添加测试用例验证这个完整的条件分支逻辑。

🔎 建议的补充测试用例
+  it("当输入显式设置 parallel_tool_calls=true 时,应透传到 Codex 请求", () => {
+    const input: Record<string, unknown> = {
+      messages: [{ role: "user", content: "你好" }],
+      parallel_tool_calls: true,
+    };
+
+    const output = transformOpenAIRequestToCodex("gpt-5-codex", input, true) as any;
+    expect(output.parallel_tool_calls).toBe(true);
+  });
+
+  it("当输入未设置 parallel_tool_calls 时,应默认为 true", () => {
+    const input: Record<string, unknown> = {
+      messages: [{ role: "user", content: "你好" }],
+    };
+
+    const output = transformOpenAIRequestToCodex("gpt-5-codex", input, true) as any;
+    expect(output.parallel_tool_calls).toBe(true);
+  });
drizzle/0045_add_codex_provider_overrides.sql (1)

1-4: 数据库迁移结构合理,建议添加约束验证

新增的 4 个字段设计合理,采用 nullable 列来表示"继承客户端设置"的语义。以下是几点建议:

  1. 考虑添加 CHECK 约束:虽然应用层会进行验证,但数据库层的约束可以提供额外的数据完整性保障:

    ALTER TABLE "providers" ADD CONSTRAINT "codex_reasoning_effort_check" 
      CHECK (codex_reasoning_effort_preference IN ('minimal', 'low', 'medium', 'high', 'xhigh', 'none') OR codex_reasoning_effort_preference IS NULL);
  2. VARCHAR 长度验证

    • varchar(20) 足够存储所有选项值(最长的是 "detailed")
    • varchar(10) 足够存储 "true"/"false"/"high" 等值
    • ✓ 长度设置合理
  3. 缺少回滚脚本:建议在同一目录下创建对应的 down 迁移脚本,以便在需要时回滚:

    ALTER TABLE "providers" DROP COLUMN "codex_parallel_tool_calls_preference";
    ALTER TABLE "providers" DROP COLUMN "codex_text_verbosity_preference";
    ALTER TABLE "providers" DROP COLUMN "codex_reasoning_summary_preference";
    ALTER TABLE "providers" DROP COLUMN "codex_reasoning_effort_preference";

根据 coding guidelines,请确认此迁移脚本已在包含 'test' 关键字的测试数据库中验证通过。

src/drizzle/schema.ts (1)

244-250: Codex 覆写字段定义合理,可考虑后续加强约束

  • 四个字段均为可空 varchar,与注释中「null / 'inherit' 表示跟随客户端」的语义一致;UI 配置的可选值长度也都在 length 限制内,设计没问题。
  • 为保持灵活性用 varchar 是可以接受的,但从数据一致性角度,未来可以考虑:
    • 用 PostgreSQL enumcheck 约束约束取值(如 'inherit' | 'minimal' | ...),避免非法字符串混入。
    • 在 TypeScript 层对应这些字段定义成窄化 union 类型,减少魔法字符串。

这些都属于后续增强项,不影响当前 PR 的正确性。

tests/unit/proxy/codex-provider-overrides.test.ts (1)

1-124: 可选:改进测试中的类型安全性

测试代码中多处使用 as any 来绕过类型检查(第 19、42、66、84、102、120 行)。虽然这在测试代码中是可接受的做法,但可以考虑定义一个测试辅助类型来提高类型安全性。

🔎 可选的重构方案

在测试文件顶部定义测试辅助类型:

+import type { CodexProviderOverrideConfig } from "@/lib/codex/provider-overrides";
+
+type TestProviderConfig = Partial<CodexProviderOverrideConfig> & {
+  providerType: string;
+};
+
 describe("Codex 供应商级参数覆写", () => {
   it("当 providerType 不是 codex 时,应直接返回原对象且不做任何处理", () => {
-    const provider = {
+    const provider: TestProviderConfig = {
       providerType: "claude",
       codexReasoningEffortPreference: "high",
       codexParallelToolCallsPreference: "false",
     };
 
     // ...
-    const output = applyCodexProviderOverrides(provider as any, input);
+    const output = applyCodexProviderOverrides(provider as CodexProviderOverrideConfig, input);

这样可以保留类型提示,同时避免完全绕过类型检查。

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to Reviews > Disable Cache setting

📥 Commits

Reviewing files that changed from the base of the PR and between d302935 and ef2c82c83c92b72a5565e8b132ea31d0f42cc82d.

📒 Files selected for processing (20)
  • drizzle/0045_add_codex_provider_overrides.sql
  • messages/en/settings.json
  • messages/ja/settings.json
  • messages/ru/settings.json
  • messages/zh-CN/settings.json
  • messages/zh-TW/settings.json
  • src/actions/providers.ts
  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
  • src/app/v1/_lib/codex/utils/request-sanitizer.ts
  • src/app/v1/_lib/converters/openai-to-codex/request.ts
  • src/app/v1/_lib/proxy/forwarder.ts
  • src/drizzle/schema.ts
  • src/lib/codex/provider-overrides.ts
  • src/lib/validation/schemas.ts
  • src/repository/_shared/transformers.ts
  • src/repository/provider.ts
  • src/types/provider.ts
  • tests/unit/proxy/codex-provider-overrides.test.ts
  • tests/unit/proxy/codex-request-sanitizer.test.ts
  • tests/unit/proxy/openai-to-codex-request.test.ts
🧰 Additional context used
📓 Path-based instructions (20)
**/*.{ts,tsx,js,jsx,json}

📄 CodeRabbit inference engine (CLAUDE.md)

Use 2-space indentation in all code files

Files:

  • src/app/v1/_lib/codex/utils/request-sanitizer.ts
  • src/app/v1/_lib/converters/openai-to-codex/request.ts
  • src/app/v1/_lib/proxy/forwarder.ts
  • tests/unit/proxy/openai-to-codex-request.test.ts
  • messages/zh-CN/settings.json
  • src/lib/codex/provider-overrides.ts
  • messages/zh-TW/settings.json
  • tests/unit/proxy/codex-provider-overrides.test.ts
  • src/repository/provider.ts
  • messages/en/settings.json
  • src/lib/validation/schemas.ts
  • src/actions/providers.ts
  • src/types/provider.ts
  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
  • messages/ru/settings.json
  • tests/unit/proxy/codex-request-sanitizer.test.ts
  • src/repository/_shared/transformers.ts
  • src/drizzle/schema.ts
  • messages/ja/settings.json
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Use double quotes for strings instead of single quotes
Use trailing commas in multi-line structures
Enforce maximum line length of 100 characters
Use path alias @/* to reference files from ./src/* directory

**/*.{ts,tsx,js,jsx}: Use Biome for linting and formatting with 2-space indent, double quotes, trailing commas, and 100 character max line length
Use path alias @/* to reference files in ./src/* directory

Files:

  • src/app/v1/_lib/codex/utils/request-sanitizer.ts
  • src/app/v1/_lib/converters/openai-to-codex/request.ts
  • src/app/v1/_lib/proxy/forwarder.ts
  • tests/unit/proxy/openai-to-codex-request.test.ts
  • src/lib/codex/provider-overrides.ts
  • tests/unit/proxy/codex-provider-overrides.test.ts
  • src/repository/provider.ts
  • src/lib/validation/schemas.ts
  • src/actions/providers.ts
  • src/types/provider.ts
  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
  • tests/unit/proxy/codex-request-sanitizer.test.ts
  • src/repository/_shared/transformers.ts
  • src/drizzle/schema.ts
src/app/v1/_lib/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Guard pipeline must execute in order: ProxyAuthenticator, SensitiveWordGuard, VersionGuard, ProxySessionGuard, ProxyRateLimitGuard, ProxyProviderResolver

Files:

  • src/app/v1/_lib/codex/utils/request-sanitizer.ts
  • src/app/v1/_lib/converters/openai-to-codex/request.ts
  • src/app/v1/_lib/proxy/forwarder.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use TypeScript strict mode for type safety
Use readonly or const assertions for immutable data structures

Files:

  • src/app/v1/_lib/codex/utils/request-sanitizer.ts
  • src/app/v1/_lib/converters/openai-to-codex/request.ts
  • src/app/v1/_lib/proxy/forwarder.ts
  • tests/unit/proxy/openai-to-codex-request.test.ts
  • src/lib/codex/provider-overrides.ts
  • tests/unit/proxy/codex-provider-overrides.test.ts
  • src/repository/provider.ts
  • src/lib/validation/schemas.ts
  • src/actions/providers.ts
  • src/types/provider.ts
  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
  • tests/unit/proxy/codex-request-sanitizer.test.ts
  • src/repository/_shared/transformers.ts
  • src/drizzle/schema.ts
src/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.ts: Hash API keys using SHA-256 before storing in database, never store plaintext keys
Mask API keys and sensitive data in application logs
Validate required environment variables at startup with clear error messages

Files:

  • src/app/v1/_lib/codex/utils/request-sanitizer.ts
  • src/app/v1/_lib/converters/openai-to-codex/request.ts
  • src/app/v1/_lib/proxy/forwarder.ts
  • src/lib/codex/provider-overrides.ts
  • src/repository/provider.ts
  • src/lib/validation/schemas.ts
  • src/actions/providers.ts
  • src/types/provider.ts
  • src/repository/_shared/transformers.ts
  • src/drizzle/schema.ts
src/app/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Implement Content-Security-Policy headers for XSS prevention

Files:

  • src/app/v1/_lib/codex/utils/request-sanitizer.ts
  • src/app/v1/_lib/converters/openai-to-codex/request.ts
  • src/app/v1/_lib/proxy/forwarder.ts
src/app/v1/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use Hono router for ultrafast, lightweight routing in proxy endpoints

Files:

  • src/app/v1/_lib/codex/utils/request-sanitizer.ts
  • src/app/v1/_lib/converters/openai-to-codex/request.ts
  • src/app/v1/_lib/proxy/forwarder.ts
src/app/v1/_lib/converters/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use Registry pattern in format converters to map conversion pairs between Claude, OpenAI, Codex, and Gemini APIs

Files:

  • src/app/v1/_lib/converters/openai-to-codex/request.ts
src/app/v1/_lib/proxy/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

src/app/v1/_lib/proxy/**/*.ts: Implement guard pipeline pattern for cross-cutting concerns in request processing (auth, rate limiting, session)
Use undici library for HTTP requests instead of node-fetch for better performance

Files:

  • src/app/v1/_lib/proxy/forwarder.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use Vitest for unit testing with Node environment, coverage thresholds: 50% lines/functions, 40% branches

Files:

  • tests/unit/proxy/openai-to-codex-request.test.ts
  • tests/unit/proxy/codex-provider-overrides.test.ts
  • tests/unit/proxy/codex-request-sanitizer.test.ts
**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

Ensure test database names contain 'test' keyword for safety validation

Files:

  • tests/unit/proxy/openai-to-codex-request.test.ts
  • tests/unit/proxy/codex-provider-overrides.test.ts
  • tests/unit/proxy/codex-request-sanitizer.test.ts
messages/**/*.json

📄 CodeRabbit inference engine (CLAUDE.md)

Support 5 locales via next-intl: en, ja, ru, zh-CN, zh-TW with messages in messages/{locale}/*.json

Store message translations in messages/{locale}/*.json files

Files:

  • messages/zh-CN/settings.json
  • messages/zh-TW/settings.json
  • messages/en/settings.json
  • messages/ru/settings.json
  • messages/ja/settings.json
**/*.{tsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Use next-intl for internationalization with 5 locales: en, ja, ru, zh-CN, zh-TW

Files:

  • messages/zh-CN/settings.json
  • messages/zh-TW/settings.json
  • messages/en/settings.json
  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
  • messages/ru/settings.json
  • messages/ja/settings.json
src/**/*provider*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Set provider circuit breaker failure threshold, open duration, and half-open success threshold in configuration

Files:

  • src/lib/codex/provider-overrides.ts
  • src/repository/provider.ts
  • src/actions/providers.ts
  • src/types/provider.ts
src/lib/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use connection pooling for database and Redis connections

Files:

  • src/lib/codex/provider-overrides.ts
  • src/lib/validation/schemas.ts
src/repository/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use Repository pattern in src/repository/ to wrap Drizzle queries

Files:

  • src/repository/provider.ts
  • src/repository/_shared/transformers.ts
src/{repository,actions}/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Avoid N+1 queries by using eager loading and batch queries for statistics

Files:

  • src/repository/provider.ts
  • src/actions/providers.ts
  • src/repository/_shared/transformers.ts
src/actions/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

src/actions/**/*.ts: Validate all user inputs with Zod schemas before processing
Use Server Actions in next-safe-action with OpenAPI generation for admin API endpoints
Use Next.js API Routes and Server Actions for admin operations and REST endpoints

Files:

  • src/actions/providers.ts
src/**/*.{tsx,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{tsx,jsx}: Use lucide-react for icons, no custom SVGs
Use React's automatic escaping to prevent XSS vulnerabilities

Files:

  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
src/drizzle/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use Drizzle ORM with PostgreSQL for database operations

src/drizzle/**/*.ts: Use Drizzle ORM with parameterized queries to prevent SQL injection
Use soft delete pattern with deletedAt column instead of hard deletes
Use JSON columns in PostgreSQL for flexible data structures (modelRedirects, providerChain, etc.)
Implement proper indexing strategy for common queries and foreign keys

Files:

  • src/drizzle/schema.ts
🧠 Learnings (13)
📚 Learning: 2026-01-03T09:08:20.573Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-03T09:08:20.573Z
Learning: Applies to src/app/v1/_lib/proxy-handler.ts : Structure request flow in proxy handler through: ProxySession.fromContext() -> detectFormat() -> GuardPipelineBuilder.run() -> ProxyForwarder.send() -> ProxyResponseHandler.dispatch()

Applied to files:

  • src/app/v1/_lib/proxy/forwarder.ts
📚 Learning: 2026-01-03T09:08:49.019Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-03T09:08:49.019Z
Learning: Applies to src/app/v1/_lib/proxy/**/*.ts : Implement guard pipeline pattern for cross-cutting concerns in request processing (auth, rate limiting, session)

Applied to files:

  • src/app/v1/_lib/proxy/forwarder.ts
📚 Learning: 2026-01-03T09:08:49.019Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-03T09:08:49.019Z
Learning: Applies to src/app/v1/_lib/proxy/**/*.ts : Use undici library for HTTP requests instead of node-fetch for better performance

Applied to files:

  • src/app/v1/_lib/proxy/forwarder.ts
📚 Learning: 2026-01-03T09:08:49.019Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-03T09:08:49.019Z
Learning: Applies to src/app/v1/_lib/proxy/*handler*.ts : Stream responses with proper backpressure handling and chunked transfer encoding

Applied to files:

  • src/app/v1/_lib/proxy/forwarder.ts
📚 Learning: 2026-01-03T09:08:20.573Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-03T09:08:20.573Z
Learning: Applies to src/app/v1/_lib/**/*.ts : Guard pipeline must execute in order: ProxyAuthenticator, SensitiveWordGuard, VersionGuard, ProxySessionGuard, ProxyRateLimitGuard, ProxyProviderResolver

Applied to files:

  • src/app/v1/_lib/proxy/forwarder.ts
📚 Learning: 2026-01-03T09:08:49.019Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-03T09:08:49.019Z
Learning: Applies to src/app/v1/**/*.ts : Use Hono router for ultrafast, lightweight routing in proxy endpoints

Applied to files:

  • src/app/v1/_lib/proxy/forwarder.ts
📚 Learning: 2026-01-03T09:08:49.019Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-03T09:08:49.019Z
Learning: Applies to src/**/*provider*.ts : Set provider circuit breaker failure threshold, open duration, and half-open success threshold in configuration

Applied to files:

  • src/app/v1/_lib/proxy/forwarder.ts
  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
📚 Learning: 2026-01-03T09:08:20.573Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-03T09:08:20.573Z
Learning: Applies to src/lib/circuit-breaker.ts : Circuit Breaker must implement state machine: CLOSED -> OPEN -> HALF_OPEN -> CLOSED with per-provider isolation and Redis persistence

Applied to files:

  • src/app/v1/_lib/proxy/forwarder.ts
📚 Learning: 2026-01-03T09:08:49.019Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-03T09:08:49.019Z
Learning: Applies to src/lib/circuit-breaker/**/*.ts : Implement circuit breaker state machine with CLOSED -> OPEN -> HALF_OPEN -> CLOSED transitions

Applied to files:

  • src/app/v1/_lib/proxy/forwarder.ts
📚 Learning: 2026-01-03T09:08:20.573Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-03T09:08:20.573Z
Learning: Applies to src/components/**/*.{ts,tsx} : Use `lucide-react` for icons instead of custom SVGs

Applied to files:

  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
📚 Learning: 2026-01-03T09:08:49.019Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-03T09:08:49.019Z
Learning: Applies to src/**/*.{tsx,jsx} : Use `lucide-react` for icons, no custom SVGs

Applied to files:

  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
📚 Learning: 2026-01-03T09:08:49.019Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-03T09:08:49.019Z
Learning: Applies to src/components/**/*.{tsx,jsx} : Use shadcn/ui component library for high-quality, accessible UI components

Applied to files:

  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
📚 Learning: 2026-01-03T09:08:20.573Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-03T09:08:20.573Z
Learning: Applies to messages/**/*.json : Support 5 locales via next-intl: en, ja, ru, zh-CN, zh-TW with messages in `messages/{locale}/*.json`

Applied to files:

  • messages/ja/settings.json
🧬 Code graph analysis (8)
src/app/v1/_lib/proxy/forwarder.ts (1)
src/lib/codex/provider-overrides.ts (1)
  • applyCodexProviderOverrides (43-90)
tests/unit/proxy/openai-to-codex-request.test.ts (1)
src/app/v1/_lib/converters/openai-to-codex/request.ts (1)
  • transformOpenAIRequestToCodex (117-314)
src/lib/codex/provider-overrides.ts (1)
src/types/provider.ts (4)
  • CodexReasoningEffortPreference (17-24)
  • CodexReasoningSummaryPreference (26-26)
  • CodexTextVerbosityPreference (28-28)
  • CodexParallelToolCallsPreference (31-31)
tests/unit/proxy/codex-provider-overrides.test.ts (1)
src/lib/codex/provider-overrides.ts (1)
  • applyCodexProviderOverrides (43-90)
src/repository/provider.ts (1)
src/drizzle/schema.ts (1)
  • providers (129-269)
src/actions/providers.ts (1)
src/types/provider.ts (4)
  • CodexReasoningEffortPreference (17-24)
  • CodexReasoningSummaryPreference (26-26)
  • CodexTextVerbosityPreference (28-28)
  • CodexParallelToolCallsPreference (31-31)
src/app/[locale]/settings/providers/_components/forms/provider-form.tsx (5)
src/components/ui/label.tsx (1)
  • Label (21-21)
src/components/ui/tooltip.tsx (4)
  • TooltipProvider (57-57)
  • Tooltip (57-57)
  • TooltipTrigger (57-57)
  • TooltipContent (57-57)
scripts/sync-settings-keys.js (2)
  • p (102-102)
  • t (72-72)
src/types/provider.ts (4)
  • CodexReasoningEffortPreference (17-24)
  • CodexReasoningSummaryPreference (26-26)
  • CodexTextVerbosityPreference (28-28)
  • CodexParallelToolCallsPreference (31-31)
src/components/ui/select.tsx (5)
  • Select (162-162)
  • SelectTrigger (170-170)
  • SelectValue (171-171)
  • SelectContent (163-163)
  • SelectItem (165-165)
tests/unit/proxy/codex-request-sanitizer.test.ts (1)
src/app/v1/_lib/codex/utils/request-sanitizer.ts (1)
  • sanitizeCodexRequest (59-137)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Greptile Review
  • GitHub Check: pr-description
  • GitHub Check: pr-review
  • GitHub Check: Docker Build Test
  • GitHub Check: 🌐 API Tests
  • GitHub Check: check-codex-status
  • GitHub Check: dev-build-deploy
🔇 Additional comments (31)
tests/unit/proxy/codex-request-sanitizer.test.ts (1)

36-36: 良好的不可变性验证

在 line 36 验证输入对象未被修改是一个很好的实践,确保了函数的纯度。虽然实现中使用了扩展运算符 {...request} 来避免突变,但显式测试这一点可以防止未来的回归问题。

src/app/v1/_lib/codex/utils/request-sanitizer.ts (1)

123-126: 实现正确,逻辑清晰

新的条件默认逻辑正确实现了以下行为:

  • undefinedtrue (向后兼容)
  • truetrue (保留显式设置)
  • falsefalse (保留显式关闭)

实现方式使用 typeof 检查是适当的,可以正确区分 undefined 和显式的布尔值。这为供应商级别覆写和客户端控制提供了基础。

src/app/v1/_lib/proxy/forwarder.ts (1)

12-12: Codex 供应商级覆写挂载位置与顺序合理

  • 放在 Codex 分支、且紧跟清洗逻辑之后统一调用 applyCodexProviderOverrides,保证:
    • 对非官方客户端:顺序为「格式转换 → Codex 清洗 → 供应商级覆写」,管理员设置优先级最高。
    • 对官方 Codex CLI 客户端:即使跳过清洗也仍可在供应商层强制覆写关键参数,符合注释说明。
  • 覆写函数内部再按 providerType 做一次防护,且使用返回值整体替换 session.request.message,不会影响非 Codex provider 的路径。

当前实现从行为和解耦上都没看到明显问题,可以保持。

Also applies to: 944-1000

messages/en/settings.json (1)

1262-1304: Codex 覆写文案与后端行为、选项集合一致

  • 四组 override(reasoningEffort / reasoningSummary / textVerbosity / parallelToolCalls)的标签、帮助说明和枚举值与后端 schema 中的字段、预期行为对齐,默认都强调 “inherit = follow client”,语义清晰。
  • 对于仅在特定模型支持的取值(如 nonexhigh),帮助文案明确标注了限制,有利于降低误配风险。

这部分配置作为英文基准文案看起来是准确且完备的。

messages/zh-CN/settings.json (1)

766-808: Codex 覆写中文文案与英文版含义基本一致

  • 四个 override 小节的 label / help / options 与英文版一一对应:
    • reasoningEffort 说明了“跟随客户端”与强制覆写的区别,并明确 none / xhigh 的模型限制。
    • reasoningSummarytextVerbosityparallelToolCalls 也都准确传达了含义和影响。
  • 术语如「推理等级」「输出冗长度」「并行工具调用」在当前上下文中易于理解,与后端字段含义对应良好。

整体翻译质量和键名保持一致,不会引入行为歧义。

src/lib/validation/schemas.ts (2)

14-25: LGTM:Codex 偏好枚举定义正确

新增的四个 Codex 偏好枚举定义合理:

  • 统一使用 "inherit" 作为不覆写的标识值
  • parallel_tool_calls 使用字符串 "true"/"false" 而非布尔值,便于在 API 和表单中传递
  • 选项值与类型定义(src/types/provider.ts)保持一致

符合 Zod 4 语法规范。


423-429: LGTM:Schema 集成正确

Codex 偏好字段已正确集成到 Provider schemas:

  • CreateProviderSchema:默认值为 "inherit",表示新建的 Provider 默认不覆写客户端参数
  • UpdateProviderSchema:设为 optional(),支持部分更新
  • 字段命名遵循现有约定(schema 层使用 snake_case)

实现符合最佳实践。

Also applies to: 594-597

src/repository/_shared/transformers.ts (1)

102-105: LGTM:Transformer 实现正确

新增的 Codex 偏好字段转换逻辑正确:

  • 使用空值合并运算符 ??undefined 统一转换为 null
  • 字段命名遵循 camelCase 约定
  • 与其他可选偏好字段(如 cacheTtlPreferencecontext1mPreference)的处理方式保持一致

实现符合代码库的转换模式。

src/lib/codex/provider-overrides.ts (3)

16-30: LGTM:辅助函数实现合理

三个辅助函数设计良好:

  • isPlainObject:正确区分普通对象与数组和 null
  • normalizeStringPreference:将空值和 "inherit" 标识符统一处理为 null(表示不覆写)
  • normalizeParallelToolCallsPreference:将字符串形式的布尔值转换为实际布尔值

逻辑清晰,边界情况处理得当。


51-56: 优秀:采用写时复制优化模式

ensureCloned 闭包实现了高效的写时复制模式:

  • 初始时 output 仅是对 input 的引用
  • 仅在首次需要修改时才进行浅拷贝
  • 避免了不必要的对象克隆开销(当所有偏好都是 inherit 时)

这种模式在可选转换场景中既保证了不可变性,又提供了良好的性能。


58-87: LGTM:覆写逻辑实现正确

三个覆写逻辑段落实现得当:

  1. parallel_tool_calls(58-64 行):直接设置布尔值
  2. reasoning(66-79 行):
    • 正确保留现有 reasoning 对象中的其他字段
    • 仅覆写 effortsummary
    • 当 reasoning 不存在时自动创建
  3. text(81-87 行):
    • 保留现有 text 对象的其他字段
    • 仅覆写 verbosity

所有逻辑都在 !== null 检查后执行,确保只在有明确覆写值时才修改请求。

messages/zh-TW/settings.json (1)

1157-1199: LGTM:i18n 配置完整且准确

新增的 Codex 覆写配置国际化内容质量高:

  • 选项值与 schema 枚举定义完全匹配
  • 帮助文本详细说明了各选项的作用和限制(如 xhigh 仅 GPT-5.1-Codex-Max 支持)
  • 统一使用"不覆寫(跟隨客戶端)"表示 inherit 选项
  • 繁体中文翻译准确、专业

与其他语言包(en、ja、ru、zh-CN)的结构保持一致。

messages/ru/settings.json (1)

1157-1199: LGTM!

Codex 参数覆写的俄语翻译结构完整,遵循了现有的国际化模式。四个配置项(reasoning effort、reasoning summary、text verbosity、parallel tool calls)都提供了标签、帮助文本和选项翻译。

src/repository/provider.ts (5)

54-57: LGTM!

Codex 偏好字段的初始化逻辑正确,使用了 ?? null 默认值模式,与现有的 context1mPreference 字段保持一致。


102-105: LGTM!

returning 子句正确包含了四个新的 Codex 偏好字段,确保创建操作后能返回完整的提供者数据。


161-164: LGTM!

所有查询方法(findProviderListfindAllProvidersfindProviderById)都正确添加了四个 Codex 偏好字段的选择,保持了数据获取的完整性。

Also applies to: 231-234, 295-298


392-401: LGTM!

updateProvider 中的条件更新逻辑正确:

  • 使用 !== undefined 检查确保只更新显式提供的字段
  • ?? null 模式正确处理 null 值
  • 与其他偏好字段的更新模式保持一致

这种模式支持部分更新,不会影响未包含在更新载荷中的字段。


449-452: LGTM!

updateProviderreturning 子句正确包含了新字段,确保更新操作返回完整的提供者数据。

src/app/[locale]/settings/providers/_components/forms/provider-form.tsx (4)

2-2: LGTM!

导入语句正确:

  • 使用 lucide-react 提供 Info 图标(符合编码指南)
  • @/components/ui/tooltip 导入 Tooltip 组件(shadcn/ui)
  • 新增的 Codex 偏好类型导入完整且必要

Also applies to: 34-34, 38-46


173-189: LGTM!

Codex 偏好状态初始化正确:

  • 默认值使用 "inherit",表示遵循客户端请求(符合设计意图)
  • sourceProvider 读取现有值,支持编辑和克隆场景
  • 类型注解完整,与导入的类型定义匹配
  • 模式与其他偏好字段(如 context1mPreference)保持一致

397-400: LGTM!

负载构造正确:

  • 编辑负载接口正确定义为可选且可为 null(支持部分更新)
  • 创建和编辑负载都正确赋值四个 Codex 偏好字段
  • 使用 snake_case 字段名(codex_reasoning_effort_preference 等),与仓储层期望的格式匹配
  • 类型与状态变量的类型定义一致

Also applies to: 439-442, 503-506


1059-1203: LGTM!

Codex 参数覆写 UI 区块实现正确:

结构:

  • 仅在 providerType === "codex" 时渲染(正确的条件显示)
  • 包含 4 个配置项,每个都使用 Select 组件
  • 布局使用 space-y-4 保持适当间距

功能:

  • 值绑定正确(value={codexReasoningEffortPreference} 等)
  • 状态更新处理器正确转换类型并调用 setState
  • 表单提交期间正确禁用(disabled={isPending}

数据完整性:

  • 所有选项值与类型定义匹配:
    • reasoningEffort: 7 个选项 ✓
    • reasoningSummary: 3 个选项 ✓
    • textVerbosity: 4 个选项 ✓
    • parallelToolCalls: 3 个选项 ✓
  • 翻译键遵循统一的命名模式

唯一问题: FieldLabelWithTooltipTooltipProvider 性能问题已在上面单独标记。

src/actions/providers.ts (4)

44-51: LGTM!

新增的 Codex 偏好类型导入符合预期,类型定义清晰。


227-230: LGTM!

getProviders() 正确返回了 4 个新增的 Codex 偏好字段,命名规范一致。


369-372: LGTM!

addProvider() 函数签名正确添加了 4 个可选的 Codex 偏好参数,命名和类型定义符合规范。


534-537: 验证确认:UpdateProviderSchema 已包含新增 Codex 偏好字段的验证。

editProvider() 新增的 4 个可选 Codex 偏好参数已在 UpdateProviderSchema(src/lib/validation/schemas.ts, 第 594-597 行)中正确验证:

  • codex_reasoning_effort_preference: CODEX_REASONING_EFFORT_PREFERENCE.optional()
  • codex_reasoning_summary_preference: CODEX_REASONING_SUMMARY_PREFERENCE.optional()
  • codex_text_verbosity_preference: CODEX_TEXT_VERBOSITY_PREFERENCE.optional()
  • codex_parallel_tool_calls_preference: CODEX_PARALLEL_TOOL_CALLS_PREFERENCE.optional()

所有字段使用 Zod 枚举常量定义,.optional() 修饰符确保了 PATCH 风格更新的语义正确性。验证逻辑完整,符合编码规范。

src/types/provider.ts (5)

119-124: LGTM!

Provider 接口正确添加了 4 个 Codex 偏好字段,注释清晰说明了这些字段仅对 Codex 类型供应商有效。


192-195: LGTM!

ProviderDisplay 接口正确添加了 4 个 Codex 偏好字段,与 Provider 接口保持一致。


263-266: LGTM!

CreateProviderData 接口正确添加了 4 个可选的 Codex 偏好字段,使用 snake_case 命名符合数据库字段规范。


332-335: LGTM!

UpdateProviderData 接口正确添加了 4 个可选的 Codex 偏好字段,使用 snake_case 命名符合数据库字段规范。


14-31: 类型定义正确且布尔值转换逻辑完整。

已验证 src/lib/codex/provider-overrides.ts 中的 normalizeParallelToolCallsPreference() 函数(第 25-30 行)正确将字符串 "true"/"false" 转换为布尔值 true/false,符合 Codex API 要求。"inherit" 和 null 值正确处理为不覆写(返回 null)。转换逻辑在第 58-64 行应用,并通过完整的测试用例验证。所有代码遵循指导原则:2 空格缩进、双引号、不超过 100 字符行长、TypeScript 严格模式启用。

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: L

  • Lines changed: 830
  • Files changed: 20
  • Split suggestions: Consider splitting into (1) DB migration + schema/types/validation, (2) Settings UI + i18n strings, (3) Proxy pipeline changes + unit 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 #536 (feat: Codex 供应商级覆写 reasoning/text/parallel_tool_calls (#404)), size L (830 lines changed across 20 files) and applied label size/L.
  • Completed a diff-only review across the requested perspectives and posted the summary via gh pr review --comment on https://github.com/ding113/claude-code-hub/pull/536.
  • No inline comments were posted because I did not find any diff-scope issues that cleared the reporting threshold.

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 implements a well-designed feature adding provider-level parameter overrides for Codex-type providers. The implementation is complete and consistent across all layers (database, repository, actions, UI, i18n).

PR Size: L

  • Lines changed: 830 (825 additions + 5 deletions)
  • Files changed: 20

Issues Found

Category Critical High Medium Low
Logic/Bugs 0 0 0 0
Security 0 0 0 0
Error Handling 0 0 0 0
Types 0 0 0 0
Comments/Docs 0 0 0 0
Tests 0 0 0 0
Simplification 0 0 0 0

Review Coverage

  • Logic and correctness - Clean. The applyCodexProviderOverrides function correctly handles all edge cases including null/inherit values, missing objects, and preserves existing properties when merging.
  • Security (OWASP Top 10) - Clean. No user input is directly used in queries or commands; values are constrained by TypeScript types and Zod enums.
  • Error handling - Clean. The override function is designed to be idempotent and safe, returning the original request unmodified when not applicable.
  • Type safety - Clean. New type definitions properly constrain the allowed values, and the implementation correctly uses type guards.
  • Documentation accuracy - Clean. Comments accurately describe the behavior.
  • Test coverage - Adequate. Unit tests cover non-codex providers, inherit/null cases, all override scenarios, and object auto-creation.
  • Code clarity - Good. The lazy cloning pattern with ensureCloned() is efficient and the code is well-structured.

Implementation Highlights

  1. Lazy Cloning Pattern (src/lib/codex/provider-overrides.ts:55-58): The ensureCloned() pattern efficiently avoids cloning the request object when no overrides are needed.

  2. Proper Type Handling: The normalizeParallelToolCallsPreference correctly converts string "true"/"false" to boolean values.

  3. Object Preservation: When overriding reasoning or text, existing fields are preserved using spread operators.

  4. Complete Data Flow: All layers are properly updated:

    • Database schema with proper column lengths
    • Repository with create/update/select support
    • Transformers for data conversion
    • Actions with type-safe parameters
    • UI form with conditional rendering for Codex providers only
    • i18n for all 5 locales

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

This PR implements a well-designed feature adding provider-level parameter overrides for Codex-type providers. The implementation is complete and consistent across all layers (database, repository, actions, UI, i18n).

PR Size: L

  • Lines changed: 830 (825 additions + 5 deletions)
  • Files changed: 20

Issues Found

Category Critical High Medium Low
Logic/Bugs 0 0 0 0
Security 0 0 0 0
Error Handling 0 0 0 0
Types 0 0 0 0
Comments/Docs 0 0 0 0
Tests 0 0 0 0
Simplification 0 0 0 0

Review Coverage

  • Logic and correctness - Clean. The applyCodexProviderOverrides function correctly handles all edge cases including null/inherit values, missing objects, and preserves existing properties when merging.
  • Security (OWASP Top 10) - Clean. No user input is directly used in queries or commands; values are constrained by TypeScript types and Zod enums.
  • Error handling - Clean. The override function is designed to be idempotent and safe, returning the original request unmodified when not applicable.
  • Type safety - Clean. New type definitions properly constrain the allowed values, and the implementation correctly uses type guards.
  • Documentation accuracy - Clean. Comments accurately describe the behavior.
  • Test coverage - Adequate. Unit tests cover non-codex providers, inherit/null cases, all override scenarios, and object auto-creation.
  • Code clarity - Good. The lazy cloning pattern with ensureCloned() is efficient and the code is well-structured.

Implementation Highlights

  1. Lazy Cloning Pattern (src/lib/codex/provider-overrides.ts:55-58): The ensureCloned() pattern efficiently avoids cloning the request object when no overrides are needed.

  2. Proper Type Handling: The normalizeParallelToolCallsPreference correctly converts string "true"/"false" to boolean values.

  3. Object Preservation: When overriding reasoning or text, existing fields are preserved using spread operators.

  4. Complete Data Flow: All layers are properly updated:

    • Database schema with proper column lengths
    • Repository with create/update/select support
    • Transformers for data conversion
    • Actions with type-safe parameters
    • UI form with conditional rendering for Codex providers only
    • i18n for all 5 locales

Automated review by Claude AI

@github-actions
Copy link
Contributor

github-actions bot commented Jan 4, 2026

🧪 测试结果

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

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

1 similar comment
@github-actions
Copy link
Contributor

github-actions bot commented Jan 4, 2026

🧪 测试结果

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

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

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: 0

Caution

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

⚠️ Outside diff range comments (1)
src/app/[locale]/settings/providers/_components/forms/provider-form.tsx (1)

542-578: 表单重置逻辑遗漏了 Codex 偏好字段。

在成功创建供应商后,表单重置逻辑(Lines 542-578)正确地重置了 context1mPreference(Line 577),但遗漏了四个 Codex 偏好字段的重置。这会导致用户在创建下一个供应商时看到上一次设置的 Codex 偏好值,而不是默认的 "inherit" 值。

建议在 Line 577 之后添加以下重置调用:

setContext1mPreference("inherit");
setCodexReasoningEffortPreference("inherit");
setCodexReasoningSummaryPreference("inherit");
setCodexTextVerbosityPreference("inherit");
setCodexParallelToolCallsPreference("inherit");
🔎 建议的修复
           setWebsiteUrl("");
           setContext1mPreference("inherit");
+          setCodexReasoningEffortPreference("inherit");
+          setCodexReasoningSummaryPreference("inherit");
+          setCodexTextVerbosityPreference("inherit");
+          setCodexParallelToolCallsPreference("inherit");
         }
         onSuccess?.();
♻️ Duplicate comments (3)
src/actions/providers.ts (1)

456-461: LGTM:偏好字段的默认值保持一致。

所有 Codex 偏好字段(包括 context_1m_preference)现在都正确地默认为 "inherit",保持了一致性。这修复了先前审查中提到的 context_1m_preference 默认值不一致的问题。

src/app/[locale]/settings/providers/_components/forms/provider-form.tsx (2)

63-91: LGTM:Tooltip 性能问题已修复。

FieldLabelWithTooltip 组件现在正确地仅使用 TooltipTooltipTriggerTooltipContent,而不在内部创建 TooltipProviderTooltipProvider 已在 Line 588 处提升到表单级别,所有 tooltip 共享一个 provider 实例,这修复了先前审查中提到的性能问题。

基于 learnings:使用 lucide-reactInfo 图标符合规范。


1057-1201: 建议重构:提取重复的 Codex 覆写选择器代码。

Lines 1061-1201 中的四个 Codex 参数覆写选择器(ReasoningEffort、ReasoningSummary、TextVerbosity、ParallelToolCalls)包含高度重复的代码结构。建议提取为可复用的 CodexOverrideSelect 组件,接收 labeltooltipvalueonValueChangeoptionsdisabled 等属性,以提高代码可维护性和可读性。

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to Reviews > Disable Cache setting

📥 Commits

Reviewing files that changed from the base of the PR and between f43b8b0414faf7c2aba4b6d9256d54c9eb935d9a and 3f33b353a38edb507034ff94bee9975db53b2d70.

📒 Files selected for processing (2)
  • src/actions/providers.ts
  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx,js,jsx,json}

📄 CodeRabbit inference engine (CLAUDE.md)

Use 2-space indentation in all code files

Files:

  • src/actions/providers.ts
  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Use double quotes for strings instead of single quotes
Use trailing commas in multi-line structures
Enforce maximum line length of 100 characters
Use path alias @/* to reference files from ./src/* directory

**/*.{ts,tsx,js,jsx}: Use Biome for linting and formatting with 2-space indent, double quotes, trailing commas, and 100 character max line length
Use path alias @/* to reference files in ./src/* directory

Files:

  • src/actions/providers.ts
  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use TypeScript strict mode for type safety
Use readonly or const assertions for immutable data structures

Files:

  • src/actions/providers.ts
  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
src/actions/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

src/actions/**/*.ts: Validate all user inputs with Zod schemas before processing
Use Server Actions in next-safe-action with OpenAPI generation for admin API endpoints
Use Next.js API Routes and Server Actions for admin operations and REST endpoints

Files:

  • src/actions/providers.ts
src/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.ts: Hash API keys using SHA-256 before storing in database, never store plaintext keys
Mask API keys and sensitive data in application logs
Validate required environment variables at startup with clear error messages

Files:

  • src/actions/providers.ts
src/**/*provider*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Set provider circuit breaker failure threshold, open duration, and half-open success threshold in configuration

Files:

  • src/actions/providers.ts
src/{repository,actions}/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Avoid N+1 queries by using eager loading and batch queries for statistics

Files:

  • src/actions/providers.ts
src/**/*.{tsx,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{tsx,jsx}: Use lucide-react for icons, no custom SVGs
Use React's automatic escaping to prevent XSS vulnerabilities

Files:

  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
**/*.{tsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Use next-intl for internationalization with 5 locales: en, ja, ru, zh-CN, zh-TW

Files:

  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
🧠 Learnings (4)
📚 Learning: 2026-01-03T09:08:20.573Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-03T09:08:20.573Z
Learning: Applies to src/components/**/*.{ts,tsx} : Use `lucide-react` for icons instead of custom SVGs

Applied to files:

  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
📚 Learning: 2026-01-03T09:08:49.019Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-03T09:08:49.019Z
Learning: Applies to src/**/*.{tsx,jsx} : Use `lucide-react` for icons, no custom SVGs

Applied to files:

  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
📚 Learning: 2026-01-03T09:08:49.019Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-03T09:08:49.019Z
Learning: Applies to src/components/**/*.{tsx,jsx} : Use shadcn/ui component library for high-quality, accessible UI components

Applied to files:

  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
📚 Learning: 2026-01-03T09:08:49.019Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-03T09:08:49.019Z
Learning: Applies to src/**/*provider*.ts : Set provider circuit breaker failure threshold, open duration, and half-open success threshold in configuration

Applied to files:

  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
🧬 Code graph analysis (2)
src/actions/providers.ts (1)
src/types/provider.ts (4)
  • CodexReasoningEffortPreference (17-24)
  • CodexReasoningSummaryPreference (26-26)
  • CodexTextVerbosityPreference (28-28)
  • CodexParallelToolCallsPreference (31-31)
src/app/[locale]/settings/providers/_components/forms/provider-form.tsx (1)
src/types/provider.ts (4)
  • CodexReasoningEffortPreference (17-24)
  • CodexReasoningSummaryPreference (26-26)
  • CodexTextVerbosityPreference (28-28)
  • CodexParallelToolCallsPreference (31-31)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: 🌐 API Tests
  • GitHub Check: Docker Build Test
  • GitHub Check: dev-build-deploy
🔇 Additional comments (3)
src/actions/providers.ts (1)

44-51: LGTM:Codex 偏好类型导入正确。

四个新增的 Codex 偏好类型导入符合代码规范,与 src/types/provider.ts 中的类型定义一致。

src/app/[locale]/settings/providers/_components/forms/provider-form.tsx (2)

172-187: LGTM:Codex 偏好状态初始化正确。

四个 Codex 偏好状态变量正确地从 sourceProvider 继承值或默认为 "inherit",与后端的默认行为保持一致。类型注解也准确匹配导入的类型定义。


395-398: LGTM:提交载荷正确包含 Codex 偏好字段。

创建和编辑供应商的提交载荷都正确地包含了四个 Codex 偏好字段,类型定义与后端 API 期望一致,状态值直接传递无需转换。

Also applies to: 437-440, 501-504

@ding113 ding113 force-pushed the feat/codex-provider-options-404 branch from 3f33b35 to 1dfe79c Compare January 4, 2026 14:02
@github-actions
Copy link
Contributor

github-actions bot commented Jan 4, 2026

🧪 测试结果

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

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

@ding113 ding113 merged commit 16059f8 into dev Jan 4, 2026
9 checks passed
@github-project-automation github-project-automation bot moved this from Backlog to Done in Claude Code Hub Roadmap Jan 4, 2026
@coderabbitai coderabbitai bot mentioned this pull request Jan 5, 2026
12 tasks
@github-actions github-actions bot mentioned this pull request Jan 6, 2026
4 tasks
@greptile-apps
Copy link

greptile-apps bot commented Jan 8, 2026

Greptile encountered an error while reviewing this PR. Please reach out to support@greptile.com for assistance.

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

Labels

area:i18n area:provider area:UI enhancement New feature or request size/L Large PR (< 1000 lines)

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant