yangdx commited on
Commit
77c6181
·
1 Parent(s): 4aa7946

Refactor graph search and add local Vite config.

Browse files

- Simplify graph search parameters in API
- Add inclusive search and min degree options
- Update Vite config for local development
- Enhance graph query endpoint in web UI
- Add new Vite config file for local setup

lightrag/api/routers/graph_routes.py CHANGED
@@ -3,9 +3,9 @@ This module contains all graph-related routes for the LightRAG API.
3
  """
4
 
5
  from typing import Optional
6
-
7
  from fastapi import APIRouter, Depends
8
 
 
9
  from ..utils_api import get_api_key_dependency
10
 
11
  router = APIRouter(tags=["graph"])
@@ -25,7 +25,7 @@ def create_graph_routes(rag, api_key: Optional[str] = None):
25
  return await rag.get_graph_labels()
26
 
27
  @router.get("/graphs", dependencies=[Depends(optional_api_key)])
28
- async def get_knowledge_graph(label: str, max_depth: int = 3):
29
  """
30
  Retrieve a connected subgraph of nodes where the label includes the specified label.
31
  Maximum number of nodes is constrained by the environment variable `MAX_GRAPH_NODES` (default: 1000).
@@ -34,50 +34,17 @@ def create_graph_routes(rag, api_key: Optional[str] = None):
34
  2. Followed by nodes directly connected to the matching nodes
35
  3. Finally, the degree of the nodes
36
  Maximum number of nodes is limited to env MAX_GRAPH_NODES(default: 1000)
37
- Control search mode by label content:
38
- 1. only label-name : exact search with the label name (selecting from the label list return previously)
39
- 2. label-name follow by '>n' : exact search of nodes with degree more than n
40
- 3. label-name follow by* : inclusive search of nodes with degree more than n
41
- 4. label-name follow by '>n*' : inclusive search
42
 
43
  Args:
44
  label (str): Label to get knowledge graph for
45
  max_depth (int, optional): Maximum depth of graph. Defaults to 3.
 
 
46
 
47
  Returns:
48
  Dict[str, List[str]]: Knowledge graph for label
49
  """
50
- # Parse label to extract search mode and min degree if specified
51
- search_mode = "exact" # Default search mode
52
- min_degree = 0 # Default minimum degree
53
- original_label = label
54
-
55
- # First check if label ends with *
56
- if label.endswith("*"):
57
- search_mode = "inclusive" # Always set to inclusive if ends with *
58
- label = label[:-1].strip() # Remove trailing *
59
-
60
- # Try to parse >n if it exists
61
- if ">" in label:
62
- try:
63
- degree_pos = label.rfind(">")
64
- degree_str = label[degree_pos + 1:].strip()
65
- min_degree = int(degree_str) + 1
66
- label = label[:degree_pos].strip()
67
- except ValueError:
68
- # If degree parsing fails, just remove * and keep the rest as label
69
- label = original_label[:-1].strip()
70
- # If no *, check for >n pattern
71
- elif ">" in label:
72
- try:
73
- degree_pos = label.rfind(">")
74
- degree_str = label[degree_pos + 1:].strip()
75
- min_degree = int(degree_str) + 1
76
- label = label[:degree_pos].strip()
77
- except ValueError:
78
- # If degree parsing fails, treat the whole string as label
79
- label = original_label
80
-
81
- return await rag.get_knowledge_graph(node_label=label, max_depth=max_depth, search_mode=search_mode, min_degree=min_degree)
82
 
83
  return router
 
3
  """
4
 
5
  from typing import Optional
 
6
  from fastapi import APIRouter, Depends
7
 
8
+ from ...utils import logger
9
  from ..utils_api import get_api_key_dependency
10
 
11
  router = APIRouter(tags=["graph"])
 
25
  return await rag.get_graph_labels()
26
 
27
  @router.get("/graphs", dependencies=[Depends(optional_api_key)])
28
+ async def get_knowledge_graph(label: str, max_depth: int = 3, inclusive: bool = False, min_degree: int = 0):
29
  """
30
  Retrieve a connected subgraph of nodes where the label includes the specified label.
31
  Maximum number of nodes is constrained by the environment variable `MAX_GRAPH_NODES` (default: 1000).
 
34
  2. Followed by nodes directly connected to the matching nodes
35
  3. Finally, the degree of the nodes
36
  Maximum number of nodes is limited to env MAX_GRAPH_NODES(default: 1000)
 
 
 
 
 
37
 
38
  Args:
39
  label (str): Label to get knowledge graph for
40
  max_depth (int, optional): Maximum depth of graph. Defaults to 3.
41
+ inclusive_search (bool, optional): If True, search for nodes that include the label. Defaults to False.
42
+ min_degree (int, optional): Minimum degree of nodes. Defaults to 0.
43
 
44
  Returns:
45
  Dict[str, List[str]]: Knowledge graph for label
46
  """
