From 19073319c150e825b6f53b3f5c588eb8d7572c21 Mon Sep 17 00:00:00 2001 From: yangdx Date: Wed, 1 Oct 2025 00:32:19 +0800 Subject: [PATCH 01/11] Add @tanstack/react-table dependency for table functionality MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Add react-table v8.21.3 • Include table-core dependency • Update package.json • Update bun.lock file --- lightrag_webui/bun.lock | 5 +++++ lightrag_webui/package.json | 1 + 2 files changed, 6 insertions(+) diff --git a/lightrag_webui/bun.lock b/lightrag_webui/bun.lock index 2ba1883c..117ab76a 100644 --- a/lightrag_webui/bun.lock +++ b/lightrag_webui/bun.lock @@ -28,6 +28,7 @@ "@react-sigma/minimap": "^5.0.2", "@sigma/edge-curve": "^3.1.0", "@sigma/node-border": "^3.0.0", + "@tanstack/react-table": "^8.21.3", "axios": "^1.7.9", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", @@ -447,6 +448,10 @@ "@tailwindcss/vite": ["@tailwindcss/vite@4.0.8", "", { "dependencies": { "@tailwindcss/node": "4.0.8", "@tailwindcss/oxide": "4.0.8", "lightningcss": "^1.29.1", "tailwindcss": "4.0.8" }, "peerDependencies": { "vite": "^5.2.0 || ^6" } }, "sha512-+SAq44yLzYlzyrb7QTcFCdU8Xa7FOA0jp+Xby7fPMUie+MY9HhJysM7Vp+vL8qIp8ceQJfLD+FjgJuJ4lL6nyg=="], + "@tanstack/react-table": ["@tanstack/react-table@8.21.3", "", { "dependencies": { "@tanstack/table-core": "8.21.3" }, "peerDependencies": { "react": ">=16.8", "react-dom": ">=16.8" } }, "sha512-5nNMTSETP4ykGegmVkhjcS8tTLW6Vl4axfEGQN3v0zdHYbK4UfoqfPChclTrJ4EoK9QynqAu9oUf8VEmrpZ5Ww=="], + + "@tanstack/table-core": ["@tanstack/table-core@8.21.3", "", {}, "sha512-ldZXEhOBb8Is7xLs01fR3YEc3DERiz5silj8tnGkFZytt1abEvl/GhUmCE0PMLaMPTa3Jk4HbKmRlHmu+gCftg=="], + "@types/bun": ["@types/bun@1.2.3", "", { "dependencies": { "bun-types": "1.2.3" } }, "sha512-054h79ipETRfjtsCW9qJK8Ipof67Pw9bodFWmkfkaUaRiIQ1dIV2VTlheshlBx3mpKr0KeK8VqnMMCtgN9rQtw=="], "@types/cookie": ["@types/cookie@0.6.0", "https://registry.npmmirror.com/@types/cookie/-/cookie-0.6.0.tgz", {}, "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="], diff --git a/lightrag_webui/package.json b/lightrag_webui/package.json index f7b0d829..74265e42 100644 --- a/lightrag_webui/package.json +++ b/lightrag_webui/package.json @@ -40,6 +40,7 @@ "@react-sigma/minimap": "^5.0.2", "@sigma/edge-curve": "^3.1.0", "@sigma/node-border": "^3.0.0", + "@tanstack/react-table": "^8.21.3", "axios": "^1.7.9", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", From 83d99e1424897e3b2a09711e86aeb980f9e9028e Mon Sep 17 00:00:00 2001 From: yangdx Date: Wed, 1 Oct 2025 20:48:37 +0800 Subject: [PATCH 02/11] fix(OllamaAPI): Add validation to ensure last message is from user role MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Validate last message role is "user" • Raise 400 error for invalid role • Improve API request validation • Prevent invalid message sequences --- lightrag/api/routers/ollama_api.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lightrag/api/routers/ollama_api.py b/lightrag/api/routers/ollama_api.py index 426583f8..f9353dda 100644 --- a/lightrag/api/routers/ollama_api.py +++ b/lightrag/api/routers/ollama_api.py @@ -483,6 +483,12 @@ class OllamaAPI: if not messages: raise HTTPException(status_code=400, detail="No messages provided") + # Validate that the last message is from a user + if messages[-1].role != "user": + raise HTTPException( + status_code=400, detail="Last message must be from user role" + ) + # Get the last message as query and previous messages as history query = messages[-1].content # Convert OllamaMessage objects to dictionaries From f83cde14df53e9d5337633ae2a676963a0fbe7d4 Mon Sep 17 00:00:00 2001 From: yangdx Date: Wed, 1 Oct 2025 21:41:12 +0800 Subject: [PATCH 03/11] fix(prompt): Improve markdown formatting requirements and reference style --- lightrag/prompt.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/lightrag/prompt.py b/lightrag/prompt.py index bcf52683..bd010cd2 100644 --- a/lightrag/prompt.py +++ b/lightrag/prompt.py @@ -237,7 +237,7 @@ Consider the conversation history if provided to maintain conversational flow an **3. Formatting & Language:** - The response MUST be in the same language as the user query. - - Use Markdown for clear formatting (e.g., headings, bold, lists). + - The response MUST utilize Markdown formatting for enhanced clarity and structure (e.g., headings, bold text, bullet points). - The response should be presented in {response_type}. **4. References Section Format:** @@ -251,9 +251,10 @@ Consider the conversation history if provided to maintain conversational flow an **5. Reference Section Example:** ``` ### References -* [1] Document Title One -* [2] Document Title Two -* [3] Document Title Three + +- [1] Document Title One +- [2] Document Title Two +- [3] Document Title Three ``` **6. Additional Instructions**: {user_prompt} @@ -290,7 +291,7 @@ Consider the conversation history if provided to maintain conversational flow an **3. Formatting & Language:** - The response MUST be in the same language as the user query. - - Use Markdown for clear formatting (e.g., headings, bold, lists). + - The response MUST utilize Markdown formatting for enhanced clarity and structure (e.g., headings, bold text, bullet points). - The response should be presented in {response_type}. **4. References Section Format:** @@ -304,9 +305,10 @@ Consider the conversation history if provided to maintain conversational flow an **5. Reference Section Example:** ``` ### References -* [1] Document Title One -* [2] Document Title Two -* [3] Document Title Three + +- [1] Document Title One +- [2] Document Title Two +- [3] Document Title Three ``` **6. Additional Instructions**: {user_prompt} From 37e8898cf63aae788d593ca914aba6c6470a2c26 Mon Sep 17 00:00:00 2001 From: yangdx Date: Wed, 1 Oct 2025 22:20:58 +0800 Subject: [PATCH 04/11] Simplify reference formatting in LLM context generation - Remove extra newlines in reference lists - Change code block type from text to generic --- lightrag/operate.py | 4 ++-- lightrag/prompt.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lightrag/operate.py b/lightrag/operate.py index 15ba7696..cd8d8a64 100644 --- a/lightrag/operate.py +++ b/lightrag/operate.py @@ -3233,7 +3233,7 @@ async def _build_llm_context( text_units_str = "\n".join( json.dumps(text_unit, ensure_ascii=False) for text_unit in text_units_context ) - reference_list_str = "\n\n".join( + reference_list_str = "\n".join( f"[{ref['reference_id']}] {ref['file_path']}" for ref in reference_list if ref["reference_id"] @@ -4124,7 +4124,7 @@ async def naive_query( text_units_str = "\n".join( json.dumps(text_unit, ensure_ascii=False) for text_unit in text_units_context ) - reference_list_str = "\n\n".join( + reference_list_str = "\n".join( f"[{ref['reference_id']}] {ref['file_path']}" for ref in reference_list if ref["reference_id"] diff --git a/lightrag/prompt.py b/lightrag/prompt.py index bd010cd2..ded23c7e 100644 --- a/lightrag/prompt.py +++ b/lightrag/prompt.py @@ -340,7 +340,7 @@ Document Chunks (Each entry has a reference_id refer to the `Reference Document Reference Document List (Each entry starts with a [reference_id] that corresponds to entries in the Document Chunks): -```text +``` {reference_list_str} ``` @@ -355,7 +355,7 @@ Document Chunks (Each entry has a reference_id refer to the `Reference Document Reference Document List (Each entry starts with a [reference_id] that corresponds to entries in the Document Chunks): -```text +``` {reference_list_str} ``` From bb6138e7486bb75f5a8f28060074d5e363c81de7 Mon Sep 17 00:00:00 2001 From: yangdx Date: Wed, 1 Oct 2025 22:35:26 +0800 Subject: [PATCH 05/11] fix(prompt): Clarify reference section restrictions in prompt templates --- lightrag/prompt.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lightrag/prompt.py b/lightrag/prompt.py index ded23c7e..d639b4b8 100644 --- a/lightrag/prompt.py +++ b/lightrag/prompt.py @@ -246,7 +246,7 @@ Consider the conversation history if provided to maintain conversational flow an - The Document Title in the citation must retain its original language. - Output each citation on an individual line - Provide maximum of 5 most relevant citations. - - Do not generate footnotes section or any text after the references. + - Do not generate footnotes section or any comment, summary, or explanation after the references. **5. Reference Section Example:** ``` @@ -300,7 +300,7 @@ Consider the conversation history if provided to maintain conversational flow an - The Document Title in the citation must retain its original language. - Output each citation on an individual line - Provide maximum of 5 most relevant citations. - - Do not generate footnotes section or any text after the references. + - Do not generate footnotes section or any comment, summary, or explanation after the references. **5. Reference Section Example:** ``` From 6bf6f43d96f5f5dfda9d123bfd77f4a9184b9031 Mon Sep 17 00:00:00 2001 From: yangdx Date: Thu, 2 Oct 2025 00:58:03 +0800 Subject: [PATCH 06/11] Remove bold formatting from instruction headers in prompts --- lightrag/prompt.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/lightrag/prompt.py b/lightrag/prompt.py index d639b4b8..8faebbf4 100644 --- a/lightrag/prompt.py +++ b/lightrag/prompt.py @@ -223,24 +223,24 @@ Consider the conversation history if provided to maintain conversational flow an ---Instructions--- -**1. Step-by-Step Instruction:** +1. Step-by-Step Instruction: - Carefully determine the user's query intent in the context of the conversation history to fully understand the user's information need. - Scrutinize both `Knowledge Graph Data` and `Document Chunks` in the **Context**. Identify and extract all pieces of information that are directly relevant to answering the user query. - Weave the extracted facts into a coherent and logical response. Your own knowledge must ONLY be used to formulate fluent sentences and connect ideas, NOT to introduce any external information. - Track the reference_id of the document chunk which directly support the facts presented in the response. Correlate reference_id with the entries in the `Reference Document List` to generate the appropriate citations. - - Generate a **References** section at the end of the response. Each reference document must directly support the facts presented in the response. + - Generate a references section at the end of the response. Each reference document must directly support the facts presented in the response. - Do not generate anything after the reference section. -**2. Content & Grounding:** +2. Content & Grounding: - Strictly adhere to the provided context from the **Context**; DO NOT invent, assume, or infer any information not explicitly stated. - If the answer cannot be found in the **Context**, state that you do not have enough information to answer. Do not attempt to guess. -**3. Formatting & Language:** +3. Formatting & Language: - The response MUST be in the same language as the user query. - The response MUST utilize Markdown formatting for enhanced clarity and structure (e.g., headings, bold text, bullet points). - The response should be presented in {response_type}. -**4. References Section Format:** +4. References Section Format: - The References section should be under heading: `### References` - Reference list entries should adhere to the format: `* [n] Document Title`. Do not include a caret (`^`) after opening square bracket (`[`). - The Document Title in the citation must retain its original language. @@ -248,7 +248,7 @@ Consider the conversation history if provided to maintain conversational flow an - Provide maximum of 5 most relevant citations. - Do not generate footnotes section or any comment, summary, or explanation after the references. -**5. Reference Section Example:** +5. Reference Section Example: ``` ### References @@ -257,7 +257,7 @@ Consider the conversation history if provided to maintain conversational flow an - [3] Document Title Three ``` -**6. Additional Instructions**: {user_prompt} +6. Additional Instructions: {user_prompt} ---Context--- @@ -277,7 +277,7 @@ Consider the conversation history if provided to maintain conversational flow an ---Instructions--- -**1. Think Step-by-Step:** +1. Step-by-Step Instruction: - Carefully determine the user's query intent in the context of the conversation history to fully understand the user's information need. - Scrutinize `Document Chunks` in the **Context**. Identify and extract all pieces of information that are directly relevant to answering the user query. - Weave the extracted facts into a coherent and logical response. Your own knowledge must ONLY be used to formulate fluent sentences and connect ideas, NOT to introduce any external information. @@ -285,16 +285,16 @@ Consider the conversation history if provided to maintain conversational flow an - Generate a **References** section at the end of the response. Each reference document must directly support the facts presented in the response. - Do not generate anything after the reference section. -**2. Content & Grounding:** +2. Content & Grounding: - Strictly adhere to the provided context from the **Context**; DO NOT invent, assume, or infer any information not explicitly stated. - If the answer cannot be found in the **Context**, state that you do not have enough information to answer. Do not attempt to guess. -**3. Formatting & Language:** +3. Formatting & Language: - The response MUST be in the same language as the user query. - The response MUST utilize Markdown formatting for enhanced clarity and structure (e.g., headings, bold text, bullet points). - The response should be presented in {response_type}. -**4. References Section Format:** +4. References Section Format: - The References section should be under heading: `### References` - Reference list entries should adhere to the format: `* [n] Document Title`. Do not include a caret (`^`) after opening square bracket (`[`). - The Document Title in the citation must retain its original language. @@ -302,7 +302,7 @@ Consider the conversation history if provided to maintain conversational flow an - Provide maximum of 5 most relevant citations. - Do not generate footnotes section or any comment, summary, or explanation after the references. -**5. Reference Section Example:** +5. Reference Section Example: ``` ### References @@ -311,7 +311,7 @@ Consider the conversation history if provided to maintain conversational flow an - [3] Document Title Three ``` -**6. Additional Instructions**: {user_prompt} +6. Additional Instructions: {user_prompt} ---Context--- From 7297ca1d5c1c056958900c8e961f8466106a8a38 Mon Sep 17 00:00:00 2001 From: Roman Marchuk Date: Wed, 1 Oct 2025 17:36:25 -0400 Subject: [PATCH 07/11] Fix dark mode graph labels for system theme and improve colors - Fix dark mode detection to work when theme is set to 'system' - Add real-time system theme change detection - Update label colors from cyan to white for better readability - Update edge colors to medium gray (#888888) for better contrast - Add development feature: random graph generator button in settings - Enhance random graph with edge attributes and labels - Install missing graphology layout dependencies --- lightrag_webui/package.json | 5 ++++ .../src/components/graph/GraphControl.tsx | 21 +++++++++++-- .../src/components/graph/Settings.tsx | 30 ++++++++++++++++++- lightrag_webui/src/hooks/useRandomGraph.tsx | 10 +++++++ lightrag_webui/src/lib/constants.ts | 8 ++--- 5 files changed, 67 insertions(+), 7 deletions(-) diff --git a/lightrag_webui/package.json b/lightrag_webui/package.json index d15a0aab..7ed9ffcb 100644 --- a/lightrag_webui/package.json +++ b/lightrag_webui/package.json @@ -43,6 +43,10 @@ "cmdk": "^1.0.4", "graphology": "^0.26.0", "graphology-generators": "^0.11.2", + "graphology-layout": "^0.6.1", + "graphology-layout-force": "^0.2.4", + "graphology-layout-forceatlas2": "^0.10.1", + "graphology-layout-noverlap": "^0.4.2", "i18next": "^24.2.2", "katex": "^0.16.22", "lucide-react": "^0.475.0", @@ -56,6 +60,7 @@ "react-markdown": "^9.1.0", "react-number-format": "^5.4.3", "react-router-dom": "^7.3.0", + "react-select": "^5.10.2", "react-syntax-highlighter": "^15.6.1", "rehype-katex": "^7.0.1", "rehype-react": "^8.0.0", diff --git a/lightrag_webui/src/components/graph/GraphControl.tsx b/lightrag_webui/src/components/graph/GraphControl.tsx index af7cf250..fc0114e9 100644 --- a/lightrag_webui/src/components/graph/GraphControl.tsx +++ b/lightrag_webui/src/components/graph/GraphControl.tsx @@ -2,7 +2,7 @@ import { useRegisterEvents, useSetSettings, useSigma } from '@react-sigma/core' import { AbstractGraph } from 'graphology-types' // import { useLayoutCircular } from '@react-sigma/layout-circular' import { useLayoutForceAtlas2 } from '@react-sigma/layout-forceatlas2' -import { useEffect } from 'react' +import { useEffect, useState } from 'react' // import useRandomGraph, { EdgeType, NodeType } from '@/hooks/useRandomGraph' import { EdgeType, NodeType } from '@/hooks/useLightragGraph' @@ -43,6 +43,20 @@ const GraphControl = ({ disableHoverEffect }: { disableHoverEffect?: boolean }) const selectedEdge = useGraphStore.use.selectedEdge() const focusedEdge = useGraphStore.use.focusedEdge() const sigmaGraph = useGraphStore.use.sigmaGraph() + + // Track system theme changes when theme is set to 'system' + const [systemThemeIsDark, setSystemThemeIsDark] = useState(() => + window.matchMedia('(prefers-color-scheme: dark)').matches + ) + + useEffect(() => { + if (theme === 'system') { + const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)') + const handler = (e: MediaQueryListEvent) => setSystemThemeIsDark(e.matches) + mediaQuery.addEventListener('change', handler) + return () => mediaQuery.removeEventListener('change', handler) + } + }, [theme]) /** * When component mount or maxIterations changes @@ -194,7 +208,9 @@ const GraphControl = ({ disableHoverEffect }: { disableHoverEffect?: boolean }) * => Setting the sigma reducers */ useEffect(() => { - const isDarkTheme = theme === 'dark' + // Check if dark mode is actually applied (handles both 'dark' theme and 'system' theme when OS is dark) + const isDarkTheme = theme === 'dark' || + (theme === 'system' && window.document.documentElement.classList.contains('dark')) const labelColor = isDarkTheme ? Constants.labelColorDarkTheme : undefined const edgeColor = isDarkTheme ? Constants.edgeColorDarkTheme : undefined @@ -298,6 +314,7 @@ const GraphControl = ({ disableHoverEffect }: { disableHoverEffect?: boolean }) sigma, disableHoverEffect, theme, + systemThemeIsDark, hideUnselectedEdges, enableEdgeEvents, renderEdgeLabels, diff --git a/lightrag_webui/src/components/graph/Settings.tsx b/lightrag_webui/src/components/graph/Settings.tsx index 37a36305..41da2f22 100644 --- a/lightrag_webui/src/components/graph/Settings.tsx +++ b/lightrag_webui/src/components/graph/Settings.tsx @@ -7,8 +7,10 @@ import Input from '@/components/ui/Input' import { controlButtonVariant } from '@/lib/constants' import { useSettingsStore } from '@/stores/settings' +import { useGraphStore } from '@/stores/graph' +import useRandomGraph from '@/hooks/useRandomGraph' -import { SettingsIcon, Undo2 } from 'lucide-react' +import { SettingsIcon, Undo2, Shuffle } from 'lucide-react' import { useTranslation } from 'react-i18next'; /** @@ -163,6 +165,9 @@ export default function Settings() { const enableHealthCheck = useSettingsStore.use.enableHealthCheck() + // Random graph functionality for development/testing + const { randomGraph } = useRandomGraph() + const setEnableNodeDrag = useCallback( () => useSettingsStore.setState((pre) => ({ enableNodeDrag: !pre.enableNodeDrag })), [] @@ -228,6 +233,11 @@ export default function Settings() { useSettingsStore.setState({ graphLayoutMaxIterations: iterations }) }, []) + const handleGenerateRandomGraph = useCallback(() => { + const graph = randomGraph() + useGraphStore.getState().setSigmaGraph(graph) + }, [randomGraph]) + const { t } = useTranslation(); const saveSettings = () => setOpened(false); @@ -376,6 +386,24 @@ export default function Settings() { defaultValue={15} onEditFinished={setGraphLayoutMaxIterations} /> + + + {/* Development/Testing Section */} +
+ + +
+ - + {/* Development/Testing Section - Only visible in development mode */} + {import.meta.env.DEV && ( + <> + - +
+ + +
+ + + + )}