feat: add data-provider

This commit is contained in:
Daniel D Orlando 2023-04-02 12:48:26 -07:00
parent 21920dd864
commit 2589754171
7 changed files with 578 additions and 0 deletions

View file

@ -0,0 +1,81 @@
import * as t from './types';
import request from './request';
import * as endpoints from './endpoints';
export function getOpenAIModels(): Promise<t.TOpenAIModels> {
return request.get(endpoints.openAiModels());
}
export function postAICompletion(payload: t.TAICompletionRequest) {
return request.post(endpoints.getAICompletion(), payload);
}
export function getConversations(pageNumber: string): Promise<t.TGetConversationsResponse> {
return request.get(endpoints.getConversations(pageNumber));
}
export function deleteConversation(payload: t.TDeleteConversationRequest) {
//todo: this should be a DELETE request
return request.post(endpoints.deleteConversation(), payload);
}
export function clearAllConversations() {
return request.post(endpoints.deleteConversation());
}
export function getMessagesByConvoId(id: string): Promise<t.TMessage[]> {
return request.get(endpoints.getMessages(id));
}
export function getConversationById(id: string): Promise<t.TConversation> {
return request.get(endpoints.getConversationById(id));
}
export function updateConversation(
payload: t.TUpdateConversationRequest
): Promise<t.TUpdateConversationResponse> {
return request.post(endpoints.updateConversation(), payload);
}
export function updateCustomGpt(payload: t.TUpdateCustomGptRequest) {
return request.post(endpoints.customGpts(), payload);
}
export function getCustomGpts(): Promise<t.TGetCustomGptsResponse> {
return request.get(endpoints.customGpts());
}
export function deleteCustomGpt(payload: t.TDeleteCustomGptRequest): Promise<t.TDeleteCustomGptResponse> {
return request.post(endpoints.deleteCustomGpt(), payload);
}
export function getModels(): Promise<t.TGetModelsResponse> {
return request.get(endpoints.getModels());
}
export function getSearchEnabled(): Promise<boolean> {
return request.get(endpoints.searchEnabled());
}
export function getSearchResults(q: string, pageNumber: string): Promise<t.TSearchResults> {
return request.get(endpoints.search(q, pageNumber));
}
export function getUser(): Promise<t.TUser> {
return request.get(endpoints.user());
}
type TSearchFetcherProps = {
pre: () => void,
q: string,
pageNumber: string,
callback: (data: any) => void
};
export const searchFetcher = async ({ pre, q, pageNumber, callback }: TSearchFetcherProps) => {
pre();
//@ts-ignore
const { data } = await request.get(endpoints.search(q, pageNumber));
console.log('search data', data);
callback(data);
};

View file

@ -0,0 +1,60 @@
export const openAiModels = () => {
return `/api/open-ai-models`;
};
export const getModels = () => {
return `/api/models`;
};
export const getAICompletion = () => {
return `/api/ask `;
};
export const user = () => {
return `/api/me`;
};
export const getMessages = (id: string) => {
return `/api/messages/${id}`;
};
export const getConversations = (pageNumber: string) => {
return `/api/convos?pageNumber=${pageNumber}`;
};
export const getConversationById = (id: string) => {
return `/api/convos/${id}`;
};
export const updateConversation = () => {
return `/api/convos/update`;
};
export const deleteConversation = () => {
return `/api/convos/clear`;
};
export const prompts = () => {
return `/api/prompts`;
};
export const customGpts = () => {
return `/api/customGpts`;
};
// TODO: turn this into a DELETE instead of POST on the backend
export const deleteCustomGpt = () => {
return `/api/customGpts/delete`;
};
export const generateTitle = () => {
return `/api/convos/gen_title`;
};
export const search = (q: string, pageNumber: string) => {
return `/api/search?q=${q}&pageNumber=${pageNumber}`;
}
export const searchEnabled = () => {
return `/api/search/enable`;
}

View file

@ -0,0 +1,9 @@
import axios from 'axios';
export function setAcceptLanguageHeader(value: string): void {
axios.defaults.headers.common['Accept-Language'] = value;
}
export function setTokenHeader(token: string) {
axios.defaults.headers.common['Authorization'] = 'Bearer ' + token;
}

View file

@ -0,0 +1,7 @@
export * from './data-service';
// export * from './endpoints';
export * from './request';
export * from './types';
export * from './react-query-service';
export * from './headers-helpers';
// export * from './events';

View file

