Path: blob/master/src/packages/frontend/account/useLanguageModelSetting.tsx
5755 views
import { redux, useMemo, useTypedRedux } from "@cocalc/frontend/app-framework";1import { getUserDefinedLLM } from "@cocalc/frontend/frame-editors/llm/use-userdefined-llm";2import {3LLMServicesAvailable,4LanguageService,5fromCustomOpenAIModel,6fromOllamaModel,7getValidLanguageModelName,8isCustomOpenAI,9isOllamaLLM,10isUserDefinedModel,11unpackUserDefinedLLMModel,12} from "@cocalc/util/db-schema/llm-utils";1314export const SETTINGS_LANGUAGE_MODEL_KEY = "language_model";1516// ATTN: it is tempting to use the `useProjectContext` hook here, but it is not possible17// The "AI Formula" dialog is outside the project context (unfortunately)18export function useLanguageModelSetting(19project_id?: string,20): [LanguageService, (llm: LanguageService) => void] {21const other_settings = useTypedRedux("account", "other_settings");22const default_llm = useTypedRedux("customize", "default_llm");23const ollama = useTypedRedux("customize", "ollama");24const custom_openai = useTypedRedux("customize", "custom_openai");25const selectableLLMs = useTypedRedux("customize", "selectable_llms");2627const haveOpenAI = useTypedRedux("customize", "openai_enabled");28const haveGoogle = useTypedRedux("customize", "google_vertexai_enabled");29const haveOllama = useTypedRedux("customize", "ollama_enabled");30const haveCustomOpenAI = useTypedRedux("customize", "custom_openai_enabled");31const haveMistral = useTypedRedux("customize", "mistral_enabled");32const haveAnthropic = useTypedRedux("customize", "anthropic_enabled");33const haveXAI = useTypedRedux("customize", "xai_enabled");3435const enabledLLMs: LLMServicesAvailable = useMemo(() => {36const projectsStore = redux.getStore("projects");37return projectsStore.whichLLMareEnabled(project_id);38}, [39haveOpenAI,40haveGoogle,41haveOllama,42haveCustomOpenAI,43haveMistral,44haveAnthropic,45haveXAI,46]);4748const llm: LanguageService = useMemo(() => {49return getValidLanguageModelName({50model: other_settings?.get("language_model") ?? default_llm,51filter: enabledLLMs,52ollama: Object.keys(ollama?.toJS() ?? {}),53custom_openai: Object.keys(custom_openai?.toJS() ?? {}),54selectable_llms: selectableLLMs?.toJS() ?? [],55});56}, [other_settings, custom_openai, ollama, selectableLLMs, enabledLLMs]);5758function setLLM(llm: LanguageService) {59setDefaultLLM(llm);60}6162return [llm, setLLM];63}6465// This changes the account's default LLM66export function setDefaultLLM(llm: LanguageService) {67const customizeStore = redux.getStore("customize");68const selectableLLMs = customizeStore.get("selectable_llms");69const ollama = customizeStore.get("ollama");70const custom_openai = customizeStore.get("custom_openai");7172if (selectableLLMs.includes(llm as any)) {73redux74.getActions("account")75.set_other_settings(SETTINGS_LANGUAGE_MODEL_KEY, llm);76} else if (isOllamaLLM(llm) && ollama?.get(fromOllamaModel(llm))) {77// check if LLM is a key in the Ollama TypedMap78redux79.getActions("account")80.set_other_settings(SETTINGS_LANGUAGE_MODEL_KEY, llm);81} else if (82isCustomOpenAI(llm) &&83custom_openai?.get(fromCustomOpenAIModel(llm))84) {85redux86.getActions("account")87.set_other_settings(SETTINGS_LANGUAGE_MODEL_KEY, llm);88} else if (isUserDefinedModel(llm) && userDefinedLLMExists(llm)) {89redux90.getActions("account")91.set_other_settings(SETTINGS_LANGUAGE_MODEL_KEY, llm);92} else {93console.warn(`setDefaultLLM: LLM "${llm}" is unknown.`);94}95}9697function userDefinedLLMExists(model: string): boolean {98const user_llm = getUserDefinedLLM();99const um = unpackUserDefinedLLMModel(model);100if (um == null) return false;101return user_llm.some((m) => m.service === um.service && m.model === um.model);102}103104105