pull/776/head
Alex 7 months ago
parent a3de360878
commit 0974085c6f

@ -36,21 +36,18 @@ else:
# load the prompts # load the prompts
current_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) current_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
with open(os.path.join(current_dir, "prompts", "combine_prompt.txt"), "r") as f: with open(os.path.join(current_dir, "prompts", "chat_combine_default.txt"), "r") as f:
template = f.read()
with open(os.path.join(current_dir, "prompts", "combine_prompt_hist.txt"), "r") as f:
template_hist = f.read()
with open(os.path.join(current_dir, "prompts", "question_prompt.txt"), "r") as f:
template_quest = f.read()
with open(os.path.join(current_dir, "prompts", "chat_combine_prompt.txt"), "r") as f:
chat_combine_template = f.read() chat_combine_template = f.read()
with open(os.path.join(current_dir, "prompts", "chat_reduce_prompt.txt"), "r") as f: with open(os.path.join(current_dir, "prompts", "chat_reduce_prompt.txt"), "r") as f:
chat_reduce_template = f.read() chat_reduce_template = f.read()
with open(os.path.join(current_dir, "prompts", "chat_combine_creative.txt"), "r") as f:
chat_reduce_creative = f.read()
with open(os.path.join(current_dir, "prompts", "chat_combine_strict.txt"), "r") as f:
chat_reduce_strict = f.read()
api_key_set = settings.API_KEY is not None api_key_set = settings.API_KEY is not None
embeddings_key_set = settings.EMBEDDINGS_KEY is not None embeddings_key_set = settings.EMBEDDINGS_KEY is not None
@ -115,8 +112,17 @@ def is_azure_configured():
return settings.OPENAI_API_BASE and settings.OPENAI_API_VERSION and settings.AZURE_DEPLOYMENT_NAME return settings.OPENAI_API_BASE and settings.OPENAI_API_VERSION and settings.AZURE_DEPLOYMENT_NAME
def complete_stream(question, docsearch, chat_history, api_key, conversation_id): def complete_stream(question, docsearch, chat_history, api_key, prompt_id, conversation_id):
llm = LLMCreator.create_llm(settings.LLM_NAME, api_key=api_key) llm = LLMCreator.create_llm(settings.LLM_NAME, api_key=api_key)
if prompt_id == 'default':
prompt = chat_reduce_template
elif prompt_id == 'creative':
prompt = chat_reduce_creative
elif prompt_id == 'strict':
prompt = chat_reduce_strict
else:
prompt = chat_reduce_template
docs = docsearch.search(question, k=2) docs = docsearch.search(question, k=2)
@ -124,7 +130,7 @@ def complete_stream(question, docsearch, chat_history, api_key, conversation_id)
docs = [docs[0]] docs = [docs[0]]
# join all page_content together with a newline # join all page_content together with a newline
docs_together = "\n".join([doc.page_content for doc in docs]) docs_together = "\n".join([doc.page_content for doc in docs])
p_chat_combine = chat_combine_template.replace("{summaries}", docs_together) p_chat_combine = prompt.replace("{summaries}", docs_together)
messages_combine = [{"role": "system", "content": p_chat_combine}] messages_combine = [{"role": "system", "content": p_chat_combine}]
source_log_docs = [] source_log_docs = []
for doc in docs: for doc in docs:
@ -201,6 +207,10 @@ def stream():
# history to json object from string # history to json object from string
history = json.loads(history) history = json.loads(history)
conversation_id = data["conversation_id"] conversation_id = data["conversation_id"]
if 'prompt_id' in data:
prompt_id = data["prompt_id"]
else:
prompt_id = 'default'
# check if active_docs is set # check if active_docs is set
@ -221,6 +231,7 @@ def stream():
return Response( return Response(
complete_stream(question, docsearch, complete_stream(question, docsearch,
chat_history=history, api_key=api_key, chat_history=history, api_key=api_key,
prompt_id=prompt_id,
conversation_id=conversation_id), mimetype="text/event-stream" conversation_id=conversation_id), mimetype="text/event-stream"
) )

