Merge branch 'main' into feat-node-expand
This commit is contained in:
16
Dockerfile
16
Dockerfile
@@ -1,13 +1,23 @@
|
|||||||
# Build stage
|
# Build stage
|
||||||
FROM python:3.11-slim as builder
|
FROM python:3.11-slim AS builder
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install Rust and required build dependencies
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
curl \
|
||||||
|
build-essential \
|
||||||
|
pkg-config \
|
||||||
|
&& rm -rf /var/lib/apt/lists/* \
|
||||||
|
&& curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y \
|
||||||
|
&& . $HOME/.cargo/env
|
||||||
|
|
||||||
# Copy only requirements files first to leverage Docker cache
|
# Copy only requirements files first to leverage Docker cache
|
||||||
COPY requirements.txt .
|
COPY requirements.txt .
|
||||||
COPY lightrag/api/requirements.txt ./lightrag/api/
|
COPY lightrag/api/requirements.txt ./lightrag/api/
|
||||||
|
|
||||||
# Install dependencies
|
# Install dependencies
|
||||||
|
ENV PATH="/root/.cargo/bin:${PATH}"
|
||||||
RUN pip install --user --no-cache-dir -r requirements.txt
|
RUN pip install --user --no-cache-dir -r requirements.txt
|
||||||
RUN pip install --user --no-cache-dir -r lightrag/api/requirements.txt
|
RUN pip install --user --no-cache-dir -r lightrag/api/requirements.txt
|
||||||
|
|
||||||
@@ -28,6 +38,10 @@ ENV PATH=/root/.local/bin:$PATH
|
|||||||
# Create necessary directories
|
# Create necessary directories
|
||||||
RUN mkdir -p /app/data/rag_storage /app/data/inputs
|
RUN mkdir -p /app/data/rag_storage /app/data/inputs
|
||||||
|
|
||||||
|
# Docker data directories
|
||||||
|
ENV WORKING_DIR=/app/data/rag_storage
|
||||||
|
ENV INPUT_DIR=/app/data/inputs
|
||||||
|
|
||||||
# Expose the default port
|
# Expose the default port
|
||||||
EXPOSE 9621
|
EXPOSE 9621
|
||||||
|
|
||||||
|
0
README-zh.md
Normal file
0
README-zh.md
Normal file
@@ -3,6 +3,7 @@ ascii_colors
|
|||||||
asyncpg
|
asyncpg
|
||||||
distro
|
distro
|
||||||
fastapi
|
fastapi
|
||||||
|
graspologic>=3.4.1
|
||||||
httpcore
|
httpcore
|
||||||
httpx
|
httpx
|
||||||
jiter
|
jiter
|
||||||
|
@@ -1843,9 +1843,10 @@ class LightRAG:
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# 1. Get current entity information
|
# 1. Get current entity information
|
||||||
node_data = await self.chunk_entity_relation_graph.get_node(entity_name)
|
node_exists = await self.chunk_entity_relation_graph.has_node(entity_name)
|
||||||
if not node_data:
|
if not node_exists:
|
||||||
raise ValueError(f"Entity '{entity_name}' does not exist")
|
raise ValueError(f"Entity '{entity_name}' does not exist")
|
||||||
|
node_data = await self.chunk_entity_relation_graph.get_node(entity_name)
|
||||||
|
|
||||||
# Check if entity is being renamed
|
# Check if entity is being renamed
|
||||||
new_entity_name = updated_data.get("entity_name", entity_name)
|
new_entity_name = updated_data.get("entity_name", entity_name)
|
||||||
@@ -1858,7 +1859,7 @@ class LightRAG:
|
|||||||
"Entity renaming is not allowed. Set allow_rename=True to enable this feature"
|
"Entity renaming is not allowed. Set allow_rename=True to enable this feature"
|
||||||
)
|
)
|
||||||
|
|
||||||
existing_node = await self.chunk_entity_relation_graph.get_node(
|
existing_node = await self.chunk_entity_relation_graph.has_node(
|
||||||
new_entity_name
|
new_entity_name
|
||||||
)
|
)
|
||||||
if existing_node:
|
if existing_node:
|
||||||
@@ -2040,14 +2041,16 @@ class LightRAG:
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# 1. Get current relation information
|
# 1. Get current relation information
|
||||||
edge_data = await self.chunk_entity_relation_graph.get_edge(
|
edge_exists = await self.chunk_entity_relation_graph.has_edge(
|
||||||
source_entity, target_entity
|
source_entity, target_entity
|
||||||
)
|
)
|
||||||
if not edge_data:
|
if not edge_exists:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"Relation from '{source_entity}' to '{target_entity}' does not exist"
|
f"Relation from '{source_entity}' to '{target_entity}' does not exist"
|
||||||
)
|
)
|
||||||
|
edge_data = await self.chunk_entity_relation_graph.get_edge(
|
||||||
|
source_entity, target_entity
|
||||||
|
)
|
||||||
# Important: First delete the old relation record from the vector database
|
# Important: First delete the old relation record from the vector database
|
||||||
old_relation_id = compute_mdhash_id(
|
old_relation_id = compute_mdhash_id(
|
||||||
source_entity + target_entity, prefix="rel-"
|
source_entity + target_entity, prefix="rel-"
|
||||||
@@ -2156,7 +2159,7 @@ class LightRAG:
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# Check if entity already exists
|
# Check if entity already exists
|
||||||
existing_node = await self.chunk_entity_relation_graph.get_node(entity_name)
|
existing_node = await self.chunk_entity_relation_graph.has_node(entity_name)
|
||||||
if existing_node:
|
if existing_node:
|
||||||
raise ValueError(f"Entity '{entity_name}' already exists")
|
raise ValueError(f"Entity '{entity_name}' already exists")
|
||||||
|
|
||||||
@@ -2250,7 +2253,7 @@ class LightRAG:
|
|||||||
raise ValueError(f"Target entity '{target_entity}' does not exist")
|
raise ValueError(f"Target entity '{target_entity}' does not exist")
|
||||||
|
|
||||||
# Check if relation already exists
|
# Check if relation already exists
|
||||||
existing_edge = await self.chunk_entity_relation_graph.get_edge(
|
existing_edge = await self.chunk_entity_relation_graph.has_edge(
|
||||||
source_entity, target_entity
|
source_entity, target_entity
|
||||||
)
|
)
|
||||||
if existing_edge:
|
if existing_edge:
|
||||||
@@ -2383,19 +2386,22 @@ class LightRAG:
|
|||||||
# 1. Check if all source entities exist
|
# 1. Check if all source entities exist
|
||||||
source_entities_data = {}
|
source_entities_data = {}
|
||||||
for entity_name in source_entities:
|
for entity_name in source_entities:
|
||||||
node_data = await self.chunk_entity_relation_graph.get_node(entity_name)
|
node_exists = await self.chunk_entity_relation_graph.has_node(
|
||||||
if not node_data:
|
entity_name
|
||||||
|
)
|
||||||
|
if not node_exists:
|
||||||
raise ValueError(f"Source entity '{entity_name}' does not exist")
|
raise ValueError(f"Source entity '{entity_name}' does not exist")
|
||||||
|
node_data = await self.chunk_entity_relation_graph.get_node(entity_name)
|
||||||
source_entities_data[entity_name] = node_data
|
source_entities_data[entity_name] = node_data
|
||||||
|
|
||||||
# 2. Check if target entity exists and get its data if it does
|
# 2. Check if target entity exists and get its data if it does
|
||||||
target_exists = await self.chunk_entity_relation_graph.has_node(
|
target_exists = await self.chunk_entity_relation_graph.has_node(
|
||||||
target_entity
|
target_entity
|
||||||
)
|
)
|
||||||
target_entity_data = {}
|
existing_target_entity_data = {}
|
||||||
if target_exists:
|
if target_exists:
|
||||||
target_entity_data = await self.chunk_entity_relation_graph.get_node(
|
existing_target_entity_data = (
|
||||||
target_entity
|
await self.chunk_entity_relation_graph.get_node(target_entity)
|
||||||
)
|
)
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Target entity '{target_entity}' already exists, will merge data"
|
f"Target entity '{target_entity}' already exists, will merge data"
|
||||||
@@ -2404,7 +2410,7 @@ class LightRAG:
|
|||||||
# 3. Merge entity data
|
# 3. Merge entity data
|
||||||
merged_entity_data = self._merge_entity_attributes(
|
merged_entity_data = self._merge_entity_attributes(
|
||||||
list(source_entities_data.values())
|
list(source_entities_data.values())
|
||||||
+ ([target_entity_data] if target_exists else []),
|
+ ([existing_target_entity_data] if target_exists else []),
|
||||||
merge_strategy,
|
merge_strategy,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -123,18 +123,21 @@ async def openai_complete_if_cache(
|
|||||||
|
|
||||||
async def inner():
|
async def inner():
|
||||||
try:
|
try:
|
||||||
|
_content = ""
|
||||||
async for chunk in response:
|
async for chunk in response:
|
||||||
content = chunk.choices[0].delta.content
|
content = chunk.choices[0].delta.content
|
||||||
if content is None:
|
if content is None:
|
||||||
continue
|
continue
|
||||||
if r"\u" in content:
|
if r"\u" in content:
|
||||||
content = safe_unicode_decode(content.encode("utf-8"))
|
content = safe_unicode_decode(content.encode("utf-8"))
|
||||||
yield content
|
_content += content
|
||||||
|
return _content
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error in stream response: {str(e)}")
|
logger.error(f"Error in stream response: {str(e)}")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
return inner()
|
response_content = await inner()
|
||||||
|
return response_content
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if (
|
if (
|
||||||
|
Reference in New Issue
Block a user