Skip to content

feat: 审计并展示供应商级参数覆写(specialSettings)#557

Merged
ding113 merged 1 commit intodevfrom
feat/special-settings-audit-provider-overrides
Jan 7, 2026
Merged

feat: 审计并展示供应商级参数覆写(specialSettings)#557
ding113 merged 1 commit intodevfrom
feat/special-settings-audit-provider-overrides

Conversation

@ding113
Copy link
Owner

@ding113 ding113 commented Jan 7, 2026

Greptile Overview

Greptile Summary

This PR added comprehensive audit tracking for provider-level parameter overrides in Codex requests. The implementation tracks when vendor-level settings override client parameters (reasoning, text.verbosity, parallel_tool_calls) and records detailed before/after change information.

Key Changes:

  • Added new specialSettings audit field stored in both Redis (temporary, 5-min TTL) and Postgres (message_request.special_settings JSONB column)
  • Created applyCodexProviderOverridesWithAudit() function that captures before/after state with per-field change tracking using Object.is() comparison
  • Integrated audit collection in proxy forwarder with dual storage (Redis for active sessions, DB for long-term audit trail)
  • Added UI components: new "Special Settings" tab in Session Details, badge indicators in Usage Logs table, and display in error details dialog
  • Added comprehensive test coverage (11 new test cases) for audit functionality
  • Added i18n translations for all 5 supported languages

Technical Highlights:

  • Proper error handling with void promise pattern and .catch() for async storage operations
  • Type-safe implementation with TypeScript throughout the stack
  • Extensible design: SpecialSetting is a union type that can support additional audit types beyond provider overrides
  • Database migration is straightforward (single JSONB column addition)

The implementation is clean, well-tested, and follows the codebase's existing patterns. All lint, typecheck, test, and build checks passed.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The implementation is thorough, well-tested, and follows established patterns. The feature is purely additive (audit/observability), includes comprehensive test coverage, proper error handling, and has passed all validation checks. The database migration is simple and safe.
  • No files require special attention

Important Files Changed

File Analysis

Filename Score Overview
src/lib/codex/provider-overrides.ts 5/5 Added audit function with comprehensive before/after tracking using Object.is for comparison, well-tested
tests/unit/proxy/codex-provider-overrides.test.ts 5/5 Comprehensive test coverage for audit functionality with 11 new test cases
src/app/v1/_lib/proxy/forwarder.ts 5/5 Integrated audit function, stores to Redis and DB with proper error handling
src/lib/session-manager.ts 5/5 Added Redis storage/retrieval for special settings with 5-minute TTL
src/repository/message-write-buffer.ts 5/5 Added specialSettings to batch update SQL with proper JSONB handling
src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-details-tabs.tsx 5/5 Added new tab for special settings with JSON display

Sequence Diagram

sequenceDiagram
    participant Client
    participant Forwarder as ProxyForwarder
    participant Session as ProxySession
    participant Override as applyCodexProviderOverridesWithAudit
    participant Redis as SessionManager (Redis)
    participant DB as Message Repository (Postgres)
    participant UI as Dashboard UI

    Client->>Forwarder: Send Codex request
    Forwarder->>Override: Apply provider-level overrides
    Override->>Override: Capture before values
    Override->>Override: Apply parameter overrides
    Override->>Override: Capture after values
    Override->>Override: Compare with Object.is()
    Override-->>Forwarder: Return {request, audit}
    
    alt audit exists (hit=true)
        Forwarder->>Session: addSpecialSetting(audit)
        Session->>Session: Store in specialSettings[]
        Forwarder->>Redis: storeSessionSpecialSettings()
        Note over Redis: TTL: 5 minutes
        Forwarder->>DB: updateMessageRequestDetails()
        Note over DB: JSONB column: special_settings
    end
    
    Forwarder->>Client: Forward modified request to upstream
    
    Note over UI: Later...
    UI->>Redis: getSessionSpecialSettings()
    Redis-->>UI: Return specialSettings array
    UI->>DB: Query usage_logs / message_request
    DB-->>UI: Return records with special_settings
    UI->>UI: Display in Session Details tab
    UI->>UI: Show badge in Usage Logs table
Loading

@coderabbitai
Copy link

coderabbitai bot commented Jan 7, 2026

📝 Walkthrough

Walkthrough

本PR引入了消息请求的"特殊设置"(special_settings)功能,用于跟踪Codex提供商参数覆盖的审计数据。包括数据库架构更新、新的类型定义、会话与代理层增强、前端UI组件扩展及多语言翻译支持。

Changes

