chore: init monorepo snapshot

This commit is contained in:
liaibo
2025-11-23 10:55:04 +08:00
commit c70ff52869
941 changed files with 246586 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
# 空文件用于标记包
+1
View File
@@ -0,0 +1 @@
# API 模块包声明
+46
View File
@@ -0,0 +1,46 @@
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel, Field
from app.services.rag_service import RagService
router = APIRouter()
rag_service = RagService()
class QueryRequest(BaseModel):
query: str = Field(..., description="用户查询")
top_k: int = Field(8, description="返回条数")
class PathRequest(BaseModel):
source: str
target: str
@router.post("/query")
async def query(payload: QueryRequest):
"""优先调用 LightRAG,失败自动降级 Supabase"""
result = await rag_service.query(payload.query, payload.top_k)
return {"data": result}
@router.post("/graph")
async def graph(payload: QueryRequest):
result = await rag_service.graph(payload.query)
return {"data": result}
@router.post("/path")
async def path(payload: PathRequest):
result = await rag_service.path(payload.source, payload.target)
return {"data": result}
@router.get("/health/full")
async def health() -> dict:
"""最小化健康检查,后续补充依赖自检"""
try:
_ = await rag_service.query("ping", top_k=1)
return {"status": "ok"}
except Exception as exc: # noqa: BLE001
raise HTTPException(status_code=500, detail=str(exc))
@@ -0,0 +1 @@
# 配置与日志模块包声明
+22
View File
@@ -0,0 +1,22 @@
from functools import lru_cache
from pydantic import BaseSettings, Field
class Settings(BaseSettings):
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")
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:
return Settings()
+27
View File
@@ -0,0 +1,27 @@
import json
import logging
import sys
from typing import Any, Dict
class JsonFormatter(logging.Formatter):
"""统一 JSON 日志,方便跨服务链路排查"""
def format(self, record: logging.LogRecord) -> str: # type: ignore[override]
log: Dict[str, Any] = {
"ts": self.formatTime(record, datefmt="%Y-%m-%dT%H:%M:%S%z"),
"level": record.levelname,
"logger": record.name,
"message": record.getMessage(),
}
if record.exc_info:
log["exc_info"] = self.formatException(record.exc_info)
for key, value in getattr(record, "extra", {}).items():
log[key] = value
return json.dumps(log, ensure_ascii=False)
def setup_logging(level: str = "INFO") -> None:
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(JsonFormatter())
logging.basicConfig(handlers=[handler], level=level, force=True)
+12
View File
@@ -0,0 +1,12 @@
from fastapi import FastAPI
from app.api.routes import router as api_router
from app.core.config import get_gateway_settings
from app.core.logging import setup_logging
settings = get_gateway_settings()
setup_logging()
app = FastAPI(title=settings.app_name)
app.include_router(api_router, prefix=settings.api_prefix)
@@ -0,0 +1 @@
# 服务层包声明
@@ -0,0 +1,37 @@
import logging
import sys
from pathlib import Path
from typing import Any, Dict
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,供路由调用"""
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,
)
async def query(self, query: str, top_k: int = 8) -> Dict[str, Any]:
return await self.kb.query(query=query, top_k=top_k)
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 path(self, source: str, target: str) -> Dict[str, Any]:
return await self.kb.lightrag.path(source=source, target=target)