diff --git a/src/lib/ai/index.ts b/src/lib/ai/index.ts new file mode 100644 index 0000000..5a2c7ff --- /dev/null +++ b/src/lib/ai/index.ts @@ -0,0 +1,41 @@ +import "server-only"; + +import { loadAiSettings } from "@/lib/ai/settings"; +import { buildSystemPrompt } from "@/lib/ai/prompt"; +import { createAnthropicProvider } from "@/lib/ai/provider-anthropic"; +import { createOpenAiCompatibleProvider } from "@/lib/ai/provider-openai"; +import { AiError, type AiProvider } from "@/lib/ai/types"; + +/** + * The only module that decides which provider is active. + * + * Every consumer asks for `getProvider()` and gets the interface. Nothing else + * in the codebase should import an adapter directly — that is what keeps + * switching provider a settings change. + */ +export async function getProvider(): Promise { + const settings = await loadAiSettings(); + + if (!settings?.apiKey) { + throw new AiError("No AI provider is configured", false); + } + + if (settings.provider === "anthropic") { + return createAnthropicProvider(settings.apiKey, settings.model); + } + + return createOpenAiCompatibleProvider( + settings.apiKey, + settings.model, + settings.provider + ); +} + +/** The full system prompt for the current settings. */ +export async function getSystemPrompt(): Promise { + const settings = await loadAiSettings(); + return buildSystemPrompt(settings?.systemPromptExtra ?? ""); +} + +export { AiError }; +export type { AiProvider, CompletionRequest, CompletionResult } from "@/lib/ai/types"; \ No newline at end of file