From 55879396c85f96fab0262da51e944bebcc9a511c Mon Sep 17 00:00:00 2001 From: hex2077 Date: Sun, 15 Feb 2026 11:21:26 +0800 Subject: [PATCH] =?UTF-8?q?feat(converters):=20=E4=B8=BA=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20metadata=20=E6=94=AF=E6=8C=81=E5=B9=B6?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BC=9A=E8=AF=9D=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 CodexConverter 和 ClaudeConverter 中增加 metadata 字段,透传上游元数据 - 重构 CodexApiService 的缓存键生成逻辑,优先使用 session_id 或 conversation_id - 从上游请求体中移除 metadata 避免透传,仅用于生成缓存键 --- src/converters/strategies/ClaudeConverter.js | 1 + src/converters/strategies/CodexConverter.js | 1 + src/providers/openai/codex-core.js | 26 ++++++++++++++++---- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/converters/strategies/ClaudeConverter.js b/src/converters/strategies/ClaudeConverter.js index ecf72cf..d654d5d 100644 --- a/src/converters/strategies/ClaudeConverter.js +++ b/src/converters/strategies/ClaudeConverter.js @@ -1871,6 +1871,7 @@ export class ClaudeConverter extends BaseConverter { stream: true, store: false, parallel_tool_calls: true, + metadata: claudeRequest.metadata || {}, reasoning: { effort: claudeRequest.reasoning?.effort || 'medium', summary: 'auto' diff --git a/src/converters/strategies/CodexConverter.js b/src/converters/strategies/CodexConverter.js index c0fa990..31ad6be 100644 --- a/src/converters/strategies/CodexConverter.js +++ b/src/converters/strategies/CodexConverter.js @@ -153,6 +153,7 @@ export class CodexConverter extends BaseConverter { input: this.convertMessages(data.messages || []), stream: true, store: false, + metadata: data.metadata || {}, reasoning: { effort: data.reasoning_effort || 'medium', summary: 'auto' diff --git a/src/providers/openai/codex-core.js b/src/providers/openai/codex-core.js index 73222ca..3160484 100644 --- a/src/providers/openai/codex-core.js +++ b/src/providers/openai/codex-core.js @@ -300,8 +300,25 @@ export class CodexApiService { * 准备请求体 */ prepareRequestBody(model, requestBody, stream) { - // 添加会话缓存 ID - const cacheKey = `${model}-${requestBody.metadata?.user_id || 'default'}`; + // 提取 metadata 并从请求体中移除,避免透传到上游 + const metadata = requestBody.metadata || {}; + + // 明确会话维度:优先使用 session_id 或 conversation_id,其次 user_id + const sessionId = metadata.session_id || metadata.conversation_id || metadata.user_id || 'default'; + + const cleanedBody = { ...requestBody }; + delete cleanedBody.metadata; + + // 生成会话缓存键 + // 默认弱化 model 依赖,以提升同会话跨模型的缓存命中率 + // 如果 sessionId 为 'default',则必须加上 model 以提供基础隔离 + let cacheKey = sessionId; + if (sessionId === 'default') { + cacheKey = `${model}-default`; + } else { + cacheKey = `${model}-${sessionId}`; + } + let cache = this.conversationCache.get(cacheKey); if (!cache || cache.expire < Date.now()) { @@ -312,10 +329,9 @@ export class CodexApiService { this.conversationCache.set(cacheKey, cache); } - // 注意:requestBody 已经是转换后的 Codex 格式 - // 只需要添加 cache key 和 stream 参数 + // 注意:requestBody 已经去除了 metadata return { - ...requestBody, + ...cleanedBody, stream, prompt_cache_key: cache.id };