Enhance image and embedding provider support
- Added new image models for GPT 5.2, 5.3, and 5.4, including capabilities for text-to-image and editing. - Updated embedding handling to include optional dimensions in requests. - Introduced support for custom embedding providers, allowing dynamic fetching and validation of custom nodes. - Improved image generation handling with Codex integration, including progress tracking and error handling. - Enhanced UI components to support adding custom embeddings and displaying their status.
This commit is contained in:
@@ -7,7 +7,7 @@ import {
|
||||
getProxyPoolById,
|
||||
} from "@/models";
|
||||
import { APIKEY_PROVIDERS } from "@/shared/constants/config";
|
||||
import { FREE_TIER_PROVIDERS, WEB_COOKIE_PROVIDERS, isOpenAICompatibleProvider, isAnthropicCompatibleProvider } from "@/shared/constants/providers";
|
||||
import { FREE_TIER_PROVIDERS, WEB_COOKIE_PROVIDERS, isOpenAICompatibleProvider, isAnthropicCompatibleProvider, isCustomEmbeddingProvider } from "@/shared/constants/providers";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
@@ -104,7 +104,8 @@ export async function POST(request) {
|
||||
FREE_TIER_PROVIDERS[provider] ||
|
||||
isWebCookieProvider ||
|
||||
isOpenAICompatibleProvider(provider) ||
|
||||
isAnthropicCompatibleProvider(provider);
|
||||
isAnthropicCompatibleProvider(provider) ||
|
||||
isCustomEmbeddingProvider(provider);
|
||||
|
||||
if (!provider || !isValidProvider) {
|
||||
return NextResponse.json({ error: "Invalid provider" }, { status: 400 });
|
||||
@@ -146,6 +147,22 @@ export async function POST(request) {
|
||||
return NextResponse.json({ error: "Only one connection is allowed for this Anthropic Compatible node" }, { status: 400 });
|
||||
}
|
||||
|
||||
providerSpecificData = {
|
||||
prefix: node.prefix,
|
||||
baseUrl: node.baseUrl,
|
||||
nodeName: node.name,
|
||||
};
|
||||
} else if (isCustomEmbeddingProvider(provider)) {
|
||||
const node = await getProviderNodeById(provider);
|
||||
if (!node) {
|
||||
return NextResponse.json({ error: "Custom Embedding node not found" }, { status: 404 });
|
||||
}
|
||||
|
||||
const existingConnections = await getProviderConnections({ provider });
|
||||
if (existingConnections.length > 0) {
|
||||
return NextResponse.json({ error: "Only one connection is allowed for this Custom Embedding node" }, { status: 400 });
|
||||
}
|
||||
|
||||
providerSpecificData = {
|
||||
prefix: node.prefix,
|
||||
baseUrl: node.baseUrl,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { getProviderNodeById } from "@/models";
|
||||
import { isOpenAICompatibleProvider, isAnthropicCompatibleProvider } from "@/shared/constants/providers";
|
||||
import { isOpenAICompatibleProvider, isAnthropicCompatibleProvider, isCustomEmbeddingProvider } from "@/shared/constants/providers";
|
||||
import { getDefaultModel } from "open-sse/config/providerModels.js";
|
||||
import { resolveOllamaLocalHost } from "open-sse/config/providers.js";
|
||||
|
||||
@@ -35,6 +35,37 @@ export async function POST(request) {
|
||||
});
|
||||
}
|
||||
|
||||
// Custom Embedding nodes: probe /models (most embedding APIs are OpenAI-compatible)
|
||||
if (isCustomEmbeddingProvider(provider)) {
|
||||
const node = await getProviderNodeById(provider);
|
||||
if (!node) {
|
||||
return NextResponse.json({ error: "Custom Embedding node not found" }, { status: 404 });
|
||||
}
|
||||
const baseUrl = node.baseUrl?.replace(/\/$/, "");
|
||||
const modelsRes = await fetch(`${baseUrl}/models`, {
|
||||
headers: { "Authorization": `Bearer ${apiKey}` },
|
||||
});
|
||||
if (modelsRes.ok) {
|
||||
return NextResponse.json({ valid: true });
|
||||
}
|
||||
// Auth errors are definitive
|
||||
if (modelsRes.status === 401 || modelsRes.status === 403) {
|
||||
return NextResponse.json({ valid: false, error: "Invalid API key" });
|
||||
}
|
||||
// Fallback: probe /embeddings with a common test model — many providers lack /models
|
||||
const embedRes = await fetch(`${baseUrl}/embeddings`, {
|
||||
method: "POST",
|
||||
headers: { "Authorization": `Bearer ${apiKey}`, "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ model: "test", input: "ping" }),
|
||||
});
|
||||
// 401/403 = bad key; anything else (including 400 "model not found") means key works
|
||||
isValid = embedRes.status !== 401 && embedRes.status !== 403;
|
||||
return NextResponse.json({
|
||||
valid: isValid,
|
||||
error: isValid ? null : "Invalid API key",
|
||||
});
|
||||
}
|
||||
|
||||
if (isAnthropicCompatibleProvider(provider)) {
|
||||
const node = await getProviderNodeById(provider);
|
||||
if (!node) {
|
||||
|
||||
Reference in New Issue
Block a user