From 2fead57d0f56d12c0ede1a3e929ac0a06ce8f1dd Mon Sep 17 00:00:00 2001 From: MythEclipse Date: Thu, 11 Jun 2026 00:42:21 +0700 Subject: [PATCH] fix: use MODEL_ROUTES directly for Anthropic proxy routing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the ANTHROPIC_MODEL_MAP layer — /v1/messages now uses the same model names as /v1/chat/completions (deepseek-v4-flash-free, gpt-5.4-mini-no-login, deepseek/deepseek-v4-flash). This way users send the original model name and it routes to the correct backend. Co-Authored-By: Claude Fable 5 --- api/relay.ts | 4 ++-- src/index.ts | 2 +- src/lib/anthropic-proxy.ts | 45 +++++--------------------------------- src/worker.ts | 4 ++-- 4 files changed, 11 insertions(+), 44 deletions(-) diff --git a/api/relay.ts b/api/relay.ts index 21ebca6..514ca9e 100644 --- a/api/relay.ts +++ b/api/relay.ts @@ -28,7 +28,7 @@ import { checkBodySize } from "../src/middleware/body-limiter"; import { createRateLimiter } from "../src/middleware/rate-limiter"; import { logRelayEvent } from "../src/middleware/logger"; import { handleChatCompletion, listModels } from "../src/lib/ai-proxy"; -import { handleAnthropicMessages, listAnthropicModels } from "../src/lib/anthropic-proxy"; +import { handleAnthropicMessages } from "../src/lib/anthropic-proxy"; // ─── Configuration ────────────────────────────────────────────────────────────── @@ -428,7 +428,7 @@ export default { // Models list if (url.pathname === "/v1/models" && req.method === "GET") { - const models = [...listModels(), ...listAnthropicModels()].map((id) => ({ + const models = listModels().map((id) => ({ id, object: "model", created: Math.floor(Date.now() / 1000), diff --git a/src/index.ts b/src/index.ts index 46f8576..a394b0e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -29,7 +29,7 @@ import { createRateLimiter } from "./middleware/rate-limiter"; import { logRelayEvent } from "./middleware/logger"; import { ProxyPool } from "./lib/proxy-pool"; import { handleChatCompletion, listModels } from "./lib/ai-proxy"; -import { handleAnthropicMessages, listAnthropicModels } from "./lib/anthropic-proxy"; +import { handleAnthropicMessages } from "./lib/anthropic-proxy"; import type { Server, ServerWebSocket } from "bun"; diff --git a/src/lib/anthropic-proxy.ts b/src/lib/anthropic-proxy.ts index 9ed0ca5..2fbee95 100644 --- a/src/lib/anthropic-proxy.ts +++ b/src/lib/anthropic-proxy.ts @@ -40,53 +40,20 @@ interface AnthropicResponse { usage: { input_tokens: number; output_tokens: number }; } -// ─── Anthropic model → backend model mapping ────────────────────────────────── +// ─── Model resolution ───────────────────────────────────────────────────────── -/** User-facing Anthropic model name → { backendModel, backendConfig }. */ -const ANTHROPIC_MODEL_MAP: Record< - string, - { backendModel: string; config: BackendConfig } -> = { - "claude-sonnet-4-20250514": { - backendModel: "deepseek-v4-flash-free", - config: MODEL_ROUTES["deepseek-v4-flash-free"]!, - }, - "claude-sonnet-4": { - backendModel: "deepseek-v4-flash-free", - config: MODEL_ROUTES["deepseek-v4-flash-free"]!, - }, - "claude-3-haiku-20240307": { - backendModel: "gpt-5.4-mini-no-login", - config: MODEL_ROUTES["gpt-5.4-mini-no-login"]!, - }, - "claude-3-haiku": { - backendModel: "gpt-5.4-mini-no-login", - config: MODEL_ROUTES["gpt-5.4-mini-no-login"]!, - }, - "claude-opus-4-20250514": { - backendModel: "deepseek/deepseek-v4-flash", - config: MODEL_ROUTES["deepseek/deepseek-v4-flash"]!, - }, - "claude-opus-4": { - backendModel: "deepseek/deepseek-v4-flash", - config: MODEL_ROUTES["deepseek/deepseek-v4-flash"]!, - }, -}; - -// Also allow using raw backend model names directly +/** Resolve a model name to a backend config (uses MODEL_ROUTES directly). */ function resolveAnthropicModel( model: string, ): { backendModel: string; config: BackendConfig } | undefined { - if (ANTHROPIC_MODEL_MAP[model]) return ANTHROPIC_MODEL_MAP[model]; - // Fallback — try using the model name directly as a backend route const direct = MODEL_ROUTES[model]; if (direct) return { backendModel: model, config: direct }; return undefined; } -/** List all available Anthropic model names. */ +/** List all available model names (same as OpenAI endpoint). */ export function listAnthropicModels(): string[] { - return Object.keys(ANTHROPIC_MODEL_MAP); + return Object.keys(MODEL_ROUTES); } // ─── Translation: Anthropic → Backend (OpenAI-format) ─────────────────────── @@ -126,7 +93,7 @@ function anthropicToBackend( } const base: BackendBody = { - model: anthReq.model, + model: backendModel, messages, max_tokens: anthReq.max_tokens, temperature: anthReq.temperature, @@ -144,7 +111,7 @@ function anthropicToBackend( // If backend has a custom adaptRequest, use it if (config.adaptRequest) { return config.adaptRequest({ - model: anthReq.model, + model: backendModel, messages, temperature: anthReq.temperature, max_tokens: anthReq.max_tokens, diff --git a/src/worker.ts b/src/worker.ts index e347cca..ca9465d 100644 --- a/src/worker.ts +++ b/src/worker.ts @@ -27,7 +27,7 @@ import { checkBodySize } from "./middleware/body-limiter"; import { createRateLimiter } from "./middleware/rate-limiter"; import { logRelayEvent } from "./middleware/logger"; import { handleChatCompletion, listModels } from "./lib/ai-proxy"; -import { handleAnthropicMessages, listAnthropicModels } from "./lib/anthropic-proxy"; +import { handleAnthropicMessages } from "./lib/anthropic-proxy"; // ─── Types ─────────────────────────────────────────────────────────────────────── @@ -424,7 +424,7 @@ export default { // Models list if (url.pathname === "/v1/models" && req.method === "GET") { - const models = [...listModels(), ...listAnthropicModels()].map((id) => ({ + const models = listModels().map((id) => ({ id, object: "model", created: Math.floor(Date.now() / 1000),