Files
kiro.rs/CHANGELOG.md
2026-03-05 21:28:41 +08:00

779 lines
52 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Changelog
## [v1.1.5] - 2026-03-02
### Fixed
- **防止孤立 tool_result 导致空消息** — `convert_user_message` 新增最终兜底逻辑,当 tool_result 被过滤为孤立块后 content 变空时插入占位符 ".",避免上游返回 400 "Improperly formed request";新增回归测试覆盖孤立 tool_result 场景 (`src/anthropic/converter.rs`)
## [v1.1.4] - 2026-03-02
### Fixed
- **WebSearch 历史消息上下文保留** — `convert_assistant_message` 新增对 `server_tool_use`(忽略)和 `web_search_tool_result`(提取 title、url、snippet、page_age 为纯文本)的处理,修复多轮对话中搜索结果被静默丢弃导致 Kiro 丢失上下文的问题;使用纯文本格式彻底规避特殊字符破坏格式的风险;新增 2 个单元测试覆盖上述路径 (`src/anthropic/converter.rs`)
## [v1.1.3] - 2026-02-27
### Changed
- **合并三个导入对话框为一个** — 删除冗余的 `KamImportDialog``BatchImportDialog`,统一使用 `ImportTokenJsonDialog`,自动识别 KAM 嵌套格式、扁平凭据格式和 Token JSON 格式 (`admin-ui/src/components/`)
- **上游网络错误归类为瞬态错误** — `error sending request`/`connection closed`/`connection reset` 纳入 `is_transient_upstream_error`,返回 502 且不输出请求体 (`src/anthropic/handlers.rs`)
- **上游报错不再输出完整请求体** — `sensitive-logs` 模式下仅输出请求体字节数 (`src/anthropic/handlers.rs`)
- **瞬态错误匹配大小写归一化** — `is_transient_upstream_error` 统一 `.to_lowercase()` 后匹配,提取 `NETWORK_ERROR_PATTERNS` 常量消除重复 (`src/anthropic/handlers.rs`)
### Removed
- **移除负载均衡模式切换** — 删除前端按钮/API/hooks 和后端路由/handler/service/types/config 字段/token_manager 方法及测试,该设置实际未被使用 (`admin-ui/`, `src/admin/`, `src/kiro/token_manager.rs`, `src/model/config.rs`)
### Added
- **Usage 诊断日志** — 流式/缓冲流式/非流式三条路径均增加 `sensitive-logs` 保护的 usage 日志,输出 estimated/context/final input_tokens 及来源、output_tokens (`src/anthropic/stream.rs`, `src/anthropic/handlers.rs`)
## [v1.1.2] - 2026-02-27
### Added
- **Kiro Account Manager 导入** — 支持导入 KAM 导出的 JSON 凭据文件 (`admin-ui/src/components/kam-import-dialog.tsx`)
- **批量导入对话框** — 新增独立的批量导入凭据组件 (`admin-ui/src/components/batch-import-dialog.tsx`)
- **凭证 disabled 字段持久化** — 从配置文件读取 disabled 状态,支持手动禁用凭据跨重启保留 (`src/kiro/model/credentials.rs`, `src/kiro/token_manager.rs`)
- **凭据级 Region 编辑** — Admin UI 支持对已有凭据在线修改 `region``apiRegion`,点击凭据卡片内联编辑,保存后持久化 (`src/admin/`, `admin-ui/src/components/credential-card.tsx`)
- **Admin API `POST /credentials/:id/region`** — 新增 Region 修改接口,支持清除(传 null或覆盖两个 region 字段 (`src/admin/handlers.rs`, `src/admin/router.rs`)
### Fixed
- **WebSearch SSE 事件序列修正** — 调整 server_tool_use 位置、content block index、page_age 转换、usage 统计 (`src/anthropic/websearch.rs`)
- **Token Manager 统计回写** — 立即回写统计数据,清除已删除凭据残留 (`src/kiro/token_manager.rs`)
- **HTTP 非安全地址批量导入** — 修复 admin-ui 在 HTTP 下的导入错误 (`admin-ui/src/lib/utils.ts`)
- **Docker 端口绑定优化** — 修正端口绑定和配置目录挂载 (`docker-compose.yml`)
- **移除重复 Sonnet 4.6 模型项** — 删除 `/v1/models` 中重复的 claude-sonnet-4-6 条目,避免 id 冲突 (`src/anthropic/handlers.rs`)
- **防止自动禁用状态被持久化** — `persist_credentials()` 仅持久化手动禁用,避免重启后自动禁用变为手动禁用导致无法自愈 (`src/kiro/token_manager.rs`)
- **sha256Hex digest 异常回退** — 在 `crypto.subtle.digest` 外围加 try/catch失败时回退到纯 JS 实现 (`admin-ui/src/lib/utils.ts`)
- **parseKamJson null 输入保护** — 对 JSON null 输入增加类型检查,避免 TypeError (`admin-ui/src/components/kam-import-dialog.tsx`)
- **额度查询 region 修复** — `get_usage_limits` 改用 `effective_api_region`,凭据指定 region 时不再因走错 endpoint 而 403 (`src/kiro/token_manager.rs`)
- **批量导入丢失 apiRegion** — `TokenJsonItem` 补充 `api_region` 字段,导入 JSON 中的 `apiRegion` 不再被丢弃 (`src/admin/types.rs`, `src/admin/service.rs`)
- **API 请求使用凭据级 region** — `provider.rs``base_url`/`mcp_url`/`base_domain` 改用 `credentials.effective_api_region()`,凭据配置了 region 时不再错误地走全局 config region 导致 403 (`src/kiro/provider.rs`)
- **Region 编辑 stale state** — 点击编辑 Region 时同步最新 props 到 input避免后台刷新后提交旧值覆盖服务端数据 (`admin-ui/src/components/credential-card.tsx`)
- **Region 值未 trim** — `set_region` 保存前对 region/apiRegion 做 trim防止带空格的值持久化后生成无效 URL (`src/admin/service.rs`)
- **过滤超长工具名** — `convert_tools` 过滤掉 name 超过 64 字符的工具,避免上游拒绝整个请求 (`src/anthropic/converter.rs`)
- **429 错误不再输出完整请求体** — 瞬态上游错误429/5xx走独立分支返回 429不触发 sensitive-logs 的请求体诊断日志 (`src/anthropic/handlers.rs`)
- **兼容旧 authRegion 配置** — `credentials.region` 增加 `#[serde(alias = "authRegion")]`,旧配置文件中的 `authRegion` 字段不再被静默忽略 (`src/kiro/model/credentials.rs`)
- **导入凭据 region 规范化** — token.json 导入路径对 region/apiRegion 做 trim + 空字符串转 None`set_region` 逻辑一致 (`src/admin/service.rs`)
### Changed
- **默认 kiro_version 更新至 0.10.0** (`src/model/config.rs`)
- **Opus 模型映射调整** — opus 默认映射到 claude-opus-4.6,仅 4.5/4-5 显式映射到 claude-opus-4.5 (`src/anthropic/converter.rs`)
- **Sonnet 4.6 Model 字段补全** — 添加 context_length、max_completion_tokens、thinking 字段 (`src/anthropic/handlers.rs`)
- **Region 配置精简** — 删除 `credentials.auth_region``config.auth_region` 冗余字段;凭据的 `region` 同时用于 Token 刷新和 API 请求默认值,`api_region` 可单独覆盖 API 路由 (`src/kiro/model/credentials.rs`, `src/model/config.rs`)
- **添加凭据 UI Region 字段语义调整** — 前端"Auth Region"改为"Region"(对应 `credentials.region`"API Region"保持,去除无意义的 `authRegion` 前端字段 (`admin-ui/`)
## [v1.1.1] - 2026-02-18
### Fixed
- **修复 Sonnet 4.6 thinking 配置变量名错误** (`src/anthropic/handlers.rs`)
- 修正 thinking 配置覆写逻辑中的变量名拼写错误
## [v1.1.0] - 2026-02-18
### Added
- **Sonnet 4.6 模型支持** (`src/anthropic/handlers.rs`, `src/anthropic/converter.rs`, `src/anthropic/types.rs`)
- 添加 claude-sonnet-4-6 及其 thinking/agentic 变体到模型列表
- 更新模型映射逻辑以正确识别 Sonnet 4.6 版本
- 为 Sonnet 4.6 启用 1M 上下文窗口和 64K 最大输出 tokens
- 更新 thinking 配置覆写逻辑以支持 Sonnet 4.6 的 adaptive thinking
## [v1.0.21] - 2026-02-17
### Changed
- **图片处理限制放宽** (`src/model/config.rs`)
- 单图总像素限制从 1.15M 放宽至 4M支持更高分辨率图片直接透传
- 图片长边限制从 1568 放宽至 4000减少不必要的缩放压缩
## [v1.0.20] - 2026-02-17
### Fixed
- **空消息内容验证与错误分类改进** (`src/anthropic/converter.rs`, `src/anthropic/handlers.rs`)
- 新增 `ConversionError::EmptyMessageContent` 错误类型,在请求转换阶段验证消息内容不为空
- 在 prefill 处理后验证最后一条消息内容有效性,支持字符串和数组两种 content 格式
- 检测空字符串、空白字符、空数组等情况,避免向上游发送无效请求
- 修复 `is_input_too_long_error` 错误地将 "Improperly formed request" 归类为上下文过长错误
- 新增 `is_improperly_formed_request_error` 函数专门处理格式错误,返回准确的错误信息
- 新增 3 个测试用例验证空消息内容检测功能
- **图片文件大小压缩优化** (`src/image.rs`)
- 新增基于文件大小的强制重新编码逻辑:即使图片尺寸符合要求,如果文件大小超过 200KB 也会重新编码降低质量
- 修复小尺寸高质量图片(如 483x480 但 631KB直接透传导致请求体过大的问题
- 新增日志输出追踪大文件重新编码过程和压缩率
## [v1.0.19] - 2026-02-17
### Changed
- **自适应压缩策略优化** (`src/anthropic/handlers.rs`)
- 请求体大小校验改为以实际序列化后的总字节数为准,不再扣除图片 base64 字节(上游存在约 5MiB 的硬性请求体大小限制,图片也必须计入)
- 压缩层级重排:当单条 user content 已超过阈值时优先截断超长消息(第三层),再移除历史消息(第四层),避免移除历史后仍无法降到阈值内
- 新增 `has_any_tool_results_or_tools` / `has_any_tool_uses` 预检,跳过无效的 tool 阈值降低迭代
- 历史消息移除改为批量 drain单轮最多 16 条),提升大上下文场景的压缩效率
- **请求体大小阈值默认上调至 4.5MiB** (`src/model/config.rs`, `config.example.json`)
- `compression.maxRequestBodyBytes` 从 400KB 上调至 4,718,592 字节4.5MiB),匹配上游实际限制
### Fixed
- **cargo fmt 格式化** (`src/anthropic/converter.rs`, `src/image.rs`)
## [v1.0.18] - 2026-02-17
### Added
- **GIF 动图抽帧采样与强制重编码** (`src/image.rs`, `src/anthropic/converter.rs`)
- 新增 `process_gif_frames()` 函数,将 GIF 动图抽帧为多张静态 JPEG避免动图 base64 体积巨大导致 upstream 400 错误
- 采样策略:总帧数不超过 20 帧,每秒最多 5 帧,超长 GIF 自动降低采样频率均匀抽取
- 新增 `process_image_to_format()` 函数,支持将任意图片强制重编码为指定格式
- GIF 抽帧失败时多级回退JPEG 重编码 → 静态 GIF 处理 → 原始数据透传
- `process_image()` 对 GIF 格式强制重编码为静态帧,即使无需缩放也避免透传体积巨大的动图
- `ImageProcessResult` 新增 `was_reencoded``original_bytes_len``final_bytes_len` 字段
### Changed
- **请求体大小阈值默认上调** (`src/model/config.rs`, `config.example.json`)
- 上游存在请求体大小硬限制(实测约 5MiB 左右会触发 400默认将 `compression.maxRequestBodyBytes` 上调至 4.5MiB 预留安全余量
- **日志分析脚本同步更新** (`tools/analyze_compression.py`, `tools/diagnose_improper_request.py`)
- 修复 ANSI 序列污染解析,并增加“自适应二次压缩/本地超限拒绝”的统计输出
## [v1.0.17] - 2026-02-15
### Added
- **自适应压缩第四层:超长用户消息内容截断** (`src/anthropic/compressor.rs`, `src/anthropic/handlers.rs`)
- 新增 `compress_long_messages_pass()` 函数,截断超长的 User 消息 content保留头部尾部附加省略标记
-`adaptive_shrink_request_body` 的三层策略之后增加第四层兜底,解决单条消息过大(如粘贴整个文件)导致自适应压缩空转的问题
- 动态计算截断阈值:初始为最大消息字符数的 3/4每轮递减 3/4最低 8192 字符
- 日志新增 `final_message_content_max_chars` 字段便于排查
## [v1.0.16] - 2026-02-15
### Fixed
- **请求体日志仅在 upstream 报错时输出完整内容** (`src/anthropic/handlers.rs`)
- 移除发送前的完整请求体 DEBUG 日志(`sensitive-logs` 模式下每次请求都输出几十 KB JSON统一只输出字节大小
- upstream 报错时在 `sensitive-logs` 模式下以 ERROR 级别输出完整请求体(截断 base64用于诊断 400/502 等错误
## [v1.0.15] - 2026-02-15
### Added
- **Opus 4.6 1M 上下文窗口支持** (`src/anthropic/types.rs`, `src/anthropic/handlers.rs`, `src/anthropic/stream.rs`)
- 新增 `get_context_window_size()` 函数Opus 4.6 返回 1,000,000 tokens其他模型返回 200,000 tokens
- 删除硬编码 `CONTEXT_WINDOW_SIZE` 常量,改用动态计算
- `MAX_BUDGET_TOKENS` 从 24,576 提升到 128,000
- `Model` 结构体新增 `context_length``max_completion_tokens``thinking` 字段
- **Agentic 模型变体** (`src/anthropic/converter.rs`, `src/anthropic/handlers.rs`)
- 新增 sonnet-agentic、opus-4.5-agentic、opus-4.6-agentic、haiku-agentic 四个模型变体
- `map_model()` 自动剥离 `-agentic` 后缀再映射
- Agentic 模型注入专用系统提示,引导自主工作模式
- **Thinking level 后缀** (`src/anthropic/handlers.rs`)
- 支持 `-thinking-minimal`(512)、`-thinking-low`(1024)、`-thinking-medium`(8192)、`-thinking-high`(24576)、`-thinking-xhigh`(32768) 后缀
- **工具压缩** (`src/anthropic/tool_compression.rs` 新建)
- 20KB 阈值两步压缩:简化 input_schema → 按比例截断 description最短 50 字符)
- **截断检测** (`src/anthropic/truncation.rs` 新建)
- 4 种截断类型的启发式检测(空输入、无效 JSON、缺少字段、未闭合字符串
- 工具 JSON 解析失败时自动检测截断并生成软失败消息
### Changed
- 工具调用仅含 tool_use 时占位符从 `" "` 改为 `"."`,提升语义清晰度
## [v1.0.14] - 2026-02-15
### Fixed
- **sensitive-logs 模式下请求体日志截断** (`src/kiro/provider.rs`, `src/anthropic/handlers.rs`)
- 400 错误日志中的 `request_body` 字段改用 `truncate_body_for_log()` 截断(保留头尾各 1200 字符),避免输出包含大量 base64 图片数据的完整请求体
- 工具输入 JSON 解析失败日志中的 `request_body` 字段改用 `truncate_middle()` 截断
- 新增 `KiroProvider::truncate_body_for_log()` 函数,正确处理 UTF-8 多字节字符边界
## [v1.0.13] - 2026-02-14
### Fixed
- **请求体大小预检输出 image_bytes 归因信息** (`src/anthropic/handlers.rs`)
- 新增 `total_image_bytes()` 函数,计算 KiroRequest 中所有图片 base64 数据的总字节数
- 错误提示信息增加 image_bytes 和 non-image bytes 字段,便于排查请求体大小归因
## [v1.0.12] - 2026-02-14
### Fixed
- **WebSearch 仅纯搜索请求走本地处理** (`src/anthropic/websearch.rs`, `src/anthropic/handlers.rs`)
- 新增 `should_handle_websearch_request()` 精确判断:仅当 tool_choice 强制选择 web_search、tools 仅含 web_search 单工具、或用户消息包含 `Perform a web search for the query:` 前缀时,才路由到本地 WebSearch 处理
- 混合工具场景web_search + 其他工具)改为剔除 web_search 后转发 upstream避免普通对话被误当成搜索查询
- 新增 `strip_web_search_tools()` 从 tools 列表中移除 web_search 工具
- 搜索查询提取增加空白归一化处理
## [v1.0.11] - 2026-02-14
### Added
- **自适应二次压缩策略** (`src/anthropic/handlers.rs`)
- 请求体超过 `max_request_body_bytes` 阈值时,自动迭代压缩:逐步降低 tool_result/tool_use_input 截断阈值,最后按轮移除最老历史消息
- 最多迭代 32 轮,避免极端输入导致过长 CPU 消耗
- `post_messages``post_messages_cc` 均支持自适应压缩
- **压缩后 tool_use/tool_result 配对修复** (`src/anthropic/compressor.rs`)
- 新增 `repair_tool_pairing_pass()`:历史截断后自动移除孤立的 tool_use 和 tool_result
- 解决截断破坏跨消息 tool_use→tool_result 配对导致 upstream 返回 400 "Improperly formed request" 的问题
- **stable 版 `floor_char_boundary` 工具函数** (`src/common/utf8.rs`)
- 新增 `common::utf8` 模块,提供 stable Rust 下的 `floor_char_boundary()` 实现
- 统一替换项目中散落的 `str::floor_char_boundary()` nightly 调用
### Fixed
- **WebSearch 支持混合工具列表** (`src/anthropic/websearch.rs`)
- `has_web_search_tool()` 改为只要 tools 中包含 web_search按 name 或 type 判断)即走本地处理,不再要求 tools 仅有一个
- `extract_search_query()` 改为取最后一条 user 消息,更符合多轮对话场景
- 新增非流式(`stream: false`)响应支持,返回完整 JSON 而非 SSE 流
### Changed
- **迁移 `floor_char_boundary` 调用到 `common::utf8` 模块** (`src/anthropic/compressor.rs`, `src/anthropic/stream.rs`, `src/admin/service.rs`, `src/kiro/token_manager.rs`, `src/kiro/provider.rs`)
- 移除各文件中重复的 `floor_char_boundary` 内联实现,统一使用 `crate::common::utf8::floor_char_boundary`
## [v1.0.10] - 2026-02-12
### Fixed
- **配额耗尽返回 429 而非 502** (`src/anthropic/handlers.rs`, `src/kiro/provider.rs`)
- 所有凭据配额耗尽时返回 `429 Too Many Requests``rate_limit_error`),而非 `502 Bad Gateway`
- 余额刷新时主动禁用低余额凭据(余额 < 1.0402 分支同步清零余额缓存
- **亲和性检查不再触发限流** (`src/kiro/token_manager.rs`)
- 亲和性检查改用 `check_rate_limit` 只读探测消除"检查本身消耗速率配额"的恶性循环
- 亲和性分流日志提升至 info 级别并脱敏 user_id便于生产监控热点凭据
### Added
- **请求体大小预检** (`src/anthropic/handlers.rs`, `src/model/config.rs`)
- 新增 `max_request_body_bytes` 配置项序列化后拦截超大请求避免无效 upstream 往返
### Changed
- **移除无意义的 max_tokens 调整逻辑** (`src/anthropic/handlers.rs`)
- 删除 max_tokens 超限警告日志和调整逻辑因为该值实际不传递给 Kiro upstream
## [v1.0.9] - 2026-02-12
### Fixed
- **修复 upstream 合并丢失的功能** (`src/anthropic/stream.rs`)
- 恢复 `stop_reason` 优先级逻辑高优先级原因可覆盖低优先级model_context_window_exceeded > max_tokens > tool_use > end_turn
- 注释掉重复的 `content_block_start` 日志,避免日志噪音
- 修复 `contextUsageEvent` 日志格式保留4位小数
- 移除冗余的 `find_char_boundary` 函数,改用标准库 `str::floor_char_boundary()`
## [v1.0.8] - 2026-02-12
### Added
- **批量导入 token.json** (`src/admin/service.rs`, `src/admin/types.rs`)
- 新增 `import_token_json` 接口,支持批量导入官方 token.json 格式凭据
- 自动映射 provider/authMethod 字段,支持 dry-run 预览模式
- 去重检测:通过 refreshToken 前缀匹配避免重复导入
- **缓存余额查询接口** (`src/admin/handlers.rs`, `src/admin/router.rs`)
- 新增 `GET /admin/credentials/balances/cached` 端点
- 返回所有凭据的缓存余额信息(含 TTL 和缓存时间)
### Changed
- **用户亲和性支持** (`src/kiro/token_manager.rs`, `src/kiro/provider.rs`)
- 新增 `UserAffinityManager`:用户与凭据绑定,保持会话连续性
- `acquire_context_for_user` 方法支持按 user_id 获取绑定凭据
- 亲和性过期时间可配置,默认 30 分钟
- **余额缓存动态 TTL** (`src/kiro/token_manager.rs`)
- 基于使用频率动态调整缓存 TTL高频用户更短 TTL
- 新增 `update_balance_cache``get_all_cached_balances` 方法
- 缓存持久化到 `kiro_balance_cache.json`
- **请求压缩管道** (`src/anthropic/converter.rs`, `src/anthropic/middleware.rs`)
- `AppState` 新增 `compression_config` 字段
- `convert_request` 支持 `CompressionConfig` 参数
- 图片压缩、空白压缩、上下文截断等功能集成
- **凭据级代理配置** (`src/kiro/provider.rs`)
- KiroProvider 支持按凭据动态选择代理
- 新增 `get_client_for_credential` 方法,缓存凭据级 client
- API 请求和 MCP 请求均使用凭据的 `effective_proxy()`
- **API Region 分离** (`src/kiro/provider.rs`)
- `base_url``mcp_url``base_domain` 使用 `effective_api_region()`
- 支持 Token 刷新和 API 调用使用不同 region
- **handlers 传递 user_id** (`src/anthropic/handlers.rs`)
- 从请求 metadata 提取 user_id 并传递给 provider
- 支持用户亲和性功能
### Fixed
- **修复 mask_user_id UTF-8 panic** (`src/anthropic/handlers.rs`)
- 使用 `chars()` 按字符而非字节切片,避免多字节字符导致 panic
## [v1.0.7] - 2026-02-10
### Added
- **图片 Token 估算与压缩模块** (`src/image.rs`)
- 新增 `estimate_image_tokens()`: 从 base64 数据解析图片尺寸并估算 token 数
- 新增 `process_image()`: 根据配置对大图进行缩放压缩
- 实现 Anthropic 官方公式: `tokens = (width × height) / 750`
- 支持 JPEG/PNG/GIF/WebP 格式
### Changed
- **Token 计算支持图片** (`src/token.rs`)
- `count_all_tokens_local()` 现在处理 `type: "image"` 的 ContentBlock
- 调用 `estimate_image_tokens()` 计算图片 token解决之前图片 token 被计为 0 的问题
- **协议转换支持图片压缩** (`src/anthropic/converter.rs`)
- `process_message_content()` 新增图片压缩处理,根据配置自动缩放超限图片
- 新增 `count_images_in_request()` 统计请求中图片总数,用于判断多图模式
- 缩放后记录日志: `图片已缩放: (原始尺寸) -> (缩放后尺寸), tokens: xxx`
- **压缩配置新增图片参数** (`src/model/config.rs`)
- `image_max_long_edge`: 长边最大像素,默认 1568Anthropic 推荐值)
- `image_max_pixels_single`: 单张图片最大总像素,默认 1,150,000约 1600 tokens
- `image_max_pixels_multi`: 多图模式下单张最大像素,默认 4,000,0002000×2000
- `image_multi_threshold`: 触发多图限制的图片数量阈值,默认 20
### Dependencies
- 新增 `image` crate (0.25): 图片处理(支持 JPEG/PNG/GIF/WebP
- 新增 `base64` crate (0.22): Base64 编解码
## [v1.0.6] - 2026-02-10
### Changed
- **压缩统计日志改用字节单位** (`src/anthropic/handlers.rs`)
- 移除不准确的 token 估算(`compressed_input_tokens``tokens_saved`),改为直接输出字节数
- 字段重命名:`whitespace_saved``whitespace_bytes_saved` 等,明确单位语义
- 注释更新:说明字节统计用于排查 upstream 请求体大小限制
### Added
- **日志脱敏工具模块** (`src/common/redact.rs`)
- `redact_opt_string`: Option<String> 脱敏为存在性表示
- `mask_email`: 邮箱脱敏(保留首字符)
- `mask_aws_account_id_in_arn`: AWS ARN 中 account id 脱敏
- `mask_url_userinfo`: URL userinfo 脱敏
- `mask_user_agent_machine_id`: User-Agent 中 machine_id 脱敏
## [v1.0.5] - 2026-02-09
### Changed
- **请求日志输出压缩前后 token 估算** (`src/anthropic/converter.rs`, `src/anthropic/handlers.rs`)
- `ConversionResult` 新增 `compression_stats` 字段,将压缩统计从 converter 内部返回给调用方
- `post_messages` / `post_messages_cc``convert_request()` 之前估算 input tokens`Received` 日志追加 `estimated_input_tokens`
- 压缩完成后输出 token 对比日志:`estimated_input_tokens``compressed_input_tokens``tokens_saved` 及各项压缩明细
- WebSearch 分支复用已有估算值,消除重复的 `count_all_tokens` 调用
- **`count_all_tokens` 改为接受借用** (`src/token.rs`)
- 参数从按值传递改为引用(`&str``&[Message]``&Option<Vec<T>>`),消除 handlers 中的深拷贝开销
- **历史截断统计增加字节数** (`src/anthropic/compressor.rs`)
- `CompressionStats` 新增 `history_bytes_saved` 字段,`total_saved()` 包含历史截断字节数
- `compress_history_pass` 返回 `(turns_removed, bytes_saved)` 元组token 估算准确计入历史截断
## [v1.0.4] - 2026-02-09
### Changed
- **Docker 构建优化**: 引入 `cargo-chef` 实现依赖层缓存,大幅加速重复构建
- 新增 `planner` 阶段生成依赖 recipe`builder` 阶段先编译依赖再编译源码
- Docker 层缓存使得仅源码变更时无需重新编译所有依赖
- **GitHub Actions Docker 构建缓存**: 启用 GHA 缓存(`cache-from/cache-to: type=gha`
- **Cargo.toml 优化**:
- `lto``true`fat LTO改为 `"thin"`,加快编译速度同时保持较好的优化效果
- `tokio` features 从 `full` 精简为实际使用的 5 个 feature`rt-multi-thread`, `macros`, `net`, `time`, `sync`),减小编译体积
## [v1.0.3] - 2026-02-09
### Fixed
- **opus4-6 上下文超限错误识别** (`src/anthropic/handlers.rs`)
-`Improperly formed request` 纳入输入过长错误检测,返回 Claude Code 可识别的 `400 Input is too long` 而非 `502 Bad Gateway`
- **Opus 4.6 模型 ID 移除时间日期** (`src/anthropic/handlers.rs`)
- `claude-opus-4-6-20260206``claude-opus-4-6`
- **post_messages 借用冲突编译错误** (`src/anthropic/handlers.rs`)
-`override_thinking_from_model_name` 调用移至 `user_id` 提取之前,修复 E0502 借用冲突
### Added
- **模型 "thinking" 后缀支持** (`src/anthropic/handlers.rs`, `src/anthropic/converter.rs`)
- 模型名含 `-thinking` 后缀时自动覆写 thinking 配置opus4.6 用 adaptive + high effort其他用 enabled
- 模型列表新增 sonnet/opus4.5/opus4.6/haiku 的 thinking 变体
### Docs
- **README.md 补充输入压缩配置文档**
- 新增"输入压缩"章节,说明 5 层压缩管道机制和 10 个可配置参数
## [v1.0.2] - 2026-02-09
### Fixed
- **opus4-6 上下文超限错误识别** (`src/anthropic/handlers.rs`)
-`Improperly formed request` 纳入输入过长错误检测,返回 Claude Code 可识别的 `400 Input is too long` 而非 `502 Bad Gateway`
- **Opus 4.6 模型 ID 移除时间日期** (`src/anthropic/handlers.rs`)
- `claude-opus-4-6-20260206``claude-opus-4-6`
- **post_messages 借用冲突编译错误** (`src/anthropic/handlers.rs`)
-`override_thinking_from_model_name` 调用移至 `user_id` 提取之前,修复 E0502 借用冲突
### Added
- **模型 "thinking" 后缀支持** (`src/anthropic/handlers.rs`, `src/anthropic/converter.rs`)
- 模型名含 `-thinking` 后缀时自动覆写 thinking 配置opus4.6 用 adaptive + high effort其他用 enabled
- 模型列表新增 sonnet/opus4.5/opus4.6/haiku 的 thinking 变体
### Docs
- **README.md 补充输入压缩配置文档**
- 新增"输入压缩"章节,说明 5 层压缩管道机制和 10 个可配置参数
## [v1.0.1] - 2026-02-08
### Fixed
- **历史截断字符统计口径修正** (`src/anthropic/compressor.rs`)
- `max_history_chars` 从按字节 `.len()` 改为按字符 `.chars().count()`,与配置语义一致
- **remove_thinking_blocks 不再全局 trim** (`src/anthropic/compressor.rs`)
- 移除末尾 `.trim()`,避免意外吞掉原始内容的首尾空白
- **token.json 导入注释/逻辑统一** (`src/admin/service.rs`)
- 更新注释:`builder-id → idc`(与实际映射一致)
- 删除 `auth_method == "builder-id"` 死分支
- **Admin UI 验活开关 added=0 卡住修复** (`admin-ui/src/components/import-token-json-dialog.tsx`)
- `enableVerify` 开启但无新增凭据时,直接跳转 result 步骤而非卡在 preview
- **工具描述截断 max_description_chars=0 语义修正** (`src/anthropic/converter.rs`)
- `0` 现在表示"不截断",而非截断为空字符串
### Added
- **输入压缩管道** (`src/anthropic/compressor.rs`)
- 新增 5 层压缩管道,规避 Kiro upstream 请求体大小限制
- 空白压缩:连续空行(3+)→2行行尾空格移除保留行首缩进
- thinking 块处理:支持 discard/truncate/keep 三种策略
- tool_result 智能截断:按行截断保留头尾,行数不足时回退字符级截断
- tool_use input 截断:递归截断 JSON 值中的大字符串
- 历史截断:保留系统消息对,按轮数/字符数从前往后成对移除
- 12 个单元测试覆盖所有压缩层和边界条件
- **CompressionConfig 配置结构体** (`src/model/config.rs`)
- 新增 `compression` 配置字段,支持通过 JSON 配置文件调整参数
- 10 个可配置参数总开关、空白压缩、thinking 策略、各截断阈值、历史限制
- 工具描述截断阈值从硬编码 10000 改为可配置(默认 4000
- **合并 upstream 新功能**: 从 upstream/master 拉取并融合大量新特性
- **负载均衡模式** (`src/model/config.rs`, `src/kiro/token_manager.rs`, `src/admin/`)
- 新增 `loadBalancingMode` 配置项,支持 `priority`(默认)和 `balanced`Least-Used两种模式
- Admin API 新增 `GET/PUT /config/load-balancing` 端点
- 前端新增负载均衡模式切换开关
- **凭据统计与持久化** (`src/kiro/token_manager.rs`)
- 新增 `success_count``last_used_at` 字段,跟踪每个凭据的调用统计
- 新增 `save_stats_debounced` 防抖持久化机制,`Drop` 时自动保存
- 新增 `refreshTokenHash` 字段用于前端重复检测
- **前端批量操作** (`admin-ui/src/components/dashboard.tsx`)
- 批量导入对话框 (`BatchImportDialog`)
- 批量验活对话框 (`BatchVerifyDialog`)
- 分页控件、批量选择/删除/恢复/验活功能
- 凭据卡片新增 Checkbox 选择、email 显示、订阅等级、成功次数、剩余用量等信息
- **配置文件路径管理** (`src/model/config.rs`)
- `Config` 新增 `config_path` 字段和 `load()`/`save()` 方法,支持配置回写
- **前端依赖**: 新增 `@radix-ui/react-checkbox` 组件
### Changed
- `convert_request()` 签名新增 `&CompressionConfig` 参数 (`src/anthropic/converter.rs`)
- `convert_tools()` 描述截断阈值参数化 (`src/anthropic/converter.rs`)
- `AppState` 新增 `compression_config` 字段 (`src/anthropic/middleware.rs`)
- `create_router_with_provider()` 新增 `CompressionConfig` 参数 (`src/anthropic/router.rs`)
- 重构 README.md 配置文档,提升新用户上手体验
- 明确配置文件默认路径:当前工作目录(或通过 `-c`/`--config``--credentials` 参数指定)
- 添加 JSON 注释警告:移除所有带 `//` 注释的示例,提供可直接复制的配置
- 修正字段必填性:仅 `apiKey` 为必填,其他字段均有默认值
- 新增命令行参数说明表格(`-c`, `--credentials`, `-h`, `-V`
- 补充遗漏的 `credentialRpm` 字段说明(凭据级 RPM 限流)
- 使用表格形式展示配置字段,标注必填/可选和默认值
- 优化 debug 日志中请求体的输出长度 (`src/anthropic/handlers.rs`)
- 新增 `truncate_middle()` 函数:截断字符串中间部分,保留头尾各 1200 字符
- 正确处理 UTF-8 多字节字符边界,不会截断中文
- 仅在启用 `sensitive-logs` feature 时生效,减少日志噪音
### Fixed
- **[P0] API Key 日志泄露修复** (`src/main.rs`)
- info 级别不再打印 API Key 前半段,仅显示末 4 位和长度
- 完整前缀仅在 `sensitive-logs` feature 的 debug 级别输出
- **[P2] 占位工具大小写变体重复插入** (`src/anthropic/converter.rs`)
- `collect_history_tool_names` 改为小写去重,避免 `read`/`Read` 等变体重复
- 占位工具 push 后同步更新 `existing_tool_names` 集合
- **[P1] 统计与缓存写盘非原子操作** (`src/kiro/token_manager.rs`, `src/admin/service.rs`)
- 统计数据和余额缓存改为临时文件 + 原子重命名,防止写入中断导致文件损坏
- **[P1] stop_reason 覆盖策略可能丢失信息** (`src/anthropic/stream.rs`)
- `set_stop_reason()` 改为基于优先级覆盖,高优先级原因可覆盖低优先级原因
- **[P2] snapshot 重复计算 SHA-256** (`src/kiro/token_manager.rs`)
- `CredentialEntry` 新增 `refresh_token_hash` 缓存字段
- Token 刷新时自动更新哈希,`snapshot()` 优先使用缓存避免重复计算
- **Clippy 警告修复** (`src/model/config.rs`)
- 修复 `field_reassign_with_default` 警告,改用结构体初始化语法
- **[P2] Assistant Prefill 静默丢弃** (`src/anthropic/converter.rs`, `src/anthropic/handlers.rs`)
- 末尾 `assistant` 消息prefill 场景)不再返回 400 错误,改为静默丢弃并回退到最后一条 `user` 消息
- Claude 4.x 已弃用 assistant prefillKiro API 也不支持,转换器在入口处截断消息列表
- 移除 `InvalidLastMessageRole` 错误变体,`build_history` 接受预处理后的消息切片
- **[P2] 凭据回写原子性** (`src/kiro/token_manager.rs`)
- `persist_credentials` 改为临时文件 + `rename` 原子替换
- 新增 `resolve_symlink_target` 辅助函数:优先 `canonicalize`,失败时用 `read_link` 解析 symlink
- 保留原文件权限,防止 umask 导致凭据文件权限放宽
- Windows 兼容:`rename` 前先删除已存在的目标文件
- 避免进程崩溃或并发调用导致凭据文件损坏
- 限制 `max_tokens` 最大值为 32000Kiro upstream 限制)
- 当用户设置超出限制的值时自动调整为 32000
- 记录 WARN 级别日志,包含原始值和调整后的值
- 涉及文件:`src/anthropic/handlers.rs`
- 工具输入 JSON 解析失败时的日志输出改为受 `sensitive-logs` feature 控制
- 默认仅输出 `buffer_len``request_body_bytes`(长度信息)
- 启用 `--features sensitive-logs` 时输出完整 `buffer``request_body`
- 涉及文件:`src/anthropic/handlers.rs`
- 修复 Kiro upstream 请求兼容性问题
- 空 content仅 tool_result/image时使用占位符避免 400
- 规范化工具 JSON Schema、补全空 description
- 禁用 reqwest 系统代理探测(仅支持显式 `config.proxy_url`
- 新增离线诊断脚本:`tools/diagnose_improper_request.py`
- 涉及文件:`src/anthropic/converter.rs``src/http_client.rs``tools/diagnose_improper_request.py``.gitignore`
- 优化 400 Bad Request "输入过长" 错误的日志输出 (`src/kiro/provider.rs`)
- 对于 `CONTENT_LENGTH_EXCEEDS_THRESHOLD` / `Input is too long` 错误,不再输出完整请求体(太占空间且无调试价值)
- 改为记录 `request_body_bytes`(字节数)和 `estimated_input_tokens`(估算 token 数)
- 新增 `estimate_tokens()` 函数:基于 CJK/非 CJK 字符比例估算 token 数量
- CJK 字符(中/日/韩): token 数 = 字符数 / 1.5
- 其他字符(英文等): token 数 = 字符数 / 3.5
- 新增 `is_input_too_long()``is_cjk_char()` 辅助函数
- 新增多维度设备指纹系统 (`src/kiro/fingerprint.rs`)
- 每个凭据生成独立的确定性指纹,模拟真实 Kiro IDE 客户端
- 支持 10+ 维度设备信息SDK 版本、Kiro 版本、Node.js 版本、操作系统、屏幕分辨率、CPU 核心数、时区等
- 提供 `user_agent()``x_amz_user_agent()` 方法构建请求头
- 参考 CLIProxyAPIPlus 实现,降低被检测风险
- 新增精细化速率限制系统 (`src/kiro/rate_limiter.rs`)
- 每日请求限制(默认 500 次/天)
- 请求间隔控制1-2 秒 + 30% 抖动)
- 指数退避策略30s → 5min倍数 1.5
- 暂停检测关键词匹配suspended, banned, quota exceeded 等)
- 新增独立冷却管理模块 (`src/kiro/cooldown.rs`)
- 分类冷却原因7 种类型速率限制、账户暂停、配额耗尽、Token 刷新失败等)
- 差异化冷却时长短冷却1-5 分钟vs 长冷却1-24 小时)
- 递增冷却机制(连续触发时延长冷却时间)
- 自动清理过期冷却
- 新增后台 Token 刷新模块 (`src/kiro/background_refresh.rs`)
- 独立后台任务定期检查即将过期的 Token
- 支持批量并发刷新(信号量控制)
- 可配置检查间隔、批处理大小、并发数
- 优雅关闭机制
- `MultiTokenManager` 新增增强方法
- `get_fingerprint()`: 获取凭据的设备指纹
- `is_credential_available()`: 综合检查凭据可用性(未禁用、未冷却、未超速率限制)
- `set_credential_cooldown()` / `clear_credential_cooldown()`: 冷却管理
- `get_expiring_credential_ids()`: 获取即将过期的凭据列表
- `start_background_refresh()`: 启动后台 Token 刷新任务
- `refresh_token_for_credential()`: 带优雅降级的 Token 刷新
- `record_api_success()` / `record_api_failure()`: 更新速率限制器状态
- `CredentialEntry` 结构体新增 `fingerprint` 字段,每个凭据独立生成设备指纹
- 修复 IDC 凭据 `fetch_profile_arn` 在某些 region 返回 `UnknownOperationException` 的问题
- 新增 `ListAvailableCustomizations` API 作为 `ListProfiles` 的回退方案
- 支持多 region 尝试:先尝试用户配置的 region失败则回退到 `us-east-1`
- 涉及文件:`src/kiro/token_manager.rs`
- 修复 `start_background_refresh` 后台刷新器生命周期问题Codex Review P1
- 问题:`refresher` 作为局部变量在函数返回后被 drop导致后台任务立即停止
- 解决:方法现在返回 `Arc<BackgroundRefresher>`,调用方需保持引用以维持任务运行
- 涉及文件:`src/kiro/token_manager.rs`
- 修复 `calculate_backoff` 退避时间可能超过配置上限的问题Codex Review P2
- 问题:添加抖动后未再次进行上限约束,可能导致实际等待时间超过 `backoff_max_ms`
- 解决:在添加抖动后再进行 `.min(max)` 约束
- 涉及文件:`src/kiro/rate_limiter.rs`
- 改进 `persist_credentials` 并发写入安全性Codex Review P1
- 问题:在锁外执行文件写入可能导致并发写入时旧快照覆盖新数据
- 解决:在持有 entries 锁的情况下完成序列化,确保快照一致性
- 涉及文件:`src/kiro/token_manager.rs`
- 修复 IDC 凭据返回 403 "The bearer token included in the request is invalid" 的问题
- 根本原因:`profile_arn` 只从第一个凭据获取并存储在全局 `AppState` 中,当使用 IDC 凭据时Bearer Token 来自 IDC 凭据,但 `profile_arn` 来自第一个凭据(可能是 Social 类型),导致 Token 和 profile_arn 不匹配
- 解决方案 1`call_api_with_retry` 中动态注入当前凭据的 `profile_arn`,确保 Token 和 profile_arn 始终匹配
- 解决方案 2IDC Token 刷新后自动调用 `ListProfiles` API 获取 `profileArn`IDC 的 OIDC 刷新不返回此字段)
- 新增 `inject_profile_arn()` 辅助方法,解析请求体 JSON 并覆盖 `profileArn` 字段
- 新增 `fetch_profile_arn()` 方法,通过 CodeWhisperer ListProfiles API 获取 profileArn
- 涉及文件:`src/kiro/provider.rs`, `src/kiro/token_manager.rs`
- 新增批量导入 token.json 功能
- 后端:新增 `POST /api/admin/credentials/import-token-json` 端点
- 支持解析官方 token.json 格式(含 `provider``refreshToken``clientId``clientSecret` 等字段)
-`provider` 字段自动映射 `authMethod`BuilderId → idc, IdC → idc, Social → social
- 支持 dry-run 预览模式,返回详细的导入结果(成功/跳过/无效)
- 通过 refreshToken 前缀匹配自动去重,避免重复导入
- 前端:新增"导入 token.json"对话框组件
- 支持拖放上传 JSON 文件或直接粘贴 JSON 内容
- 三步流程:输入 → 预览 → 结果
- 涉及文件:
- `src/admin/types.rs`(新增 `TokenJsonItem``ImportTokenJsonRequest``ImportTokenJsonResponse` 等类型)
- `src/admin/service.rs`(新增 `import_token_json()` 方法)
- `src/admin/handlers.rs`(新增 `import_token_json` handler
- `src/admin/router.rs`(添加路由)
- `src/kiro/token_manager.rs`(新增 `has_refresh_token_prefix()` 方法)
- `admin-ui/src/types/api.ts`(新增导入相关类型)
- `admin-ui/src/api/credentials.ts`(新增 `importTokenJson()` 函数)
- `admin-ui/src/hooks/use-credentials.ts`(新增 `useImportTokenJson()` hook
- `admin-ui/src/components/import-token-json-dialog.tsx`(新建)
- `admin-ui/src/components/dashboard.tsx`(添加导入按钮)
- 修复字符串切片在多字节字符中间切割导致 panic 的风险DoS 漏洞)
- `generate_fingerprint()``has_refresh_token_prefix()` 使用 `floor_char_boundary()` 安全截断
- 涉及文件:`src/admin/service.rs`, `src/kiro/token_manager.rs`
- 修复日志截断在多字节字符中间切割导致 panic 的问题
- `truncate_for_log()` 使用 `floor_char_boundary()` 安全截断 UTF-8 字符串
- 删除 `stream.rs` 中冗余的 `find_char_boundary()` 函数,直接使用标准库方法
- 涉及文件:`src/kiro/provider.rs`, `src/anthropic/stream.rs`
- 移除历史消息中孤立的 tool_use无对应 tool_result
- Kiro API 要求 tool_use 必须有配对的 tool_result否则返回 400 Bad Request
- 新增 `remove_orphaned_tool_uses()` 函数清理孤立的 tool_use
- 涉及文件:`src/anthropic/converter.rs`
- 修复 `/cc/v1/messages` 缓冲流 ping 定时器首次立即触发的问题
-`interval()` 改为 `interval_at(Instant::now() + ping_period, ping_period)`
- 现在首个 ping 会在 25 秒后触发,与 `/v1/messages` 行为一致
- 涉及文件:`src/anthropic/handlers.rs`
- 修复 Clippy `collapsible_if` 警告
- 使用 let-chains 语法合并嵌套 if 语句
- 涉及文件:`src/anthropic/stream.rs`
- 增强 400 Bad Request 错误日志,记录完整请求信息
- 移除请求体截断限制,记录完整的 `request_body`
- 新增 `request_url``request_headers` 字段
- 新增 `format_headers_for_log()` 辅助函数,对 Authorization 头进行脱敏处理
- 删除不再使用的 `truncate_for_log()` 函数YAGNI 原则)
- 涉及文件:`src/kiro/provider.rs`
- 改进凭据选择算法:同优先级内实现负载均衡
- 第一优先级:使用次数最少
- 第二优先级:余额最多(使用次数相同时)
- 第三优先级:轮询选择(使用次数和余额完全相同时,避免总选第一个)
- 新增 `selection_rr` 原子计数器用于轮询抖动
- 新增 `select_best_candidate_id()` 方法实现三级排序逻辑
- 涉及文件:`src/kiro/token_manager.rs`
- 修复测试代码使用 `serde_json::json!` 构造 Tool 对象导致的类型不匹配问题
- 改用 `Tool` 结构体直接构造,确保类型安全
- 涉及文件:`src/anthropic/websearch.rs`
- 修复 `select_best_candidate_id()` 中 NaN 余额处理问题
- 在评分阶段将 NaN/Infinity 余额归一化为 0.0
- 避免 NaN 被 `total_cmp` 视为最大值导致错误的凭据选择
- 避免 NaN 导致 `scored` 被完全过滤后除零 panic
- 涉及文件:`src/kiro/token_manager.rs`
- 新增 `system` 字段格式兼容性支持(`src/anthropic/types.rs`
- 支持字符串格式:`"system": "You are a helpful assistant"`new-api 等网关添加的系统提示词)
- 支持数组格式:`"system": [{"type": "text", "text": "..."}]`Claude Code 原生格式)
- 自动将字符串格式转换为单元素数组,保持内部处理一致性
- 新增 6 个单元测试验证格式兼容性
- 新增请求体大小限制50MB`DefaultBodyLimit::max(50 * 1024 * 1024)`
- 涉及文件:`src/anthropic/router.rs`
- 调整全局禁用恢复时间:`GLOBAL_DISABLE_RECOVERY_MINUTES` 从 10 分钟降至 5 分钟
- 加快模型暂时不可用后的自动恢复速度
- 调整总重试次数硬上限:`MAX_TOTAL_RETRIES` 从 5 降至 3
- 进一步减少无效重试开销,加快故障转移速度
- 余额初始化改为顺序查询,每次间隔 0.5 秒避免触发限流
- 从并发查询改为顺序查询(`initialize_balances()`
- 移除 30 秒整体超时机制
- 涉及文件:`src/kiro/token_manager.rs`
- 修复 assistant 消息仅包含 tool_use 时 content 为空导致 Kiro API 报错的问题
- 当 text_content 为空且存在 tool_uses 时,使用 "OK" 作为占位符
- 涉及文件:`src/anthropic/converter.rs`
- 修复 `MODEL_TEMPORARILY_UNAVAILABLE` 错误检测逻辑未实际调用的问题
-`call_mcp()``call_api()` 中添加错误检测和熔断触发逻辑
- 移除 `report_model_unavailable()``disable_all_credentials()``#[allow(dead_code)]` 标记
- 现在当检测到该错误时会正确触发全局熔断机制
- 新增 WebSearch 工具支持(`src/anthropic/websearch.rs`
- 实现 Anthropic WebSearch 请求到 Kiro MCP 的转换
- 支持 SSE 流式响应,生成完整的搜索结果事件序列
- 自动检测纯 WebSearch 请求tools 仅包含 web_search并路由到专用处理器
- 新增 MCP API 调用支持(`src/kiro/provider.rs`
- 新增 `call_mcp()` 方法,支持 WebSearch 等工具调用
- 新增 `mcp_url()``build_mcp_headers()` 方法
- 完整的重试和故障转移逻辑
- 新增凭据级 `region` 字段,用于 OIDC token 刷新时指定 endpoint 区域
- 未配置时回退到 config.json 的全局 region
- API 调用仍使用 config.json 的 region
- 新增凭据级 `machineId` 字段,支持每个凭据使用独立的机器码
- 支持 64 字符十六进制和 UUID 格式(自动标准化)
- 未配置时回退到 config.json 的 machineId都未配置时由 refreshToken 派生
- 启动时自动补全并持久化到配置文件
- 新增 GitHub Actions Docker 构建工作流(`.github/workflows/docker-build.yaml`
- 支持 linux/amd64 和 linux/arm64 双架构
- 推送到 GitHub Container Registry
- 版本号升级至 2026.1.5
- TLS 库从 native-tls 切换至 rustlsreqwest 依赖调整)
- `authMethod` 自动推断:未指定时根据是否有 clientId/clientSecret 自动判断为 idc 或 social
- 移除 web_search/websearch 工具过滤(`is_unsupported_tool` 现在返回 false
- 修复 machineId 格式兼容性问题,支持 UUID 格式自动转换为 64 字符十六进制
### Removed
- 移除 `current_id` 概念(后端和前端)
- 后端:移除 `MultiTokenManager.current_id` 字段和相关方法(`switch_to_next``select_highest_priority``select_by_balance``credentials`
- 后端:移除 `ManagerSnapshot.current_id` 字段
- 后端:移除 `CredentialStatusItem.is_current` 字段
- 前端:移除 `CredentialsStatusResponse.currentId``CredentialStatusItem.isCurrent`
- 原因:多用户并发访问时,"当前凭据"概念无意义,凭据选择由 `acquire_context_for_user()` 动态决定
- 新增启动时余额初始化功能
- `initialize_balances()`: 启动时并发查询所有凭据余额并更新缓存
- 整体超时 30 秒,避免阻塞启动流程
- 初始化失败或超时时输出警告日志
- 改进凭据选择算法:从单一"使用次数最少"改为两级排序
- 第一优先级:使用次数最少
- 第二优先级:余额最多(使用次数相同时)
- 未初始化余额的凭据会被降级处理,避免被优先选中
- 移除前端"当前活跃"凭据展示
- 前端:移除凭据卡片的"当前"高亮和 Badge
- 前端:移除 Dashboard 中的"当前活跃"统计卡片
- 统计卡片布局从 3 列调整为 2 列
- 新增 `sensitive-logs` feature flag显式启用才允许打印潜在敏感信息仅用于排障
- 默认关闭Kiro 请求体只输出长度,凭证只输出摘要信息
- 启用方式:`cargo build --features sensitive-logs`
- 修复 SSE 流 ping 保活首次立即触发的问题
- 使用 `interval_at(Instant::now() + ping_period, ping_period)` 延迟首次触发
- 避免连接建立后立即发送无意义的 ping 事件
- 改进服务启动错误处理
- 绑定监听地址失败时输出错误日志并退出exit code 1
- HTTP 服务异常退出时输出错误日志并退出exit code 1
- 修复合并 upstream 后 `CredentialEntry` 结构体字段缺失导致的编译错误
- 添加 `disable_reason: Option<DisableReason>` 字段(公共 API 展示用)
- 添加 `auto_heal_reason: Option<AutoHealReason>` 字段(内部自愈逻辑用)
- 修复禁用原因字段不同步问题
- `report_failure()`: 禁用时同步设置两个字段
- `set_disabled()`: 启用/禁用时同步设置/清除两个字段
- `reset_and_enable()`: 重置时同步清除两个字段
- 自愈循环:重新启用凭据时同步清除 `disable_reason`
- `mark_insufficient_balance()`: 清除 `auto_heal_reason` 防止被自愈循环错误恢复
- 重命名内部字段以提高可读性
- `DisabledReason``AutoHealReason`(自愈原因枚举)
- `disabled_reason``auto_heal_reason`(自愈原因字段)
- 日志中的 `user_id` 现在会进行掩码处理,保护用户隐私
- 长度 > 25保留前13后8字符`user_f516339a***897ac7`
- 长度 13-25保留前4后4字符
- 长度 ≤ 12完全掩码为 `***`
- 新增缓存余额查询 API`GET /credentials/balances/cached`
- 后端:`CachedBalanceInfo` 结构体、`get_all_cached_balances()` 方法
- 前端:凭据卡片直接显示缓存余额和更新时间
- 30 秒自动轮询更新,缓存超过 1 分钟时点击强制刷新
- 新增 Bonus 用量包支持(`src/kiro/model/usage_limits.rs`
- 新增 `Bonus` 结构体,支持 GIFT 类型的额外用量包
- 新增 `Bonus::is_active()` 方法,按状态/过期时间判断是否激活
- `usage_limit()``current_usage()` 现在会合并基础额度、免费试用额度和所有激活的 bonuses
- 新增 Kiro Web Portal API 模块(`src/kiro/web_portal.rs`
- 支持 CBOR 协议与 app.kiro.dev 通信
- 实现 `get_user_info()``get_user_usage_and_limits()` API
- 新增 `aggregate_account_info()` 聚合账号信息(套餐/用量/邮箱等)
- Admin UI 前端增强
- 新增数字格式化工具(`admin-ui/src/lib/format.ts`K/M/B 显示、Token 对格式化、过期时间格式化
- 新增统计相关 API 和 Hooks`getCredentialStats`, `resetCredentialStats`, `resetAllStats`
- 新增账号信息 API`getCredentialAccountInfo`, `useCredentialAccountInfo`
- 扩展 `CredentialStatusItem` 添加统计字段调用次数、Token 用量、最后调用时间等)
- 新增完整的账号信息类型定义(`AccountAggregateInfo`, `CreditsUsageSummary` 等)
- 新增 `serde_cbor` 依赖用于 CBOR 编解码
- 修复手动查询余额后列表页面不显示缓存余额的问题
- `get_balance()` 成功后调用 `update_balance_cache()` 更新缓存
- 现在点击"查看余额"后,列表页面会正确显示缓存的余额值
- 修复关闭余额弹窗后卡片不更新缓存余额的问题
- 弹窗关闭时调用 `queryClient.invalidateQueries({ queryKey: ['cached-balances'] })`
- 确保卡片和弹窗使用的两个独立数据源保持同步
- 增强 Token 刷新日志,添加凭证 ID 追踪
- 新增 `refresh_token_with_id()` 函数支持传入凭证 ID
- 日志现在包含 `credential_id` 字段,便于多凭据环境下的问题排查
- 调整重试策略:单凭据最大重试次数 3→2单请求最大重试次数 9→5
- `MAX_RETRIES_PER_CREDENTIAL`: 3 → 2
- `MAX_TOTAL_RETRIES`: 9 → 5
- `MAX_FAILURES_PER_CREDENTIAL`: 3 → 2
- 减少无效凭据的重试开销,加快故障转移速度
- 新增用户亲和性绑定功能:连续对话优先使用同一凭据(基于 `metadata.user_id`
- 新增 `src/kiro/affinity.rs` 模块,实现 `UserAffinityManager`
- 新增 `acquire_context_for_user()` 方法支持亲和性查询
- 亲和性绑定 TTL 为 30 分钟
- 新增余额感知故障转移:凭据失效时自动切换到余额最高的可用凭据
- 新增动态余额缓存 TTL 策略:
- 高频渠道10分钟内 ≥20 次调用10 分钟刷新
- 低频渠道30 分钟刷新
- 低余额渠道(余额 < 1.024 小时刷新
- 新增 `record_usage()` 方法自动记录凭据使用频率
- 新增负载均衡无亲和性绑定时优先分配到使用频率最低的凭据
- 新增 `DisableReason` 枚举区分凭据禁用原因失败次数余额不足模型不可用手动禁用
- 成功请求时自动重置 `MODEL_TEMPORARILY_UNAVAILABLE` 计数器避免跨时间累计触发
- 新增 `MODEL_TEMPORARILY_UNAVAILABLE` 错误检测和全局禁用机制
- 当该 500 错误发生 2 次时自动禁用所有凭据
- 5 分钟后自动恢复余额不足的凭据除外
- `CredentialEntrySnapshot` 新增 `disable_reason` 字段支持查询禁用原因
- 新增自动余额刷新成功请求后自动在后台刷新余额缓存基于动态 TTL 策略
- 新增 `spawn_balance_refresh()` 方法使用 `tokio::spawn` 异步刷新
- 新增 `should_refresh_balance()` 方法根据 TTL 判断是否需要刷新