Skip to content

feat: add thinking signature recovery#540

Closed
ding113 wants to merge 1 commit intodevfrom
feature/thinking-signature-fix
Closed

feat: add thinking signature recovery#540
ding113 wants to merge 1 commit intodevfrom
feature/thinking-signature-fix

Conversation

@ding113
Copy link
Owner

@ding113 ding113 commented Jan 5, 2026

Summary

Adds an optional thinking signature recovery mechanism that automatically strips thinking/redacted_thinking blocks from requests and retries when upstream providers return 4xx/5xx errors related to signature incompatibility. This prevents sessions from entering unrecoverable error loops when switching between different provider types.

Problem

Related Issues:

When users switch between Anthropic and non-Anthropic providers (e.g., AWS Bedrock), the thinking blocks may contain signatures that are incompatible with the target provider. This results in errors like:

  • Invalid \signature` in `thinking` block`
  • thinking blocks cannot be modified

Previously, these errors would cause the session to enter an unrecoverable 4xx/5xx error loop. PR #519 added an error rule to provide better error messages, but this PR goes further by implementing automatic recovery.

Solution

  1. System Setting Toggle (enableThinkingSignatureFix): Disabled by default to ensure opt-in behavior
  2. Error Detection: Pattern matching for thinking/signature related errors via isThinkingSignatureRelatedError()
  3. Request Sanitization: sanitizeClaudeMessagesRequestThinkingBlocks() removes only thinking/redacted_thinking content blocks
  4. Automatic Retry: When an error matches the pattern and the request contains thinking blocks, CCH strips them and retries once
  5. Exclusion Logic: Does not retry for 401/402/403/404/429 to avoid masking auth/quota/rate-limit issues
  6. Audit Trail: Records thinking_signature_fix_applied and thinking_signature_fix_reason for observability

Changes

Core Changes

  • src/app/v1/_lib/proxy/thinking-signature-recovery.ts - New module for error detection and request sanitization
  • src/app/v1/_lib/proxy/forwarder.ts - Integrates recovery logic into the proxy pipeline
  • src/app/v1/_lib/proxy/session.ts - Adds state tracking for fix application
  • src/app/v1/_lib/proxy/response-handler.ts - Writes audit fields on response completion
  • src/app/v1/_lib/proxy/error-handler.ts - Minor integration updates

Database Migration

  • drizzle/0047_mute_joystick.sql - Adds three columns:
    • message_request.thinking_signature_fix_applied (boolean)
    • message_request.thinking_signature_fix_reason (text)
    • system_settings.enable_thinking_signature_fix (boolean)

Configuration & UI

  • src/lib/config/system-settings-cache.ts - Exports isThinkingSignatureFixEnabled()
  • src/lib/validation/schemas.ts - Adds schema validation for new setting
  • src/actions/system-config.ts - Server action updates
  • src/app/[locale]/settings/config/_components/system-settings-form.tsx - Toggle in settings UI
  • src/app/[locale]/dashboard/logs/_components/usage-logs-table.tsx - "Fix" badge in logs view

i18n

  • Added translations for all 5 locales (en, ja, ru, zh-CN, zh-TW) in messages/*/settings.json and messages/*/dashboard.json

Tests

  • tests/unit/proxy/thinking-signature-recovery.test.ts - Core detection/sanitization logic
  • tests/unit/proxy/proxy-forwarder-thinking-signature-recovery.test.ts - Integration tests
  • tests/unit/repository/message-write-buffer.test.ts - Audit field persistence
  • tests/unit/repository/usage-logs-thinking-signature-fix-columns.test.ts - Query/display tests
  • tests/unit/dashboard-logs-thinking-signature-fix-ui.test.tsx - UI component tests
  • tests/unit/validation/system-settings-thinking-signature-fix-schema.test.ts - Schema validation

Breaking Changes

None. The feature is disabled by default and must be explicitly enabled in system settings.

Testing

Automated Tests

  • Unit tests for error detection patterns
  • Unit tests for request sanitization
  • Integration tests for retry logic
  • UI component tests
  • Schema validation tests

Manual Testing

  1. Enable the setting in System Settings → "Enable Thinking Signature Fix"
  2. Trigger a multi-provider session where thinking blocks cause signature errors
  3. Verify the "Fix" badge appears in Dashboard → Logs for affected requests
  4. Check audit fields in database for tracking

Checklist

  • Code follows project conventions
  • Self-review completed
  • Tests pass locally (bun run test, bun run test:coverage:thinking-signature-fix)
  • TypeScript check passes (bun run typecheck)
  • Linting passes (bun run lint)
  • Build succeeds (bun run build)
  • Database migration included

Description enhanced by Claude AI

@coderabbitai
Copy link

coderabbitai bot commented Jan 5, 2026

📝 Walkthrough

Walkthrough

实现了一个思考签名修复特性,允许系统在上游返回 4xx/5xx 错误且请求包含思考/签名块时,移除这些块并重试,同时提供可配置的全局开关和审计日志追踪。

Changes

分组 / 文件 变更描述
数据库迁移
drizzle/0047_mute_joystick.sql, drizzle/meta/0047_snapshot.json, drizzle/meta/_journal.json
添加三个新列:message_request.thinking_signature_fix_appliedmessage_request.thinking_signature_fix_reasonsystem_settings.enable_thinking_signature_fix;新增 JSON 架构快照和数据库版本日志条目。
国际化配置
messages/en/dashboard.json, messages/en/settings.json, messages/ja/..., messages/ru/..., messages/zh-CN/..., messages/zh-TW/...
在多种语言中添加翻译键 thinkingSignatureFixenableThinkingSignatureFixenableThinkingSignatureFixDesc,用于仪表板日志表列和设置配置标签。
系统配置和验证
src/types/system-config.ts, src/lib/config/system-settings-cache.ts, src/lib/config/index.ts, src/lib/validation/schemas.ts, src/repository/system-config.ts, src/repository/_shared/transformers.ts
添加 enableThinkingSignatureFix 字段到系统设置类型、默认配置、验证模式和存储库读写流程;新增 isThinkingSignatureFixEnabled() 辅助函数。
设置表单和页面
src/actions/system-config.ts, src/app/[locale]/settings/config/_components/system-settings-form.tsx, src/app/[locale]/settings/config/page.tsx, src/app/api/admin/system-config/route.ts
扩展系统设置表单提交流程,添加 enableThinkingSignatureFix 字段的验证、传播和 UI 开关控件;扩展 API 端点以接收新字段。
数据库架构和消息持久化
src/drizzle/schema.ts, src/repository/message.ts, src/repository/message-write-buffer.ts, src/repository/usage-logs.ts
messageRequestsystemSettings 表的 Drizzle 架构中添加新列定义;扩展消息更新接口和批写入映射以支持思考签名审计字段;在使用日志查询中选择新字段。
代理层实现
src/app/v1/_lib/proxy/thinking-signature-recovery.ts, src/app/v1/_lib/proxy/session.ts, src/app/v1/_lib/proxy/forwarder.ts, src/app/v1/_lib/proxy/error-handler.ts, src/app/v1/_lib/proxy/response-handler.ts
实现思考块检测和清理逻辑(isThinkingSignatureRelatedErrorsanitizeClaudeMessagesRequestThinkingBlocks);在代理会话中添加审计状态跟踪;在转发器中集成条件重试机制;在错误和响应处理器中记录审计补丁。
UI 和显示
src/app/[locale]/dashboard/logs/_components/usage-logs-table.tsx
log.thinkingSignatureFixApplied 为真时,在使用日志表中渲染一个紫色主题的 Badge,显示"Fix"标签。
测试
tests/unit/proxy/thinking-signature-recovery.test.ts, tests/unit/proxy/proxy-forwarder-thinking-signature-recovery.test.ts, tests/unit/dashboard-logs-thinking-signature-fix-ui.test.tsx, tests/unit/repository/message-write-buffer.test.ts, tests/unit/repository/usage-logs-thinking-signature-fix-columns.test.ts, tests/unit/validation/system-settings-thinking-signature-fix-schema.test.ts, tests/setup.ts (间接), vitest.thinking-signature-fix.config.ts
为思考块检测、清理、代理转发器重试流程、UI 渲染、数据库字段映射、验证模式和使用日志查询添加单元测试;新增专用 Vitest 配置文件和 npm 脚本用于覆盖率报告。
配置和环境
.gitignore, package.json
添加覆盖率目录忽略规则;添加 test:coverage:thinking-signature-fix npm 脚本。

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 55.56% 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 标题'feat: add thinking signature recovery'清晰地总结了本PR的主要改动——添加思维签名恢复功能,与实际变更(新增系统设置开关、自动移除thinking块并重试、审计日志等)高度相关。
Description check ✅ Passed PR描述详尽地说明了背景、具体改动、数据库迁移和验证方式,与提供的变更摘要完全相关,包含系统设置、重试逻辑、审计字段、UI标记等所有关键内容。
✨ 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 feature/thinking-signature-fix

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

