🚀 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:
Danny Avila 2025-04-01 03:50:32 -04:00 committed by GitHub
parent cd7cdaa703
commit 90b8769ef3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 905 additions and 777 deletions

View file

@ -37,6 +37,10 @@ export const useEndpoints = ({
const { data: endpoints = [] } = useGetEndpointsQuery({ select: mapEndpoints });
const { instanceProjectId } = startupConfig ?? {};
const interfaceConfig = startupConfig?.interface ?? {};
const includedEndpoints = useMemo(
() => new Set(startupConfig?.modelSpecs?.addedEndpoints ?? []),
[startupConfig?.modelSpecs?.addedEndpoints],
);
const { endpoint } = conversation ?? {};
@ -73,11 +77,14 @@ export const useEndpoints = ({
if (endpoints[i] === EModelEndpoint.agents && !hasAgentAccess) {
continue;
}
if (includedEndpoints.size > 0 && !includedEndpoints.has(endpoints[i])) {
continue;
}
result.push(endpoints[i]);
}
return result;
}, [endpoints, hasAgentAccess]);
}, [endpoints, hasAgentAccess, includedEndpoints]);
const endpointRequiresUserKey = useCallback(
(ep: string) => {

View file

@ -172,13 +172,19 @@ export default function useSelectMention({
});
/* We don't reset the latest message, only when changing settings mid-converstion */
newConversation({ template: currentConvo, preset: currentConvo, keepLatestMessage: true });
newConversation({
template: currentConvo,
preset: currentConvo,
keepLatestMessage: true,
keepAddedConvos: true,
});
return;
}
newConversation({
template: { ...(template as Partial<TConversation>) },
preset: { ...kwargs, spec: null, iconURL: null, modelLabel: null, endpoint: newEndpoint },
keepAddedConvos: isNewModular,
});
},
[conversation, getDefaultConversation, modularChat, newConversation, endpointsConfig],
@ -233,7 +239,7 @@ export default function useSelectMention({
return;
}
newConversation({ preset: newPreset, keepAddedConvos: true });
newConversation({ preset: newPreset, keepAddedConvos: isModular });
},
[
modularChat,

View file

@ -7,36 +7,35 @@ const avatarCache: Record<string, string> = {};
const useAvatar = (user: TUser | undefined) => {
return useMemo(() => {
if (!user?.username) {
const { username, name } = user ?? {};
const seed = name || username;
if (!seed) {
return '';
}
if (user.avatar) {
if (user?.avatar && user?.avatar !== '') {
return user.avatar;
}
const { username } = user;
if (avatarCache[username]) {
return avatarCache[username];
if (avatarCache[seed]) {
return avatarCache[seed];
}
const avatar = createAvatar(initials, {
seed: username,
seed,
fontFamily: ['Verdana'],
fontSize: 36,
});
let avatarDataUri = '';
avatar
.toDataUri()
.then((dataUri) => {
avatarDataUri = dataUri;
avatarCache[username] = dataUri; // Store in cache
})
.catch((error) => {
console.error('Failed to generate avatar:', error);
});
try {
avatarDataUri = avatar.toDataUri();
if (avatarDataUri) {
avatarCache[seed] = avatarDataUri;
}
} catch (error) {
console.error('Failed to generate avatar:', error);
}
return avatarDataUri;
}, [user]);

View file

@ -528,7 +528,8 @@ export default function useEventHandlers({
setCompleted((prev) => new Set(prev.add(initialResponse.messageId)));
const conversationId = userMessage.conversationId ?? submission.conversationId ?? '';
const conversationId =
userMessage.conversationId ?? submission.conversation?.conversationId ?? '';
const parseErrorResponse = (data: TResData | Partial<TMessage>) => {
const metadata = data['responseMessage'] ?? data;

View file

@ -124,7 +124,7 @@ export default function useSSE(
const data = JSON.parse(e.data);
if (data.final != null) {
clearDraft(submission.conversationId);
clearDraft(submission.conversation?.conversationId);
const { plugins } = data;
finalHandler(data, { ...submission, plugins } as EventSubmission);
(startupConfig?.balance?.enabled ?? false) && balanceQuery.refetch();
@ -190,7 +190,10 @@ export default function useSSE(
const latestMessages = getMessages();
const conversationId = latestMessages?.[latestMessages.length - 1]?.conversationId;
return await abortConversation(
conversationId ?? userMessage.conversationId ?? submission.conversationId,
conversationId ??
userMessage.conversationId ??
submission.conversation?.conversationId ??
'',
submission as EventSubmission,
latestMessages,
);