Skip to content
File

Blob: src/worker/lib/ai/index.ts

typescript48 lines
1import { createMockAiClient } from "@/worker/lib/ai/mock";
2import { createOpenAiCompatClient } from "@/worker/lib/ai/openai-compat";
3import {
4 createWorkersAiClient,
5 DEFAULT_WORKERS_CHAT_MODEL,
6 DEFAULT_WORKERS_SUMMARIZE_MODEL,
7} from "@/worker/lib/ai/workers-ai";
8import { AiMisconfiguredError, type AiClient, type AiMode } from "@/worker/lib/ai/types";
9 
10export function createAiClient(env: Env): AiClient {
11 const mode = resolveMode(env.BLAND_AI_MODE);
12 switch (mode) {
13 case "mock":
14 return createMockAiClient();
15 case "openai-compat":
16 return createOpenAiCompatClient({
17 endpoint: env.BLAND_AI_OPENAI_ENDPOINT,
18 apiKey: env.BLAND_AI_OPENAI_API_KEY,
19 chatModel: env.BLAND_AI_OPENAI_CHAT_MODEL || "llama3",
20 summarizeModel: env.BLAND_AI_OPENAI_SUMMARIZE_MODEL || env.BLAND_AI_OPENAI_CHAT_MODEL || "llama3",
21 });
22 case "workers-ai":
23 return createWorkersAiClient(env.AI, {
24 chatModel: env.BLAND_AI_WORKERS_CHAT_MODEL || DEFAULT_WORKERS_CHAT_MODEL,
25 summarizeModel: env.BLAND_AI_WORKERS_SUMMARIZE_MODEL || DEFAULT_WORKERS_SUMMARIZE_MODEL,
26 });
27 }
28}
29 
30function resolveMode(raw: string): AiMode {
31 const value = (raw || "").trim().toLowerCase();
32 if (value === "mock") return "mock";
33 if (value === "openai-compat") return "openai-compat";
34 if (value === "workers-ai" || value === "") return "workers-ai";
35 throw new AiMisconfiguredError(`Unknown BLAND_AI_MODE: ${raw}`);
36}
37 
38export { AiMisconfiguredError, AiBackendError } from "@/worker/lib/ai/types";
39export type {
40 AiClient,
41 AiChatMessage,
42 AiChatOptions,
43 AiFrame,
44 AiSummarizeOptions,
45 AiSummarizeResult,
46 AiMode,
47} from "@/worker/lib/ai/types";