From 83354889cf2e63175e38a336b238c07c5886d417 Mon Sep 17 00:00:00 2001 From: bitgineer <133060368+bitgineer@users.noreply.github.com> Date: Mon, 30 Mar 2026 01:27:09 -0400 Subject: [PATCH] fix: handle anthropic-compatible providers in BaseExecutor (#428) The BaseExecutor's buildUrl() and buildHeaders() methods only handled openai-compatible-* providers but not anthropic-compatible-* providers. This caused Anthropic-compatible synthetic providers to fail API testing by hitting the wrong endpoint (returning documentation instead of valid API responses) and using incorrect auth headers. Changes: - Added buildUrl() handling for anthropic-compatible-* providers to append /messages path - Added buildHeaders() handling for x-api-key header and anthropic-version for anthropic-compatible providers Fixes #XXX Co-authored-by: Bitgineer --- open-sse/executors/base.js | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/open-sse/executors/base.js b/open-sse/executors/base.js index 74ca14d1..589dc9b3 100644 --- a/open-sse/executors/base.js +++ b/open-sse/executors/base.js @@ -29,6 +29,11 @@ export class BaseExecutor { const path = this.provider.includes("responses") ? "/responses" : "/chat/completions"; return `${normalized}${path}`; } + if (this.provider?.startsWith?.("anthropic-compatible-")) { + const baseUrl = credentials?.providerSpecificData?.baseUrl || "https://api.anthropic.com/v1"; + const normalized = baseUrl.replace(/\/$/, ""); + return `${normalized}/messages`; + } const baseUrls = this.getBaseUrls(); return baseUrls[urlIndex] || baseUrls[0] || this.config.baseUrl; } @@ -39,10 +44,23 @@ export class BaseExecutor { ...this.config.headers }; - if (credentials.accessToken) { - headers["Authorization"] = `Bearer ${credentials.accessToken}`; - } else if (credentials.apiKey) { - headers["Authorization"] = `Bearer ${credentials.apiKey}`; + if (this.provider?.startsWith?.("anthropic-compatible-")) { + // Anthropic-compatible providers use x-api-key header + if (credentials.apiKey) { + headers["x-api-key"] = credentials.apiKey; + } else if (credentials.accessToken) { + headers["Authorization"] = `Bearer ${credentials.accessToken}`; + } + if (!headers["anthropic-version"]) { + headers["anthropic-version"] = "2023-06-01"; + } + } else { + // Standard Bearer token auth for other providers + if (credentials.accessToken) { + headers["Authorization"] = `Bearer ${credentials.accessToken}`; + } else if (credentials.apiKey) { + headers["Authorization"] = `Bearer ${credentials.apiKey}`; + } } if (stream) {