feat(channels): 添加对 Gemini 渠道的支持和相关配置
This commit is contained in:
1 parent
88ae321d4f
commit
7707de2b3e
10 files changed
+108
-18
No files matched your search
@@ -90,11 +90,12 @@ const buildModelsFetchRequest = (
|
||||
headers.set("anthropic-version", DEFAULT_CLAUDE_API_VERSION);
|
||||
break;
|
||||
case "openai":
|
||||
case "gemini":
|
||||
case "openai-audio":
|
||||
case "openai-responses":
|
||||
case "claude-to-openai":
|
||||
default:
|
||||
targetUrl = buildPrefixedTargetUrl(config.endpoint, "/v1/models");
|
||||
targetUrl = buildPrefixedTargetUrl(config.endpoint, "/v1/models", "/v1", config.type);
|
||||
headers.set("Authorization", `Bearer ${apiKey}`);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ const buildProxyRequest = (
|
||||
config: ChannelConfig
|
||||
): Request => {
|
||||
const url = new URL(request.url)
|
||||
const targetUrl = buildPrefixedTargetUrl(config.endpoint, url.pathname)
|
||||
const targetUrl = buildPrefixedTargetUrl(config.endpoint, url.pathname, "/v1", config.type)
|
||||
const apiKey = config.api_key || ""
|
||||
|
||||
const targetHeaders = new Headers(request.headers)
|
||||
|
||||
@@ -10,10 +10,27 @@ const joinPath = (...segments: string[]): string => {
|
||||
return `/${cleanedSegments.join("/")}`;
|
||||
};
|
||||
|
||||
const normalizeGeminiBasePath = (basePath: string): string => {
|
||||
if (basePath.endsWith("v1beta/openai")) {
|
||||
return basePath;
|
||||
}
|
||||
|
||||
if (basePath.endsWith("v1beta")) {
|
||||
return joinPath(basePath, "openai");
|
||||
}
|
||||
|
||||
if (basePath.endsWith("openai")) {
|
||||
return basePath;
|
||||
}
|
||||
|
||||
return joinPath(basePath, "v1beta/openai");
|
||||
};
|
||||
|
||||
export const buildPrefixedTargetUrl = (
|
||||
endpoint: string,
|
||||
requestPath: string,
|
||||
prefixToStrip = "/v1"
|
||||
prefixToStrip = "/v1",
|
||||
providerType?: string | null,
|
||||
): URL => {
|
||||
const targetUrl = new URL(endpoint);
|
||||
|
||||
@@ -22,6 +39,14 @@ export const buildPrefixedTargetUrl = (
|
||||
}
|
||||
|
||||
const currentBasePath = trimSlashes(targetUrl.pathname);
|
||||
|
||||
if (providerType === "gemini") {
|
||||
const geminiBasePath = normalizeGeminiBasePath(currentBasePath);
|
||||
const normalizedRequestPath = requestPath.replace(/^\/v1(?=\/|$)/, "");
|
||||
targetUrl.pathname = joinPath(geminiBasePath, normalizedRequestPath);
|
||||
return targetUrl;
|
||||
}
|
||||
|
||||
const normalizedPrefix = trimSlashes(prefixToStrip);
|
||||
const baseAlreadyContainsPrefix = normalizedPrefix.length > 0
|
||||
&& currentBasePath.endsWith(normalizedPrefix);
|
||||
|
||||
@@ -17,6 +17,7 @@ export type ProviderFetch = (
|
||||
const providerMap: Record<string, ProviderFetch> = {
|
||||
"azure-openai": azureOpenaiProxy.fetch,
|
||||
"openai": openaiProxy.fetch,
|
||||
"gemini": openaiProxy.fetch,
|
||||
"azure-openai-audio": azureOpenaiProxy.fetch,
|
||||
"openai-audio": openaiProxy.fetch,
|
||||
"claude": claudeProxy.fetch,
|
||||
|
||||
@@ -4,16 +4,20 @@ type RoutePolicy = {
|
||||
allowedTypes: ChannelType[] | null
|
||||
}
|
||||
|
||||
const TEXT_CHANNEL_TYPES: ChannelType[] = [
|
||||
const CHAT_COMPLETIONS_CHANNEL_TYPES: ChannelType[] = [
|
||||
"openai",
|
||||
"azure-openai",
|
||||
"gemini",
|
||||
]
|
||||
|
||||
const MESSAGES_CHANNEL_TYPES: ChannelType[] = [
|
||||
"claude",
|
||||
"claude-to-openai",
|
||||
]
|
||||
|
||||
const ROUTE_POLICIES: Record<RouteId, RoutePolicy> = {
|
||||
"chat-completions": { allowedTypes: TEXT_CHANNEL_TYPES },
|
||||
"messages": { allowedTypes: TEXT_CHANNEL_TYPES },
|
||||
"chat-completions": { allowedTypes: CHAT_COMPLETIONS_CHANNEL_TYPES },
|
||||
"messages": { allowedTypes: MESSAGES_CHANNEL_TYPES },
|
||||
"responses": { allowedTypes: ["openai-responses", "azure-openai-responses"] },
|
||||
"audio-speech": { allowedTypes: ["openai-audio", "azure-openai-audio"] },
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user