mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-18 09:20:15 +01:00
🚀 feat: Use Model Specs + Specific Endpoints, Limit Providers for Agents (#6650)
* 🔧 refactor: Remove modelSpecs prop from ModelSelector and related components
* fix: Update submission.conversationId references in SSE hooks and data types as was incorrectly typed
* feat: Allow showing specific endpoints alongside model specs via `addedEndpoints` field
* feat: allowed agents providers via `agents.allowedProviders` field
* fix: bump dicebear/sharp dependencies to resolve CVE-2024-12905 and improve avatar gen logic
* fix: rename variable for clarity in loadDefaultInterface function
* fix: add keepAddedConvos option to newConversation calls for modular chat support
* fix: include model information in endpoint selection for improved context
* fix: update data-provider version to 0.7.78 and increment config version to 1.2.4
This commit is contained in:
parent
cd7cdaa703
commit
90b8769ef3
27 changed files with 905 additions and 777 deletions
|
|
@ -16,7 +16,6 @@ const defaultInterface = getConfigDefaults().interface;
|
|||
export default function Header() {
|
||||
const { data: startupConfig } = useGetStartupConfig();
|
||||
const { navVisible } = useOutletContext<ContextType>();
|
||||
const modelSpecs = useMemo(() => startupConfig?.modelSpecs?.list ?? [], [startupConfig]);
|
||||
const interfaceConfig = useMemo(
|
||||
() => startupConfig?.interface ?? defaultInterface,
|
||||
[startupConfig],
|
||||
|
|
@ -39,7 +38,7 @@ export default function Header() {
|
|||
<div className="hide-scrollbar flex w-full items-center justify-between gap-2 overflow-x-auto">
|
||||
<div className="mx-2 flex items-center gap-2">
|
||||
{!navVisible && <HeaderNewChat />}
|
||||
{<ModelSelector startupConfig={startupConfig} modelSpecs={modelSpecs} />}
|
||||
{<ModelSelector startupConfig={startupConfig} />}
|
||||
{interfaceConfig.presets === true && interfaceConfig.modelSelect && <PresetsMenu />}
|
||||
{hasAccessToBookmarks === true && <BookmarkMenu />}
|
||||
{hasAccessToMultiConvo === true && <AddMultiConvo />}
|
||||
|
|
|
|||
|
|
@ -98,9 +98,9 @@ function ModelSelectorContent() {
|
|||
);
|
||||
}
|
||||
|
||||
export default function ModelSelector({ startupConfig, modelSpecs }: ModelSelectorProps) {
|
||||
export default function ModelSelector({ startupConfig }: ModelSelectorProps) {
|
||||
return (
|
||||
<ModelSelectorProvider modelSpecs={modelSpecs} startupConfig={startupConfig}>
|
||||
<ModelSelectorProvider startupConfig={startupConfig}>
|
||||
<ModelSelectorContent />
|
||||
</ModelSelectorProvider>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -44,24 +44,20 @@ export function useModelSelectorContext() {
|
|||
|
||||
interface ModelSelectorProviderProps {
|
||||
children: React.ReactNode;
|
||||
modelSpecs: t.TModelSpec[];
|
||||
startupConfig: t.TStartupConfig | undefined;
|
||||
}
|
||||
|
||||
export function ModelSelectorProvider({
|
||||
children,
|
||||
modelSpecs,
|
||||
startupConfig,
|
||||
}: ModelSelectorProviderProps) {
|
||||
export function ModelSelectorProvider({ children, startupConfig }: ModelSelectorProviderProps) {
|
||||
const agentsMap = useAgentsMapContext();
|
||||
const assistantsMap = useAssistantsMapContext();
|
||||
const { data: endpointsConfig } = useGetEndpointsQuery();
|
||||
const { conversation, newConversation } = useChatContext();
|
||||
const modelSpecs = useMemo(() => startupConfig?.modelSpecs?.list ?? [], [startupConfig]);
|
||||
const { mappedEndpoints, endpointRequiresUserKey } = useEndpoints({
|
||||
agentsMap,
|
||||
assistantsMap,
|
||||
endpointsConfig,
|
||||
startupConfig,
|
||||
endpointsConfig,
|
||||
});
|
||||
const { onSelectEndpoint, onSelectSpec } = useSelectMention({
|
||||
// presets,
|
||||
|
|
@ -146,6 +142,7 @@ export function ModelSelectorProvider({
|
|||
if (isAgentsEndpoint(endpoint.value)) {
|
||||
onSelectEndpoint?.(endpoint.value, {
|
||||
agent_id: model,
|
||||
model: agentsMap?.[model]?.model ?? '',
|
||||
});
|
||||
} else if (isAssistantsEndpoint(endpoint.value)) {
|
||||
onSelectEndpoint?.(endpoint.value, {
|
||||
|
|
@ -157,7 +154,7 @@ export function ModelSelectorProvider({
|
|||
}
|
||||
setSelectedValues({
|
||||
endpoint: endpoint.value,
|
||||
model: model,
|
||||
model,
|
||||
modelSpec: '',
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// file deepcode ignore HardcodedNonCryptoSecret: No hardcoded secrets
|
||||
import { ViolationTypes, ErrorTypes } from 'librechat-data-provider';
|
||||
import { ViolationTypes, ErrorTypes, alternateName } from 'librechat-data-provider';
|
||||
import type { TOpenAIMessage } from 'librechat-data-provider';
|
||||
import type { LocalizeFunction } from '~/common';
|
||||
import { formatJSON, extractJson, isJson } from '~/utils/json';
|
||||
|
|
@ -53,6 +53,11 @@ const errorMessages = {
|
|||
const { info } = json;
|
||||
return localize('com_error_input_length', { 0: info });
|
||||
},
|
||||
[ErrorTypes.INVALID_AGENT_PROVIDER]: (json: TGenericError, localize: LocalizeFunction) => {
|
||||
const { info } = json;
|
||||
const provider = (alternateName[info] as string | undefined) ?? info;
|
||||
return localize('com_error_invalid_agent_provider', { 0: provider });
|
||||
},
|
||||
[ErrorTypes.GOOGLE_ERROR]: (json: TGenericError) => {
|
||||
const { info } = json;
|
||||
return info;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useState, memo } from 'react';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import * as Select from '@ariakit/react/select';
|
||||
import { Fragment, useState, memo } from 'react';
|
||||
import { FileText, LogOut } from 'lucide-react';
|
||||
import { LinkIcon, GearIcon, DropdownMenuSeparator } from '~/components';
|
||||
import { useGetStartupConfig, useGetUserBalance } from '~/data-provider';
|
||||
|
|
@ -23,7 +23,7 @@ function AccountSettings() {
|
|||
const [showFiles, setShowFiles] = useRecoilState(store.showFiles);
|
||||
|
||||
const avatarSrc = useAvatar(user);
|
||||
const name = user?.avatar ?? user?.username ?? '';
|
||||
const avatarSeed = user?.avatar || user?.name || user?.username || '';
|
||||
|
||||
return (
|
||||
<Select.SelectProvider>
|
||||
|
|
@ -34,7 +34,7 @@ function AccountSettings() {
|
|||
>
|
||||
<div className="-ml-0.9 -mt-0.8 h-8 w-8 flex-shrink-0">
|
||||
<div className="relative flex">
|
||||
{name.length === 0 ? (
|
||||
{avatarSeed.length === 0 ? (
|
||||
<div
|
||||
style={{
|
||||
backgroundColor: 'rgb(121, 137, 255)',
|
||||
|
|
@ -51,7 +51,7 @@ function AccountSettings() {
|
|||
<img
|
||||
className="rounded-full"
|
||||
src={(user?.avatar ?? '') || avatarSrc}
|
||||
alt={`${name}'s avatar`}
|
||||
alt={`${user?.name || user?.username || user?.email || ''}'s avatar`}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -56,18 +56,24 @@ export default function AgentPanel({
|
|||
const { control, handleSubmit, reset } = methods;
|
||||
const agent_id = useWatch({ control, name: 'id' });
|
||||
|
||||
const allowedProviders = useMemo(
|
||||
() => new Set(agentsConfig?.allowedProviders),
|
||||
[agentsConfig?.allowedProviders],
|
||||
);
|
||||
|
||||
const providers = useMemo(
|
||||
() =>
|
||||
Object.keys(endpointsConfig ?? {})
|
||||
.filter(
|
||||
(key) =>
|
||||
!isAssistantsEndpoint(key) &&
|
||||
(allowedProviders.size > 0 ? allowedProviders.has(key) : true) &&
|
||||
key !== EModelEndpoint.agents &&
|
||||
key !== EModelEndpoint.chatGPTBrowser &&
|
||||
key !== EModelEndpoint.gptPlugins,
|
||||
)
|
||||
.map((provider) => createProviderOption(provider)),
|
||||
[endpointsConfig],
|
||||
[endpointsConfig, allowedProviders],
|
||||
);
|
||||
|
||||
/* Mutations */
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { getEndpointField, cn } from '~/utils';
|
|||
import { useLocalize } from '~/hooks';
|
||||
import { Panel } from '~/common';
|
||||
|
||||
export default function Parameters({
|
||||
export default function ModelPanel({
|
||||
setActivePanel,
|
||||
providers,
|
||||
models: modelsData,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue