Merge dev into sync-main-to-dev

Resolved version conflict - keeping dev version 1.3.0
This commit is contained in:
LearningCircuit
2025-12-03 10:59:06 +01:00
385 changed files with 61619 additions and 8208 deletions

View File

@@ -1,102 +0,0 @@
#!/usr/bin/env python3
"""Check if metrics are being saved in the database."""
import sys
from pathlib import Path
# Add parent directory to path
sys.path.insert(0, str(Path(__file__).parent.parent))
from src.local_deep_research.database.encrypted_db import db_manager
from src.local_deep_research.database.models import TokenUsage, SearchCall
def check_user_metrics(username: str, password: str):
"""Check metrics for a specific user."""
print(f"\n🔍 Checking metrics for user: {username}")
print("=" * 60)
try:
# Open database
if not db_manager.open_user_database(username, password):
print("❌ Failed to open database")
return
# Get session
session = db_manager.get_session(username)
if not session:
print("❌ Failed to get session")
return
# Check token usage
token_count = session.query(TokenUsage).count()
print(f"\n📊 Token Usage Records: {token_count}")
if token_count > 0:
# Get recent token usage
recent_tokens = (
session.query(TokenUsage)
.order_by(TokenUsage.created_at.desc())
.limit(5)
.all()
)
print("\n Recent token usage:")
for token in recent_tokens:
print(
f" - {token.created_at}: {token.model_name} - {token.total_tokens} tokens"
)
print(
f" Phase: {token.research_phase}, Status: {token.success_status}"
)
# Check search calls
search_count = session.query(SearchCall).count()
print(f"\n🔎 Search Call Records: {search_count}")
if search_count > 0:
# Get recent searches
recent_searches = (
session.query(SearchCall)
.order_by(SearchCall.created_at.desc())
.limit(5)
.all()
)
print("\n Recent searches:")
for search in recent_searches:
print(
f" - {search.created_at}: {search.search_engine} - {search.query[:50]}..."
)
print(f" Results: {search.results_returned}")
session.close()
except Exception as e:
print(f"❌ Error: {e}")
import traceback
traceback.print_exc()
finally:
if username in db_manager.connections:
db_manager.connections.pop(username)
def main():
"""Check metrics for test users."""
# Check for a specific test user (modify as needed)
test_users = [
("simple_1751323627595", "password"), # Latest test user
# Add more test users as needed
]
for username, password in test_users:
try:
check_user_metrics(username, password)
except Exception as e:
print(f"Failed to check {username}: {e}")
print("\n" + "=" * 60)
print("✅ Metrics check complete")
if __name__ == "__main__":
main()

View File

