mirror of
https://github.com/tiennm99/DocsGPT.git
synced 2026-10-17 06:14:25 +00:00
Merge pull request #782 from arc53/feature/add-prompts
Feature/add prompts
This commit is contained in:
7 files changed
+257
-143
No files matched your search
@@ -25,6 +25,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"]
|
||||||
answer = Blueprint('answer', __name__)
|
answer = Blueprint('answer', __name__)
|
||||||
|
|
||||||
if settings.LLM_NAME == "gpt4":
|
if settings.LLM_NAME == "gpt4":
|
||||||
@@ -43,10 +44,10 @@ with open(os.path.join(current_dir, "prompts", "chat_reduce_prompt.txt"), "r") a
|
|||||||
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:
|
with open(os.path.join(current_dir, "prompts", "chat_combine_creative.txt"), "r") as f:
|
||||||
chat_reduce_creative = f.read()
|
chat_combine_creative = f.read()
|
||||||
|
|
||||||
with open(os.path.join(current_dir, "prompts", "chat_combine_strict.txt"), "r") as f:
|
with open(os.path.join(current_dir, "prompts", "chat_combine_strict.txt"), "r") as f:
|
||||||
chat_reduce_strict = f.read()
|
chat_combine_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
|
||||||
@@ -90,23 +91,6 @@ def get_vectorstore(data):
|
|||||||
return vectorstore
|
return vectorstore
|
||||||
|
|
||||||
|
|
||||||
# def get_docsearch(vectorstore, embeddings_key):
|
|
||||||
# if settings.EMBEDDINGS_NAME == "openai_text-embedding-ada-002":
|
|
||||||
# if is_azure_configured():
|
|
||||||
# os.environ["OPENAI_API_TYPE"] = "azure"
|
|
||||||
# openai_embeddings = OpenAIEmbeddings(model=settings.AZURE_EMBEDDINGS_DEPLOYMENT_NAME)
|
|
||||||
# else:
|
|
||||||
# openai_embeddings = OpenAIEmbeddings(openai_api_key=embeddings_key)
|
|
||||||
# docsearch = FAISS.load_local(vectorstore, openai_embeddings)
|
|
||||||
# elif settings.EMBEDDINGS_NAME == "huggingface_sentence-transformers/all-mpnet-base-v2":
|
|
||||||
# docsearch = FAISS.load_local(vectorstore, HuggingFaceHubEmbeddings())
|
|
||||||
# elif settings.EMBEDDINGS_NAME == "huggingface_hkunlp/instructor-large":
|
|
||||||
# docsearch = FAISS.load_local(vectorstore, HuggingFaceInstructEmbeddings())
|
|
||||||
# elif settings.EMBEDDINGS_NAME == "cohere_medium":
|
|
||||||
# docsearch = FAISS.load_local(vectorstore, CohereEmbeddings(cohere_api_key=embeddings_key))
|
|
||||||
# return docsearch
|
|
||||||
|
|
||||||
|
|
||||||
def is_azure_configured():
|
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
|
||||||
|
|
||||||
@@ -115,13 +99,16 @@ def complete_stream(question, docsearch, chat_history, api_key, prompt_id, conve
|
|||||||
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':
|
if prompt_id == 'default':
|
||||||
prompt = chat_reduce_template
|
prompt = chat_combine_template
|
||||||
elif prompt_id == 'creative':
|
elif prompt_id == 'creative':
|
||||||
prompt = chat_reduce_creative
|
prompt = chat_combine_creative
|
||||||
elif prompt_id == 'strict':
|
elif prompt_id == 'strict':
|
||||||
prompt = chat_reduce_strict
|
prompt = chat_combine_strict
|
||||||
else:
|
else:
|
||||||
prompt = chat_reduce_template
|
prompt = prompts_collection.find_one({"_id": ObjectId(prompt_id)})["content"]
|
||||||
|
import sys
|
||||||
|
print(prompt_id, file=sys.stderr)
|
||||||
|
print(prompt, file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
docs = docsearch.search(question, k=2)
|
docs = docsearch.search(question, k=2)
|
||||||
@@ -253,6 +240,19 @@ def api_answer():
|
|||||||
embeddings_key = data["embeddings_key"]
|
embeddings_key = data["embeddings_key"]
|
||||||
else:
|
else:
|
||||||
embeddings_key = settings.EMBEDDINGS_KEY
|
embeddings_key = settings.EMBEDDINGS_KEY
|
||||||
|
if 'prompt_id' in data:
|
||||||
|
prompt_id = data["prompt_id"]
|
||||||
|
else:
|
||||||
|
prompt_id = 'default'
|
||||||
|
|
||||||
|
if prompt_id == 'default':
|
||||||
|
prompt = chat_combine_template
|
||||||
|
elif prompt_id == 'creative':
|
||||||
|
prompt = chat_combine_creative
|
||||||
|
elif prompt_id == 'strict':
|
||||||
|
prompt = chat_combine_strict
|
||||||
|
else:
|
||||||
|
prompt = prompts_collection.find_one({"_id": ObjectId(prompt_id)})["content"]
|
||||||
|
|
||||||
# use try and except to check for exception
|
# use try and except to check for exception
|
||||||
try:
|
try:
|
||||||
@@ -270,7 +270,7 @@ def api_answer():
|
|||||||
docs = docsearch.search(question, k=2)
|
docs = docsearch.search(question, k=2)
|
||||||
# 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:
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
import os
|
import os
|
||||||
from flask import Blueprint, request, jsonify
|
from flask import Blueprint, request, jsonify
|
||||||
import requests
|
import requests
|
||||||
import json
|
|
||||||
from pymongo import MongoClient
|
from pymongo import MongoClient
|
||||||
from bson.objectid import ObjectId
|
from bson.objectid import ObjectId
|
||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
import http.client
|
|
||||||
|
|
||||||
from application.api.user.tasks import ingest
|
from application.api.user.tasks import ingest
|
||||||
|
|
||||||
@@ -17,6 +15,7 @@ db = mongo["docsgpt"]
|
|||||||
conversations_collection = db["conversations"]
|
conversations_collection = db["conversations"]
|
||||||
vectors_collection = db["vectors"]
|
vectors_collection = db["vectors"]
|
||||||
prompts_collection = db["prompts"]
|
prompts_collection = db["prompts"]
|
||||||
|
feedback_collection = db["feedback"]
|
||||||
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__))))
|
||||||
@@ -71,19 +70,15 @@ def api_feedback():
|
|||||||
answer = data["answer"]
|
answer = data["answer"]
|
||||||
feedback = data["feedback"]
|
feedback = data["feedback"]
|
||||||
|
|
||||||
print("-" * 5)
|
|
||||||
print("Question: " + question)
|
feedback_collection.insert_one(
|
||||||
print("Answer: " + answer)
|
{
|
||||||
print("Feedback: " + feedback)
|
"question": question,
|
||||||
print("-" * 5)
|
"answer": answer,
|
||||||
response = requests.post(
|
"feedback": feedback,
|
||||||
url="https://86x89umx77.execute-api.eu-west-2.amazonaws.com/docsgpt-feedback",
|
}
|
||||||
headers={
|
|
||||||
"Content-Type": "application/json; charset=utf-8",
|
|
||||||
},
|
|
||||||
data=json.dumps({"answer": answer, "question": question, "feedback": feedback}),
|
|
||||||
)
|
)
|
||||||
return {"status": http.client.responses.get(response.status_code, "ok")}
|
return {"status": "ok"}
|
||||||
|
|
||||||
@user.route("/api/delete_by_ids", methods=["get"])
|
@user.route("/api/delete_by_ids", methods=["get"])
|
||||||
def delete_by_ids():
|
def delete_by_ids():
|
||||||
@@ -249,18 +244,20 @@ def check_docs():
|
|||||||
@user.route("/api/create_prompt", methods=["POST"])
|
@user.route("/api/create_prompt", methods=["POST"])
|
||||||
def create_prompt():
|
def create_prompt():
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
prompt = data["prompt"]
|
content = data["content"]
|
||||||
name = data["name"]
|
name = data["name"]
|
||||||
|
if name == "":
|
||||||
|
return {"status": "error"}
|
||||||
user = "local"
|
user = "local"
|
||||||
# write to mongodb
|
resp = prompts_collection.insert_one(
|
||||||
prompts_collection.insert_one(
|
|
||||||
{
|
{
|
||||||
"name": name,
|
"name": name,
|
||||||
"prompt": prompt,
|
"content": content,
|
||||||
"user": user,
|
"user": user,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return {"status": "ok"}
|
new_id = str(resp.inserted_id)
|
||||||
|
return {"id": new_id}
|
||||||
|
|
||||||
@user.route("/api/get_prompts", methods=["GET"])
|
@user.route("/api/get_prompts", methods=["GET"])
|
||||||
def get_prompts():
|
def get_prompts():
|
||||||
@@ -271,32 +268,51 @@ def get_prompts():
|
|||||||
list_prompts.append({"id": "creative", "name": "creative", "type": "public"})
|
list_prompts.append({"id": "creative", "name": "creative", "type": "public"})
|
||||||
list_prompts.append({"id": "precise", "name": "precise", "type": "public"})
|
list_prompts.append({"id": "precise", "name": "precise", "type": "public"})
|
||||||
for prompt in prompts:
|
for prompt in prompts:
|
||||||
list_prompts.append({"id": str(prompt["_id"]), "name": prompt["name"], type: "private"})
|
list_prompts.append({"id": str(prompt["_id"]), "name": prompt["name"], "type": "private"})
|
||||||
|
|
||||||
return jsonify(list_prompts)
|
return jsonify(list_prompts)
|
||||||
|
|
||||||
@user.route("/api/get_single_prompt", methods=["GET"])
|
@user.route("/api/get_single_prompt", methods=["GET"])
|
||||||
def get_single_prompt():
|
def get_single_prompt():
|
||||||
prompt_id = request.args.get("id")
|
prompt_id = request.args.get("id")
|
||||||
|
if prompt_id == 'default':
|
||||||
|
with open(os.path.join(current_dir, "prompts", "chat_combine_default.txt"), "r") as f:
|
||||||
|
chat_combine_template = f.read()
|
||||||
|
return jsonify({"content": chat_combine_template})
|
||||||
|
elif prompt_id == 'creative':
|
||||||
|
with open(os.path.join(current_dir, "prompts", "chat_combine_creative.txt"), "r") as f:
|
||||||
|
chat_reduce_creative = f.read()
|
||||||
|
return jsonify({"content": chat_reduce_creative})
|
||||||
|
elif prompt_id == 'strict':
|
||||||
|
with open(os.path.join(current_dir, "prompts", "chat_combine_strict.txt"), "r") as f:
|
||||||
|
chat_reduce_strict = f.read()
|
||||||
|
return jsonify({"content": chat_reduce_strict})
|
||||||
|
|
||||||
|
|
||||||
prompt = prompts_collection.find_one({"_id": ObjectId(prompt_id)})
|
prompt = prompts_collection.find_one({"_id": ObjectId(prompt_id)})
|
||||||
return jsonify(prompt['prompt'])
|
return jsonify({"content": prompt["content"]})
|
||||||
|
|
||||||
@user.route("/api/delete_prompt", methods=["POST"])
|
@user.route("/api/delete_prompt", methods=["POST"])
|
||||||
def delete_prompt():
|
def delete_prompt():
|
||||||
prompt_id = request.args.get("id")
|
data = request.get_json()
|
||||||
|
id = data["id"]
|
||||||
prompts_collection.delete_one(
|
prompts_collection.delete_one(
|
||||||
{
|
{
|
||||||
"_id": ObjectId(prompt_id),
|
"_id": ObjectId(id),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return {"status": "ok"}
|
return {"status": "ok"}
|
||||||
|
|
||||||
@user.route("/api/update_prompt_name", methods=["POST"])
|
@user.route("/api/update_prompt", methods=["POST"])
|
||||||
def update_prompt_name():
|
def update_prompt_name():
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
id = data["id"]
|
id = data["id"]
|
||||||
name = data["name"]
|
name = data["name"]
|
||||||
prompts_collection.update_one({"_id": ObjectId(id)},{"$set":{"name":name}})
|
content = data["content"]
|
||||||
|
# check if name is null
|
||||||
|
if name == "":
|
||||||
|
return {"status": "error"}
|
||||||
|
prompts_collection.update_one({"_id": ObjectId(id)},{"$set":{"name":name, "content": content}})
|
||||||
return {"status": "ok"}
|
return {"status": "ok"}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+183
-91
@@ -13,14 +13,10 @@ import { Doc } from './preferences/preferenceApi';
|
|||||||
|
|
||||||
type PromptProps = {
|
type PromptProps = {
|
||||||
prompts: { name: string; id: string; type: string }[];
|
prompts: { name: string; id: string; type: string }[];
|
||||||
selectedPrompt: { name: string; id: string };
|
selectedPrompt: { name: string; id: string; type: string };
|
||||||
onSelectPrompt: (name: string, id: string) => void;
|
onSelectPrompt: (name: string, id: string, type: string) => void;
|
||||||
onAddPrompt: (name: string) => void;
|
setPrompts: (prompts: { name: string; id: string; type: string }[]) => void;
|
||||||
newPromptName: string;
|
apiHost: string;
|
||||||
onNewPromptNameChange: (name: string) => void;
|
|
||||||
isAddPromptModalOpen: boolean;
|
|
||||||
onToggleAddPromptModal: () => void;
|
|
||||||
onDeletePrompt: (name: string, id: string) => void;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const Setting: React.FC = () => {
|
const Setting: React.FC = () => {
|
||||||
@@ -32,15 +28,10 @@ const Setting: React.FC = () => {
|
|||||||
{ name: string; id: string; type: string }[]
|
{ name: string; id: string; type: string }[]
|
||||||
>([]);
|
>([]);
|
||||||
const selectedPrompt = useSelector(selectPrompt);
|
const selectedPrompt = useSelector(selectPrompt);
|
||||||
const [newPromptName, setNewPromptName] = useState('');
|
|
||||||
const [isAddPromptModalOpen, setAddPromptModalOpen] = useState(false);
|
const [isAddPromptModalOpen, setAddPromptModalOpen] = useState(false);
|
||||||
const documents = useSelector(selectSourceDocs);
|
const documents = useSelector(selectSourceDocs);
|
||||||
const [isAddDocumentModalOpen, setAddDocumentModalOpen] = useState(false);
|
const [isAddDocumentModalOpen, setAddDocumentModalOpen] = useState(false);
|
||||||
const [newDocument, setNewDocument] = useState<Document>({
|
|
||||||
name: '',
|
|
||||||
vectorDate: '',
|
|
||||||
vectorLocation: '',
|
|
||||||
});
|
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const apiHost = import.meta.env.VITE_API_HOST || 'https://docsapi.arc53.com';
|
const apiHost = import.meta.env.VITE_API_HOST || 'https://docsapi.arc53.com';
|
||||||
@@ -50,10 +41,6 @@ const Setting: React.FC = () => {
|
|||||||
setWidgetScreenshot(screenshot);
|
setWidgetScreenshot(screenshot);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function to toggle the Add Document modal
|
|
||||||
const toggleAddDocumentModal = () => {
|
|
||||||
setAddDocumentModalOpen(!isAddDocumentModalOpen);
|
|
||||||
};
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchPrompts = async () => {
|
const fetchPrompts = async () => {
|
||||||
try {
|
try {
|
||||||
@@ -172,19 +159,11 @@ const Setting: React.FC = () => {
|
|||||||
<Prompts
|
<Prompts
|
||||||
prompts={prompts}
|
prompts={prompts}
|
||||||
selectedPrompt={selectedPrompt}
|
selectedPrompt={selectedPrompt}
|
||||||
onSelectPrompt={(name, id) =>
|
onSelectPrompt={(name, id, type) =>
|
||||||
dispatch(setPrompt({ name: name, id: id }))
|
dispatch(setPrompt({ name: name, id: id, type: type }))
|
||||||
}
|
}
|
||||||
onAddPrompt={addPrompt}
|
setPrompts={setPrompts}
|
||||||
newPromptName={''}
|
apiHost={apiHost}
|
||||||
onNewPromptNameChange={function (name: string): void {
|
|
||||||
throw new Error('Function not implemented.');
|
|
||||||
}}
|
|
||||||
isAddPromptModalOpen={false}
|
|
||||||
onToggleAddPromptModal={function (): void {
|
|
||||||
throw new Error('Function not implemented.');
|
|
||||||
}}
|
|
||||||
onDeletePrompt={onDeletePrompt}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
case 'Documents':
|
case 'Documents':
|
||||||
@@ -205,17 +184,6 @@ const Setting: React.FC = () => {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function addPrompt(name: string) {
|
|
||||||
if (name) {
|
|
||||||
setNewPromptName('');
|
|
||||||
toggleAddPromptModal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleAddPromptModal() {
|
|
||||||
setAddPromptModalOpen(!isAddPromptModalOpen);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const General: React.FC = () => {
|
const General: React.FC = () => {
|
||||||
@@ -252,65 +220,199 @@ const Prompts: React.FC<PromptProps> = ({
|
|||||||
prompts,
|
prompts,
|
||||||
selectedPrompt,
|
selectedPrompt,
|
||||||
onSelectPrompt,
|
onSelectPrompt,
|
||||||
onAddPrompt,
|
setPrompts,
|
||||||
onDeletePrompt,
|
apiHost,
|
||||||
}) => {
|
}) => {
|
||||||
const [isAddPromptModalOpen, setAddPromptModalOpen] = useState(false);
|
const handleSelectPrompt = ({
|
||||||
const [newPromptName, setNewPromptName] = useState('');
|
name,
|
||||||
|
id,
|
||||||
const openAddPromptModal = () => {
|
type,
|
||||||
setAddPromptModalOpen(true);
|
}: {
|
||||||
|
name: string;
|
||||||
|
id: string;
|
||||||
|
type: string;
|
||||||
|
}) => {
|
||||||
|
setNewPromptName(name);
|
||||||
|
onSelectPrompt(name, id, type);
|
||||||
};
|
};
|
||||||
|
const [newPromptName, setNewPromptName] = useState(selectedPrompt.name);
|
||||||
|
const [newPromptContent, setNewPromptContent] = useState('');
|
||||||
|
|
||||||
const closeAddPromptModal = () => {
|
const handleAddPrompt = async () => {
|
||||||
setAddPromptModalOpen(false);
|
try {
|
||||||
};
|
const response = await fetch(`${apiHost}/api/create_prompt`, {
|
||||||
|
method: 'POST',
|
||||||
const handleSelectPrompt = (name: string) => {
|
headers: {
|
||||||
const selected = prompts.find((prompt) => prompt.name === name);
|
'Content-Type': 'application/json',
|
||||||
if (selected) {
|
},
|
||||||
onSelectPrompt(selected.name, selected.id);
|
body: JSON.stringify({
|
||||||
|
name: newPromptName,
|
||||||
|
content: newPromptContent,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to add prompt');
|
||||||
|
}
|
||||||
|
const newPrompt = await response.json();
|
||||||
|
if (setPrompts) {
|
||||||
|
setPrompts([
|
||||||
|
...prompts,
|
||||||
|
{ name: newPromptName, id: newPrompt.id, type: 'private' },
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
onSelectPrompt(newPromptName, newPrompt.id, newPromptContent);
|
||||||
|
setNewPromptName(newPromptName);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDeletePrompt = (name: string) => {
|
const handleDeletePrompt = () => {
|
||||||
const selected = prompts.find((prompt) => prompt.name === name);
|
setPrompts(prompts.filter((prompt) => prompt.id !== selectedPrompt.id));
|
||||||
if (selected) {
|
console.log('selectedPrompt.id', selectedPrompt.id);
|
||||||
onDeletePrompt(selected.name, selected.id);
|
|
||||||
}
|
fetch(`${apiHost}/api/delete_prompt`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ id: selectedPrompt.id }),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to delete prompt');
|
||||||
|
}
|
||||||
|
// get 1st prompt and set it as selected
|
||||||
|
if (prompts.length > 0) {
|
||||||
|
onSelectPrompt(prompts[0].name, prompts[0].id, prompts[0].type);
|
||||||
|
setNewPromptName(prompts[0].name);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchPromptContent = async () => {
|
||||||
|
console.log('fetching prompt content');
|
||||||
|
try {
|
||||||
|
const response = await fetch(
|
||||||
|
`${apiHost}/api/get_single_prompt?id=${selectedPrompt.id}`,
|
||||||
|
{
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to fetch prompt content');
|
||||||
|
}
|
||||||
|
const promptContent = await response.json();
|
||||||
|
setNewPromptContent(promptContent.content);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchPromptContent();
|
||||||
|
}, [selectedPrompt]);
|
||||||
|
|
||||||
|
const handleSaveChanges = () => {
|
||||||
|
fetch(`${apiHost}/api/update_prompt`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
id: selectedPrompt.id,
|
||||||
|
name: newPromptName,
|
||||||
|
content: newPromptContent,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to update prompt');
|
||||||
|
}
|
||||||
|
onSelectPrompt(newPromptName, selectedPrompt.id, selectedPrompt.type);
|
||||||
|
setNewPromptName(newPromptName);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mt-[59px]">
|
<div className="mt-[59px]">
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<p className="font-bold text-jet">Active Prompt</p>
|
<p className="font-semibold">Active Prompt</p>
|
||||||
<DropdownPrompt
|
<DropdownPrompt
|
||||||
options={prompts}
|
options={prompts}
|
||||||
selectedValue={selectedPrompt.name}
|
selectedValue={selectedPrompt.name}
|
||||||
onSelect={handleSelectPrompt}
|
onSelect={handleSelectPrompt}
|
||||||
showDelete={true}
|
|
||||||
onDelete={handleDeletePrompt}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/* <div>
|
|
||||||
|
<div className="mb-4">
|
||||||
|
<p>Prompt name </p>{' '}
|
||||||
|
<p className="mb-2 text-xs italic text-eerie-black text-gray-500">
|
||||||
|
start by editing name
|
||||||
|
</p>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={newPromptName}
|
||||||
|
placeholder="Active Prompt Name"
|
||||||
|
className="w-full rounded-lg border-2 p-2"
|
||||||
|
onChange={(e) => setNewPromptName(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-4">
|
||||||
|
<p className="mb-2">Prompt content</p>
|
||||||
|
<textarea
|
||||||
|
className="h-32 w-full rounded-lg border-2 p-2"
|
||||||
|
value={newPromptContent}
|
||||||
|
onChange={(e) => setNewPromptContent(e.target.value)}
|
||||||
|
placeholder="Active prompt contents"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex justify-between">
|
||||||
<button
|
<button
|
||||||
onClick={openAddPromptModal}
|
className={`rounded-lg bg-green-500 px-4 py-2 font-bold text-white transition-all hover:bg-green-700 ${
|
||||||
className="rounded-lg bg-purple-300 px-4 py-2 font-bold text-white transition-all hover:bg-purple-600"
|
newPromptName === selectedPrompt.name
|
||||||
|
? 'cursor-not-allowed opacity-50'
|
||||||
|
: ''
|
||||||
|
}`}
|
||||||
|
onClick={handleAddPrompt}
|
||||||
|
disabled={newPromptName === selectedPrompt.name}
|
||||||
>
|
>
|
||||||
Add New Prompt
|
Add New Prompt
|
||||||
</button>
|
</button>
|
||||||
</div> */}
|
<button
|
||||||
{isAddPromptModalOpen && (
|
className={`rounded-lg bg-red-500 px-4 py-2 font-bold text-white transition-all hover:bg-red-700 ${
|
||||||
<AddPromptModal
|
selectedPrompt.type === 'public'
|
||||||
newPromptName={newPromptName}
|
? 'cursor-not-allowed opacity-50'
|
||||||
onNewPromptNameChange={setNewPromptName}
|
: ''
|
||||||
onAddPrompt={() => {
|
}`}
|
||||||
onAddPrompt(newPromptName);
|
onClick={handleDeletePrompt}
|
||||||
closeAddPromptModal();
|
disabled={selectedPrompt.type === 'public'}
|
||||||
}}
|
>
|
||||||
onClose={closeAddPromptModal}
|
Delete Prompt
|
||||||
/>
|
</button>
|
||||||
)}
|
<button
|
||||||
|
className={`rounded-lg bg-blue-500 px-4 py-2 font-bold text-white transition-all hover:bg-blue-700 ${
|
||||||
|
selectedPrompt.type === 'public'
|
||||||
|
? 'cursor-not-allowed opacity-50'
|
||||||
|
: ''
|
||||||
|
}`}
|
||||||
|
onClick={handleSaveChanges}
|
||||||
|
disabled={selectedPrompt.type === 'public'}
|
||||||
|
>
|
||||||
|
Save Changes
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -319,14 +421,10 @@ function DropdownPrompt({
|
|||||||
options,
|
options,
|
||||||
selectedValue,
|
selectedValue,
|
||||||
onSelect,
|
onSelect,
|
||||||
showDelete,
|
|
||||||
onDelete,
|
|
||||||
}: {
|
}: {
|
||||||
options: { name: string; id: string; type: string }[];
|
options: { name: string; id: string; type: string }[];
|
||||||
selectedValue: string;
|
selectedValue: string;
|
||||||
onSelect: (value: string) => void;
|
onSelect: (value: { name: string; id: string; type: string }) => void;
|
||||||
showDelete?: boolean;
|
|
||||||
onDelete: (value: string) => void;
|
|
||||||
}) {
|
}) {
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
|
||||||
@@ -356,19 +454,13 @@ function DropdownPrompt({
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
onSelect(option.name);
|
onSelect(option);
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
}}
|
}}
|
||||||
className="ml-2 flex-1 overflow-hidden overflow-ellipsis whitespace-nowrap py-3"
|
className="ml-2 flex-1 overflow-hidden overflow-ellipsis whitespace-nowrap py-3"
|
||||||
>
|
>
|
||||||
{option.name}
|
{option.name}
|
||||||
</span>
|
</span>
|
||||||
{showDelete && option.type === 'private' && (
|
|
||||||
<button onClick={() => onDelete(option.name)} className="p-2">
|
|
||||||
{/* Icon or text for delete button */}
|
|
||||||
Delete
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ export function fetchAnswerApi(
|
|||||||
selectedDocs: Doc,
|
selectedDocs: Doc,
|
||||||
history: Array<any> = [],
|
history: Array<any> = [],
|
||||||
conversationId: string | null,
|
conversationId: string | null,
|
||||||
|
promptId: string | null,
|
||||||
): Promise<
|
): Promise<
|
||||||
| {
|
| {
|
||||||
result: any;
|
result: any;
|
||||||
@@ -62,6 +63,7 @@ export function fetchAnswerApi(
|
|||||||
history: history,
|
history: history,
|
||||||
active_docs: docPath,
|
active_docs: docPath,
|
||||||
conversation_id: conversationId,
|
conversation_id: conversationId,
|
||||||
|
prompt_id: promptId,
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
@@ -89,6 +91,7 @@ export function fetchAnswerSteaming(
|
|||||||
selectedDocs: Doc,
|
selectedDocs: Doc,
|
||||||
history: Array<any> = [],
|
history: Array<any> = [],
|
||||||
conversationId: string | null,
|
conversationId: string | null,
|
||||||
|
promptId: string | null,
|
||||||
onEvent: (event: MessageEvent) => void,
|
onEvent: (event: MessageEvent) => void,
|
||||||
): Promise<Answer> {
|
): Promise<Answer> {
|
||||||
let namePath = selectedDocs.name;
|
let namePath = selectedDocs.name;
|
||||||
@@ -123,6 +126,7 @@ export function fetchAnswerSteaming(
|
|||||||
active_docs: docPath,
|
active_docs: docPath,
|
||||||
history: JSON.stringify(history),
|
history: JSON.stringify(history),
|
||||||
conversation_id: conversationId,
|
conversation_id: conversationId,
|
||||||
|
prompt_id: promptId,
|
||||||
};
|
};
|
||||||
|
|
||||||
fetch(apiHost + '/stream', {
|
fetch(apiHost + '/stream', {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export const fetchAnswer = createAsyncThunk<Answer, { question: string }>(
|
|||||||
state.preference.selectedDocs!,
|
state.preference.selectedDocs!,
|
||||||
state.conversation.queries,
|
state.conversation.queries,
|
||||||
state.conversation.conversationId,
|
state.conversation.conversationId,
|
||||||
|
state.preference.prompt.id,
|
||||||
(event) => {
|
(event) => {
|
||||||
const data = JSON.parse(event.data);
|
const data = JSON.parse(event.data);
|
||||||
|
|
||||||
@@ -81,6 +82,7 @@ export const fetchAnswer = createAsyncThunk<Answer, { question: string }>(
|
|||||||
state.preference.selectedDocs!,
|
state.preference.selectedDocs!,
|
||||||
state.conversation.queries,
|
state.conversation.queries,
|
||||||
state.conversation.conversationId,
|
state.conversation.conversationId,
|
||||||
|
state.preference.prompt.id,
|
||||||
);
|
);
|
||||||
if (answer) {
|
if (answer) {
|
||||||
let sourcesPrepped = [];
|
let sourcesPrepped = [];
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { RootState } from '../store';
|
|||||||
|
|
||||||
interface Preference {
|
interface Preference {
|
||||||
apiKey: string;
|
apiKey: string;
|
||||||
prompt: { name: string; id: string };
|
prompt: { name: string; id: string; type: 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;
|
||||||
@@ -16,7 +16,7 @@ interface Preference {
|
|||||||
|
|
||||||
const initialState: Preference = {
|
const initialState: Preference = {
|
||||||
apiKey: 'xxx',
|
apiKey: 'xxx',
|
||||||
prompt: { name: 'default', id: 'default' },
|
prompt: { name: 'default', id: 'default', type: 'public' },
|
||||||
selectedDocs: {
|
selectedDocs: {
|
||||||
name: 'default',
|
name: 'default',
|
||||||
language: 'default',
|
language: 'default',
|
||||||
|
|||||||
@@ -13,7 +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' },
|
prompt: { name: 'default', id: 'default', type: 'private' },
|
||||||
conversations: null,
|
conversations: null,
|
||||||
sourceDocs: [
|
sourceDocs: [
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in new issue
Block a user