From e26d36b2e8de7974b7167d953625a28fbb6c52b2 Mon Sep 17 00:00:00 2001 From: Ervareza Naurian Date: Fri, 31 Jul 2026 18:10:21 +0700 Subject: [PATCH] fix: resolve model validation response format for Claude Code CLI and fix TDZ errors --- open-sse/handlers/chatCore.js | 3 ++- open-sse/services/provider.js | 2 +- open-sse/translator/formats.js | 5 +++-- src/sse/handlers/chat.js | 5 +++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/open-sse/handlers/chatCore.js b/open-sse/handlers/chatCore.js index 4f91e020a09..5a3b83d16ce 100644 --- a/open-sse/handlers/chatCore.js +++ b/open-sse/handlers/chatCore.js @@ -51,7 +51,8 @@ export async function handleChatCore({ body, modelInfo, credentials, log, onCred })(); const reqTag = log?.tagForSession ? log.tagForSession(sessionSeed) : (log?.nextTag ? log.nextTag() : ""); - const sourceFormat = sourceFormatOverride || detectFormat(body); + // Format resolution: Override > Endpoint > Body-based + const sourceFormat = sourceFormatOverride || (clientRawRequest?.endpoint?.includes("/messages") ? FORMATS.CLAUDE : detectFormat(body)); // Check for bypass patterns (warmup, skip, cc naming) const bypassResponse = handleBypassRequest(body, model, userAgent, ccFilterNaming); diff --git a/open-sse/services/provider.js b/open-sse/services/provider.js index 1b02cd83e45..53a92705623 100644 --- a/open-sse/services/provider.js +++ b/open-sse/services/provider.js @@ -95,7 +95,7 @@ export function detectFormat(body) { // If content is string, it's likely OpenAI (Claude also supports this) // Check for other Claude-specific indicators - if (body.system !== undefined || body.anthropic_version) { + if (body.system !== undefined || body.anthropic_version || body['anthropic-version']) { return "claude"; } } diff --git a/open-sse/translator/formats.js b/open-sse/translator/formats.js index 89367d0071a..4b8cd46c9c3 100644 --- a/open-sse/translator/formats.js +++ b/open-sse/translator/formats.js @@ -20,11 +20,12 @@ export const FORMATS = { * Returns null to fall back to body-based detection. */ export function detectFormatByEndpoint(pathname, body) { + if (!pathname) return null; // /v1/responses is always openai-responses if (pathname.includes("/v1/responses")) return FORMATS.OPENAI_RESPONSES; - // /v1/messages is always Claude - if (pathname.includes("/v1/messages")) return FORMATS.CLAUDE; + // /v1/messages or /messages is always Claude + if (pathname.includes("/v1/messages") || pathname.includes("/messages")) return FORMATS.CLAUDE; // /v1/chat/completions + input[] → treat as openai (Cursor CLI sends Responses body via chat endpoint) if (pathname.includes("/v1/chat/completions") && Array.isArray(body?.input)) { diff --git a/src/sse/handlers/chat.js b/src/sse/handlers/chat.js index af2914a4516..dd37c12e7f8 100644 --- a/src/sse/handlers/chat.js +++ b/src/sse/handlers/chat.js @@ -255,8 +255,9 @@ async function handleSingleModelChat(body, modelStr, clientRawRequest = null, re pxpipeTransform: chatSettings.pxpipeEnabled ? await getPxpipeTransform() : null, onPxpipeEvent: appendPxpipeEvent, providerThinking, - // Detect source format by endpoint + body - sourceFormatOverride: request?.url ? detectFormatByEndpoint(new URL(request.url).pathname, body) : null, + sourceFormatOverride: (clientRawRequest?.endpoint || request?.url) + ? detectFormatByEndpoint(clientRawRequest?.endpoint || (request?.url?.startsWith("http") ? new URL(request.url).pathname : request?.url || ""), body) + : null, onCredentialsRefreshed: async (newCreds) => { await updateProviderCredentials(credentials.connectionId, { ...newCreds,