@ -16,6 +16,7 @@ mongo = MongoClient(settings.MONGO_URI)
db = mongo["docsgpt"] db = mongo["docsgpt"]
conversations_collection = db["conversations"] conversations_collection = db["conversations"]
vectors_collection = db["vectors"] vectors_collection = db["vectors"]
prompts_collection = db["prompts"]
user = Blueprint('user', __name__) user = Blueprint('user', __name__)
current_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) current_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
@ -188,7 +189,7 @@ def combined_json():
"date": "default", "date": "default",
"docLink": "default", "docLink": "default",
"model": settings.EMBEDDINGS_NAME, "model": settings.EMBEDDINGS_NAME,
"location": "local", "location": "remote",
} }
] ]
# structure: name, language, version, description, fullName, date, docLink # structure: name, language, version, description, fullName, date, docLink
@ -245,6 +246,59 @@ def check_docs():
return {"status": "loaded"} return {"status": "loaded"}
@user.route("/api/create_prompt", methods=["POST"])
def create_prompt():
data = request.get_json()
prompt = data["prompt"]
name = data["name"]
user = "local"
# write to mongodb
prompts_collection.insert_one(
{
"name": name,
"prompt": prompt,
"user": user,
}
)
return {"status": "ok"}
@user.route("/api/get_prompts", methods=["GET"])
def get_prompts():
user = "local"
prompts = prompts_collection.find({"user": user})
list_prompts = []
list_prompts.append({"id": "default", "name": "default", "type": "public"})
list_prompts.append({"id": "creative", "name": "creative", "type": "public"})
list_prompts.append({"id": "precise", "name": "precise", "type": "public"})
for prompt in prompts:
list_prompts.append({"id": str(prompt["_id"]), "name": prompt["name"], type: "private"})
return jsonify(list_prompts)
@user.route("/api/get_single_prompt", methods=["GET"])
def get_single_prompt():
prompt_id = request.args.get("id")
prompt = prompts_collection.find_one({"_id": ObjectId(prompt_id)})
return jsonify(prompt['prompt'])
@user.route("/api/delete_prompt", methods=["POST"])
def delete_prompt():
prompt_id = request.args.get("id")
prompts_collection.delete_one(
{
"_id": ObjectId(prompt_id),
}
)
return {"status": "ok"}
@user.route("/api/update_prompt_name", methods=["POST"])
def update_prompt_name():
data = request.get_json()
id = data["id"]
name = data["name"]
prompts_collection.update_one({"_id": ObjectId(id)},{"$set":{"name":name}})
return {"status": "ok"}

@ -0,0 +1,9 @@
You are a helpful AI assistant, DocsGPT, specializing in document assistance, designed to offer detailed and informative responses.
If appropriate, your answers can include code examples, formatted as follows:
```(language)
(code)
```
You effectively utilize chat history, ensuring relevant and tailored responses.
If a question doesn't align with your context, you provide friendly and helpful replies.
----------------
{summaries}

@ -0,0 +1,13 @@
You are an AI Assistant, DocsGPT, adept at offering document assistance.
Your expertise lies in providing answer on top of provided context.
You can leverage the chat history if needed.
Answer the question based on the context below.
Keep the answer concise. Respond "Irrelevant context" if not sure about the answer.
If question is not related to the context, respond "Irrelevant context".
When using code examples, use the following format:
```(language)
(code)
```
----------------
Context:
{summaries}

@ -1,25 +0,0 @@
You are a DocsGPT, friendly and helpful AI assistant by Arc53 that provides help with documents. You give thorough answers with code examples if possible.
QUESTION: How to merge tables in pandas?
=========
Content: pandas provides various facilities for easily combining together Series or DataFrame with various kinds of set logic for the indexes and relational algebra functionality in the case of join / merge-type operations.
Source: 28-pl
Content: pandas provides a single function, merge(), as the entry point for all standard database join operations between DataFrame or named Series objects: \n\npandas.merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=('_x', '_y'), copy=True, indicator=False, validate=None)
Source: 30-pl
=========
FINAL ANSWER: To merge two tables in pandas, you can use the pd.merge() function. The basic syntax is: \n\npd.merge(left, right, on, how) \n\nwhere left and right are the two tables to merge, on is the column to merge on, and how is the type of merge to perform. \n\nFor example, to merge the two tables df1 and df2 on the column 'id', you can use: \n\npd.merge(df1, df2, on='id', how='inner')
SOURCES: 28-pl 30-pl
QUESTION: How are you?
=========
CONTENT:
SOURCE:
=========
FINAL ANSWER: I am fine, thank you. How are you?
SOURCES:
QUESTION: {{ question }}
=========
{{ summaries }}
=========
FINAL ANSWER:

