mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-18 01:10:14 +01:00
🔍 refactor: Search & Message Retrieval (#6903)
* refactor: conversation search fetch * refactor: Message and Convo fetch with paramters and search * refactor: update search states and cleanup old store states * refactor: re-enable search API; fix: search conversation * fix: message's convo fetch * fix: redirect when searching * chore: use logger instead of console * fix: search message loading * feat: small optimizations * feat(Message): remove cache for search path * fix: handle delete of all archivedConversation and sharedLinks * chore: cleanup * fix: search messages * style: update ConvoOptions styles * refactor(SearchButtons): streamline conversation fetching and remove unused state * fix: ensure messages are invalidated after fetching conversation data * fix: add iconURL to conversation query selection --------- Co-authored-by: Danny Avila <danny@librechat.ai>
This commit is contained in:
parent
851938e7a6
commit
88f4ad7c47
30 changed files with 489 additions and 576 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import type { AssistantsEndpoint } from './schemas';
|
||||
import * as q from './types/queries';
|
||||
|
||||
// Testing this buildQuery function
|
||||
const buildQuery = (params: Record<string, unknown>): string => {
|
||||
|
|
@ -28,8 +29,19 @@ export const userPlugins = () => '/api/user/plugins';
|
|||
|
||||
export const deleteUser = () => '/api/user/delete';
|
||||
|
||||
export const messages = (conversationId: string, messageId?: string) =>
|
||||
`/api/messages/${conversationId}${messageId != null && messageId ? `/${messageId}` : ''}`;
|
||||
export const messages = (params: q.MessagesListParams) => {
|
||||
const { conversationId, messageId, ...rest } = params;
|
||||
|
||||
if (conversationId && messageId) {
|
||||
return `/api/messages/${conversationId}/${messageId}`;
|
||||
}
|
||||
|
||||
if (conversationId) {
|
||||
return `/api/messages/${conversationId}`;
|
||||
}
|
||||
|
||||
return `/api/messages${buildQuery(rest)}`;
|
||||
};
|
||||
|
||||
const shareRoot = '/api/share';
|
||||
export const shareMessages = (shareId: string) => `${shareRoot}/${shareId}`;
|
||||
|
|
@ -62,22 +74,7 @@ export const abortRequest = (endpoint: string) => `/api/ask/${endpoint}/abort`;
|
|||
|
||||
export const conversationsRoot = '/api/convos';
|
||||
|
||||
export const conversations = (
|
||||
isArchived?: boolean,
|
||||
sortBy?: 'title' | 'createdAt' | 'updatedAt',
|
||||
sortDirection?: 'asc' | 'desc',
|
||||
tags?: string[],
|
||||
search?: string,
|
||||
cursor?: string,
|
||||
) => {
|
||||
const params = {
|
||||
isArchived,
|
||||
sortBy,
|
||||
sortDirection,
|
||||
tags,
|
||||
search,
|
||||
cursor,
|
||||
};
|
||||
export const conversations = (params: q.ConversationListParams) => {
|
||||
return `${conversationsRoot}${buildQuery(params)}`;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -30,16 +30,6 @@ export function deleteUser(): Promise<s.TPreset> {
|
|||
return request.delete(endpoints.deleteUser());
|
||||
}
|
||||
|
||||
export function getMessagesByConvoId(conversationId: string): Promise<s.TMessage[]> {
|
||||
if (
|
||||
conversationId === config.Constants.NEW_CONVO ||
|
||||
conversationId === config.Constants.PENDING_CONVO
|
||||
) {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
return request.get(endpoints.messages(conversationId));
|
||||
}
|
||||
|
||||
export function getSharedMessages(shareId: string): Promise<t.TSharedMessagesResponse> {
|
||||
return request.get(endpoints.shareMessages(shareId));
|
||||
}
|
||||
|
|
@ -70,31 +60,6 @@ export function deleteSharedLink(shareId: string): Promise<m.TDeleteSharedLinkRe
|
|||
return request.delete(endpoints.shareMessages(shareId));
|
||||
}
|
||||
|
||||
export function updateMessage(payload: t.TUpdateMessageRequest): Promise<unknown> {
|
||||
const { conversationId, messageId, text } = payload;
|
||||
if (!conversationId) {
|
||||
throw new Error('conversationId is required');
|
||||
}
|
||||
|
||||
return request.put(endpoints.messages(conversationId, messageId), { text });
|
||||
}
|
||||
|
||||
export const editArtifact = async ({
|
||||
messageId,
|
||||
...params
|
||||
}: m.TEditArtifactRequest): Promise<m.TEditArtifactResponse> => {
|
||||
return request.post(`/api/messages/artifact/${messageId}`, params);
|
||||
};
|
||||
|
||||
export function updateMessageContent(payload: t.TUpdateMessageContent): Promise<unknown> {
|
||||
const { conversationId, messageId, index, text } = payload;
|
||||
if (!conversationId) {
|
||||
throw new Error('conversationId is required');
|
||||
}
|
||||
|
||||
return request.put(endpoints.messages(conversationId, messageId), { text, index });
|
||||
}
|
||||
|
||||
export function updateUserKey(payload: t.TUpdateUserKeyRequest) {
|
||||
const { value } = payload;
|
||||
if (!value) {
|
||||
|
|
@ -602,24 +567,11 @@ export function clearAllConversations(): Promise<unknown> {
|
|||
export const listConversations = (
|
||||
params?: q.ConversationListParams,
|
||||
): Promise<q.ConversationListResponse> => {
|
||||
const isArchived = params?.isArchived ?? false;
|
||||
const sortBy = params?.sortBy;
|
||||
const sortDirection = params?.sortDirection;
|
||||
const tags = params?.tags || [];
|
||||
const search = params?.search || '';
|
||||
const cursor = params?.cursor;
|
||||
|
||||
if (search !== '' && isArchived === false) {
|
||||
return request.get(endpoints.search(search, cursor));
|
||||
} else {
|
||||
return request.get(
|
||||
endpoints.conversations(isArchived, sortBy, sortDirection, tags, search, cursor),
|
||||
);
|
||||
}
|
||||
return request.get(endpoints.conversations(params ?? {}));
|
||||
};
|
||||
|
||||
export function getConversations(cursor: string): Promise<t.TGetConversationsResponse> {
|
||||
return request.get(endpoints.conversations(undefined, undefined, undefined, [], '', cursor));
|
||||
return request.get(endpoints.conversations({ cursor }));
|
||||
}
|
||||
|
||||
export function getConversationById(id: string): Promise<s.TConversation> {
|
||||
|
|
@ -642,6 +594,45 @@ export function genTitle(payload: m.TGenTitleRequest): Promise<m.TGenTitleRespon
|
|||
return request.post(endpoints.genTitle(), payload);
|
||||
}
|
||||
|
||||
export const listMessages = (params?: q.MessagesListParams): Promise<q.MessagesListResponse> => {
|
||||
return request.get(endpoints.messages(params ?? {}));
|
||||
};
|
||||
|
||||
export function updateMessage(payload: t.TUpdateMessageRequest): Promise<unknown> {
|
||||
const { conversationId, messageId, text } = payload;
|
||||
if (!conversationId) {
|
||||
throw new Error('conversationId is required');
|
||||
}
|
||||
|
||||
return request.put(endpoints.messages({ conversationId, messageId }), { text });
|
||||
}
|
||||
|
||||
export function updateMessageContent(payload: t.TUpdateMessageContent): Promise<unknown> {
|
||||
const { conversationId, messageId, index, text } = payload;
|
||||
if (!conversationId) {
|
||||
throw new Error('conversationId is required');
|
||||
}
|
||||
|
||||
return request.put(endpoints.messages({ conversationId, messageId }), { text, index });
|
||||
}
|
||||
|
||||
export const editArtifact = async ({
|
||||
messageId,
|
||||
...params
|
||||
}: m.TEditArtifactRequest): Promise<m.TEditArtifactResponse> => {
|
||||
return request.post(`/api/messages/artifact/${messageId}`, params);
|
||||
};
|
||||
|
||||
export function getMessagesByConvoId(conversationId: string): Promise<s.TMessage[]> {
|
||||
if (
|
||||
conversationId === config.Constants.NEW_CONVO ||
|
||||
conversationId === config.Constants.PENDING_CONVO
|
||||
) {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
return request.get(endpoints.messages({ conversationId }));
|
||||
}
|
||||
|
||||
export function getPrompt(id: string): Promise<{ prompt: t.TPrompt }> {
|
||||
return request.get(endpoints.getPrompt(id));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,21 +27,6 @@ export type MinimalConversation = Pick<
|
|||
|
||||
export type ConversationListResponse = {
|
||||
conversations: MinimalConversation[];
|
||||
mwssages?: s.TMessage[];
|
||||
nextCursor: string | null;
|
||||
};
|
||||
|
||||
export type SearchConversationListParams = {
|
||||
nextCursor?: string | null;
|
||||
pageSize?: number;
|
||||
search: string;
|
||||
};
|
||||
|
||||
export type SearchConversation = Pick<s.TConversation, 'conversationId' | 'title' | 'user'>;
|
||||
|
||||
export type SearchConversationListResponse = {
|
||||
conversations: SearchConversation[];
|
||||
messages: s.TMessage[];
|
||||
nextCursor: string | null;
|
||||
};
|
||||
|
||||
|
|
@ -51,6 +36,23 @@ export type ConversationUpdater = (
|
|||
conversation: s.TConversation,
|
||||
) => ConversationData;
|
||||
|
||||
/* Messages */
|
||||
export type MessagesListParams = {
|
||||
cursor?: string | null;
|
||||
sortBy?: 'endpoint' | 'createdAt' | 'updatedAt';
|
||||
sortDirection?: 'asc' | 'desc';
|
||||
pageSize?: number;
|
||||
conversationId?: string;
|
||||
messageId?: string;
|
||||
search?: string;
|
||||
};
|
||||
|
||||
export type MessagesListResponse = {
|
||||
messages: s.TMessage[];
|
||||
nextCursor: string | null;
|
||||
};
|
||||
|
||||
/* Shared Links */
|
||||
export type SharedMessagesResponse = Omit<s.TSharedLink, 'messages'> & {
|
||||
messages: s.TMessage[];
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue