├── .dockerignore ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ ├── feature_request.yml │ └── question.yml ├── dependabot.yml ├── pull_request_template.md └── workflows │ ├── docker-publish.yml │ ├── linting.yaml │ ├── pypi-publish.yml │ └── stale.yaml ├── .gitignore ├── .pre-commit-config.yaml ├── Dockerfile ├── LICENSE ├── MANIFEST.in ├── README-zh.md ├── README.assets ├── b2aaf634151b4706892693ffb43d9093.png └── iShot_2025-03-23_12.40.08.png ├── README.md ├── SECURITY.md ├── assets └── logo.png ├── config.ini.example ├── docker-compose.yml ├── docs ├── Algorithm.md ├── DockerDeployment.md ├── LightRAG_concurrent_explain.md └── rerank_integration.md ├── env.example ├── env.ollama-binding-options.example ├── examples ├── graph_visual_with_html.py ├── graph_visual_with_neo4j.py ├── insert_custom_kg.py ├── lightrag_azure_openai_demo.py ├── lightrag_gemini_demo.py ├── lightrag_gemini_demo_no_tiktoken.py ├── lightrag_gemini_track_token_demo.py ├── lightrag_ollama_demo.py ├── lightrag_openai_compatible_demo.py ├── lightrag_openai_demo.py ├── lightrag_openai_mongodb_graph_demo.py ├── modalprocessors_example.py ├── raganything_example.py ├── rerank_example.py └── unofficial-sample │ ├── copy_llm_cache_to_another_storage.py │ ├── lightrag_bedrock_demo.py │ ├── lightrag_cloudflare_demo.py │ ├── lightrag_hf_demo.py │ ├── lightrag_llamaindex_direct_demo.py │ ├── lightrag_llamaindex_litellm_demo.py │ ├── lightrag_llamaindex_litellm_opik_demo.py │ ├── lightrag_lmdeploy_demo.py │ ├── lightrag_nvidia_demo.py │ └── lightrag_openai_neo4j_milvus_redis_demo.py ├── k8s-deploy ├── README-zh.md ├── README.md ├── databases │ ├── 00-config.sh │ ├── 01-prepare.sh │ ├── 02-install-database.sh │ ├── 03-uninstall-database.sh │ ├── 04-cleanup.sh │ ├── README.md │ ├── elasticsearch │ │ └── values.yaml │ ├── install-kubeblocks.sh │ ├── mongodb │ │ └── values.yaml │ ├── neo4j │ │ └── values.yaml │ ├── postgresql │ │ └── values.yaml │ ├── qdrant │ │ └── values.yaml │ ├── redis │ │ └── values.yaml │ ├── scripts │ │ └── common.sh │ └── uninstall-kubeblocks.sh ├── install_lightrag.sh ├── install_lightrag_dev.sh ├── lightrag │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ ├── pvc.yaml │ │ ├── secret.yaml │ │ └── service.yaml │ └── values.yaml ├── uninstall_lightrag.sh └── uninstall_lightrag_dev.sh ├── lightrag-api ├── lightrag.service.example ├── lightrag ├── __init__.py ├── api │ ├── .env.aoi.example │ ├── .gitignore │ ├── README-zh.md │ ├── README.assets │ │ ├── image-20250323122538997.png │ │ ├── image-20250323122754387.png │ │ ├── image-20250323123011220.png │ │ └── image-20250323194750379.png │ ├── README.md │ ├── __init__.py │ ├── auth.py │ ├── config.py │ ├── gunicorn_config.py │ ├── lightrag_server.py │ ├── routers │ │ ├── __init__.py │ │ ├── document_routes.py │ │ ├── graph_routes.py │ │ ├── ollama_api.py │ │ └── query_routes.py │ ├── run_with_gunicorn.py │ ├── utils_api.py │ └── webui │ │ ├── assets │ │ ├── KaTeX_AMS-Regular-BQhdFMY1.woff2 │ │ ├── KaTeX_AMS-Regular-DMm9YOAa.woff │ │ ├── KaTeX_AMS-Regular-DRggAlZN.ttf │ │ ├── KaTeX_Caligraphic-Bold-ATXxdsX0.ttf │ │ ├── KaTeX_Caligraphic-Bold-BEiXGLvX.woff │ │ ├── KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 │ │ ├── KaTeX_Caligraphic-Regular-CTRA-rTL.woff │ │ ├── KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 │ │ ├── KaTeX_Caligraphic-Regular-wX97UBjC.ttf │ │ ├── KaTeX_Fraktur-Bold-BdnERNNW.ttf │ │ ├── KaTeX_Fraktur-Bold-BsDP51OF.woff │ │ ├── KaTeX_Fraktur-Bold-CL6g_b3V.woff2 │ │ ├── KaTeX_Fraktur-Regular-CB_wures.ttf │ │ ├── KaTeX_Fraktur-Regular-CTYiF6lA.woff2 │ │ ├── KaTeX_Fraktur-Regular-Dxdc4cR9.woff │ │ ├── KaTeX_Main-Bold-Cx986IdX.woff2 │ │ ├── KaTeX_Main-Bold-Jm3AIy58.woff │ │ ├── KaTeX_Main-Bold-waoOVXN0.ttf │ │ ├── KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 │ │ ├── KaTeX_Main-BoldItalic-DzxPMmG6.ttf │ │ ├── KaTeX_Main-BoldItalic-SpSLRI95.woff │ │ ├── KaTeX_Main-Italic-3WenGoN9.ttf │ │ ├── KaTeX_Main-Italic-BMLOBm91.woff │ │ ├── KaTeX_Main-Italic-NWA7e6Wa.woff2 │ │ ├── KaTeX_Main-Regular-B22Nviop.woff2 │ │ ├── KaTeX_Main-Regular-Dr94JaBh.woff │ │ ├── KaTeX_Main-Regular-ypZvNtVU.ttf │ │ ├── KaTeX_Math-BoldItalic-B3XSjfu4.ttf │ │ ├── KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 │ │ ├── KaTeX_Math-BoldItalic-iY-2wyZ7.woff │ │ ├── KaTeX_Math-Italic-DA0__PXp.woff │ │ ├── KaTeX_Math-Italic-flOr_0UB.ttf │ │ ├── KaTeX_Math-Italic-t53AETM-.woff2 │ │ ├── KaTeX_SansSerif-Bold-CFMepnvq.ttf │ │ ├── KaTeX_SansSerif-Bold-D1sUS0GD.woff2 │ │ ├── KaTeX_SansSerif-Bold-DbIhKOiC.woff │ │ ├── KaTeX_SansSerif-Italic-C3H0VqGB.woff2 │ │ ├── KaTeX_SansSerif-Italic-DN2j7dab.woff │ │ ├── KaTeX_SansSerif-Italic-YYjJ1zSn.ttf │ │ ├── KaTeX_SansSerif-Regular-BNo7hRIc.ttf │ │ ├── KaTeX_SansSerif-Regular-CS6fqUqJ.woff │ │ ├── KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 │ │ ├── KaTeX_Script-Regular-C5JkGWo-.ttf │ │ ├── KaTeX_Script-Regular-D3wIWfF6.woff2 │ │ ├── KaTeX_Script-Regular-D5yQViql.woff │ │ ├── KaTeX_Size1-Regular-C195tn64.woff │ │ ├── KaTeX_Size1-Regular-Dbsnue_I.ttf │ │ ├── KaTeX_Size1-Regular-mCD8mA8B.woff2 │ │ ├── KaTeX_Size2-Regular-B7gKUWhC.ttf │ │ ├── KaTeX_Size2-Regular-Dy4dx90m.woff2 │ │ ├── KaTeX_Size2-Regular-oD1tc_U0.woff │ │ ├── KaTeX_Size3-Regular-CTq5MqoE.woff │ │ ├── KaTeX_Size3-Regular-DgpXs0kz.ttf │ │ ├── KaTeX_Size4-Regular-BF-4gkZK.woff │ │ ├── KaTeX_Size4-Regular-DWFBv043.ttf │ │ ├── KaTeX_Size4-Regular-Dl5lxZxV.woff2 │ │ ├── KaTeX_Typewriter-Regular-C0xS9mPB.woff │ │ ├── KaTeX_Typewriter-Regular-CO6r4hn1.woff2 │ │ ├── KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf │ │ ├── _basePickBy-CGXZVaMl.js │ │ ├── _baseUniq-D-427rzS.js │ │ ├── architectureDiagram-IEHRJDOE-KEsPf0zj.js │ │ ├── blockDiagram-JOT3LUYC-C5TSsZ70.js │ │ ├── c4Diagram-VJAJSXHY-DfzHPmQ1.js │ │ ├── chunk-4BMEZGHF-CbUqLJH_.js │ │ ├── chunk-A2AXSNBT-ZI6SIAYy.js │ │ ├── chunk-AEK57VVT--Edz4Twz.js │ │ ├── chunk-D6G4REZN-5bNYmyqV.js │ │ ├── chunk-RZ5BOZE2-BhCqM4LN.js │ │ ├── chunk-XZIHB7SX-Bhbr-OLQ.js │ │ ├── classDiagram-GIVACNV2-DHufEbeX.js │ │ ├── classDiagram-v2-COTLJTTW-DHufEbeX.js │ │ ├── clone-BvhE3BKU.js │ │ ├── cytoscape.esm-CfBqOv7Q.js │ │ ├── dagre-OKDRZEBW-Bp-tFHer.js │ │ ├── diagram-SSKATNLV-lu4K19HW.js │ │ ├── diagram-VNBRO52H-Cr8B4odU.js │ │ ├── erDiagram-Q7BY3M3F-7GiFWS5w.js │ │ ├── feature-documents-36AWafKt.js │ │ ├── feature-graph-BipNuM18.css │ │ ├── feature-graph-Chuw_ipx.js │ │ ├── feature-retrieval-Bsekt8JN.js │ │ ├── flowDiagram-4HSFHLVR-Bw-uNqAT.js │ │ ├── ganttDiagram-APWFNJXF-IppLiff8.js │ │ ├── gitGraphDiagram-7IBYFJ6S-K6pljuQ3.js │ │ ├── graph-BPepmx12.js │ │ ├── graph-vendor-B-X5JegA.js │ │ ├── index-1Hy45NwC.js │ │ ├── index-C3sDhLdo.js │ │ ├── index-CafJWW1u.css │ │ ├── infoDiagram-PH2N3AL5-B1FzsqbO.js │ │ ├── journeyDiagram-U35MCT3I-CqkrWYvE.js │ │ ├── kanban-definition-NDS4AKOZ-DUdObGWr.js │ │ ├── katex-B1t2RQs_.css │ │ ├── katex-DCmpTppl.js │ │ ├── layout-CmsmH6ov.js │ │ ├── markdown-vendor-DmIvJdn7.js │ │ ├── mermaid-vendor-DGPC_TDM.js │ │ ├── mindmap-definition-ALO5MXBD-CaFaW_OF.js │ │ ├── pieDiagram-IB7DONF6-CztW5aQI.js │ │ ├── quadrantDiagram-7GDLP6J5-BWdOiVfZ.js │ │ ├── radar-MK3ICKWK-BkgLvISn.js │ │ ├── react-vendor-DEwriMA6.js │ │ ├── requirementDiagram-KVF5MWMF-CGNFa7_w.js │ │ ├── sankeyDiagram-QLVOVGJD-oKHHFy3G.js │ │ ├── sequenceDiagram-X6HHIX6F-BEtP4eac.js │ │ ├── stateDiagram-DGXRK772-CDzJNbIf.js │ │ ├── stateDiagram-v2-YXO3MK2T-CE61sgaM.js │ │ ├── timeline-definition-BDJGKUSR-Ys8HGHVJ.js │ │ ├── ui-vendor-CeCm8EER.js │ │ ├── utils-vendor-BysuhMZA.js │ │ └── xychartDiagram-VJFVF3MP-CJWOP-q-.js │ │ ├── favicon.png │ │ ├── index.html │ │ └── logo.svg ├── base.py ├── constants.py ├── exceptions.py ├── kg │ ├── __init__.py │ ├── deprecated │ │ └── chroma_impl.py │ ├── faiss_impl.py │ ├── json_doc_status_impl.py │ ├── json_kv_impl.py │ ├── memgraph_impl.py │ ├── milvus_impl.py │ ├── mongo_impl.py │ ├── nano_vector_db_impl.py │ ├── neo4j_impl.py │ ├── networkx_impl.py │ ├── postgres_impl.py │ ├── qdrant_impl.py │ ├── redis_impl.py │ └── shared_storage.py ├── lightrag.py ├── llm.py ├── llm │ ├── Readme.md │ ├── __init__.py │ ├── anthropic.py │ ├── azure_openai.py │ ├── bedrock.py │ ├── binding_options.py │ ├── hf.py │ ├── jina.py │ ├── llama_index_impl.py │ ├── lmdeploy.py │ ├── lollms.py │ ├── nvidia_openai.py │ ├── ollama.py │ ├── openai.py │ ├── siliconcloud.py │ └── zhipu.py ├── namespace.py ├── operate.py ├── prompt.py ├── rerank.py ├── tools │ ├── __init__.py │ └── lightrag_visualizer │ │ ├── README-zh.md │ │ ├── README.md │ │ ├── __init__.py │ │ ├── assets │ │ ├── Geist-Regular.ttf │ │ ├── LICENSE - Geist.txt │ │ ├── LICENSE - SmileySans.txt │ │ ├── SmileySans-Oblique.ttf │ │ └── place_font_here │ │ ├── graph_visualizer.py │ │ └── requirements.txt ├── types.py ├── utils.py └── utils_graph.py ├── lightrag_webui ├── .gitignore ├── .prettierrc.json ├── README.md ├── bun.lock ├── components.json ├── env.development.smaple ├── env.local.sample ├── eslint.config.js ├── index.html ├── package.json ├── public │ ├── favicon.png │ └── logo.svg ├── src │ ├── App.tsx │ ├── AppRouter.tsx │ ├── api │ │ └── lightrag.ts │ ├── components │ │ ├── ApiKeyAlert.tsx │ │ ├── AppSettings.tsx │ │ ├── LanguageToggle.tsx │ │ ├── Root.tsx │ │ ├── ThemeProvider.tsx │ │ ├── ThemeToggle.tsx │ │ ├── documents │ │ │ ├── ClearDocumentsDialog.tsx │ │ │ ├── DeleteDocumentsDialog.tsx │ │ │ ├── DeselectDocumentsDialog.tsx │ │ │ ├── PipelineStatusDialog.tsx │ │ │ └── UploadDocumentsDialog.tsx │ │ ├── graph │ │ │ ├── EditablePropertyRow.tsx │ │ │ ├── FocusOnNode.tsx │ │ │ ├── FullScreenControl.tsx │ │ │ ├── GraphControl.tsx │ │ │ ├── GraphLabels.tsx │ │ │ ├── GraphSearch.tsx │ │ │ ├── LayoutsControl.tsx │ │ │ ├── Legend.tsx │ │ │ ├── LegendButton.tsx │ │ │ ├── PropertiesView.tsx │ │ │ ├── PropertyEditDialog.tsx │ │ │ ├── PropertyRowComponents.tsx │ │ │ ├── Settings.tsx │ │ │ ├── SettingsDisplay.tsx │ │ │ └── ZoomControl.tsx │ │ ├── retrieval │ │ │ ├── ChatMessage.tsx │ │ │ └── QuerySettings.tsx │ │ ├── status │ │ │ ├── StatusCard.tsx │ │ │ ├── StatusDialog.tsx │ │ │ └── StatusIndicator.tsx │ │ └── ui │ │ │ ├── Alert.tsx │ │ │ ├── AlertDialog.tsx │ │ │ ├── AsyncSearch.tsx │ │ │ ├── AsyncSelect.tsx │ │ │ ├── Badge.tsx │ │ │ ├── Button.tsx │ │ │ ├── Card.tsx │ │ │ ├── Checkbox.tsx │ │ │ ├── Command.tsx │ │ │ ├── DataTable.tsx │ │ │ ├── Dialog.tsx │ │ │ ├── EmptyCard.tsx │ │ │ ├── FileUploader.tsx │ │ │ ├── Input.tsx │ │ │ ├── NumberInput.tsx │ │ │ ├── PaginationControls.tsx │ │ │ ├── Popover.tsx │ │ │ ├── Progress.tsx │ │ │ ├── ScrollArea.tsx │ │ │ ├── Select.tsx │ │ │ ├── Separator.tsx │ │ │ ├── TabContent.tsx │ │ │ ├── Table.tsx │ │ │ ├── Tabs.tsx │ │ │ ├── Text.tsx │ │ │ └── Tooltip.tsx │ ├── contexts │ │ ├── TabVisibilityProvider.tsx │ │ ├── context.ts │ │ ├── types.ts │ │ └── useTabVisibility.ts │ ├── features │ │ ├── ApiSite.tsx │ │ ├── DocumentManager.tsx │ │ ├── GraphViewer.tsx │ │ ├── LoginPage.tsx │ │ ├── RetrievalTesting.tsx │ │ └── SiteHeader.tsx │ ├── hooks │ │ ├── useDebounce.tsx │ │ ├── useLightragGraph.tsx │ │ ├── useRandomGraph.tsx │ │ └── useTheme.tsx │ ├── i18n.ts │ ├── index.css │ ├── lib │ │ ├── constants.ts │ │ └── utils.ts │ ├── locales │ │ ├── ar.json │ │ ├── en.json │ │ ├── fr.json │ │ ├── zh.json │ │ └── zh_TW.json │ ├── main.tsx │ ├── services │ │ └── navigation.ts │ ├── stores │ │ ├── graph.ts │ │ ├── settings.ts │ │ └── state.ts │ └── vite-env.d.ts ├── tailwind.config.js ├── tsconfig.json └── vite.config.ts ├── paging.md ├── pyproject.toml ├── reproduce ├── Step_0.py ├── Step_1.py ├── Step_1_openai_compatible.py ├── Step_2.py ├── Step_3.py ├── Step_3_openai_compatible.py └── batch_eval.py ├── setup.py └── tests ├── test_graph_storage.py └── test_lightrag_ollama_chat.py /.dockerignore: -------------------------------------------------------------------------------- 1 | # Python-related files and directories 2 | __pycache__ 3 | .cache 4 | 5 | # Virtual environment directories 6 | *.venv 7 | 8 | # Env 9 | env/ 10 | *.env* 11 | .env_example 12 | 13 | # Distribution / build files 14 | site 15 | dist/ 16 | build/ 17 | .eggs/ 18 | *.egg-info/ 19 | *.tgz 20 | *.tar.gz 21 | 22 | # Exclude siles and folders 23 | *.yml 24 | .dockerignore 25 | Dockerfile 26 | Makefile 27 | 28 | # Exclude other projects 29 | /tests 30 | /scripts 31 | 32 | # Python version manager file 33 | .python-version 34 | 35 | # Reports 36 | *.coverage/ 37 | *.log 38 | log/ 39 | *.logfire 40 | 41 | # Cache 42 | .cache/ 43 | .mypy_cache 44 | .pytest_cache 45 | .ruff_cache 46 | .gradio 47 | .logfire 48 | temp/ 49 | 50 | # MacOS-related files 51 | .DS_Store 52 | 53 | # VS Code settings (local configuration files) 54 | .vscode 55 | 56 | # file 57 | TODO.md 58 | 59 | # Exclude Git-related files 60 | .git 61 | .github 62 | .gitignore 63 | .pre-commit-config.yaml 64 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | lightrag/api/webui/** binary 2 | lightrag/api/webui/** linguist-generated 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: File a bug report 3 | title: "[Bug]:" 4 | labels: ["bug", "triage"] 5 | 6 | body: 7 | - type: checkboxes 8 | id: existingcheck 9 | attributes: 10 | label: Do you need to file an issue? 11 | description: Please help us manage our time by avoiding duplicates and common bugs with the steps below. 12 | options: 13 | - label: I have searched the existing issues and this bug is not already filed. 14 | - label: I believe this is a legitimate bug, not just a question or feature request. 15 | - type: textarea 16 | id: description 17 | attributes: 18 | label: Describe the bug 19 | description: A clear and concise description of what the bug is. 20 | placeholder: What went wrong? 21 | - type: textarea 22 | id: reproduce 23 | attributes: 24 | label: Steps to reproduce 25 | description: Steps to reproduce the behavior. 26 | placeholder: How can we replicate the issue? 27 | - type: textarea 28 | id: expected_behavior 29 | attributes: 30 | label: Expected Behavior 31 | description: A clear and concise description of what you expected to happen. 32 | placeholder: What should have happened? 33 | - type: textarea 34 | id: configused 35 | attributes: 36 | label: LightRAG Config Used 37 | description: The LightRAG configuration used for the run. 38 | placeholder: The settings content or LightRAG configuration 39 | value: | 40 | # Paste your config here 41 | - type: textarea 42 | id: screenshotslogs 43 | attributes: 44 | label: Logs and screenshots 45 | description: If applicable, add screenshots and logs to help explain your problem. 46 | placeholder: Add logs and screenshots here 47 | - type: textarea 48 | id: additional_information 49 | attributes: 50 | label: Additional Information 51 | description: | 52 | - LightRAG Version: e.g., v0.1.1 53 | - Operating System: e.g., Windows 10, Ubuntu 20.04 54 | - Python Version: e.g., 3.8 55 | - Related Issues: e.g., #1 56 | - Any other relevant information. 57 | value: | 58 | - LightRAG Version: 59 | - Operating System: 60 | - Python Version: 61 | - Related Issues: 62 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: File a feature request 3 | labels: ["enhancement"] 4 | title: "[Feature Request]:" 5 | 6 | body: 7 | - type: checkboxes 8 | id: existingcheck 9 | attributes: 10 | label: Do you need to file a feature request? 11 | description: Please help us manage our time by avoiding duplicates and common feature request with the steps below. 12 | options: 13 | - label: I have searched the existing feature request and this feature request is not already filed. 14 | - label: I believe this is a legitimate feature request, not just a question or bug. 15 | - type: textarea 16 | id: feature_request_description 17 | attributes: 18 | label: Feature Request Description 19 | description: A clear and concise description of the feature request you would like. 20 | placeholder: What this feature request add more or improve? 21 | - type: textarea 22 | id: additional_context 23 | attributes: 24 | label: Additional Context 25 | description: Add any other context or screenshots about the feature request here. 26 | placeholder: Any additional information 27 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.yml: -------------------------------------------------------------------------------- 1 | name: Question 2 | description: Ask a general question 3 | labels: ["question"] 4 | title: "[Question]:" 5 | 6 | body: 7 | - type: checkboxes 8 | id: existingcheck 9 | attributes: 10 | label: Do you need to ask a question? 11 | description: Please help us manage our time by avoiding duplicates and common questions with the steps below. 12 | options: 13 | - label: I have searched the existing question and discussions and this question is not already answered. 14 | - label: I believe this is a legitimate question, not just a bug or feature request. 15 | - type: textarea 16 | id: question 17 | attributes: 18 | label: Your Question 19 | description: A clear and concise description of your question. 20 | placeholder: What is your question? 21 | - type: textarea 22 | id: context 23 | attributes: 24 | label: Additional Context 25 | description: Provide any additional context or details that might help us understand your question better. 26 | placeholder: Add any relevant information here 27 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "pip" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | ## Description 12 | 13 | [Briefly describe the changes made in this pull request.] 14 | 15 | ## Related Issues 16 | 17 | [Reference any related issues or tasks addressed by this pull request.] 18 | 19 | ## Changes Made 20 | 21 | [List the specific changes made in this pull request.] 22 | 23 | ## Checklist 24 | 25 | - [ ] Changes tested locally 26 | - [ ] Code reviewed 27 | - [ ] Documentation updated (if necessary) 28 | - [ ] Unit tests added (if applicable) 29 | 30 | ## Additional Notes 31 | 32 | [Add any additional notes or context for the reviewer(s).] 33 | -------------------------------------------------------------------------------- /.github/workflows/docker-publish.yml: -------------------------------------------------------------------------------- 1 | name: Build and Push Docker Image 2 | 3 | on: 4 | release: 5 | types: [published] 6 | workflow_dispatch: 7 | 8 | permissions: 9 | contents: read 10 | packages: write 11 | 12 | jobs: 13 | build-and-push: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout code 17 | uses: actions/checkout@v4 18 | 19 | - name: Set up Docker Buildx 20 | uses: docker/setup-buildx-action@v3 21 | 22 | - name: Login to GitHub Container Registry 23 | uses: docker/login-action@v3 24 | with: 25 | registry: ghcr.io 26 | username: ${{ github.actor }} 27 | password: ${{ secrets.GITHUB_TOKEN }} 28 | 29 | - name: Extract metadata for Docker 30 | id: meta 31 | uses: docker/metadata-action@v5 32 | with: 33 | images: ghcr.io/${{ github.repository }} 34 | tags: | 35 | type=semver,pattern={{version}} 36 | type=raw,value=latest,enable={{is_default_branch}} 37 | 38 | - name: Build and push Docker image 39 | uses: docker/build-push-action@v5 40 | with: 41 | context: . 42 | platforms: linux/amd64,linux/arm64 43 | push: true 44 | tags: ${{ steps.meta.outputs.tags }} 45 | labels: ${{ steps.meta.outputs.labels }} 46 | cache-from: type=gha 47 | cache-to: type=gha,mode=max 48 | -------------------------------------------------------------------------------- /.github/workflows/linting.yaml: -------------------------------------------------------------------------------- 1 | name: Linting and Formatting 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | lint-and-format: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - name: Checkout code 17 | uses: actions/checkout@v2 18 | 19 | - name: Set up Python 20 | uses: actions/setup-python@v2 21 | with: 22 | python-version: '3.x' 23 | 24 | - name: Install dependencies 25 | run: | 26 | python -m pip install --upgrade pip 27 | pip install pre-commit 28 | 29 | - name: Run pre-commit 30 | run: pre-commit run --all-files --show-diff-on-failure 31 | -------------------------------------------------------------------------------- /.github/workflows/pypi-publish.yml: -------------------------------------------------------------------------------- 1 | name: Upload LightRAG-hku Package 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | permissions: 8 | contents: read 9 | 10 | jobs: 11 | release-build: 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v4 16 | 17 | - uses: actions/setup-python@v5 18 | with: 19 | python-version: "3.x" 20 | 21 | - name: Build release distributions 22 | run: | 23 | python -m pip install build 24 | python -m build 25 | 26 | - name: Upload distributions 27 | uses: actions/upload-artifact@v4 28 | with: 29 | name: release-dists 30 | path: dist/ 31 | 32 | pypi-publish: 33 | runs-on: ubuntu-latest 34 | needs: 35 | - release-build 36 | permissions: 37 | id-token: write 38 | 39 | environment: 40 | name: pypi 41 | 42 | steps: 43 | - name: Retrieve release distributions 44 | uses: actions/download-artifact@v4 45 | with: 46 | name: release-dists 47 | path: dist/ 48 | 49 | - name: Publish release distributions to PyPI 50 | uses: pypa/gh-action-pypi-publish@release/v1 51 | with: 52 | packages-dir: dist/ 53 | -------------------------------------------------------------------------------- /.github/workflows/stale.yaml: -------------------------------------------------------------------------------- 1 | # .github/workflows/stale.yml 2 | name: Mark stale issues and pull requests 3 | 4 | on: 5 | schedule: 6 | - cron: '30 22 * * *' # run at 22:30+08 every day 7 | 8 | permissions: 9 | issues: write 10 | pull-requests: write 11 | 12 | jobs: 13 | stale: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/stale@v9 17 | with: 18 | days-before-stale: 90 # 90 days 19 | days-before-close: 7 # 7 days after marked as stale 20 | stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.' 21 | close-issue-message: 'This issue has been automatically closed because it has not had recent activity. Please open a new issue if you still have this problem.' 22 | stale-pr-message: 'This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.' 23 | close-pr-message: 'This pull request has been automatically closed because it has not had recent activity.' 24 | # If there are specific labels, exempt them from being marked as stale, for example: 25 | exempt-issue-labels: 'enhancement,tracked' 26 | # exempt-pr-labels: 'bug,enhancement,help wanted' 27 | repo-token: ${{ secrets.GITHUB_TOKEN }} # token provided by GitHub 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Python-related files 2 | __pycache__/ 3 | *.py[cod] 4 | *.egg-info/ 5 | .eggs/ 6 | *.tgz 7 | *.tar.gz 8 | *.ini 9 | 10 | # Virtual Environment 11 | .venv/ 12 | env/ 13 | venv/ 14 | *.env* 15 | .env_example 16 | 17 | # Build / Distribution 18 | dist/ 19 | build/ 20 | site/ 21 | 22 | # Logs / Reports 23 | *.log 24 | *.log.* 25 | *.logfire 26 | *.coverage/ 27 | log/ 28 | 29 | # Caches 30 | .cache/ 31 | .mypy_cache/ 32 | .pytest_cache/ 33 | .ruff_cache/ 34 | .gradio/ 35 | .history/ 36 | temp/ 37 | 38 | # IDE / Editor Files 39 | .idea/ 40 | .vscode/ 41 | .vscode/settings.json 42 | 43 | # Framework-specific files 44 | local_neo4jWorkDir/ 45 | neo4jWorkDir/ 46 | 47 | # Data & Storage 48 | inputs/ 49 | rag_storage/ 50 | examples/input/ 51 | examples/output/ 52 | output*/ 53 | data/ 54 | 55 | # Miscellaneous 56 | .DS_Store 57 | TODO.md 58 | ignore_this.txt 59 | *.ignore.* 60 | 61 | # Project-specific files 62 | dickens*/ 63 | book.txt 64 | LightRAG.pdf 65 | download_models_hf.py 66 | lightrag-dev/ 67 | gui/ 68 | 69 | # unit-test files 70 | test_* 71 | 72 | # Cline files 73 | memory-bank/ 74 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/pre-commit/pre-commit-hooks 3 | rev: v5.0.0 4 | hooks: 5 | - id: trailing-whitespace 6 | exclude: ^lightrag/api/webui/ 7 | - id: end-of-file-fixer 8 | exclude: ^lightrag/api/webui/ 9 | - id: requirements-txt-fixer 10 | exclude: ^lightrag/api/webui/ 11 | 12 | 13 | - repo: https://github.com/astral-sh/ruff-pre-commit 14 | rev: v0.6.4 15 | hooks: 16 | - id: ruff-format 17 | exclude: ^lightrag/api/webui/ 18 | - id: ruff 19 | args: [--fix, --ignore=E402] 20 | exclude: ^lightrag/api/webui/ 21 | 22 | 23 | - repo: https://github.com/mgedmin/check-manifest 24 | rev: "0.49" 25 | hooks: 26 | - id: check-manifest 27 | stages: [manual] 28 | exclude: ^lightrag/api/webui/ 29 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Build stage 2 | FROM python:3.11-slim AS builder 3 | 4 | WORKDIR /app 5 | 6 | # Install Rust and required build dependencies 7 | RUN apt-get update && apt-get install -y \ 8 | curl \ 9 | build-essential \ 10 | pkg-config \ 11 | && rm -rf /var/lib/apt/lists/* \ 12 | && curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y \ 13 | && . $HOME/.cargo/env 14 | 15 | # Copy pyproject.toml and source code for dependency installation 16 | COPY pyproject.toml . 17 | COPY setup.py . 18 | COPY lightrag/ ./lightrag/ 19 | 20 | # Install dependencies 21 | ENV PATH="/root/.cargo/bin:${PATH}" 22 | RUN pip install --user --no-cache-dir . 23 | RUN pip install --user --no-cache-dir .[api] 24 | 25 | # Install depndencies for default storage 26 | RUN pip install --user --no-cache-dir nano-vectordb networkx 27 | # Install depndencies for default LLM 28 | RUN pip install --user --no-cache-dir openai ollama tiktoken 29 | # Install depndencies for default document loader 30 | RUN pip install --user --no-cache-dir pypdf2 python-docx python-pptx openpyxl 31 | 32 | # Final stage 33 | FROM python:3.11-slim 34 | 35 | WORKDIR /app 36 | 37 | # Copy only necessary files from builder 38 | COPY --from=builder /root/.local /root/.local 39 | COPY ./lightrag ./lightrag 40 | COPY setup.py . 41 | 42 | RUN pip install ".[api]" 43 | # Make sure scripts in .local are usable 44 | ENV PATH=/root/.local/bin:$PATH 45 | 46 | # Create necessary directories 47 | RUN mkdir -p /app/data/rag_storage /app/data/inputs 48 | 49 | # Docker data directories 50 | ENV WORKING_DIR=/app/data/rag_storage 51 | ENV INPUT_DIR=/app/data/inputs 52 | 53 | # Expose the default port 54 | EXPOSE 9621 55 | 56 | # Set entrypoint 57 | ENTRYPOINT ["python", "-m", "lightrag.api.lightrag_server"] 58 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 LightRAG Team 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include requirements.txt 2 | include lightrag/api/requirements.txt 3 | recursive-include lightrag/api/webui * 4 | -------------------------------------------------------------------------------- /README.assets/b2aaf634151b4706892693ffb43d9093.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/README.assets/b2aaf634151b4706892693ffb43d9093.png -------------------------------------------------------------------------------- /README.assets/iShot_2025-03-23_12.40.08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/README.assets/iShot_2025-03-23_12.40.08.png -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Reporting Security Issues 2 | 3 | The LightRAG team and community take security bugs seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions. 4 | 5 | To report a security issue, please use the GitHub Security Advisory: [Report a Vulnerability](https://github.com/HKUDS/LightRAG/security/advisories/new) 6 | 7 | The LightRAG team will send a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance. 8 | 9 | Report security bugs in third-party modules to the person or team maintaining the module. 10 | 11 | ### Supported Versions 12 | 13 | The following versions currently being supported with security updates. 14 | 15 | | Version | Supported | 16 | | ------- | ------------------ | 17 | | 1.2.x | :x: | 18 | | 1.3.x | :white_check_mark: | 19 | -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/assets/logo.png -------------------------------------------------------------------------------- /config.ini.example: -------------------------------------------------------------------------------- 1 | [neo4j] 2 | uri = neo4j+s://xxxxxxxx.databases.neo4j.io 3 | username = neo4j 4 | password = your-password 5 | 6 | [mongodb] 7 | uri = mongodb+srv://name:password@your-cluster-address 8 | database = lightrag 9 | 10 | [redis] 11 | uri=redis://localhost:6379/1 12 | 13 | [qdrant] 14 | uri = http://localhost:16333 15 | 16 | [postgres] 17 | host = localhost 18 | port = 5432 19 | user = your_username 20 | password = your_password 21 | database = your_database 22 | workspace = default # 可选,默认为default 23 | max_connections = 12 24 | 25 | [memgraph] 26 | uri = bolt://localhost:7687 27 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | lightrag: 3 | container_name: lightrag 4 | image: ghcr.io/hkuds/lightrag:latest 5 | build: 6 | context: . 7 | dockerfile: Dockerfile 8 | tags: 9 | - ghcr.io/hkuds/lightrag:latest 10 | ports: 11 | - "${PORT:-9621}:9621" 12 | volumes: 13 | - ./data/rag_storage:/app/data/rag_storage 14 | - ./data/inputs:/app/data/inputs 15 | - ./data/tiktoken:/app/data/tiktoken 16 | - ./config.ini:/app/config.ini 17 | - ./.env:/app/.env 18 | env_file: 19 | - .env 20 | environment: 21 | - TIKTOKEN_CACHE_DIR=/app/data/tiktoken 22 | restart: unless-stopped 23 | extra_hosts: 24 | - "host.docker.internal:host-gateway" 25 | -------------------------------------------------------------------------------- /docs/Algorithm.md: -------------------------------------------------------------------------------- 1 | ![LightRAG Indexing Flowchart](https://learnopencv.com/wp-content/uploads/2024/11/LightRAG-VectorDB-Json-KV-Store-Indexing-Flowchart-scaled.jpg) 2 | *Figure 1: LightRAG Indexing Flowchart - Img Caption : [Source](https://learnopencv.com/lightrag/)* 3 | ![LightRAG Retrieval and Querying Flowchart](https://learnopencv.com/wp-content/uploads/2024/11/LightRAG-Querying-Flowchart-Dual-Level-Retrieval-Generation-Knowledge-Graphs-scaled.jpg) 4 | *Figure 2: LightRAG Retrieval and Querying Flowchart - Img Caption : [Source](https://learnopencv.com/lightrag/)* 5 | -------------------------------------------------------------------------------- /examples/graph_visual_with_html.py: -------------------------------------------------------------------------------- 1 | import pipmaster as pm 2 | 3 | if not pm.is_installed("pyvis"): 4 | pm.install("pyvis") 5 | if not pm.is_installed("networkx"): 6 | pm.install("networkx") 7 | 8 | import networkx as nx 9 | from pyvis.network import Network 10 | import random 11 | 12 | # Load the GraphML file 13 | G = nx.read_graphml("./dickens/graph_chunk_entity_relation.graphml") 14 | 15 | # Create a Pyvis network 16 | net = Network(height="100vh", notebook=True) 17 | 18 | # Convert NetworkX graph to Pyvis network 19 | net.from_nx(G) 20 | 21 | 22 | # Add colors and title to nodes 23 | for node in net.nodes: 24 | node["color"] = "#{:06x}".format(random.randint(0, 0xFFFFFF)) 25 | if "description" in node: 26 | node["title"] = node["description"] 27 | 28 | # Add title to edges 29 | for edge in net.edges: 30 | if "description" in edge: 31 | edge["title"] = edge["description"] 32 | 33 | # Save and display the network 34 | net.show("knowledge_graph.html") 35 | -------------------------------------------------------------------------------- /examples/lightrag_gemini_demo.py: -------------------------------------------------------------------------------- 1 | # pip install -q -U google-genai to use gemini as a client 2 | 3 | import os 4 | import numpy as np 5 | from google import genai 6 | from google.genai import types 7 | from dotenv import load_dotenv 8 | from lightrag.utils import EmbeddingFunc 9 | from lightrag import LightRAG, QueryParam 10 | from sentence_transformers import SentenceTransformer 11 | from lightrag.kg.shared_storage import initialize_pipeline_status 12 | 13 | import asyncio 14 | import nest_asyncio 15 | 16 | # Apply nest_asyncio to solve event loop issues 17 | nest_asyncio.apply() 18 | 19 | load_dotenv() 20 | gemini_api_key = os.getenv("GEMINI_API_KEY") 21 | 22 | WORKING_DIR = "./dickens" 23 | 24 | if os.path.exists(WORKING_DIR): 25 | import shutil 26 | 27 | shutil.rmtree(WORKING_DIR) 28 | 29 | os.mkdir(WORKING_DIR) 30 | 31 | 32 | async def llm_model_func( 33 | prompt, system_prompt=None, history_messages=[], keyword_extraction=False, **kwargs 34 | ) -> str: 35 | # 1. Initialize the GenAI Client with your Gemini API Key 36 | client = genai.Client(api_key=gemini_api_key) 37 | 38 | # 2. Combine prompts: system prompt, history, and user prompt 39 | if history_messages is None: 40 | history_messages = [] 41 | 42 | combined_prompt = "" 43 | if system_prompt: 44 | combined_prompt += f"{system_prompt}\n" 45 | 46 | for msg in history_messages: 47 | # Each msg is expected to be a dict: {"role": "...", "content": "..."} 48 | combined_prompt += f"{msg['role']}: {msg['content']}\n" 49 | 50 | # Finally, add the new user prompt 51 | combined_prompt += f"user: {prompt}" 52 | 53 | # 3. Call the Gemini model 54 | response = client.models.generate_content( 55 | model="gemini-1.5-flash", 56 | contents=[combined_prompt], 57 | config=types.GenerateContentConfig(max_output_tokens=500, temperature=0.1), 58 | ) 59 | 60 | # 4. Return the response text 61 | return response.text 62 | 63 | 64 | async def embedding_func(texts: list[str]) -> np.ndarray: 65 | model = SentenceTransformer("all-MiniLM-L6-v2") 66 | embeddings = model.encode(texts, convert_to_numpy=True) 67 | return embeddings 68 | 69 | 70 | async def initialize_rag(): 71 | rag = LightRAG( 72 | working_dir=WORKING_DIR, 73 | llm_model_func=llm_model_func, 74 | embedding_func=EmbeddingFunc( 75 | embedding_dim=384, 76 | max_token_size=8192, 77 | func=embedding_func, 78 | ), 79 | ) 80 | 81 | await rag.initialize_storages() 82 | await initialize_pipeline_status() 83 | 84 | return rag 85 | 86 | 87 | def main(): 88 | # Initialize RAG instance 89 | rag = asyncio.run(initialize_rag()) 90 | file_path = "story.txt" 91 | with open(file_path, "r") as file: 92 | text = file.read() 93 | 94 | rag.insert(text) 95 | 96 | response = rag.query( 97 | query="What is the main theme of the story?", 98 | param=QueryParam(mode="hybrid", top_k=5, response_type="single line"), 99 | ) 100 | 101 | print(response) 102 | 103 | 104 | if __name__ == "__main__": 105 | main() 106 | -------------------------------------------------------------------------------- /examples/lightrag_openai_mongodb_graph_demo.py: -------------------------------------------------------------------------------- 1 | import os 2 | import asyncio 3 | from lightrag import LightRAG, QueryParam 4 | from lightrag.llm.openai import gpt_4o_mini_complete, openai_embed 5 | from lightrag.utils import EmbeddingFunc 6 | import numpy as np 7 | from lightrag.kg.shared_storage import initialize_pipeline_status 8 | 9 | ######### 10 | # Uncomment the below two lines if running in a jupyter notebook to handle the async nature of rag.insert() 11 | # import nest_asyncio 12 | # nest_asyncio.apply() 13 | ######### 14 | WORKING_DIR = "./mongodb_test_dir" 15 | if not os.path.exists(WORKING_DIR): 16 | os.mkdir(WORKING_DIR) 17 | 18 | 19 | os.environ["OPENAI_API_KEY"] = "sk-" 20 | os.environ["MONGO_URI"] = "mongodb://0.0.0.0:27017/?directConnection=true" 21 | os.environ["MONGO_DATABASE"] = "LightRAG" 22 | os.environ["MONGO_KG_COLLECTION"] = "MDB_KG" 23 | 24 | # Embedding Configuration and Functions 25 | EMBEDDING_MODEL = os.environ.get("EMBEDDING_MODEL", "text-embedding-3-large") 26 | EMBEDDING_MAX_TOKEN_SIZE = int(os.environ.get("EMBEDDING_MAX_TOKEN_SIZE", 8192)) 27 | 28 | 29 | async def embedding_func(texts: list[str]) -> np.ndarray: 30 | return await openai_embed( 31 | texts, 32 | model=EMBEDDING_MODEL, 33 | ) 34 | 35 | 36 | async def get_embedding_dimension(): 37 | test_text = ["This is a test sentence."] 38 | embedding = await embedding_func(test_text) 39 | return embedding.shape[1] 40 | 41 | 42 | async def create_embedding_function_instance(): 43 | # Get embedding dimension 44 | embedding_dimension = await get_embedding_dimension() 45 | # Create embedding function instance 46 | return EmbeddingFunc( 47 | embedding_dim=embedding_dimension, 48 | max_token_size=EMBEDDING_MAX_TOKEN_SIZE, 49 | func=embedding_func, 50 | ) 51 | 52 | 53 | async def initialize_rag(): 54 | embedding_func_instance = await create_embedding_function_instance() 55 | 56 | rag = LightRAG( 57 | working_dir=WORKING_DIR, 58 | llm_model_func=gpt_4o_mini_complete, 59 | embedding_func=embedding_func_instance, 60 | graph_storage="MongoGraphStorage", 61 | log_level="DEBUG", 62 | ) 63 | 64 | await rag.initialize_storages() 65 | await initialize_pipeline_status() 66 | 67 | return rag 68 | 69 | 70 | def main(): 71 | # Initialize RAG instance 72 | rag = asyncio.run(initialize_rag()) 73 | 74 | with open("./book.txt", "r", encoding="utf-8") as f: 75 | rag.insert(f.read()) 76 | 77 | # Perform naive search 78 | print( 79 | rag.query( 80 | "What are the top themes in this story?", param=QueryParam(mode="naive") 81 | ) 82 | ) 83 | 84 | # Perform local search 85 | print( 86 | rag.query( 87 | "What are the top themes in this story?", param=QueryParam(mode="local") 88 | ) 89 | ) 90 | 91 | # Perform global search 92 | print( 93 | rag.query( 94 | "What are the top themes in this story?", param=QueryParam(mode="global") 95 | ) 96 | ) 97 | 98 | # Perform hybrid search 99 | print( 100 | rag.query( 101 | "What are the top themes in this story?", param=QueryParam(mode="hybrid") 102 | ) 103 | ) 104 | 105 | 106 | if __name__ == "__main__": 107 | main() 108 | -------------------------------------------------------------------------------- /examples/unofficial-sample/lightrag_bedrock_demo.py: -------------------------------------------------------------------------------- 1 | """ 2 | LightRAG meets Amazon Bedrock ⛰️ 3 | """ 4 | 5 | import os 6 | import logging 7 | 8 | from lightrag import LightRAG, QueryParam 9 | from lightrag.llm.bedrock import bedrock_complete, bedrock_embed 10 | from lightrag.utils import EmbeddingFunc 11 | from lightrag.kg.shared_storage import initialize_pipeline_status 12 | 13 | import asyncio 14 | import nest_asyncio 15 | 16 | nest_asyncio.apply() 17 | 18 | logging.getLogger("aiobotocore").setLevel(logging.WARNING) 19 | 20 | WORKING_DIR = "./dickens" 21 | if not os.path.exists(WORKING_DIR): 22 | os.mkdir(WORKING_DIR) 23 | 24 | 25 | async def initialize_rag(): 26 | rag = LightRAG( 27 | working_dir=WORKING_DIR, 28 | llm_model_func=bedrock_complete, 29 | llm_model_name="Anthropic Claude 3 Haiku // Amazon Bedrock", 30 | embedding_func=EmbeddingFunc( 31 | embedding_dim=1024, max_token_size=8192, func=bedrock_embed 32 | ), 33 | ) 34 | 35 | await rag.initialize_storages() 36 | await initialize_pipeline_status() 37 | 38 | return rag 39 | 40 | 41 | def main(): 42 | rag = asyncio.run(initialize_rag()) 43 | 44 | with open("./book.txt", "r", encoding="utf-8") as f: 45 | rag.insert(f.read()) 46 | 47 | for mode in ["naive", "local", "global", "hybrid"]: 48 | print("\n+-" + "-" * len(mode) + "-+") 49 | print(f"| {mode.capitalize()} |") 50 | print("+-" + "-" * len(mode) + "-+\n") 51 | print( 52 | rag.query( 53 | "What are the top themes in this story?", param=QueryParam(mode=mode) 54 | ) 55 | ) 56 | 57 | 58 | if __name__ == "__main__": 59 | main() 60 | -------------------------------------------------------------------------------- /examples/unofficial-sample/lightrag_hf_demo.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from lightrag import LightRAG, QueryParam 4 | from lightrag.llm.hf import hf_model_complete, hf_embed 5 | from lightrag.utils import EmbeddingFunc 6 | from transformers import AutoModel, AutoTokenizer 7 | from lightrag.kg.shared_storage import initialize_pipeline_status 8 | 9 | import asyncio 10 | import nest_asyncio 11 | 12 | nest_asyncio.apply() 13 | 14 | WORKING_DIR = "./dickens" 15 | 16 | if not os.path.exists(WORKING_DIR): 17 | os.mkdir(WORKING_DIR) 18 | 19 | 20 | async def initialize_rag(): 21 | rag = LightRAG( 22 | working_dir=WORKING_DIR, 23 | llm_model_func=hf_model_complete, 24 | llm_model_name="meta-llama/Llama-3.1-8B-Instruct", 25 | embedding_func=EmbeddingFunc( 26 | embedding_dim=384, 27 | max_token_size=5000, 28 | func=lambda texts: hf_embed( 29 | texts, 30 | tokenizer=AutoTokenizer.from_pretrained( 31 | "sentence-transformers/all-MiniLM-L6-v2" 32 | ), 33 | embed_model=AutoModel.from_pretrained( 34 | "sentence-transformers/all-MiniLM-L6-v2" 35 | ), 36 | ), 37 | ), 38 | ) 39 | 40 | await rag.initialize_storages() 41 | await initialize_pipeline_status() 42 | 43 | return rag 44 | 45 | 46 | def main(): 47 | rag = asyncio.run(initialize_rag()) 48 | 49 | with open("./book.txt", "r", encoding="utf-8") as f: 50 | rag.insert(f.read()) 51 | 52 | # Perform naive search 53 | print( 54 | rag.query( 55 | "What are the top themes in this story?", param=QueryParam(mode="naive") 56 | ) 57 | ) 58 | 59 | # Perform local search 60 | print( 61 | rag.query( 62 | "What are the top themes in this story?", param=QueryParam(mode="local") 63 | ) 64 | ) 65 | 66 | # Perform global search 67 | print( 68 | rag.query( 69 | "What are the top themes in this story?", param=QueryParam(mode="global") 70 | ) 71 | ) 72 | 73 | # Perform hybrid search 74 | print( 75 | rag.query( 76 | "What are the top themes in this story?", param=QueryParam(mode="hybrid") 77 | ) 78 | ) 79 | 80 | 81 | if __name__ == "__main__": 82 | main() 83 | -------------------------------------------------------------------------------- /examples/unofficial-sample/lightrag_openai_neo4j_milvus_redis_demo.py: -------------------------------------------------------------------------------- 1 | import os 2 | import asyncio 3 | from lightrag import LightRAG, QueryParam 4 | from lightrag.llm.ollama import ollama_embed, openai_complete_if_cache 5 | from lightrag.utils import EmbeddingFunc 6 | from lightrag.kg.shared_storage import initialize_pipeline_status 7 | 8 | # WorkingDir 9 | ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) 10 | WORKING_DIR = os.path.join(ROOT_DIR, "myKG") 11 | if not os.path.exists(WORKING_DIR): 12 | os.mkdir(WORKING_DIR) 13 | print(f"WorkingDir: {WORKING_DIR}") 14 | 15 | # redis 16 | os.environ["REDIS_URI"] = "redis://localhost:6379" 17 | 18 | # neo4j 19 | BATCH_SIZE_NODES = 500 20 | BATCH_SIZE_EDGES = 100 21 | os.environ["NEO4J_URI"] = "neo4j://localhost:7687" 22 | os.environ["NEO4J_USERNAME"] = "neo4j" 23 | os.environ["NEO4J_PASSWORD"] = "12345678" 24 | 25 | # milvus 26 | os.environ["MILVUS_URI"] = "http://localhost:19530" 27 | os.environ["MILVUS_USER"] = "root" 28 | os.environ["MILVUS_PASSWORD"] = "Milvus" 29 | os.environ["MILVUS_DB_NAME"] = "lightrag" 30 | 31 | 32 | async def llm_model_func( 33 | prompt, system_prompt=None, history_messages=[], keyword_extraction=False, **kwargs 34 | ) -> str: 35 | return await openai_complete_if_cache( 36 | "deepseek-chat", 37 | prompt, 38 | system_prompt=system_prompt, 39 | history_messages=history_messages, 40 | api_key="", 41 | base_url="", 42 | **kwargs, 43 | ) 44 | 45 | 46 | embedding_func = EmbeddingFunc( 47 | embedding_dim=768, 48 | max_token_size=512, 49 | func=lambda texts: ollama_embed( 50 | texts, embed_model="shaw/dmeta-embedding-zh", host="http://117.50.173.35:11434" 51 | ), 52 | ) 53 | 54 | 55 | async def initialize_rag(): 56 | rag = LightRAG( 57 | working_dir=WORKING_DIR, 58 | llm_model_func=llm_model_func, 59 | summary_max_tokens=10000, 60 | embedding_func=embedding_func, 61 | chunk_token_size=512, 62 | chunk_overlap_token_size=256, 63 | kv_storage="RedisKVStorage", 64 | graph_storage="Neo4JStorage", 65 | vector_storage="MilvusVectorDBStorage", 66 | doc_status_storage="RedisKVStorage", 67 | ) 68 | 69 | await rag.initialize_storages() 70 | await initialize_pipeline_status() 71 | 72 | return rag 73 | 74 | 75 | def main(): 76 | # Initialize RAG instance 77 | rag = asyncio.run(initialize_rag()) 78 | 79 | with open("./book.txt", "r", encoding="utf-8") as f: 80 | rag.insert(f.read()) 81 | 82 | # Perform naive search 83 | print( 84 | rag.query( 85 | "What are the top themes in this story?", param=QueryParam(mode="naive") 86 | ) 87 | ) 88 | 89 | # Perform local search 90 | print( 91 | rag.query( 92 | "What are the top themes in this story?", param=QueryParam(mode="local") 93 | ) 94 | ) 95 | 96 | # Perform global search 97 | print( 98 | rag.query( 99 | "What are the top themes in this story?", param=QueryParam(mode="global") 100 | ) 101 | ) 102 | 103 | # Perform hybrid search 104 | print( 105 | rag.query( 106 | "What are the top themes in this story?", param=QueryParam(mode="hybrid") 107 | ) 108 | ) 109 | 110 | 111 | if __name__ == "__main__": 112 | main() 113 | -------------------------------------------------------------------------------- /k8s-deploy/databases/00-config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Get the directory where this script is located 4 | DATABASE_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 5 | source "$DATABASE_SCRIPT_DIR/scripts/common.sh" 6 | 7 | # Namespace configuration 8 | NAMESPACE="rag" 9 | # version 10 | KB_VERSION="1.0.0-beta.48" 11 | ADDON_CLUSTER_CHART_VERSION="1.0.0-alpha.0" 12 | # Helm repository 13 | HELM_REPO="https://apecloud.github.io/helm-charts" 14 | 15 | # Set to true to enable the database, false to disable 16 | ENABLE_POSTGRESQL=true 17 | ENABLE_REDIS=false 18 | ENABLE_QDRANT=false 19 | ENABLE_NEO4J=true 20 | ENABLE_ELASTICSEARCH=false 21 | ENABLE_MONGODB=false 22 | -------------------------------------------------------------------------------- /k8s-deploy/databases/01-prepare.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Get the directory where this script is located 4 | DATABASE_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 5 | # Load configuration file 6 | source "$DATABASE_SCRIPT_DIR/00-config.sh" 7 | 8 | check_dependencies 9 | 10 | # Check if KubeBlocks is already installed, install it if it is not. 11 | source "$DATABASE_SCRIPT_DIR/install-kubeblocks.sh" 12 | 13 | # Create namespaces 14 | print "Creating namespaces..." 15 | kubectl create namespace $NAMESPACE 2>/dev/null || true 16 | 17 | # Install database addons 18 | print "Installing KubeBlocks database addons..." 19 | 20 | # Add and update Helm repository 21 | print "Adding and updating KubeBlocks Helm repository..." 22 | helm repo add kubeblocks $HELM_REPO 23 | helm repo update 24 | # Install database addons based on configuration 25 | [ "$ENABLE_POSTGRESQL" = true ] && print "Installing PostgreSQL addon..." && helm upgrade --install kb-addon-postgresql kubeblocks/postgresql --namespace kb-system --version $ADDON_CLUSTER_CHART_VERSION 26 | [ "$ENABLE_REDIS" = true ] && print "Installing Redis addon..." && helm upgrade --install kb-addon-redis kubeblocks/redis --namespace kb-system --version $ADDON_CLUSTER_CHART_VERSION 27 | [ "$ENABLE_ELASTICSEARCH" = true ] && print "Installing Elasticsearch addon..." && helm upgrade --install kb-addon-elasticsearch kubeblocks/elasticsearch --namespace kb-system --version $ADDON_CLUSTER_CHART_VERSION 28 | [ "$ENABLE_QDRANT" = true ] && print "Installing Qdrant addon..." && helm upgrade --install kb-addon-qdrant kubeblocks/qdrant --namespace kb-system --version $ADDON_CLUSTER_CHART_VERSION 29 | [ "$ENABLE_MONGODB" = true ] && print "Installing MongoDB addon..." && helm upgrade --install kb-addon-mongodb kubeblocks/mongodb --namespace kb-system --version $ADDON_CLUSTER_CHART_VERSION 30 | [ "$ENABLE_NEO4J" = true ] && print "Installing Neo4j addon..." && helm upgrade --install kb-addon-neo4j kubeblocks/neo4j --namespace kb-system --version $ADDON_CLUSTER_CHART_VERSION 31 | 32 | print_success "KubeBlocks database addons installation completed!" 33 | print "Now you can run 02-install-database.sh to install database clusters" 34 | -------------------------------------------------------------------------------- /k8s-deploy/databases/03-uninstall-database.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Get the directory where this script is located 4 | DATABASE_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 5 | 6 | # Load configuration file 7 | source "$DATABASE_SCRIPT_DIR/00-config.sh" 8 | 9 | print "Uninstalling database clusters..." 10 | 11 | # Uninstall database clusters based on configuration 12 | [ "$ENABLE_POSTGRESQL" = true ] && print "Uninstalling PostgreSQL cluster..." && helm uninstall pg-cluster --namespace $NAMESPACE 2>/dev/null || true 13 | [ "$ENABLE_REDIS" = true ] && print "Uninstalling Redis cluster..." && helm uninstall redis-cluster --namespace $NAMESPACE 2>/dev/null || true 14 | [ "$ENABLE_ELASTICSEARCH" = true ] && print "Uninstalling Elasticsearch cluster..." && helm uninstall es-cluster --namespace $NAMESPACE 2>/dev/null || true 15 | [ "$ENABLE_QDRANT" = true ] && print "Uninstalling Qdrant cluster..." && helm uninstall qdrant-cluster --namespace $NAMESPACE 2>/dev/null || true 16 | [ "$ENABLE_MONGODB" = true ] && print "Uninstalling MongoDB cluster..." && helm uninstall mongodb-cluster --namespace $NAMESPACE 2>/dev/null || true 17 | [ "$ENABLE_NEO4J" = true ] && print "Uninstalling Neo4j cluster..." && helm uninstall neo4j-cluster --namespace $NAMESPACE 2>/dev/null || true 18 | 19 | print_success "Database clusters uninstalled" 20 | print "To uninstall database addons and KubeBlocks, run 04-cleanup.sh" 21 | -------------------------------------------------------------------------------- /k8s-deploy/databases/04-cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Get the directory where this script is located 4 | DATABASE_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 5 | 6 | # Load configuration file 7 | source "$DATABASE_SCRIPT_DIR/00-config.sh" 8 | 9 | print "Uninstalling KubeBlocks database addons..." 10 | 11 | # Uninstall database addons based on configuration 12 | [ "$ENABLE_POSTGRESQL" = true ] && print "Uninstalling PostgreSQL addon..." && helm uninstall kb-addon-postgresql --namespace kb-system 2>/dev/null || true 13 | [ "$ENABLE_REDIS" = true ] && print "Uninstalling Redis addon..." && helm uninstall kb-addon-redis --namespace kb-system 2>/dev/null || true 14 | [ "$ENABLE_ELASTICSEARCH" = true ] && print "Uninstalling Elasticsearch addon..." && helm uninstall kb-addon-elasticsearch --namespace kb-system 2>/dev/null || true 15 | [ "$ENABLE_QDRANT" = true ] && print "Uninstalling Qdrant addon..." && helm uninstall kb-addon-qdrant --namespace kb-system 2>/dev/null || true 16 | [ "$ENABLE_MONGODB" = true ] && print "Uninstalling MongoDB addon..." && helm uninstall kb-addon-mongodb --namespace kb-system 2>/dev/null || true 17 | [ "$ENABLE_NEO4J" = true ] && print "Uninstalling Neo4j addon..." && helm uninstall kb-addon-neo4j --namespace kb-system 2>/dev/null || true 18 | 19 | print_success "Database addons uninstallation completed!" 20 | 21 | source "$DATABASE_SCRIPT_DIR/uninstall-kubeblocks.sh" 22 | 23 | kubectl delete namespace $NAMESPACE 24 | kubectl delete namespace kb-system 25 | 26 | print_success "KubeBlocks uninstallation completed!" 27 | -------------------------------------------------------------------------------- /k8s-deploy/databases/elasticsearch/values.yaml: -------------------------------------------------------------------------------- 1 | ## description: The version of ElasticSearch. 2 | ## default: 8.8.2 3 | version: "8.8.2" 4 | 5 | ## description: Mode for ElasticSearch 6 | ## default: multi-node 7 | ## one of: [single-node, multi-node] 8 | mode: single-node 9 | 10 | ## description: The number of replicas, for single-node mode, the replicas is 1, for multi-node mode, the default replicas is 3. 11 | ## default: 1 12 | ## minimum: 1 13 | ## maximum: 5 14 | replicas: 1 15 | 16 | ## description: CPU cores. 17 | ## default: 1 18 | ## minimum: 0.5 19 | ## maximum: 64 20 | cpu: 1 21 | 22 | ## description: Memory, the unit is Gi. 23 | ## default: 2 24 | ## minimum: 1 25 | ## maximum: 1000 26 | memory: 2 27 | 28 | ## description: Storage size, the unit is Gi. 29 | ## default: 20 30 | ## minimum: 1 31 | ## maximum: 10000 32 | storage: 5 33 | 34 | extra: 35 | terminationPolicy: Delete 36 | disableExporter: true 37 | -------------------------------------------------------------------------------- /k8s-deploy/databases/install-kubeblocks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Get the directory where this script is located 4 | DATABASE_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 5 | # Load configuration file 6 | source "$DATABASE_SCRIPT_DIR/00-config.sh" 7 | 8 | # Check dependencies 9 | check_dependencies 10 | 11 | # Function for installing KubeBlocks 12 | install_kubeblocks() { 13 | print "Ready to install KubeBlocks." 14 | 15 | # Install CSI Snapshotter CRDs 16 | kubectl create -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v8.2.0/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml 17 | kubectl create -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v8.2.0/client/config/crd/snapshot.storage.k8s.io_volumesnapshots.yaml 18 | kubectl create -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v8.2.0/client/config/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml 19 | 20 | # Add and update Piraeus repository 21 | helm repo add piraeus-charts https://piraeus.io/helm-charts/ 22 | helm repo update 23 | 24 | # Install snapshot controller 25 | helm install snapshot-controller piraeus-charts/snapshot-controller -n kb-system --create-namespace 26 | kubectl wait --for=condition=ready pods -l app.kubernetes.io/name=snapshot-controller -n kb-system --timeout=60s 27 | print_success "snapshot-controller installation complete!" 28 | 29 | # Install KubeBlocks CRDs 30 | kubectl create -f https://github.com/apecloud/kubeblocks/releases/download/v${KB_VERSION}/kubeblocks_crds.yaml 31 | 32 | # Add and update KubeBlocks repository 33 | helm repo add kubeblocks $HELM_REPO 34 | helm repo update 35 | 36 | # Install KubeBlocks 37 | helm install kubeblocks kubeblocks/kubeblocks --namespace kb-system --create-namespace --version=${KB_VERSION} 38 | 39 | # Verify installation 40 | print "Waiting for KubeBlocks to be ready..." 41 | kubectl wait --for=condition=ready pods -l app.kubernetes.io/instance=kubeblocks -n kb-system --timeout=120s 42 | print_success "KubeBlocks installation complete!" 43 | } 44 | 45 | # Check if KubeBlocks is already installed 46 | print "Checking if KubeBlocks is already installed in kb-system namespace..." 47 | if kubectl get namespace kb-system &>/dev/null && kubectl get deployment kubeblocks -n kb-system &>/dev/null; then 48 | print_success "KubeBlocks is already installed in kb-system namespace." 49 | else 50 | # Call the function to install KubeBlocks 51 | install_kubeblocks 52 | fi 53 | -------------------------------------------------------------------------------- /k8s-deploy/databases/mongodb/values.yaml: -------------------------------------------------------------------------------- 1 | ## description: Cluster version. 2 | ## default: 6.0.16 3 | ## one of: [8.0.8, 8.0.6, 8.0.4, 7.0.19, 7.0.16, 7.0.12, 6.0.22, 6.0.20, 6.0.16, 5.0.30, 5.0.28, 4.4.29, 4.2.24, 4.0.28] 4 | version: 6.0.16 5 | 6 | ## description: Cluster topology mode. 7 | ## default: standalone 8 | ## one of: [standalone, replicaset] 9 | mode: standalone 10 | 11 | ## description: CPU cores. 12 | ## default: 0.5 13 | ## minimum: 0.5 14 | ## maximum: 64 15 | cpu: 1 16 | 17 | ## description: Memory, the unit is Gi. 18 | ## default: 0.5 19 | ## minimum: 0.5 20 | ## maximum: 1000 21 | memory: 1 22 | 23 | ## description: Storage size, the unit is Gi. 24 | ## default: 20 25 | ## minimum: 1 26 | ## maximum: 10000 27 | storage: 20 28 | 29 | ## default: enabled 30 | ## one of: [enabled, disabled] 31 | hostnetwork: "disabled" 32 | 33 | extra: 34 | terminationPolicy: Delete 35 | -------------------------------------------------------------------------------- /k8s-deploy/databases/neo4j/values.yaml: -------------------------------------------------------------------------------- 1 | # Version 2 | # description: Cluster version. 3 | # default: 5.26.5 4 | # one of: [5.26.5, 4.4.42] 5 | version: 5.26.5 6 | 7 | # Mode 8 | # description: Cluster topology mode. 9 | # default: singlealone 10 | # one of: [singlealone] 11 | mode: singlealone 12 | 13 | # CPU 14 | # description: CPU cores. 15 | # default: 2 16 | # minimum: 2 17 | # maximum: 64 18 | cpu: 2 19 | 20 | # Memory(Gi) 21 | # description: Memory, the unit is Gi. 22 | # default: 2 23 | # minimum: 2 24 | # maximum: 1000 25 | memory: 4 26 | 27 | # Storage(Gi) 28 | # description: Storage size, the unit is Gi. 29 | # default: 20 30 | # minimum: 1 31 | # maximum: 10000 32 | storage: 20 33 | 34 | # Replicas 35 | # description: The number of replicas, for standalone mode, the replicas is 1, for replicaset mode, the default replicas is 3. 36 | # default: 1 37 | # minimum: 1 38 | # maximum: 5 39 | replicas: 1 40 | 41 | # Storage Class Name 42 | # description: Storage class name of the data volume 43 | storageClassName: "" 44 | 45 | extra: 46 | terminationPolicy: Delete 47 | -------------------------------------------------------------------------------- /k8s-deploy/databases/postgresql/values.yaml: -------------------------------------------------------------------------------- 1 | ## description: service version. 2 | ## default: 15.7.0 3 | version: 16.4.0 4 | 5 | ## mode postgresql cluster topology mode replication 6 | mode: replication 7 | 8 | ## description: The number of replicas, for standalone mode, the replicas is 1, for replication mode, the default replicas is 2. 9 | ## default: 1 10 | ## minimum: 1 11 | ## maximum: 5 12 | replicas: 2 13 | 14 | ## description: CPU cores. 15 | ## default: 0.5 16 | ## minimum: 0.5 17 | ## maximum: 64 18 | cpu: 1 19 | 20 | ## description: Memory, the unit is Gi. 21 | ## default: 0.5 22 | ## minimum: 0.5 23 | ## maximum: 1000 24 | memory: 1 25 | 26 | ## description: Storage size, the unit is Gi. 27 | ## default: 20 28 | ## minimum: 1 29 | ## maximum: 10000 30 | storage: 5 31 | 32 | ## terminationPolicy define Cluster termination policy. One of DoNotTerminate, Delete, WipeOut. 33 | terminationPolicy: Delete 34 | -------------------------------------------------------------------------------- /k8s-deploy/databases/qdrant/values.yaml: -------------------------------------------------------------------------------- 1 | ## description: The version of Qdrant. 2 | ## default: 1.10.0 3 | version: 1.10.0 4 | 5 | ## description: The number of replicas. 6 | ## default: 1 7 | ## minimum: 1 8 | ## maximum: 16 9 | replicas: 1 10 | 11 | ## description: CPU cores. 12 | ## default: 1 13 | ## minimum: 0.5 14 | ## maximum: 64 15 | cpu: 1 16 | 17 | ## description: Memory, the unit is Gi. 18 | ## default: 2 19 | ## minimum: 0.5 20 | ## maximum: 1000 21 | memory: 1 22 | 23 | ## description: Storage size, the unit is Gi. 24 | ## default: 20 25 | ## minimum: 1 26 | ## maximum: 10000 27 | storage: 20 28 | 29 | ## customized default values to override kblib chart's values 30 | extra: 31 | terminationPolicy: Delete 32 | -------------------------------------------------------------------------------- /k8s-deploy/databases/redis/values.yaml: -------------------------------------------------------------------------------- 1 | ## description: Cluster version. 2 | ## default: 7.2.7 3 | version: 7.2.7 4 | 5 | ## description: Cluster topology mode. 6 | ## default: replication 7 | ## one of: [standalone, replication, cluster, replication-twemproxy] 8 | mode: standalone 9 | 10 | ## description: The number of replicas, for standalone mode, the replicas is 1, for replication mode, the default replicas is 2. 11 | ## default: 1 12 | ## minimum: 1 13 | ## maximum: 5 14 | replicas: 1 15 | 16 | ## description: CPU cores. 17 | ## default: 0.5 18 | ## minimum: 0.5 19 | ## maximum: 64 20 | cpu: 0.5 21 | 22 | ## description: Memory, the unit is Gi. 23 | ## default: 0.5 24 | ## minimum: 0.5 25 | ## maximum: 1000 26 | memory: 1 27 | 28 | ## description: Storage size, the unit is Gi. 29 | ## default: 20 30 | ## minimum: 1 31 | ## maximum: 10000 32 | storage: 20 33 | extra: 34 | disableExporter: true 35 | -------------------------------------------------------------------------------- /k8s-deploy/databases/scripts/common.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | print_title() { 4 | echo "============================================" 5 | echo "$1" 6 | echo "============================================" 7 | } 8 | 9 | print_success() { 10 | echo "✅ $1" 11 | } 12 | 13 | print_error() { 14 | echo "❌ $1" 15 | } 16 | 17 | print_warning() { 18 | echo "⚠️ $1" 19 | } 20 | 21 | print_info() { 22 | echo "🔹 $1" 23 | } 24 | 25 | print() { 26 | echo "$1" 27 | } 28 | 29 | # Check dependencies 30 | check_dependencies(){ 31 | print "Checking dependencies..." 32 | command -v kubectl >/dev/null 2>&1 || { print "Error: kubectl command not found"; exit 1; } 33 | command -v helm >/dev/null 2>&1 || { print "Error: helm command not found"; exit 1; } 34 | 35 | # Check if Kubernetes is available 36 | print "Checking if Kubernetes is available..." 37 | kubectl cluster-info &>/dev/null 38 | if [ $? -ne 0 ]; then 39 | print "Error: Kubernetes cluster is not accessible. Please ensure you have proper access to a Kubernetes cluster." 40 | exit 1 41 | fi 42 | print_success "Kubernetes cluster is accessible." 43 | } 44 | -------------------------------------------------------------------------------- /k8s-deploy/databases/uninstall-kubeblocks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Get the directory where this script is located 4 | DATABASE_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 5 | # Load configuration file 6 | source "$DATABASE_SCRIPT_DIR/00-config.sh" 7 | 8 | # Check dependencies 9 | print "Checking dependencies..." 10 | command -v kubectl >/dev/null 2>&1 || { print "Error: kubectl command not found"; exit 1; } 11 | command -v helm >/dev/null 2>&1 || { print "Error: helm command not found"; exit 1; } 12 | 13 | print "Checking if Kubernetes is available..." 14 | if ! kubectl cluster-info &>/dev/null; then 15 | print "Error: Kubernetes cluster is not accessible. Please ensure you have proper access to a Kubernetes cluster." 16 | exit 1 17 | fi 18 | 19 | print "Checking if KubeBlocks is installed in kb-system namespace..." 20 | if ! kubectl get namespace kb-system &>/dev/null; then 21 | print "KubeBlocks is not installed in kb-system namespace." 22 | exit 0 23 | fi 24 | 25 | # Function for uninstalling KubeBlocks 26 | uninstall_kubeblocks() { 27 | print "Uninstalling KubeBlocks..." 28 | 29 | # Uninstall KubeBlocks Helm chart 30 | helm uninstall kubeblocks -n kb-system 31 | 32 | # Uninstall snapshot controller 33 | helm uninstall snapshot-controller -n kb-system 34 | 35 | # Delete KubeBlocks CRDs 36 | kubectl delete -f https://github.com/apecloud/kubeblocks/releases/download/v${KB_VERSION}/kubeblocks_crds.yaml --ignore-not-found=true 37 | 38 | # Delete CSI Snapshotter CRDs 39 | kubectl delete -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v8.2.0/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml --ignore-not-found=true 40 | kubectl delete -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v8.2.0/client/config/crd/snapshot.storage.k8s.io_volumesnapshots.yaml --ignore-not-found=true 41 | kubectl delete -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v8.2.0/client/config/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml --ignore-not-found=true 42 | 43 | # Delete the kb-system namespace 44 | print "Waiting for resources to be removed..." 45 | kubectl delete namespace kb-system --timeout=180s 46 | 47 | print "KubeBlocks has been successfully uninstalled!" 48 | } 49 | 50 | # Call the function to uninstall KubeBlocks 51 | uninstall_kubeblocks 52 | -------------------------------------------------------------------------------- /k8s-deploy/install_lightrag_dev.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | NAMESPACE=rag 4 | 5 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 6 | 7 | check_dependencies(){ 8 | echo "Checking dependencies..." 9 | command -v kubectl >/dev/null 2>&1 || { echo "Error: kubectl command not found"; exit 1; } 10 | command -v helm >/dev/null 2>&1 || { echo "Error: helm command not found"; exit 1; } 11 | 12 | # Check if Kubernetes is available 13 | echo "Checking if Kubernetes is available..." 14 | kubectl cluster-info &>/dev/null 15 | if [ $? -ne 0 ]; then 16 | echo "Error: Kubernetes cluster is not accessible. Please ensure you have proper access to a Kubernetes cluster." 17 | exit 1 18 | fi 19 | echo "Kubernetes cluster is accessible." 20 | } 21 | 22 | check_dependencies 23 | 24 | if [ -z "$OPENAI_API_KEY" ]; then 25 | echo "OPENAI_API_KEY environment variable is not set" 26 | read -s -p "Enter your OpenAI API key: " OPENAI_API_KEY 27 | if [ -z "$OPENAI_API_KEY" ]; then 28 | echo "Error: OPENAI_API_KEY must be provided" 29 | exit 1 30 | fi 31 | export OPENAI_API_KEY=$OPENAI_API_KEY 32 | fi 33 | 34 | if [ -z "$OPENAI_API_BASE" ]; then 35 | echo "OPENAI_API_BASE environment variable is not set, will use default value" 36 | read -p "Enter OpenAI API base URL (press Enter to skip if not needed): " OPENAI_API_BASE 37 | export OPENAI_API_BASE=$OPENAI_API_BASE 38 | fi 39 | 40 | required_env_vars=("OPENAI_API_BASE" "OPENAI_API_KEY") 41 | 42 | for var in "${required_env_vars[@]}"; do 43 | if [ -z "${!var}" ]; then 44 | echo "Error: $var environment variable is not set" 45 | exit 1 46 | fi 47 | done 48 | 49 | if ! kubectl get namespace rag &> /dev/null; then 50 | echo "creating namespace 'rag'..." 51 | kubectl create namespace rag 52 | fi 53 | 54 | helm upgrade --install lightrag-dev $SCRIPT_DIR/lightrag \ 55 | --namespace rag \ 56 | --set-string env.LIGHTRAG_KV_STORAGE=JsonKVStorage \ 57 | --set-string env.LIGHTRAG_VECTOR_STORAGE=NanoVectorDBStorage \ 58 | --set-string env.LIGHTRAG_GRAPH_STORAGE=NetworkXStorage \ 59 | --set-string env.LIGHTRAG_DOC_STATUS_STORAGE=JsonDocStatusStorage \ 60 | --set-string env.LLM_BINDING=openai \ 61 | --set-string env.LLM_MODEL=gpt-4o-mini \ 62 | --set-string env.LLM_BINDING_HOST=$OPENAI_API_BASE \ 63 | --set-string env.LLM_BINDING_API_KEY=$OPENAI_API_KEY \ 64 | --set-string env.EMBEDDING_BINDING=openai \ 65 | --set-string env.EMBEDDING_MODEL=text-embedding-ada-002 \ 66 | --set-string env.EMBEDDING_DIM=1536 \ 67 | --set-string env.EMBEDDING_BINDING_API_KEY=$OPENAI_API_KEY 68 | 69 | # Wait for LightRAG pod to be ready 70 | echo "" 71 | echo "Waiting for lightrag-dev pod to be ready..." 72 | kubectl wait --for=condition=ready pod -l app.kubernetes.io/instance=lightrag-dev --timeout=300s -n rag 73 | echo "lightrag-dev pod is ready" 74 | echo "" 75 | echo "Running Port-Forward:" 76 | echo " kubectl --namespace rag port-forward svc/lightrag-dev 9621:9621" 77 | echo "===========================================" 78 | echo "" 79 | echo "✅ You can visit LightRAG at: http://localhost:9621" 80 | echo "" 81 | kubectl --namespace rag port-forward svc/lightrag-dev 9621:9621 82 | -------------------------------------------------------------------------------- /k8s-deploy/lightrag/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /k8s-deploy/lightrag/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: lightrag 3 | description: A Helm chart for LightRAG, an efficient and lightweight RAG system 4 | type: application 5 | version: 0.1.0 6 | appVersion: "1.0.0" 7 | maintainers: 8 | - name: LightRAG Team 9 | - name: earayu 10 | email: earayu@gmail.com 11 | -------------------------------------------------------------------------------- /k8s-deploy/lightrag/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | =========================================== 2 | LightRAG has been successfully deployed! 3 | =========================================== 4 | 5 | View application logs: 6 | kubectl logs -f --namespace {{ .Release.Namespace }} deploy/{{ include "lightrag.fullname" . }} 7 | 8 | =========================================== 9 | 10 | Access the application: 11 | {{- if contains "NodePort" .Values.service.type }} 12 | Run these commands to get access information: 13 | ----------------------------------------- 14 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "lightrag.fullname" . }}) 15 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 16 | echo "LightRAG is accessible at: http://$NODE_IP:$NODE_PORT" 17 | ----------------------------------------- 18 | {{- else if contains "LoadBalancer" .Values.service.type }} 19 | Run these commands to get access information (external IP may take a minute to assign): 20 | ----------------------------------------- 21 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "lightrag.fullname" . }} --template "{{ "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}" }}") 22 | echo "LightRAG is accessible at: http://$SERVICE_IP:{{ .Values.service.port }}" 23 | ----------------------------------------- 24 | If SERVICE_IP is empty, retry the command or check service status with: 25 | kubectl get svc --namespace {{ .Release.Namespace }} {{ include "lightrag.fullname" . }} 26 | {{- else if contains "ClusterIP" .Values.service.type }} 27 | For development environments, to access LightRAG from your local machine: 28 | 29 | 1. Run this port-forward command in your terminal: 30 | kubectl --namespace {{ .Release.Namespace }} port-forward svc/{{ include "lightrag.fullname" . }} {{ .Values.service.port }}:{{ .Values.env.PORT }} 31 | 32 | 2. While the command is running, open your browser and navigate to: 33 | http://localhost:{{ .Values.service.port }} 34 | 35 | Note: To stop port-forwarding, press Ctrl+C in the terminal. 36 | {{- end }} 37 | 38 | =========================================== 39 | -------------------------------------------------------------------------------- /k8s-deploy/lightrag/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Application name 3 | */}} 4 | {{- define "lightrag.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Full application name 10 | */}} 11 | {{- define "lightrag.fullname" -}} 12 | {{- default .Release.Name .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 13 | {{- end }} 14 | 15 | {{/* 16 | Common labels 17 | */}} 18 | {{- define "lightrag.labels" -}} 19 | app.kubernetes.io/name: {{ include "lightrag.name" . }} 20 | app.kubernetes.io/instance: {{ .Release.Name }} 21 | app.kubernetes.io/managed-by: {{ .Release.Service }} 22 | {{- end }} 23 | 24 | {{/* 25 | Selector labels 26 | */}} 27 | {{- define "lightrag.selectorLabels" -}} 28 | app.kubernetes.io/name: {{ include "lightrag.name" . }} 29 | app.kubernetes.io/instance: {{ .Release.Name }} 30 | {{- end }} 31 | 32 | {{/* 33 | .env file content 34 | */}} 35 | {{- define "lightrag.envContent" -}} 36 | {{- $first := true -}} 37 | {{- range $key, $val := .Values.env -}} 38 | {{- if not $first -}}{{- "\n" -}}{{- end -}} 39 | {{- $first = false -}} 40 | {{ $key }}={{ $val }} 41 | {{- end -}} 42 | {{- end -}} 43 | -------------------------------------------------------------------------------- /k8s-deploy/lightrag/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "lightrag.fullname" . }} 5 | labels: 6 | {{- include "lightrag.labels" . | nindent 4 }} 7 | spec: 8 | replicas: {{ .Values.replicaCount }} 9 | selector: 10 | matchLabels: 11 | {{- include "lightrag.selectorLabels" . | nindent 6 }} 12 | template: 13 | metadata: 14 | annotations: 15 | checksum/config: {{ include "lightrag.envContent" . | sha256sum }} 16 | labels: 17 | {{- include "lightrag.selectorLabels" . | nindent 8 }} 18 | spec: 19 | containers: 20 | - name: {{ .Chart.Name }} 21 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" 22 | imagePullPolicy: IfNotPresent 23 | ports: 24 | - name: http 25 | containerPort: {{ .Values.env.PORT }} 26 | protocol: TCP 27 | readinessProbe: 28 | httpGet: 29 | path: /health 30 | port: http 31 | initialDelaySeconds: 10 32 | periodSeconds: 5 33 | timeoutSeconds: 2 34 | successThreshold: 1 35 | failureThreshold: 3 36 | resources: 37 | {{- toYaml .Values.resources | nindent 12 }} 38 | volumeMounts: 39 | - name: rag-storage 40 | mountPath: /app/data/rag_storage 41 | - name: inputs 42 | mountPath: /app/data/inputs 43 | - name: env-file 44 | mountPath: /app/.env 45 | subPath: .env 46 | volumes: 47 | - name: env-file 48 | secret: 49 | secretName: {{ include "lightrag.fullname" . }}-env 50 | {{- if .Values.persistence.enabled }} 51 | - name: rag-storage 52 | persistentVolumeClaim: 53 | claimName: {{ include "lightrag.fullname" . }}-rag-storage 54 | - name: inputs 55 | persistentVolumeClaim: 56 | claimName: {{ include "lightrag.fullname" . }}-inputs 57 | {{- else }} 58 | - name: rag-storage 59 | emptyDir: {} 60 | - name: inputs 61 | emptyDir: {} 62 | {{- end }} 63 | -------------------------------------------------------------------------------- /k8s-deploy/lightrag/templates/pvc.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.persistence.enabled }} 2 | --- 3 | apiVersion: v1 4 | kind: PersistentVolumeClaim 5 | metadata: 6 | name: {{ include "lightrag.fullname" . }}-rag-storage 7 | labels: 8 | {{- include "lightrag.labels" . | nindent 4 }} 9 | spec: 10 | accessModes: 11 | - ReadWriteOnce 12 | resources: 13 | requests: 14 | storage: {{ .Values.persistence.ragStorage.size }} 15 | --- 16 | apiVersion: v1 17 | kind: PersistentVolumeClaim 18 | metadata: 19 | name: {{ include "lightrag.fullname" . }}-inputs 20 | labels: 21 | {{- include "lightrag.labels" . | nindent 4 }} 22 | spec: 23 | accessModes: 24 | - ReadWriteOnce 25 | resources: 26 | requests: 27 | storage: {{ .Values.persistence.inputs.size }} 28 | {{- end }} 29 | -------------------------------------------------------------------------------- /k8s-deploy/lightrag/templates/secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: {{ include "lightrag.fullname" . }}-env 5 | labels: 6 | {{- include "lightrag.labels" . | nindent 4 }} 7 | type: Opaque 8 | stringData: 9 | .env: |- 10 | {{- include "lightrag.envContent" . | nindent 4 }} 11 | -------------------------------------------------------------------------------- /k8s-deploy/lightrag/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "lightrag.fullname" . }} 5 | labels: 6 | {{- include "lightrag.labels" . | nindent 4 }} 7 | spec: 8 | type: {{ .Values.service.type }} 9 | ports: 10 | - port: {{ .Values.service.port }} 11 | targetPort: {{ .Values.env.PORT }} 12 | protocol: TCP 13 | name: http 14 | selector: 15 | {{- include "lightrag.selectorLabels" . | nindent 4 }} 16 | -------------------------------------------------------------------------------- /k8s-deploy/lightrag/values.yaml: -------------------------------------------------------------------------------- 1 | replicaCount: 1 2 | 3 | image: 4 | repository: ghcr.io/hkuds/lightrag 5 | tag: latest 6 | 7 | service: 8 | type: ClusterIP 9 | port: 9621 10 | 11 | resources: 12 | limits: 13 | cpu: 1000m 14 | memory: 2Gi 15 | requests: 16 | cpu: 500m 17 | memory: 1Gi 18 | 19 | persistence: 20 | enabled: true 21 | ragStorage: 22 | size: 10Gi 23 | inputs: 24 | size: 5Gi 25 | 26 | env: 27 | HOST: 0.0.0.0 28 | PORT: 9621 29 | WEBUI_TITLE: Graph RAG Engine 30 | WEBUI_DESCRIPTION: Simple and Fast Graph Based RAG System 31 | LLM_BINDING: openai 32 | LLM_MODEL: gpt-4o-mini 33 | LLM_BINDING_HOST: 34 | LLM_BINDING_API_KEY: 35 | EMBEDDING_BINDING: openai 36 | EMBEDDING_MODEL: text-embedding-ada-002 37 | EMBEDDING_DIM: 1536 38 | EMBEDDING_BINDING_API_KEY: 39 | LIGHTRAG_KV_STORAGE: PGKVStorage 40 | LIGHTRAG_VECTOR_STORAGE: PGVectorStorage 41 | # LIGHTRAG_KV_STORAGE: RedisKVStorage 42 | # LIGHTRAG_VECTOR_STORAGE: QdrantVectorDBStorage 43 | LIGHTRAG_GRAPH_STORAGE: Neo4JStorage 44 | LIGHTRAG_DOC_STATUS_STORAGE: PGDocStatusStorage 45 | # Replace with your POSTGRES credentials 46 | POSTGRES_HOST: pg-cluster-postgresql-postgresql 47 | POSTGRES_PORT: 5432 48 | POSTGRES_USER: postgres 49 | POSTGRES_PASSWORD: 50 | POSTGRES_DATABASE: postgres 51 | POSTGRES_WORKSPACE: default 52 | # Replace with your NEO4J credentials 53 | NEO4J_URI: neo4j://neo4j-cluster-neo4j:7687 54 | NEO4J_USERNAME: neo4j 55 | NEO4J_PASSWORD: 56 | # Replace with your Qdrant credentials 57 | QDRANT_URL: http://qdrant-cluster-qdrant-qdrant:6333 58 | # REDIS_URI: redis://default:${REDIS_PASSWORD}@redis-cluster-redis-redis:6379 59 | -------------------------------------------------------------------------------- /k8s-deploy/uninstall_lightrag.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | NAMESPACE=rag 4 | helm uninstall lightrag --namespace $NAMESPACE 5 | -------------------------------------------------------------------------------- /k8s-deploy/uninstall_lightrag_dev.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | NAMESPACE=rag 4 | helm uninstall lightrag-dev --namespace $NAMESPACE 5 | -------------------------------------------------------------------------------- /lightrag-api: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source /home/netman/lightrag-xyj/venv/bin/activate 4 | lightrag-server 5 | -------------------------------------------------------------------------------- /lightrag.service.example: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=LightRAG XYJ Ollama Service 3 | After=network.target 4 | 5 | [Service] 6 | Type=simple 7 | User=netman 8 | # Memory settings 9 | MemoryHigh=8G 10 | MemoryMax=12G 11 | WorkingDirectory=/home/netman/lightrag-xyj 12 | ExecStart=/home/netman/lightrag-xyj/lightrag-api 13 | Restart=always 14 | RestartSec=10 15 | 16 | [Install] 17 | WantedBy=multi-user.target 18 | -------------------------------------------------------------------------------- /lightrag/__init__.py: -------------------------------------------------------------------------------- 1 | from .lightrag import LightRAG as LightRAG, QueryParam as QueryParam 2 | 3 | __version__ = "1.4.7" 4 | __author__ = "Zirui Guo" 5 | __url__ = "https://github.com/HKUDS/LightRAG" 6 | -------------------------------------------------------------------------------- /lightrag/api/.env.aoi.example: -------------------------------------------------------------------------------- 1 | AZURE_OPENAI_API_VERSION=2024-08-01-preview 2 | AZURE_OPENAI_DEPLOYMENT=gpt-4o 3 | AZURE_OPENAI_API_KEY=myapikey 4 | AZURE_OPENAI_ENDPOINT=https://myendpoint.openai.azure.com 5 | 6 | AZURE_EMBEDDING_DEPLOYMENT=text-embedding-3-large 7 | AZURE_EMBEDDING_API_VERSION=2023-05-15 8 | -------------------------------------------------------------------------------- /lightrag/api/.gitignore: -------------------------------------------------------------------------------- 1 | inputs 2 | rag_storage 3 | -------------------------------------------------------------------------------- /lightrag/api/README.assets/image-20250323122538997.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/README.assets/image-20250323122538997.png -------------------------------------------------------------------------------- /lightrag/api/README.assets/image-20250323122754387.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/README.assets/image-20250323122754387.png -------------------------------------------------------------------------------- /lightrag/api/README.assets/image-20250323123011220.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/README.assets/image-20250323123011220.png -------------------------------------------------------------------------------- /lightrag/api/README.assets/image-20250323194750379.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/README.assets/image-20250323194750379.png -------------------------------------------------------------------------------- /lightrag/api/__init__.py: -------------------------------------------------------------------------------- 1 | __api_version__ = "0199" 2 | -------------------------------------------------------------------------------- /lightrag/api/routers/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module contains all the routers for the LightRAG API. 3 | """ 4 | 5 | from .document_routes import router as document_router 6 | from .query_routes import router as query_router 7 | from .graph_routes import router as graph_router 8 | from .ollama_api import OllamaAPI 9 | 10 | __all__ = ["document_router", "query_router", "graph_router", "OllamaAPI"] 11 | -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_AMS-Regular-DMm9YOAa.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_AMS-Regular-DMm9YOAa.woff -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_AMS-Regular-DRggAlZN.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_AMS-Regular-DRggAlZN.ttf -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Fraktur-Regular-CB_wures.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Fraktur-Regular-CB_wures.ttf -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Main-Bold-Cx986IdX.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Main-Bold-Cx986IdX.woff2 -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Main-Bold-Jm3AIy58.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Main-Bold-Jm3AIy58.woff -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Main-Bold-waoOVXN0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Main-Bold-waoOVXN0.ttf -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Main-Italic-3WenGoN9.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Main-Italic-3WenGoN9.ttf -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Main-Italic-BMLOBm91.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Main-Italic-BMLOBm91.woff -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Main-Regular-B22Nviop.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Main-Regular-B22Nviop.woff2 -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Main-Regular-Dr94JaBh.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Main-Regular-Dr94JaBh.woff -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Main-Regular-ypZvNtVU.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Main-Regular-ypZvNtVU.ttf -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Math-Italic-DA0__PXp.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Math-Italic-DA0__PXp.woff -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Math-Italic-flOr_0UB.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Math-Italic-flOr_0UB.ttf -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Math-Italic-t53AETM-.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Math-Italic-t53AETM-.woff2 -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Script-Regular-C5JkGWo-.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Script-Regular-C5JkGWo-.ttf -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Script-Regular-D3wIWfF6.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Script-Regular-D5yQViql.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Script-Regular-D5yQViql.woff -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Size1-Regular-C195tn64.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Size1-Regular-C195tn64.woff -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Size2-Regular-oD1tc_U0.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Size2-Regular-oD1tc_U0.woff -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Size3-Regular-CTq5MqoE.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Size3-Regular-CTq5MqoE.woff -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Size4-Regular-BF-4gkZK.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Size4-Regular-BF-4gkZK.woff -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Size4-Regular-DWFBv043.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Size4-Regular-DWFBv043.ttf -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 -------------------------------------------------------------------------------- /lightrag/api/webui/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf -------------------------------------------------------------------------------- /lightrag/api/webui/assets/_basePickBy-CGXZVaMl.js: -------------------------------------------------------------------------------- 1 | import{e as v,c as b,g as m,k as O,h as P,j as p,l as w,m as c,n as x,t as A,o as N}from"./_baseUniq-D-427rzS.js";import{aU as g,aq as _,aV as $,aW as E,aX as F,aY as I,aZ as M,a_ as y,a$ as B,b0 as T}from"./mermaid-vendor-DGPC_TDM.js";var S=/\s/;function q(n){for(var r=n.length;r--&&S.test(n.charAt(r)););return r}var G=/^\s+/;function H(n){return n&&n.slice(0,q(n)+1).replace(G,"")}var o=NaN,L=/^[-+]0x[0-9a-f]+$/i,R=/^0b[01]+$/i,W=/^0o[0-7]+$/i,X=parseInt;function Y(n){if(typeof n=="number")return n;if(v(n))return o;if(g(n)){var r=typeof n.valueOf=="function"?n.valueOf():n;n=g(r)?r+"":r}if(typeof n!="string")return n===0?n:+n;n=H(n);var t=R.test(n);return t||W.test(n)?X(n.slice(2),t?2:8):L.test(n)?o:+n}var z=1/0,C=17976931348623157e292;function K(n){if(!n)return n===0?n:0;if(n=Y(n),n===z||n===-1/0){var r=n<0?-1:1;return r*C}return n===n?n:0}function U(n){var r=K(n),t=r%1;return r===r?t?r-t:r:0}function fn(n){var r=n==null?0:n.length;return r?b(n):[]}var l=Object.prototype,Z=l.hasOwnProperty,dn=_(function(n,r){n=Object(n);var t=-1,e=r.length,a=e>2?r[2]:void 0;for(a&&$(r[0],r[1],a)&&(e=1);++t-1?a[f?r[i]:i]:void 0}}var J=Math.max;function Q(n,r,t){var e=n==null?0:n.length;if(!e)return-1;var a=t==null?0:U(t);return a<0&&(a=J(e+a,0)),P(n,m(r),a)}var hn=D(Q);function V(n,r){var t=-1,e=I(n)?Array(n.length):[];return p(n,function(a,f,i){e[++t]=r(a,f,i)}),e}function gn(n,r){var t=M(n)?w:V;return t(n,m(r))}var j=Object.prototype,k=j.hasOwnProperty;function nn(n,r){return n!=null&&k.call(n,r)}function mn(n,r){return n!=null&&c(n,r,nn)}function rn(n,r){return n{const e=a.append("rect");if(e.attr("x",t.x),e.attr("y",t.y),e.attr("fill",t.fill),e.attr("stroke",t.stroke),e.attr("width",t.width),e.attr("height",t.height),t.name&&e.attr("name",t.name),t.rx&&e.attr("rx",t.rx),t.ry&&e.attr("ry",t.ry),t.attrs!==void 0)for(const r in t.attrs)e.attr(r,t.attrs[r]);return t.class&&e.attr("class",t.class),e},"drawRect"),d=n((a,t)=>{const e={x:t.startx,y:t.starty,width:t.stopx-t.startx,height:t.stopy-t.starty,fill:t.fill,stroke:t.stroke,class:"rect"};c(a,e).lower()},"drawBackgroundRect"),g=n((a,t)=>{const e=t.text.replace(x," "),r=a.append("text");r.attr("x",t.x),r.attr("y",t.y),r.attr("class","legend"),r.style("text-anchor",t.anchor),t.class&&r.attr("class",t.class);const s=r.append("tspan");return s.attr("x",t.x+t.textMargin*2),s.text(e),r},"drawText"),h=n((a,t,e,r)=>{const s=a.append("image");s.attr("x",t),s.attr("y",e);const i=l.sanitizeUrl(r);s.attr("xlink:href",i)},"drawImage"),m=n((a,t,e,r)=>{const s=a.append("use");s.attr("x",t),s.attr("y",e);const i=l.sanitizeUrl(r);s.attr("xlink:href",`#${i}`)},"drawEmbeddedImage"),y=n(()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),"getNoteRect"),p=n(()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0}),"getTextObj");export{d as a,p as b,m as c,c as d,h as e,g as f,y as g}; 2 | -------------------------------------------------------------------------------- /lightrag/api/webui/assets/chunk-RZ5BOZE2-BhCqM4LN.js: -------------------------------------------------------------------------------- 1 | import{_ as n,d as r,e as d,l as g}from"./mermaid-vendor-DGPC_TDM.js";var u=n((e,t)=>{let o;return t==="sandbox"&&(o=r("#i"+e)),(t==="sandbox"?r(o.nodes()[0].contentDocument.body):r("body")).select(`[id="${e}"]`)},"getDiagramElement"),b=n((e,t,o,i)=>{e.attr("class",o);const{width:a,height:s,x:h,y:x}=l(e,t);d(e,s,a,i);const c=w(h,x,a,s,t);e.attr("viewBox",c),g.debug(`viewBox configured: ${c} with padding: ${t}`)},"setupViewPortForSVG"),l=n((e,t)=>{var i;const o=((i=e.node())==null?void 0:i.getBBox())||{width:0,height:0,x:0,y:0};return{width:o.width+t*2,height:o.height+t*2,x:o.x,y:o.y}},"calculateDimensionsWithPadding"),w=n((e,t,o,i,a)=>`${e-a} ${t-a} ${o} ${i}`,"createViewBox");export{u as g,b as s}; 2 | -------------------------------------------------------------------------------- /lightrag/api/webui/assets/chunk-XZIHB7SX-Bhbr-OLQ.js: -------------------------------------------------------------------------------- 1 | import{_ as s}from"./mermaid-vendor-DGPC_TDM.js";var t,e=(t=class{constructor(i){this.init=i,this.records=this.init()}reset(){this.records=this.init()}},s(t,"ImperativeState"),t);export{e as I}; 2 | -------------------------------------------------------------------------------- /lightrag/api/webui/assets/classDiagram-GIVACNV2-DHufEbeX.js: -------------------------------------------------------------------------------- 1 | import{s as a,c as s,a as e,C as t}from"./chunk-A2AXSNBT-ZI6SIAYy.js";import{_ as i}from"./mermaid-vendor-DGPC_TDM.js";import"./chunk-RZ5BOZE2-BhCqM4LN.js";import"./feature-graph-Chuw_ipx.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";var f={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{f as diagram}; 2 | -------------------------------------------------------------------------------- /lightrag/api/webui/assets/classDiagram-v2-COTLJTTW-DHufEbeX.js: -------------------------------------------------------------------------------- 1 | import{s as a,c as s,a as e,C as t}from"./chunk-A2AXSNBT-ZI6SIAYy.js";import{_ as i}from"./mermaid-vendor-DGPC_TDM.js";import"./chunk-RZ5BOZE2-BhCqM4LN.js";import"./feature-graph-Chuw_ipx.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";var f={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{f as diagram}; 2 | -------------------------------------------------------------------------------- /lightrag/api/webui/assets/clone-BvhE3BKU.js: -------------------------------------------------------------------------------- 1 | import{b as r}from"./_baseUniq-D-427rzS.js";var e=4;function a(o){return r(o,e)}export{a as c}; 2 | -------------------------------------------------------------------------------- /lightrag/api/webui/assets/infoDiagram-PH2N3AL5-B1FzsqbO.js: -------------------------------------------------------------------------------- 1 | import{_ as e,l as o,K as i,e as n,L as p}from"./mermaid-vendor-DGPC_TDM.js";import{p as m}from"./radar-MK3ICKWK-BkgLvISn.js";import"./feature-graph-Chuw_ipx.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";import"./_baseUniq-D-427rzS.js";import"./_basePickBy-CGXZVaMl.js";import"./clone-BvhE3BKU.js";var g={parse:e(async r=>{const a=await m("info",r);o.debug(a)},"parse")},v={version:p.version},d=e(()=>v.version,"getVersion"),c={getVersion:d},l=e((r,a,s)=>{o.debug(`rendering info diagram 2 | `+r);const t=i(a);n(t,100,400,!0),t.append("g").append("text").attr("x",100).attr("y",40).attr("class","version").attr("font-size",32).style("text-anchor","middle").text(`v${s}`)},"draw"),f={draw:l},L={parser:g,db:c,renderer:f};export{L as diagram}; 3 | -------------------------------------------------------------------------------- /lightrag/api/webui/assets/stateDiagram-v2-YXO3MK2T-CE61sgaM.js: -------------------------------------------------------------------------------- 1 | import{s as r,b as e,a,S as s}from"./chunk-AEK57VVT--Edz4Twz.js";import{_ as i}from"./mermaid-vendor-DGPC_TDM.js";import"./chunk-RZ5BOZE2-BhCqM4LN.js";import"./feature-graph-Chuw_ipx.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";var b={parser:a,get db(){return new s(2)},renderer:e,styles:r,init:i(t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute},"init")};export{b as diagram}; 2 | -------------------------------------------------------------------------------- /lightrag/api/webui/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/api/webui/favicon.png -------------------------------------------------------------------------------- /lightrag/api/webui/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Lightrag 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | -------------------------------------------------------------------------------- /lightrag/constants.py: -------------------------------------------------------------------------------- 1 | """ 2 | Centralized configuration constants for LightRAG. 3 | 4 | This module defines default values for configuration constants used across 5 | different parts of the LightRAG system. Centralizing these values ensures 6 | consistency and makes maintenance easier. 7 | """ 8 | 9 | # Default values for server settings 10 | DEFAULT_WOKERS = 2 11 | DEFAULT_MAX_GRAPH_NODES = 1000 12 | 13 | # Default values for extraction settings 14 | DEFAULT_SUMMARY_LANGUAGE = "English" # Default language for summaries 15 | DEFAULT_FORCE_LLM_SUMMARY_ON_MERGE = 4 16 | DEFAULT_MAX_GLEANING = 1 17 | DEFAULT_SUMMARY_MAX_TOKENS = 10000 # Default maximum token size 18 | 19 | # Separator for graph fields 20 | GRAPH_FIELD_SEP = "" 21 | 22 | # Query and retrieval configuration defaults 23 | DEFAULT_TOP_K = 40 24 | DEFAULT_CHUNK_TOP_K = 10 25 | DEFAULT_MAX_ENTITY_TOKENS = 10000 26 | DEFAULT_MAX_RELATION_TOKENS = 10000 27 | DEFAULT_MAX_TOTAL_TOKENS = 30000 28 | DEFAULT_COSINE_THRESHOLD = 0.2 29 | DEFAULT_RELATED_CHUNK_NUMBER = 5 30 | # Deprated: history message have negtive effect on query performance 31 | DEFAULT_HISTORY_TURNS = 0 32 | 33 | # Rerank configuration defaults 34 | DEFAULT_ENABLE_RERANK = True 35 | DEFAULT_MIN_RERANK_SCORE = 0.0 36 | 37 | # File path configuration for vector and graph database(Should not be changed, used in Milvus Schema) 38 | DEFAULT_MAX_FILE_PATH_LENGTH = 4090 39 | 40 | # Default temperature for LLM 41 | DEFAULT_TEMPERATURE = 1.0 42 | 43 | # Async configuration defaults 44 | DEFAULT_MAX_ASYNC = 4 # Default maximum async operations 45 | DEFAULT_MAX_PARALLEL_INSERT = 2 # Default maximum parallel insert operations 46 | 47 | # Embedding configuration defaults 48 | DEFAULT_EMBEDDING_FUNC_MAX_ASYNC = 8 # Default max async for embedding functions 49 | DEFAULT_EMBEDDING_BATCH_NUM = 10 # Default batch size for embedding computations 50 | 51 | # Ollama Server Timetout in seconds 52 | DEFAULT_TIMEOUT = 150 53 | 54 | # Logging configuration defaults 55 | DEFAULT_LOG_MAX_BYTES = 10485760 # Default 10MB 56 | DEFAULT_LOG_BACKUP_COUNT = 5 # Default 5 backups 57 | DEFAULT_LOG_FILENAME = "lightrag.log" # Default log filename 58 | 59 | # Ollama server configuration defaults 60 | DEFAULT_OLLAMA_MODEL_NAME = "lightrag" 61 | DEFAULT_OLLAMA_MODEL_TAG = "latest" 62 | DEFAULT_OLLAMA_MODEL_SIZE = 7365960935 63 | DEFAULT_OLLAMA_CREATED_AT = "2024-01-15T00:00:00Z" 64 | DEFAULT_OLLAMA_DIGEST = "sha256:lightrag" 65 | -------------------------------------------------------------------------------- /lightrag/exceptions.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import httpx 4 | from typing import Literal 5 | 6 | 7 | class APIStatusError(Exception): 8 | """Raised when an API response has a status code of 4xx or 5xx.""" 9 | 10 | response: httpx.Response 11 | status_code: int 12 | request_id: str | None 13 | 14 | def __init__( 15 | self, message: str, *, response: httpx.Response, body: object | None 16 | ) -> None: 17 | super().__init__(message, response.request, body=body) 18 | self.response = response 19 | self.status_code = response.status_code 20 | self.request_id = response.headers.get("x-request-id") 21 | 22 | 23 | class APIConnectionError(Exception): 24 | def __init__( 25 | self, *, message: str = "Connection error.", request: httpx.Request 26 | ) -> None: 27 | super().__init__(message, request, body=None) 28 | 29 | 30 | class BadRequestError(APIStatusError): 31 | status_code: Literal[400] = 400 # pyright: ignore[reportIncompatibleVariableOverride] 32 | 33 | 34 | class AuthenticationError(APIStatusError): 35 | status_code: Literal[401] = 401 # pyright: ignore[reportIncompatibleVariableOverride] 36 | 37 | 38 | class PermissionDeniedError(APIStatusError): 39 | status_code: Literal[403] = 403 # pyright: ignore[reportIncompatibleVariableOverride] 40 | 41 | 42 | class NotFoundError(APIStatusError): 43 | status_code: Literal[404] = 404 # pyright: ignore[reportIncompatibleVariableOverride] 44 | 45 | 46 | class ConflictError(APIStatusError): 47 | status_code: Literal[409] = 409 # pyright: ignore[reportIncompatibleVariableOverride] 48 | 49 | 50 | class UnprocessableEntityError(APIStatusError): 51 | status_code: Literal[422] = 422 # pyright: ignore[reportIncompatibleVariableOverride] 52 | 53 | 54 | class RateLimitError(APIStatusError): 55 | status_code: Literal[429] = 429 # pyright: ignore[reportIncompatibleVariableOverride] 56 | 57 | 58 | class APITimeoutError(APIConnectionError): 59 | def __init__(self, request: httpx.Request) -> None: 60 | super().__init__(message="Request timed out.", request=request) 61 | -------------------------------------------------------------------------------- /lightrag/llm/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/llm/__init__.py -------------------------------------------------------------------------------- /lightrag/llm/nvidia_openai.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | if sys.version_info < (3, 9): 5 | pass 6 | else: 7 | pass 8 | 9 | import pipmaster as pm # Pipmaster for dynamic library install 10 | 11 | # install specific modules 12 | if not pm.is_installed("openai"): 13 | pm.install("openai") 14 | 15 | from openai import ( 16 | AsyncOpenAI, 17 | APIConnectionError, 18 | RateLimitError, 19 | APITimeoutError, 20 | ) 21 | from tenacity import ( 22 | retry, 23 | stop_after_attempt, 24 | wait_exponential, 25 | retry_if_exception_type, 26 | ) 27 | 28 | from lightrag.utils import ( 29 | wrap_embedding_func_with_attrs, 30 | ) 31 | 32 | 33 | import numpy as np 34 | 35 | 36 | @wrap_embedding_func_with_attrs(embedding_dim=2048) 37 | @retry( 38 | stop=stop_after_attempt(3), 39 | wait=wait_exponential(multiplier=1, min=4, max=60), 40 | retry=retry_if_exception_type( 41 | (RateLimitError, APIConnectionError, APITimeoutError) 42 | ), 43 | ) 44 | async def nvidia_openai_embed( 45 | texts: list[str], 46 | model: str = "nvidia/llama-3.2-nv-embedqa-1b-v1", 47 | # refer to https://build.nvidia.com/nim?filters=usecase%3Ausecase_text_to_embedding 48 | base_url: str = "https://integrate.api.nvidia.com/v1", 49 | api_key: str = None, 50 | input_type: str = "passage", # query for retrieval, passage for embedding 51 | trunc: str = "NONE", # NONE or START or END 52 | encode: str = "float", # float or base64 53 | ) -> np.ndarray: 54 | if api_key: 55 | os.environ["OPENAI_API_KEY"] = api_key 56 | 57 | openai_async_client = ( 58 | AsyncOpenAI() if base_url is None else AsyncOpenAI(base_url=base_url) 59 | ) 60 | response = await openai_async_client.embeddings.create( 61 | model=model, 62 | input=texts, 63 | encoding_format=encode, 64 | extra_body={"input_type": input_type, "truncate": trunc}, 65 | ) 66 | return np.array([dp.embedding for dp in response.data]) 67 | -------------------------------------------------------------------------------- /lightrag/llm/siliconcloud.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | if sys.version_info < (3, 9): 4 | pass 5 | else: 6 | pass 7 | import pipmaster as pm # Pipmaster for dynamic library install 8 | 9 | # install specific modules 10 | if not pm.is_installed("lmdeploy"): 11 | pm.install("lmdeploy") 12 | 13 | from openai import ( 14 | APIConnectionError, 15 | RateLimitError, 16 | APITimeoutError, 17 | ) 18 | from tenacity import ( 19 | retry, 20 | stop_after_attempt, 21 | wait_exponential, 22 | retry_if_exception_type, 23 | ) 24 | 25 | 26 | import numpy as np 27 | import aiohttp 28 | import base64 29 | import struct 30 | 31 | 32 | @retry( 33 | stop=stop_after_attempt(3), 34 | wait=wait_exponential(multiplier=1, min=4, max=60), 35 | retry=retry_if_exception_type( 36 | (RateLimitError, APIConnectionError, APITimeoutError) 37 | ), 38 | ) 39 | async def siliconcloud_embedding( 40 | texts: list[str], 41 | model: str = "netease-youdao/bce-embedding-base_v1", 42 | base_url: str = "https://api.siliconflow.cn/v1/embeddings", 43 | max_token_size: int = 8192, 44 | api_key: str = None, 45 | ) -> np.ndarray: 46 | if api_key and not api_key.startswith("Bearer "): 47 | api_key = "Bearer " + api_key 48 | 49 | headers = {"Authorization": api_key, "Content-Type": "application/json"} 50 | 51 | truncate_texts = [text[0:max_token_size] for text in texts] 52 | 53 | payload = {"model": model, "input": truncate_texts, "encoding_format": "base64"} 54 | 55 | base64_strings = [] 56 | async with aiohttp.ClientSession() as session: 57 | async with session.post(base_url, headers=headers, json=payload) as response: 58 | content = await response.json() 59 | if "code" in content: 60 | raise ValueError(content) 61 | base64_strings = [item["embedding"] for item in content["data"]] 62 | 63 | embeddings = [] 64 | for string in base64_strings: 65 | decode_bytes = base64.b64decode(string) 66 | n = len(decode_bytes) // 4 67 | float_array = struct.unpack("<" + "f" * n, decode_bytes) 68 | embeddings.append(float_array) 69 | return np.array(embeddings) 70 | -------------------------------------------------------------------------------- /lightrag/namespace.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Iterable 4 | 5 | 6 | class NameSpace: 7 | KV_STORE_FULL_DOCS = "full_docs" 8 | KV_STORE_TEXT_CHUNKS = "text_chunks" 9 | KV_STORE_LLM_RESPONSE_CACHE = "llm_response_cache" 10 | KV_STORE_FULL_ENTITIES = "full_entities" 11 | KV_STORE_FULL_RELATIONS = "full_relations" 12 | 13 | VECTOR_STORE_ENTITIES = "entities" 14 | VECTOR_STORE_RELATIONSHIPS = "relationships" 15 | VECTOR_STORE_CHUNKS = "chunks" 16 | 17 | GRAPH_STORE_CHUNK_ENTITY_RELATION = "chunk_entity_relation" 18 | 19 | DOC_STATUS = "doc_status" 20 | 21 | 22 | def is_namespace(namespace: str, base_namespace: str | Iterable[str]): 23 | if isinstance(base_namespace, str): 24 | return namespace.endswith(base_namespace) 25 | return any(is_namespace(namespace, ns) for ns in base_namespace) 26 | -------------------------------------------------------------------------------- /lightrag/tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/tools/__init__.py -------------------------------------------------------------------------------- /lightrag/tools/lightrag_visualizer/README-zh.md: -------------------------------------------------------------------------------- 1 | # 3D GraphML Viewer 2 | 3 | 一个基于 Dear ImGui 和 ModernGL 的交互式 3D 图可视化工具。 4 | 5 | ## 功能特点 6 | 7 | - **3D 交互式可视化**: 使用 ModernGL 实现高性能的 3D 图形渲染 8 | - **多种布局算法**: 支持多种图布局方式 9 | - Spring 布局 10 | - Circular 布局 11 | - Shell 布局 12 | - Random 布局 13 | - **社区检测**: 支持图社区结构的自动检测和可视化 14 | - **交互控制**: 15 | - WASD + QE 键控制相机移动 16 | - 鼠标右键拖拽控制视角 17 | - 节点选择和高亮 18 | - 可调节节点大小和边宽度 19 | - 可控制标签显示 20 | - 可在节点的Connections间快速跳转 21 | - **社区检测**: 支持图社区结构的自动检测和可视化 22 | - **交互控制**: 23 | - WASD + QE 键控制相机移动 24 | - 鼠标右键拖拽控制视角 25 | - 节点选择和高亮 26 | - 可调节节点大小和边宽度 27 | - 可控制标签显示 28 | 29 | ## 技术栈 30 | 31 | - **imgui_bundle**: 用户界面 32 | - **ModernGL**: OpenGL 图形渲染 33 | - **NetworkX**: 图数据结构和算法 34 | - **NumPy**: 数值计算 35 | - **community**: 社区检测 36 | 37 | ## 使用方法 38 | 39 | 1. **启动程序**: 40 | ```bash 41 | pip install lightrag-hku[tools] 42 | lightrag-viewer 43 | ``` 44 | 45 | 2. **加载字体**: 46 | - 将中文字体文件 `font.ttf` 放置在 `assets` 目录下 47 | - 或者修改 `CUSTOM_FONT` 常量来使用其他字体文件 48 | 49 | 3. **加载图文件**: 50 | - 点击界面上的 "Load GraphML" 按钮 51 | - 选择 GraphML 格式的图文件 52 | 53 | 4. **交互控制**: 54 | - **相机移动**: 55 | - W: 前进 56 | - S: 后退 57 | - A: 左移 58 | - D: 右移 59 | - Q: 上升 60 | - E: 下降 61 | - **视角控制**: 62 | - 按住鼠标右键拖动来旋转视角 63 | - **节点交互**: 64 | - 鼠标悬停可高亮节点 65 | - 点击可选中节点 66 | 67 | 5. **可视化设置**: 68 | - 可通过 UI 控制面板调整: 69 | - 布局类型 70 | - 节点大小 71 | - 边的宽度 72 | - 标签显示 73 | - 标签大小 74 | - 背景颜色 75 | 76 | ## 自定义设置 77 | 78 | - **节点缩放**: 通过 `node_scale` 参数调整节点大小 79 | - **边宽度**: 通过 `edge_width` 参数调整边的宽度 80 | - **标签显示**: 可通过 `show_labels` 开关标签显示 81 | - **标签大小**: 使用 `label_size` 调整标签大小 82 | - **标签颜色**: 通过 `label_color` 设置标签颜色 83 | - **视距控制**: 使用 `label_culling_distance` 控制标签显示的最大距离 84 | 85 | ## 性能优化 86 | 87 | - 使用 ModernGL 进行高效的图形渲染 88 | - 视距裁剪优化标签显示 89 | - 社区检测算法优化大规模图的可视化效果 90 | 91 | ## 系统要求 92 | 93 | - Python 3.10+ 94 | - OpenGL 3.3+ 兼容的显卡 95 | - 支持的操作系统:Windows/Linux/MacOS 96 | -------------------------------------------------------------------------------- /lightrag/tools/lightrag_visualizer/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/tools/lightrag_visualizer/__init__.py -------------------------------------------------------------------------------- /lightrag/tools/lightrag_visualizer/assets/Geist-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/tools/lightrag_visualizer/assets/Geist-Regular.ttf -------------------------------------------------------------------------------- /lightrag/tools/lightrag_visualizer/assets/SmileySans-Oblique.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/tools/lightrag_visualizer/assets/SmileySans-Oblique.ttf -------------------------------------------------------------------------------- /lightrag/tools/lightrag_visualizer/assets/place_font_here: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag/tools/lightrag_visualizer/assets/place_font_here -------------------------------------------------------------------------------- /lightrag/tools/lightrag_visualizer/requirements.txt: -------------------------------------------------------------------------------- 1 | imgui_bundle 2 | moderngl 3 | networkx 4 | numpy 5 | pyglm 6 | python-louvain 7 | scipy 8 | tk 9 | -------------------------------------------------------------------------------- /lightrag/types.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from pydantic import BaseModel 4 | from typing import Any, Optional 5 | 6 | 7 | class GPTKeywordExtractionFormat(BaseModel): 8 | high_level_keywords: list[str] 9 | low_level_keywords: list[str] 10 | 11 | 12 | class KnowledgeGraphNode(BaseModel): 13 | id: str 14 | labels: list[str] 15 | properties: dict[str, Any] # anything else goes here 16 | 17 | 18 | class KnowledgeGraphEdge(BaseModel): 19 | id: str 20 | type: Optional[str] 21 | source: str # id of source node 22 | target: str # id of target node 23 | properties: dict[str, Any] # anything else goes here 24 | 25 | 26 | class KnowledgeGraph(BaseModel): 27 | nodes: list[KnowledgeGraphNode] = [] 28 | edges: list[KnowledgeGraphEdge] = [] 29 | is_truncated: bool = False 30 | -------------------------------------------------------------------------------- /lightrag_webui/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /lightrag_webui/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/prettierrc", 3 | "semi": false, 4 | "tabWidth": 2, 5 | "singleQuote": true, 6 | "printWidth": 100, 7 | "trailingComma": "none", 8 | "endOfLine": "crlf", 9 | "plugins": ["prettier-plugin-tailwindcss"] 10 | } 11 | -------------------------------------------------------------------------------- /lightrag_webui/README.md: -------------------------------------------------------------------------------- 1 | # LightRAG WebUI 2 | 3 | LightRAG WebUI is a React-based web interface for interacting with the LightRAG system. It provides a user-friendly interface for querying, managing, and exploring LightRAG's functionalities. 4 | 5 | ## Installation 6 | 7 | 1. **Install Bun:** 8 | 9 | If you haven't already installed Bun, follow the official documentation: [https://bun.sh/docs/installation](https://bun.sh/docs/installation) 10 | 11 | 2. **Install Dependencies:** 12 | 13 | In the `lightrag_webui` directory, run the following command to install project dependencies: 14 | 15 | ```bash 16 | bun install --frozen-lockfile 17 | ``` 18 | 19 | 3. **Build the Project:** 20 | 21 | Run the following command to build the project: 22 | 23 | ```bash 24 | bun run build --emptyOutDir 25 | ``` 26 | 27 | This command will bundle the project and output the built files to the `lightrag/api/webui` directory. 28 | 29 | ## Development 30 | 31 | - **Start the Development Server:** 32 | 33 | If you want to run the WebUI in development mode, use the following command: 34 | 35 | ```bash 36 | bun run dev 37 | ``` 38 | 39 | ## Script Commands 40 | 41 | The following are some commonly used script commands defined in `package.json`: 42 | 43 | - `bun install`: Installs project dependencies. 44 | - `bun run dev`: Starts the development server. 45 | - `bun run build`: Builds the project. 46 | - `bun run lint`: Runs the linter. 47 | -------------------------------------------------------------------------------- /lightrag_webui/components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "new-york", 4 | "rsc": false, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "", 8 | "css": "src/index.css", 9 | "baseColor": "zinc", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils", 16 | "ui": "@/components/ui", 17 | "lib": "@/lib", 18 | "hooks": "@/hooks" 19 | }, 20 | "iconLibrary": "lucide" 21 | } 22 | -------------------------------------------------------------------------------- /lightrag_webui/env.development.smaple: -------------------------------------------------------------------------------- 1 | # Development environment configuration 2 | VITE_BACKEND_URL=/api 3 | -------------------------------------------------------------------------------- /lightrag_webui/env.local.sample: -------------------------------------------------------------------------------- 1 | VITE_BACKEND_URL=http://localhost:9621 2 | VITE_API_PROXY=true 3 | VITE_API_ENDPOINTS=/,/api,/documents,/graphs,/graph,/health,/query,/docs,/openapi.json,/login,/auth-status 4 | -------------------------------------------------------------------------------- /lightrag_webui/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import reactHooks from 'eslint-plugin-react-hooks' 4 | import reactRefresh from 'eslint-plugin-react-refresh' 5 | import stylisticJs from '@stylistic/eslint-plugin-js' 6 | import tseslint from 'typescript-eslint' 7 | import prettier from 'eslint-config-prettier' 8 | import react from 'eslint-plugin-react' 9 | 10 | export default tseslint.config( 11 | { ignores: ['dist'] }, 12 | { 13 | extends: [js.configs.recommended, ...tseslint.configs.recommended, prettier], 14 | files: ['**/*.{ts,tsx,js,jsx}'], 15 | languageOptions: { 16 | ecmaVersion: 2020, 17 | globals: globals.browser 18 | }, 19 | settings: { react: { version: '19.0' } }, 20 | plugins: { 21 | 'react-hooks': reactHooks, 22 | 'react-refresh': reactRefresh, 23 | '@stylistic/js': stylisticJs, 24 | react 25 | }, 26 | rules: { 27 | ...reactHooks.configs.recommended.rules, 28 | 'react-refresh/only-export-components': ['warn', { allowConstantExport: true }], 29 | ...react.configs.recommended.rules, 30 | ...react.configs['jsx-runtime'].rules, 31 | '@stylistic/js/indent': ['error', 2], 32 | '@stylistic/js/quotes': ['error', 'single'], 33 | '@typescript-eslint/no-explicit-any': ['off'] 34 | } 35 | } 36 | ) 37 | -------------------------------------------------------------------------------- /lightrag_webui/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Lightrag 11 | 12 | 13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /lightrag_webui/public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HKUDS/LightRAG/7780776af67097d80dae5e77e6f058c075c6fd78/lightrag_webui/public/favicon.png -------------------------------------------------------------------------------- /lightrag_webui/src/AppRouter.tsx: -------------------------------------------------------------------------------- 1 | import { HashRouter as Router, Routes, Route, useNavigate } from 'react-router-dom' 2 | import { useEffect, useState } from 'react' 3 | import { useAuthStore } from '@/stores/state' 4 | import { navigationService } from '@/services/navigation' 5 | import { Toaster } from 'sonner' 6 | import App from './App' 7 | import LoginPage from '@/features/LoginPage' 8 | import ThemeProvider from '@/components/ThemeProvider' 9 | 10 | const AppContent = () => { 11 | const [initializing, setInitializing] = useState(true) 12 | const { isAuthenticated } = useAuthStore() 13 | const navigate = useNavigate() 14 | 15 | // Set navigate function for navigation service 16 | useEffect(() => { 17 | navigationService.setNavigate(navigate) 18 | }, [navigate]) 19 | 20 | // Token validity check 21 | useEffect(() => { 22 | 23 | const checkAuth = async () => { 24 | try { 25 | const token = localStorage.getItem('LIGHTRAG-API-TOKEN') 26 | 27 | if (token && isAuthenticated) { 28 | setInitializing(false); 29 | return; 30 | } 31 | 32 | if (!token) { 33 | useAuthStore.getState().logout() 34 | } 35 | } catch (error) { 36 | console.error('Auth initialization error:', error) 37 | if (!isAuthenticated) { 38 | useAuthStore.getState().logout() 39 | } 40 | } finally { 41 | setInitializing(false) 42 | } 43 | } 44 | 45 | checkAuth() 46 | 47 | return () => { 48 | } 49 | }, [isAuthenticated]) 50 | 51 | // Redirect effect for protected routes 52 | useEffect(() => { 53 | if (!initializing && !isAuthenticated) { 54 | const currentPath = window.location.hash.slice(1); 55 | if (currentPath !== '/login') { 56 | console.log('Not authenticated, redirecting to login'); 57 | navigate('/login'); 58 | } 59 | } 60 | }, [initializing, isAuthenticated, navigate]); 61 | 62 | // Show nothing while initializing 63 | if (initializing) { 64 | return null 65 | } 66 | 67 | return ( 68 | 69 | } /> 70 | : null} 73 | /> 74 | 75 | ) 76 | } 77 | 78 | const AppRouter = () => { 79 | return ( 80 | 81 | 82 | 83 | 89 | 90 | 91 | ) 92 | } 93 | 94 | export default AppRouter 95 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/ApiKeyAlert.tsx: -------------------------------------------------------------------------------- 1 | import { useState, useCallback, useEffect } from 'react' 2 | import { useTranslation } from 'react-i18next' 3 | import { 4 | AlertDialog, 5 | AlertDialogContent, 6 | AlertDialogDescription, 7 | AlertDialogHeader, 8 | AlertDialogTitle 9 | } from '@/components/ui/AlertDialog' 10 | import Button from '@/components/ui/Button' 11 | import Input from '@/components/ui/Input' 12 | import { useSettingsStore } from '@/stores/settings' 13 | import { useBackendState } from '@/stores/state' 14 | import { InvalidApiKeyError, RequireApiKeError } from '@/api/lightrag' 15 | 16 | interface ApiKeyAlertProps { 17 | open: boolean; 18 | onOpenChange: (open: boolean) => void; 19 | } 20 | 21 | const ApiKeyAlert = ({ open: opened, onOpenChange: setOpened }: ApiKeyAlertProps) => { 22 | const { t } = useTranslation() 23 | const apiKey = useSettingsStore.use.apiKey() 24 | const [tempApiKey, setTempApiKey] = useState('') 25 | const message = useBackendState.use.message() 26 | 27 | useEffect(() => { 28 | setTempApiKey(apiKey || '') 29 | }, [apiKey, opened]) 30 | 31 | useEffect(() => { 32 | if (message) { 33 | if (message.includes(InvalidApiKeyError) || message.includes(RequireApiKeError)) { 34 | setOpened(true) 35 | } 36 | } 37 | }, [message, setOpened]) 38 | 39 | const setApiKey = useCallback(() => { 40 | useSettingsStore.setState({ apiKey: tempApiKey || null }) 41 | setOpened(false) 42 | }, [tempApiKey, setOpened]) 43 | 44 | const handleTempApiKeyChange = useCallback( 45 | (e: React.ChangeEvent) => { 46 | setTempApiKey(e.target.value) 47 | }, 48 | [setTempApiKey] 49 | ) 50 | 51 | return ( 52 | 53 | 54 | 55 | {t('apiKeyAlert.title')} 56 | 57 | {t('apiKeyAlert.description')} 58 | 59 | 60 |
61 |
e.preventDefault()}> 62 | 70 | 71 | 74 |
75 | {message && ( 76 |
77 | {message} 78 |
79 | )} 80 |
81 |
82 |
83 | ) 84 | } 85 | 86 | export default ApiKeyAlert 87 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/AppSettings.tsx: -------------------------------------------------------------------------------- 1 | import { useState, useCallback } from 'react' 2 | import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/Popover' 3 | import Button from '@/components/ui/Button' 4 | import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/Select' 5 | import { useSettingsStore } from '@/stores/settings' 6 | import { PaletteIcon } from 'lucide-react' 7 | import { useTranslation } from 'react-i18next' 8 | import { cn } from '@/lib/utils' 9 | 10 | interface AppSettingsProps { 11 | className?: string 12 | } 13 | 14 | export default function AppSettings({ className }: AppSettingsProps) { 15 | const [opened, setOpened] = useState(false) 16 | const { t } = useTranslation() 17 | 18 | const language = useSettingsStore.use.language() 19 | const setLanguage = useSettingsStore.use.setLanguage() 20 | 21 | const theme = useSettingsStore.use.theme() 22 | const setTheme = useSettingsStore.use.setTheme() 23 | 24 | const handleLanguageChange = useCallback((value: string) => { 25 | setLanguage(value as 'en' | 'zh' | 'fr' | 'ar' | 'zh_TW') 26 | }, [setLanguage]) 27 | 28 | const handleThemeChange = useCallback((value: string) => { 29 | setTheme(value as 'light' | 'dark' | 'system') 30 | }, [setTheme]) 31 | 32 | return ( 33 | 34 | 35 | 38 | 39 | 40 |
41 |
42 | 43 | 55 |
56 | 57 |
58 | 59 | 69 |
70 |
71 |
72 |
73 | ) 74 | } 75 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/LanguageToggle.tsx: -------------------------------------------------------------------------------- 1 | import Button from '@/components/ui/Button' 2 | import { useCallback } from 'react' 3 | import { controlButtonVariant } from '@/lib/constants' 4 | import { useTranslation } from 'react-i18next' 5 | import { useSettingsStore } from '@/stores/settings' 6 | 7 | /** 8 | * Component that toggles the language between English and Chinese. 9 | */ 10 | export default function LanguageToggle() { 11 | const { i18n } = useTranslation() 12 | const currentLanguage = i18n.language 13 | const setLanguage = useSettingsStore.use.setLanguage() 14 | 15 | const setEnglish = useCallback(() => { 16 | i18n.changeLanguage('en') 17 | setLanguage('en') 18 | }, [i18n, setLanguage]) 19 | 20 | const setChinese = useCallback(() => { 21 | i18n.changeLanguage('zh') 22 | setLanguage('zh') 23 | }, [i18n, setLanguage]) 24 | 25 | if (currentLanguage === 'zh') { 26 | return ( 27 | 36 | ) 37 | } 38 | return ( 39 | 48 | ) 49 | } 50 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/Root.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode, useEffect, useState } from 'react' 2 | import { initializeI18n } from '@/i18n' 3 | import App from '@/App' 4 | 5 | export const Root = () => { 6 | const [isI18nInitialized, setIsI18nInitialized] = useState(false) 7 | 8 | useEffect(() => { 9 | // Initialize i18n immediately with persisted language 10 | initializeI18n().then(() => { 11 | setIsI18nInitialized(true) 12 | }) 13 | }, []) 14 | 15 | if (!isI18nInitialized) { 16 | return null // or a loading spinner 17 | } 18 | 19 | return ( 20 | 21 | 22 | 23 | ) 24 | } 25 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/ThemeProvider.tsx: -------------------------------------------------------------------------------- 1 | import { createContext, useEffect } from 'react' 2 | import { Theme, useSettingsStore } from '@/stores/settings' 3 | 4 | type ThemeProviderProps = { 5 | children: React.ReactNode 6 | } 7 | 8 | type ThemeProviderState = { 9 | theme: Theme 10 | setTheme: (theme: Theme) => void 11 | } 12 | 13 | const initialState: ThemeProviderState = { 14 | theme: 'system', 15 | setTheme: () => null 16 | } 17 | 18 | const ThemeProviderContext = createContext(initialState) 19 | 20 | /** 21 | * Component that provides the theme state and setter function to its children. 22 | */ 23 | export default function ThemeProvider({ children, ...props }: ThemeProviderProps) { 24 | const theme = useSettingsStore.use.theme() 25 | const setTheme = useSettingsStore.use.setTheme() 26 | 27 | useEffect(() => { 28 | const root = window.document.documentElement 29 | root.classList.remove('light', 'dark') 30 | 31 | if (theme === 'system') { 32 | const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)') 33 | const handleChange = (e: MediaQueryListEvent) => { 34 | root.classList.remove('light', 'dark') 35 | root.classList.add(e.matches ? 'dark' : 'light') 36 | } 37 | 38 | root.classList.add(mediaQuery.matches ? 'dark' : 'light') 39 | mediaQuery.addEventListener('change', handleChange) 40 | 41 | return () => mediaQuery.removeEventListener('change', handleChange) 42 | } else { 43 | root.classList.add(theme) 44 | } 45 | }, [theme]) 46 | 47 | const value = { 48 | theme, 49 | setTheme 50 | } 51 | 52 | return ( 53 | 54 | {children} 55 | 56 | ) 57 | } 58 | 59 | export { ThemeProviderContext } 60 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/ThemeToggle.tsx: -------------------------------------------------------------------------------- 1 | import Button from '@/components/ui/Button' 2 | import useTheme from '@/hooks/useTheme' 3 | import { MoonIcon, SunIcon } from 'lucide-react' 4 | import { useCallback } from 'react' 5 | import { controlButtonVariant } from '@/lib/constants' 6 | import { useTranslation } from 'react-i18next' 7 | 8 | /** 9 | * Component that toggles the theme between light and dark. 10 | */ 11 | export default function ThemeToggle() { 12 | const { theme, setTheme } = useTheme() 13 | const setLight = useCallback(() => setTheme('light'), [setTheme]) 14 | const setDark = useCallback(() => setTheme('dark'), [setTheme]) 15 | const { t } = useTranslation() 16 | 17 | if (theme === 'dark') { 18 | return ( 19 | 28 | ) 29 | } 30 | return ( 31 | 40 | ) 41 | } 42 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/documents/DeselectDocumentsDialog.tsx: -------------------------------------------------------------------------------- 1 | import { useState, useCallback, useEffect } from 'react' 2 | import Button from '@/components/ui/Button' 3 | import { 4 | Dialog, 5 | DialogContent, 6 | DialogDescription, 7 | DialogHeader, 8 | DialogTitle, 9 | DialogTrigger, 10 | DialogFooter 11 | } from '@/components/ui/Dialog' 12 | 13 | import { XIcon, AlertCircleIcon } from 'lucide-react' 14 | import { useTranslation } from 'react-i18next' 15 | 16 | interface DeselectDocumentsDialogProps { 17 | selectedCount: number 18 | onDeselect: () => void 19 | } 20 | 21 | export default function DeselectDocumentsDialog({ selectedCount, onDeselect }: DeselectDocumentsDialogProps) { 22 | const { t } = useTranslation() 23 | const [open, setOpen] = useState(false) 24 | 25 | // Reset state when dialog closes 26 | useEffect(() => { 27 | if (!open) { 28 | // No state to reset for this simple dialog 29 | } 30 | }, [open]) 31 | 32 | const handleDeselect = useCallback(() => { 33 | onDeselect() 34 | setOpen(false) 35 | }, [onDeselect, setOpen]) 36 | 37 | return ( 38 | 39 | 40 | 48 | 49 | e.preventDefault()}> 50 | 51 | 52 | 53 | {t('documentPanel.deselectDocuments.title')} 54 | 55 | 56 | {t('documentPanel.deselectDocuments.description', { count: selectedCount })} 57 | 58 | 59 | 60 | 61 | 64 | 70 | 71 | 72 | 73 | ) 74 | } 75 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/graph/FocusOnNode.tsx: -------------------------------------------------------------------------------- 1 | import { useCamera, useSigma } from '@react-sigma/core' 2 | import { useEffect } from 'react' 3 | import { useGraphStore } from '@/stores/graph' 4 | 5 | /** 6 | * Component that highlights a node and centers the camera on it. 7 | */ 8 | const FocusOnNode = ({ node, move }: { node: string | null; move?: boolean }) => { 9 | const sigma = useSigma() 10 | const { gotoNode } = useCamera() 11 | 12 | /** 13 | * When the selected item changes, highlighted the node and center the camera on it. 14 | */ 15 | useEffect(() => { 16 | const graph = sigma.getGraph(); 17 | 18 | if (move) { 19 | if (node && graph.hasNode(node)) { 20 | try { 21 | graph.setNodeAttribute(node, 'highlighted', true); 22 | gotoNode(node); 23 | } catch (error) { 24 | console.error('Error focusing on node:', error); 25 | } 26 | } else { 27 | // If no node is selected but move is true, reset to default view 28 | sigma.setCustomBBox(null); 29 | sigma.getCamera().animate({ x: 0.5, y: 0.5, ratio: 1 }, { duration: 0 }); 30 | } 31 | useGraphStore.getState().setMoveToSelectedNode(false); 32 | } else if (node && graph.hasNode(node)) { 33 | try { 34 | graph.setNodeAttribute(node, 'highlighted', true); 35 | } catch (error) { 36 | console.error('Error highlighting node:', error); 37 | } 38 | } 39 | 40 | return () => { 41 | if (node && graph.hasNode(node)) { 42 | try { 43 | graph.setNodeAttribute(node, 'highlighted', false); 44 | } catch (error) { 45 | console.error('Error cleaning up node highlight:', error); 46 | } 47 | } 48 | } 49 | }, [node, move, sigma, gotoNode]) 50 | 51 | return null 52 | } 53 | 54 | export default FocusOnNode 55 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/graph/FullScreenControl.tsx: -------------------------------------------------------------------------------- 1 | import { useFullScreen } from '@react-sigma/core' 2 | import { MaximizeIcon, MinimizeIcon } from 'lucide-react' 3 | import { controlButtonVariant } from '@/lib/constants' 4 | import Button from '@/components/ui/Button' 5 | import { useTranslation } from 'react-i18next' 6 | 7 | /** 8 | * Component that toggles full screen mode. 9 | */ 10 | const FullScreenControl = () => { 11 | const { isFullScreen, toggle } = useFullScreen() 12 | const { t } = useTranslation() 13 | 14 | return ( 15 | <> 16 | {isFullScreen ? ( 17 | 20 | ) : ( 21 | 24 | )} 25 | 26 | ) 27 | } 28 | 29 | export default FullScreenControl 30 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/graph/Legend.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { useTranslation } from 'react-i18next' 3 | import { useGraphStore } from '@/stores/graph' 4 | import { Card } from '@/components/ui/Card' 5 | import { ScrollArea } from '@/components/ui/ScrollArea' 6 | 7 | interface LegendProps { 8 | className?: string 9 | } 10 | 11 | const Legend: React.FC = ({ className }) => { 12 | const { t } = useTranslation() 13 | const typeColorMap = useGraphStore.use.typeColorMap() 14 | 15 | if (!typeColorMap || typeColorMap.size === 0) { 16 | return null 17 | } 18 | 19 | return ( 20 | 21 |

{t('graphPanel.legend')}

22 | 23 |
24 | {Array.from(typeColorMap.entries()).map(([type, color]) => ( 25 |
26 |
30 | 31 | {t(`graphPanel.nodeTypes.${type.toLowerCase()}`, type)} 32 | 33 |
34 | ))} 35 |
36 | 37 | 38 | ) 39 | } 40 | 41 | export default Legend 42 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/graph/LegendButton.tsx: -------------------------------------------------------------------------------- 1 | import { useCallback } from 'react' 2 | import { BookOpenIcon } from 'lucide-react' 3 | import Button from '@/components/ui/Button' 4 | import { controlButtonVariant } from '@/lib/constants' 5 | import { useSettingsStore } from '@/stores/settings' 6 | import { useTranslation } from 'react-i18next' 7 | 8 | /** 9 | * Component that toggles legend visibility. 10 | */ 11 | const LegendButton = () => { 12 | const { t } = useTranslation() 13 | const showLegend = useSettingsStore.use.showLegend() 14 | const setShowLegend = useSettingsStore.use.setShowLegend() 15 | 16 | const toggleLegend = useCallback(() => { 17 | setShowLegend(!showLegend) 18 | }, [showLegend, setShowLegend]) 19 | 20 | return ( 21 | 29 | ) 30 | } 31 | 32 | export default LegendButton 33 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/graph/PropertyRowComponents.tsx: -------------------------------------------------------------------------------- 1 | import { PencilIcon } from 'lucide-react' 2 | import Text from '@/components/ui/Text' 3 | import { useTranslation } from 'react-i18next' 4 | 5 | interface PropertyNameProps { 6 | name: string 7 | } 8 | 9 | export const PropertyName = ({ name }: PropertyNameProps) => { 10 | const { t } = useTranslation() 11 | 12 | const getPropertyNameTranslation = (propName: string) => { 13 | const translationKey = `graphPanel.propertiesView.node.propertyNames.${propName}` 14 | const translation = t(translationKey) 15 | return translation === translationKey ? propName : translation 16 | } 17 | 18 | return ( 19 | 20 | {getPropertyNameTranslation(name)} 21 | 22 | ) 23 | } 24 | 25 | interface EditIconProps { 26 | onClick: () => void 27 | } 28 | 29 | export const EditIcon = ({ onClick }: EditIconProps) => ( 30 |
31 | 35 |
36 | ) 37 | 38 | interface PropertyValueProps { 39 | value: any 40 | onClick?: () => void 41 | tooltip?: string 42 | } 43 | 44 | export const PropertyValue = ({ value, onClick, tooltip }: PropertyValueProps) => ( 45 |
46 | 54 |
55 | ) 56 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/graph/SettingsDisplay.tsx: -------------------------------------------------------------------------------- 1 | import { useSettingsStore } from '@/stores/settings' 2 | import { useTranslation } from 'react-i18next' 3 | 4 | /** 5 | * Component that displays current values of important graph settings 6 | * Positioned to the right of the toolbar at the bottom-left corner 7 | */ 8 | const SettingsDisplay = () => { 9 | const { t } = useTranslation() 10 | const graphQueryMaxDepth = useSettingsStore.use.graphQueryMaxDepth() 11 | const graphMaxNodes = useSettingsStore.use.graphMaxNodes() 12 | 13 | return ( 14 |
15 |
{t('graphPanel.sideBar.settings.depth')}: {graphQueryMaxDepth}
16 |
{t('graphPanel.sideBar.settings.max')}: {graphMaxNodes}
17 |
18 | ) 19 | } 20 | 21 | export default SettingsDisplay 22 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/status/StatusDialog.tsx: -------------------------------------------------------------------------------- 1 | import { LightragStatus } from '@/api/lightrag' 2 | import { useTranslation } from 'react-i18next' 3 | import { 4 | Dialog, 5 | DialogContent, 6 | DialogHeader, 7 | DialogTitle, 8 | DialogDescription, 9 | } from '@/components/ui/Dialog' 10 | import StatusCard from './StatusCard' 11 | 12 | interface StatusDialogProps { 13 | open: boolean 14 | onOpenChange: (open: boolean) => void 15 | status: LightragStatus | null 16 | } 17 | 18 | const StatusDialog = ({ open, onOpenChange, status }: StatusDialogProps) => { 19 | const { t } = useTranslation() 20 | 21 | return ( 22 | 23 | 24 | 25 | {t('graphPanel.statusDialog.title')} 26 | 27 | {t('graphPanel.statusDialog.description')} 28 | 29 | 30 | 31 | 32 | 33 | ) 34 | } 35 | 36 | export default StatusDialog 37 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/status/StatusIndicator.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils' 2 | import { useBackendState } from '@/stores/state' 3 | import { useEffect, useState } from 'react' 4 | import StatusDialog from './StatusDialog' 5 | import { useTranslation } from 'react-i18next' 6 | 7 | const StatusIndicator = () => { 8 | const { t } = useTranslation() 9 | const health = useBackendState.use.health() 10 | const lastCheckTime = useBackendState.use.lastCheckTime() 11 | const status = useBackendState.use.status() 12 | const [animate, setAnimate] = useState(false) 13 | const [dialogOpen, setDialogOpen] = useState(false) 14 | 15 | // listen to health change 16 | useEffect(() => { 17 | setAnimate(true) 18 | const timer = setTimeout(() => setAnimate(false), 300) 19 | return () => clearTimeout(timer) 20 | }, [lastCheckTime]) 21 | 22 | return ( 23 |
24 |
setDialogOpen(true)} 27 | > 28 |
38 | 39 | {health ? t('graphPanel.statusIndicator.connected') : t('graphPanel.statusIndicator.disconnected')} 40 | 41 |
42 | 43 | 48 |
49 | ) 50 | } 51 | 52 | export default StatusIndicator 53 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/ui/Alert.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import { cva, type VariantProps } from 'class-variance-authority' 3 | 4 | import { cn } from '@/lib/utils' 5 | 6 | const alertVariants = cva( 7 | 'relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7', 8 | { 9 | variants: { 10 | variant: { 11 | default: 'bg-background text-foreground', 12 | destructive: 13 | 'border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive' 14 | } 15 | }, 16 | defaultVariants: { 17 | variant: 'default' 18 | } 19 | } 20 | ) 21 | 22 | const Alert = React.forwardRef< 23 | HTMLDivElement, 24 | React.HTMLAttributes & VariantProps 25 | >(({ className, variant, ...props }, ref) => ( 26 |
27 | )) 28 | Alert.displayName = 'Alert' 29 | 30 | const AlertTitle = React.forwardRef>( 31 | ({ className, ...props }, ref) => ( 32 |
37 | ) 38 | ) 39 | AlertTitle.displayName = 'AlertTitle' 40 | 41 | const AlertDescription = React.forwardRef< 42 | HTMLParagraphElement, 43 | React.HTMLAttributes 44 | >(({ className, ...props }, ref) => ( 45 |
46 | )) 47 | AlertDescription.displayName = 'AlertDescription' 48 | 49 | export { Alert, AlertTitle, AlertDescription } 50 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/ui/Badge.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import { cva, type VariantProps } from 'class-variance-authority' 3 | 4 | import { cn } from '@/lib/utils' 5 | 6 | const badgeVariants = cva( 7 | 'inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2', 8 | { 9 | variants: { 10 | variant: { 11 | default: 'border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80', 12 | secondary: 13 | 'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80', 14 | destructive: 15 | 'border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80', 16 | outline: 'text-foreground' 17 | } 18 | }, 19 | defaultVariants: { 20 | variant: 'default' 21 | } 22 | } 23 | ) 24 | 25 | export interface BadgeProps 26 | extends React.HTMLAttributes, 27 | VariantProps {} 28 | 29 | function Badge({ className, variant, ...props }: BadgeProps) { 30 | return
31 | } 32 | 33 | export default Badge 34 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/ui/Button.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import { Slot } from '@radix-ui/react-slot' 3 | import { cva, type VariantProps } from 'class-variance-authority' 4 | import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/Tooltip' 5 | import { cn } from '@/lib/utils' 6 | 7 | // eslint-disable-next-line react-refresh/only-export-components 8 | export const buttonVariants = cva( 9 | 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0', 10 | { 11 | variants: { 12 | variant: { 13 | default: 'bg-primary text-primary-foreground hover:bg-primary/90', 14 | destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90', 15 | outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground', 16 | secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80', 17 | ghost: 'hover:bg-accent hover:text-accent-foreground', 18 | link: 'text-primary underline-offset-4 hover:underline' 19 | }, 20 | size: { 21 | default: 'h-10 px-4 py-2', 22 | sm: 'h-9 rounded-md px-3', 23 | lg: 'h-11 rounded-md px-8', 24 | icon: 'size-8' 25 | } 26 | }, 27 | defaultVariants: { 28 | variant: 'default', 29 | size: 'default' 30 | } 31 | } 32 | ) 33 | 34 | interface ButtonProps 35 | extends React.ButtonHTMLAttributes, 36 | VariantProps { 37 | asChild?: boolean 38 | side?: 'top' | 'right' | 'bottom' | 'left' 39 | tooltip?: string 40 | } 41 | 42 | const Button = React.forwardRef( 43 | ({ className, variant, tooltip, size, side = 'right', asChild = false, ...props }, ref) => { 44 | const Comp = asChild ? Slot : 'button' 45 | if (!tooltip) { 46 | return ( 47 | 52 | ) 53 | } 54 | 55 | return ( 56 | 57 | 58 | 59 | 64 | 65 | {tooltip} 66 | 67 | 68 | ) 69 | } 70 | ) 71 | Button.displayName = 'Button' 72 | 73 | export type ButtonVariantType = Exclude< 74 | NonNullable[0]>['variant'], 75 | undefined 76 | > 77 | 78 | export default Button 79 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/ui/Card.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | import { cn } from '@/lib/utils' 4 | 5 | const Card = React.forwardRef>( 6 | ({ className, ...props }, ref) => ( 7 |
12 | ) 13 | ) 14 | Card.displayName = 'Card' 15 | 16 | const CardHeader = React.forwardRef>( 17 | ({ className, ...props }, ref) => ( 18 |
19 | ) 20 | ) 21 | CardHeader.displayName = 'CardHeader' 22 | 23 | const CardTitle = React.forwardRef>( 24 | ({ className, ...props }, ref) => ( 25 |
30 | ) 31 | ) 32 | CardTitle.displayName = 'CardTitle' 33 | 34 | const CardDescription = React.forwardRef>( 35 | ({ className, ...props }, ref) => ( 36 |
37 | ) 38 | ) 39 | CardDescription.displayName = 'CardDescription' 40 | 41 | const CardContent = React.forwardRef>( 42 | ({ className, ...props }, ref) => ( 43 |
44 | ) 45 | ) 46 | CardContent.displayName = 'CardContent' 47 | 48 | const CardFooter = React.forwardRef>( 49 | ({ className, ...props }, ref) => ( 50 |
51 | ) 52 | ) 53 | CardFooter.displayName = 'CardFooter' 54 | 55 | export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } 56 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/ui/Checkbox.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import * as CheckboxPrimitive from '@radix-ui/react-checkbox' 3 | import { Check } from 'lucide-react' 4 | 5 | import { cn } from '@/lib/utils' 6 | 7 | const Checkbox = React.forwardRef< 8 | React.ComponentRef, 9 | React.ComponentPropsWithoutRef 10 | >(({ className, ...props }, ref) => ( 11 | 19 | 20 | 21 | 22 | 23 | )) 24 | Checkbox.displayName = CheckboxPrimitive.Root.displayName 25 | 26 | export default Checkbox 27 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/ui/DataTable.tsx: -------------------------------------------------------------------------------- 1 | import { ColumnDef, flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table' 2 | 3 | import { 4 | Table, 5 | TableBody, 6 | TableCell, 7 | TableHead, 8 | TableHeader, 9 | TableRow 10 | } from '@/components/ui/Table' 11 | 12 | interface DataTableProps { 13 | columns: ColumnDef[] 14 | data: TData[] 15 | } 16 | 17 | export default function DataTable({ columns, data }: DataTableProps) { 18 | const table = useReactTable({ 19 | data, 20 | columns, 21 | getCoreRowModel: getCoreRowModel() 22 | }) 23 | 24 | return ( 25 |
26 | 27 | 28 | {table.getHeaderGroups().map((headerGroup) => ( 29 | 30 | {headerGroup.headers.map((header) => { 31 | return ( 32 | 33 | {header.isPlaceholder 34 | ? null 35 | : flexRender(header.column.columnDef.header, header.getContext())} 36 | 37 | ) 38 | })} 39 | 40 | ))} 41 | 42 | 43 | {table.getRowModel().rows?.length ? ( 44 | table.getRowModel().rows.map((row) => ( 45 | 46 | {row.getVisibleCells().map((cell) => ( 47 | 48 | {flexRender(cell.column.columnDef.cell, cell.getContext())} 49 | 50 | ))} 51 | 52 | )) 53 | ) : ( 54 | 55 | 56 | No results. 57 | 58 | 59 | )} 60 | 61 |
62 |
63 | ) 64 | } 65 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/ui/EmptyCard.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils' 2 | import { Card, CardDescription, CardTitle } from '@/components/ui/Card' 3 | import { FilesIcon } from 'lucide-react' 4 | 5 | interface EmptyCardProps extends React.ComponentPropsWithoutRef { 6 | title: string 7 | description?: string 8 | action?: React.ReactNode 9 | icon?: React.ComponentType<{ className?: string }> 10 | } 11 | 12 | export default function EmptyCard({ 13 | title, 14 | description, 15 | icon: Icon = FilesIcon, 16 | action, 17 | className, 18 | ...props 19 | }: EmptyCardProps) { 20 | return ( 21 | 28 |
29 |
31 |
32 | {title} 33 | {description ? {description} : null} 34 |
35 | {action ? action : null} 36 |
37 | ) 38 | } 39 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/ui/Input.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import { cn } from '@/lib/utils' 3 | 4 | const Input = React.forwardRef>( 5 | ({ className, type, ...props }, ref) => { 6 | return ( 7 | 16 | ) 17 | } 18 | ) 19 | Input.displayName = 'Input' 20 | 21 | export default Input 22 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/ui/Popover.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import * as PopoverPrimitive from '@radix-ui/react-popover' 3 | 4 | import { cn } from '@/lib/utils' 5 | 6 | const Popover = PopoverPrimitive.Root 7 | 8 | const PopoverTrigger = PopoverPrimitive.Trigger 9 | 10 | // Define the props type to include positioning props 11 | type PopoverContentProps = React.ComponentPropsWithoutRef & { 12 | collisionPadding?: number | Partial>; 13 | sticky?: 'partial' | 'always'; 14 | avoidCollisions?: boolean; 15 | }; 16 | 17 | const PopoverContent = React.forwardRef< 18 | React.ComponentRef, 19 | PopoverContentProps 20 | >(({ className, align = 'center', sideOffset = 4, collisionPadding, sticky, avoidCollisions = false, ...props }, ref) => ( 21 | 22 | 35 | 36 | )) 37 | PopoverContent.displayName = PopoverPrimitive.Content.displayName 38 | 39 | export { Popover, PopoverTrigger, PopoverContent } 40 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/ui/Progress.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import * as ProgressPrimitive from '@radix-ui/react-progress' 3 | 4 | import { cn } from '@/lib/utils' 5 | 6 | const Progress = React.forwardRef< 7 | React.ComponentRef, 8 | React.ComponentPropsWithoutRef 9 | >(({ className, value, ...props }, ref) => ( 10 | 15 | 19 | 20 | )) 21 | Progress.displayName = ProgressPrimitive.Root.displayName 22 | 23 | export default Progress 24 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/ui/ScrollArea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area' 3 | 4 | import { cn } from '@/lib/utils' 5 | 6 | const ScrollArea = React.forwardRef< 7 | React.ComponentRef, 8 | React.ComponentPropsWithoutRef 9 | >(({ className, children, ...props }, ref) => ( 10 | 15 | 16 | {children} 17 | 18 | 19 | 20 | 21 | )) 22 | ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName 23 | 24 | const ScrollBar = React.forwardRef< 25 | React.ComponentRef, 26 | React.ComponentPropsWithoutRef 27 | >(({ className, orientation = 'vertical', ...props }, ref) => ( 28 | 39 | 40 | 41 | )) 42 | ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName 43 | 44 | export { ScrollArea, ScrollBar } 45 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/ui/Separator.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import * as SeparatorPrimitive from '@radix-ui/react-separator' 3 | 4 | import { cn } from '@/lib/utils' 5 | 6 | const Separator = React.forwardRef< 7 | React.ComponentRef, 8 | React.ComponentPropsWithoutRef 9 | >(({ className, orientation = 'horizontal', decorative = true, ...props }, ref) => ( 10 | 21 | )) 22 | Separator.displayName = SeparatorPrimitive.Root.displayName 23 | 24 | export default Separator 25 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/ui/TabContent.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | import { useTabVisibility } from '@/contexts/useTabVisibility'; 3 | 4 | interface TabContentProps { 5 | tabId: string; 6 | children: React.ReactNode; 7 | className?: string; 8 | } 9 | 10 | /** 11 | * TabContent component that manages visibility based on tab selection 12 | * Works with the TabVisibilityContext to show/hide content based on active tab 13 | */ 14 | const TabContent: React.FC = ({ tabId, children, className = '' }) => { 15 | const { isTabVisible, setTabVisibility } = useTabVisibility(); 16 | const isVisible = isTabVisible(tabId); 17 | 18 | // Register this tab with the context when mounted 19 | useEffect(() => { 20 | setTabVisibility(tabId, true); 21 | 22 | // Cleanup when unmounted 23 | return () => { 24 | setTabVisibility(tabId, false); 25 | }; 26 | }, [tabId, setTabVisibility]); 27 | 28 | // Use CSS to hide content instead of not rendering it 29 | // This prevents components from unmounting when tabs are switched 30 | return ( 31 |
32 | {children} 33 |
34 | ); 35 | }; 36 | 37 | export default TabContent; 38 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/ui/Table.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | import { cn } from '@/lib/utils' 4 | 5 | const Table = React.forwardRef>( 6 | ({ className, ...props }, ref) => ( 7 |
8 | 9 | 10 | ) 11 | ) 12 | Table.displayName = 'Table' 13 | 14 | const TableHeader = React.forwardRef< 15 | HTMLTableSectionElement, 16 | React.HTMLAttributes 17 | >(({ className, ...props }, ref) => ( 18 | 19 | )) 20 | TableHeader.displayName = 'TableHeader' 21 | 22 | const TableBody = React.forwardRef< 23 | HTMLTableSectionElement, 24 | React.HTMLAttributes 25 | >(({ className, ...props }, ref) => ( 26 | 27 | )) 28 | TableBody.displayName = 'TableBody' 29 | 30 | const TableFooter = React.forwardRef< 31 | HTMLTableSectionElement, 32 | React.HTMLAttributes 33 | >(({ className, ...props }, ref) => ( 34 | tr]:last:border-b-0', className)} 37 | {...props} 38 | /> 39 | )) 40 | TableFooter.displayName = 'TableFooter' 41 | 42 | const TableRow = React.forwardRef>( 43 | ({ className, ...props }, ref) => ( 44 | 52 | ) 53 | ) 54 | TableRow.displayName = 'TableRow' 55 | 56 | const TableHead = React.forwardRef< 57 | HTMLTableCellElement, 58 | React.ThHTMLAttributes 59 | // eslint-disable-next-line react/prop-types 60 | >(({ className, ...props }, ref) => ( 61 |
[role=checkbox]]:translate-y-[2px]', 65 | className 66 | )} 67 | {...props} 68 | /> 69 | )) 70 | TableHead.displayName = 'TableHead' 71 | 72 | const TableCell = React.forwardRef< 73 | HTMLTableCellElement, 74 | React.TdHTMLAttributes 75 | // eslint-disable-next-line react/prop-types 76 | >(({ className, ...props }, ref) => ( 77 | [role=checkbox]]:translate-y-[2px]', 81 | className 82 | )} 83 | {...props} 84 | /> 85 | )) 86 | TableCell.displayName = 'TableCell' 87 | 88 | const TableCaption = React.forwardRef< 89 | HTMLTableCaptionElement, 90 | React.HTMLAttributes 91 | >(({ className, ...props }, ref) => ( 92 |
93 | )) 94 | TableCaption.displayName = 'TableCaption' 95 | 96 | export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption } 97 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/ui/Tabs.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import * as TabsPrimitive from '@radix-ui/react-tabs' 3 | 4 | import { cn } from '@/lib/utils' 5 | 6 | const Tabs = TabsPrimitive.Root 7 | 8 | const TabsList = React.forwardRef< 9 | React.ComponentRef, 10 | React.ComponentPropsWithoutRef 11 | >(({ className, ...props }, ref) => ( 12 | 20 | )) 21 | TabsList.displayName = TabsPrimitive.List.displayName 22 | 23 | const TabsTrigger = React.forwardRef< 24 | React.ComponentRef, 25 | React.ComponentPropsWithoutRef 26 | >(({ className, ...props }, ref) => ( 27 | 35 | )) 36 | TabsTrigger.displayName = TabsPrimitive.Trigger.displayName 37 | 38 | const TabsContent = React.forwardRef< 39 | React.ComponentRef, 40 | React.ComponentPropsWithoutRef 41 | >(({ className, ...props }, ref) => ( 42 | 54 | )) 55 | TabsContent.displayName = TabsPrimitive.Content.displayName 56 | 57 | export { Tabs, TabsList, TabsTrigger, TabsContent } 58 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/ui/Text.tsx: -------------------------------------------------------------------------------- 1 | import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/Tooltip' 2 | import { cn } from '@/lib/utils' 3 | 4 | const Text = ({ 5 | text, 6 | className, 7 | tooltipClassName, 8 | tooltip, 9 | side, 10 | onClick 11 | }: { 12 | text: string 13 | className?: string 14 | tooltipClassName?: string 15 | tooltip?: string 16 | side?: 'top' | 'right' | 'bottom' | 'left' 17 | onClick?: () => void 18 | }) => { 19 | if (!tooltip) { 20 | return ( 21 | 27 | ) 28 | } 29 | 30 | return ( 31 | 32 | 33 | 34 | 40 | 41 | 42 | {tooltip} 43 | 44 | 45 | 46 | ) 47 | } 48 | 49 | export default Text 50 | -------------------------------------------------------------------------------- /lightrag_webui/src/components/ui/Tooltip.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import * as TooltipPrimitive from '@radix-ui/react-tooltip' 3 | import { cn } from '@/lib/utils' 4 | 5 | const TooltipProvider = TooltipPrimitive.Provider 6 | 7 | const Tooltip = TooltipPrimitive.Root 8 | 9 | const TooltipTrigger = TooltipPrimitive.Trigger 10 | 11 | const processTooltipContent = (content: string) => { 12 | if (typeof content !== 'string') return content 13 | return ( 14 |
15 | {content} 16 |
17 | ) 18 | } 19 | 20 | const TooltipContent = React.forwardRef< 21 | React.ComponentRef, 22 | React.ComponentPropsWithoutRef & { 23 | side?: 'top' | 'right' | 'bottom' | 'left' 24 | align?: 'start' | 'center' | 'end' 25 | } 26 | >(({ className, side = 'left', align = 'start', children, ...props }, ref) => { 27 | const contentRef = React.useRef(null); 28 | 29 | React.useEffect(() => { 30 | if (contentRef.current) { 31 | contentRef.current.scrollTop = 0; 32 | } 33 | }, [children]); 34 | 35 | return ( 36 | 46 | {typeof children === 'string' ? processTooltipContent(children) : children} 47 | 48 | ); 49 | }) 50 | TooltipContent.displayName = TooltipPrimitive.Content.displayName 51 | 52 | export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } 53 | -------------------------------------------------------------------------------- /lightrag_webui/src/contexts/TabVisibilityProvider.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect, useMemo } from 'react'; 2 | import { TabVisibilityContext } from './context'; 3 | import { TabVisibilityContextType } from './types'; 4 | import { useSettingsStore } from '@/stores/settings'; 5 | 6 | interface TabVisibilityProviderProps { 7 | children: React.ReactNode; 8 | } 9 | 10 | /** 11 | * Provider component for the TabVisibility context 12 | * Manages the visibility state of tabs throughout the application 13 | */ 14 | export const TabVisibilityProvider: React.FC = ({ children }) => { 15 | // Get current tab from settings store 16 | const currentTab = useSettingsStore.use.currentTab(); 17 | 18 | // Initialize visibility state with all tabs visible 19 | const [visibleTabs, setVisibleTabs] = useState>(() => ({ 20 | 'documents': true, 21 | 'knowledge-graph': true, 22 | 'retrieval': true, 23 | 'api': true 24 | })); 25 | 26 | // Keep all tabs visible because we use CSS to control TAB visibility instead of React 27 | useEffect(() => { 28 | setVisibleTabs((prev) => ({ 29 | ...prev, 30 | 'documents': true, 31 | 'knowledge-graph': true, 32 | 'retrieval': true, 33 | 'api': true 34 | })); 35 | }, [currentTab]); 36 | 37 | // Create the context value with memoization to prevent unnecessary re-renders 38 | const contextValue = useMemo( 39 | () => ({ 40 | visibleTabs, 41 | setTabVisibility: (tabId: string, isVisible: boolean) => { 42 | setVisibleTabs((prev) => ({ 43 | ...prev, 44 | [tabId]: isVisible, 45 | })); 46 | }, 47 | isTabVisible: (tabId: string) => !!visibleTabs[tabId], 48 | }), 49 | [visibleTabs] 50 | ); 51 | 52 | return ( 53 | 54 | {children} 55 | 56 | ); 57 | }; 58 | 59 | export default TabVisibilityProvider; 60 | -------------------------------------------------------------------------------- /lightrag_webui/src/contexts/context.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | import { TabVisibilityContextType } from './types'; 3 | 4 | // Default context value 5 | const defaultContext: TabVisibilityContextType = { 6 | visibleTabs: {}, 7 | setTabVisibility: () => {}, 8 | isTabVisible: () => false, 9 | }; 10 | 11 | // Create the context 12 | export const TabVisibilityContext = createContext(defaultContext); 13 | -------------------------------------------------------------------------------- /lightrag_webui/src/contexts/types.ts: -------------------------------------------------------------------------------- 1 | export interface TabVisibilityContextType { 2 | visibleTabs: Record; 3 | setTabVisibility: (tabId: string, isVisible: boolean) => void; 4 | isTabVisible: (tabId: string) => boolean; 5 | } 6 | -------------------------------------------------------------------------------- /lightrag_webui/src/contexts/useTabVisibility.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | import { TabVisibilityContext } from './context'; 3 | import { TabVisibilityContextType } from './types'; 4 | 5 | /** 6 | * Custom hook to access the tab visibility context 7 | * @returns The tab visibility context 8 | */ 9 | export const useTabVisibility = (): TabVisibilityContextType => { 10 | const context = useContext(TabVisibilityContext); 11 | 12 | if (!context) { 13 | throw new Error('useTabVisibility must be used within a TabVisibilityProvider'); 14 | } 15 | 16 | return context; 17 | }; 18 | -------------------------------------------------------------------------------- /lightrag_webui/src/features/ApiSite.tsx: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react' 2 | import { useTabVisibility } from '@/contexts/useTabVisibility' 3 | import { backendBaseUrl } from '@/lib/constants' 4 | import { useTranslation } from 'react-i18next' 5 | 6 | export default function ApiSite() { 7 | const { t } = useTranslation() 8 | const { isTabVisible } = useTabVisibility() 9 | const isApiTabVisible = isTabVisible('api') 10 | const [iframeLoaded, setIframeLoaded] = useState(false) 11 | 12 | // Load the iframe once on component mount 13 | useEffect(() => { 14 | if (!iframeLoaded) { 15 | setIframeLoaded(true) 16 | } 17 | }, [iframeLoaded]) 18 | 19 | // Use CSS to hide content when tab is not visible 20 | return ( 21 |
22 | {iframeLoaded ? ( 23 |