内聚块 / 文件 变更摘要
数据库迁移与元数据
drizzle/0049_shocking_ultimatum.sql, drizzle/meta/0049_snapshot.json, drizzle/meta/_journal.json
向 message_request 表添加 special_settings jsonb 列;生成PostgreSQL数据库架构快照;追加迁移日志条目(idx 49)
类型定义
src/types/special-settings.ts, src/types/message.ts
新增SpecialSetting类型模块定义审计数据结构;扩展MessageRequest和CreateMessageRequestData接口添加specialSettings字段
会话与代理管理
src/lib/session-manager.ts, src/app/v1/_lib/proxy/session.ts
SessionManager新增getSessionSpecialSettings和storeSessionSpecialSettings方法;ProxySession新增specialSettings状态和公开方法(addSpecialSetting/getSpecialSettings)
提供商覆盖与审计
src/lib/codex/provider-overrides.ts, src/app/v1/_lib/proxy/forwarder.ts, tests/unit/proxy/codex-provider-overrides.test.ts
新增applyCodexProviderOverridesWithAudit函数实现审计逻辑;转发器集成新函数以持久化审计数据至special_settings;添加审计相关单元测试
数据仓储层
src/repository/message.ts, src/repository/message-write-buffer.ts, src/repository/usage-logs.ts, src/repository/_shared/transformers.ts
扩展updateMessageRequestDetails支持specialSettings参数;消息写缓冲区添加specialSettings字段映射;使用日志查询投影specialSettings;转换器添加specialSettings到MessageRequest负载
后端API与会话操作
src/actions/active-sessions.ts
getSessionDetails返回类型扩展specialSettings字段;并行数据获取集成SessionManager.getSessionSpecialSettings调用
仪表板日志UI组件
src/app/[locale]/dashboard/logs/_components/error-details-dialog.tsx, src/app/[locale]/dashboard/logs/_components/usage-logs-table.tsx
ErrorDetailsDialog接受specialSettings prop并渲染JSON内容;UsageLogsTable传递specialSettings至对话框并添加条件徽章UI
会话消息UI组件
src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-details-tabs.tsx, src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-messages-client.tsx, src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-messages-client.test.tsx
SessionMessagesDetailsTabs新增specialSettings标签页;session-messages-client管理specialSettings状态并传递至子组件;扩展导出数据包含specialSettings;添加相关测试覆盖
多语言翻译
messages/en/dashboard.json, messages/ja/dashboard.json, messages/ru/dashboard.json, messages/zh-CN/dashboard.json, messages/zh-TW/dashboard.json
在日志表、日志详情和会话详情节点下添加specialSettings翻译键(英文"Special"、日文"特殊設定"、俄文"Особые настройки"、中文"特殊设置/特殊設定")

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed PR 标题清晰准确地描述了主要改动:添加审计和展示供应商级参数覆写功能(specialSettings),这是本 PR 的核心目标。
Description check ✅ Passed PR描述详细阐述了审计跟踪的实现内容,包括specialSettings字段、applyCodexProviderOverridesWithAudit函数、UI集成等,与代码变更相关联。

✏️ 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/special-settings-audit-provider-overrides

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!

此拉取请求旨在增强系统对 Codex 类型供应商参数覆写行为的透明度和可审计性。通过引入 specialSettings 字段,系统现在能够详细记录和展示供应商级别参数(如 reasoningtextparallel_tool_calls)的覆写过程,包括这些覆写是否被应用以及具体的变化。这不仅有助于故障排除,也为长期的数据审计提供了支持,并已在用户界面中集成展示,提升了用户对请求处理细节的可见性。

Highlights

  • 新增供应商级参数覆写审计字段: 引入了一个名为 specialSettings 的新字段,用于审计和记录 Codex 类型供应商的参数覆写情况。此字段将详细记录参数是否被命中、是否生效以及变更前后的具体值。
  • 数据持久化与缓存: 新的 specialSettings 数据将同时存储在 Redis(用于会话详情的临时存储)和 PostgreSQL 数据库(message_request.special_settings 字段,用于长期审计和查询)中,确保数据的可追溯性。
  • 用户界面展示: 在用户界面中,已在“使用日志列表”、“使用日志详情”和“会话请求详情”页面新增了“特殊设置”的展示,方便用户直观查看参数覆写情况。
  • 增强的参数覆写逻辑: 更新了 applyCodexProviderOverrides 函数,现在它会返回一个审计对象,详细说明了参数覆写是如何应用的,包括哪些参数被修改以及它们在修改前后的值。
  • 多语言支持: 为新的“特殊设置”UI元素添加了多语言支持,包括英语、日语、俄语、简体中文和繁体中文。
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 github-actions bot added enhancement New feature or request area:UI area:session area:i18n size/XL Extra Large PR (> 1000 lines) labels Jan 7, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Jan 7, 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 新增了对供应商级参数覆写的审计与可视化功能,整体实现非常完整,覆盖了数据库、后端逻辑和前端展示。代码质量很高,在 src/lib/codex/provider-overrides.ts 文件中,我发现一处可以优化的地方,通过重构可以提高代码的可维护性。除此之外,其他改动都很好地实现了预期功能。

Comment on lines +128 to +169
const beforeParallelToolCalls = toAuditValue(request.parallel_tool_calls);
const beforeReasoning = isPlainObject(request.reasoning) ? request.reasoning : null;
const beforeReasoningEffort = toAuditValue(beforeReasoning?.effort);
const beforeReasoningSummary = toAuditValue(beforeReasoning?.summary);
const beforeText = isPlainObject(request.text) ? request.text : null;
const beforeTextVerbosity = toAuditValue(beforeText?.verbosity);

const nextRequest = applyCodexProviderOverrides(provider, request);

const afterParallelToolCalls = toAuditValue(nextRequest.parallel_tool_calls);
const afterReasoning = isPlainObject(nextRequest.reasoning) ? nextRequest.reasoning : null;
const afterReasoningEffort = toAuditValue(afterReasoning?.effort);
const afterReasoningSummary = toAuditValue(afterReasoning?.summary);
const afterText = isPlainObject(nextRequest.text) ? nextRequest.text : null;
const afterTextVerbosity = toAuditValue(afterText?.verbosity);

