From 54fb400d9132ebe996b07f3b18795141490ff940 Mon Sep 17 00:00:00 2001 From: rex993 <6278392+rex993@users.noreply.github.com> Date: Fri, 18 Apr 2025 17:28:39 +1000 Subject: [PATCH 1/2] Set LiteLLM logging level (#758) ## Description LiteLLM adds the debugging lines: LiteLLM:INFO to the output when running and can flood the output making actual cognee debugging difficult. This .env config will suppress logging to ERROR level only. Note there is an open bug with LiteLLM here [https://github.com/BerriAI/litellm/issues/9815](https://github.com/BerriAI/litellm/issues/9815) as 'cost calculation' lines will still be shown despite ERROR level logging ## DCO Affirmation I affirm that all code in every commit of this pull request conforms to the terms of the Topoteretes Developer Certificate of Origin. Co-authored-by: rex --- .env.template | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.env.template b/.env.template index ba7126182..da862f285 100644 --- a/.env.template +++ b/.env.template @@ -62,3 +62,6 @@ DB_NAME=cognee_db # MIGRATION_DB_PASSWORD=cognee # MIGRATION_DB_HOST="127.0.0.1" # MIGRATION_DB_PORT=5432 + +# LITELLM Logging Level. Set to quiten down logging +LITELLM_LOG="ERROR" From 751eca7aafe1630aedcf1bbc2234c900f110fd57 Mon Sep 17 00:00:00 2001 From: Boris Date: Fri, 18 Apr 2025 15:23:51 +0200 Subject: [PATCH 2/2] fix: cognee ui with new visualization (#733) ## Description ## DCO Affirmation I affirm that all code in every commit of this pull request conforms to the terms of the Topoteretes Developer Certificate of Origin. --------- Co-authored-by: Igor Ilic <30923996+dexters1@users.noreply.github.com> --- cognee-frontend/src/app/auth/AuthPage.tsx | 4 +- cognee-frontend/src/app/favicon.ico | Bin 25931 -> 169254 bytes cognee-frontend/src/app/favicon.png | Bin 0 -> 3119 bytes cognee-frontend/src/app/globals.css | 6 + cognee-frontend/src/app/page.module.css | 2 +- cognee-frontend/src/app/page.tsx | 4 +- .../src/app/wizard/AddStep/AddStep.tsx | 2 +- cognee-frontend/src/app/wizard/WizardPage.tsx | 4 +- .../exploration/getExplorationGraphUrl.ts | 5 +- .../src/modules/ingestion/addData.ts | 9 +- .../CognifyLoadingIndicator.module.css | 8 +- cognee-frontend/src/ui/App/Logo/Logo.tsx | 13 --- cognee-frontend/src/ui/App/Logo/TextLogo.tsx | 7 ++ .../src/ui/App/Logo/TextLogo.v1.tsx | 14 --- .../src/ui/App/Logo/TextLogo.v2.tsx | 29 ----- cognee-frontend/src/ui/App/index.ts | 3 +- .../src/ui/Layout/Divider/Divider.module.css | 2 +- .../src/ui/Partials/Explorer/Explorer.tsx | 16 +-- .../src/ui/Partials/Footer/Footer.tsx | 4 +- .../src/ui/Partials/SearchView/SearchView.tsx | 14 ++- .../ui/Partials/SettingsModal/Settings.tsx | 105 ++++++++---------- .../src/ui/Partials/SignInForm/SignInForm.tsx | 4 +- .../WizardContent/WizardContent.module.css | 2 +- cognee/api/v1/add/routers/get_add_router.py | 19 +++- cognee/api/v1/datasets/datasets.py | 3 +- .../datasets/routers/get_datasets_router.py | 22 ++-- .../v1/users/routers/get_visualize_router.py | 13 +-- cognee/modules/settings/get_settings.py | 36 +++--- .../modules/settings/save_vector_db_config.py | 4 +- .../methods/check_permission_on_documents.py | 2 +- docker-compose.yml | 65 +++++------ entrypoint.sh | 5 +- 32 files changed, 194 insertions(+), 232 deletions(-) create mode 100644 cognee-frontend/src/app/favicon.png delete mode 100644 cognee-frontend/src/ui/App/Logo/Logo.tsx create mode 100644 cognee-frontend/src/ui/App/Logo/TextLogo.tsx delete mode 100644 cognee-frontend/src/ui/App/Logo/TextLogo.v1.tsx delete mode 100644 cognee-frontend/src/ui/App/Logo/TextLogo.v2.tsx diff --git a/cognee-frontend/src/app/auth/AuthPage.tsx b/cognee-frontend/src/app/auth/AuthPage.tsx index 7b7391039..9cfb5e89f 100644 --- a/cognee-frontend/src/app/auth/AuthPage.tsx +++ b/cognee-frontend/src/app/auth/AuthPage.tsx @@ -9,9 +9,9 @@ import SignInForm from '@/ui/Partials/SignInForm/SignInForm'; export default function AuthPage() { return (
- + - + diff --git a/cognee-frontend/src/app/favicon.ico b/cognee-frontend/src/app/favicon.ico index 718d6fea4835ec2d246af9800eddb7ffb276240c..f3b120fe0f7b8c5831af123e2f003236528dcee8 100644 GIT binary patch literal 169254 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 literal 25931 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 LrJugUA?W`A8`#=m diff --git a/cognee-frontend/src/app/favicon.png b/cognee-frontend/src/app/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..90e5fa3922a669cceae0e119694dbbba9361d6ac GIT binary patch literal 3119 zcmb7`c{~(~7RSfFWqFM)WD=KKSwk@y(k0z3A3~8RL35D8iGqzc#5{QvBz{;u&Evcv5or}_ z$${eOzfs}NgP+dP;$I&AP@eZ}cP~?03(I*_8~SzD7sXwAD%MF1GfG%BOi>Lscx?PV zDyenA|Mz;MjF*|2BLWXpjVuTxq|sK@VAtgk0w72-!po9vD<-#&!qFov>cm+Ykx2sG zz9fbEClJ_o$?aP1**D#x8nJtumK!WsXju=z{(W@!s|&GS(*0ziuv%bPan8tA-LqB7 z)fekGzuM}#CJT*-NxLd&3b{d55o=;Z?XVZtoaYr(t&>nTDI&tHoafgyQA`VWg*ivu z^key!uGBnuIRfE31df((fi+SQeX{tBrk*DDY@=kLlAbgqKH_sie5tn-o(SdUBSq_5 zT*Ihk!nb*Otj~es8|2Cmu5|sKkQ1EVA0IIhqFm;eswG24I|K*C>m-e*>LmB{QidA` zE>@h!6S>6eHnS&5nbx9vEs0(Ei@p@+aO%H^P0q|2e4l?3yCKe#8U3PDz_|Az1FT)-E#48@rq^#iRv$rP$TQ>&-i|2vX>T%Cq zq(z{QZt4w*uRniXXndEIg2cwIlKkuhE)|XKEuGYPxZ+trJ+PQhhufOB86ebR8mtX> z*pZ~(lt?~*-(yp=2uXVxwR)-In-sh-OSw0vpA$$HSA^diZFaONKzstyX_lqj$`6ZA z$-CA&;Wi%Q@kOQb%BiG5Z##kYvx$bLH7xqor?R5Rk-JZn96)n-z}L*vJ?NIQkWSOy zD;kzESGO&1>tM`1xThoX%7r>?s?=|KZ(ft>$6;fCb-HCsm>3iW8Ni5#9GMMR(jc8t zKCKoB*6H&_J$F37n!cStXkzoQR+pPOq_oEeJ5MawK_b}fCkCVY^W#K~_C+g*uK)Xz z$_Dy_@yr{I?pttSZ-!{XN=~PZd6sa+FFZO!C$CLj83?86dNURVh_rppEXO$qh_9~Z zi~Yd?=8UvC)`dBLx#GawV;EttbozFG}#4YJJ}yv01aRSSTE zCBnn^yU7M39s!jLbY*)k;EWh0bt0=#WG^ks3&_}RCVP%Z6a6M(0g`x$bqC4z#KGwS zJ6R$dRLCipK3C9Pas(+yFyqlf(R^tc_58?@tqlGLBf%wLv5Gg*Jwa*6(20VbpBmr< zm9Ur@+p`?62nxXTJ`ICI#GvV%ujWr3c!Zx!Eqtf;b-yzJ==*R1F;^OlWMu98#t=dwyphY6Iijo}z z6h^8Wj(YkZl(N6@1pT36s2-a$NROicLDjr1_ek$5x}}Oo`EP+@ZnYl(*NxQ;byRb& zdwwR*kSqHeb|s<76`{5)p>c1AK@Fyg)Os_NIdhu)fv-{x6O%nw-UMB(BEdO*5{IS8nAZfx9^&?5X^PxT@Mj7l~-%jVnxGW`+TonlS~fOM|Ftn3Ujt^OMGEr@zAC+v-$yG#_h@X_kLwh{q7>QIdsrVXzYM!%<0Ip2v(13AaUY#@IyWod|nK>HP?ybZ=dKtq5D@#>wZq` zRd|DYzZLdZW}T~)JGV&pK*J<+;(OYrd9z7!m_B5A&tap zG0>LC*hDpI=*@ZNKr}Nq9q7W+)vRysa{f9{{<$mULZG?j!lbVAjtTyCdDu#(_S#8z z|9aJ`cE-f)%y`o?cE-H7=b!B%7eLsx)D6qrFOn*OqmI3AoS^tAMh7oCVGWNY=y6m0qIX?*gx(!A=%djd}XyVnpJm*nodO}y(DoVGBQ#S6!rG^c~<$pyqhW8 zK}xukmj8nt8QW!)A<6o9s()nY3z$SRQj~6K`O){9(EHY~40seM(>$Cr0@e_eJzfxK zR(Xx}$4iEfxa;;NN!YBtnCt!SDf9C0?fDeZTU|??6aHC~KR=?j!3*tR-Jb_6WRp+$ T86@uTzX!mLQJ2e%u;Kp({7R*e literal 0 HcmV?d00001 diff --git a/cognee-frontend/src/app/globals.css b/cognee-frontend/src/app/globals.css index 7179f07b6..118237db8 100644 --- a/cognee-frontend/src/app/globals.css +++ b/cognee-frontend/src/app/globals.css @@ -5,6 +5,12 @@ "Roboto Mono", "Oxygen Mono", "Ubuntu Monospace", "Source Code Pro", "Fira Mono", "Droid Sans Mono", "Courier New", monospace; + --button-padding: 14px 20px !important; + --button-border-radius: 100px !important; + --global-color-primary: #6510F4 !important; + --global-color-primary-active: #500cc5 !important; + --global-color-primary-text: white !important; + --global-color-secondary: #0DFF00 !important; --global-background-default: #0D051C; --textarea-default-color: #0D051C !important; } diff --git a/cognee-frontend/src/app/page.module.css b/cognee-frontend/src/app/page.module.css index 02878d478..696d52720 100644 --- a/cognee-frontend/src/app/page.module.css +++ b/cognee-frontend/src/app/page.module.css @@ -11,7 +11,6 @@ display: flex; flex-direction: row; flex: 1; - gap: 32px; } .datasetsView { @@ -28,6 +27,7 @@ .dataView { width: 70%; animation: grow-width 0.3s ease-in-out; + padding: 0 0 0 32px; } @keyframes grow-width { diff --git a/cognee-frontend/src/app/page.tsx b/cognee-frontend/src/app/page.tsx index e1aafe01b..3d8a04dc2 100644 --- a/cognee-frontend/src/app/page.tsx +++ b/cognee-frontend/src/app/page.tsx @@ -68,9 +68,9 @@ export default function Home() { return (
- + - + diff --git a/cognee-frontend/src/app/wizard/AddStep/AddStep.tsx b/cognee-frontend/src/app/wizard/AddStep/AddStep.tsx index f377a46e4..6052ac52c 100644 --- a/cognee-frontend/src/app/wizard/AddStep/AddStep.tsx +++ b/cognee-frontend/src/app/wizard/AddStep/AddStep.tsx @@ -21,7 +21,7 @@ export default function AddStep({ onNext }: ConfigStepProps) { const uploadFiles = useCallback(() => { disableUploading() - addData({ id: 'main' }, files) + addData({ name: 'main' }, files) .then(() => { onNext(); }) diff --git a/cognee-frontend/src/app/wizard/WizardPage.tsx b/cognee-frontend/src/app/wizard/WizardPage.tsx index 2c3aeccfd..1a9158975 100644 --- a/cognee-frontend/src/app/wizard/WizardPage.tsx +++ b/cognee-frontend/src/app/wizard/WizardPage.tsx @@ -33,9 +33,9 @@ export default function WizardPage({ return (
- + - + {wizardStep === 'explore' && ( diff --git a/cognee-frontend/src/modules/exploration/getExplorationGraphUrl.ts b/cognee-frontend/src/modules/exploration/getExplorationGraphUrl.ts index 185f16a81..080302691 100644 --- a/cognee-frontend/src/modules/exploration/getExplorationGraphUrl.ts +++ b/cognee-frontend/src/modules/exploration/getExplorationGraphUrl.ts @@ -1,13 +1,12 @@ import { fetch } from '@/utils'; export default function getExplorationGraphUrl(dataset: { id: string }) { - return fetch(`/v1/datasets/${dataset.id}/graph`) + return fetch('/v1/visualize') .then(async (response) => { if (response.status !== 200) { throw new Error((await response.text()).replaceAll("\"", "")); } return response; }) - .then((response) => response.text()) - .then((text) => text.replace('"', '')); + .then((response) => response.text()); } diff --git a/cognee-frontend/src/modules/ingestion/addData.ts b/cognee-frontend/src/modules/ingestion/addData.ts index caa280837..601c6f884 100644 --- a/cognee-frontend/src/modules/ingestion/addData.ts +++ b/cognee-frontend/src/modules/ingestion/addData.ts @@ -1,11 +1,16 @@ import { fetch } from '@/utils'; -export default function addData(dataset: { id: string }, files: File[]) { +export default function addData(dataset: { id?: string, name?: string }, files: File[]) { const formData = new FormData(); files.forEach((file) => { formData.append('data', file, file.name); }) - formData.append('datasetId', dataset.id); + if (dataset.id) { + formData.append('datasetId', dataset.id); + } + if (dataset.name) { + formData.append('datasetName', dataset.name); + } return fetch('/v1/add', { method: 'POST', diff --git a/cognee-frontend/src/ui/App/Loading/CognifyLoadingIndicator/CognifyLoadingIndicator.module.css b/cognee-frontend/src/ui/App/Loading/CognifyLoadingIndicator/CognifyLoadingIndicator.module.css index 1ce50963d..1c2388373 100644 --- a/cognee-frontend/src/ui/App/Loading/CognifyLoadingIndicator/CognifyLoadingIndicator.module.css +++ b/cognee-frontend/src/ui/App/Loading/CognifyLoadingIndicator/CognifyLoadingIndicator.module.css @@ -3,7 +3,7 @@ width: 106px; height: 106px; border-radius: 50%; - background: linear-gradient(90deg, #D82EB5 0.52%, #9245FD 103.83%); + background: linear-gradient(90deg, #6510F4 0.52%, #0DFF00 103.83%); } .donut1.spin { animation: rotate1 1s linear infinite; @@ -13,13 +13,13 @@ width: 76px; height: 76px; border-radius: 50%; - background: linear-gradient(90deg, #D82EB5 0.52%, #9245FD 103.83%); + background: linear-gradient(90deg, #6510F4 0.52%, #0DFF00 103.83%); position: relative; left: 15px; top: 15px; } .donut2.spin { - background: linear-gradient(270deg, #D82EB5 0.52%, #9245FD 103.83%); + background: linear-gradient(270deg, #6510F4 0.52%, #0DFF00 103.83%); animation: rotate1 1s linear infinite; } @@ -27,7 +27,7 @@ width: 46px; height: 46px; border-radius: 50%; - background: linear-gradient(90deg, #D82EB5 0.52%, #9245FD 103.83%); + background: linear-gradient(90deg, #6510F4 0.52%, #0DFF00 103.83%); position: relative; left: 15px; top: 15px; diff --git a/cognee-frontend/src/ui/App/Logo/Logo.tsx b/cognee-frontend/src/ui/App/Logo/Logo.tsx deleted file mode 100644 index 26dc86135..000000000 --- a/cognee-frontend/src/ui/App/Logo/Logo.tsx +++ /dev/null @@ -1,13 +0,0 @@ -export default function Logo({ width = 29, height = 32, className = '' }) { - return ( - - - - - - - - - - ); -} \ No newline at end of file diff --git a/cognee-frontend/src/ui/App/Logo/TextLogo.tsx b/cognee-frontend/src/ui/App/Logo/TextLogo.tsx new file mode 100644 index 000000000..2ea9607a0 --- /dev/null +++ b/cognee-frontend/src/ui/App/Logo/TextLogo.tsx @@ -0,0 +1,7 @@ +export default function TextLogo({ width = 158, height = 44, color = 'currentColor', className = '' }) { + return ( + + + + ); +} diff --git a/cognee-frontend/src/ui/App/Logo/TextLogo.v1.tsx b/cognee-frontend/src/ui/App/Logo/TextLogo.v1.tsx deleted file mode 100644 index 884f63d61..000000000 --- a/cognee-frontend/src/ui/App/Logo/TextLogo.v1.tsx +++ /dev/null @@ -1,14 +0,0 @@ -export default function TextLogo({ width = 160, height = 42, color = 'currentColor', className = '' }) { - return ( - - - - - - - - - - - ); -} \ No newline at end of file diff --git a/cognee-frontend/src/ui/App/Logo/TextLogo.v2.tsx b/cognee-frontend/src/ui/App/Logo/TextLogo.v2.tsx deleted file mode 100644 index e16206363..000000000 --- a/cognee-frontend/src/ui/App/Logo/TextLogo.v2.tsx +++ /dev/null @@ -1,29 +0,0 @@ -export default function TextLogo({ width = 285, height = 81, color = 'white' }) { - return ( - - - - - - - - - - - - - - - - - - - - - - - - - - ); -} \ No newline at end of file diff --git a/cognee-frontend/src/ui/App/index.ts b/cognee-frontend/src/ui/App/index.ts index d0f095694..719972a6d 100644 --- a/cognee-frontend/src/ui/App/index.ts +++ b/cognee-frontend/src/ui/App/index.ts @@ -1,4 +1,3 @@ -export { default as Logo } from './Logo/Logo'; -export { default as TextLogo } from './Logo/TextLogo.v2'; +export { default as TextLogo } from './Logo/TextLogo'; export { default as LoadingIndicator } from './Loading/DefaultLoadingIndicator/LoadingIndicator'; export { default as CognifyLoadingIndicator } from './Loading/CognifyLoadingIndicator/CognifyLoadingIndicator'; diff --git a/cognee-frontend/src/ui/Layout/Divider/Divider.module.css b/cognee-frontend/src/ui/Layout/Divider/Divider.module.css index e9e33d6f9..ec3854f3f 100644 --- a/cognee-frontend/src/ui/Layout/Divider/Divider.module.css +++ b/cognee-frontend/src/ui/Layout/Divider/Divider.module.css @@ -1,5 +1,5 @@ .divider { height: 1px; - background: linear-gradient(90deg, #D82EB5 0.52%, #9245FD 103.83%); + background: linear-gradient(90deg, #6510F4 0.52%, #0DFF00 103.83%); } diff --git a/cognee-frontend/src/ui/Partials/Explorer/Explorer.tsx b/cognee-frontend/src/ui/Partials/Explorer/Explorer.tsx index ea50a726a..8ae30c1e9 100644 --- a/cognee-frontend/src/ui/Partials/Explorer/Explorer.tsx +++ b/cognee-frontend/src/ui/Partials/Explorer/Explorer.tsx @@ -1,9 +1,9 @@ -import { useCallback, useEffect, useState } from 'react'; import classNames from 'classnames'; +import { useCallback, useEffect, useState } from 'react'; import { Spacer, Stack, Text } from 'ohmy-ui'; -import { getExplorationGraphUrl } from '@/modules/exploration'; -import { IFrameView, SearchView } from '@/ui/Partials'; import { LoadingIndicator } from '@/ui/App'; +import { IFrameView, SearchView } from '@/ui/Partials'; +import { getExplorationGraphUrl } from '@/modules/exploration'; import styles from './Explorer.module.css'; interface ExplorerProps { @@ -14,13 +14,13 @@ interface ExplorerProps { export default function Explorer({ dataset, className, style }: ExplorerProps) { const [error, setError] = useState(null); - const [graphUrl, setGraphUrl] = useState(null); + const [graphHtml, setGraphHtml] = useState(null); const exploreData = useCallback(() => { getExplorationGraphUrl(dataset) - .then((graphUrl) => { + .then((graphHtml) => { setError(null); - setGraphUrl(graphUrl); + setGraphHtml(graphHtml); }) .catch((error) => { setError(error); @@ -43,12 +43,12 @@ export default function Explorer({ dataset, className, style }: ExplorerProps) { {error.message} ) : ( <> - {!graphUrl ? ( + {!graphHtml ? ( ) : ( - + )} )} diff --git a/cognee-frontend/src/ui/Partials/Footer/Footer.tsx b/cognee-frontend/src/ui/Partials/Footer/Footer.tsx index ac74f5dc2..17b4f854e 100644 --- a/cognee-frontend/src/ui/Partials/Footer/Footer.tsx +++ b/cognee-frontend/src/ui/Partials/Footer/Footer.tsx @@ -13,10 +13,10 @@ export default function Footer() {
- + - +
diff --git a/cognee-frontend/src/ui/Partials/SearchView/SearchView.tsx b/cognee-frontend/src/ui/Partials/SearchView/SearchView.tsx index b4fa07777..8def51c00 100644 --- a/cognee-frontend/src/ui/Partials/SearchView/SearchView.tsx +++ b/cognee-frontend/src/ui/Partials/SearchView/SearchView.tsx @@ -31,11 +31,11 @@ export default function SearchView() { value: 'INSIGHTS', label: 'Query insights from documents', }, { - value: 'SUMMARIES', - label: 'Query document summaries', + value: 'GRAPH_COMPLETION', + label: 'Completion using Cognee\'s graph based memory', }, { - value: 'CHUNKS', - label: 'Query document chunks', + value: 'RAG_COMPLETION', + label: 'Completion using RAG', }]; const [searchType, setSearchType] = useState(searchOptions[0]); @@ -167,6 +167,10 @@ type InsightMessage = [Node, Relationship, Node]; function convertToSearchTypeOutput(systemMessages: any[], searchType: string): string { + if (systemMessages.length > 0 && typeof(systemMessages[0]) === "string") { + return systemMessages[0]; + } + switch (searchType) { case 'INSIGHTS': return systemMessages.map((message: InsightMessage) => { @@ -181,6 +185,6 @@ function convertToSearchTypeOutput(systemMessages: any[], searchType: string): s case 'CHUNKS': return systemMessages.map((message: { text: string }) => message.text).join('\n'); default: - return ''; + return ""; } } diff --git a/cognee-frontend/src/ui/Partials/SettingsModal/Settings.tsx b/cognee-frontend/src/ui/Partials/SettingsModal/Settings.tsx index 08574bd6b..9d8b2ff75 100644 --- a/cognee-frontend/src/ui/Partials/SettingsModal/Settings.tsx +++ b/cognee-frontend/src/ui/Partials/SettingsModal/Settings.tsx @@ -21,7 +21,11 @@ interface SelectOption { interface SettingsForm extends HTMLFormElement { vectorDBUrl: HTMLInputElement; vectorDBApiKey: HTMLInputElement; + llmProvider: HTMLInputElement; + llmModel: HTMLInputElement; llmApiKey: HTMLInputElement; + llmEndpoint: HTMLInputElement; + llmApiVersion: HTMLInputElement; } const defaultProvider = { @@ -37,18 +41,16 @@ const defaultModel = { export default function Settings({ onDone = () => {}, submitButtonText = 'Save' }) { const [llmConfig, setLLMConfig] = useState<{ apiKey: string; - model: SelectOption; - models: { - [key: string]: SelectOption[]; - }; - provider: SelectOption; - providers: SelectOption[]; + model: string; + endpoint: string; + apiVersion: string; + provider: string; }>(); const [vectorDBConfig, setVectorDBConfig] = useState<{ url: string; apiKey: string; provider: SelectOption; - options: SelectOption[]; + providers: SelectOption[]; }>(); const { @@ -68,9 +70,11 @@ export default function Settings({ onDone = () => {}, submitButtonText = 'Save' }; const newLLMConfig = { - provider: llmConfig?.provider.value, - model: llmConfig?.model.value, + provider: formElements.llmProvider.value, + model: formElements.llmModel.value, apiKey: formElements.llmApiKey.value, + endpoint: formElements.llmEndpoint.value, + apiVersion: formElements.llmApiVersion.value, }; startSaving(); @@ -96,7 +100,7 @@ export default function Settings({ onDone = () => {}, submitButtonText = 'Save' if (config?.provider !== newVectorDBProvider) { return { ...config, - options: config?.options || [], + providers: config?.providers || [], provider: newVectorDBProvider, url: '', apiKey: '', @@ -106,43 +110,21 @@ export default function Settings({ onDone = () => {}, submitButtonText = 'Save' }); }, []); - const handleLLMProviderChange = useCallback((newLLMProvider: SelectOption) => { - setLLMConfig((config) => { - if (config?.provider !== newLLMProvider) { - return { - provider: newLLMProvider, - providers: config?.providers || [], - model: config?.models?.[newLLMProvider.value]?.[0] || defaultModel, - models: config?.models || {}, - apiKey: config?.apiKey || '', - }; - } - return config; - }); - }, []); - - const handleLLMModelChange = useCallback((newLLMModel: SelectOption) => { - setLLMConfig((config) => { - if (config?.model !== newLLMModel) { - return { - provider: config?.provider || defaultProvider, - providers: config?.providers || [], - model: newLLMModel, - models: config?.models || {}, - apiKey: config?.apiKey || '', - }; - } - return config; - }); - }, []); - useEffect(() => { const fetchConfig = async () => { const response = await fetch('/v1/settings'); const settings = await response.json(); + if (!settings.llm.provider) { + settings.llm.provider = settings.llm.providers[0].value; + } if (!settings.llm.model) { - settings.llm.model = settings.llm.models[settings.llm.provider.value][0]; + settings.llm.model = settings.llm.models[settings.llm.provider][0].value; + } + if (!settings.vectorDb.provider) { + settings.vectorDb.provider = settings.vectorDb.providers[0]; + } else { + settings.vectorDb.provider = settings.vectorDb.providers.find((provider: SelectOption) => provider.value === settings.vectorDb.provider); } setLLMConfig(settings.llm); setVectorDBConfig(settings.vectorDb); @@ -151,28 +133,39 @@ export default function Settings({ onDone = () => {}, submitButtonText = 'Save' }, []); return ( -
+ LLM provider: - + + + LLM model: - + + + + + + LLM endpoint: + + + + + + LLM API key: + + + + + + LLM API version: + + + - - - @@ -180,7 +173,7 @@ export default function Settings({ onDone = () => {}, submitButtonText = 'Save' Vector DB provider: diff --git a/cognee-frontend/src/ui/Partials/SignInForm/SignInForm.tsx b/cognee-frontend/src/ui/Partials/SignInForm/SignInForm.tsx index 24b5c6d30..a7477d126 100644 --- a/cognee-frontend/src/ui/Partials/SignInForm/SignInForm.tsx +++ b/cognee-frontend/src/ui/Partials/SignInForm/SignInForm.tsx @@ -67,13 +67,13 @@ export default function SignInForm({ onSignInSuccess = () => window.location.hre Email: - + Password: - + diff --git a/cognee-frontend/src/ui/Partials/Wizard/WizardContent/WizardContent.module.css b/cognee-frontend/src/ui/Partials/Wizard/WizardContent/WizardContent.module.css index 31e2d88fe..b9d6f2d4b 100644 --- a/cognee-frontend/src/ui/Partials/Wizard/WizardContent/WizardContent.module.css +++ b/cognee-frontend/src/ui/Partials/Wizard/WizardContent/WizardContent.module.css @@ -2,7 +2,7 @@ width: 100%; max-width: 400px; height: max-content; - background: linear-gradient(90deg, #D82EB5 0.52%, #9245FD 103.83%); + background: linear-gradient(90deg, #6510F4 0.52%, #0DFF00 103.83%); padding: 24px; margin: 0 auto; position: relative; diff --git a/cognee/api/v1/add/routers/get_add_router.py b/cognee/api/v1/add/routers/get_add_router.py index f96b6f477..a27c6c502 100644 --- a/cognee/api/v1/add/routers/get_add_router.py +++ b/cognee/api/v1/add/routers/get_add_router.py @@ -1,8 +1,10 @@ +from uuid import UUID from fastapi import Form, UploadFile, Depends from fastapi.responses import JSONResponse from fastapi import APIRouter -from typing import List +from typing import List, Optional import subprocess +from cognee.modules.data.methods import get_dataset from cognee.shared.logging_utils import get_logger import requests @@ -18,12 +20,23 @@ def get_add_router() -> APIRouter: @router.post("/", response_model=None) async def add( data: List[UploadFile], - datasetId: str = Form(...), + datasetId: Optional[UUID] = Form(default=None), + datasetName: Optional[str] = Form(default=None), user: User = Depends(get_authenticated_user), ): """This endpoint is responsible for adding data to the graph.""" from cognee.api.v1.add import add as cognee_add + if not datasetId and not datasetName: + raise ValueError("Either datasetId or datasetName must be provided.") + + if datasetId and not datasetName: + dataset = await get_dataset(user_id=user.id, dataset_id=datasetId) + try: + datasetName = dataset.name + except IndexError: + raise ValueError("No dataset found with the provided datasetName.") + try: if isinstance(data, str) and data.startswith("http"): if "github" in data: @@ -43,7 +56,7 @@ def get_add_router() -> APIRouter: return await cognee_add(file_data) else: - await cognee_add(data, datasetId, user=user) + await cognee_add(data, datasetName, user=user) except Exception as error: return JSONResponse(status_code=409, content={"error": str(error)}) diff --git a/cognee/api/v1/datasets/datasets.py b/cognee/api/v1/datasets/datasets.py index a6552d937..c81f9326c 100644 --- a/cognee/api/v1/datasets/datasets.py +++ b/cognee/api/v1/datasets/datasets.py @@ -1,3 +1,4 @@ +from uuid import UUID from cognee.modules.users.methods import get_default_user from cognee.modules.ingestion import discover_directory_datasets from cognee.modules.pipelines.operations.get_pipeline_status import get_pipeline_status @@ -26,7 +27,7 @@ class datasets: return await get_dataset_data(dataset.id) @staticmethod - async def get_status(dataset_ids: list[str]) -> dict: + async def get_status(dataset_ids: list[UUID]) -> dict: return await get_pipeline_status(dataset_ids) @staticmethod diff --git a/cognee/api/v1/datasets/routers/get_datasets_router.py b/cognee/api/v1/datasets/routers/get_datasets_router.py index e7325a713..48cd70d8d 100644 --- a/cognee/api/v1/datasets/routers/get_datasets_router.py +++ b/cognee/api/v1/datasets/routers/get_datasets_router.py @@ -59,13 +59,13 @@ def get_datasets_router() -> APIRouter: @router.delete( "/{dataset_id}", response_model=None, responses={404: {"model": ErrorResponseDTO}} ) - async def delete_dataset(dataset_id: str, user: User = Depends(get_authenticated_user)): + async def delete_dataset(dataset_id: UUID, user: User = Depends(get_authenticated_user)): from cognee.modules.data.methods import get_dataset, delete_dataset dataset = await get_dataset(user.id, dataset_id) if dataset is None: - raise EntityNotFoundError(message=f"Dataset ({dataset_id}) not found.") + raise EntityNotFoundError(message=f"Dataset ({str(dataset_id)}) not found.") await delete_dataset(dataset) @@ -75,7 +75,7 @@ def get_datasets_router() -> APIRouter: responses={404: {"model": ErrorResponseDTO}}, ) async def delete_data( - dataset_id: str, data_id: str, user: User = Depends(get_authenticated_user) + dataset_id: UUID, data_id: UUID, user: User = Depends(get_authenticated_user) ): from cognee.modules.data.methods import get_data, delete_data from cognee.modules.data.methods import get_dataset @@ -85,17 +85,17 @@ def get_datasets_router() -> APIRouter: # TODO: Handle situation differently if user doesn't have permission to access data? if dataset is None: - raise EntityNotFoundError(message=f"Dataset ({dataset_id}) not found.") + raise EntityNotFoundError(message=f"Dataset ({str(dataset_id)}) not found.") data = await get_data(user.id, data_id) if data is None: - raise EntityNotFoundError(message=f"Data ({data_id}) not found.") + raise EntityNotFoundError(message=f"Data ({str(data_id)}) not found.") await delete_data(data) @router.get("/{dataset_id}/graph", response_model=str) - async def get_dataset_graph(dataset_id: str, user: User = Depends(get_authenticated_user)): + async def get_dataset_graph(dataset_id: UUID, user: User = Depends(get_authenticated_user)): from cognee.shared.utils import render_graph from cognee.infrastructure.databases.graph import get_graph_engine @@ -119,7 +119,7 @@ def get_datasets_router() -> APIRouter: response_model=list[DataDTO], responses={404: {"model": ErrorResponseDTO}}, ) - async def get_dataset_data(dataset_id: str, user: User = Depends(get_authenticated_user)): + async def get_dataset_data(dataset_id: UUID, user: User = Depends(get_authenticated_user)): from cognee.modules.data.methods import get_dataset_data, get_dataset dataset = await get_dataset(user.id, dataset_id) @@ -127,7 +127,7 @@ def get_datasets_router() -> APIRouter: if dataset is None: return JSONResponse( status_code=404, - content=ErrorResponseDTO(f"Dataset ({dataset_id}) not found."), + content=ErrorResponseDTO(f"Dataset ({str(dataset_id)}) not found."), ) dataset_data = await get_dataset_data(dataset_id=dataset.id) @@ -139,7 +139,7 @@ def get_datasets_router() -> APIRouter: @router.get("/status", response_model=dict[str, PipelineRunStatus]) async def get_dataset_status( - datasets: Annotated[List[str], Query(alias="dataset")] = None, + datasets: Annotated[List[UUID], Query(alias="dataset")] = None, user: User = Depends(get_authenticated_user), ): from cognee.api.v1.datasets.datasets import datasets as cognee_datasets @@ -153,7 +153,7 @@ def get_datasets_router() -> APIRouter: @router.get("/{dataset_id}/data/{data_id}/raw", response_class=FileResponse) async def get_raw_data( - dataset_id: str, data_id: str, user: User = Depends(get_authenticated_user) + dataset_id: UUID, data_id: UUID, user: User = Depends(get_authenticated_user) ): from cognee.modules.data.methods import get_data from cognee.modules.data.methods import get_dataset, get_dataset_data @@ -170,7 +170,7 @@ def get_datasets_router() -> APIRouter: if dataset_data is None: raise EntityNotFoundError(message=f"No data found in dataset ({dataset_id}).") - matching_data = [data for data in dataset_data if str(data.id) == data_id] + matching_data = [data for data in dataset_data if data.id == data_id] # Check if matching_data contains an element if len(matching_data) == 0: diff --git a/cognee/api/v1/users/routers/get_visualize_router.py b/cognee/api/v1/users/routers/get_visualize_router.py index d92c9689f..153bb5bfa 100644 --- a/cognee/api/v1/users/routers/get_visualize_router.py +++ b/cognee/api/v1/users/routers/get_visualize_router.py @@ -1,9 +1,6 @@ -from fastapi import Depends -from fastapi.responses import JSONResponse from fastapi import APIRouter +from fastapi.responses import HTMLResponse, JSONResponse from cognee.shared.logging_utils import get_logger -from cognee.modules.users.models import User -from cognee.modules.users.methods import get_authenticated_user logger = get_logger() @@ -11,16 +8,14 @@ logger = get_logger() def get_visualize_router() -> APIRouter: router = APIRouter() - @router.post("/", response_model=None) - async def visualize( - user: User = Depends(get_authenticated_user), - ): + @router.get("/", response_model=None) + async def visualize(): """This endpoint is responsible for adding data to the graph.""" from cognee.api.v1.visualize import visualize_graph try: html_visualization = await visualize_graph() - return html_visualization + return HTMLResponse(html_visualization) except Exception as error: return JSONResponse(status_code=409, content={"error": str(error)}) diff --git a/cognee/modules/settings/get_settings.py b/cognee/modules/settings/get_settings.py index 063c18971..876474559 100644 --- a/cognee/modules/settings/get_settings.py +++ b/cognee/modules/settings/get_settings.py @@ -18,8 +18,10 @@ class ModelName(Enum): class LLMConfig(BaseModel): api_key: str - model: ConfigChoice - provider: ConfigChoice + model: str + provider: str + endpoint: str + api_version: str models: dict[str, list[ConfigChoice]] providers: list[ConfigChoice] @@ -27,7 +29,7 @@ class LLMConfig(BaseModel): class VectorDBConfig(BaseModel): api_key: str url: str - provider: ConfigChoice + provider: str providers: list[ConfigChoice] @@ -82,19 +84,11 @@ def get_settings() -> SettingsDict: return SettingsDict.model_validate( dict( llm={ - "provider": { - "label": llm_config.llm_provider, - "value": llm_config.llm_provider, - } - if llm_config.llm_provider - else llm_providers[0], - "model": { - "value": llm_config.llm_model, - "label": llm_config.llm_model, - } - if llm_config.llm_model - else None, - "api_key": (llm_config.llm_api_key[:-10] + "**********") + "provider": llm_config.llm_provider, + "model": llm_config.llm_model, + "endpoint": llm_config.llm_endpoint, + "api_version": llm_config.llm_api_version, + "api_key": (llm_config.llm_api_key[0:10] + "*" * (len(llm_config.llm_api_key) - 10)) if llm_config.llm_api_key else None, "providers": llm_providers, @@ -150,12 +144,12 @@ def get_settings() -> SettingsDict: }, }, vector_db={ - "provider": { - "label": vector_config.vector_db_provider, - "value": vector_config.vector_db_provider.lower(), - }, + "provider": vector_config.vector_db_provider, "url": vector_config.vector_db_url, - "api_key": vector_config.vector_db_key, + "api_key": ( + vector_config.vector_db_key[0:10] + + "*" * (len(vector_config.vector_db_key) - 10) + ), "providers": vector_dbs, }, ) diff --git a/cognee/modules/settings/save_vector_db_config.py b/cognee/modules/settings/save_vector_db_config.py index 7c48435a8..44b917cf7 100644 --- a/cognee/modules/settings/save_vector_db_config.py +++ b/cognee/modules/settings/save_vector_db_config.py @@ -13,5 +13,7 @@ async def save_vector_db_config(vector_db_config: VectorDBConfig): vector_config = get_vectordb_config() vector_config.vector_db_url = vector_db_config.url - vector_config.vector_db_key = vector_db_config.api_key vector_config.vector_db_provider = vector_db_config.provider + + if "*****" not in vector_db_config.api_key and len(vector_db_config.api_key.strip()) > 0: + vector_config.vector_db_key = vector_db_config.api_key diff --git a/cognee/modules/users/permissions/methods/check_permission_on_documents.py b/cognee/modules/users/permissions/methods/check_permission_on_documents.py index b2386b06a..54c5f0c35 100644 --- a/cognee/modules/users/permissions/methods/check_permission_on_documents.py +++ b/cognee/modules/users/permissions/methods/check_permission_on_documents.py @@ -37,5 +37,5 @@ async def check_permission_on_documents(user: User, permission_type: str, docume if not has_permissions: raise PermissionDeniedError( - message=f"User {user.email} does not have {permission_type} permission on documents" + message=f"User {user.id} does not have {permission_type} permission on documents" ) diff --git a/docker-compose.yml b/docker-compose.yml index d9ad50d63..0e5195900 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,6 +10,7 @@ services: - .:/app - /app/cognee-frontend/ # Ignore frontend code environment: + - DEBUG=false # Change to true if debugging - HOST=0.0.0.0 - ENVIRONMENT=local - PYTHONPATH=. @@ -18,30 +19,32 @@ services: - "host.docker.internal:host-gateway" ports: - 8000:8000 - # - 5678:5678 # Debugging + - 5678:5678 # Debugger port deploy: resources: limits: - cpus: "2.0" + cpus: "4.0" memory: 8GB # NOTE: Frontend is a work in progress and is not intended to be used by users yet. # If you want to use Cognee with a UI environment you can run the cognee-gui.py script or # integrate the Cognee MCP Server to Cursor / Claude Desktop / Visual Studio Code ( through Cline/Roo ) -# frontend: -# container_name: frontend -# build: -# context: ./cognee-frontend -# dockerfile: Dockerfile -# volumes: -# - ./cognee-frontend/src:/app/src -# - ./cognee-frontend/public:/app/public -# ports: -# - 3000:3000 -# # - 9229:9229 # Debugging -# networks: -# - cognee-network + frontend: + container_name: frontend + profiles: + - ui + build: + context: ./cognee-frontend + dockerfile: Dockerfile + volumes: + - ./cognee-frontend/src:/app/src + - ./cognee-frontend/public:/app/public + ports: + - 3000:3000 + # - 9229:9229 # Debugging + networks: + - cognee-network neo4j: image: neo4j:latest @@ -86,21 +89,20 @@ services: ports: - "3002:8000" - # UNCOMMENT IF USING POSTGRES - # postgres: - # image: pgvector/pgvector:pg17 - # container_name: postgres - # environment: - # POSTGRES_USER: cognee - # POSTGRES_PASSWORD: cognee - # POSTGRES_DB: cognee_db - # volumes: - # - postgres_data:/var/lib/postgresql/data - # ports: - # - 5432:5432 - # networks: - # - cognee-network - # UNCOMMENT THE VOLUES SECTION BELOW AS WELL TO USE POSTGRES + postgres: + image: pgvector/pgvector:pg17 + container_name: postgres + profiles: + - postgres + environment: + POSTGRES_USER: cognee + POSTGRES_PASSWORD: cognee + POSTGRES_DB: cognee_db + # - postgres_data:/var/lib/postgresql/data + ports: + - 5432:5432 + networks: + - cognee-network networks: cognee-network: @@ -108,5 +110,4 @@ networks: volumes: chromadb_data: -# UNCOMMENT IF USING POSTGRES -# postgres_data: + postgres_data: diff --git a/entrypoint.sh b/entrypoint.sh index edb198443..5874f7e51 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -4,8 +4,7 @@ set -e # Exit on error echo "Debug mode: $DEBUG" echo "Environment: $ENVIRONMENT" -# Run Alembic migrations with proper error handling - +# Run Alembic migrations with proper error handling. # Note on UserAlreadyExists error handling: # During database migrations, we attempt to create a default user. If this user # already exists (e.g., from a previous deployment or migration), it's not a @@ -30,7 +29,7 @@ echo "Starting Gunicorn" sleep 2 # Modified Gunicorn startup with error handling -if [ "$ENVIRONMENT" = "dev" ]; then +if [ "$ENVIRONMENT" = "dev" ] || [ "$ENVIRONMENT" = "local" ]; then if [ "$DEBUG" = "true" ]; then echo "Waiting for the debugger to attach..." exec python -m debugpy --wait-for-client --listen 0.0.0.0:5678 -m gunicorn -w 3 -k uvicorn.workers.UvicornWorker -t 30000 --bind=0.0.0.0:8000 --log-level debug --reload cognee.api.client:app