@gemini-code-assist
Copy link
Contributor

Summary of Changes

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

This pull request addresses a common issue of 'thinking signature' incompatibility errors that can arise when interacting with various AI providers, particularly during provider switching. It introduces a robust, configurable recovery mechanism that automatically attempts to fix these errors by sanitizing request bodies and retrying failed requests. This enhancement aims to improve session stability and prevent unrecoverable error loops, while also providing clear audit trails for transparency and debugging.

Highlights

  • Thinking Signature Recovery Mechanism: Introduced a new feature to automatically recover from 'thinking signature' incompatibility errors from upstream providers. When enabled, if a 4xx/5xx error (excluding specific authentication/rate-limit codes) occurs and the request body contains 'thinking' or 'redacted_thinking' blocks, the system will strip these blocks and retry the request once.
  • New System Setting: Added a new system setting, enableThinkingSignatureFix, which is disabled by default. This allows administrators to control whether this recovery mechanism is active.
  • Audit Logging and UI Integration: Implemented audit fields (thinking_signature_fix_applied and thinking_signature_fix_reason) in the message_request table to track when the fix is applied. A 'Fix' badge will also be displayed in the Dashboard logs for affected requests.
  • Database Schema Updates: New columns have been added to the message_request table (thinking_signature_fix_applied, thinking_signature_fix_reason) and the system_settings table (enable_thinking_signature_fix) to support the new feature and its auditing.
  • Comprehensive Testing: New unit tests and a dedicated Vitest coverage configuration (vitest.thinking-signature-fix.config.ts) have been added to ensure the reliability and stability of the thinking signature recovery logic.
Using Gemini Code Assist

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

Invoking Gemini

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

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

Customization

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

Limitations & Feedback

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

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

Footnotes

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

@github-actions
Copy link
Contributor

github-actions bot commented Jan 5, 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 新增了 thinking signature 恢复功能,这是一个非常实用的容错增强。当上游服务因为 thinking 块签名不兼容而返回错误时,系统会自动移除相关内容并重试一次,从而避免会话中断。

整体实现非常完整,涵盖了数据库结构变更、核心代理逻辑、UI 展示和相关配置,并且为这个关键功能增加了专门的单元测试和覆盖率检查,这是一个很好的实践。核心的恢复逻辑设计得很周全,特别是排除了认证、配额等状态码,避免了掩盖其他重要问题。

我提出了一些建议以进一步提升代码质量:

  1. forwarder.ts 中复杂的重试逻辑提取为独立方法,以提高代码的可读性。
  2. 在重试逻辑中为 JSON 解析失败的情况添加日志,以便于未来问题诊断。

总的来说,这是一个高质量的 PR,很好地解决了实际问题。

});