const changes: ProviderParameterOverrideSpecialSetting["changes"] = [
{
path: "parallel_tool_calls",
before: beforeParallelToolCalls,
after: afterParallelToolCalls,
changed: !Object.is(beforeParallelToolCalls, afterParallelToolCalls),
},
{
path: "reasoning.effort",
before: beforeReasoningEffort,
after: afterReasoningEffort,
changed: !Object.is(beforeReasoningEffort, afterReasoningEffort),
},
{
path: "reasoning.summary",
before: beforeReasoningSummary,
after: afterReasoningSummary,
changed: !Object.is(beforeReasoningSummary, afterReasoningSummary),
},
{
path: "text.verbosity",
before: beforeTextVerbosity,
after: afterTextVerbosity,
changed: !Object.is(beforeTextVerbosity, afterTextVerbosity),
},
];
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

当前实现中,捕获参数覆写前后值的逻辑存在重复。例如,获取 beforeafter 值的代码块几乎相同,并且 changes 数组是手动构建的,这使得在未来添加更多审计参数时不够灵活。

建议通过提取辅助函数和数据驱动的方式来重构此部分代码,以提高可维护性和可扩展性。

  const getAuditValues = (req: Record<string, unknown>) => {
    const reasoning = isPlainObject(req.reasoning) ? req.reasoning : null;
    const text = isPlainObject(req.text) ? req.text : null;
    return {
      parallel_tool_calls: toAuditValue(req.parallel_tool_calls),
      "reasoning.effort": toAuditValue(reasoning?.effort),
      "reasoning.summary": toAuditValue(reasoning?.summary),
      "text.verbosity": toAuditValue(text?.verbosity),
    };
  };

  const beforeValues = getAuditValues(request);
  const nextRequest = applyCodexProviderOverrides(provider, request);
  const afterValues = getAuditValues(nextRequest);

  const auditPaths = Object.keys(beforeValues) as Array<keyof typeof beforeValues>;

  const changes: ProviderParameterOverrideSpecialSetting["changes"] = auditPaths.map((path) => ({
    path,
    before: beforeValues[path],
    after: afterValues[path],
    changed: !Object.is(beforeValues[path], afterValues[path]),
  }));

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

🧹 Nitpick comments (2)
src/types/special-settings.ts (1)

12-26: 类型定义结构清晰,审计字段设计合理。

ProviderParameterOverrideSpecialSetting 的实现体现了良好的审计设计:

  • 使用字面量类型("provider_parameter_override""provider")支持未来的类型判别
  • hitchanged 布尔标志清晰区分了"规则是否匹配"与"是否实际修改"的语义
  • changes 数组提供了字段级别的细粒度变更追踪
  • 可空的 providerId/providerName/providerType 正确表达了"不适用"的语义

基于 learnings,此处使用 null 而非 undefined 是正确的,因为 null 明确表示"无提供商上下文",而不是"未加载"。

可选优化建议:强化 providerType 类型约束

当前 providerType: string | null 提供了良好的灵活性,但如果希望更严格的类型安全,可以考虑引用 ProviderType 联合类型:

+import type { ProviderType } from "@/types/provider";
+
 export type ProviderParameterOverrideSpecialSetting = {
   type: "provider_parameter_override";
   scope: "provider";
   providerId: number | null;
   providerName: string | null;
-  providerType: string | null;
+  providerType: ProviderType | null;
   hit: boolean;
   changed: boolean;
   changes: Array<{
     path: string;
     before: SpecialSettingChangeValue;
     after: SpecialSettingChangeValue;
     changed: boolean;
   }>;
 };

不过,当前的 string | null 设计在审计场景下也是合理的,因为它避免了在新增提供商类型时破坏类型兼容性。可根据项目对类型严格性的偏好决定是否采纳。

src/lib/session-manager.ts (1)

14-15: Redis 中特殊设置读写与现有 requestBody 模式保持一致,但要注意请求序号约定

storeSessionSpecialSettingsgetSessionSpecialSettings 复用了 normalizeRequestSequenceSESSION_TTL,key 形如 session:{id}:req:{sequence}:specialSettings,与现有 requestBody / headers / meta 的分片存储方式一致,实现上没问题。需要注意的是:写入端在 requestSequence 归一化失败时会回退到 1,而读取端如果没有拿到合法的 requestSequence 会直接返回 null,不会默认读第 1 条;请确认所有调用方都会传入经过校验的序号,否则 UI 可能永远读不到 Redis 里存好的审计记录。

Also applies to: 1430-1480

📜 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 9e8f9fe and 6bd9b0c.

📒 Files selected for processing (26)
  • drizzle/0049_shocking_ultimatum.sql
  • drizzle/meta/0049_snapshot.json
  • drizzle/meta/_journal.json
  • messages/en/dashboard.json
  • messages/ja/dashboard.json
  • messages/ru/dashboard.json
  • messages/zh-CN/dashboard.json
  • messages/zh-TW/dashboard.json
  • src/actions/active-sessions.ts
  • src/app/[locale]/dashboard/logs/_components/error-details-dialog.tsx
  • src/app/[locale]/dashboard/logs/_components/usage-logs-table.tsx
  • src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-details-tabs.tsx
  • src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-messages-client.test.tsx
  • src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-messages-client.tsx
  • src/app/v1/_lib/proxy/forwarder.ts
  • src/app/v1/_lib/proxy/session.ts
  • src/drizzle/schema.ts
  • src/lib/codex/provider-overrides.ts
  • src/lib/session-manager.ts
  • src/repository/_shared/transformers.ts
  • src/repository/message-write-buffer.ts
  • src/repository/message.ts
  • src/repository/usage-logs.ts
  • src/types/message.ts
  • src/types/special-settings.ts
  • tests/unit/proxy/codex-provider-overrides.test.ts