47
+ logger.info(f"Inclusive search : {inclusive}, Min degree: {min_degree}, Label: {label}")
48
+ return await rag.get_knowledge_graph(node_label=label, max_depth=max_depth, inclusive=inclusive, min_degree=min_degree)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
  return router
lightrag/lightrag.py CHANGED
@@ -504,7 +504,7 @@ class LightRAG:
504
  return text
505
 
506
  async def get_knowledge_graph(
507
- self, node_label: str, max_depth: int, search_mode: str = "exact", min_degree: int = 0
508
  ) -> KnowledgeGraph:
509
  """Get knowledge graph for a given label
510
 
@@ -520,8 +520,6 @@ class LightRAG:
520
  return await self.chunk_entity_relation_graph.get_knowledge_graph(
521
  node_label=node_label,
522
  max_depth=max_depth,
523
- search_mode=search_mode,
524
- min_degree=min_degree
525
  )
526
 
527
  def _get_storage_class(self, storage_name: str) -> Callable[..., Any]:
 
504
  return text
505
 
506
  async def get_knowledge_graph(
507
+ self, node_label: str, max_depth: int, inclusive: bool = False, min_degree: int = 0
508
  ) -> KnowledgeGraph:
509
  """Get knowledge graph for a given label
510
 
 
520
  return await self.chunk_entity_relation_graph.get_knowledge_graph(
521
  node_label=node_label,
522
  max_depth=max_depth,
 
 
523
  )
524
 
525
  def _get_storage_class(self, storage_name: str) -> Callable[..., Any]:
lightrag_webui/package.json CHANGED
@@ -4,11 +4,11 @@
4
  "version": "0.0.0",
5
  "type": "module",
6
  "scripts": {
7
- "dev": "bunx --bun vite",
8
  "build": "bunx --bun vite build",
9
  "lint": "eslint .",
10
  "preview": "bunx --bun vite preview",
11
- "dev-no-bun": "vite",
12
  "build-no-bun": "vite build --emptyOutDir",
13
  "preview-no-bun": "vite preview"
14
  },
 
4
  "version": "0.0.0",
5
  "type": "module",
6
  "scripts": {
7
+ "dev": "bunx --bun vite --config vite.config.local.js",
8
  "build": "bunx --bun vite build",
9
  "lint": "eslint .",
10
  "preview": "bunx --bun vite preview",
11
+ "dev-no-bun": "vite --config vite.config.local.js",
12
  "build-no-bun": "vite build --emptyOutDir",
13
  "preview-no-bun": "vite preview"
14
  },
lightrag_webui/src/api/lightrag.ts CHANGED
@@ -161,8 +161,12 @@ axiosInstance.interceptors.response.use(
161
  )
162
 
163
  // API methods
164
- export const queryGraphs = async (label: string, maxDepth: number): Promise<LightragGraphType> => {
165
- const response = await axiosInstance.get(`/graphs?label=${label}&max_depth=${maxDepth}`)
 
 
 
 
166
  return response.data
167
  }
168
 
 
161
  )
162
 
163
  // API methods
164
+ export const queryGraphs = async (
165
+ label: string,
166
+ maxDepth: number,
167
+ inclusive: boolean = false
168
+ ): Promise<LightragGraphType> => {
169
+ const response = await axiosInstance.get(`/graphs?label=${encodeURIComponent(label)}&max_depth=${maxDepth}&inclusive=${inclusive}`)
170
  return response.data
171
  }
172
 
lightrag_webui/vite.config.local.js ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { defineConfig } from 'vite'
2
+ import baseConfig from './vite.config'
3
+ import { mergeConfig } from 'vite'
4
+
5
+ export default mergeConfig(
6
+ baseConfig,
7
+ defineConfig({
8
+ server: {
9
+ proxy: {
10
+ '/api': {
11
+ target: 'http://localhost:9621',
12
+ changeOrigin: true,
13
+ rewrite: (path) => path.replace(/^\/api/, '')
14
+ },
15
+ '/documents': {
16
+ target: 'http://localhost:9621',
17
+ changeOrigin: true
18
+ },
19
+ '/graphs': {
20
+ target: 'http://localhost:9621',
21
+ changeOrigin: true
22
+ },
23
+ '/graph': {
24
+ target: 'http://localhost:9621',
25
+ changeOrigin: true
26
+ },
27
+ '/health': {
28
+ target: 'http://localhost:9621',
29
+ changeOrigin: true
30
+ },
31
+ '/query': {
32
+ target: 'http://localhost:9621',
33
+ changeOrigin: true
34
+ }
35
+ }
36
+ }
37
+ })
38
+ )