// 可选:对 thinking/signature 相关 400 做一次最小降级重试,避免会话进入不可恢复错误循环
try {
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

thinking signature 恢复的重试逻辑(1654-1771行)非常复杂,目前嵌套在 doForward 方法中,使得该方法变得冗长且难以阅读。为了提高代码的可读性和可维护性,建议将这部分逻辑提取到一个独立的私有方法中,例如 _tryThinkingSignatureRecovery(proxyError, provider, init, session, ...)

Comment on lines +1659 to +1663
try {
parsedBody = JSON.parse(init.body);
} catch {
parsedBody = null;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

thinking signature 恢复逻辑中,如果 JSON.parse(init.body) 失败,parsedBody 会被设为 null,然后静默地跳过整个恢复流程。虽然这种处理是安全的,但如果 init.body 是一个字符串但不是有效的 JSON,这通常是一个预期之外的状态。建议在 catch 块中增加一个 debugwarn 级别的日志,记录 JSON 解析失败的情况,以便于未来诊断类似问题。

          try {
            parsedBody = JSON.parse(init.body);
          } catch (e) {
            logger.debug("[ThinkingSignatureFix] Failed to parse request body as JSON", {
              providerId: provider.id,
              providerName: provider.name,
              error: e instanceof Error ? e.message : String(e),
            });
            parsedBody = null;
          }

@github-actions github-actions bot added the size/XL Extra Large PR (> 1000 lines) label Jan 5, 2026
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 (7)
messages/ru/dashboard.json (1)

131-131: “Fix” 是否需要在俄语环境下本地化?

logs.table.thinkingSignatureFix 当前值为英文 "Fix",在俄语界面中略显突兀。如果产品设计希望跨语言统一使用英文短 Badge,这样保持即可;否则可以考虑改成简短俄语(例如 “Фикс” 或更贴切的动词),与其他列标题风格更一致。

messages/ja/dashboard.json (1)

131-131: 日语 locale 下 “Fix” 的文案风格确认

这里 logs.table.thinkingSignatureFix 使用英文 "Fix",在日文界面中会有一点风格不统一。若设计上刻意统一使用英文 Badge 文案(方便跨语言识别),保持现状即可;若追求完全本地化,可考虑换成简短日文(例如「修正」等)以与表格其他列标题风格一致。

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

131-131: 可读性:考虑将标签从「修复」改为更具体表述

当前 "thinkingSignatureFix": "修复" 在表格中是可读的,但略显笼统;如果希望后续与其他可能的“修复”含义区分,可以考虑改为「签名修复」之类更具体的文案,以便一眼看出含义。

可选文案调整示例
-      "thinkingSignatureFix": "修复",
+      "thinkingSignatureFix": "签名修复",
tests/unit/dashboard-logs-thinking-signature-fix-ui.test.tsx (1)

5-103: UsageLogsTable “Fix” 标记单测逻辑清晰完备

这段测试正确构造了包含 thinkingSignatureFixAppliedUsageLogRow,通过 NextIntlClientProvider 注入真实文案,最后断言渲染文本包含 "Fix",很好地保护了仪表盘日志中修复标记的 UI 行为。若后续还有类似日志用例,可以考虑提取一个构造 UsageLogRow 的测试工厂方法,减少重复样板数据。

tests/unit/validation/system-settings-thinking-signature-fix-schema.test.ts (1)

1-15: Schema 测试有效防止漏声明 enableThinkingSignatureFix 字段

这里不仅校验了 safeParse 成功,还额外断言返回数据里确实包含 enableThinkingSignatureFix: true,可以防止 Zod 将未知字段静默剥离导致“误通过”,很好地锁定了系统设置 schema 对该开关字段的约束。后续如果想更严格,可以再补一条传入非布尔值应失败的用例,但当前测试已满足主要需求。

tests/unit/proxy/thinking-signature-recovery.test.ts (1)

52-106: 消息清理测试实现正确。

测试用例覆盖了主要场景:

  • 正确移除 thinkingredacted_thinking 块,保留其他类型
  • 验证 changed 标志和 removedBlocks 计数
  • 安全处理非 Claude 消息结构
  • 正确处理字符串类型的 content

可以考虑添加以下边缘场景的测试(可选):

  • messages 数组
  • 移除所有块后 content 为空数组的消息
🔎 可选测试用例示例
it("应正确处理空 messages 数组", () => {
  const input = { model: "claude-sonnet", messages: [] };
  const result = sanitizeClaudeMessagesRequestThinkingBlocks(input);
  expect(result.changed).toBe(false);
  expect(result.sanitized).toBe(input);
});

it("应正确处理移除后 content 为空的情况", () => {
  const input = {
    model: "claude-sonnet",
    messages: [
      { role: "assistant", content: [{ type: "thinking", thinking: "test" }] },
    ],
  };
  const result = sanitizeClaudeMessagesRequestThinkingBlocks(input);
  expect(result.changed).toBe(true);
  expect(result.removedBlocks).toBe(1);
  const messages = result.sanitized.messages as any[];
  expect(messages[0].content).toEqual([]);
});
src/app/v1/_lib/proxy/session.ts (1)

262-281: 可选:简化冗余的防御性包装。

Boolean() 包装和 ?? null 在这里是冗余的,因为字段已经有正确的类型和初始值。不过这不影响功能,仅是代码风格建议。

🔎 建议的简化
  getThinkingSignatureFixApplied(): boolean {
-   return Boolean(this.thinkingSignatureFixApplied);
+   return this.thinkingSignatureFixApplied;
  }

  getThinkingSignatureFixReason(): string | null {
-   return this.thinkingSignatureFixReason ?? null;
+   return this.thinkingSignatureFixReason;
  }
📜 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 6ab0c9d and d89f06a.

📒 Files selected for processing (42)
  • .gitignore
  • drizzle/0047_mute_joystick.sql
  • drizzle/meta/0047_snapshot.json
  • drizzle/meta/_journal.json
  • messages/en/dashboard.json
  • messages/en/settings.json
  • messages/ja/dashboard.json
  • messages/ja/settings.json
  • messages/ru/dashboard.json
  • messages/ru/settings.json
  • messages/zh-CN/dashboard.json
  • messages/zh-CN/settings.json
  • messages/zh-TW/dashboard.json
  • messages/zh-TW/settings.json
  • package.json
  • src/actions/system-config.ts
  • src/app/[locale]/dashboard/logs/_components/usage-logs-table.tsx
  • src/app/[locale]/settings/config/_components/system-settings-form.tsx
  • src/app/[locale]/settings/config/page.tsx
  • src/app/api/admin/system-config/route.ts
  • src/app/v1/_lib/proxy/error-handler.ts
  • src/app/v1/_lib/proxy/forwarder.ts
  • src/app/v1/_lib/proxy/response-handler.ts
  • src/app/v1/_lib/proxy/session.ts
  • src/app/v1/_lib/proxy/thinking-signature-recovery.ts
  • src/drizzle/schema.ts
  • src/lib/config/index.ts
  • src/lib/config/system-settings-cache.ts
  • src/lib/validation/schemas.ts
  • src/repository/_shared/transformers.ts
  • src/repository/message-write-buffer.ts
  • src/repository/message.ts
  • src/repository/system-config.ts
  • src/repository/usage-logs.ts
  • src/types/system-config.ts
  • tests/unit/dashboard-logs-thinking-signature-fix-ui.test.tsx
  • tests/unit/proxy/proxy-forwarder-thinking-signature-recovery.test.ts
  • tests/unit/proxy/thinking-signature-recovery.test.ts
  • tests/unit/repository/message-write-buffer.test.ts
  • tests/unit/repository/usage-logs-thinking-signature-fix-columns.test.ts
  • tests/unit/validation/system-settings-thinking-signature-fix-schema.test.ts
  • vitest.thinking-signature-fix.config.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:

  • package.json
  • src/types/system-config.ts
  • drizzle/meta/_journal.json
  • messages/en/dashboard.json
  • messages/zh-CN/settings.json
  • src/lib/config/index.ts
  • src/repository/message-write-buffer.ts
  • src/app/[locale]/settings/config/page.tsx
  • tests/unit/repository/usage-logs-thinking-signature-fix-columns.test.ts
  • messages/ja/settings.json
  • messages/ru/settings.json
  • messages/zh-TW/dashboard.json
  • src/repository/message.ts
  • src/app/[locale]/dashboard/logs/_components/usage-logs-table.tsx
  • messages/zh-CN/dashboard.json
  • tests/unit/proxy/thinking-signature-recovery.test.ts
  • messages/zh-TW/settings.json
  • src/repository/system-config.ts
  • src/app/v1/_lib/proxy/thinking-signature-recovery.ts
  • messages/ja/dashboard.json
  • src/repository/usage-logs.ts
  • src/actions/system-config.ts
  • src/lib/validation/schemas.ts
  • src/app/api/admin/system-config/route.ts
  • vitest.thinking-signature-fix.config.ts
  • src/app/v1/_lib/proxy/session.ts
  • tests/unit/proxy/proxy-forwarder-thinking-signature-recovery.test.ts
  • src/app/v1/_lib/proxy/error-handler.ts
  • src/app/v1/_lib/proxy/response-handler.ts
  • tests/unit/validation/system-settings-thinking-signature-fix-schema.test.ts
  • src/lib/config/system-settings-cache.ts
  • tests/unit/repository/message-write-buffer.test.ts
  • messages/en/settings.json
  • src/app/[locale]/settings/config/_components/system-settings-form.tsx
  • drizzle/meta/0047_snapshot.json
  • src/repository/_shared/transformers.ts
  • src/app/v1/_lib/proxy/forwarder.ts
  • src/drizzle/schema.ts
  • messages/ru/dashboard.json
  • tests/unit/dashboard-logs-thinking-signature-fix-ui.test.tsx
**/*.{tsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • package.json
  • drizzle/meta/_journal.json
  • messages/en/dashboard.json
  • messages/zh-CN/settings.json
  • src/app/[locale]/settings/config/page.tsx
  • messages/ja/settings.json
  • messages/ru/settings.json
  • messages/zh-TW/dashboard.json
  • src/app/[locale]/dashboard/logs/_components/usage-logs-table.tsx
  • messages/zh-CN/dashboard.json
  • messages/zh-TW/settings.json
  • messages/ja/dashboard.json
  • messages/en/settings.json
  • src/app/[locale]/settings/config/_components/system-settings-form.tsx
  • drizzle/meta/0047_snapshot.json
  • messages/ru/dashboard.json
  • tests/unit/dashboard-logs-thinking-signature-fix-ui.test.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/types/system-config.ts
  • src/lib/config/index.ts
  • src/repository/message-write-buffer.ts
  • src/app/[locale]/settings/config/page.tsx
  • tests/unit/repository/usage-logs-thinking-signature-fix-columns.test.ts
  • src/repository/message.ts
  • src/app/[locale]/dashboard/logs/_components/usage-logs-table.tsx
  • tests/unit/proxy/thinking-signature-recovery.test.ts
  • src/repository/system-config.ts
  • src/app/v1/_lib/proxy/thinking-signature-recovery.ts
  • src/repository/usage-logs.ts
  • src/actions/system-config.ts
  • src/lib/validation/schemas.ts
  • src/app/api/admin/system-config/route.ts
  • vitest.thinking-signature-fix.config.ts
  • src/app/v1/_lib/proxy/session.ts
  • tests/unit/proxy/proxy-forwarder-thinking-signature-recovery.test.ts
  • src/app/v1/_lib/proxy/error-handler.ts
  • src/app/v1/_lib/proxy/response-handler.ts
  • tests/unit/validation/system-settings-thinking-signature-fix-schema.test.ts
  • src/lib/config/system-settings-cache.ts
  • tests/unit/repository/message-write-buffer.test.ts
  • src/app/[locale]/settings/config/_components/system-settings-form.tsx
  • src/repository/_shared/transformers.ts
  • src/app/v1/_lib/proxy/forwarder.ts
  • src/drizzle/schema.ts
  • tests/unit/dashboard-logs-thinking-signature-fix-ui.test.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/types/system-config.ts
  • src/lib/config/index.ts
  • src/repository/message-write-buffer.ts
  • src/app/[locale]/settings/config/page.tsx
  • tests/unit/repository/usage-logs-thinking-signature-fix-columns.test.ts
  • src/repository/message.ts
  • src/app/[locale]/dashboard/logs/_components/usage-logs-table.tsx
  • tests/unit/proxy/thinking-signature-recovery.test.ts
  • src/repository/system-config.ts
  • src/app/v1/_lib/proxy/thinking-signature-recovery.ts
  • src/repository/usage-logs.ts
  • src/actions/system-config.ts
  • src/lib/validation/schemas.ts
  • src/app/api/admin/system-config/route.ts
  • vitest.thinking-signature-fix.config.ts
  • src/app/v1/_lib/proxy/session.ts
  • tests/unit/proxy/proxy-forwarder-thinking-signature-recovery.test.ts
  • src/app/v1/_lib/proxy/error-handler.ts
  • src/app/v1/_lib/proxy/response-handler.ts
  • tests/unit/validation/system-settings-thinking-signature-fix-schema.test.ts
  • src/lib/config/system-settings-cache.ts
  • tests/unit/repository/message-write-buffer.test.ts
  • src/app/[locale]/settings/config/_components/system-settings-form.tsx
  • src/repository/_shared/transformers.ts
  • src/app/v1/_lib/proxy/forwarder.ts
  • src/drizzle/schema.ts
  • tests/unit/dashboard-logs-thinking-signature-fix-ui.test.tsx
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/types/system-config.ts
  • src/lib/config/index.ts
  • src/repository/message-write-buffer.ts
  • src/repository/message.ts
  • src/repository/system-config.ts
  • src/app/v1/_lib/proxy/thinking-signature-recovery.ts
  • src/repository/usage-logs.ts
  • src/actions/system-config.ts
  • src/lib/validation/schemas.ts
  • src/app/api/admin/system-config/route.ts
  • src/app/v1/_lib/proxy/session.ts
  • src/app/v1/_lib/proxy/error-handler.ts
  • src/app/v1/_lib/proxy/response-handler.ts
  • src/lib/config/system-settings-cache.ts
  • src/repository/_shared/transformers.ts
  • src/app/v1/_lib/proxy/forwarder.ts
  • 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/en/dashboard.json
  • messages/zh-CN/settings.json
  • messages/ja/settings.json
  • messages/ru/settings.json
  • messages/zh-TW/dashboard.json
  • messages/zh-CN/dashboard.json
  • messages/zh-TW/settings.json
  • messages/ja/dashboard.json
  • messages/en/settings.json
  • messages/ru/dashboard.json
src/lib/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use connection pooling for database and Redis connections

Files:

  • src/lib/config/index.ts
  • src/lib/validation/schemas.ts
  • src/lib/config/system-settings-cache.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/message.ts
  • src/repository/system-config.ts
  • src/repository/usage-logs.ts
  • src/repository/_shared/transformers.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/app/v1/_lib/proxy/response-handler.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/repository/message.ts
  • src/repository/system-config.ts
  • src/repository/usage-logs.ts
  • src/actions/system-config.ts
  • src/repository/_shared/transformers.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/config/page.tsx
  • src/app/[locale]/dashboard/logs/_components/usage-logs-table.tsx
  • src/app/[locale]/settings/config/_components/system-settings-form.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/repository/usage-logs-thinking-signature-fix-columns.test.ts
  • tests/unit/proxy/thinking-signature-recovery.test.ts
  • tests/unit/proxy/proxy-forwarder-thinking-signature-recovery.test.ts
  • tests/unit/validation/system-settings-thinking-signature-fix-schema.test.ts
  • tests/unit/repository/message-write-buffer.test.ts
  • tests/unit/dashboard-logs-thinking-signature-fix-ui.test.tsx
**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • tests/unit/repository/usage-logs-thinking-signature-fix-columns.test.ts
  • tests/unit/proxy/thinking-signature-recovery.test.ts
  • tests/unit/proxy/proxy-forwarder-thinking-signature-recovery.test.ts
  • tests/unit/validation/system-settings-thinking-signature-fix-schema.test.ts
  • tests/unit/repository/message-write-buffer.test.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/thinking-signature-recovery.ts
  • src/app/v1/_lib/proxy/session.ts
  • src/app/v1/_lib/proxy/error-handler.ts
  • src/app/v1/_lib/proxy/response-handler.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/thinking-signature-recovery.ts
  • src/app/v1/_lib/proxy/session.ts
  • src/app/v1/_lib/proxy/error-handler.ts
  • src/app/v1/_lib/proxy/response-handler.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/thinking-signature-recovery.ts
  • src/app/api/admin/system-config/route.ts
  • src/app/v1/_lib/proxy/session.ts
  • src/app/v1/_lib/proxy/error-handler.ts
  • src/app/v1/_lib/proxy/response-handler.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/thinking-signature-recovery.ts
  • src/app/v1/_lib/proxy/session.ts
  • src/app/v1/_lib/proxy/error-handler.ts
  • src/app/v1/_lib/proxy/response-handler.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/system-config.ts
src/app/api/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Implement health check endpoint returning database and Redis status

Files:

  • src/app/api/admin/system-config/route.ts
src/app/v1/_lib/proxy/*handler*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Stream responses with proper backpressure handling and chunked transfer encoding

Files:

  • src/app/v1/_lib/proxy/error-handler.ts
  • src/app/v1/_lib/proxy/response-handler.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
🧠 Learnings (19)
📚 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 **/*.test.{ts,tsx} : Use Vitest for unit testing with Node environment, coverage thresholds: 50% lines/functions, 40% branches

Applied to files:

  • package.json
  • tests/unit/repository/usage-logs-thinking-signature-fix-columns.test.ts
  • vitest.thinking-signature-fix.config.ts
  • .gitignore
  • tests/unit/dashboard-logs-thinking-signature-fix-ui.test.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 **/*.test.ts : Ensure test database names contain 'test' keyword for safety validation

Applied to files:

  • package.json
  • tests/unit/repository/usage-logs-thinking-signature-fix-columns.test.ts
  • vitest.thinking-signature-fix.config.ts
  • tests/unit/validation/system-settings-thinking-signature-fix-schema.test.ts
  • tests/unit/repository/message-write-buffer.test.ts
  • tests/unit/dashboard-logs-thinking-signature-fix-ui.test.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 tests/integration/**/*.test.{ts,tsx} : Integration tests requiring database must be placed in `tests/integration/` and use test database with 'test' in the name

Applied to files:

  • tests/unit/repository/usage-logs-thinking-signature-fix-columns.test.ts
  • tests/unit/validation/system-settings-thinking-signature-fix-schema.test.ts
  • tests/unit/dashboard-logs-thinking-signature-fix-ui.test.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 tests/integration/**/*.test.ts : Place integration tests requiring database in `tests/integration/` (excluded by default)

Applied to files:

  • tests/unit/repository/usage-logs-thinking-signature-fix-columns.test.ts
  • vitest.thinking-signature-fix.config.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/repository/**/*.ts : Use Repository pattern in `src/repository/` to wrap Drizzle queries

Applied to files:

  • tests/unit/repository/usage-logs-thinking-signature-fix-columns.test.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 : Implement proper indexing strategy for common queries and foreign keys

Applied to files:

  • tests/unit/repository/usage-logs-thinking-signature-fix-columns.test.ts
  • drizzle/meta/0047_snapshot.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/drizzle/**/*.ts : Use Drizzle ORM with PostgreSQL for database operations

Applied to files:

  • tests/unit/repository/usage-logs-thinking-signature-fix-columns.test.ts
  • drizzle/meta/0047_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/**/*{message,response,log}*.ts : Log request duration, token usage, and cost to message_request table for analytics

Applied to files:

  • src/app/[locale]/dashboard/logs/_components/usage-logs-table.tsx
  • src/repository/usage-logs.ts
  • 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 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: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/thinking-signature-recovery.ts
  • src/app/v1/_lib/proxy/session.ts
  • tests/unit/proxy/proxy-forwarder-thinking-signature-recovery.test.ts
  • src/app/v1/_lib/proxy/error-handler.ts
  • src/app/v1/_lib/proxy/response-handler.ts
  • 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/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/session.ts
  • tests/unit/proxy/proxy-forwarder-thinking-signature-recovery.test.ts
  • src/app/v1/_lib/proxy/response-handler.ts
  • 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/session.ts
  • 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/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/app/v1/_lib/proxy/session.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:

  • drizzle/meta/0047_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/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: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/**/*guard*.ts : Implement fail-open strategy: allow requests when Redis is unavailable

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 (13)
tests/unit/repository/usage-logs-thinking-signature-fix-columns.test.ts (1)
src/repository/usage-logs.ts (2)
  • findUsageLogsBatch (112-261)
  • findUsageLogsWithDetails (306-482)
src/app/[locale]/dashboard/logs/_components/usage-logs-table.tsx (2)
src/components/ui/badge.tsx (1)
  • Badge (39-39)
scripts/sync-settings-keys.js (1)
  • t (72-72)
tests/unit/proxy/thinking-signature-recovery.test.ts (2)
src/app/v1/_lib/proxy/errors.ts (1)
  • ProxyError (14-450)
src/app/v1/_lib/proxy/thinking-signature-recovery.ts (2)
  • isThinkingSignatureRelatedError (18-42)
  • sanitizeClaudeMessagesRequestThinkingBlocks (52-101)
src/repository/system-config.ts (1)
src/drizzle/schema.ts (1)
  • systemSettings (453-490)
src/app/v1/_lib/proxy/thinking-signature-recovery.ts (1)
src/app/v1/_lib/proxy/errors.ts (1)
  • ProxyError (14-450)
src/repository/usage-logs.ts (1)
src/drizzle/schema.ts (1)
  • messageRequest (274-359)
tests/unit/proxy/proxy-forwarder-thinking-signature-recovery.test.ts (2)
src/app/v1/_lib/proxy/session.ts (1)
  • ProxySession (48-758)
src/app/v1/_lib/proxy/forwarder.ts (2)
  • ProxyForwarder (188-2246)
  • doForward (786-1797)
src/app/v1/_lib/proxy/response-handler.ts (1)
src/app/v1/_lib/proxy/session.ts (1)
  • ProxySession (48-758)
tests/unit/validation/system-settings-thinking-signature-fix-schema.test.ts (1)
src/lib/validation/schemas.ts (1)
  • UpdateSystemSettingsSchema (705-746)
tests/unit/repository/message-write-buffer.test.ts (1)
src/repository/message-write-buffer.ts (2)
  • enqueueMessageRequestUpdate (324-334)
  • stopMessageRequestWriteBuffer (343-357)
src/app/[locale]/settings/config/_components/system-settings-form.tsx (2)
src/components/ui/label.tsx (1)
  • Label (21-21)
src/components/ui/switch.tsx (1)
  • Switch (28-28)
src/app/v1/_lib/proxy/forwarder.ts (5)
src/app/v1/_lib/proxy/errors.ts (1)
  • ProxyError (14-450)
src/lib/config/index.ts (1)
  • isThinkingSignatureFixEnabled (11-11)
src/lib/config/system-settings-cache.ts (1)
  • isThinkingSignatureFixEnabled (115-118)
src/app/v1/_lib/proxy/thinking-signature-recovery.ts (2)
  • sanitizeClaudeMessagesRequestThinkingBlocks (52-101)
  • isThinkingSignatureRelatedError (18-42)
src/app/v1/_lib/proxy/session.ts (1)
  • ProxySession (48-758)
src/drizzle/schema.ts (1)
src/lib/polyfills/file.ts (1)
  • text (40-42)
⏰ 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: 🌐 API Tests
  • GitHub Check: pr-description
  • GitHub Check: Docker Build Test
  • GitHub Check: pr-review
  • GitHub Check: check-codex-status
  • GitHub Check: dev-build-deploy
🔇 Additional comments (59)
messages/en/settings.json (1)

107-108: 思考签名修复开关文案清晰且与功能一致

enableThinkingSignatureFix 及描述准确概括了触发条件(4xx/5xx + 含 thinking/redacted_thinking)、一次性重试以及日志标记行为,命名也与现有 config.form.* 保持一致,无需调整。

messages/en/dashboard.json (1)

131-131: Dashboard 日志表新增 “Fix” 标记键命名与用法一致

logs.table.thinkingSignatureFix 命名与现有表格键风格一致,英文短文案 “Fix” 也契合 Badge 样式,便于快速识别触发了思考签名修复的请求。

messages/ja/settings.json (1)

105-106: 日文配置文案自然且与功能一致

这两条日文文案准确说明了开关行为(4xx/5xx + thinking/redacted_thinking 时去除并单次重试且记录到日志),语气和细节与其他语言版本保持一致,无需调整。

messages/ru/settings.json (1)

105-106: 俄文翻译与设计语义对齐

俄文标题和说明完整涵盖了开关含义(触发条件、仅重试一次、专门针对供应商切换时的签名不兼容、并写入审计日志),与功能设计和其他语言版本保持一致,可以直接使用。

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

88-89: 中文配置项文案清晰、信息完整

这两个配置项标题和说明准确传达了开关的触发条件、处理方式和审计行为,术语风格与本文件其他条目及多语言版本保持一致,无需修改。

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

105-106: 翻譯文案準確清晰

新增的 Thinking 簽名修復功能翻譯準確,描述詳細說明了功能的觸發條件(上游返回 4xx/5xx 且請求包含 thinking/redacted_thinking 區塊)、行為(移除區塊並重試)以及審計追蹤,符合功能設計意圖。

.gitignore (1)

16-16: 正確忽略測試覆蓋率目錄

新增的覆蓋率目錄忽略規則與新增的 test:coverage:thinking-signature-fix 測試腳本相對應,符合現有的覆蓋率目錄管理模式。

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

131-131: 表格標籤翻譯簡潔適當

新增的 thinkingSignatureFix 標籤翻譯為「修復」,簡潔明了,適合在使用記錄表格中作為標記顯示,與功能設計一致。

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

744-745: Schema 擴展正確無誤

UpdateSystemSettingsSchema 新增的 enableThinkingSignatureFix 可選布爾欄位驗證邏輯清晰,與其他功能開關保持一致,支持系統設定的部分更新,實現合理。

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

164-164: 轉換邏輯實現正確

新增的 enableThinkingSignatureFix 欄位轉換邏輯與其他系統設定保持一致,預設值為 false(功能預設關閉),符合漸進式功能發布的最佳實踐。

package.json (1)

23-23: 新增测试覆盖率脚本符合预期。

该脚本遵循了现有覆盖率测试脚本的命名和结构模式,用于针对性测试 thinking-signature-fix 特性。

src/lib/config/index.ts (1)

11-11: 配置导出符合规范。

新增的 isThinkingSignatureFixEnabled 导出遵循了现有的配置导出模式,为特性开关提供了清晰的公共 API。

src/app/v1/_lib/proxy/error-handler.ts (1)

335-340: 审计字段条件注入实现正确。

使用条件展开运算符仅在应用了 thinking signature 修复时才添加审计字段,这是一个清晰且高效的模式。实现假设当 getThinkingSignatureFixApplied() 返回 true 时,getThinkingSignatureFixReason() 必定返回有效值,这应该在 session 层面得到保证。

src/app/[locale]/settings/config/page.tsx (1)

44-44: 设置字段传递符合既定模式。

新增的 enableThinkingSignatureFix 字段遵循了其他系统设置的传递模式,与现有代码结构保持一致。

tests/unit/repository/message-write-buffer.test.ts (1)

146-167: 测试覆盖全面且实现正确。

该测试用例有效验证了新增审计字段的批量写入功能:

  • 测试场景清晰:验证 thinkingSignatureFixAppliedthinkingSignatureFixReason 字段能够正确入队并生成相应的 SQL 更新语句
  • 第 155 行将 thinkingSignatureFixReason 设置为 JSON 字符串是正确的,与实际存储格式一致
  • SQL 断言验证了列名的存在,适用于批量写入场景
drizzle/0047_mute_joystick.sql (1)

1-3: 数据库迁移结构合理。

迁移文件正确添加了三个新列:

  • thinking_signature_fix_applied: 布尔标志,用于审计
  • thinking_signature_fix_reason: 可选文本字段,记录修复原因
  • enable_thinking_signature_fix: 系统级开关

字段命名、类型和约束均符合预期,默认值设置为关闭状态符合渐进式发布的最佳实践。

src/repository/system-config.ts (4)

151-151: 后备配置正确设置。

createFallbackSettings() 中正确添加了 enableThinkingSignatureFix: false 的默认值,与数据库迁移中的默认值保持一致。


176-176: 查询选择字段完整。

fullSelection 中正确添加了 enableThinkingSignatureFix 字段,确保从数据库读取时包含该配置。


307-310: 更新逻辑遵循现有模式。

条件更新逻辑与文件中其他配置字段保持一致,仅在 payload.enableThinkingSignatureFix !== undefined 时更新该字段,支持部分更新的设计。


330-330: 返回字段列表完整。

.returning() 子句中正确包含了 enableThinkingSignatureFix 字段,确保更新后返回最新的配置值。

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

221-228: UI 标记正确实现。

条件渲染的 Badge 组件实现合理:

  • 仅在 log.thinkingSignatureFixApplied 为真时显示
  • 样式与其他 Badge(如成本倍率)保持一致
  • 使用紫色主题与其他特殊功能标记(如 1M Context)保持视觉一致性
  • 正确使用 shrink-0 防止在容器中被压缩

代码结构清晰,遵循了现有的 UI 模式。

src/types/system-config.ts (2)

35-36: 类型定义准确。

SystemSettings 接口中添加了必需的 enableThinkingSignatureFix: boolean 字段,与数据库 schema 中的 NOT NULL 约束一致。注释清晰说明了该字段的用途。


71-72: 更新接口设计合理。

UpdateSystemSettingsInput 中将 enableThinkingSignatureFix 定义为可选字段,支持部分更新模式,与文件中其他配置字段保持一致。

drizzle/meta/_journal.json (1)

334-340: 迁移日志条目正确。

新增的迁移条目遵循现有模式:

  • 索引递增正确(46 → 47)
  • 版本号与其他条目一致
  • 标签与迁移文件名匹配
  • 时间戳合理
  • 断点标志与其他条目保持一致

元数据结构完整且格式正确。

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

13-14: thinking/signature 修复重试路径整体设计合理,满足“最小降级 + 可审计”目标

  • 仅在 !response.ok 且开启 enableThinkingSignatureFix,并且解析出的请求体经 sanitizeClaudeMessagesRequestThinkingBlocks 确认实际移除了 thinking/redacted_thinking 块时才进入重试,符合“有问题才动手”的设计。
  • 对 401/402/403/404/429 使用排除列表直接短路,避免掩盖鉴权、配额、路由类真实问题,这里的注释也把语义解释得很清楚。
  • 重试时重新挂上响应超时定时器,并在 retryResponse.ok 分支下为 session 填充 clearResponseTimeout/responseController,让 response-handler 能透明接管后续生命周期,保持与普通成功路径一致。
  • 通过 session.setThinkingSignatureFixApplied 记录触发状态、移除块数量、原始错误和策略(命中过滤规则 vs 仅靠状态码保守兜底),为后续 DB 审计字段和前端 “Fix” 标记提供了充分上下文,链路清晰。

整体看,这段逻辑与外层重试/熔断状态机衔接良好,没有明显的重试风暴或隐藏错误风险,属于可以放心合入的变更。

Also applies to: 43-46, 1648-1773

src/repository/message.ts (1)

135-137: 消息请求扩展字段对接思考签名修复审计信息是正确的

updateMessageRequestDetails 中新增 thinkingSignatureFixApplied / thinkingSignatureFixReason 两个可选字段,并在构造 updateData 时仅在字段非 undefined 时写入,既与 message_request 表中新列保持一致,也避免在未触发修复时反复更新列值。这与上层通过 session 条件打补丁的用法是对齐的。

Also applies to: 196-201

src/app/v1/_lib/proxy/response-handler.ts (1)

58-70: 统一的 getThinkingSignatureFixAuditPatch 有效消除了重复并保证审计信息在各路径上一致落盘

  • 帮助函数通过 session.getThinkingSignatureFixApplied/Reason 决定是否附加 thinkingSignatureFixApplied / thinkingSignatureFixReason,未触发修复时返回空对象,避免无意义更新。
  • 在非流正常完成、非流提前终止、流式完成、抽象的 finalizeRequestStats 以及 persistRequestFailure 多个路径中统一 ...getThinkingSignatureFixAuditPatch(session),可以确保无论请求成功、失败还是在后台统计阶段出错,只要前面走过修复重试逻辑,对应的审计信息都会写入 message_request
  • message.ts 中的新字段和 usage-logs.ts 的查询结构配合后,上游 ProxySession → DB → 仪表盘 Logs 的审计链路是闭合的。

这部分实现没有逻辑漏洞,看起来可以直接合入。

Also applies to: 247-258, 393-409, 1765-1772, 1839-1854, 1978-1989

src/lib/config/system-settings-cache.ts (1)

27-34: 系统设置缓存对 enableThinkingSignatureFix 的扩展符合现有模式

  • DEFAULT_SETTINGSgetCachedSystemSettings 的 fallback 返回值中新增 enableThinkingSignatureFix: false,保持了“读失败时 fail-open 到安全默认值”的既有约定。
  • 新增的 isThinkingSignatureFixEnabled() 复用缓存读路径,与 isHttp2Enabled() 对称,使代理层可以在热路径上按布尔值快速判断是否启用修复逻辑,而无需关心完整 SystemSettings 结构。

整体实现简单直接,没有发现行为风险。

Also applies to: 80-96, 110-118

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

30-63: UsageLogRow 增加思考签名修复审计字段且已在查询层完整贯通

  • UsageLogRow 接口中新增 thinkingSignatureFixApplied / thinkingSignatureFixReason,并在两种查询入口(游标分页的 findUsageLogsBatch 与详情版 findUsageLogsWithDetails)里从 messageRequest 显式选出对应列,最终通过 ...row 映射到返回结果,保证仪表盘/前端可以直接消费这两个审计字段。
  • 新字段不参与任何聚合统计或 totalTokens 计算,只作为额外的可视化/排障信息输出,避免了对现有统计口径的影响。

实现与上游仓储和前端用法对齐,没有发现问题。

Also applies to: 188-222, 405-437

tests/unit/repository/usage-logs-thinking-signature-fix-columns.test.ts (3)

3-16: 辅助函数实现合理

createThenableQuery 辅助函数很好地模拟了 Drizzle 查询构建器的链式调用模式,使测试能够验证字段选择而无需真实数据库连接。


19-43: findUsageLogsBatch 测试实现正确

测试正确验证了 findUsageLogsBatch 的 select 调用包含 thinkingSignatureFixAppliedthinkingSignatureFixReason 字段。使用 vi.resetModules() 和动态导入确保了模拟的正确隔离。


45-92: findUsageLogsWithDetails 测试实现合理

测试通过队列模拟两次 select 调用(summary 和 logs),并验证第二次调用包含审计字段。虽然这依赖于实现细节(select 调用顺序),但注释已清楚说明约定,且这是验证字段选择的合理方式。

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

29-31: 审计字段定义清晰准确

新增的 thinkingSignatureFixAppliedthinkingSignatureFixReason 字段定义合理:

  • 字段设为可选,仅在触发修复时才会被设置,避免不必要的数据写入
  • 注释清楚说明了字段用途和默认值策略
  • 类型定义与数据库 schema 保持一致

64-65: 列映射配置正确

列名映射遵循现有模式,camelCase 到 snake_case 的转换与其他字段保持一致。

src/drizzle/schema.ts (2)

320-322: message_request 审计字段设计合理

新增的审计字段设计合理:

  • thinkingSignatureFixApplied 使用 NOT NULL + default(false) 简化查询逻辑,避免处理 null 值
  • thinkingSignatureFixReason 设为可空,适合存储可选的元数据信息
  • 注释清晰说明字段用途
  • 未添加索引符合审计字段的使用场景(主要用于展示和审计,非主查询条件)

485-486: 系统设置开关定义正确

enableThinkingSignatureFix 使用 NOT NULL + default(false) 确保:

  • 功能默认关闭,符合保守策略
  • 不需要处理 null 值的边界情况
  • 与现有系统设置字段模式保持一致
drizzle/meta/0047_snapshot.json (1)

504-516: Drizzle 快照正确生成

该快照文件由 drizzle-kit 自动生成,正确反映了 schema 变更:

  • message_request.thinking_signature_fix_appliedthinking_signature_fix_reason
  • system_settings.enable_thinking_signature_fix

类型定义和约束与 schema.ts 一致。

Also applies to: 1914-1920

src/actions/system-config.ts (1)

41-41: 系统设置扩展实现正确

enableThinkingSignatureFix 新设置的集成遵循现有模式:

  • 字段为可选,支持部分更新
  • 通过 Zod schema 进行验证
  • 正确传递给 updateSystemSettings 进行持久化
  • 缓存失效机制确保代理请求获取最新配置

Also applies to: 63-63

src/app/[locale]/settings/config/_components/system-settings-form.tsx (5)

23-35: 类型定义正确。

新增的 enableThinkingSignatureFix 字段已正确添加到 SystemSettingsFormPropsinitialSettings 类型中,遵循了现有设置的模式。


58-60: 状态管理实现正确。

新增的 enableThinkingSignatureFix 状态管理遵循了现有布尔设置的模式,从 initialSettings 正确初始化。


71-81: 表单提交逻辑正确。

新设置已正确包含在 saveSystemSettings 调用的 payload 中,与其他设置保持一致。


88-97: 服务器响应同步正确。

成功保存后,本地状态正确地从服务器响应中更新,确保了 UI 与后端的一致性。


224-239: UI 实现符合规范。

新增的开关控件完全遵循了现有设置项的模式,包括:

  • 正确的标签关联(htmlForid 匹配)
  • 国际化翻译键的使用
  • 禁用状态的正确绑定
tests/unit/proxy/thinking-signature-recovery.test.ts (1)

9-50: 错误识别测试覆盖全面。

测试用例很好地覆盖了:

  • 不同格式的 "Invalid signature" 错误消息(有/无 messages 前缀)
  • 不稳定的状态码场景(4xx 和 5xx)
  • "cannot be modified" 错误模式
  • 负面测试用例(非 ProxyError 类型、不相关的错误消息)

这些测试与实现代码中的错误检测逻辑保持一致。

src/app/api/admin/system-config/route.ts (2)

30-49: API 文档更新正确。

JSDoc 注释已更新,包含了新增的六个可选字段,包括 enableThinkingSignatureFix,与实际实现保持一致。


64-78: 系统设置更新逻辑正确。

新增的六个字段(包括 enableThinkingSignatureFix)已正确地:

  • 通过 UpdateSystemSettingsSchema 验证
  • validated 对象中提取
  • 传递给 updateSystemSettings 函数

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

vitest.thinking-signature-fix.config.ts (3)

11-21: 测试环境配置正确。

测试配置合理地:

  • 使用 Node 环境(适合代理逻辑测试)
  • 通过 include 精确定位两个相关测试文件
  • 排除了标准的构建和集成测试目录

23-37: 覆盖率配置策略合理。

针对关键的故障恢复逻辑设置了更高的覆盖率阈值(80%/80%/70%/80%),这是一个良好的实践。通过只包含 thinking-signature-recovery.ts 文件,避免了大文件(如 forwarder.ts)导致的指标失真。


39-52: 测试配置选项符合最佳实践。

测试隔离和 mock 清理选项(isolate, mockReset, restoreMocks, clearMocks)确保了测试之间的独立性,路径别名配置与项目结构一致。

tests/unit/proxy/proxy-forwarder-thinking-signature-recovery.test.ts (6)

1-101: 测试辅助函数实现合理。

Mock 配置和辅助函数设计良好:

  • isThinkingSignatureFixEnabledMock 允许在测试中控制功能开关
  • createSession 支持可选的 thinking 块包含(通过 includeThinkingBlocks 参数)
  • createClaudeProvider 创建完整的 Provider 对象用于测试

这些辅助函数为后续测试用例提供了灵活的基础。


104-161: 重试逻辑测试全面且准确。

此测试用例完整地验证了 thinking signature 修复的核心流程:

  • ✅ 第一次请求包含 thinking 块,返回 400 错误
  • ✅ 第二次请求移除了 thinking 块,返回成功
  • ✅ 会话状态正确标记了修复操作(getThinkingSignatureFixApplied
  • ✅ 响应超时清理钩子正确附加到会话对象

测试覆盖了功能的关键行为路径。


163-210: 5xx 错误回退测试正确。

此测试验证了即使错误消息不明确包含 "Invalid signature",只要请求包含 thinking 块且上游返回 5xx 错误,系统仍会尝试移除 thinking 块并重试。这覆盖了 PR 目标中提到的"错误码不稳定"场景。


212-246: 功能开关测试正确。

此测试验证了当 enableThinkingSignatureFix 关闭时,即使遇到相关错误也不会触发重试,确保了功能开关的有效性。


248-278: 排除状态码测试关键且正确。

此测试使用参数化测试验证了 401/402/403/404/429 等关键错误码不会触发重试。这是一个重要的安全考虑,确保了认证、配额和限流错误不会被掩盖。测试实现清晰且全面。


280-308: 无 thinking 块场景测试正确。

此测试验证了当请求不包含 thinking 或 redacted_thinking 块时,即使功能开启且遇到错误,也不会触发不必要的重试。这避免了对无关请求的性能影响。

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

96-99: LGTM!

审计字段设计合理,私有字段配合公共访问器的模式与类中其他属性保持一致(如 cacheTtlResolvedcontext1mApplied)。

src/app/v1/_lib/proxy/thinking-signature-recovery.ts (3)

3-7: LGTM!

类型定义简洁明了,包含了调用方所需的全部信息:处理后的对象、是否有变化、以及移除的块数量。


18-42: LGTM!

错误检测逻辑设计合理:

  1. 类型和状态码校验提供了基本防护
  2. 关键词匹配覆盖了两种典型错误模式
  3. 多信号组合(hasContentIndex && hasInvalid && hasSignature && hasThinking)降低了误判风险
  4. 注释清晰说明了设计意图和不稳定的上游错误格式

52-101: LGTM!

清理函数实现得很好:

  1. 最小侵入性:仅移除 thinkingredacted_thinking 块,不影响其他内容
  2. 引用保留优化:未发生变化时返回原对象引用,避免不必要的对象创建
  3. 纯函数设计:不修改输入参数,通过浅拷贝创建新对象
  4. 健壮的类型处理:正确处理各种边界情况(非数组、非对象等)

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Code Review Summary

No significant issues identified in this PR.

PR Size: XL

  • Lines changed: 3454
  • Files changed: 42
  • Split suggestions: Split into (1) proxy recovery core, (2) DB schema/migration, (3) UI + i18n, (4) tests + Vitest config.

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.

  • Reviewed PR #540 (head pull/540/merge) across all changed files/lines.
  • Applied PR size label: size/XL.
  • Submitted a review comment via gh pr review using the “No significant issues identified” summary format (no inline comments posted since nothing met the reporting threshold).

@greptile-apps
Copy link

greptile-apps bot commented Jan 9, 2026

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

@ding113 ding113 closed this Jan 9, 2026
@github-project-automation github-project-automation bot moved this from Backlog to Done in Claude Code Hub Roadmap Jan 9, 2026
@ding113 ding113 deleted the feature/thinking-signature-fix branch January 27, 2026 09:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:core area:i18n 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