diff --git a/src/apps/models-modal/ModelsSourceSelector.tsx b/src/apps/models-modal/ModelsSourceSelector.tsx
index f7f436adb..3f6160cc0 100644
--- a/src/apps/models-modal/ModelsSourceSelector.tsx
+++ b/src/apps/models-modal/ModelsSourceSelector.tsx
@@ -1,7 +1,7 @@
import * as React from 'react';
import { shallow } from 'zustand/shallow';
-import { Box, Button, IconButton, ListItemDecorator, MenuItem, Option, Select, Typography } from '@mui/joy';
+import { Badge, Box, Button, IconButton, ListItemDecorator, MenuItem, Option, Select, Typography } from '@mui/joy';
import AddIcon from '@mui/icons-material/Add';
import CloudDoneOutlinedIcon from '@mui/icons-material/CloudDoneOutlined';
import CloudOutlinedIcon from '@mui/icons-material/CloudOutlined';
@@ -10,8 +10,8 @@ import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
import { DModelSourceId, useModelsStore } from '~/modules/llms/store-llms';
import { IModelVendor, ModelVendorId } from '~/modules/llms/vendors/IModelVendor';
+import { ModelVendorOpenAI } from '~/modules/llms/vendors/openai/openai.vendor';
import { createModelSourceForVendor, findAllVendors, findVendorById } from '~/modules/llms/vendors/vendor.registry';
-import { hasServerKeyOpenAI } from '~/modules/llms/vendors/openai/openai.vendor';
import { CloseableMenu } from '~/common/components/CloseableMenu';
import { ConfirmationModal } from '~/common/components/ConfirmationModal';
@@ -19,14 +19,16 @@ import { hideOnDesktop, hideOnMobile } from '~/common/theme';
function locationIcon(vendor?: IModelVendor | null) {
- if (vendor && vendor.id === 'openai' && hasServerKeyOpenAI)
+ if (vendor && vendor.id === 'openai' && ModelVendorOpenAI.hasServerKey)
return ;
return !vendor ? null : vendor.location === 'local' ? : ;
}
-function vendorIcon(vendor?: IModelVendor | null) {
+function vendorIcon(vendor: IModelVendor | null, greenMark: boolean) {
const Icon = !vendor ? null : vendor.Icon;
- return Icon ? : null;
+ return (greenMark && Icon)
+ ?
+ : Icon ? : null;
}
@@ -73,23 +75,26 @@ export function ModelsSourceSelector(props: {
// vendor list items
- const vendorItems = React.useMemo(() => findAllVendors().filter(v => !!v.instanceLimit).map(vendor => {
- const sourceCount = modelSources.filter(source => source.vId === vendor.id).length;
- const enabled = vendor.instanceLimit > sourceCount;
- return {
- vendor,
- enabled,
- sourceCount,
- component: (
-
- ),
- };
- }), [handleAddSourceFromVendor, modelSources]);
+ const vendorItems = React.useMemo(() => findAllVendors()
+ .filter(v => !!v.instanceLimit)
+ .map(vendor => {
+ const sourceCount = modelSources.filter(source => source.vId === vendor.id).length;
+ const enabled = vendor.instanceLimit > sourceCount;
+ return {
+ vendor,
+ enabled,
+ sourceCount,
+ component: (
+
+ ),
+ };
+ },
+ ), [handleAddSourceFromVendor, modelSources]);
// source items
diff --git a/src/modules/llms/vendors/IModelVendor.ts b/src/modules/llms/vendors/IModelVendor.ts
index 966f194d9..80720c32b 100644
--- a/src/modules/llms/vendors/IModelVendor.ts
+++ b/src/modules/llms/vendors/IModelVendor.ts
@@ -13,6 +13,7 @@ export interface IModelVendor !!apiKey && apiKey.startsWith('sk-') && apiKey.length > 40;
export interface SourceSetupAnthropic {
@@ -27,6 +26,7 @@ export const ModelVendorAnthropic: IModelVendor !!apiKey && apiKey.length >= 32;
export interface SourceSetupAzure {
@@ -40,7 +39,8 @@ export const ModelVendorAzure: IModelVendor = {
id: 'oobabooga',
name: 'Oobabooga',
- rank: 15,
+ rank: 25,
location: 'local',
instanceLimit: 1,
diff --git a/src/modules/llms/vendors/openai/OpenAISourceSetup.tsx b/src/modules/llms/vendors/openai/OpenAISourceSetup.tsx
index 213717d2b..fd5da098c 100644
--- a/src/modules/llms/vendors/openai/OpenAISourceSetup.tsx
+++ b/src/modules/llms/vendors/openai/OpenAISourceSetup.tsx
@@ -14,7 +14,7 @@ import { settingsCol1Width, settingsGap } from '~/common/theme';
import type { ModelDescriptionSchema } from '../../transports/server/server.common';
import { DLLM, DModelSource, DModelSourceId, useModelsStore, useSourceSetup } from '../../store-llms';
-import { hasServerKeyOpenAI, isValidOpenAIApiKey, LLMOptionsOpenAI, ModelVendorOpenAI, SourceSetupOpenAI } from './openai.vendor';
+import { isValidOpenAIApiKey, LLMOptionsOpenAI, ModelVendorOpenAI, SourceSetupOpenAI } from './openai.vendor';
import { openAIModelToModelDescription } from './openai.data';
@@ -30,7 +30,7 @@ export function OpenAISourceSetup(props: { sourceId: DModelSourceId }) {
// derived state
const { oaiKey, oaiOrg, oaiHost, heliKey, moderationCheck } = access;
- const needsUserKey = !hasServerKeyOpenAI;
+ const needsUserKey = !ModelVendorOpenAI.hasServerKey;
const keyValid = isValidOpenAIApiKey(oaiKey);
const keyError = (/*needsUserKey ||*/ !!oaiKey) && !keyValid;
const shallFetchSucceed = oaiKey ? keyValid : !needsUserKey;
diff --git a/src/modules/llms/vendors/openai/openai.vendor.ts b/src/modules/llms/vendors/openai/openai.vendor.ts
index 3c2b9463b..43967e964 100644
--- a/src/modules/llms/vendors/openai/openai.vendor.ts
+++ b/src/modules/llms/vendors/openai/openai.vendor.ts
@@ -11,7 +11,6 @@ import { OpenAISourceSetup } from './OpenAISourceSetup';
// special symbols
-export const hasServerKeyOpenAI = !!process.env.HAS_SERVER_KEY_OPENAI;
export const isValidOpenAIApiKey = (apiKey?: string) => !!apiKey && apiKey.startsWith('sk-') && apiKey.length > 40;
export interface SourceSetupOpenAI {
@@ -34,6 +33,7 @@ export const ModelVendorOpenAI: IModelVendor !!apiKey && apiKey.startsWith('sk-or-') && apiKey.length > 40;
// use OpenAI-compatible host and key
@@ -34,9 +33,10 @@ export interface SourceSetupOpenRouter {
export const ModelVendorOpenRouter: IModelVendor = {
id: 'openrouter',
name: 'OpenRouter',
- rank: 25,
+ rank: 12,
location: 'cloud',
instanceLimit: 1,
+ hasServerKey: !!process.env.HAS_SERVER_KEY_OPENAI,
// components
Icon: OpenRouterIcon,