0.1.02思维导图全屏/lightrag修复/luckysheet修复

This commit is contained in:
liaibo
2026-01-06 05:21:53 +08:00
parent fb6832c30d
commit 9884ea0ea6
12 changed files with 570 additions and 199 deletions
+4 -5
View File
@@ -1,21 +1,20 @@
from functools import lru_cache
from pydantic import BaseSettings, Field
from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8", case_sensitive=False, extra="ignore")
app_name: str = Field("AIMNOTE RAG Gateway", env="RAG_GATEWAY_APP_NAME")
api_prefix: str = "/rag"
environment: str = Field("development", env="RAG_GATEWAY_ENV")
lightrag_url: str = Field("http://127.0.0.1:7777", env="LIGHTRAG_URL")
lightrag_api_key: str = Field("", env="LIGHTRAG_API_KEY")
supabase_rest_url: str = Field("http://127.0.0.1:54321/rest/v1", env="SUPABASE_REST_URL")
supabase_key: str = Field("", env="SUPABASE_SERVICE_ROLE_KEY")
embedding_base_url: str = Field("http://127.0.0.1:11434/v1", env="EMBEDDING_BASE_URL")
embedding_model: str = Field("qwen3-embedding:8b", env="EMBEDDING_MODEL")
class Config:
env_file = ".env"
case_sensitive = False
@lru_cache()
def get_gateway_settings() -> Settings:
@@ -1,37 +1,54 @@
import logging
import sys
from pathlib import Path
from typing import Any, Dict
from typing import Any, Dict, Optional
import httpx
from app.core.config import get_gateway_settings
ROOT = Path(__file__).resolve().parents[3]
sys.path.append(str(ROOT / "siyuan-rag-llm-main"))
from utils.rag.rag_knowledge_base import HybridRAGKnowledgeBase # type: ignore # noqa: E402
logger = logging.getLogger(__name__)
class RagService:
"""包装 HybridRAGKnowledgeBase,供路由调用"""
"""RAG 网关:直接调用 LightRAG 独立服务。
说明:历史版本依赖 `siyuan-rag-llm-main`(回档后目录缺失),导致服务无法启动。
当前实现改为通过 HTTP 调用 LightRAG 的官方 API/query、/query/data 等)。
"""
def __init__(self) -> None:
settings = get_gateway_settings()
self.kb = HybridRAGKnowledgeBase(
lightrag_url=settings.lightrag_url,
supabase_rest_url=settings.supabase_rest_url,
supabase_service_key=settings.supabase_key,
embedding_base_url=settings.embedding_base_url,
embedding_model=settings.embedding_model,
)
self.base_url = settings.lightrag_url.rstrip("/")
self.api_key = settings.lightrag_api_key
def _headers(self) -> dict:
headers: dict = {}
if self.api_key:
headers["X-API-Key"] = self.api_key
return headers
async def query(self, query: str, top_k: int = 8) -> Dict[str, Any]:
return await self.kb.query(query=query, top_k=top_k)
"""调用 LightRAG /query,返回生成回答与引用。"""
payload = {"query": query, "top_k": top_k}
async with httpx.AsyncClient(base_url=self.base_url, timeout=60.0, headers=self._headers()) as client:
resp = await client.post("/query", json=payload)
resp.raise_for_status()
data = resp.json()
if not isinstance(data, dict):
return {"response": str(data), "references": []}
return data
async def graph(self, query: str) -> Dict[str, Any]:
result = await self.kb.lightrag.graph(query=query)
await self.kb.sync_graph_metadata(result)
return result
async def graph(self, query: str, top_k: int = 60) -> Dict[str, Any]:
"""调用 LightRAG /query/data 获取结构化检索结果(实体/关系/分块/引用)。"""
payload = {"query": query, "top_k": top_k, "mode": "mix"}
async with httpx.AsyncClient(base_url=self.base_url, timeout=60.0, headers=self._headers()) as client:
resp = await client.post("/query/data", json=payload)
resp.raise_for_status()
data = resp.json()
return data if isinstance(data, dict) else {"status": "failure", "message": "invalid response", "data": data}
async def path(self, source: str, target: str) -> Dict[str, Any]:
return await self.kb.lightrag.path(source=source, target=target)
"""路径查询:当前 LightRAG API 未提供等价 /path 接口,先返回明确错误。"""
message = "当前 LightRAG API 未提供 /path 等价接口(rag_gateway:path 暂不可用)"
logger.warning("%s: source=%s target=%s", message, source, target)
return {"status": "not_supported", "message": message, "source": source, "target": target}