fix lint/format issues

This commit is contained in:
Feng Yue
2025-08-31 14:21:56 +08:00
parent e4078e36ad
commit 0240a17c1e
2 changed files with 56 additions and 36 deletions

View File

@@ -136,7 +136,9 @@ const config = {
bindCredentials: process.env.LDAP_BIND_PASSWORD || 'admin', bindCredentials: process.env.LDAP_BIND_PASSWORD || 'admin',
searchBase: process.env.LDAP_SEARCH_BASE || 'dc=example,dc=com', searchBase: process.env.LDAP_SEARCH_BASE || 'dc=example,dc=com',
searchFilter: process.env.LDAP_SEARCH_FILTER || '(uid={{username}})', searchFilter: process.env.LDAP_SEARCH_FILTER || '(uid={{username}})',
searchAttributes: process.env.LDAP_SEARCH_ATTRIBUTES ? process.env.LDAP_SEARCH_ATTRIBUTES.split(',') : ['dn', 'uid', 'cn', 'mail', 'givenName', 'sn'], searchAttributes: process.env.LDAP_SEARCH_ATTRIBUTES
? process.env.LDAP_SEARCH_ATTRIBUTES.split(',')
: ['dn', 'uid', 'cn', 'mail', 'givenName', 'sn'],
timeout: parseInt(process.env.LDAP_TIMEOUT) || 5000, timeout: parseInt(process.env.LDAP_TIMEOUT) || 5000,
connectTimeout: parseInt(process.env.LDAP_CONNECT_TIMEOUT) || 10000, connectTimeout: parseInt(process.env.LDAP_CONNECT_TIMEOUT) || 10000,
// TLS/SSL 配置 // TLS/SSL 配置
@@ -144,11 +146,17 @@ const config = {
// 是否忽略证书错误 (用于自签名证书) // 是否忽略证书错误 (用于自签名证书)
rejectUnauthorized: process.env.LDAP_TLS_REJECT_UNAUTHORIZED !== 'false', // 默认验证证书设置为false则忽略 rejectUnauthorized: process.env.LDAP_TLS_REJECT_UNAUTHORIZED !== 'false', // 默认验证证书设置为false则忽略
// CA证书文件路径 (可选用于自定义CA证书) // CA证书文件路径 (可选用于自定义CA证书)
ca: process.env.LDAP_TLS_CA_FILE ? require('fs').readFileSync(process.env.LDAP_TLS_CA_FILE) : undefined, ca: process.env.LDAP_TLS_CA_FILE
? require('fs').readFileSync(process.env.LDAP_TLS_CA_FILE)
: undefined,
// 客户端证书文件路径 (可选,用于双向认证) // 客户端证书文件路径 (可选,用于双向认证)
cert: process.env.LDAP_TLS_CERT_FILE ? require('fs').readFileSync(process.env.LDAP_TLS_CERT_FILE) : undefined, cert: process.env.LDAP_TLS_CERT_FILE
? require('fs').readFileSync(process.env.LDAP_TLS_CERT_FILE)
: undefined,
// 客户端私钥文件路径 (可选,用于双向认证) // 客户端私钥文件路径 (可选,用于双向认证)
key: process.env.LDAP_TLS_KEY_FILE ? require('fs').readFileSync(process.env.LDAP_TLS_KEY_FILE) : undefined, key: process.env.LDAP_TLS_KEY_FILE
? require('fs').readFileSync(process.env.LDAP_TLS_KEY_FILE)
: undefined,
// 服务器名称 (用于SNI可选) // 服务器名称 (用于SNI可选)
servername: process.env.LDAP_TLS_SERVERNAME || undefined servername: process.env.LDAP_TLS_SERVERNAME || undefined
} }

View File