🧰 Additional context used
📓 Path-based instructions (21)
**/*.{ts,tsx,js,jsx,json}

📄 CodeRabbit inference engine (CLAUDE.md)

Use 2-space indentation in all code files

Files:

  • src/repository/message-write-buffer.ts
  • src/app/v1/_lib/proxy/session.ts
  • src/actions/active-sessions.ts
  • src/repository/_shared/transformers.ts
  • src/repository/message.ts
  • src/drizzle/schema.ts
  • messages/ja/dashboard.json
  • src/repository/usage-logs.ts
  • messages/zh-CN/dashboard.json
  • src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-details-tabs.tsx
  • messages/ru/dashboard.json
  • src/types/special-settings.ts
  • messages/zh-TW/dashboard.json
  • tests/unit/proxy/codex-provider-overrides.test.ts
  • src/types/message.ts
  • src/lib/codex/provider-overrides.ts
  • drizzle/meta/_journal.json
  • src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-messages-client.test.tsx
  • src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-messages-client.tsx
  • drizzle/meta/0049_snapshot.json
  • src/app/[locale]/dashboard/logs/_components/usage-logs-table.tsx
  • src/lib/session-manager.ts
  • src/app/[locale]/dashboard/logs/_components/error-details-dialog.tsx
  • src/app/v1/_lib/proxy/forwarder.ts
  • messages/en/dashboard.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/repository/message-write-buffer.ts
  • src/app/v1/_lib/proxy/session.ts
  • src/actions/active-sessions.ts
  • src/repository/_shared/transformers.ts
  • src/repository/message.ts
  • src/drizzle/schema.ts
  • src/repository/usage-logs.ts
  • src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-details-tabs.tsx
  • src/types/special-settings.ts
  • tests/unit/proxy/codex-provider-overrides.test.ts
  • src/types/message.ts
  • src/lib/codex/provider-overrides.ts
  • src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-messages-client.test.tsx
  • src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-messages-client.tsx
  • src/app/[locale]/dashboard/logs/_components/usage-logs-table.tsx
  • src/lib/session-manager.ts
  • src/app/[locale]/dashboard/logs/_components/error-details-dialog.tsx
  • src/app/v1/_lib/proxy/forwarder.ts
src/repository/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

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

Files:

  • src/repository/message-write-buffer.ts
  • src/repository/_shared/transformers.ts
  • src/repository/message.ts
  • src/repository/usage-logs.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/repository/message-write-buffer.ts
  • src/app/v1/_lib/proxy/session.ts
  • src/actions/active-sessions.ts
  • src/repository/_shared/transformers.ts
  • src/repository/message.ts
  • src/drizzle/schema.ts
  • src/repository/usage-logs.ts
  • src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-details-tabs.tsx
  • src/types/special-settings.ts
  • tests/unit/proxy/codex-provider-overrides.test.ts
  • src/types/message.ts
  • src/lib/codex/provider-overrides.ts
  • src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-messages-client.test.tsx
  • src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-messages-client.tsx
  • src/app/[locale]/dashboard/logs/_components/usage-logs-table.tsx
  • src/lib/session-manager.ts
  • src/app/[locale]/dashboard/logs/_components/error-details-dialog.tsx
  • src/app/v1/_lib/proxy/forwarder.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/repository/message-write-buffer.ts
  • src/app/v1/_lib/proxy/session.ts
  • src/actions/active-sessions.ts
  • src/repository/_shared/transformers.ts
  • src/repository/message.ts
  • src/drizzle/schema.ts
  • src/repository/usage-logs.ts
  • src/types/special-settings.ts
  • src/types/message.ts
  • src/lib/codex/provider-overrides.ts
  • src/lib/session-manager.ts
  • src/app/v1/_lib/proxy/forwarder.ts
src/**/*{message,response,log}*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Log request duration, token usage, and cost to message_request table for analytics

Files:

  • src/repository/message-write-buffer.ts
  • src/repository/message.ts
  • src/repository/usage-logs.ts
  • src/types/message.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/message-write-buffer.ts
  • src/actions/active-sessions.ts
  • src/repository/_shared/transformers.ts
  • src/repository/message.ts
  • src/repository/usage-logs.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/proxy/session.ts
  • src/app/v1/_lib/proxy/forwarder.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/session.ts
  • src/app/v1/_lib/proxy/forwarder.ts
src/app/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Implement Content-Security-Policy headers for XSS prevention

Files:

  • src/app/v1/_lib/proxy/session.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/proxy/session.ts
  • src/app/v1/_lib/proxy/forwarder.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/active-sessions.ts
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
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/ja/dashboard.json
  • messages/zh-CN/dashboard.json
  • messages/ru/dashboard.json
  • messages/zh-TW/dashboard.json
  • messages/en/dashboard.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/ja/dashboard.json
  • messages/zh-CN/dashboard.json
  • src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-details-tabs.tsx
  • messages/ru/dashboard.json
  • messages/zh-TW/dashboard.json
  • drizzle/meta/_journal.json
  • src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-messages-client.test.tsx
  • src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-messages-client.tsx
  • drizzle/meta/0049_snapshot.json
  • src/app/[locale]/dashboard/logs/_components/usage-logs-table.tsx
  • src/app/[locale]/dashboard/logs/_components/error-details-dialog.tsx
  • messages/en/dashboard.json
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]/dashboard/sessions/[sessionId]/messages/_components/session-details-tabs.tsx
  • src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-messages-client.test.tsx
  • src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-messages-client.tsx
  • src/app/[locale]/dashboard/logs/_components/usage-logs-table.tsx
  • src/app/[locale]/dashboard/logs/_components/error-details-dialog.tsx