@ -0,0 +1,172 @@
import {
UseQueryOptions,
useQuery,
useMutation,
useQueryClient,
UseMutationResult,
QueryObserverResult,
} from "@tanstack/react-query";
import * as t from "./types";
import * as dataService from "./data-service";
export enum QueryKeys {
messages = "messsages",
allConversations = "allConversations",
conversation = "conversation",
models = "models",
customGpts = "customGpts",
searchEnabled = "searchEnabled",
user = "user",
}
export const useGetUserQuery = (): QueryObserverResult<t.TUser> => {
return useQuery<t.TUser>([QueryKeys.user], () => dataService.getUser(), {
refetchOnWindowFocus: false,
refetchOnReconnect: false,
refetchOnMount: false,
});
};
export const useGetMessagesByConvoId = (
id: string,
config?: UseQueryOptions<t.TMessage[]>
): QueryObserverResult<t.TMessage[]> => {
return useQuery<t.TMessage[]>([QueryKeys.messages, id], () =>
dataService.getMessagesByConvoId(id),
{
refetchOnWindowFocus: false,
refetchOnReconnect: false,
refetchOnMount: false,
...config,
}
);
};
export const useGetConversationByIdQuery = (
id: string,
config?: UseQueryOptions<t.TConversation>
): QueryObserverResult<t.TConversation> => {
return useQuery<t.TConversation>([QueryKeys.conversation, id], () =>
dataService.getConversationById(id),
{
refetchOnWindowFocus: false,
refetchOnReconnect: false,
refetchOnMount: false,
enabled: false,
...config
}
);
}
export const useUpdateConversationMutation = (
id: string
): UseMutationResult<
t.TUpdateConversationResponse,
unknown,
t.TUpdateConversationRequest,
unknown
> => {
const queryClient = useQueryClient();
return useMutation(
(payload: t.TUpdateConversationRequest) =>
dataService.updateConversation(payload),
{
onSuccess: () => {
queryClient.invalidateQueries([QueryKeys.conversation, id]);
},
}
);
};
// export const useDeleteConversationMutation = (
// id: string
// ): UseMutationResult<
export const useUpdateCustomGptMutation = (): UseMutationResult<
t.TUpdateCustomGptResponse,
unknown,
t.TUpdateCustomGptRequest,
unknown
> => {
const queryClient = useQueryClient();
return useMutation(
(payload: t.TUpdateCustomGptRequest) =>
dataService.updateCustomGpt(payload),
{
onSuccess: () => {
queryClient.invalidateQueries([QueryKeys.customGpts]);
},
}
);
};
export const useGetCustomGptsQuery = (): QueryObserverResult<
t.TCustomGpt[],
unknown
> => {
return useQuery([QueryKeys.customGpts], () => dataService.getCustomGpts(), {
refetchOnWindowFocus: false,
refetchOnReconnect: false,
refetchOnMount: false,
});
};
export const useDeleteCustomGptMutation = (): UseMutationResult<
t.TDeleteCustomGptResponse,
unknown,
t.TDeleteCustomGptRequest,
unknown
> => {
const queryClient = useQueryClient();
return useMutation(
(payload: t.TDeleteCustomGptRequest) =>
dataService.deleteCustomGpt(payload),
{
onSuccess: () => {
queryClient.invalidateQueries([QueryKeys.customGpts]);
},
}
);
};
export const useGetModelsQuery = (): QueryObserverResult<
t.TGetModelsResponse,
unknown
> => {
return useQuery([QueryKeys.models], () => dataService.getModels(), {
refetchOnWindowFocus: false,
refetchOnReconnect: false,
refetchOnMount: false,
});
};
export const useClearConversationsMutation = (): UseMutationResult<unknown> => {
const queryClient = useQueryClient();
return useMutation(() => dataService.clearAllConversations(), {
onSuccess: () => {
queryClient.invalidateQueries([QueryKeys.allConversations]);
},
});
};
export const useGetConversationsQuery = (pageNumber: string): QueryObserverResult<t.TGetConversationsResponse> => {
return useQuery([QueryKeys.allConversations, pageNumber], () =>
dataService.getConversations(pageNumber), {
refetchOnWindowFocus: false,
refetchOnReconnect: false,
refetchOnMount: false,
}
);
}
export const useGetSearchEnabledQuery = (config?: UseQueryOptions<boolean>): QueryObserverResult<boolean> => {
return useQuery<boolean>([QueryKeys.searchEnabled], () =>
dataService.getSearchEnabled(), {
refetchOnWindowFocus: false,
refetchOnReconnect: false,
refetchOnMount: false,
...config,
}
);
}

View file

