From 267cfb621efe031636824fae83bdd82d3284e5f9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Mar 2024 10:25:02 +0000 Subject: [PATCH 01/32] Bump express from 4.18.2 to 4.19.2 in /mock-backend Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2. - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/master/History.md) - [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2) --- updated-dependencies: - dependency-name: express dependency-type: indirect ... Signed-off-by: dependabot[bot] --- mock-backend/package-lock.json | 53 +++++----------------------------- 1 file changed, 8 insertions(+), 45 deletions(-) diff --git a/mock-backend/package-lock.json b/mock-backend/package-lock.json index 2d070b7..2407342 100644 --- a/mock-backend/package-lock.json +++ b/mock-backend/package-lock.json @@ -357,9 +357,9 @@ } }, "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "engines": { "node": ">= 0.6" } @@ -458,16 +458,16 @@ } }, "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.1", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -515,43 +515,6 @@ "isarray": "0.0.1" } }, - "node_modules/express/node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/express/node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", From afecae37865962516cde1fc631dae94532552350 Mon Sep 17 00:00:00 2001 From: sarfaraz siddiqui Date: Sun, 31 Mar 2024 03:50:11 +0530 Subject: [PATCH 02/32] added feature #887 --- application/api/answer/routes.py | 4 +++- frontend/src/components/SourceDropdown.tsx | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/application/api/answer/routes.py b/application/api/answer/routes.py index bd1fa21..b122eac 100644 --- a/application/api/answer/routes.py +++ b/application/api/answer/routes.py @@ -207,7 +207,9 @@ def stream(): prompt_id = data["prompt_id"] else: prompt_id = 'default' - if 'chunks' in data: + if 'selectedDocs' in data and data['selectedDocs'] is None: + chunks = 0 + elif 'chunks' in data: chunks = int(data["chunks"]) else: chunks = 2 diff --git a/frontend/src/components/SourceDropdown.tsx b/frontend/src/components/SourceDropdown.tsx index 04b95d7..353d49d 100644 --- a/frontend/src/components/SourceDropdown.tsx +++ b/frontend/src/components/SourceDropdown.tsx @@ -24,6 +24,12 @@ function SourceDropdown({ const embeddingsName = import.meta.env.VITE_EMBEDDINGS_NAME || 'huggingface_sentence-transformers/all-mpnet-base-v2'; + + const handleEmptyDocumentSelect = () => { + dispatch(setSelectedDocs(null)); + setIsDocsListOpen(false); + }; + return (
)} From 02d4f7f2da3bf3974fd54aa0b74045dd8e617dfd Mon Sep 17 00:00:00 2001 From: sarfaraz siddiqui Date: Wed, 3 Apr 2024 18:08:46 +0530 Subject: [PATCH 03/32] functions can accept null --- frontend/src/conversation/conversationApi.ts | 113 ++++++++++--------- 1 file changed, 59 insertions(+), 54 deletions(-) diff --git a/frontend/src/conversation/conversationApi.ts b/frontend/src/conversation/conversationApi.ts index e586366..e3a8219 100644 --- a/frontend/src/conversation/conversationApi.ts +++ b/frontend/src/conversation/conversationApi.ts @@ -6,7 +6,7 @@ const apiHost = import.meta.env.VITE_API_HOST || 'https://docsapi.arc53.com'; export function fetchAnswerApi( question: string, signal: AbortSignal, - selectedDocs: Doc, + selectedDocs: Doc | null, history: Array = [], conversationId: string | null, promptId: string | null, @@ -28,24 +28,26 @@ export function fetchAnswerApi( title: any; } > { - let namePath = selectedDocs.name; - if (selectedDocs.language === namePath) { - namePath = '.project'; - } - let docPath = 'default'; - if (selectedDocs.location === 'local') { - docPath = 'local' + '/' + selectedDocs.name + '/'; - } else if (selectedDocs.location === 'remote') { - docPath = - selectedDocs.language + - '/' + - namePath + - '/' + - selectedDocs.version + - '/' + - selectedDocs.model + - '/'; + + if (selectedDocs) { + let namePath = selectedDocs.name; + if (selectedDocs.language === namePath) { + namePath = '.project'; + } + if (selectedDocs.location === 'local') { + docPath = 'local' + '/' + selectedDocs.name + '/'; + } else if (selectedDocs.location === 'remote') { + docPath = + selectedDocs.language + + '/' + + namePath + + '/' + + selectedDocs.version + + '/' + + selectedDocs.model + + '/'; + } } //in history array remove all keys except prompt and response history = history.map((item) => { @@ -89,31 +91,33 @@ export function fetchAnswerApi( export function fetchAnswerSteaming( question: string, signal: AbortSignal, - selectedDocs: Doc, + selectedDocs: Doc | null, history: Array = [], conversationId: string | null, promptId: string | null, chunks: string, onEvent: (event: MessageEvent) => void, ): Promise { - let namePath = selectedDocs.name; - if (selectedDocs.language === namePath) { - namePath = '.project'; - } - let docPath = 'default'; - if (selectedDocs.location === 'local') { - docPath = 'local' + '/' + selectedDocs.name + '/'; - } else if (selectedDocs.location === 'remote') { - docPath = - selectedDocs.language + - '/' + - namePath + - '/' + - selectedDocs.version + - '/' + - selectedDocs.model + - '/'; + + if (selectedDocs) { + let namePath = selectedDocs.name; + if (selectedDocs.language === namePath) { + namePath = '.project'; + } + if (selectedDocs.location === 'local') { + docPath = 'local' + '/' + selectedDocs.name + '/'; + } else if (selectedDocs.location === 'remote') { + docPath = + selectedDocs.language + + '/' + + namePath + + '/' + + selectedDocs.version + + '/' + + selectedDocs.model + + '/'; + } } history = history.map((item) => { @@ -186,7 +190,7 @@ export function fetchAnswerSteaming( } export function searchEndpoint( question: string, - selectedDocs: Doc, + selectedDocs: Doc | null, conversation_id: string | null, history: Array = [], chunks: string, @@ -196,24 +200,25 @@ export function searchEndpoint( "question": "Summarise", "conversation_id": null, "history": "[]" */ - let namePath = selectedDocs.name; - if (selectedDocs.language === namePath) { - namePath = '.project'; - } - let docPath = 'default'; - if (selectedDocs.location === 'local') { - docPath = 'local' + '/' + selectedDocs.name + '/'; - } else if (selectedDocs.location === 'remote') { - docPath = - selectedDocs.language + - '/' + - namePath + - '/' + - selectedDocs.version + - '/' + - selectedDocs.model + - '/'; + if (selectedDocs) { + let namePath = selectedDocs.name; + if (selectedDocs.language === namePath) { + namePath = '.project'; + } + if (selectedDocs.location === 'local') { + docPath = 'local' + '/' + selectedDocs.name + '/'; + } else if (selectedDocs.location === 'remote') { + docPath = + selectedDocs.language + + '/' + + namePath + + '/' + + selectedDocs.version + + '/' + + selectedDocs.model + + '/'; + } } const body = { From ac994d307733a88f404221d6f93f838033804dfd Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Wed, 3 Apr 2024 19:19:53 +0530 Subject: [PATCH 04/32] add prompt,chunks in create key --- frontend/src/Setting.tsx | 80 ++++++++++++++++++++++++++-- frontend/src/components/Dropdown.tsx | 32 +++++------ frontend/src/upload/Upload.tsx | 1 + 3 files changed, 90 insertions(+), 23 deletions(-) diff --git a/frontend/src/Setting.tsx b/frontend/src/Setting.tsx index 172691a..46c64ca 100644 --- a/frontend/src/Setting.tsx +++ b/frontend/src/Setting.tsx @@ -205,6 +205,7 @@ const General: React.FC = () => {

Select Theme

{ @@ -218,6 +219,7 @@ const General: React.FC = () => { Select Language

{ Chunks processed per query

dispatch(setChunks(value))} @@ -677,7 +680,13 @@ const APIKeys: React.FC = () => { console.log(error); } }; - const createAPIKey = (payload: { name: string; source: string }) => { + + const createAPIKey = (payload: { + name: string; + source: string; + prompt_id: string; + chunks: string; + }) => { fetch(`${apiHost}/api/create_api_key`, { method: 'POST', headers: { @@ -808,7 +817,12 @@ const SaveAPIKeyModal: React.FC = ({ apiKey, close }) => { type CreateAPIKeyModalProps = { close: () => void; - createAPIKey: (payload: { name: string; source: string }) => void; + createAPIKey: (payload: { + name: string; + source: string; + prompt_id: string; + chunks: string; + }) => void; }; const CreateAPIKeyModal: React.FC = ({ close, @@ -819,7 +833,33 @@ const CreateAPIKeyModal: React.FC = ({ label: string; value: string; } | null>(null); + + const chunkOptions = ['0', '2', '4', '6', '8', '10']; + const [chunk, setChunk] = useState('2'); + const [activePrompts, setActivePrompts] = useState< + { name: string; id: string; type: string }[] + >([]); + const [prompt, setPrompt] = useState<{ + name: string; + id: string; + type: string; + } | null>(null); const docs = useSelector(selectSourceDocs); + 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(); + setActivePrompts(promptsData); + } catch (error) { + console.error(error); + } + }; + fetchPrompts(); + }, []); const extractDocPaths = () => docs ? docs @@ -872,7 +912,7 @@ const CreateAPIKeyModal: React.FC = ({
@@ -881,11 +921,41 @@ const CreateAPIKeyModal: React.FC = ({ options={extractDocPaths()} />
+ +
+ + setPrompt(value) + } + /> +
+
+

+ Chunks processed per query +

+ setChunk(value)} + /> +
+ + + + ); +} + +function EditPrompt({ + setModalState, + handleEditPrompt, + editPromptName, + setEditPromptName, + editPromptContent, + setEditPromptContent, + currentPromptEdit, +}: { + setModalState: (state: ActiveState) => void; + handleEditPrompt?: (id: string, type: string) => void; + editPromptName: string; + setEditPromptName: (name: string) => void; + editPromptContent: string; + setEditPromptContent: (content: string) => void; + currentPromptEdit: { name: string; id: string; type: string }; +}) { + return ( +
+

Edit Prompt

+

+ Edit your custom prompt and save it to DocsGPT. +

+
+ setEditPromptName(e.target.value)} + > +
+ + Prompt Name + +
+
+ + Prompt Text + +
+ +
+
+ + +
+
+ ); +} + +export default function PromptsModal({ + modalState, + setModalState, + type, + newPromptName, + setNewPromptName, + newPromptContent, + setNewPromptContent, + editPromptName, + setEditPromptName, + editPromptContent, + setEditPromptContent, + currentPromptEdit, + handleAddPrompt, + handleEditPrompt, +}: { + modalState: ActiveState; + setModalState: (state: ActiveState) => void; + type: 'ADD' | 'EDIT'; + newPromptName: string; + setNewPromptName: (name: string) => void; + newPromptContent: string; + setNewPromptContent: (content: string) => void; + editPromptName: string; + setEditPromptName: (name: string) => void; + editPromptContent: string; + setEditPromptContent: (content: string) => void; + currentPromptEdit: { name: string; id: string; type: string }; + handleAddPrompt?: () => void; + handleEditPrompt?: (id: string, type: string) => void; +}) { + let view; + + if (type === 'ADD') { + view = ( + + ); + } else if (type === 'EDIT') { + view = ( + + ); + } else { + view = <>; + } + return ( +
+
+ {view} +
+
+ ); +} diff --git a/frontend/src/upload/Upload.tsx b/frontend/src/upload/Upload.tsx index 45fc4e1..15ae206 100644 --- a/frontend/src/upload/Upload.tsx +++ b/frontend/src/upload/Upload.tsx @@ -307,6 +307,8 @@ export default function Upload({ onSelect={(value: { label: string; value: string }) => setUrlType(value) } + size="w-full" + rounded="3xl" /> {urlType.label !== 'Reddit' ? ( <> From 9cadd74a96340f6823feb1f23fe17ca9a1fce8e6 Mon Sep 17 00:00:00 2001 From: Siddhant Rai Date: Thu, 4 Apr 2024 13:42:32 +0530 Subject: [PATCH 07/32] fix: minor ui changes --- frontend/src/Setting.tsx | 2 +- frontend/src/components/Dropdown.tsx | 20 ++++++++++++++------ frontend/src/preferences/PromptsModal.tsx | 8 ++++---- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/frontend/src/Setting.tsx b/frontend/src/Setting.tsx index 26c8701..7834ae2 100644 --- a/frontend/src/Setting.tsx +++ b/frontend/src/Setting.tsx @@ -281,6 +281,7 @@ const Prompts: React.FC = ({ ...prompts, { name: newPromptName, id: newPrompt.id, type: 'private' }, ]); + setModalState('INACTIVE'); } onSelectPrompt(newPromptName, newPrompt.id, newPromptContent); setNewPromptName(newPromptName); @@ -305,7 +306,6 @@ const Prompts: React.FC = ({ // 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) => { diff --git a/frontend/src/components/Dropdown.tsx b/frontend/src/components/Dropdown.tsx index f14df98..5c22de2 100644 --- a/frontend/src/components/Dropdown.tsx +++ b/frontend/src/components/Dropdown.tsx @@ -76,7 +76,7 @@ function Dropdown({ /> {isOpen && ( -
+
{options.map((option: any, index) => (
)} {showDelete && onDelete && ( - Delete onDelete(option.id)} - /> + disabled={option.type === 'public'} + > + Delete + )}
))} diff --git a/frontend/src/preferences/PromptsModal.tsx b/frontend/src/preferences/PromptsModal.tsx index ce0ecb4..596c9f5 100644 --- a/frontend/src/preferences/PromptsModal.tsx +++ b/frontend/src/preferences/PromptsModal.tsx @@ -48,7 +48,7 @@ function AddPrompt({
@@ -86,7 +86,7 @@ function EditPrompt({

Edit Prompt

- Edit your custom prompt and save it to DocsGPT. + Edit your custom prompt and save it to DocsGPT

-
-
- {tabs.map((tab, index) => ( - - ))} -
-
- -
-
- {renderActiveTab()} - - {/* {activeTab === 'Widgets' && ( - - )} */} -
- ); - - function scrollTabs(direction: number) { - const container = document.querySelector('.flex-nowrap'); - if (container) { - container.scrollLeft += direction * 100; // Adjust the scroll amount as needed - } - } - - function renderActiveTab() { - switch (activeTab) { - case 'General': - return ; - case 'Documents': - return ( - - ); - case 'Widgets': - return ( - - ); - case 'API Keys': - return ; - default: - return null; - } - } -}; - -const General: React.FC = () => { - const themes = ['Light', 'Dark']; - const languages = ['English']; - const chunks = ['0', '2', '4', '6', '8', '10']; - const [prompts, setPrompts] = useState< - { name: string; id: string; type: string }[] - >([]); - const selectedChunks = useSelector(selectChunks); - const [isDarkTheme, toggleTheme] = useDarkTheme(); - const [selectedTheme, setSelectedTheme] = useState( - isDarkTheme ? 'Dark' : 'Light', - ); - const dispatch = useDispatch(); - const [selectedLanguage, setSelectedLanguage] = useState(languages[0]); - const selectedPrompt = useSelector(selectPrompt); - const apiHost = import.meta.env.VITE_API_HOST || 'https://docsapi.arc53.com'; - - 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(); - }, []); - return ( -
-
-

Select Theme

- { - setSelectedTheme(option); - option !== selectedTheme && toggleTheme(); - }} - size="w-56" - rounded="3xl" - /> -
-
-

- Select Language -

- -
-
-

- Chunks processed per query -

- dispatch(setChunks(value))} - size="w-56" - rounded="3xl" - /> -
-
- - dispatch(setPrompt({ name: name, id: id, type: type })) - } - setPrompts={setPrompts} - apiHost={apiHost} - /> -
-
- ); -}; - -export default Setting; - -const Prompts: React.FC = ({ - prompts, - selectedPrompt, - onSelectPrompt, - setPrompts, -}) => { - const handleSelectPrompt = ({ - name, - id, - type, - }: { - name: string; - id: string; - type: string; - }) => { - setEditPromptName(name); - onSelectPrompt(name, id, type); - }; - const [newPromptName, setNewPromptName] = useState(''); - const [newPromptContent, setNewPromptContent] = useState(''); - const [editPromptName, setEditPromptName] = useState(''); - const [editPromptContent, setEditPromptContent] = useState(''); - const [currentPromptEdit, setCurrentPromptEdit] = useState({ - id: '', - name: '', - type: '', - }); - const [modalType, setModalType] = useState<'ADD' | 'EDIT'>('ADD'); - const [modalState, setModalState] = useState('INACTIVE'); - - const handleAddPrompt = async () => { - try { - const response = await fetch(`${apiHost}/api/create_prompt`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - 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' }, - ]); - } - setModalState('INACTIVE'); - onSelectPrompt(newPromptName, newPrompt.id, newPromptContent); - setNewPromptName(newPromptName); - } catch (error) { - console.error(error); - } - }; - - const handleDeletePrompt = (id: string) => { - setPrompts(prompts.filter((prompt) => prompt.id !== id)); - fetch(`${apiHost}/api/delete_prompt`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ id: 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); - } - }) - .catch((error) => { - console.error(error); - }); - }; - - const fetchPromptContent = async (id: string) => { - console.log('fetching prompt content'); - try { - const response = await fetch( - `${apiHost}/api/get_single_prompt?id=${id}`, - { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - }, - }, - ); - if (!response.ok) { - throw new Error('Failed to fetch prompt content'); - } - const promptContent = await response.json(); - setEditPromptContent(promptContent.content); - } catch (error) { - console.error(error); - } - }; - - const handleSaveChanges = (id: string, type: string) => { - fetch(`${apiHost}/api/update_prompt`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - id: id, - name: editPromptName, - content: editPromptContent, - }), - }) - .then((response) => { - if (!response.ok) { - throw new Error('Failed to update prompt'); - } - if (setPrompts) { - const existingPromptIndex = prompts.findIndex( - (prompt) => prompt.id === id, - ); - if (existingPromptIndex === -1) { - setPrompts([ - ...prompts, - { name: editPromptName, id: id, type: type }, - ]); - } else { - const updatedPrompts = [...prompts]; - updatedPrompts[existingPromptIndex] = { - name: editPromptName, - id: id, - type: type, - }; - setPrompts(updatedPrompts); - } - } - setModalState('INACTIVE'); - onSelectPrompt(editPromptName, id, type); - }) - .catch((error) => { - console.error(error); - }); - }; - - return ( - <> -
-
-
-

Active Prompt

- { - setModalType('EDIT'); - setEditPromptName(name); - fetchPromptContent(id); - setCurrentPromptEdit({ id: id, name: name, type: type }); - setModalState('ACTIVE'); - }} - onDelete={handleDeletePrompt} - /> -
- -
-
- - - ); -}; - -type AddPromptModalProps = { - newPromptName: string; - onNewPromptNameChange: (name: string) => void; - onAddPrompt: () => void; - onClose: () => void; -}; - -const AddPromptModal: React.FC = ({ - newPromptName, - onNewPromptNameChange, - onAddPrompt, - onClose, -}) => { - return ( -
-
-

Add New Prompt

- onNewPromptNameChange(e.target.value)} - className="mb-4 w-full rounded-3xl border-2 p-2 dark:border-chinese-silver" - /> - - -
-
- ); -}; -type DocumentsProps = { - documents: Doc[] | null; - handleDeleteDocument: (index: number, document: Doc) => void; -}; - -const Documents: React.FC = ({ - documents, - handleDeleteDocument, -}) => { - return ( -
-
-
- - - - - - - - - - - {documents && - documents.map((document, index) => ( - - - - - - - ))} - -
Document NameVector DateType
- {document.name} - - {document.date} - - {document.location === 'remote' - ? 'Pre-loaded' - : 'Private'} - - {document.location !== 'remote' && ( - Delete { - event.stopPropagation(); - handleDeleteDocument(index, document); - }} - /> - )} -
-
- {/* */} -
- - {/* {isAddDocumentModalOpen && ( - - )} */} -
- ); -}; - -type Document = { - name: string; - vectorDate: string; - vectorLocation: string; -}; - -// Modal for adding a new document -type AddDocumentModalProps = { - newDocument: Document; - onNewDocumentChange: (document: Document) => void; - onAddDocument: () => void; - onClose: () => void; -}; - -const AddDocumentModal: React.FC = ({ - newDocument, - onNewDocumentChange, - onAddDocument, - onClose, -}) => { - return ( -
-
-

Add New Document

- - onNewDocumentChange({ ...newDocument, name: e.target.value }) - } - className="mb-4 w-full rounded-lg border-2 p-2" - /> - - onNewDocumentChange({ ...newDocument, vectorDate: e.target.value }) - } - className="mb-4 w-full rounded-lg border-2 p-2" - /> - - onNewDocumentChange({ - ...newDocument, - vectorLocation: e.target.value, - }) - } - className="mb-4 w-full rounded-lg border-2 p-2" - /> - - -
-
- ); -}; -const APIKeys: React.FC = () => { - const [isCreateModalOpen, setCreateModal] = useState(false); - const [isSaveKeyModalOpen, setSaveKeyModal] = useState(false); - const [newKey, setNewKey] = useState(''); - const [apiKeys, setApiKeys] = useState< - { name: string; key: string; source: string; id: string }[] - >([]); - const handleDeleteKey = (id: string) => { - fetch(`${apiHost}/api/delete_api_key`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ id }), - }) - .then((response) => { - if (!response.ok) { - throw new Error('Failed to delete API Key'); - } - return response.json(); - }) - .then((data) => { - data.status === 'ok' && - setApiKeys((previous) => previous.filter((elem) => elem.id !== id)); - }) - .catch((error) => { - console.error(error); - }); - }; - useEffect(() => { - fetchAPIKeys(); - }, []); - const fetchAPIKeys = async () => { - try { - const response = await fetch(`${apiHost}/api/get_api_keys`); - if (!response.ok) { - throw new Error('Failed to fetch API Keys'); - } - const apiKeys = await response.json(); - setApiKeys(apiKeys); - } catch (error) { - console.log(error); - } - }; - const createAPIKey = (payload: { name: string; source: string }) => { - fetch(`${apiHost}/api/create_api_key`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(payload), - }) - .then((response) => { - if (!response.ok) { - throw new Error('Failed to create API Key'); - } - return response.json(); - }) - .then((data) => { - setApiKeys([...apiKeys, data]); - setCreateModal(false); //close the create key modal - setNewKey(data.key); - setSaveKeyModal(true); // render the newly created key - fetchAPIKeys(); - }) - .catch((error) => { - console.error(error); - }); - }; - return ( -
-
-
- -
- {isCreateModalOpen && ( - setCreateModal(false)} - createAPIKey={createAPIKey} - /> - )} - {isSaveKeyModalOpen && ( - setSaveKeyModal(false)} - /> - )} -
-
- - - - - - - - - - - {apiKeys?.map((element, index) => ( - - - - - - - ))} - -
Name - Source document - API Key
{element.name}{element.source}{element.key} - Delete handleDeleteKey(element.id)} - /> -
-
-
-
-
- ); -}; -type SaveAPIKeyModalProps = { - apiKey: string; - close: () => void; -}; -const SaveAPIKeyModal: React.FC = ({ apiKey, close }) => { - const [isCopied, setIsCopied] = useState(false); - const handleCopyKey = () => { - navigator.clipboard.writeText(apiKey); - setIsCopied(true); - }; - return ( -
-
- -

Please save your Key

-

- This is the only time your key will be shown. -

-
-
-

API Key

- {apiKey} -
- -
- -
-
- ); -}; - -type CreateAPIKeyModalProps = { - close: () => void; - createAPIKey: (payload: { name: string; source: string }) => void; -}; -const CreateAPIKeyModal: React.FC = ({ - close, - createAPIKey, -}) => { - const [APIKeyName, setAPIKeyName] = useState(''); - const [sourcePath, setSourcePath] = useState<{ - label: string; - value: string; - } | null>(null); - const docs = useSelector(selectSourceDocs); - const extractDocPaths = () => - docs - ? docs - .filter((doc) => doc.model === embeddingsName) - .map((doc: Doc) => { - let namePath = doc.name; - if (doc.language === namePath) { - namePath = '.project'; - } - let docPath = 'default'; - if (doc.location === 'local') { - docPath = 'local' + '/' + doc.name + '/'; - } else if (doc.location === 'remote') { - docPath = - doc.language + - '/' + - namePath + - '/' + - doc.version + - '/' + - doc.model + - '/'; - } - return { - label: doc.name, - value: docPath, - }; - }) - : []; - - return ( -
-
- - - Create New API Key - -
- - API Key Name - - setAPIKeyName(e.target.value)} - /> -
-
- - setSourcePath(selection) - } - options={extractDocPaths()} - /> -
- -
-
- ); -}; -const Widgets: React.FC<{ - widgetScreenshot: File | null; - onWidgetScreenshotChange: (screenshot: File | null) => void; -}> = ({ widgetScreenshot, onWidgetScreenshotChange }) => { - const widgetSources = ['Source 1', 'Source 2', 'Source 3']; - const widgetMethods = ['Method 1', 'Method 2', 'Method 3']; - const widgetTypes = ['Type 1', 'Type 2', 'Type 3']; - - const [selectedWidgetSource, setSelectedWidgetSource] = useState( - widgetSources[0], - ); - const [selectedWidgetMethod, setSelectedWidgetMethod] = useState( - widgetMethods[0], - ); - const [selectedWidgetType, setSelectedWidgetType] = useState(widgetTypes[0]); - - // const [widgetScreenshot, setWidgetScreenshot] = useState(null); - const [widgetCode, setWidgetCode] = useState(''); // Your widget code state - - const handleScreenshotChange = ( - event: React.ChangeEvent, - ) => { - const files = event.target.files; - - if (files && files.length > 0) { - const selectedScreenshot = files[0]; - onWidgetScreenshotChange(selectedScreenshot); // Update the screenshot in the parent component - } - }; - - const handleCopyToClipboard = () => { - // Create a new textarea element to select the text - const textArea = document.createElement('textarea'); - textArea.value = widgetCode; - document.body.appendChild(textArea); - - // Select and copy the text - textArea.select(); - document.execCommand('copy'); - - // Clean up the textarea element - document.body.removeChild(textArea); - }; - - return ( -
-
-

Widget Source

- -
-
-

Widget Method

- -
-
-

Widget Type

- -
-
-

Widget Code Snippet

-
-
- - Prompt Text - +
+
- -
-
- -
); @@ -83,58 +88,62 @@ function EditPrompt({ currentPromptEdit: { name: string; id: string; type: string }; }) { return ( -
-

Edit Prompt

-

- Edit your custom prompt and save it to DocsGPT -

-
- setEditPromptName(e.target.value)} - > -
- - Prompt Name - +
+ +
+

+ Edit Prompt +

+

+ Edit your custom prompt and save it to DocsGPT +

+
+ setEditPromptName(e.target.value)} + > +
+ + Prompt Name + +
+
+ + Prompt Text + +
+
-
- - Prompt Text - +
+
- -
-
- -
); @@ -205,7 +214,7 @@ export default function PromptsModal({ modalState === 'ACTIVE' ? 'visible' : 'hidden' } fixed top-0 left-0 z-30 h-screen w-screen bg-gray-alpha`} > -
+
{view}
diff --git a/frontend/src/settings/APIKeys.tsx b/frontend/src/settings/APIKeys.tsx index 05c21ab..a043272 100644 --- a/frontend/src/settings/APIKeys.tsx +++ b/frontend/src/settings/APIKeys.tsx @@ -59,7 +59,12 @@ const APIKeys: React.FC = () => { console.log(error); } }; - const createAPIKey = (payload: { name: string; source: string }) => { + const createAPIKey = (payload: { + name: string; + source: string; + prompt_id: string; + chunks: string; + }) => { fetch(`${apiHost}/api/create_api_key`, { method: 'POST', headers: { @@ -75,9 +80,9 @@ const APIKeys: React.FC = () => { }) .then((data) => { setApiKeys([...apiKeys, data]); - setCreateModal(false); //close the create key modal + setCreateModal(false); setNewKey(data.key); - setSaveKeyModal(true); // render the newly created key + setSaveKeyModal(true); fetchAPIKeys(); }) .catch((error) => { @@ -90,9 +95,9 @@ const APIKeys: React.FC = () => {
{isCreateModalOpen && ( @@ -155,7 +160,33 @@ const CreateAPIKeyModal: React.FC = ({ label: string; value: string; } | null>(null); + + const chunkOptions = ['0', '2', '4', '6', '8', '10']; + const [chunk, setChunk] = React.useState('2'); + const [activePrompts, setActivePrompts] = React.useState< + { name: string; id: string; type: string }[] + >([]); + const [prompt, setPrompt] = React.useState<{ + name: string; + id: string; + type: string; + } | null>(null); const docs = useSelector(selectSourceDocs); + React.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(); + setActivePrompts(promptsData); + } catch (error) { + console.error(error); + } + }; + fetchPrompts(); + }, []); const extractDocPaths = () => docs ? docs @@ -188,14 +219,14 @@ const CreateAPIKeyModal: React.FC = ({ return (
-
- - + Create New API Key -
+
API Key Name @@ -208,21 +239,51 @@ const CreateAPIKeyModal: React.FC = ({
setSourcePath(selection) } options={extractDocPaths()} + size="w-full" + rounded="xl" + /> +
+
+ + setPrompt(value) + } + size="w-full" + /> +
+
+

+ Chunks processed per query +

+ setChunk(value)} + size="w-full" />
@@ -239,8 +300,8 @@ const SaveAPIKeyModal: React.FC = ({ apiKey, close }) => { }; return (
-
-

Please save your Key

@@ -253,7 +314,7 @@ const SaveAPIKeyModal: React.FC = ({ apiKey, close }) => { {apiKey}
@@ -130,7 +130,7 @@ function EditPrompt({
@@ -450,4 +450,3 @@ export default function Upload({ ); } -// TODO: sanitize all inputs From 00b663915537c12bc1464ca070c2de48e9dba4e9 Mon Sep 17 00:00:00 2001 From: Siddhant Rai Date: Wed, 10 Apr 2024 12:37:29 +0530 Subject: [PATCH 31/32] fix: minor ui changes --- frontend/src/settings/APIKeys.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/frontend/src/settings/APIKeys.tsx b/frontend/src/settings/APIKeys.tsx index a043272..7803ff4 100644 --- a/frontend/src/settings/APIKeys.tsx +++ b/frontend/src/settings/APIKeys.tsx @@ -219,13 +219,15 @@ const CreateAPIKeyModal: React.FC = ({ return (
-
+
- - Create New API Key - +
+ + Create New API Key + +
API Key Name From 19bb1b4aa46025533a1f8df8cc10eeb6a0208092 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 12 Apr 2024 09:39:33 +0100 Subject: [PATCH 32/32] Create SECURITY.md --- SECURITY.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..ba034aa --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,14 @@ +# Security Policy + +## Supported Versions + +Supported Versions: + +Currently, we support security patches by committing changes and bumping the version published on Github. + +## Reporting a Vulnerability + +Found a vulnerability? Please email us: + +security@arc53.com +