**/*.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
  • src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-messages-client.test.tsx
**/*.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/**/*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/lib/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use connection pooling for database and Redis connections

Files:

  • src/lib/codex/provider-overrides.ts
  • src/lib/session-manager.ts
src/lib/session-manager.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Session Manager must use 5-minute Redis context cache with sliding window and record decision chains for audit trail

Files:

  • src/lib/session-manager.ts
🧠 Learnings (14)
📚 Learning: 2026-01-05T03:01:39.354Z
Learnt from: NieiR
Repo: ding113/claude-code-hub PR: 539
File: src/types/user.ts:158-170
Timestamp: 2026-01-05T03:01:39.354Z
Learning: In TypeScript interfaces, explicitly document and enforce distinct meanings for null and undefined. Example: for numeric limits like limitTotalUsd, use 'number | null | undefined' when null signifies explicitly unlimited (e.g., matches DB schema or special UI logic) and undefined signifies 'inherit default'. This pattern should be consistently reflected in type definitions across related fields to preserve semantic clarity between database constraints and UI behavior.

Applied to files:

  • src/repository/message-write-buffer.ts
  • src/app/v1/_lib/proxy/session.ts
  • src/actions/active-sessions.ts
  • src/repository/_shared/transformers.ts
  • src/repository/message.ts
  • src/drizzle/schema.ts
  • src/repository/usage-logs.ts
  • src/types/special-settings.ts
  • src/types/message.ts
  • src/lib/codex/provider-overrides.ts
  • src/lib/session-manager.ts
  • 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/session.ts
  • 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/drizzle/**/*.ts : Use JSON columns in PostgreSQL for flexible data structures (modelRedirects, providerChain, etc.)

Applied to files:

  • src/drizzle/schema.ts
  • drizzle/0049_shocking_ultimatum.sql
  • drizzle/meta/0049_snapshot.json
📚 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 : Implement proper indexing strategy for common queries and foreign keys

Applied to files:

  • src/drizzle/schema.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/drizzle/**/*.ts : Use Drizzle ORM with PostgreSQL for database operations

Applied to files:

  • src/drizzle/schema.ts
📚 Learning: 2026-01-05T03:02:06.594Z
Learnt from: NieiR
Repo: ding113/claude-code-hub PR: 539
File: src/app/[locale]/dashboard/_components/user/user-key-table-row.tsx:66-66
Timestamp: 2026-01-05T03:02:06.594Z
Learning: In the claude-code-hub project, the translations.actions.addKey field in UserKeyTableRowProps is defined as optional for backward compatibility, but all actual callers in the codebase provide the complete translations object. The field has been added to all 5 locale files (messages/{locale}/dashboard.json).

Applied to files:

  • messages/ja/dashboard.json
  • messages/zh-CN/dashboard.json
  • src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-details-tabs.tsx
  • messages/ru/dashboard.json
  • messages/zh-TW/dashboard.json
  • src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-messages-client.test.tsx
  • messages/en/dashboard.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 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/dashboard.json
  • messages/zh-CN/dashboard.json
📚 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/**/*{message,response,log}*.ts : Log request duration, token usage, and cost to message_request table for analytics

Applied to files:

  • src/repository/usage-logs.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/session/**/*.ts : Store session data in Redis with 5-minute TTL for session stickiness

Applied to files:

  • src/lib/session-manager.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/lib/session-manager.ts : Session Manager must use 5-minute Redis context cache with sliding window and record decision chains for audit trail

Applied to files:

  • src/lib/session-manager.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/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 : 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/**/*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
📚 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
🧬 Code graph analysis (15)
src/repository/message-write-buffer.ts (1)
src/types/message.ts (1)
  • CreateMessageRequestData (241-290)
src/app/v1/_lib/proxy/session.ts (1)
src/types/special-settings.ts (1)
  • SpecialSetting (8-8)
src/actions/active-sessions.ts (2)
src/types/special-settings.ts (1)
  • SpecialSetting (8-8)
src/lib/session-manager.ts (1)
  • SessionManager (80-2008)
src/repository/message.ts (1)
src/types/message.ts (1)
  • CreateMessageRequestData (241-290)
src/drizzle/schema.ts (1)
src/types/special-settings.ts (1)
  • SpecialSetting (8-8)
src/repository/usage-logs.ts (1)
src/types/special-settings.ts (1)
  • SpecialSetting (8-8)
src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-details-tabs.tsx (2)
src/components/ui/tabs.tsx (3)
  • TabsList (54-54)
  • TabsTrigger (54-54)
  • TabsContent (54-54)
src/components/ui/code-display.tsx (1)
  • CodeDisplay (64-520)
tests/unit/proxy/codex-provider-overrides.test.ts (1)
src/lib/codex/provider-overrides.ts (1)
  • applyCodexProviderOverridesWithAudit (103-183)
src/types/message.ts (1)
src/types/special-settings.ts (1)
  • SpecialSetting (8-8)
src/lib/codex/provider-overrides.ts (1)
src/types/special-settings.ts (1)
  • ProviderParameterOverrideSpecialSetting (12-26)
src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-messages-client.tsx (1)
src/actions/active-sessions.ts (1)
  • getSessionDetails (510-673)
src/app/[locale]/dashboard/logs/_components/usage-logs-table.tsx (1)
src/components/ui/badge.tsx (1)
  • Badge (39-39)
src/lib/session-manager.ts (4)
src/types/special-settings.ts (1)
  • SpecialSetting (8-8)
src/lib/redis/client.ts (1)
  • getRedisClient (75-154)
src/lib/utils/request-sequence.ts (1)
  • normalizeRequestSequence (9-14)
src/lib/logger.ts (1)
  • logger (168-187)
src/app/[locale]/dashboard/logs/_components/error-details-dialog.tsx (1)
src/types/special-settings.ts (1)
  • SpecialSetting (8-8)
src/app/v1/_lib/proxy/forwarder.ts (2)
src/lib/codex/provider-overrides.ts (1)
  • applyCodexProviderOverridesWithAudit (103-183)
src/repository/message.ts (1)
  • updateMessageRequestDetails (116-200)
⏰ 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: pr-description
  • GitHub Check: pr-label
  • GitHub Check: check-codex-status
  • GitHub Check: pr-review
  • GitHub Check: Docker Build Test
  • GitHub Check: 🌐 API Tests
  • GitHub Check: dev-build-deploy
🔇 Additional comments (37)
messages/en/dashboard.json (1)

131-131: 翻译结构一致,实现正确。

英文翻译键已在三个位置正确添加:日志表格列、日志详情嵌套对象和会话详情。结构与其他语言环境保持一致。

Also applies to: 157-159, 388-388

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

131-131: 繁体中文翻译正确且一致。

"特殊設定"翻译已在所有三个位置正确添加,与其他语言环境的结构保持一致。

Also applies to: 157-159, 388-388

messages/ja/dashboard.json (1)

131-131: 日文翻译正确且结构一致。

"特殊設定"翻译已在所有三个位置正确添加,与其他语言环境保持一致。

Also applies to: 157-159, 387-387

drizzle/0049_shocking_ultimatum.sql (1)

1-1: 数据库迁移正确使用了 jsonb 类型。

列定义遵循 snake_case 命名约定,使用 jsonb 类型符合项目对灵活数据结构的使用模式。现有行的该字段值将为 NULL,这对于可选的审计字段来说是可以接受的。

messages/zh-CN/dashboard.json (2)

131-131: 简体中文翻译正确且一致。

"特殊设置"翻译已在所有三个位置正确添加:日志表格列(line 131)、日志详情嵌套对象(lines 157-159)和会话详情(line 388)。结构与其他语言环境保持一致。

Also applies to: 157-159, 388-388


131-131: 俄语(ru)语言环境文件已正确更新。messages/ru/dashboard.json 包含了所有必需的 "specialSettings" 翻译,位置与其他语言环境一致(第 131 行、157 行和 387 行)。无需进一步操作。

drizzle/meta/_journal.json (1)

348-354: LGTM!迁移日志条目格式正确。

新增的迁移条目格式符合 Drizzle ORM 规范,包含了所有必需字段(idx、version、when、tag、breakpoints)。

src/app/v1/_lib/proxy/session.ts (3)

12-12: LGTM!类型导入正确。

使用了路径别名 @/ 引用类型定义,符合项目编码规范。


98-100: LGTM!字段封装良好。

私有字段 specialSettings 的实现符合类设计原则,初始化为空数组确保了类型安全。注释清晰说明了用途和可扩展性。


271-278: LGTM!方法实现简洁且一致。

两个公共方法的实现符合类的设计模式:

  • addSpecialSetting() 提供了简单的追加操作
  • getSpecialSettings() 对空数组返回 null,与类中其他类似方法(如 getCacheTtlResolved())的模式保持一致
src/drizzle/schema.ts (2)

16-16: LGTM!类型导入符合规范。

使用路径别名 @/ 引用类型定义,遵循项目编码标准。


321-322: LGTM!数据库架构设计合理。

新字段 specialSettings 的实现符合最佳实践:

  • 使用 JSONB 类型存储灵活的结构化数据,符合项目编码指南
  • 字段可空,保证向后兼容性
  • 使用 $type<SpecialSetting[]>() 确保类型安全
  • 注释清晰说明了审计与展示用途

基于 learnings,这种灵活的 JSON 列存储模式符合项目在 modelRedirectsproviderChain 等字段的使用惯例。

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

136-136: LGTM!转换器实现一致且类型安全。

specialSettings 字段的处理遵循了文件中的既定模式:

  • 使用可选链式调用(?.)安全访问数据库字段
  • 使用空值合并运算符(??)设置默认值为 null
  • 与其他可空字段(如 cacheTtlApplied)的处理方式保持一致

基于 learnings,此处使用 null 表示"明确无特殊设置"的语义是恰当的,与数据库架构和 ProxySession.getSpecialSettings() 的返回约定相符。

src/types/special-settings.ts (2)

1-8: LGTM!类型定义设计良好,具有良好的扩展性。

文档注释清晰说明了特殊设置的用途和应用场景。类型别名 SpecialSetting 的设计允许未来轻松扩展为联合类型(如 Type1 | Type2 | Type3),而无需修改使用方代码,体现了良好的前瞻性设计。


10-10: LGTM!变更值类型定义合理。

SpecialSettingChangeValue 联合类型涵盖了参数覆写场景中常见的值类型(字符串、数字、布尔值及空值),在保证类型安全的同时提供了足够的灵活性。

src/types/message.ts (1)

3-3: 类型定义规范且一致。

新增的 specialSettings 字段类型定义符合规范:

  • 使用 SpecialSetting[] | null 明确区分 null(显式设置)与 undefined(未设置)的语义
  • 在公共接口 MessageRequest 和数据库写入类型 CreateMessageRequestData 中保持一致
  • 注释清晰说明了字段用途(审计与展示)

基于 learnings,类型定义遵循了最佳实践,明确区分 null 和 undefined 的语义。

Also applies to: 230-231, 288-289

src/repository/usage-logs.ts (1)

