Skip to content

feat(signature): add signature pool for thinking block signature replacement - #1756

Closed
touwaeriol wants to merge 2 commits into
Wei-Shaw:mainfrom
touwaeriol:feat/signature-pool-v2
Closed

touwaeriol wants to merge 2 commits into
Wei-Shaw:mainfrom
touwaeriol:feat/signature-pool-v2

Conversation

@touwaeriol

Copy link
Copy Markdown
Contributor

背景 / Background

当前签名整流器在检测到 thinking block 签名错误时,采用删除 thinking 块的方式重试。这虽然能解决错误,但会丢失 thinking 内容,降低模型推理质量。

Currently, the signature rectifier strips thinking blocks entirely when a signature validation error is detected. While this resolves the error, it loses thinking content and degrades model reasoning quality.


目的 / Purpose

新增签名池策略:从成功响应中收割有效签名,遇到签名错误时用池中签名替换而非删除,保留完整的 thinking 内容。

Add a signature pool strategy: harvest valid signatures from successful responses and replace invalid ones from the pool on errors, preserving full thinking content.


改动内容 / Changes

后端 / Backend

  • 异步签名收割器 (signature/harvester.go):io.ReadCloser 装饰器,通过 buffered channel + background goroutine 从 SSE 流中提取签名,零性能影响。支持 content_block_start(legacy)和 content_block_delta/signature_delta(current API)两种事件格式。带 panic recover、ctx.Done 防泄漏、sync.Once 安全关闭
  • Redis ZSET 签名池 (repository/signature_pool_cache.go):Lua 脚本实现原子 Add+Trim+Expiry,1小时软 TTL,按时间戳排序
  • 平台隔离桶 (signature/pool.go):OAuth 按平台隔离(oauth:anthropic / oauth:antigravity),API Key 按账号独立池,防止跨平台签名污染
  • 池替换整流器 (signature/pool_rectifier.go):从池中取最新签名替换请求中所有 thinking 块签名,循环使用
  • 整流器工厂 (signature_rectifier_factory.go):根据 SignaturePoolSize 配置决定使用 strip 还是 pool 策略
  • Gateway 集成:成功响应路径添加 harvester 包装(3处),签名错误重试逻辑重构为 rectifier stage 循环
  • RectifierSettings 新增 signature_pool_size 字段

  • Async signature harvester (signature/harvester.go): io.ReadCloser decorator using buffered channel + background goroutine to extract signatures from SSE streams with zero performance impact. Supports both content_block_start (legacy) and content_block_delta/signature_delta (current API) event formats. Includes panic recovery, ctx.Done leak prevention, and sync.Once safe close
  • Redis ZSET signature pool (repository/signature_pool_cache.go): Lua script for atomic Add+Trim+Expiry with 1-hour soft TTL, ordered by timestamp
  • Platform-isolated buckets (signature/pool.go): OAuth buckets isolated by platform (oauth:anthropic / oauth:antigravity), API Key gets per-account pools, preventing cross-platform signature contamination
  • Pool replace rectifier (signature/pool_rectifier.go): Fetches newest signatures from pool and replaces all thinking block signatures in the request, cycling through available entries
  • Rectifier factory (signature_rectifier_factory.go): Chooses strip vs pool strategy based on SignaturePoolSize setting
  • Gateway integration: Response paths wrapped with harvester (3 locations), signature error retry logic refactored into rectifier stage loop
  • RectifierSettings: Added signature_pool_size field

前端 / Frontend

  • 设置页面:在整流器配置区域新增签名池大小输入框,根据池大小动态切换 hint 文案(strip vs pool 模式说明)
  • Settings page: Added signature pool size input in rectifier settings, with dynamic hint text switching based on pool size (strip vs pool mode description)

决策表 / Decision Table

条件 / Condition 策略 / Strategy
signature_pool_size = 0 Strip(删除 thinking 块 / strip thinking blocks)
signature_pool_size > 0 + 账号开关开 / switch on Pool(签名替换 / signature replacement)
signature_pool_size > 0 + 池空 / pool empty 透传错误 / pass-through error(不降级为 strip / no strip fallback)

测试 / Tests

  • 签名包 26 个单元测试(harvester、rectifier、replace)
  • Redis 池 10 个单元测试(miniredis)
  • 覆盖:异步提取、SSE 解析、panic 隔离、context 取消、平台隔离、双重关闭、池替换循环等场景

…acement

