mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-23 09:38:02 +00:00
feat: claude转发增加runtimeAddon
This commit is contained in:
@@ -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()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user