7-7: 数据查询集成正确。

specialSettings 字段已正确集成到使用日志的数据检索路径:

  • UsageLogRow 类型中声明,与 MessageRequest 接口保持一致
  • 在批量查询(findUsageLogsBatch)和详细查询(findUsageLogsWithDetails)中均包含该字段
  • 作为 JSONB 字段直接传递,无需额外转换

实现符合仓储层的数据访问模式。

Also applies to: 60-60, 218-218, 432-432

src/repository/message-write-buffer.ts (1)

29-29: 批量写入逻辑正确。

specialSettings 字段已正确集成到异步写入缓冲区:

  • 类型引用 CreateMessageRequestData["special_settings"] 保证与数据模型一致
  • COLUMN_MAP 中正确映射为数据库列名 special_settings
  • 在 SQL 构建逻辑中与 providerChain 采用相同的 JSONB 处理方式(null 显式处理、JSON 序列化)

实现遵循了现有的 JSONB 字段处理模式。

Also applies to: 62-62, 104-112

src/app/[locale]/dashboard/logs/_components/usage-logs-table.tsx (2)

497-497: props 传递正确。

specialSettings 已正确传递给 ErrorDetailsDialog 组件,与其他日志字段保持一致的数据流。


237-244: 特殊设置徽章逻辑清晰且实现正确。

条件判断包含存在性和长度检查,防御性强;徽章样式与其他内联标识(如 cacheTtlApplied)保持一致;使用 shrink-0 防止在紧凑布局中被压缩。实现符合现有的徽章模式。

翻译键 logs.table.specialSettings 已在所有 5 个语言包中定义:en、ja、ru、zh-CN、zh-TW。

src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-messages-client.tsx (2)

63-69: 会话详情数据流集成正确。

specialSettings 状态管理遵循了现有模式:

  • 使用类型提取确保与 getSessionDetails 返回类型同步
  • resetDetailsState 中正确重置为 null
  • 从服务端响应中提取并设置状态

类型安全且与其他会话字段保持一致。

Also applies to: 100-100, 145-145


185-185: 导出和组件传递实现完整。

specialSettings 已正确集成到数据导出和组件传递链路:

  • 包含在请求导出 JSON 中,便于审计和问题排查
  • 传递给 SessionMessagesDetailsTabs 组件,支持 UI 展示

数据流完整,支持特殊设置的端到端追踪。

Also applies to: 386-386

src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-messages-client.test.tsx (2)

19-19: LGTM!测试数据和属性更新正确

所有测试用例都正确地传递了新的 specialSettings={null} 属性,且翻译键的命名遵循了现有模式。

Also applies to: 92-92, 154-154, 181-181, 216-216, 268-268


198-202: LGTM!特殊设置标签页的测试覆盖恰当

测试逻辑清晰,验证了标签页的渲染和空状态显示,符合文件中其他标签页测试的模式。

src/app/[locale]/dashboard/logs/_components/error-details-dialog.tsx (3)

31-31: LGTM!类型定义准确

SpecialSetting 类型导入正确,属性定义为可选且可空(SpecialSetting[] | null)符合审计数据可能缺失的业务场景。

Also applies to: 48-48


81-81: LGTM!数据处理逻辑清晰

属性解构和 JSON 格式化逻辑简洁明了,正确处理了空数组的情况。

Also applies to: 120-121


421-431: LGTM!UI 渲染实现恰当

特殊设置部分的 UI 渲染遵循了对话框中其他部分的一致模式,条件渲染逻辑正确,JSON 格式展示清晰易读。

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

2-5: LGTM!导入语句正确

新增的 applyCodexProviderOverridesWithAudit 函数导入正确,保持了原有函数的导入。


128-230: LGTM!审计功能测试覆盖全面