@@ -272,11 +272,11 @@ function handleStreamResponse(upstreamResponse, clientResponse, options = {}) {
let hasEnded = false let hasEnded = false
let eventCount = 0 let eventCount = 0
const maxEvents = 10000 // 最大事件数量限制 const maxEvents = 10000 // 最大事件数量限制
// 专门用于保存最后几个chunks以提取usage数据 // 专门用于保存最后几个chunks以提取usage数据
let finalChunksBuffer = '' let finalChunksBuffer = ''
const FINAL_CHUNKS_SIZE = 32 * 1024 // 32KB保留最终chunks const FINAL_CHUNKS_SIZE = 32 * 1024 // 32KB保留最终chunks
let allParsedEvents = [] // 存储所有解析的事件用于最终usage提取 const allParsedEvents = [] // 存储所有解析的事件用于最终usage提取
// 设置响应头 // 设置响应头
clientResponse.setHeader('Content-Type', 'text/event-stream') clientResponse.setHeader('Content-Type', 'text/event-stream')
@@ -314,7 +314,7 @@ function handleStreamResponse(upstreamResponse, clientResponse, options = {}) {
continue continue
} }
const eventData = JSON.parse(jsonStr) const eventData = JSON.parse(jsonStr)
// 保存所有成功解析的事件 // 保存所有成功解析的事件
allParsedEvents.push(eventData) allParsedEvents.push(eventData)
@@ -324,14 +324,17 @@ function handleStreamResponse(upstreamResponse, clientResponse, options = {}) {
} }
// 使用强化的usage提取函数 // 使用强化的usage提取函数
const { usageData: extractedUsage, actualModel: extractedModel } = extractUsageDataRobust( const { usageData: extractedUsage, actualModel: extractedModel } =
eventData, extractUsageDataRobust(
`stream-event-${isFromFinalBuffer ? 'final' : 'normal'}` eventData,
) `stream-event-${isFromFinalBuffer ? 'final' : 'normal'}`
)
if (extractedUsage && !usageData) { if (extractedUsage && !usageData) {
usageData = extractedUsage usageData = extractedUsage
if (extractedModel) actualModel = extractedModel if (extractedModel) {
actualModel = extractedModel
}
logger.debug(`🎯 Stream usage captured via robust extraction`, { logger.debug(`🎯 Stream usage captured via robust extraction`, {
isFromFinalBuffer, isFromFinalBuffer,
usageData, usageData,
@@ -358,7 +361,6 @@ function handleStreamResponse(upstreamResponse, clientResponse, options = {}) {
logger.debug('🎯 Stream usage (backup method - top-level):', usageData) logger.debug('🎯 Stream usage (backup method - top-level):', usageData)
} }
} }
} catch (e) { } catch (e) {
logger.debug('SSE parsing error (expected for incomplete chunks):', e.message) logger.debug('SSE parsing error (expected for incomplete chunks):', e.message)
} }
@@ -418,7 +420,9 @@ function handleStreamResponse(upstreamResponse, clientResponse, options = {}) {
// 防止主缓冲区过大 - 但保持最后部分用于usage解析 // 防止主缓冲区过大 - 但保持最后部分用于usage解析
if (buffer.length > MAX_BUFFER_SIZE) { if (buffer.length > MAX_BUFFER_SIZE) {
logger.warn(`Stream ${streamId} buffer exceeded limit, truncating main buffer but preserving final chunks`) logger.warn(
`Stream ${streamId} buffer exceeded limit, truncating main buffer but preserving final chunks`
)
// 保留最后1/4而不是1/2为usage数据留更多空间 // 保留最后1/4而不是1/2为usage数据留更多空间
buffer = buffer.slice(-MAX_BUFFER_SIZE / 4) buffer = buffer.slice(-MAX_BUFFER_SIZE / 4)
} }
@@ -481,16 +485,18 @@ function handleStreamResponse(upstreamResponse, clientResponse, options = {}) {
// 方法3: 从所有解析的事件中重新搜索usage // 方法3: 从所有解析的事件中重新搜索usage
if (!usageData && allParsedEvents.length > 0) { if (!usageData && allParsedEvents.length > 0) {
logger.debug('🔍 Searching through all parsed events for usage...') logger.debug('🔍 Searching through all parsed events for usage...')
// 倒序查找因为usage通常在最后 // 倒序查找因为usage通常在最后
for (let i = allParsedEvents.length - 1; i >= 0; i--) { for (let i = allParsedEvents.length - 1; i >= 0; i--) {
const { usageData: foundUsage, actualModel: foundModel } = extractUsageDataRobust( const { usageData: foundUsage, actualModel: foundModel } = extractUsageDataRobust(
allParsedEvents[i], allParsedEvents[i],
`final-event-scan-${i}` `final-event-scan-${i}`
) )
if (foundUsage) { if (foundUsage) {
usageData = foundUsage usageData = foundUsage
if (foundModel) actualModel = foundModel if (foundModel) {
actualModel = foundModel
}
logger.debug(`🎯 Usage found in event ${i} during final scan!`) logger.debug(`🎯 Usage found in event ${i} during final scan!`)
break break
} }
@@ -505,8 +511,11 @@ function handleStreamResponse(upstreamResponse, clientResponse, options = {}) {
lastEvent: allParsedEvents[allParsedEvents.length - 1], lastEvent: allParsedEvents[allParsedEvents.length - 1],
eventCount: allParsedEvents.length eventCount: allParsedEvents.length
} }
const { usageData: combinedUsage } = extractUsageDataRobust(combinedData, 'combined-events') const { usageData: combinedUsage } = extractUsageDataRobust(
combinedData,
'combined-events'
)
if (combinedUsage) { if (combinedUsage) {
usageData = combinedUsage usageData = combinedUsage
logger.debug('🎯 Usage found via combined events analysis!') logger.debug('🎯 Usage found via combined events analysis!')
@@ -529,7 +538,7 @@ function handleStreamResponse(upstreamResponse, clientResponse, options = {}) {
totalEvents: allParsedEvents.length, totalEvents: allParsedEvents.length,
finalBufferSize: finalChunksBuffer.length, finalBufferSize: finalChunksBuffer.length,
mainBufferSize: buffer.length, mainBufferSize: buffer.length,
lastFewEvents: allParsedEvents.slice(-3).map(e => ({ lastFewEvents: allParsedEvents.slice(-3).map((e) => ({
type: e.type, type: e.type,
hasUsage: !!e.usage, hasUsage: !!e.usage,
hasResponse: !!e.response, hasResponse: !!e.response,
@@ -610,35 +619,39 @@ function extractUsageDataRobust(responseData, context = 'unknown') {
actualModel = responseData.model actualModel = responseData.model
logger.debug('✅ Usage extracted via Strategy 1 (top-level)', { usageData, actualModel }) logger.debug('✅ Usage extracted via Strategy 1 (top-level)', { usageData, actualModel })
} }
// 策略 2: response.usage (Responses API) // 策略 2: response.usage (Responses API)
else if (responseData?.response?.usage) { else if (responseData?.response?.usage) {
usageData = responseData.response.usage usageData = responseData.response.usage
actualModel = responseData.response.model || responseData.model actualModel = responseData.response.model || responseData.model
logger.debug('✅ Usage extracted via Strategy 2 (response.usage)', { usageData, actualModel }) logger.debug('✅ Usage extracted via Strategy 2 (response.usage)', { usageData, actualModel })
} }
// 策略 3: 嵌套搜索 - 深度查找 usage 字段 // 策略 3: 嵌套搜索 - 深度查找 usage 字段
else { else {
const findUsageRecursive = (obj, path = '') => { const findUsageRecursive = (obj, path = '') => {
if (!obj || typeof obj !== 'object') return null if (!obj || typeof obj !== 'object') {
return null
}
for (const [key, value] of Object.entries(obj)) { for (const [key, value] of Object.entries(obj)) {
const currentPath = path ? `${path}.${key}` : key const currentPath = path ? `${path}.${key}` : key
if (key === 'usage' && value && typeof value === 'object') { if (key === 'usage' && value && typeof value === 'object') {
logger.debug(`✅ Usage found at path: ${currentPath}`, value) logger.debug(`✅ Usage found at path: ${currentPath}`, value)
return { usage: value, path: currentPath } return { usage: value, path: currentPath }
} }
if (typeof value === 'object' && value !== null) { if (typeof value === 'object' && value !== null) {
const nested = findUsageRecursive(value, currentPath) const nested = findUsageRecursive(value, currentPath)
if (nested) return nested if (nested) {
return nested
}
} }
} }
return null return null
} }
const found = findUsageRecursive(responseData) const found = findUsageRecursive(responseData)
if (found) { if (found) {
usageData = found.usage usageData = found.usage
@@ -650,14 +663,14 @@ function extractUsageDataRobust(responseData, context = 'unknown') {
modelParent = modelParent?.[part] modelParent = modelParent?.[part]
} }
actualModel = modelParent?.model || responseData?.model actualModel = modelParent?.model || responseData?.model
logger.debug('✅ Usage extracted via Strategy 3 (recursive)', { logger.debug('✅ Usage extracted via Strategy 3 (recursive)', {
usageData, usageData,
actualModel, actualModel,
foundPath: found.path foundPath: found.path
}) })
} }
} }
// 策略 4: 特殊响应格式处理 // 策略 4: 特殊响应格式处理
if (!usageData) { if (!usageData) {
// 检查是否有 choices 数组usage 可能在最后一个 choice 中 // 检查是否有 choices 数组usage 可能在最后一个 choice 中
@@ -684,12 +697,11 @@ function extractUsageDataRobust(responseData, context = 'unknown') {
} else { } else {
logger.warn('❌ Failed to extract usage data', { logger.warn('❌ Failed to extract usage data', {
context, context,
responseDataStructure: JSON.stringify(responseData, null, 2).substring(0, 1000) + '...', responseDataStructure: `${JSON.stringify(responseData, null, 2).substring(0, 1000)}...`,
availableKeys: Object.keys(responseData || {}), availableKeys: Object.keys(responseData || {}),
responseSize: JSON.stringify(responseData || {}).length responseSize: JSON.stringify(responseData || {}).length
}) })
} }
} catch (extractionError) { } catch (extractionError) {
logger.error('🚨 Error during usage extraction', { logger.error('🚨 Error during usage extraction', {
context, context,