@ -1,33 +0,0 @@
You are a DocsGPT, friendly and helpful AI assistant by Arc53 that provides help with documents. You give thorough answers with code examples if possible.
QUESTION: How to merge tables in pandas?
=========
Content: pandas provides various facilities for easily combining together Series or DataFrame with various kinds of set logic for the indexes and relational algebra functionality in the case of join / merge-type operations.
Source: 28-pl
Content: pandas provides a single function, merge(), as the entry point for all standard database join operations between DataFrame or named Series objects: \n\npandas.merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=('_x', '_y'), copy=True, indicator=False, validate=None)
Source: 30-pl
=========
FINAL ANSWER: To merge two tables in pandas, you can use the pd.merge() function. The basic syntax is: \n\npd.merge(left, right, on, how) \n\nwhere left and right are the two tables to merge, on is the column to merge on, and how is the type of merge to perform. \n\nFor example, to merge the two tables df1 and df2 on the column 'id', you can use: \n\npd.merge(df1, df2, on='id', how='inner')
SOURCES: 28-pl 30-pl
QUESTION: How are you?
=========
CONTENT:
SOURCE:
=========
FINAL ANSWER: I am fine, thank you. How are you?
SOURCES:
QUESTION: {{ historyquestion }}
=========
CONTENT:
SOURCE:
=========
FINAL ANSWER: {{ historyanswer }}
SOURCES:
QUESTION: {{ question }}
=========
{{ summaries }}
=========
FINAL ANSWER:

@ -1,4 +0,0 @@
Use the following portion of a long document to see if any of the text is relevant to answer the question.
{{ context }}
Question: {{ question }}
Provide all relevant text to the question verbatim. Summarize if needed. If nothing relevant return "-".

