Files
Termix/plugins/ai/backend/providers/registry.ts
T
LukeGus 504710b065 feat: ship the AI assistant as a first-party in-process plugin
Moves src/backend/ai and its routes into plugins/ai, mounted through a
small /ai dispatcher instead of its own port. Moves the ai-enabled and
ai-private-endpoints settings routes out of user-settings-routes.ts
into the plugin too, so it has no leftover core dependents.
2026-09-21 15:20:05 -05:00

65 lines
1.9 KiB
TypeScript

import { anthropicAdapter } from "./anthropic.js";
import { geminiAdapter } from "./gemini.js";
import { ollamaAdapter } from "./ollama.js";
import { openAiAdapter } from "./openai.js";
import {
AiProviderError,
type AiProviderType,
type ProviderAdapter,
} from "./types.js";
/**
* openai_compatible reuses the OpenAI adapter: OpenRouter, Groq, Mistral,
* DeepSeek, together.ai, LM Studio and vLLM all speak the same wire format,
* they differ only in base URL.
*/
const ADAPTERS: Record<AiProviderType, ProviderAdapter> = {
ollama: ollamaAdapter,
anthropic: anthropicAdapter,
openai: openAiAdapter,
gemini: geminiAdapter,
openai_compatible: openAiAdapter,
};
export function getAdapter(providerType: string): ProviderAdapter {
const adapter = ADAPTERS[providerType as AiProviderType];
if (!adapter) {
throw new AiProviderError(`Unknown provider type: ${providerType}`);
}
return adapter;
}
/** Provider types that cannot work without a base URL. */
export const REQUIRES_BASE_URL: AiProviderType[] = [
"ollama",
"openai_compatible",
];
/** Provider types that cannot work without an API key. */
export const REQUIRES_API_KEY: AiProviderType[] = [
"anthropic",
"openai",
"gemini",
];
/**
* Shown when a provider's model list cannot be fetched: no key entered yet,
* the endpoint is unreachable, or the vendor has no list endpoint. Users can
* always type a model id the list does not contain, so this is a starting
* point rather than a restriction.
*/
export const FALLBACK_MODELS: Record<AiProviderType, string[]> = {
ollama: [
"llama3.2",
"llama3.1",
"qwen2.5-coder",
"mistral",
"phi4",
"gemma2",
],
anthropic: ["claude-opus-5", "claude-sonnet-5", "claude-haiku-4-5"],
openai: ["gpt-5", "gpt-5-mini", "o4-mini", "gpt-4.1"],
gemini: ["gemini-2.5-pro", "gemini-2.5-flash", "gemini-2.0-flash"],
openai_compatible: [],
};