feat: claude转发增加runtimeAddon

This commit is contained in:
shaw
2025-10-19 18:05:19 +08:00
parent edf302fd6b
commit b61a3103e9

View File

@@ -12,6 +12,9 @@ const claudeCodeHeadersService = require('./claudeCodeHeadersService')
const redis = require('../models/redis') const redis = require('../models/redis')
const ClaudeCodeValidator = require('../validators/clients/claudeCodeValidator') const ClaudeCodeValidator = require('../validators/clients/claudeCodeValidator')
const { formatDateWithTimezone } = require('../utils/dateHelper') const { formatDateWithTimezone } = require('../utils/dateHelper')
const runtimeAddon = require('../utils/runtimeAddon')
const RUNTIME_EVENT_FMT_CLAUDE_REQ = 'fmtClaudeReq'
class ClaudeRelayService { class ClaudeRelayService {
constructor() { constructor() {
@@ -896,6 +899,36 @@ class ClaudeRelayService {
return filteredHeaders return filteredHeaders
} }
_applyLocalRequestFormatters(body, headers, context = {}) {
const normalizedHeaders = headers && typeof headers === 'object' ? { ...headers } : {}
try {
const payload = {
body,
headers: normalizedHeaders,
...context
}
const result = runtimeAddon.emitSync(RUNTIME_EVENT_FMT_CLAUDE_REQ, payload)
if (!result || typeof result !== 'object') {
return { body, headers: normalizedHeaders }
}
const nextBody = result.body && typeof result.body === 'object' ? result.body : body
const nextHeaders =
result.headers && typeof result.headers === 'object' ? result.headers : normalizedHeaders
const abortResponse =
result.abortResponse && typeof result.abortResponse === 'object'
? result.abortResponse
: null
return { body: nextBody, headers: nextHeaders, abortResponse }
} catch (error) {
logger.warn('⚠️ 应用本地 fmtClaudeReq 插件失败:', error)
return { body, headers: normalizedHeaders }
}
}
// 🔗 发送请求到Claude API // 🔗 发送请求到Claude API
async _makeClaudeRequest( async _makeClaudeRequest(
body, body,
@@ -921,7 +954,8 @@ class ClaudeRelayService {
const isRealClaudeCode = this.isRealClaudeCodeRequest(body) const isRealClaudeCode = this.isRealClaudeCodeRequest(body)
// 如果不是真实的 Claude Code 请求,需要使用从账户获取的 Claude Code headers // 如果不是真实的 Claude Code 请求,需要使用从账户获取的 Claude Code headers
const finalHeaders = { ...filteredHeaders } let finalHeaders = { ...filteredHeaders }
let requestPayload = body
if (!isRealClaudeCode) { if (!isRealClaudeCode) {
// 获取该账号存储的 Claude Code headers // 获取该账号存储的 Claude Code headers
@@ -936,6 +970,21 @@ class ClaudeRelayService {
}) })
} }
const extensionResult = this._applyLocalRequestFormatters(requestPayload, finalHeaders, {
account,
accountId,
clientHeaders,
requestOptions,
isStream: false
})
if (extensionResult.abortResponse) {
return extensionResult.abortResponse
}
requestPayload = extensionResult.body
finalHeaders = extensionResult.headers
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// 支持自定义路径(如 count_tokens // 支持自定义路径(如 count_tokens
let requestPath = url.pathname let requestPath = url.pathname
@@ -1064,7 +1113,7 @@ class ClaudeRelayService {
}) })
// 写入请求体 // 写入请求体
req.write(JSON.stringify(body)) req.write(JSON.stringify(requestPayload))
req.end() req.end()
}) })
} }
@@ -1225,7 +1274,8 @@ class ClaudeRelayService {
const isRealClaudeCode = this.isRealClaudeCodeRequest(body) const isRealClaudeCode = this.isRealClaudeCodeRequest(body)
// 如果不是真实的 Claude Code 请求,需要使用从账户获取的 Claude Code headers // 如果不是真实的 Claude Code 请求,需要使用从账户获取的 Claude Code headers
const finalHeaders = { ...filteredHeaders } let finalHeaders = { ...filteredHeaders }
let requestPayload = body
if (!isRealClaudeCode) { if (!isRealClaudeCode) {
// 获取该账号存储的 Claude Code headers // 获取该账号存储的 Claude Code headers
@@ -1240,6 +1290,23 @@ class ClaudeRelayService {
}) })
} }
const extensionResult = this._applyLocalRequestFormatters(requestPayload, finalHeaders, {
account,
accountId,
accountType,
sessionHash,
clientHeaders,
requestOptions,
isStream: true
})
if (extensionResult.abortResponse) {
return extensionResult.abortResponse
}
requestPayload = extensionResult.body
finalHeaders = extensionResult.headers
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const url = new URL(this.claudeApiUrl) const url = new URL(this.claudeApiUrl)
@@ -1871,7 +1938,7 @@ class ClaudeRelayService {
}) })
// 写入请求体 // 写入请求体
req.write(JSON.stringify(body)) req.write(JSON.stringify(requestPayload))
req.end() req.end()
}) })
} }