When enabled (signature_pool_size > 0), the system harvests thinking
signatures from successful upstream responses into a Redis-backed pool.
On signature validation errors, instead of stripping thinking blocks,
it replaces invalid signatures with valid ones from the pool.

Key components:
- Async harvester: io.ReadCloser decorator with channel+goroutine,
  zero impact on the main read path
- Redis ZSET pool: per-platform buckets (oauth:anthropic, oauth:antigravity),
  per-account for API keys, 1h soft TTL
- Pool rectifier: replaces all thinking block signatures from pool,
  cycling through available signatures
- Factory: decides strip vs pool strategy based on settings
- Platform isolation: OAuth/antigravity signatures never mix
@Wei-Shaw Wei-Shaw closed this Apr 21, 2026
@Wei-Shaw Wei-Shaw reopened this Apr 21, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Apr 21, 2026
@Wei-Shaw Wei-Shaw closed this Apr 21, 2026
@Wei-Shaw Wei-Shaw reopened this Apr 21, 2026
Repository owner unlocked this conversation Apr 21, 2026
@Wei-Shaw Wei-Shaw closed this Apr 21, 2026
@Wei-Shaw Wei-Shaw reopened this Apr 21, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Apr 21, 2026
@Wei-Shaw Wei-Shaw closed this Apr 21, 2026
@Wei-Shaw Wei-Shaw reopened this Apr 21, 2026
@Wei-Shaw Wei-Shaw closed this Apr 21, 2026
@Wei-Shaw Wei-Shaw reopened this Apr 21, 2026
Repository owner unlocked this conversation Apr 21, 2026
@Wei-Shaw Wei-Shaw closed this Apr 21, 2026
@Wei-Shaw Wei-Shaw reopened this Apr 21, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Apr 21, 2026
Repository owner unlocked this conversation Apr 21, 2026
@Wei-Shaw Wei-Shaw closed this Apr 21, 2026
@Wei-Shaw Wei-Shaw reopened this Apr 21, 2026
@github-actions

github-actions Bot commented Apr 21, 2026 •

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA. ✅
Posted by the CLA Assistant Lite bot.

@touwaeriol

Copy link
Copy Markdown
Contributor Author

我已阅读CLA文件,并在此签署CLA文件。

@touwaeriol

Copy link
Copy Markdown
Contributor Author

I have read the CLA Document and I hereby sign the CLA

github-actions Bot added a commit that referenced this pull request Apr 21, 2026
@touwaeriol touwaeriol closed this Apr 22, 2026
touwaeriol added a commit to touwaeriol/sub2api that referenced this pull request Apr 22, 2026
回滚针对 Claude OAuth 转发流程做的两块增强:

A. Claude Code CLI 模拟套件 (6d0e056 + 5 个后续 fix)
  - TLS ClientHello 模拟(17→52 cipher suites、Claude Code 2.1.114 baseline、JA3/JA4 对齐)
  - HTTP UA / anthropic-beta tokens / Stainless headers 同步
  - Sidecar 流量:claude_sidecar_probe + claude_startup_probe + count_tokens 注入
  - Sticky session UUID(accounts.extra.metadata.user_id Redis 复用)
  - 429 no-switch 短路
  - Admin UI: 账号级 randomize fingerprint 按钮 + binding count
  - 配套 safe.Go panic-recover 包(无遗留依赖一并删除)
  - capture_fingerprint / verify_fingerprint 工具

B. Signature Pool (16 个 commits)
  - signature/ 整个包(harvester、pool、rectifier、replace 等)
  - signature_rectifier_factory.go
  - signature_pool_cache.go
  - 前端 signature pool size UI / i18n
  - 上游 PR Wei-Shaw#1756 已 close 未合并,本地实现一并撤回

DB 清理:
  - 新增 migration 115_cleanup_claude_code_mimicry_fields.sql
    DROP idx_accounts_tls_fp_profile_id(来自 108)
    清理 accounts.extra 的 metadata / tls_fingerprint_randomized / sticky_session_user_id
  - 删除 migration 108_add_tls_fingerprint_profile_id_index.sql 文件

保留:
  - 上游 TLS fingerprint profile 基础功能
  - 统一 OAuth token refresh API (Wei-Shaw#1035, 跨 4 个平台)
  - Anthropic 用量查询节流
  - GenerateSessionHash(被 OpenAI/Gemini 等多处使用)

74 files changed, 310 insertions(+), 6150 deletions(-)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants