fix: use MODEL_ROUTES directly for Anthropic proxy routing
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 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
2fca9febe4
commit
2fead57d0f
+2
-2
@@ -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),
|
||||
|
||||
+1
-1
@@ -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";
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
+2
-2
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user