mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-22 16:43:35 +00:00
fix: 优化droid默认启用推理的问题
This commit is contained in:
@@ -10,16 +10,6 @@ const logger = require('../utils/logger')
|
||||
|
||||
const SYSTEM_PROMPT = 'You are Droid, an AI software engineering agent built by Factory.'
|
||||
|
||||
const MODEL_REASONING_CONFIG = {
|
||||
'claude-opus-4-1-20250805': 'off',
|
||||
'claude-sonnet-4-20250514': 'medium',
|
||||
'claude-sonnet-4-5-20250929': 'high',
|
||||
'gpt-5-2025-08-07': 'high',
|
||||
'gpt-5-codex': 'off'
|
||||
}
|
||||
|
||||
const VALID_REASONING_LEVELS = new Set(['low', 'medium', 'high'])
|
||||
|
||||
/**
|
||||
* Droid API 转发服务
|
||||
*/
|
||||
@@ -35,16 +25,7 @@ class DroidRelayService {
|
||||
|
||||
this.userAgent = 'factory-cli/0.19.4'
|
||||
this.systemPrompt = SYSTEM_PROMPT
|
||||
this.modelReasoningMap = new Map()
|
||||
this.API_KEY_STICKY_PREFIX = 'droid_api_key'
|
||||
|
||||
Object.entries(MODEL_REASONING_CONFIG).forEach(([modelId, level]) => {
|
||||
if (!modelId) {
|
||||
return
|
||||
}
|
||||
const normalized = typeof level === 'string' ? level.toLowerCase() : ''
|
||||
this.modelReasoningMap.set(modelId, normalized)
|
||||
})
|
||||
}
|
||||
|
||||
_normalizeEndpointType(endpointType) {
|
||||
@@ -82,7 +63,6 @@ class DroidRelayService {
|
||||
logger.info(`🔄 将请求模型从 ${originalModel} 映射为 ${mappedModel}`)
|
||||
}
|
||||
normalizedBody.model = mappedModel
|
||||
normalizedBody.__forceDisableThinking = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -901,9 +881,7 @@ class DroidRelayService {
|
||||
headers['x-api-key'] = 'placeholder'
|
||||
headers['x-api-provider'] = 'anthropic'
|
||||
|
||||
// 处理 anthropic-beta 头
|
||||
const reasoningLevel = this._getReasoningLevel(requestBody)
|
||||
if (reasoningLevel) {
|
||||
if (this._isThinkingRequested(requestBody)) {
|
||||
headers['anthropic-beta'] = 'interleaved-thinking-2025-05-14'
|
||||
}
|
||||
}
|
||||
@@ -940,6 +918,36 @@ class DroidRelayService {
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断请求是否启用 Anthropic 推理模式
|
||||
*/
|
||||
_isThinkingRequested(requestBody) {
|
||||
const thinking = requestBody && typeof requestBody === 'object' ? requestBody.thinking : null
|
||||
if (!thinking) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (thinking === true) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (typeof thinking === 'string') {
|
||||
return thinking.trim().toLowerCase() === 'enabled'
|
||||
}
|
||||
|
||||
if (typeof thinking === 'object') {
|
||||
if (thinking.enabled === true) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (typeof thinking.type === 'string') {
|
||||
return thinking.type.trim().toLowerCase() === 'enabled'
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理请求体(注入 system prompt 等)
|
||||
*/
|
||||
@@ -950,17 +958,6 @@ class DroidRelayService {
|
||||
const hasStreamField =
|
||||
requestBody && Object.prototype.hasOwnProperty.call(requestBody, 'stream')
|
||||
|
||||
const shouldDisableThinking =
|
||||
endpointType === 'anthropic' && processedBody.__forceDisableThinking === true
|
||||
|
||||
if ('__forceDisableThinking' in processedBody) {
|
||||
delete processedBody.__forceDisableThinking
|
||||
}
|
||||
|
||||
if (requestBody && '__forceDisableThinking' in requestBody) {
|
||||
delete requestBody.__forceDisableThinking
|
||||
}
|
||||
|
||||
if (processedBody && Object.prototype.hasOwnProperty.call(processedBody, 'metadata')) {
|
||||
delete processedBody.metadata
|
||||
}
|
||||
@@ -975,9 +972,7 @@ class DroidRelayService {
|
||||
processedBody.stream = true
|
||||
}
|
||||
|
||||
const hasTemperatureField = Object.prototype.hasOwnProperty.call(processedBody, 'temperature')
|
||||
|
||||
// Anthropic 端点:处理 thinking 字段
|
||||
// Anthropic 端点:仅注入系统提示
|
||||
if (endpointType === 'anthropic') {
|
||||
if (this.systemPrompt) {
|
||||
const promptBlock = { type: 'text', text: this.systemPrompt }
|
||||
@@ -992,43 +987,9 @@ class DroidRelayService {
|
||||
processedBody.system = [promptBlock]
|
||||
}
|
||||
}
|
||||
|
||||
const reasoningLevel = shouldDisableThinking ? null : this._getReasoningLevel(requestBody)
|
||||
if (reasoningLevel) {
|
||||
const budgetTokens = {
|
||||
low: 4096,
|
||||
medium: 12288,
|
||||
high: 24576
|
||||
}
|
||||
processedBody.thinking = {
|
||||
type: 'enabled',
|
||||
budget_tokens: budgetTokens[reasoningLevel]
|
||||
}
|
||||
} else {
|
||||
delete processedBody.thinking
|
||||
}
|
||||
|
||||
if (shouldDisableThinking) {
|
||||
if ('thinking' in processedBody) {
|
||||
delete processedBody.thinking
|
||||
}
|
||||
} else if (processedBody.thinking && processedBody.thinking.type === 'enabled') {
|
||||
if (hasTemperatureField) {
|
||||
const parsedTemperature =
|
||||
typeof processedBody.temperature === 'string'
|
||||
? parseFloat(processedBody.temperature)
|
||||
: processedBody.temperature
|
||||
|
||||
if (typeof parsedTemperature !== 'number' || Number.isNaN(parsedTemperature)) {
|
||||
delete processedBody.temperature
|
||||
}
|
||||
}
|
||||
|
||||
processedBody.temperature = 1
|
||||
}
|
||||
}
|
||||
|
||||
// OpenAI 端点:处理 reasoning 字段
|
||||
// OpenAI 端点:仅前置系统提示
|
||||
if (endpointType === 'openai') {
|
||||
if (this.systemPrompt) {
|
||||
if (processedBody.instructions) {
|
||||
@@ -1039,16 +1000,6 @@ class DroidRelayService {
|
||||
processedBody.instructions = this.systemPrompt
|
||||
}
|
||||
}
|
||||
|
||||
const reasoningLevel = this._getReasoningLevel(requestBody)
|
||||
if (reasoningLevel) {
|
||||
processedBody.reasoning = {
|
||||
effort: reasoningLevel,
|
||||
summary: 'auto'
|
||||
}
|
||||
} else {
|
||||
delete processedBody.reasoning
|
||||
}
|
||||
}
|
||||
|
||||
// 处理 temperature 和 top_p 参数
|
||||
@@ -1064,26 +1015,6 @@ class DroidRelayService {
|
||||
return processedBody
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取推理级别(如果在 requestBody 中配置)
|
||||
*/
|
||||
_getReasoningLevel(requestBody) {
|
||||
if (!requestBody || !requestBody.model) {
|
||||
return null
|
||||
}
|
||||
|
||||
const configured = this.modelReasoningMap.get(requestBody.model)
|
||||
if (!configured) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (!VALID_REASONING_LEVELS.has(configured)) {
|
||||
return null
|
||||
}
|
||||
|
||||
return configured
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理非流式响应
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user