feat: add Bedrock request optimizer (PRE-SEND thinking + cache injection) (#1301)

* feat: add Bedrock request optimizer (PRE-SEND thinking + cache injection)

Add a PRE-SEND request optimizer that enhances Bedrock API requests
before forwarding, complementing the existing POST-ERROR rectifier system.

New modules:
- thinking_optimizer: 3-path model detection (adaptive/legacy/skip)
  - Opus 4.6/Sonnet 4.6: adaptive thinking + effort max + 1M context beta
  - Legacy models: inject extended thinking with max budget
  - Haiku: skip (no modification)
- cache_injector: auto-inject cache_control breakpoints (max 4)
  - Injects at tools/system/assistant message positions
  - TTL upgrade for existing breakpoints (5m → 1h)

Gate: only activates for Bedrock providers (CLAUDE_CODE_USE_BEDROCK=1)
Config: stored in SQLite settings table, default OFF, user opt-in
UI: new Optimizer section in RectifierConfigPanel with 3 toggles + TTL

18 unit tests covering all paths. Verified against live Bedrock API.

* chore: remove docs/plans directory

* fix: address code review findings for Bedrock request optimizer

P0 fixes:
- Replace hardcoded Chinese with i18n t() calls in optimizer panel,
  add translation keys to zh/en/ja locale files
- Fix u64 underflow: max_tokens - 1 → max_tokens.saturating_sub(1)
- Move optimizer from before retry loop to per-provider with body
  cloning, preventing Bedrock fields leaking to non-Bedrock providers

P1 fixes:
- Replace .map() side-effect pattern with idiomatic if-let (clippy)
- Fix module alphabetical ordering in mod.rs
- Add cache_ttl whitelist validation in set_optimizer_config
- Remove #[allow(unused_assignments)] and dead budget decrement

---------

Co-authored-by: Keith (via OpenClaw) <keithyt06@users.noreply.github.com>
Co-authored-by: Jason <farion1231@gmail.com>
This commit is contained in:
Keith Yu
2026-03-07 18:57:21 +08:00
committed by GitHub
parent 27d21c23ac
commit 8217bfff50
14 changed files with 969 additions and 9 deletions
+6 -1
View File
@@ -8,7 +8,7 @@ use crate::proxy::{
extract_session_id,
forwarder::RequestForwarder,
server::ProxyState,
types::{AppProxyConfig, RectifierConfig},
types::{AppProxyConfig, OptimizerConfig, RectifierConfig},
ProxyError,
};
use axum::http::HeaderMap;
@@ -59,6 +59,8 @@ pub struct RequestContext {
pub session_id: String,
/// 整流器配置
pub rectifier_config: RectifierConfig,
/// 优化器配置
pub optimizer_config: OptimizerConfig,
}
impl RequestContext {
@@ -93,6 +95,7 @@ impl RequestContext {
// 从数据库读取整流器配置
let rectifier_config = state.db.get_rectifier_config().unwrap_or_default();
let optimizer_config = state.db.get_optimizer_config().unwrap_or_default();
let current_provider_id =
crate::settings::get_current_provider(&app_type).unwrap_or_default();
@@ -156,6 +159,7 @@ impl RequestContext {
app_type,
session_id,
rectifier_config,
optimizer_config,
})
}
@@ -216,6 +220,7 @@ impl RequestContext {
first_byte_timeout,
idle_timeout,
self.rectifier_config.clone(),
self.optimizer_config.clone(),
)
}