9router/src/sse/services/model.js
Quan 07717bad60 feat: cherry-pick PR #183 — multi-provider support, PWA, dynamic models, UI improvements
Cherry-picked from decolua/9router PR #183.
Note: open-sse changes included but need further review due to extensive modifications.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-25 11:40:50 +07:00

68 lines
2.2 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
};
}
// Check if this is a combo name before resolving as alias
// This prevents combo names from being incorrectly routed to providers
const combo = await getComboByName(parsed.model);
if (combo) {
// Return null provider to signal this should be handled as combo
// The caller (handleChat) will detect this and handle it as combo
return { provider: null, 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;
}