SunSeekerX
584fa8c9c1
feat: 大规模性能优化 - Redis Pipeline 批量操作、索引系统、连接池优化
2025-12-31 02:08:47 +08:00
shaw
67c20fa30e
feat: 为 claude-official 账户添加 403 错误重试机制
...
针对 OAuth 和 Setup Token 类型的 Claude 账户,遇到 403 错误时:
- 休息 2 秒后进行重试
- 最多重试 2 次(总共最多 3 次请求)
- 重试后仍是 403 才标记账户为 blocked
同时支持流式和非流式请求,并修复了流式请求中的竞态条件问题。
2025-12-24 19:54:25 +08:00
shaw
8ec8a59b07
feat: claude账号新增支持拦截预热请求
2025-12-21 22:28:22 +08:00
shaw
638d2ff189
feat: 支持claude单账户开启串行队列
2025-12-19 22:29:57 +08:00
guoyongchang
26bfdd6892
[feat/cron-test-support]optimize.
2025-12-19 14:03:31 +08:00
guoyongchang
cd3f51e9e2
refactor: optimize cron test support feature
...
**优化内容:**
1. **验证和安全性加强**
- 移除cron验证重复,统一使用accountTestSchedulerService.validateCronExpression()方法
- 添加model参数类型和长度验证(max 256 chars)
- 限制cronExpression长度至100字符防止DoS攻击
- 双层验证:service层和route层都进行长度检查
2. **性能优化**
- 优化_refreshAllTasks()使用Promise.all()并行加载所有平台配置(之前是顺序加载)
- 改进错误处理,平台加载失败时继续处理其他平台
3. **数据管理改进**
- 为test config添加1年TTL过期机制(之前没有过期设置)
- 保证test history已有30天TTL和5条记录限制
4. **错误响应标准化**
- 统一所有API响应格式,确保error状态都包含message字段
- 改进错误消息的可读性和上下文信息
5. **用户体验改进**
- Vue组件使用showToast()替代原生alert()
- 移除console.error()改用toast通知用户
- 成功保存时显示成功提示
6. **代码整理**
- 移除未使用的maxConcurrentTests变量及其getStatus()中的引用
- 保持代码整洁性
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com >
2025-12-19 13:39:39 +08:00
guoyongchang
09cf951cdc
[feat/cron-test-support]done.
2025-12-19 10:25:43 +08:00
huajiwuyan
052e236a93
fix(scheduler): 恢复OpenAI 账号选择支持 priority + lastUsedAt
2025-12-15 23:17:44 +08:00
shaw
ce13e5ddb1
fix: console账号转发使用白名单透传header
2025-12-15 09:38:51 +08:00
DaydreamCoding
07633ddbf8
feat: enhance concurrency queue with health check and admin endpoints
...
- Add queue health check for fast-fail when overloaded (P90 > threshold)
- Implement socket identity verification with UUID token
- Add wait time statistics (P50/P90/P99) and queue stats tracking
- Add admin endpoints for queue stats and cleanup
- Add CLEAR_CONCURRENCY_QUEUES_ON_STARTUP config option
- Update documentation with troubleshooting and proxy config guide
2025-12-12 14:32:09 +08:00
LZY
51aa8dc381
fix:修复codex统计token问题
2025-12-10 22:56:25 +08:00
Wesley Liddick
4337af06d4
Merge pull request #791 from DaydreamCoding/feature/log-opt
...
fix: improve logging for client disconnections in relay services
2025-12-10 07:11:24 -05:00
QTom
8901994644
fix: improve logging for client disconnections in relay services
...
当客户端主动断开连接时,改为使用 INFO 级别记录而不是 ERROR 级别,
因为这是正常情况而非错误。
- ccrRelayService: 区分客户端断开与实际错误
- claudeConsoleRelayService: 区分客户端断开与实际错误
- claudeRelayService: 区分客户端断开与实际错误
- droidRelayService: 区分客户端断开与实际错误
2025-12-10 14:18:44 +08:00
QTom
3b9c96dff8
feat(queue): 优化用户消息队列锁释放时机
...
将队列锁释放时机从"请求完成后"提前到"请求发送后",因为 Claude API
限流(RPM)基于请求发送时刻计算,无需等待响应完成。
主要变更:
- 移除锁续租机制(startLockRenewal、refreshUserMessageLock)
- 所有 relay 服务在请求发送成功后立即释放锁
- 流式请求通过 onResponseStart 回调在收到响应头时释放
- 调整默认配置:timeoutMs 60s→5s,lockTtlMs 120s→5s
- 新增 USER_MESSAGE_QUEUE_LOCK_TTL_MS 环境变量支持
2025-12-10 01:26:00 +08:00
QTom
b409adf9d8
feat: 修复 userMessageQueue 配置缺失导致的 500 错误
...
- 在 config.example.js 添加缺失的 userMessageQueue 配置段
- 在 userMessageQueueService.js 添加防御性代码,当配置未定义时使用默认值
修复 #783 合并后新用户安装报错:
Cannot read properties of undefined (reading 'enabled')
2025-12-09 18:41:13 +08:00
QTom
f5d1c25295
feat: 添加用户消息串行队列功能,防止同账户并发请求触发限流
...
- 新增 userMessageQueueService.js 实现基于 Redis 的队列锁机制
- 在 claudeRelayService、claudeConsoleRelayService、bedrockRelayService、ccrRelayService 中集成队列锁
- 添加 Redis 原子性 Lua 脚本:acquireUserMessageLock、releaseUserMessageLock、refreshUserMessageLock
- 支持锁续租机制,防止长时间请求锁过期
- 添加可配置参数:USER_MESSAGE_QUEUE_ENABLED、USER_MESSAGE_QUEUE_DELAY_MS、USER_MESSAGE_QUEUE_TIMEOUT_MS
- 添加 Web 管理界面配置入口
- 添加 logger.performance 方法用于结构化性能日志
- 添加完整单元测试 (tests/userMessageQueue.test.js)
2025-12-09 17:04:01 +08:00
shaw
aa71c58400
fix: 修复强制会话绑定首次会话的bug
2025-12-08 21:05:21 +08:00
shaw
c79fdc4d71
feat: 增加Claude会话强制绑定
2025-12-08 16:06:23 +08:00
shaw
659072075d
fix: 统一格式化claude参数传递
2025-12-08 14:23:13 +08:00
John Doe
24796fc889
fix: format droidAccountService.js with Prettier
2025-12-07 21:14:42 +03:00
John Doe
201d95c84e
[fix] Droid: dynamic x-api-provider and custom User-Agent support
...
- Dynamic x-api-provider selection for OpenAI endpoint based on model
- Models with '-max' suffix use 'openai' provider
- Other models use 'azure_openai' provider
- Fixes gpt-5.1-codex-max model compatibility issue
- Update default User-Agent to factory-cli/0.32.1
- Add custom User-Agent field for Droid accounts
- Backend: userAgent field in createAccount and updateAccount
- Frontend: User-Agent input in account creation/edit UI
- Supports all Droid auth modes: OAuth, Manual, API Key
This resolves the issue where gpt-5.1-codex-max failed with 'Azure OpenAI only supports...' error due to incorrect provider header.
2025-12-07 21:08:48 +03:00
John Doe
b3e27e9f15
[fix] Add cache token capture for Droid OpenAI endpoint
...
The _parseOpenAIUsageFromSSE method was not capturing cache-related
tokens (cache_read_input_tokens, cache_creation_input_tokens) from
OpenAI format responses, while the Anthropic endpoint correctly
captured them.
This fix adds extraction of:
- cached_tokens from input_tokens_details
- cache_creation_input_tokens from both input_tokens_details and
top-level usage object
This ensures proper cache statistics tracking and cost calculation
for OpenAI models (like GPT-5/Codex) when using the Droid provider.
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-12-06 23:00:54 +03:00
shaw
b8a6cc627a
Merge branch 'lusipad/main'
2025-12-06 10:56:57 +08:00
lusipad
849d8e047b
docs: translate isProAccount function comments to English
...
- Change function description from Chinese to English
- Translate inline comments (API priority, local config)
- Keep function logic unchanged
This completes the full English comment translation for all modified files.
2025-12-06 04:54:41 +08:00
lusipad
10a1d61427
docs: translate remaining Chinese comments in claudeAccountService.js
...
- Filter Opus models based on account type and model version
- Free account: does not support any Opus model
- Pro account: only supports Opus 4.5+
- Max account: supports all Opus versions
- Account without subscription info defaults to supported
All logic unchanged, only comment translation.
2025-12-06 04:44:52 +08:00
lusipad
ea053c6a16
docs: convert Chinese comments to English
...
- Change VERSION判断逻辑 to VERSION LOGIC
- Change ACCOUNT TYPE判断逻辑 to ACCOUNT TYPE LOGIC
- Translate remaining Chinese phrases to English
- Keep all logic unchanged, only translation
2025-12-06 04:43:11 +08:00
lusipad
c1c941aa4c
fix(opus): fix PR#762 review issues and add maintenance comments
...
- Fix regex to support 2-digit minor versions (e.g., opus-4-10)
- Prevent matching 8-digit dates as minor version numbers
- Unify English comments for consistency across codebase
- Extract isProAccount() helper to eliminate code duplication
- Add detailed version logic comments for future maintenance
Changes:
- VERSION LOGIC: Opus 4.5+ returns true (Pro eligible), <4.5 returns false (Max only)
- ACCOUNT RESTRICTIONS: Free=no Opus, Pro=Opus 4.5+, Max=all Opus versions
- REGEX FIX: (\d{1,2}) limits minor version to 1-2 digits, avoiding date confusion
Test: All 21 tests pass
Format: Prettier validated
2025-12-06 04:26:11 +08:00
lusipad
06b18b7186
refactor: extract isProAccount helper for Pro account detection
...
Extract duplicate Pro account detection logic into a reusable helper
function that handles both API-returned (hasClaudePro) and locally
configured (accountType) data sources.
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-12-05 08:12:51 +08:00
lusipad
12cb841a64
refactor: address Copilot review feedback
...
- Import isOpus45OrNewer from modelHelper instead of duplicating code
- Remove invalid 'claude_free' check (only 'free' is used in practice)
2025-12-05 07:56:53 +08:00
lusipad
b94bd2b822
feat(account): 支持 Pro 账号使用 Opus 4.5+ 模型
...
Opus 4.5 已对 Claude Pro 用户开放,调整账户模型限制逻辑:
- Pro 账号:支持 Opus 4.5+,不支持历史版本 (3.x/4.0/4.1)
- Free 账号:不支持任何 Opus 模型
- Max 账号:支持所有 Opus 版本
修改内容:
- 新增 isOpus45OrNewer() 函数用于精确识别模型版本
- 更新 claudeAccountService.js 中的账户选择逻辑
- 更新 unifiedClaudeScheduler.js 中的模型支持检查
- 新增测试脚本验证官方模型名称识别
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-12-05 07:38:55 +08:00
IanShaw027
4cf1762467
fix: 修复 ESLint curly 规则问题
...
- 在 if 语句后添加必需的大括号
- 修复 unifiedClaudeScheduler.js (1处)
- 修复 unstableUpstreamHelper.js (2处)
2025-12-05 02:28:30 +08:00
IanShaw027
0d64d40654
feat: 添加上游不稳定错误检测与账户临时不可用机制
...
## 背景
当上游 API(如 Anthropic、AWS Bedrock 等)出现临时故障时,服务会持续向故障
账户发送请求,导致用户体验下降。需要自动检测上游不稳定状态并临时排除故障账户。
## 改动内容
### 新增 unstableUpstreamHelper.js
- 检测多种上游不稳定错误模式
- 支持环境变量扩展检测规则
### 修改 unifiedClaudeScheduler.js
- 新增 markAccountTemporarilyUnavailable() 方法:标记账户临时不可用
- 新增 isAccountTemporarilyUnavailable() 方法:检查账户是否临时不可用
- 专属账户检查:claude-official、claude-console、bedrock 临时不可用时自动回退到池
- 池账户选择:跳过临时不可用的账户
### 修改 claudeRelayService.js
- _handleServerError() 方法增加临时不可用标记逻辑
- 5xx 错误时自动标记账户临时不可用(5分钟 TTL)
## 检测的状态码
| 分类 | 状态码 | 说明 |
|------|--------|------|
| 服务器错误 | 500-599 | 内部错误、服务不可用等 |
| 超时类 | 408 | 请求超时 |
| 连接类 | 499 | 客户端关闭请求 (Nginx) |
| 网关类 | 502, 503, 504 | 网关错误、服务不可用、网关超时 |
| CDN类 | 522 | Cloudflare 连接超时 |
| 语义类 | error.type = "server_error" | API 级别服务器错误 |
## 环境变量配置
- UNSTABLE_ERROR_TYPES: 额外的错误类型(逗号分隔)
- UNSTABLE_ERROR_KEYWORDS: 错误消息关键词(逗号分隔)
## Redis 键
- temp_unavailable:{accountType}:{accountId} - TTL 300秒
2025-12-05 02:28:30 +08:00
SunSeekerX
8aca1f9dd1
feat(account): 新增账户自动防护禁用开关
...
支持 disableAutoProtection 配置项,启用后上游 401/400/429/529 错误不再自动禁用账户
2025-12-04 20:47:12 +08:00
IanShaw027
5fd78b6411
fix: 过滤 Cloudflare CDN headers 以防止 API 安全检查
...
使用 Cloudflare 橙色云(CDN 代理模式)时,Cloudflare 会自动添加 CDN 相关的 headers
(cf-*, x-forwarded-*, cdn-loop 等),这会触发上游 API 提供商的安全检查:
1. 已确认问题:88code API 检测到 CDN headers 后返回 403 Forbidden,
导致 Codex CLI 无法使用
2. 潜在风险:其他 API 提供商(OpenAI、Anthropic)可能也会因检测到
代理/CDN 特征而采取限制措施
创建统一的 headerFilter 工具类,在所有转发服务中过滤 Cloudflare CDN headers,
使转发请求伪装成正常的直接客户端请求。
1. 新增 src/utils/headerFilter.js
- 统一的 CDN headers 过滤列表(13 个 Cloudflare headers)
- 提供 filterForOpenAI() 和 filterForClaude() 方法
- 在现有过滤逻辑基础上添加 CDN header 过滤
2. 更新 src/services/openaiResponsesRelayService.js
- 使用 filterForOpenAI() 替代内联的 _filterRequestHeaders()
- 保持向后兼容性
3. 更新 src/services/claudeRelayService.js
- 使用 filterForClaude() 替代 _filterClientHeaders() 实现
- 简化代码,移除重复的 header 列表定义
4. 修复 src/routes/openaiRoutes.js
- 添加对 input 字段的类型检查(可以是数组或字符串)
- 防止 "startsWith is not a function" 错误
x-real-ip, x-forwarded-for, x-forwarded-proto, x-forwarded-host,
x-forwarded-port, x-accel-buffering, cf-ray, cf-connecting-ip,
cf-ipcountry, cf-visitor, cf-request-id, cdn-loop, true-client-ip
- ✅ Codex CLI 通过中转服务成功调用 88code API(之前返回 403)
- ✅ 保留所有业务必需的 headers(conversation_id、session_id 等)
- ✅ 移除所有 Cloudflare CDN 痕迹
- ✅ 保持橙色云的 DDoS 防护和 CDN 加速优势
- ✅ Docker 构建成功
1. 解决 88code 403 问题,Codex CLI 可正常使用
2. 降低因 CDN/代理特征被上游 API 识别的风险
3. 提升与各种 API 提供商的兼容性
4. 统一管理 CDN headers 过滤逻辑,便于维护
2025-12-03 07:07:12 -08:00
shaw
e8e6f972b4
fix: 增强console账号test端点
2025-12-01 15:08:40 +08:00
shaw
02018e10f3
feat: 为console类型账号增加count_tokens端点判断
2025-12-01 10:14:12 +08:00
Dave
249e256360
fix: 修复 Claude API 400 错误:tool_result/tool_use 不匹配问题
...
错误信息:
messages.14.content.0: unexpected tool_use_id found in tool_result blocks: toolu_01Ekn6YJMk7yt7hNcn4PZxtM.
Each tool_result block must have a corresponding tool_use block in the previous message.
根本原因:
文件: src/services/claudeRelayService.js 中的 _enforceCacheControlLimit() 方法
原实现问题:
1. 当 cache_control 块超过 4 个时,直接删除整个内容块(splice)
2. 这会删除 tool_use 块,导致后续的 tool_result 找不到对应的 tool_use_id
3. 也会删除用户的文本消息,导致上下文丢失
重要背景(官方文档确认)
根据 Claude API 官方文档:
- 最多可定义 4 个 cache_control 断点
- 如果超过限制,API 不会报错,只是静默地忽略多余的断点
- "20 个块回溯窗口" 是缓存命中检查的范围,与断点数量限制无关
因此,这个函数的原始设计(删除内容块)是不必要且有害的。
修复方案:
保留函数但修改行为:只删除 cache_control 属性,保留内容本身
修改位置;
文件: src/services/claudeRelayService.js
修改内容:
将 removeFromMessages() 和 removeFromSystem() 函数从"删除整个内容块"改为"只删除 cache_control 属性":
// 修改前:直接删除整个内容块
message.content.splice(contentIndex, 1)
// 修改后:只删除 cache_control 属性,保留内容
delete contentItem.cache_control
效果对比;
| 场景 | 修复前 | 修复后 |
|------------|----------------|----------------|
| 用户文本消息 | ❌ 整个消息被删除 | ✅ 保留消息,只移除缓存标记 |
| tool_use 块 | ❌ 被删除导致 400 错误 | ✅ 保留完整内容 |
| system 提示词 | ❌ 整个提示词被删除 | ✅ 保留提示词内容 |
| 缓存功能 | ⚠️ 强制限制 | ✅ 降级(不缓存但内容完整) |
2025-11-29 17:50:45 +08:00
shaw
6ec4f4bf5b
fix: 修复claude console账号Test未响应的的bug
2025-11-29 14:13:28 +08:00
shaw
326adaaeca
fix: 修复Openai-api账户分组调度设置问题
2025-11-29 14:12:42 +08:00
shaw
63a7c2514b
fix: 修复gemini-api账户共享池无法调度问题
2025-11-29 10:02:51 +08:00
shaw
28caa93d99
feat: 重新支持apikey费用排序功能
2025-11-28 15:32:50 +08:00
shaw
49645e8a50
feat: 增强claude转发特征模拟
2025-11-28 13:54:42 +08:00
shaw
7db70e2dc0
feat: 为claude类型账号增加测试功能
2025-11-28 10:51:01 +08:00
shaw
fd2b8a0114
refacto: 重构admin.js
2025-11-27 22:16:45 +08:00
shaw
851809a132
Merge branch 'xilu0/main'
2025-11-27 20:41:37 +08:00
shaw
4aeb47062b
fix: droid增加comm端点
2025-11-27 20:38:50 +08:00
Dave King
94ff095754
fix: 修复Redis映射表竞态条件导致API Key临时失效问题
...
问题:编辑API Key后立即使用时会偶现(概率1%)报"API密钥已过期"错误,
一会儿后自动恢复。这是因为updateApiKey()方法未传递hashedKey参数给
setApiKey(),导致映射表未更新而主数据已更新的不一致状态。
修复:
- updateApiKey()传递keyData.apiKey(hashedKey)给setApiKey()
- 确保每次更新API Key时映射表也被同步更新
- 添加日志记录帮助监控映射表问题
细节:
1. updateApiKey(): 传递hashedKey参数确保映射表一致性
2. validateApiKey(): 添加警告日志检测映射表缺失
3. updateApiKey(): 增强日志记录"hashMap updated"
这解决了Redis双重存储(apikey:{id}和apikey:hash_map)的
竞态条件问题。
Fix: #API-Key-Expiry-Race-Condition
2025-11-27 10:56:58 +08:00
shaw
4d21c85f83
fix: claude转发移除x-authorization 头
2025-11-26 19:38:28 +08:00
shaw
3fb874fc29
feat: admin-next/api-stats查询被禁用的key增加名字显示
2025-11-26 10:18:43 +08:00
shaw
22fbabbc47
fix: 优化apikeys页面加载速度
2025-11-25 15:01:15 +08:00