diff --git a/src/packages/frontend/account/other-settings.tsx b/src/packages/frontend/account/other-settings.tsx index 27a77341792..220cc1d5ae7 100644 --- a/src/packages/frontend/account/other-settings.tsx +++ b/src/packages/frontend/account/other-settings.tsx @@ -378,7 +378,7 @@ export class OtherSettings extends Component { render_language_model(): Rendered { const projectsStore = redux.getStore("projects"); - const enabled = projectsStore.llmEnabledSummary(); + const enabled = projectsStore.whichLLMareEnabled(); const ollama = redux.getStore("customize").get("ollama")?.toJS() ?? {}; const defaultModel = getValidLanguageModelName( diff --git a/src/packages/frontend/account/useLanguageModelSetting.tsx b/src/packages/frontend/account/useLanguageModelSetting.tsx index e3c431c9eb9..5739605c3f9 100644 --- a/src/packages/frontend/account/useLanguageModelSetting.tsx +++ b/src/packages/frontend/account/useLanguageModelSetting.tsx @@ -21,7 +21,7 @@ export function useLanguageModelSetting(): [ const filter = useMemo(() => { const projectsStore = redux.getStore("projects"); - return projectsStore.llmEnabledSummary(); + return projectsStore.whichLLMareEnabled(); }, [haveOpenAI, haveGoogle, haveOllama]); const llm = useMemo(() => { diff --git a/src/packages/frontend/components/language-model-icon.tsx b/src/packages/frontend/components/language-model-icon.tsx index 80954715c92..6bfe97c8387 100644 --- a/src/packages/frontend/components/language-model-icon.tsx +++ b/src/packages/frontend/components/language-model-icon.tsx @@ -1,5 +1,9 @@ import { CSS } from "@cocalc/frontend/app-framework"; -import { isLanguageModel, model2vendor } from "@cocalc/util/db-schema/llm"; +import { + isLanguageModel, + isOllamaLLM, + model2vendor, +} from "@cocalc/util/db-schema/llm"; import { unreachable } from "@cocalc/util/misc"; import AIAvatar from "./ai-avatar"; import GoogleGeminiLogo from "./google-gemini-avatar"; @@ -19,12 +23,16 @@ export function LanguageModelVendorAvatar( const style: CSS = { marginRight: "5px", ...props.style, - }; + } as const; function fallback() { return ; } + if (model == null) { + return fallback(); + } + if (isLanguageModel(model)) { const vendor = model2vendor(model); switch (vendor) { @@ -40,6 +48,7 @@ export function LanguageModelVendorAvatar( return fallback(); } } + case "ollama": return ; @@ -47,7 +56,11 @@ export function LanguageModelVendorAvatar( unreachable(vendor); return fallback(); } - } else { - return fallback(); } + + if (isOllamaLLM(model)) { + return ; + } + + return fallback(); } diff --git a/src/packages/frontend/components/ollama-avatar.tsx b/src/packages/frontend/components/ollama-avatar.tsx index c9c33f93c1e..3b25614446f 100644 --- a/src/packages/frontend/components/ollama-avatar.tsx +++ b/src/packages/frontend/components/ollama-avatar.tsx @@ -1,15 +1,14 @@ -import { CSS } from "../app-framework"; -import ollamaPng from "./ollama.png"; +import { CSS } from "@cocalc/frontend/app-framework"; export default function OllamaAvatar({ size = 64, style, + backgroundColor = "transparent", }: { size: number; style?: CSS; + backgroundColor?: string; }) { - // render the ollamaPng (a square png image with transparent background) with the given size and background color - return (
- + > + + + + + + + + + + + + +
); } diff --git a/src/packages/frontend/components/ollama.png b/src/packages/frontend/components/ollama.png deleted file mode 100644 index 1f142c8d534..00000000000 Binary files a/src/packages/frontend/components/ollama.png and /dev/null differ diff --git a/src/packages/frontend/frame-editors/llm/model-switch.tsx b/src/packages/frontend/frame-editors/llm/model-switch.tsx index 046bf90aff2..85d9b804e9d 100644 --- a/src/packages/frontend/frame-editors/llm/model-switch.tsx +++ b/src/packages/frontend/frame-editors/llm/model-switch.tsx @@ -111,10 +111,10 @@ export default function ModelSwitch({ if (!showOllama || !ollama) return null; return Object.entries(ollama.toJS()).map(([key, config]) => { - const title = config.display ?? `Ollama: ${key}`; + const { display } = config; return ( - - {title} + + {display} ); }); diff --git a/src/packages/frontend/projects/store.ts b/src/packages/frontend/projects/store.ts index 29c1adfc29d..4a6489743f7 100644 --- a/src/packages/frontend/projects/store.ts +++ b/src/packages/frontend/projects/store.ts @@ -734,7 +734,8 @@ export class ProjectsStore extends Store { openAICache.clear(); } - public llmEnabledSummary(project_id: string = "global", tag?: string) { + // ATTN: the useLanguageModelSetting hook computes this dynamically, with dependencies + public whichLLMareEnabled(project_id: string = "global", tag?: string) { const haveOpenAI = this.hasLanguageModelEnabled(project_id, tag, "openai"); const haveGoogle = this.hasLanguageModelEnabled(project_id, tag, "google"); const haveOllama = this.hasLanguageModelEnabled(project_id, tag, "ollama"); diff --git a/src/packages/frontend/sagews/chatgpt.ts b/src/packages/frontend/sagews/chatgpt.ts index 33b3a72e998..cf60e1f5f87 100644 --- a/src/packages/frontend/sagews/chatgpt.ts +++ b/src/packages/frontend/sagews/chatgpt.ts @@ -27,7 +27,7 @@ export function helpMeFix({ const other_settings = redux.getStore("account").get("other_settings"); const projectsStore = redux.getStore("projects"); - const enabled = projectsStore.llmEnabledSummary(); + const enabled = projectsStore.whichLLMareEnabled(); const ollama = redux.getStore("customize").get("ollama")?.toJS() ?? {}; const model = getValidLanguageModelName( diff --git a/src/packages/hub/webapp-configuration.ts b/src/packages/hub/webapp-configuration.ts index 94ad8227420..8dd725d6461 100644 --- a/src/packages/hub/webapp-configuration.ts +++ b/src/packages/hub/webapp-configuration.ts @@ -181,14 +181,13 @@ export class WebappConfiguration { const ollama = this.data.all.ollama_configuration; if (isEmpty(ollama)) return {}; - const public_ollama = {}; + const public_ollama: { [key: string]: OllamaPublic } = {}; for (const key in ollama) { const conf = ollama[key]; const cocalc = conf.cocalc ?? {}; if (cocalc.disabled) continue; const model = conf.model ?? key; public_ollama[key] = { - key, model, display: cocalc.display ?? `Ollama ${model}`, icon: cocalc.icon, // fallback is the Ollama icon, frontend does that diff --git a/src/packages/util/db-schema/llm.ts b/src/packages/util/db-schema/llm.ts index 38e46f7c601..c0c41cc21e6 100644 --- a/src/packages/util/db-schema/llm.ts +++ b/src/packages/util/db-schema/llm.ts @@ -138,7 +138,7 @@ export const DEFAULT_MODEL: LanguageModel = "gpt-3.5-turbo"; export function model2vendor(model: LanguageModel | string): Vendor { if (model.startsWith("gpt-")) { return "openai"; - } else if (model.startsWith("ollama-")) { + } else if (isOllamaLLM(model)) { return "ollama"; } else { return "google"; diff --git a/src/packages/util/types/llm.ts b/src/packages/util/types/llm.ts index 70cce04b8c0..f9395d166d5 100644 --- a/src/packages/util/types/llm.ts +++ b/src/packages/util/types/llm.ts @@ -32,8 +32,7 @@ export interface ChatOptions { } export interface OllamaPublic { - key: string; // the key in the dict model: string; display: string; - icon: string; + icon?: string; // fallback to OllamaAvatar }