@ -6,7 +6,7 @@ import Documentation from './assets/documentation.svg';
import Discord from './assets/discord.svg'; import Discord from './assets/discord.svg';
import Arrow2 from './assets/dropdown-arrow.svg'; import Arrow2 from './assets/dropdown-arrow.svg';
import Expand from './assets/expand.svg'; import Expand from './assets/expand.svg';
import Exit from './assets/exit.svg'; import Trash from './assets/trash.svg';
import Github from './assets/github.svg'; import Github from './assets/github.svg';
import Hamburger from './assets/hamburger.svg'; import Hamburger from './assets/hamburger.svg';
import Info from './assets/info.svg'; import Info from './assets/info.svg';
@ -298,9 +298,9 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
</p> </p>
{doc.location === 'local' && ( {doc.location === 'local' && (
<img <img
src={Exit} src={Trash}
alt="Exit" alt="Delete"
className="mr-4 h-3 w-3 cursor-pointer hover:opacity-50" className="mr-4 h-4 w-4 cursor-pointer hover:opacity-50"
id={`img-${index}`} id={`img-${index}`}
onClick={(event) => { onClick={(event) => {
event.stopPropagation(); event.stopPropagation();

@ -1,70 +1,112 @@
import React, { useState } from 'react'; import React, { useState, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import Arrow2 from './assets/dropdown-arrow.svg'; import Arrow2 from './assets/dropdown-arrow.svg';
import ArrowLeft from './assets/arrow-left.svg'; import ArrowLeft from './assets/arrow-left.svg';
import ArrowRight from './assets/arrow-right.svg'; import ArrowRight from './assets/arrow-right.svg';
import Trash from './assets/trash.svg';
import {
selectPrompt,
setPrompt,
selectSourceDocs,
} from './preferences/preferenceSlice';
import { Doc } from './preferences/preferenceApi';
type PromptProps = { type PromptProps = {
prompts: string[]; prompts: { name: string; id: string; type: string }[];
selectedPrompt: string; selectedPrompt: { name: string; id: string };
onSelectPrompt: (prompt: string) => void; onSelectPrompt: (name: string, id: string) => void;
onAddPrompt: (name: string) => void; onAddPrompt: (name: string) => void;
newPromptName: string; newPromptName: string;
onNewPromptNameChange: (name: string) => void; onNewPromptNameChange: (name: string) => void;
isAddPromptModalOpen: boolean; isAddPromptModalOpen: boolean;
onToggleAddPromptModal: () => void; onToggleAddPromptModal: () => void;
onDeletePrompt: (name: string) => void; onDeletePrompt: (name: string, id: string) => void;
}; };
const Setting: React.FC = () => { const Setting: React.FC = () => {
const tabs = ['General', 'Prompts', 'Documents', 'Widgets']; const tabs = ['General', 'Prompts', 'Documents'];
//const tabs = ['General', 'Prompts', 'Documents', 'Widgets'];
const [activeTab, setActiveTab] = useState('General'); const [activeTab, setActiveTab] = useState('General');
const [prompts, setPrompts] = useState<string[]>(['Prompt 1', 'Prompt 2']); const [prompts, setPrompts] = useState<
const [selectedPrompt, setSelectedPrompt] = useState(''); { name: string; id: string; type: string }[]
>([]);
const selectedPrompt = useSelector(selectPrompt);
const [newPromptName, setNewPromptName] = useState(''); const [newPromptName, setNewPromptName] = useState('');
const [isAddPromptModalOpen, setAddPromptModalOpen] = useState(false); const [isAddPromptModalOpen, setAddPromptModalOpen] = useState(false);
const [documents, setDocuments] = useState<Document[]>([]); const documents = useSelector(selectSourceDocs);
const [isAddDocumentModalOpen, setAddDocumentModalOpen] = useState(false); const [isAddDocumentModalOpen, setAddDocumentModalOpen] = useState(false);
const [newDocument, setNewDocument] = useState<Document>({ const [newDocument, setNewDocument] = useState<Document>({
name: '', name: '',
vectorDate: '', vectorDate: '',
vectorLocation: '', vectorLocation: '',
}); });
const onDeletePrompt = (name: string) => { const dispatch = useDispatch();
setPrompts(prompts.filter((prompt) => prompt !== name));
setSelectedPrompt(''); // Clear the selected prompt const apiHost = import.meta.env.VITE_API_HOST || 'https://docsapi.arc53.com';
};
const [widgetScreenshot, setWidgetScreenshot] = useState<File | null>(null); const [widgetScreenshot, setWidgetScreenshot] = useState<File | null>(null);
const updateWidgetScreenshot = (screenshot: File | null) => { const updateWidgetScreenshot = (screenshot: File | null) => {
setWidgetScreenshot(screenshot); setWidgetScreenshot(screenshot);
}; };
// Function to add a new document
const addDocument = () => {
if (
newDocument.name &&
newDocument.vectorDate &&
newDocument.vectorLocation
) {
setDocuments([...documents, newDocument]);
setNewDocument({
name: '',
vectorDate: '',
vectorLocation: '',
});
toggleAddDocumentModal();
}
};
// Function to toggle the Add Document modal // Function to toggle the Add Document modal
const toggleAddDocumentModal = () => { const toggleAddDocumentModal = () => {
setAddDocumentModalOpen(!isAddDocumentModalOpen); setAddDocumentModalOpen(!isAddDocumentModalOpen);
}; };
useEffect(() => {
const fetchPrompts = async () => {
try {
const response = await fetch(`${apiHost}/api/get_prompts`);
if (!response.ok) {
throw new Error('Failed to fetch prompts');
}
const promptsData = await response.json();
setPrompts(promptsData);
} catch (error) {
console.error(error);
}
};
fetchPrompts();
}, []);
const onDeletePrompt = (name: string, id: string) => {
setPrompts(prompts.filter((prompt) => prompt.id !== id));
fetch(`${apiHost}/api/delete_prompt`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
// send id in body only
body: JSON.stringify({ id: id }),
})
.then((response) => {
if (!response.ok) {
throw new Error('Failed to delete prompt');
}
})
.catch((error) => {
console.error(error);
});
};
const handleDeleteDocument = (index: number) => { const handleDeleteClick = (index: number, doc: Doc) => {
const updatedDocuments = [...documents]; const docPath = 'indexes/' + 'local' + '/' + doc.name;
updatedDocuments.splice(index, 1);
setDocuments(updatedDocuments); fetch(`${apiHost}/api/delete_old?path=${docPath}`, {
method: 'GET',
})
.then(() => {
// remove the image element from the DOM
const imageElement = document.querySelector(
`#img-${index}`,
) as HTMLElement;
const parentElement = imageElement.parentNode as HTMLElement;
parentElement.parentNode?.removeChild(parentElement);
})
.catch((error) => console.error(error));
}; };
return ( return (
@ -105,15 +147,6 @@ const Setting: React.FC = () => {
</div> </div>
{renderActiveTab()} {renderActiveTab()}
{isAddDocumentModalOpen && (
<AddDocumentModal
newDocument={newDocument}
onNewDocumentChange={setNewDocument}
onAddDocument={addDocument}
onClose={toggleAddDocumentModal}
/>
)}
{/* {activeTab === 'Widgets' && ( {/* {activeTab === 'Widgets' && (
<Widgets <Widgets
widgetScreenshot={widgetScreenshot} widgetScreenshot={widgetScreenshot}
@ -139,7 +172,9 @@ const Setting: React.FC = () => {
<Prompts <Prompts
prompts={prompts} prompts={prompts}
selectedPrompt={selectedPrompt} selectedPrompt={selectedPrompt}
onSelectPrompt={setSelectedPrompt} onSelectPrompt={(name, id) =>
dispatch(setPrompt({ name: name, id: id }))
}
onAddPrompt={addPrompt} onAddPrompt={addPrompt}
newPromptName={''} newPromptName={''}
onNewPromptNameChange={function (name: string): void { onNewPromptNameChange={function (name: string): void {
@ -156,10 +191,7 @@ const Setting: React.FC = () => {
return ( return (
<Documents <Documents
documents={documents} documents={documents}
isAddDocumentModalOpen={isAddDocumentModalOpen} handleDeleteDocument={handleDeleteClick}
newDocument={newDocument}
handleDeleteDocument={handleDeleteDocument}
toggleAddDocumentModal={toggleAddDocumentModal}
/> />
); );
case 'Widgets': case 'Widgets':
@ -176,7 +208,6 @@ const Setting: React.FC = () => {
function addPrompt(name: string) { function addPrompt(name: string) {
if (name) { if (name) {
setPrompts([...prompts, name]);
setNewPromptName(''); setNewPromptName('');
toggleAddPromptModal(); toggleAddPromptModal();
} }
@ -188,8 +219,8 @@ const Setting: React.FC = () => {
}; };
const General: React.FC = () => { const General: React.FC = () => {
const themes = ['Light', 'Dark']; const themes = ['Light'];
const languages = ['English', 'French', 'Hindi']; const languages = ['English'];
const [selectedTheme, setSelectedTheme] = useState(themes[0]); const [selectedTheme, setSelectedTheme] = useState(themes[0]);
const [selectedLanguage, setSelectedLanguage] = useState(languages[0]); const [selectedLanguage, setSelectedLanguage] = useState(languages[0]);
@ -235,30 +266,40 @@ const Prompts: React.FC<PromptProps> = ({
setAddPromptModalOpen(false); setAddPromptModalOpen(false);
}; };
const handleDeletePrompt = () => { const handleSelectPrompt = (name: string) => {
if (selectedPrompt) { const selected = prompts.find((prompt) => prompt.name === name);
onDeletePrompt(selectedPrompt); // Remove the selected prompt if (selected) {
onSelectPrompt(selected.name, selected.id);
}
};
const handleDeletePrompt = (name: string) => {
const selected = prompts.find((prompt) => prompt.name === name);
if (selected) {
onDeletePrompt(selected.name, selected.id);
} }
}; };
return ( return (
<div className="mt-[59px]"> <div className="mt-[59px]">
<div className="mb-4"> <div className="mb-4">
<p className="font-bold text-jet">Select Prompt</p> <p className="font-bold text-jet">Active Prompt</p>
<Dropdown <DropdownPrompt
options={prompts} options={prompts}
selectedValue={selectedPrompt} selectedValue={selectedPrompt.name}
onSelect={onSelectPrompt} onSelect={handleSelectPrompt}
showDelete={true}
onDelete={handleDeletePrompt}
/> />
</div> </div>
<div> {/* <div>
<button <button
onClick={openAddPromptModal} onClick={openAddPromptModal}
className="rounded-lg bg-purple-300 px-4 py-2 font-bold text-white transition-all hover:bg-purple-600" className="rounded-lg bg-purple-300 px-4 py-2 font-bold text-white transition-all hover:bg-purple-600"
> >
Add New Prompt Add New Prompt
</button> </button>
</div> </div> */}
{isAddPromptModalOpen && ( {isAddPromptModalOpen && (
<AddPromptModal <AddPromptModal
newPromptName={newPromptName} newPromptName={newPromptName}
@ -270,34 +311,92 @@ const Prompts: React.FC<PromptProps> = ({
onClose={closeAddPromptModal} onClose={closeAddPromptModal}
/> />
)} )}
<div className="mt-4">
<button
onClick={handleDeletePrompt}
className="rounded-lg bg-red-300 px-4 py-2 font-bold text-white transition-all hover:bg-red-600 hover:text-zinc-800"
>
Delete Prompt
</button>
</div>
</div> </div>
); );
}; };
function DropdownPrompt({
options,
selectedValue,
onSelect,
showDelete,
onDelete,
}: {
options: { name: string; id: string; type: string }[];
selectedValue: string;
onSelect: (value: string) => void;
showDelete?: boolean;
onDelete: (value: string) => void;
}) {
const [isOpen, setIsOpen] = useState(false);
return (
<div className="relative mt-2 w-32">
<button
onClick={() => setIsOpen(!isOpen)}
className="flex w-full cursor-pointer items-center rounded-xl border-2 bg-white p-3"
>
<span className="flex-1 overflow-hidden text-ellipsis">
{selectedValue}
</span>
<img
src={Arrow2}
alt="arrow"
className={`transform ${
isOpen ? 'rotate-180' : 'rotate-0'
} h-3 w-3 transition-transform`}
/>
</button>
{isOpen && (
<div className="absolute left-0 right-0 z-50 -mt-3 rounded-b-xl border-2 bg-white shadow-lg">
{options.map((option, index) => (
<div
key={index}
className="flex cursor-pointer items-center justify-between hover:bg-gray-100"
>
<span
onClick={() => {
onSelect(option.name);
setIsOpen(false);
}}
className="ml-2 flex-1 overflow-hidden overflow-ellipsis whitespace-nowrap py-3"
>
{option.name}
</span>
{showDelete && option.type === 'private' && (
<button onClick={() => onDelete(option.name)} className="p-2">
{/* Icon or text for delete button */}
Delete
</button>
)}
</div>
))}
</div>
)}
</div>
);
}
function Dropdown({ function Dropdown({
options, options,
selectedValue, selectedValue,
onSelect, onSelect,
showDelete,
onDelete,
}: { }: {
options: string[]; options: string[];
selectedValue: string; selectedValue: string;
onSelect: (value: string) => void; onSelect: (value: string) => void;
showDelete?: boolean; // optional
onDelete?: (value: string) => void; // optional
}) { }) {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
return ( return (
<div className="relative mt-2 h-[43.33px] w-[342px]"> <div className="relative mt-2 w-32">
<button <button
onClick={() => setIsOpen(!isOpen)} onClick={() => setIsOpen(!isOpen)}
className="flex w-full cursor-pointer items-center rounded-3xl border-2 bg-white p-3" className="flex w-full cursor-pointer items-center rounded-xl border-2 bg-white p-3"
> >
<span className="flex-1 overflow-hidden text-ellipsis"> <span className="flex-1 overflow-hidden text-ellipsis">
{selectedValue} {selectedValue}
@ -307,23 +406,31 @@ function Dropdown({
alt="arrow" alt="arrow"
className={`transform ${ className={`transform ${
isOpen ? 'rotate-180' : 'rotate-0' isOpen ? 'rotate-180' : 'rotate-0'
} h-4 w-4 transition-transform`} } h-3 w-3 transition-transform`}
/> />
</button> </button>
{isOpen && ( {isOpen && (
<div className="absolute left-0 right-0 top-12 z-50 mt-2 bg-white p-2 shadow-lg"> <div className="absolute left-0 right-0 z-50 -mt-3 rounded-b-xl border-2 bg-white shadow-lg">
{options.map((option, index) => ( {options.map((option, index) => (
<div <div
key={index} key={index}
onClick={() => { className="flex cursor-pointer items-center justify-between hover:bg-gray-100"
onSelect(option);
setIsOpen(false);
}}
className="flex cursor-pointer items-center justify-between border-b-2 py-3 hover:bg-gray-100"
> >
<span className="flex-1 overflow-hidden overflow-ellipsis whitespace-nowrap"> <span
onClick={() => {
onSelect(option);
setIsOpen(false);
}}
className="ml-2 flex-1 overflow-hidden overflow-ellipsis whitespace-nowrap py-3"
>
{option} {option}
</span> </span>
{showDelete && onDelete && (
<button onClick={() => onDelete(option)} className="p-2">
{/* Icon or text for delete button */}
Delete
</button>
)}
</div> </div>
))} ))}
</div> </div>
@ -347,24 +454,24 @@ const AddPromptModal: React.FC<AddPromptModalProps> = ({
}) => { }) => {
return ( return (
<div className="fixed top-0 left-0 flex h-screen w-screen items-center justify-center bg-gray-900 bg-opacity-50"> <div className="fixed top-0 left-0 flex h-screen w-screen items-center justify-center bg-gray-900 bg-opacity-50">
<div className="rounded-lg bg-white p-4"> <div className="rounded-3xl bg-white p-4">
<p className="mb-2 text-2xl font-bold text-jet">Add New Prompt</p> <p className="mb-2 text-2xl font-bold text-jet">Add New Prompt</p>
<input <input
type="text" type="text"
placeholder="Enter Prompt Name" placeholder="Enter Prompt Name"
value={newPromptName} value={newPromptName}
onChange={(e) => onNewPromptNameChange(e.target.value)} onChange={(e) => onNewPromptNameChange(e.target.value)}
className="mb-4 w-full rounded-lg border-2 p-2" className="mb-4 w-full rounded-3xl border-2 p-2"
/> />
<button <button
onClick={onAddPrompt} onClick={onAddPrompt}
className="rounded-lg bg-purple-300 px-4 py-2 font-bold text-white transition-all hover:bg-purple-600" className="rounded-3xl bg-purple-300 px-4 py-2 font-bold text-white transition-all hover:bg-purple-600"
> >
Save Save
</button> </button>
<button <button
onClick={onClose} onClick={onClose}
className="mt-4 rounded-lg px-4 py-2 font-bold text-red-500" className="mt-4 rounded-3xl px-4 py-2 font-bold text-red-500"
> >
Cancel Cancel
</button> </button>
@ -374,19 +481,13 @@ const AddPromptModal: React.FC<AddPromptModalProps> = ({
}; };
type DocumentsProps = { type DocumentsProps = {
documents: Document[]; documents: Doc[] | null;
isAddDocumentModalOpen: boolean; handleDeleteDocument: (index: number, document: Doc) => void;
newDocument: Document;
handleDeleteDocument: (index: number) => void;
toggleAddDocumentModal: () => void;
}; };
const Documents: React.FC<DocumentsProps> = ({ const Documents: React.FC<DocumentsProps> = ({
documents, documents,
isAddDocumentModalOpen,
newDocument,
handleDeleteDocument, handleDeleteDocument,
toggleAddDocumentModal,
}) => { }) => {
return ( return (
<div className="mt-8"> <div className="mt-8">
@ -394,42 +495,51 @@ const Documents: React.FC<DocumentsProps> = ({
{/* <h2 className="text-xl font-semibold">Documents</h2> */} {/* <h2 className="text-xl font-semibold">Documents</h2> */}
<div className="mt-[27px] overflow-x-auto"> <div className="mt-[27px] overflow-x-auto">
<table className="block w-full table-auto content-center justify-center"> <table className="block w-full table-auto content-center justify-center text-center">
<thead> <thead>
<tr> <tr>
<th className="border px-4 py-2">Document Name</th> <th className="border px-4 py-2">Document Name</th>
<th className="border px-4 py-2">Vector Date</th> <th className="border px-4 py-2">Vector Date</th>
<th className="border px-4 py-2">Vector Location</th> <th className="border px-4 py-2">Type</th>
<th className="border px-4 py-2">Actions</th> <th className="border px-4 py-2"></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{documents.map((document, index) => ( {documents &&
<tr key={index}> documents.map((document, index) => (
<td className="border px-4 py-2">{document.name}</td> <tr key={index}>
<td className="border px-4 py-2">{document.vectorDate}</td> <td className="border px-4 py-2">{document.name}</td>
<td className="border px-4 py-2"> <td className="border px-4 py-2">{document.date}</td>
{document.vectorLocation} <td className="border px-4 py-2">
</td> {document.location === 'remote'
<td className="border px-4 py-2"> ? 'Pre-loaded'
<button : 'Private'}
className="rounded-lg bg-red-600 px-2 py-1 font-bold text-white hover:bg-red-800" </td>
onClick={() => handleDeleteDocument(index)} <td className="border px-4 py-2">
> {document.location !== 'remote' && (
Delete <img
</button> src={Trash}
</td> alt="Delete"
</tr> className="h-4 w-4 cursor-pointer hover:opacity-50"
))} id={`img-${index}`}
onClick={(event) => {
event.stopPropagation();
handleDeleteDocument(index, document);
}}
/>
)}
</td>
</tr>
))}
</tbody> </tbody>
</table> </table>
</div> </div>
<button {/* <button
onClick={toggleAddDocumentModal} onClick={toggleAddDocumentModal}
className="mt-10 w-32 rounded-lg bg-purple-300 px-4 py-2 font-bold text-white transition-all hover:bg-purple-600" className="mt-10 w-32 rounded-lg bg-purple-300 px-4 py-2 font-bold text-white transition-all hover:bg-purple-600"
> >
Add New Add New
</button> </button> */}
</div> </div>
{/* {isAddDocumentModalOpen && ( {/* {isAddDocumentModalOpen && (

@ -6,7 +6,7 @@ export type Doc = {
version: string; version: string;
description: string; description: string;
fullName: string; fullName: string;
dat: string; date: string;
docLink: string; docLink: string;
model: string; model: string;
}; };

@ -8,6 +8,7 @@ import { RootState } from '../store';
interface Preference { interface Preference {
apiKey: string; apiKey: string;
prompt: { name: string; id: string };
selectedDocs: Doc | null; selectedDocs: Doc | null;
sourceDocs: Doc[] | null; sourceDocs: Doc[] | null;
conversations: { name: string; id: string }[] | null; conversations: { name: string; id: string }[] | null;
@ -15,6 +16,7 @@ interface Preference {
const initialState: Preference = { const initialState: Preference = {
apiKey: 'xxx', apiKey: 'xxx',
prompt: { name: 'default', id: 'default' },
selectedDocs: { selectedDocs: {
name: 'default', name: 'default',
language: 'default', language: 'default',
@ -22,7 +24,7 @@ const initialState: Preference = {
version: 'default', version: 'default',
description: 'default', description: 'default',
fullName: 'default', fullName: 'default',
dat: 'default', date: 'default',
docLink: 'default', docLink: 'default',
model: 'openai_text-embedding-ada-002', model: 'openai_text-embedding-ada-002',
} as Doc, } as Doc,
@ -46,11 +48,19 @@ export const prefSlice = createSlice({
setConversations: (state, action) => { setConversations: (state, action) => {
state.conversations = action.payload; state.conversations = action.payload;
}, },
setPrompt: (state, action) => {
state.prompt = action.payload;
},
}, },
}); });
export const { setApiKey, setSelectedDocs, setSourceDocs, setConversations } = export const {
prefSlice.actions; setApiKey,
setSelectedDocs,
setSourceDocs,
setConversations,
setPrompt,
} = prefSlice.actions;
export default prefSlice.reducer; export default prefSlice.reducer;
export const prefListenerMiddleware = createListenerMiddleware(); export const prefListenerMiddleware = createListenerMiddleware();
@ -84,3 +94,4 @@ export const selectConversations = (state: RootState) =>
state.preference.conversations; state.preference.conversations;
export const selectConversationId = (state: RootState) => export const selectConversationId = (state: RootState) =>
state.conversation.conversationId; state.conversation.conversationId;
export const selectPrompt = (state: RootState) => state.preference.prompt;

@ -13,6 +13,7 @@ const store = configureStore({
preference: { preference: {
apiKey: key ?? '', apiKey: key ?? '',
selectedDocs: doc !== null ? JSON.parse(doc) : null, selectedDocs: doc !== null ? JSON.parse(doc) : null,
prompt: { name: 'default', id: 'default' },
conversations: null, conversations: null,
sourceDocs: [ sourceDocs: [
{ {
@ -20,7 +21,7 @@ const store = configureStore({
language: '', language: '',
name: 'default', name: 'default',
version: '', version: '',
dat: '', date: '',
description: '', description: '',
docLink: '', docLink: '',
fullName: '', fullName: '',

Loading…
Cancel
Save