四个测试用例系统地验证了审计功能的各种场景:

  • ✅ 非 Codex 提供商返回 audit=null
  • ✅ 无有效偏好设置返回 audit=null
  • ✅ 偏好命中但值未变化时的审计记录(changed=false
  • ✅ 偏好命中且值变化时的完整变更明细

测试断言详尽,边界情况覆盖到位,为审计功能提供了可靠的质量保障。

src/actions/active-sessions.ts (2)

13-13: LGTM!类型定义准确且一致

SpecialSetting 类型导入正确,返回类型中的 specialSettings: SpecialSetting[] | null 与整个代码库中的类型定义保持一致。

Also applies to: 522-522


621-621: LGTM!数据获取逻辑集成恰当

特殊设置数据已正确集成到现有的并行数据获取流程中:

  • ✅ 使用 Promise.all 并行获取,保持性能优化
  • ✅ 调用 SessionManager.getSessionSpecialSettings API 正确
  • ✅ 数据流清晰,遵循文件中的现有模式

Also applies to: 631-631, 659-659

messages/ru/dashboard.json (1)

131-131: 所有翻译键在 5 个语言环境中均已完整存在。验证显示 logs.table.specialSettingslogs.details.specialSettings.titlesessions.details.specialSettings 都在所有 5 个语言环境(en、ja、ru、zh-CN、zh-TW)的 dashboard.json 中都有相应的翻译。不需要进一步操作。

Likely an incorrect or invalid review comment.

src/app/[locale]/dashboard/sessions/[sessionId]/messages/_components/session-details-tabs.tsx (1)

32-41: 特殊设置 Tab 的数据流和展示逻辑是连贯的

新增 specialSettings prop、specialSettingsContent 的 memo 以及对应的 TabsTrigger/TabsContent,与 requestBody/requestMessages 分支保持了一致的数据流和 UX,用 CodeDisplay 以 JSON 展示、无数据时回退到 noData,实现上没有明显问题。需要注意的一点是:调用方要始终显式传入 null 或实际值,而不要省略这个 prop,以避免在极端情况下出现 specialSettings === undefined 导致 content 变成 undefined 的潜在 runtime 边界情况。

Also applies to: 43-52, 66-70, 120-141, 194-210

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

12-20: Codex 覆写审计与 Session/DB 持久化集成合理

在 Codex 分支中使用 applyCodexProviderOverridesWithAudit 得到覆写后的 request 与 audit,再通过 session.addSpecialSetting 聚合到会话级别,并分别写入 Redis(storeSessionSpecialSettings)和 Postgres(updateMessageRequestDetailsspecialSettings 字段),且这两处都是 best-effort、失败仅记录 error 日志不影响主请求流程,整体逻辑和容错策略是稳妥的。

Also applies to: 996-1031

drizzle/meta/0049_snapshot.json (1)

1-2338: Drizzle 元数据快照中新增 special_settings 列与代码保持一致

快照里的 message_request.special_settings jsonb(可为 NULL、无额外索引)与 Drizzle schema / CreateMessageRequestData["special_settings"] 的设计相符,这个文件属于自动生成的元数据,不需要手工调整。

src/repository/message.ts (1)

116-200: specialSettings 的 null/undefined 语义处理良好,避免了意外覆盖

updateMessageRequestDetails 中为 details 新增了可选的 specialSettings 字段,并且只在 details.specialSettings !== undefined 时才写入 updateData.specialSettings,使得:undefined 表示“不更新列”,而 null 或数组则分别表示“清空列”或“写入审计数组”,这与 CreateMessageRequestData["special_settings"] 以及全局对 null/undefined 区分语义的约定是一致的,接口向后兼容性也保持良好。Based on learnings, 这种做法有利于后续在 UI/统计层准确区分“未设置”和“显式无特殊设置”。

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

7-17: applyCodexProviderOverridesWithAudit 的审计建模与覆写逻辑解耦良好

通过新增 toAuditValue 只记录原子值,并在调用既有 applyCodexProviderOverrides 前后采样 parallel_tool_callsreasoning.effort/summarytext.verbosity,再用 Object.is 判定各 path 的变化,构造出带 hit/changed 语义的 ProviderParameterOverrideSpecialSetting,整体审计模型清晰且与具体覆写逻辑解耦。CodexProviderOverrideConfig 增补的 id/name 也为审计记录提供了重要上下文;对 providerType !== "codex" 或所有偏好为 inherit 的情况统一返回 { request, audit: null },边界处理到位。

Also applies to: 23-29, 103-183

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

No files reviewed, no comments

Edit Code Review Agent Settings | Greptile

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 adds comprehensive audit tracking for provider-level parameter overrides in Codex requests. The implementation properly tracks when vendor-level settings override client parameters and records detailed before/after change information. The code is well-structured, follows existing patterns, and includes comprehensive test coverage.

PR Size: XL

  • Lines changed: ~2800 additions, 5 deletions
  • Files changed: 26

Split Suggestions for future similar features:

  1. Core audit logic (provider-overrides.ts, types, tests) could be a standalone PR
  2. Database/persistence layer (session-manager.ts, message.ts, schema) as a second PR
  3. UI components and i18n as a third PR

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
  • Security (OWASP Top 10) - Clean
  • Error handling - Clean (proper .catch() handlers for fire-and-forget promises)
  • Type safety - Clean (proper TypeScript throughout)
  • Documentation accuracy - Clean
  • Test coverage - Adequate (11 new test cases cover audit functionality)
  • Code clarity - Good

Detailed Analysis

Positive Observations (not commenting per instructions, but for context):

  • Error handling uses the established void ... .catch() pattern consistently
  • The Object.is() comparison for change detection handles edge cases correctly
  • The SpecialSetting union type is extensible for future audit types
  • Test coverage is comprehensive with edge cases covered
  • i18n translations added for all 5 locales

No Issues Identified:
After thorough validation through the 6 review perspectives:

  1. Silent Failure Hunter: All async operations use .catch() with proper logging
  2. Type Design Auditor: No any types, proper null handling
  3. Test Analyzer: Critical paths covered with 11 new test cases
  4. Comment Analyzer: Comments are accurate and match implementation
  5. General Code Reviewer: No logic bugs, security issues, or standard violations detected
  6. Code Simplifier: Code is appropriately complex for the feature

The implementation follows the codebase's established patterns for:

  • Redis storage with TTL
  • Database persistence via write buffers
  • UI component composition
  • i18n message structure

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

Reviewed the new specialSettings auditing flow end-to-end (capture in proxy forwarder, persist to Redis/DB, and display in Usage Logs + Session details). No high-confidence defects found in the added/modified lines.

PR Size: XL

  • Lines changed: 2807 (2802 additions, 5 deletions)
  • Files changed: 26
  • Split suggestions: consider separating into (1) DB migration/schema + repository plumbing, (2) proxy/session capture & persistence, (3) dashboard UI + i18n + 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 #557 and pulled full metadata + diff for review.
  • Applied the PR size label: size/XL (2807 lines changed across 26 files).
  • Completed a 6‑perspective diff-only review (logic, security, error handling, types, comments/docs, tests, simplification) and found no issues in added/modified lines that met the reporting confidence threshold.
  • Posted the required PR review summary via gh pr review --comment (includes split suggestions appropriate for an XL PR).

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

Labels

area:i18n area:session area:UI 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