mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-01-10 20:48:54 +01:00
* feat: add timer duration to showToast, show toast for preset selection * refactor: replace old /chat/ route with /c/. e2e tests will fail here * refactor: move typedefs to root of /api/ and add a few to assistant types in TS * refactor: reorganize data-provider imports, fix dependency cycle, strategize new plan to separate react dependent packages * feat: add dataService for uploading images * feat(data-provider): add mutation keys * feat: file resizing and upload * WIP: initial API image handling * fix: catch JSON.parse of localStorage tools * chore: experimental: use module-alias for absolute imports * refactor: change temp_file_id strategy * fix: updating files state by using Map and defining react query callbacks in a way that keeps them during component unmount, initial delete handling * feat: properly handle file deletion * refactor: unexpose complete filepath and resize from server for higher fidelity * fix: make sure resized height, width is saved, catch bad requests * refactor: use absolute imports * fix: prevent setOptions from being called more than once for OpenAIClient, made note to fix for PluginsClient * refactor: import supportsFiles and models vars from schemas * fix: correctly replace temp file id * refactor(BaseClient): use absolute imports, pass message 'opts' to buildMessages method, count tokens for nested objects/arrays * feat: add validateVisionModel to determine if model has vision capabilities * chore(checkBalance): update jsdoc * feat: formatVisionMessage: change message content format dependent on role and image_urls passed * refactor: add usage to File schema, make create and updateFile, correctly set and remove TTL * feat: working vision support TODO: file size, type, amount validations, making sure they are styled right, and making sure you can add images from the clipboard/dragging * feat: clipboard support for uploading images * feat: handle files on drop to screen, refactor top level view code to Presentation component so the useDragHelpers hook has ChatContext * fix(Images): replace uploaded images in place * feat: add filepath validation to protect sensitive files * fix: ensure correct file_ids are push and not the Map key values * fix(ToastContext): type issue * feat: add basic file validation * fix(useDragHelpers): correct context issue with `files` dependency * refactor: consolidate setErrors logic to setError * feat: add dialog Image overlay on image click * fix: close endpoints menu on click * chore: set detail to auto, make note for configuration * fix: react warning (button desc. of button) * refactor: optimize filepath handling, pass file_ids to images for easier re-use * refactor: optimize image file handling, allow re-using files in regen, pass more file metadata in messages * feat: lazy loading images including use of upload preview * fix: SetKeyDialog closing, stopPropagation on Dialog content click * style(EndpointMenuItem): tighten up the style, fix dark theme showing in lightmode, make menu more ux friendly * style: change maxheight of all settings textareas to 138px from 300px * style: better styling for textarea and enclosing buttons * refactor(PresetItems): swap back edit and delete icons * feat: make textarea placeholder dynamic to endpoint * style: show user hover buttons only on hover when message is streaming * fix: ordered list not going past 9, fix css * feat: add User/AI labels; style: hide loading spinner * feat: add back custom footer, change original footer text * feat: dynamic landing icons based on endpoint * chore: comment out assistants route * fix: autoScroll to newest on /c/ view * fix: Export Conversation on new UI * style: match message style of official more closely * ci: fix api jest unit tests, comment out e2e tests for now as they will fail until addressed * feat: more file validation and use blob in preview field, not filepath, to fix temp deletion * feat: filefilter for multer * feat: better AI labels based on custom name, model, and endpoint instead of `ChatGPT`
196 lines
5.7 KiB
TypeScript
196 lines
5.7 KiB
TypeScript
import * as f from './types/files';
|
|
import * as a from './types/assistants';
|
|
import * as t from './types';
|
|
import * as s from './schemas';
|
|
import request from './request';
|
|
import * as endpoints from './api-endpoints';
|
|
|
|
export function getConversations(pageNumber: string): Promise<t.TGetConversationsResponse> {
|
|
return request.get(endpoints.conversations(pageNumber));
|
|
}
|
|
|
|
export function abortRequestWithMessage(
|
|
endpoint: string,
|
|
abortKey: string,
|
|
message: string,
|
|
): Promise<void> {
|
|
return request.post(endpoints.abortRequest(endpoint), { arg: { abortKey, message } });
|
|
}
|
|
|
|
export function deleteConversation(payload: t.TDeleteConversationRequest) {
|
|
//todo: this should be a DELETE request
|
|
return request.post(endpoints.deleteConversation(), { arg: payload });
|
|
}
|
|
|
|
export function clearAllConversations(): Promise<unknown> {
|
|
return request.post(endpoints.deleteConversation(), { arg: {} });
|
|
}
|
|
|
|
export function revokeUserKey(name: string): Promise<unknown> {
|
|
return request.delete(endpoints.revokeUserKey(name));
|
|
}
|
|
|
|
export function revokeAllUserKeys(): Promise<unknown> {
|
|
return request.delete(endpoints.revokeAllUserKeys());
|
|
}
|
|
|
|
export function getMessagesByConvoId(conversationId: string): Promise<s.TMessage[]> {
|
|
if (conversationId === 'new') {
|
|
return Promise.resolve([]);
|
|
}
|
|
return request.get(endpoints.messages(conversationId));
|
|
}
|
|
|
|
export function getConversationById(id: string): Promise<s.TConversation> {
|
|
return request.get(endpoints.conversationById(id));
|
|
}
|
|
|
|
export function updateConversation(
|
|
payload: t.TUpdateConversationRequest,
|
|
): Promise<t.TUpdateConversationResponse> {
|
|
return request.post(endpoints.updateConversation(), { arg: payload });
|
|
}
|
|
|
|
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 updateUserKey(payload: t.TUpdateUserKeyRequest) {
|
|
const { value } = payload;
|
|
if (!value) {
|
|
throw new Error('value is required');
|
|
}
|
|
|
|
return request.put(endpoints.keys(), payload);
|
|
}
|
|
|
|
export function getPresets(): Promise<s.TPreset[]> {
|
|
return request.get(endpoints.presets());
|
|
}
|
|
|
|
export function createPreset(payload: s.TPreset): Promise<s.TPreset[]> {
|
|
return request.post(endpoints.presets(), payload);
|
|
}
|
|
|
|
export function updatePreset(payload: s.TPreset): Promise<s.TPreset[]> {
|
|
return request.post(endpoints.presets(), payload);
|
|
}
|
|
|
|
export function deletePreset(arg: s.TPreset | object): Promise<s.TPreset[]> {
|
|
return request.post(endpoints.deletePreset(), arg);
|
|
}
|
|
|
|
export function getSearchEnabled(): Promise<boolean> {
|
|
return request.get(endpoints.searchEnabled());
|
|
}
|
|
|
|
export function getUser(): Promise<t.TUser> {
|
|
return request.get(endpoints.user());
|
|
}
|
|
|
|
export function getUserBalance(): Promise<string> {
|
|
return request.get(endpoints.balance());
|
|
}
|
|
|
|
export const searchConversations = async (
|
|
q: string,
|
|
pageNumber: string,
|
|
): Promise<t.TSearchResults> => {
|
|
return request.get(endpoints.search(q, pageNumber));
|
|
};
|
|
|
|
export const getAIEndpoints = (): Promise<t.TEndpointsConfig> => {
|
|
return request.get(endpoints.aiEndpoints());
|
|
};
|
|
|
|
export const getModels = async (): Promise<t.TModelsConfig> => {
|
|
return request.get(endpoints.models());
|
|
};
|
|
|
|
export const updateTokenCount = (text: string) => {
|
|
return request.post(endpoints.tokenizer(), { arg: text });
|
|
};
|
|
|
|
export const login = (payload: t.TLoginUser) => {
|
|
return request.post(endpoints.login(), payload);
|
|
};
|
|
|
|
export const logout = () => {
|
|
return request.post(endpoints.logout());
|
|
};
|
|
|
|
export const register = (payload: t.TRegisterUser) => {
|
|
return request.post(endpoints.register(), payload);
|
|
};
|
|
|
|
export const userKeyQuery = (name: string): Promise<t.TCheckUserKeyResponse> =>
|
|
request.get(endpoints.userKeyQuery(name));
|
|
|
|
export const getLoginGoogle = () => {
|
|
return request.get(endpoints.loginGoogle());
|
|
};
|
|
|
|
export const requestPasswordReset = (
|
|
payload: t.TRequestPasswordReset,
|
|
): Promise<t.TRequestPasswordResetResponse> => {
|
|
return request.post(endpoints.requestPasswordReset(), payload);
|
|
};
|
|
|
|
export const resetPassword = (payload: t.TResetPassword) => {
|
|
return request.post(endpoints.resetPassword(), payload);
|
|
};
|
|
|
|
export const getAvailablePlugins = (): Promise<s.TPlugin[]> => {
|
|
return request.get(endpoints.plugins());
|
|
};
|
|
|
|
export const updateUserPlugins = (payload: t.TUpdateUserPlugins) => {
|
|
return request.post(endpoints.userPlugins(), payload);
|
|
};
|
|
|
|
export const getStartupConfig = (): Promise<t.TStartupConfig> => {
|
|
return request.get(endpoints.config());
|
|
};
|
|
|
|
/* Assistants */
|
|
|
|
export const createAssistant = (data: a.AssistantCreateParams): Promise<a.Assistant> => {
|
|
return request.post(endpoints.assistants(), data);
|
|
};
|
|
|
|
export const getAssistantById = (assistant_id: string): Promise<a.Assistant> => {
|
|
return request.get(endpoints.assistants(assistant_id));
|
|
};
|
|
|
|
export const updateAssistant = (
|
|
assistant_id: string,
|
|
data: a.AssistantUpdateParams,
|
|
): Promise<a.Assistant> => {
|
|
return request.patch(endpoints.assistants(assistant_id), data);
|
|
};
|
|
|
|
export const deleteAssistant = (assistant_id: string): Promise<void> => {
|
|
return request.delete(endpoints.assistants(assistant_id));
|
|
};
|
|
|
|
export const listAssistants = (
|
|
params?: a.AssistantListParams,
|
|
): Promise<a.AssistantListResponse> => {
|
|
return request.get(endpoints.assistants(), { params });
|
|
};
|
|
|
|
/* Files */
|
|
|
|
export const uploadImage = (data: FormData): Promise<f.FileUploadResponse> => {
|
|
return request.postMultiPart(endpoints.images(), data);
|
|
};
|
|
|
|
export const deleteFiles = async (files: f.BatchFile[]): Promise<f.DeleteFilesResponse> =>
|
|
request.deleteWithOptions(endpoints.files(), {
|
|
data: { files },
|
|
});
|