- Added support for 'anthropic-compatible' provider nodes in backend. - Implemented isAnthropicCompatible logic in open-sse for /messages URL construction and headers. - Added UI for creating and managing Anthropic Compatible providers in the dashboard. - Updated validation logic for Anthropic-compatible endpoints. - Sanitize base URL input (strip trailing /messages) to prevent 404s and improve UX. - Improve validation: use GET /models (2xx success), and support x-api-key / Authorization Bearer hybrid proxies. - Enable model import via /models for Anthropic Compatible providers. - Ensure Authorization is omitted when x-api-key is present to avoid strict proxy conflicts. - Resolve Anthropic-compatible credentials by prefix during model resolution (e.g., acx/model). - Update default executor to match provider header/url behavior for Anthropic-compatible providers.
60 lines
1.9 KiB
JavaScript
60 lines
1.9 KiB
JavaScript
// Re-export from open-sse with localDb integration
|
|
import { getModelAliases, getComboByName, getProviderNodes } from "@/lib/localDb";
|
|
import { parseModel, resolveModelAliasFromMap, getModelInfoCore } from "open-sse/services/model.js";
|
|
|
|
export { parseModel };
|
|
|
|
/**
|
|
* Resolve model alias from localDb
|
|
*/
|
|
export async function resolveModelAlias(alias) {
|
|
const aliases = await getModelAliases();
|
|
return resolveModelAliasFromMap(alias, aliases);
|
|
}
|
|
|
|
/**
|
|
* Get full model info (parse or resolve)
|
|
*/
|
|
export async function getModelInfo(modelStr) {
|
|
const parsed = parseModel(modelStr);
|
|
|
|
if (!parsed.isAlias) {
|
|
if (parsed.provider === parsed.providerAlias) {
|
|
// Check OpenAI Compatible nodes
|
|
const openaiNodes = await getProviderNodes({ type: "openai-compatible" });
|
|
const matchedOpenAI = openaiNodes.find((node) => node.prefix === parsed.providerAlias);
|
|
if (matchedOpenAI) {
|
|
return { provider: matchedOpenAI.id, model: parsed.model };
|
|
}
|
|
|
|
// Check Anthropic Compatible nodes
|
|
const anthropicNodes = await getProviderNodes({ type: "anthropic-compatible" });
|
|
const matchedAnthropic = anthropicNodes.find((node) => node.prefix === parsed.providerAlias);
|
|
if (matchedAnthropic) {
|
|
return { provider: matchedAnthropic.id, model: parsed.model };
|
|
}
|
|
}
|
|
return {
|
|
provider: parsed.provider,
|
|
model: parsed.model
|
|
};
|
|
}
|
|
|
|
return getModelInfoCore(modelStr, getModelAliases);
|
|
}
|
|
|
|
/**
|
|
* Check if model is a combo and get models list
|
|
* @returns {Promise<string[]|null>} Array of models or null if not a combo
|
|
*/
|
|
export async function getComboModels(modelStr) {
|
|
// Only check if it's not in provider/model format
|
|
if (modelStr.includes("/")) return null;
|
|
|
|
const combo = await getComboByName(modelStr);
|
|
if (combo && combo.models && combo.models.length > 0) {
|
|
return combo.models;
|
|
}
|
|
return null;
|
|
}
|