Path: blob/master/src/packages/frontend/components/language-model-icon.tsx
6023 views
import { CSS, useTypedRedux } from "@cocalc/frontend/app-framework";1import {2LLMServiceName,3LanguageModel,4SERVICES,5fromCustomOpenAIModel,6fromOllamaModel,7fromUserDefinedLLMModel,8isGoogleModel,9isLanguageModel,10isUserDefinedModel,11model2vendor,12} from "@cocalc/util/db-schema/llm-utils";13import { unreachable } from "@cocalc/util/misc";14import AIAvatar from "./ai-avatar";15import AnthropicAvatar from "./anthropic-avatar";16import GoogleGeminiLogo from "./google-gemini-avatar";17import GooglePalmLogo from "./google-palm-avatar";18import MistralAvatar from "./mistral-avatar";19import OllamaAvatar from "./ollama-avatar";20import OpenAIAvatar from "./openai-avatar";21import XAIAvatar from "./xai-avatar";2223export function LanguageModelVendorAvatar(24props: Readonly<{25model?: LanguageModel;26size?: number;27style?: CSS;28}>,29) {30const { model, size = 20 } = props;3132const ollama = useTypedRedux("customize", "ollama");33const custom_openai = useTypedRedux("customize", "custom_openai");3435const style: CSS = {36marginRight: "5px",37...props.style,38} as const;3940function fallback() {41return <AIAvatar size={size} style={style} />;42}4344if (model == null) {45return fallback();46}4748function renderImgIcon(icon: string) {49return (50<img51width={size}52height={size}53src={icon}54style={{ display: "inline-block", ...style }}55/>56);57}5859function renderModel(model: string, vendor?: LLMServiceName) {60const useIcon = vendor == null;61const vendorName = vendor ?? model2vendor(model).name;62switch (vendorName) {63case "openai":64return <OpenAIAvatar size={size} style={style} />;6566case "custom_openai": {67const icon = custom_openai?.getIn([68fromCustomOpenAIModel(model),69"icon",70]);71if (useIcon && typeof icon === "string") {72return renderImgIcon(icon);73} else {74return <OpenAIAvatar size={size} style={style} />;75}76}7778case "google": {79if (model === "chat-bison-001") {80// Palm2, no longer supported, just for backwards compatibility81return <GooglePalmLogo size={size} style={style} />;82} else if (!useIcon || isGoogleModel(model)) {83return <GoogleGeminiLogo size={size} style={style} />;84} else {85return fallback();86}87}8889case "mistralai":90return <MistralAvatar size={size} style={style} />;9192case "ollama": {93const icon = ollama?.getIn([fromOllamaModel(model), "icon"]);94if (useIcon && typeof icon === "string") {95return renderImgIcon(icon);96} else {97return <OllamaAvatar size={size} style={style} />;98}99}100101case "anthropic":102return <AnthropicAvatar size={size} style={style} />;103104case "xai":105return <XAIAvatar size={size} style={style} />;106107case "user":108// should never happen, because it is unpacked below109return fallback();110111default:112unreachable(vendorName);113return fallback();114}115}116117if (isUserDefinedModel(model)) {118const udm = fromUserDefinedLLMModel(model);119if (!udm) {120return fallback();121} else {122// TODO: support a customizable icon for user defined LLMs123for (const vendor of SERVICES) {124if (udm.startsWith(`${vendor}-`)) {125return renderModel(udm, vendor);126}127}128}129} else if (isLanguageModel(model)) {130return renderModel(model);131}132133return fallback();134}135136137