131 lines
4.4 KiB
Python
Executable File
131 lines
4.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""Test P3: RAG semantico su file Gitea indicizzati."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import os
|
|
import sys
|
|
|
|
ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
|
if ROOT not in sys.path:
|
|
sys.path.insert(0, ROOT)
|
|
|
|
|
|
def _load_dotenv() -> None:
|
|
env_path = os.path.join(ROOT, ".env")
|
|
if not os.path.isfile(env_path):
|
|
return
|
|
with open(env_path, encoding="utf-8") as fh:
|
|
for line in fh:
|
|
line = line.strip()
|
|
if not line or line.startswith("#") or "=" not in line:
|
|
continue
|
|
key, _, value = line.partition("=")
|
|
key = key.strip()
|
|
if key and key not in os.environ:
|
|
os.environ[key] = value.strip().strip("'").strip('"')
|
|
|
|
|
|
def _configure_paths() -> str:
|
|
in_container = os.path.isfile("/.dockerenv") or (
|
|
os.path.isdir("/data") and os.access("/data", os.W_OK)
|
|
)
|
|
if in_container:
|
|
os.environ.setdefault("MCP_DB", "/data/loogle_mcp.db")
|
|
os.environ.setdefault("MCP_VECTOR_FALLBACK", "/data/vector_fallback.db")
|
|
return "container"
|
|
os.environ["MCP_DB"] = "/tmp/loogle_mcp_p3_test.db"
|
|
os.environ["MCP_VECTOR_FALLBACK"] = "/tmp/loogle_mcp_p3_vectors.db"
|
|
return "host"
|
|
|
|
|
|
def main() -> int:
|
|
_load_dotenv()
|
|
mode = _configure_paths()
|
|
print(f"mode={mode} db={os.environ['MCP_DB']} vector={os.environ['MCP_VECTOR_FALLBACK']}")
|
|
|
|
from app.db import get_conn, init_db
|
|
from app.knowledge import gitea_indexer
|
|
from app.mcp import tools
|
|
|
|
init_db()
|
|
if not get_conn().execute(
|
|
"SELECT 1 FROM sqlite_master WHERE name='indexed_gitea_files'"
|
|
).fetchone():
|
|
raise RuntimeError("tabella indexed_gitea_files assente")
|
|
|
|
if not os.environ.get("GITEA_API_TOKEN_DANIELE", "").strip():
|
|
print("SKIP: GITEA_API_TOKEN_DANIELE assente")
|
|
return 1
|
|
|
|
repo = "daniele/rete"
|
|
existing = gitea_indexer.list_indexed_files(limit=5, repo=repo)
|
|
stats = gitea_indexer.index_stats()
|
|
if len(existing) < 1 or stats.get("qdrant_points", 0) < 1:
|
|
index_result = gitea_indexer.index_repo(
|
|
repo,
|
|
username="daniele",
|
|
force=True,
|
|
max_files=1,
|
|
)
|
|
print("index", json.dumps(index_result, ensure_ascii=False))
|
|
else:
|
|
print("index_skip", "already", len(existing), "files")
|
|
|
|
files = gitea_indexer.list_indexed_files(limit=5, repo=repo)
|
|
if not files:
|
|
raise RuntimeError("indexed_gitea_files vuota")
|
|
print("indexed_sample", [f["path"] for f in files[:3]])
|
|
|
|
claims = {"sub": "daniele", "scope": "knowledge:read gitea:read admin", "admin": "admin"}
|
|
for query in ("failover tier-b", "runbook"):
|
|
hits = gitea_indexer.search_gitea_knowledge("daniele", query, limit=5, is_admin=True)
|
|
if not hits:
|
|
raise RuntimeError(f"search_gitea_knowledge senza risultati per: {query}")
|
|
top = hits[0]
|
|
print(
|
|
f"search_ok[{query}]",
|
|
top.get("path") or top.get("title"),
|
|
round(float(top.get("score", 0)), 3),
|
|
)
|
|
|
|
tool_out = tools.call_tool(
|
|
"search_gitea_knowledge",
|
|
{"query": "failover", "limit": 5},
|
|
claims,
|
|
)
|
|
if not json.loads(tool_out["content"][0]["text"]).get("results"):
|
|
raise RuntimeError("tool search_gitea_knowledge vuoto")
|
|
|
|
unified = tools.call_tool(
|
|
"search_knowledge",
|
|
{"query": "FAILOVER CENSIMENTO documenti servizi", "limit": 12},
|
|
claims,
|
|
)
|
|
unified_payload = json.loads(unified["content"][0]["text"])
|
|
results = unified_payload.get("results") or []
|
|
sources = set()
|
|
for r in results:
|
|
if r.get("repo"):
|
|
sources.add("gitea")
|
|
elif r.get("source"):
|
|
sources.add(r["source"])
|
|
else:
|
|
sources.add("paperless")
|
|
print("search_knowledge_sources", sorted(sources))
|
|
if "gitea" not in sources:
|
|
raise RuntimeError("search_knowledge non include risultati Gitea")
|
|
|
|
list_tool = tools.call_tool("list_gitea_indexed_files", {"repo": repo, "limit": 5}, claims)
|
|
if json.loads(list_tool["content"][0]["text"]).get("count", 0) <= 0:
|
|
raise RuntimeError("list_gitea_indexed_files vuoto")
|
|
|
|
print("OK P3: search + unified + list (reindex opzionale via tool reindex_gitea_repo)")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|