Add init_repo

This commit is contained in:
2025-11-05 00:16:42 +00:00
parent d7fb2d6938
commit e70341480b
+87 -13
View File
@@ -42,7 +42,7 @@ OLLAMA_BASE_URL = "http://127.0.0.1:11434"
os.environ["OLLAMA_HOST"] = OLLAMA_BASE_URL os.environ["OLLAMA_HOST"] = OLLAMA_BASE_URL
os.environ["OLLAMA_API_BASE"] = OLLAMA_BASE_URL os.environ["OLLAMA_API_BASE"] = OLLAMA_BASE_URL
CODEBASE_PATH = Path(os.environ.get("CODEBASE_PATH", "/home/popertots/Crussell")) # change as needed CODEBASE_PATH = Path(os.environ.get("CODEBASE_PATH", ".")) # change as needed
VECTOR_DB_PATH = Path(os.environ.get("VECTOR_DB_PATH", "./chroma_db")) VECTOR_DB_PATH = Path(os.environ.get("VECTOR_DB_PATH", "./chroma_db"))
BM25_INDEX_PATH = Path(os.environ.get("BM25_INDEX_PATH", "./bm25_index.json")) BM25_INDEX_PATH = Path(os.environ.get("BM25_INDEX_PATH", "./bm25_index.json"))
RAGIGNORE_PATH = CODEBASE_PATH / ".ragignore" RAGIGNORE_PATH = CODEBASE_PATH / ".ragignore"
@@ -2244,6 +2244,92 @@ Example read_file_lines_tool("src/auth/login.py", start=45, end=60) → full
Note: This tool treats / as '/home/popertots/Crussell/' so adjust paths accordingly""" Note: This tool treats / as '/home/popertots/Crussell/' so adjust paths accordingly"""
return EnhancedToon.file_content_results(read_file_lines(path, start, end), path) return EnhancedToon.file_content_results(read_file_lines(path, start, end), path)
@mcp.tool()
def init_repo(git_url: str) -> str:
"""What it does Initialise the RAG stack with a brandnew Git repository or update an existing one.
The function will:
1. Clone the repo if it does not already exist locally,
2. Pull the latest changes if it does,
3. Reset the global `CODEBASE_PATH` to the local clone,
4. Remove any stale index artefacts,
5. Rebuild the vector/BM25 indexes with the same lockprotected flow used by `rebuild_index`,
6. Return a humanreadable status message.
Next steps:
• Call `health_check` to confirm that the server is ready.
• Use `search_codebase` or `find_code_references` to explore the new code.
• Use `read_file_lines_tool` to inspect any hit in detail.
"""
import shutil
from pathlib import Path
import subprocess
# ----- 1. Determine where to clone ---------------------------------
repo_name = git_url.split('/')[-1]
if repo_name.endswith('.git'):
repo_name = repo_name[:-4]
clone_dir = Path.cwd() / repo_name
# ----- 2. Clone / pull -----------------------------------------------
try:
if clone_dir.exists():
# Existing repo → pull
subprocess.run(
["git", "-C", str(clone_dir), "pull"],
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
)
else:
# New repo → clone
subprocess.run(
["git", "clone", git_url],
cwd=str(Path.cwd()),
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
)
except subprocess.CalledProcessError as e:
return f"❌ Failed to clone/pull {git_url}: {e.stderr.strip()}"
# ----- 3. Update the global CODEBASE_PATH --------------------------------
global CODEBASE_PATH
CODEBASE_PATH = clone_dir
# ----- 4. Remove stale indices ----------------------------------------
for artefact in ("chroma_db", "bm25_index.json", "embeddings"):
artefact_path = CODEBASE_PATH / artefact
if artefact_path.exists():
try:
if artefact_path.is_dir():
shutil.rmtree(artefact_path)
else:
artefact_path.unlink()
except Exception as e:
logger.warning(f"Could not delete {artefact_path}: {e}")
# ----- 5. Rebuild the index (protected by the startup lock) ------------
try:
rebuild_index()
except Exception as e:
return f"❌ Index rebuild failed: {e}"
# ----- 6. Report success -----------------------------------------------
branch_name = subprocess.check_output(
["git", "-C", str(CODEBASE_PATH), "rev-parse", "--abbrev-ref", "HEAD"],
text=True,
).strip()
git_hash = subprocess.check_output(
["git", "-C", str(CODEBASE_PATH), "rev-parse", "HEAD"],
text=True,
).strip()
return f"✅ Initialized repository at {CODEBASE_PATH} on branch {branch_name} with hash {git_hash}"
@mcp.tool() @mcp.tool()
def rebuild_index() -> str: def rebuild_index() -> str:
"""What it does Recreates all embeddings, BM25, and metadata indexes after major code changes. """What it does Recreates all embeddings, BM25, and metadata indexes after major code changes.
@@ -2275,17 +2361,6 @@ Example rebuild_index() → '✅ Index rebuilt (13.2s); 11,234 chunks'"""
# ----------------------------- # -----------------------------
# Startup # Startup
# ----------------------------- # -----------------------------
def startup():
with _startup_lock:
if VECTOR_DB_PATH.exists() and BM25_INDEX_PATH.exists():
try:
load_indexes()
except Exception as e:
logger.warning(f"Failed loading indexes: {e}; rebuilding")
build_indexes()
else:
logger.info("No existing indexes found, building from scratch...")
build_indexes()
def signal_handler(sig, frame): def signal_handler(sig, frame):
"""Handle graceful shutdown on Ctrl+C.""" """Handle graceful shutdown on Ctrl+C."""
@@ -2316,7 +2391,6 @@ if __name__ == "__main__":
signal.signal(signal.SIGTERM, signal_handler) signal.signal(signal.SIGTERM, signal_handler)
try: try:
startup()
logger.info("="*60) logger.info("="*60)
logger.info("🚀 MCP RAG Server is ready!") logger.info("🚀 MCP RAG Server is ready!")
logger.info("Use 'python serve_http.py' for HTTP server") logger.info("Use 'python serve_http.py' for HTTP server")