jatin gyass
update for the new web data source
4db2d34
Raw
History Blame Contribute Delete
6.86 kB
"""Quick smoke test for the multi-agent system.
Checks:
1. GOOGLE_API_KEY is set and reachable
2. Core imports work (state, tools, orchestrator)
3. WorkflowState initialisation is correct
4. Routing logic behaves as expected
Run:
.venv/Scripts/python test.py
"""
from __future__ import annotations
import asyncio
import os
import sys
try:
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
except Exception:
pass
from dotenv import load_dotenv
load_dotenv()
SEP = "=" * 60
def check_env() -> bool:
key = os.getenv("GOOGLE_API_KEY", "")
print(SEP)
print("GOOGLE_API_KEY set :", bool(key), f"(...{key[-4:]})" if key else "")
print("PLANNER_MODEL :", os.getenv("PLANNER_MODEL", "gemini-2.5-flash"))
print("DATABASE_URL :", os.getenv("DATABASE_URL", "(not set)"))
print("REDIS_URL :", os.getenv("REDIS_URL", "(not set)"))
print(SEP)
if not key:
print("[X] No GOOGLE_API_KEY found β€” set it in .env")
return False
return True
async def check_gemini(key: str) -> bool:
import httpx
model = os.getenv("PLANNER_MODEL", "gemini-2.5-flash")
url = (
f"https://generativelanguage.googleapis.com/v1beta/models/"
f"{model}:generateContent?key={key}"
)
body = {"contents": [{"parts": [{"text": "Reply with exactly: API key works"}]}]}
async with httpx.AsyncClient(timeout=15) as c:
r = await c.post(url, json=body)
print(f"\n[1] Gemini live call -> HTTP {r.status_code}")
if r.status_code >= 300:
print(" error:", r.text[:400])
print("\n[X] Common causes:")
print(" 400 API_KEY_INVALID -> wrong/expired key")
print(" 403 PERMISSION_DENIED -> 'Generative Language API' not enabled,")
print(" OR Google project access denied β€”")
print(" create a new key at https://aistudio.google.com/apikey")
print(" 404 model not found -> check PLANNER_MODEL in .env")
print(" 429 -> rate/quota limit, try again shortly")
return False
try:
reply = r.json()["candidates"][0]["content"]["parts"][0]["text"].strip()
except Exception:
reply = r.text[:200]
print(" model reply:", reply)
print("[OK] Gemini API key is working.\n")
return True
def check_imports() -> bool:
print("[2] Checking imports ...")
try:
from backend.state.graph_state import ( # noqa: F401
WorkflowState, TaskStatus, StepStatus, AgentRole,
create_initial_state, make_plan_step, make_agent_event,
)
from backend.agents.orchestrator import ( # noqa: F401
build_workflow, route_after_executor,
route_after_critic, route_after_planner,
)
print(" backend.state OK")
print(" backend.orchestrator OK")
except ImportError as e:
print(f" [X] Import failed: {e}")
return False
try:
from backend.tools.registry import execute_tool, calculate # noqa: F401
print(" backend.tools OK")
except ImportError as e:
print(f" [X] tools import failed: {e}")
return False
print("[OK] All imports succeeded.\n")
return True
def check_state() -> bool:
print("[3] WorkflowState smoke test ...")
from backend.state.graph_state import (
create_initial_state, TaskStatus, make_plan_step, StepStatus,
)
state = create_initial_state("Write a hello-world script")
assert state["task"] == "Write a hello-world script"
assert state["status"] == TaskStatus.PENDING
assert state["plan"] == []
assert state["iteration"] == 0
assert state["total_tokens"] == 0
assert len(state["events"]) == 1
step = make_plan_step("s1", "Write code", "Create hello.py", tool="run_python")
assert step["status"] == StepStatus.PENDING
assert step["attempts"] == 0
print(" initial state OK")
print(" make_plan_step OK")
print("[OK] State checks passed.\n")
return True
def check_routing() -> bool:
print("[4] Routing logic smoke test ...")
from backend.state.graph_state import create_initial_state, TaskStatus, StepStatus
from backend.agents.orchestrator import (
route_after_executor, route_after_critic, route_after_planner,
)
def _state(status, plan=None, needs_replanning=False):
s = create_initial_state("test")
s["status"] = status
s["plan"] = plan or []
s["needs_replanning"] = needs_replanning
return s
# executor β†’ critic when REFLECTING
assert route_after_executor(_state(TaskStatus.REFLECTING)) == "critic"
# executor β†’ self when steps pending
assert route_after_executor(
_state(TaskStatus.EXECUTING, [{"step_id": "s1", "status": StepStatus.PENDING}])
) == "executor"
# executor β†’ end on FAILED
assert route_after_executor(_state(TaskStatus.FAILED)) == "end"
# critic β†’ planner on needs_replanning
assert route_after_critic(_state(TaskStatus.PLANNING, needs_replanning=True)) == "planner"
# critic β†’ memory_store when approved
assert route_after_critic(_state(TaskStatus.COMPLETED)) == "memory_store"
# planner β†’ end with empty plan
assert route_after_planner(_state(TaskStatus.EXECUTING, plan=[])) == "end"
# planner β†’ executor with valid plan
assert route_after_planner(
_state(TaskStatus.EXECUTING, [{"step_id": "s1", "status": StepStatus.PENDING}])
) == "executor"
print(" route_after_executor OK")
print(" route_after_critic OK")
print(" route_after_planner OK")
print("[OK] Routing checks passed.\n")
return True
async def main() -> None:
ok = check_env()
if not ok:
sys.exit(1)
key = os.getenv("GOOGLE_API_KEY", "")
gemini_ok = await check_gemini(key)
imports_ok = check_imports()
state_ok = check_state() if imports_ok else False
routing_ok = check_routing() if imports_ok else False
print(SEP)
print("Summary")
print(SEP)
print(" Gemini API :", "[OK]" if gemini_ok else "[FAIL]")
print(" Imports :", "[OK]" if imports_ok else "[FAIL]")
print(" State :", "[OK]" if state_ok else "[FAIL]")
print(" Routing :", "[OK]" if routing_ok else "[FAIL]")
print(SEP)
system_ok = imports_ok and state_ok and routing_ok
if system_ok and gemini_ok:
print("\nAll checks passed. The system is ready.")
elif system_ok:
print("\nSystem checks passed. Fix the Gemini API key to enable LLM calls.")
else:
print("\nSystem checks failed. See above for details.")
sys.exit(1)
if __name__ == "__main__":
asyncio.run(main())