mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 09:50:21 +08:00
feat: 新增 Thinking 整流器处理跨 Provider 签名错误 (#115)
当 Provider A 生成的 thinking 块被发送到 Provider B 时,签名验证会失败。 本次更新实现了自动整流机制,在遇到签名错误时自动清洗 thinking 块后重试。 主要更改: - 新增 ThinkingRectifier 整流器,移除 thinking 块和 signature 字段 - 新增 ThinkingSignatureException 异常类型 - ErrorClassifier 新增 Thinking 错误模式检测 - FallbackOrchestrator 支持整流后在当前候选重试 - Handler 层传递 request_body_ref 容器支持请求体动态修改 - Usage API 新增 has_rectified 字段标识整流过的请求 - 新增 THINKING_RECTIFIER_ENABLED 配置项控制功能开关 其他改进: - CacheAwareScheduler 支持 exact/convertible 候选分组排序 - StreamProcessor 预读阶段新增格式转换试验 - ProviderAPIKey.api_formats 改为可空(None 表示支持所有格式) - Dockerfile 修复 entrypoint.sh 换行符问题 Closes #115 Co-Authored-By: FredericMN <FredericMN@users.noreply.github.com>
This commit is contained in:
34
src/services/cache/aware_scheduler.py
vendored
34
src/services/cache/aware_scheduler.py
vendored
@@ -1084,10 +1084,12 @@ class CacheAwareScheduler:
|
||||
continue
|
||||
|
||||
# Key 直属 Provider,通过 api_formats 按端点格式筛选
|
||||
# api_formats=None 视为"全支持"(兼容历史数据)
|
||||
active_keys = [
|
||||
key
|
||||
for key in provider.api_keys
|
||||
if key.is_active and endpoint_format_str in (key.api_formats or [])
|
||||
if key.is_active
|
||||
and (key.api_formats is None or endpoint_format_str in key.api_formats)
|
||||
]
|
||||
if not active_keys:
|
||||
continue
|
||||
@@ -1264,21 +1266,31 @@ class CacheAwareScheduler:
|
||||
"""
|
||||
根据优先级模式对候选列表排序(数字越小越优先)
|
||||
|
||||
- provider: 提供商优先模式,保持原有顺序(按 Provider.provider_priority -> Key.internal_priority 排序,已由查询保证)
|
||||
Key.internal_priority 表示 Endpoint 内部优先级,同优先级内通过哈希分散负载均衡
|
||||
- global_key: 全局 Key 优先模式,按 Key.global_priority_by_format 升序排序(数字小的优先)
|
||||
有优先级的优先,NULL 的排后面
|
||||
同优先级内通过哈希分散实现负载均衡
|
||||
排序规则:
|
||||
1. exact 候选(needs_conversion=False)优先于 convertible 候选
|
||||
2. 在同一类型内,按优先级模式排序:
|
||||
- provider: 提供商优先模式,按 Provider.provider_priority -> Key.internal_priority 排序
|
||||
- global_key: 全局 Key 优先模式,按 Key.global_priority_by_format 排序
|
||||
"""
|
||||
if not candidates:
|
||||
return candidates
|
||||
|
||||
if self.priority_mode == self.PRIORITY_MODE_GLOBAL_KEY:
|
||||
# 全局 Key 优先模式:按 global_priority 分组,同组内哈希分散负载均衡
|
||||
return self._sort_by_global_priority_with_hash(candidates, affinity_key, api_format)
|
||||
# 按 needs_conversion 分组:exact 优先
|
||||
exact_candidates = [c for c in candidates if not c.needs_conversion]
|
||||
convertible_candidates = [c for c in candidates if c.needs_conversion]
|
||||
|
||||
# 提供商优先模式:保持原有顺序(provider_priority 排序已经由查询保证)
|
||||
return candidates
|
||||
if self.priority_mode == self.PRIORITY_MODE_GLOBAL_KEY:
|
||||
# 全局 Key 优先模式:分别对两组排序后合并
|
||||
sorted_exact = self._sort_by_global_priority_with_hash(
|
||||
exact_candidates, affinity_key, api_format
|
||||
)
|
||||
sorted_convertible = self._sort_by_global_priority_with_hash(
|
||||
convertible_candidates, affinity_key, api_format
|
||||
)
|
||||
return sorted_exact + sorted_convertible
|
||||
|
||||
# 提供商优先模式:exact 在前,convertible 在后(各组内部顺序已由构建时保证)
|
||||
return exact_candidates + convertible_candidates
|
||||
|
||||
def _sort_by_global_priority_with_hash(
|
||||
self,
|
||||
|
||||
Reference in New Issue
Block a user