@@ -1,342 +0,0 @@
import os
import signal
import subprocess
import sys
import time
from pathlib import Path
import psutil
def kill_flask_servers():
"""
Kill all Python processes running main.py (Flask servers)
Uses psutil to find and kill processes more reliably than just using command line
"""
killed_pids = []
for proc in psutil.process_iter(["pid", "name", "cmdline"]):
try:
cmdline = proc.info["cmdline"]
if (
cmdline
and "python" in proc.info["name"].lower()
and any(
"local_deep_research.web.app" in arg
for arg in cmdline
if arg
)
):
pid = proc.info["pid"]
print(f"Found Flask server process {pid}, killing...")
# Windows requires SIGTERM
os.kill(pid, signal.SIGTERM)
killed_pids.append(pid)
except (
psutil.NoSuchProcess,
psutil.AccessDenied,
psutil.ZombieProcess,
):
pass
if killed_pids:
print(
f"Killed Flask server processes with PIDs: {', '.join(map(str, killed_pids))}"
)
else:
print("No Flask server processes found.")
# Give processes time to die
time.sleep(1)
# Verify all are dead
for pid in killed_pids:
if psutil.pid_exists(pid):
print(f"Warning: Process {pid} still exists after kill signal.")
else:
print(f"Confirmed process {pid} was terminated.")
return killed_pids
def check_flask_servers():
"""Check if any Flask servers are running and return their PIDs."""
running_servers = []
for proc in psutil.process_iter(["pid", "name", "cmdline"]):
try:
cmdline = proc.info["cmdline"]
if (
cmdline
and "python" in proc.info["name"].lower()
and any(
"local_deep_research.web.app" in arg
for arg in cmdline
if arg
)
):
pid = proc.info["pid"]
running_servers.append(pid)
except (
psutil.NoSuchProcess,
psutil.AccessDenied,
psutil.ZombieProcess,
):
pass
return running_servers
def start_flask_server(port=5000):
"""Start a Flask server in the background."""
print(f"Starting Flask server on port {port}...")
# Get the virtual environment Python executable
# Try multiple common venv locations
venv_paths = [
Path("venv_dev") / "bin" / "python", # Linux/Mac
Path("venv") / "bin" / "python", # Linux/Mac
Path(".venv") / "Scripts" / "python.exe", # Windows
Path("venv_dev") / "Scripts" / "python.exe", # Windows
Path("venv") / "Scripts" / "python.exe", # Windows
]
venv_path = None
for path in venv_paths:
if path.exists():
venv_path = str(path)
break
if not venv_path:
print(
"Error: Could not find Python executable in any common venv location"
)
return None
try:
# First, check if port is already in use
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = sock.connect_ex(("127.0.0.1", port))
sock.close()
if result == 0:
print(f"Error: Port {port} is already in use")
return None
# Start the Flask server directly without background flags
# to better catch any startup errors
process = subprocess.Popen(
[
venv_path,
"-m",
"local_deep_research.web.app",
"--port",
str(port),
],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True, # Use text mode for easier output reading
)
# Wait a moment to ensure the server has time to start
time.sleep(3)
# Check if the process is still running
if process.poll() is None:
print(f"Flask server started on port {port} with PID {process.pid}")
# Try to read initial output to see if there are errors
stdout_data, stderr_data = "", ""
try:
# Read with timeout to avoid blocking
import select
if os.name == "nt": # Windows
# Windows doesn't support select on pipes, use non-blocking mode
import msvcrt
if (
process.stdout
and msvcrt.get_osfhandle(process.stdout.fileno()) != -1
):
stdout_data = process.stdout.read(1024) or ""
if (
process.stderr
and msvcrt.get_osfhandle(process.stderr.fileno()) != -1
):
stderr_data = process.stderr.read(1024) or ""
else: # Unix
if (
process.stdout
and select.select([process.stdout], [], [], 0.5)[0]
):
stdout_data = process.stdout.read(1024) or ""
if (
process.stderr
and select.select([process.stderr], [], [], 0.5)[0]
):
stderr_data = process.stderr.read(1024) or ""
except Exception as e:
print(f"Warning: Could not read process output: {e}")
# Log any output for debugging
if stdout_data:
print(f"Server stdout: {stdout_data.strip()}")
if stderr_data:
print(f"Server stderr: {stderr_data.strip()}")
# Test if the server is actually responding
try:
import urllib.request
with urllib.request.urlopen(
f"http://localhost:{port}/", timeout=2
) as response:
if response.status == 200:
print(
f"Server is responsive at http://localhost:{port}/"
)
else:
print(
f"Warning: Server responded with status {response.status}"
)
except Exception as e:
print(f"Warning: Could not connect to server: {e}")
print(
"The process is running but the server may not be responding to requests"
)
return process.pid
else:
stdout, stderr = process.communicate()
print(
f"Error starting Flask server. Server process exited with code {process.returncode}"
)
if stdout:
print(f"Server stdout: {stdout.strip()}")
if stderr:
print(f"Server stderr: {stderr.strip()}")
return None
except Exception as e:
print(f"Error starting Flask server: {e!s}")
return None
def start_flask_server_windows(port=5000):
"""Start a Flask server using Windows 'start' command which is more reliable for Windows environments."""
print(
f"Starting Flask server on port {port} using Windows 'start' command..."
)
# Get the virtual environment Python executable
# Try multiple common venv locations
venv_paths = [
Path("venv_dev") / "Scripts" / "python.exe", # Windows
Path("venv") / "Scripts" / "python.exe", # Windows
Path(".venv") / "Scripts" / "python.exe", # Windows
]
venv_path = None
for path in venv_paths:
if path.exists():
venv_path = str(path)
break
if not venv_path:
print(
"Error: Could not find Python executable in any common venv location"
)
return None
try:
# Use Windows 'start' command to launch in a new window
# This is more reliable on Windows for Flask apps
cmd = f'start "Flask Server" /MIN "{venv_path}" -m local_deep_research.web.app --port {port}'
subprocess.run(cmd, shell=True, check=True)
print(f"Flask server starting on port {port}")
print(
"Note: The process is running in a minimized window. Close that window to stop the server."
)
# Wait a moment to ensure the server has time to start
time.sleep(3)
# We can't get the PID easily with this method, but return True to indicate success
return True
except Exception as e:
print(f"Error starting Flask server: {e!s}")
return None
def restart_server(port=5000):
"""Kill all Flask servers and start a new one."""
kill_flask_servers()
print("All Flask server processes terminated.")
pid = start_flask_server(port)
if pid:
print(f"New Flask server started on port {port} with PID {pid}")
return True
else:
print("Failed to start new Flask server")
return False
def show_status():
"""Show status of running Flask servers."""
running_servers = check_flask_servers()
if running_servers:
print(f"Found {len(running_servers)} running Flask server(s):")
for pid in running_servers:
try:
proc = psutil.Process(pid)
cmdline = proc.cmdline()
port = None
# Try to extract the port number
for i, arg in enumerate(cmdline):
if arg == "--port" and i + 1 < len(cmdline):
port = cmdline[i + 1]
if port:
print(f" - PID {pid}: Running on port {port}")
else:
print(f" - PID {pid}: Running (port unknown)")
except (psutil.NoSuchProcess, psutil.AccessDenied):
print(f" - PID {pid}: [Process information unavailable]")
else:
print("No Flask servers currently running.")
return len(running_servers) > 0
if __name__ == "__main__":
if len(sys.argv) > 1:
if sys.argv[1] == "restart":
kill_flask_servers()
print("All Flask server processes terminated.")
if os.name == "nt": # Windows
start_flask_server_windows()
else:
start_flask_server()
elif sys.argv[1] == "start":
if os.name == "nt": # Windows
start_flask_server_windows()
else:
start_flask_server()
elif sys.argv[1] == "status":
show_status()
else:
print(
"Unknown command. Usage: python kill_servers.py [restart|start|status]"
)
else:
kill_flask_servers()