@ -0,0 +1,66 @@
import axios, { AxiosRequestConfig } from "axios";
async function _get<T>(url: string, options?: AxiosRequestConfig): Promise<T> {
const response = await axios.get(url, { withCredentials: true, ...options});
return response.data;
}
async function _post(url: string, data?: any) {
const response = await axios.post(url, JSON.stringify(data), {
withCredentials: true,
headers: { "Content-Type": "application/json" },
});
return response.data;
}
async function _postMultiPart(
url: string,
formData: FormData,
options?: AxiosRequestConfig
) {
const response = await axios.post(url, formData, {
withCredentials: true,
...options,
headers: { "Content-Type": "multipart/form-data" },
});
return response.data;
}
async function _put(url: string, data?: any) {
const response = await axios.put(url, JSON.stringify(data), {
withCredentials: true,
headers: { "Content-Type": "application/json" },
});
return response.data;
}
async function _delete<T>(url: string): Promise<T> {
const response = await axios.delete(url, { withCredentials: true });
return response.data;
}
async function _deleteWithOptions<T>(
url: string,
options?: AxiosRequestConfig
): Promise<T> {
const response = await axios.delete(url, { withCredentials: true, ...options});
return response.data;
}
async function _patch(url: string, data?: any) {
const response = await axios.patch(url, JSON.stringify(data), {
withCredentials: true,
headers: { "Content-Type": "application/json" },
});
return response.data;
}
export default {
get: _get,
post: _post,
postMultiPart: _postMultiPart,
put: _put,
delete: _delete,
deleteWithOptions: _deleteWithOptions,
patch: _patch,
};

View file

@ -0,0 +1,183 @@
export type TMessage = {
messageId: string,
conversationId: string,
conversationSignature: string | null,
clientId: string,
invocationId: string,
parentMessageId: string,
sender: string,
text: string,
isCreatedByUser: boolean,
error: boolean,
createdAt: string,
updatedAt: string,
searchResult: string[],
submitting: boolean,
children?: any[] | undefined,
bgColor?: string,
model?: string,
cancelled?: boolean
};
export type TMessageTreeNode = {}
export type TSearchMessage = {}
export type TSearchMessageTreeNode = {}
export type TMessageToAsk = {}
export enum EModelEndpoint {
azureOpenAI = 'azureOpenAI',
openAI = 'openAI',
bingAI = 'bingAI',
chatGPTBrowser = 'chatGPTBrowser'
}
export type TConversation = {
conversationId: string;
title: string;
user: string | null;
endpoint: EModelEndpoint;
model: string; // for azureOpenAI, openAI, chatGPTBrowser only, eg. gpt-3.5-turbo
// for azureOpenAI, openAI only
chatGptLabel?: string;
promptPrefix?: string;
temperature?: number;
top_p?: number;
presence_penalty?: number;
// for bingAI only
jailbreak?: boolean;
jailbreakConversationId?: string;
conversationSignature?: string;
clientId?: string;
invocationId?: string;
toneStyle?: string;
suggestions?: string[];
messages?: TMessage[];
createdAt: string;
updatedAt: string;
}
export type TPrompt = {
title: string,
prompt: string,
category: string,
createdAt: string,
updatedAt: string
};
export type TCustomGpt = {
chatGptLabel: string,
promptPrefix: string,
value: string,
createdAt: string,
updatedAt: string,
_id: string
};
export type TModel = {
_id: string,
name: string,
value: string,
model: string,
chatGptLabel?: string,
promptPrefix?: string
};
export type TUser = {
username: string,
display: string
};
export type TGetConversationsResponse = {
conversations: TConversation[],
pageNumber: string,
pageSize: string | number,
pages: string | number
};
export type TGetConversationResponse = {
data: TConversation
};
export type TGetMessagesResponse = {
data: TMessage[]
};
export type TDeleteConversationRequest = {
conversationId: string
};
export type TAICompletionRequest = {
chatGptLabel?: string,
conversationId: string,
current: boolean,
isCreatedByUser: boolean,
model: string,
messageId: string,
parentMessageId: string,
overrideParentMessageId?: boolean,
promptPrefix?: string,
sender: string,
text: string
};
export type TGetModelsResponse = {
hasOpenAI: boolean,
hasChatGpt: boolean,
hasBing: boolean
};
export type TOpenAIModel = {
object: string,
id: string,
ready: boolean,
owner: string,
created: string | null,
permissions: string[] | null
};
export type TOpenAIModels = {
models: {
object: string,
data: TOpenAIModel[]
}
};
export type TConversationUpdate = {
conversationId: string,
title?: string
};
export type TUpdateConversationRequest = {
arg: {},
withCredentials?: boolean
};
export type TUpdateConversationResponse = {
data: TConversation
};
export type TUpdateCustomGptRequest = {
value: string,
chatGptLabel: string,
promptPrefix?: string,
prevLabel?: string
};
export type TUpdateCustomGptResponse = {};
export type TDeleteCustomGptRequest = {
id: string
};
export type TDeleteCustomGptResponse = {};
export type TClearConversationsRequest = {};
export type TClearConversationsResponse = {};
export type TGetCustomGptsResponse = {};
export type TSearchResults = {};