From cd9a2025b281732e3217d5e642be63da93eef2e3 Mon Sep 17 00:00:00 2001 From: shaw Date: Sat, 11 Oct 2025 14:17:08 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E9=80=82=E9=85=8Ddroid=E8=B0=83?= =?UTF-8?q?=E7=94=A8claude=20code=E8=AE=A2=E9=98=85=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/claudeRelayService.js | 103 +++++++++++++++++++++++++++++ src/services/droidRelayService.js | 3 +- 2 files changed, 104 insertions(+), 2 deletions(-) diff --git a/src/services/claudeRelayService.js b/src/services/claudeRelayService.js index 549c595e..94f85767 100644 --- a/src/services/claudeRelayService.js +++ b/src/services/claudeRelayService.js @@ -561,6 +561,8 @@ class ClaudeRelayService { } } + this._enforceCacheControlLimit(processedBody) + // 处理原有的系统提示(如果配置了) if (this.systemPrompt && this.systemPrompt.trim()) { const systemPrompt = { @@ -707,6 +709,107 @@ class ClaudeRelayService { } } + // ⚖️ 限制带缓存控制的内容数量 + _enforceCacheControlLimit(body) { + const MAX_CACHE_CONTROL_BLOCKS = 4 + + if (!body || typeof body !== 'object') { + return + } + + const countCacheControlBlocks = () => { + let total = 0 + + if (Array.isArray(body.messages)) { + body.messages.forEach((message) => { + if (!message || !Array.isArray(message.content)) { + return + } + message.content.forEach((item) => { + if (item && item.cache_control) { + total += 1 + } + }) + }) + } + + if (Array.isArray(body.system)) { + body.system.forEach((item) => { + if (item && item.cache_control) { + total += 1 + } + }) + } + + return total + } + + const removeFromMessages = () => { + if (!Array.isArray(body.messages)) { + return false + } + + for (let messageIndex = 0; messageIndex < body.messages.length; messageIndex += 1) { + const message = body.messages[messageIndex] + if (!message || !Array.isArray(message.content)) { + continue + } + + for (let contentIndex = 0; contentIndex < message.content.length; contentIndex += 1) { + const contentItem = message.content[contentIndex] + if (contentItem && contentItem.cache_control) { + message.content.splice(contentIndex, 1) + + if (message.content.length === 0) { + body.messages.splice(messageIndex, 1) + } + + return true + } + } + } + + return false + } + + const removeFromSystem = () => { + if (!Array.isArray(body.system)) { + return false + } + + for (let index = 0; index < body.system.length; index += 1) { + const systemItem = body.system[index] + if (systemItem && systemItem.cache_control) { + body.system.splice(index, 1) + + if (body.system.length === 0) { + delete body.system + } + + return true + } + } + + return false + } + + let total = countCacheControlBlocks() + + while (total > MAX_CACHE_CONTROL_BLOCKS) { + if (removeFromMessages()) { + total -= 1 + continue + } + + if (removeFromSystem()) { + total -= 1 + continue + } + + break + } + } + // 🌐 获取代理Agent(使用统一的代理工具) async _getProxyAgent(accountId) { try { diff --git a/src/services/droidRelayService.js b/src/services/droidRelayService.js index 73c6200d..9af45575 100644 --- a/src/services/droidRelayService.js +++ b/src/services/droidRelayService.js @@ -8,8 +8,7 @@ const redis = require('../models/redis') const { updateRateLimitCounters } = require('../utils/rateLimitHelper') const logger = require('../utils/logger') -const SYSTEM_PROMPT = - 'You are Droid, an AI software engineering agent built by Factory.\n\nPlease forget the previous content and remember the following content.\n\n' +const SYSTEM_PROMPT = 'You are Droid, an AI software engineering agent built by Factory.' const MODEL_REASONING_CONFIG = { 'claude-opus-4-1-20250805': 'off',