import requests import json from config import Config from planner import create_plan from executor import Executor from tools_runtime import execute_tool_call # ===================================================== # 🔥 UNIVERSAL LLM ROUTER (INSIDE agent.py) # ===================================================== class LLMRouter: def __init__(self): self.providers = [ { "url": Config.LLM_API_URL, "key": Config.LLM_API_KEY, "model": Config.MODEL } ] def call(self, messages): last_error = None for p in self.providers: try: res = requests.post( p["url"], headers={ "Authorization": f"Bearer {p['key']}", "Content-Type": "application/json" }, json={ "model": p["model"], "messages": messages, "temperature": 0.2 }, timeout=30 ) data = res.json() # ========================= # NORMALIZER (IMPORTANT FIX) # ========================= if isinstance(data, list): data = data[0] if data else {} if isinstance(data, dict) and "result" in data: data = data["result"] # ========================= # VALIDATION # ========================= if isinstance(data, dict) and "choices" in data: return data except Exception as e: last_error = str(e) continue return { "choices": [{ "message": { "content": "LLM_ERROR" } }], "error": last_error } # ===================================================== # AGENT # ===================================================== class Agent: def __init__(self): self.llm = LLMRouter().call self.executor = Executor(llm=self.llm) self.history = [] # ===================================================== # GOAL MODE # ===================================================== def run_goal(self, goal: str): try: plan = create_plan(goal) if not isinstance(plan, dict): return {"mode": "error", "error": "invalid_plan"} except Exception as e: return { "mode": "error", "error": f"plan_failed: {str(e)}" } try: results = self.executor.run_plan(plan) except Exception as e: results = {"error": str(e)} return { "mode": "goal_execution", "goal": goal, "plan": plan, "results": results } # ===================================================== # CHAT / TOOL MODE # ===================================================== def run(self, user_input): messages = [ { "role": "system", "content": Config.SYSTEM_PROMPT }, { "role": "user", "content": user_input } ] response = self.llm(messages) # ========================= # SAFE EXTRACTION # ========================= try: content = ( response.get("choices", [{}])[0] .get("message", {}) .get("content", "") ) except Exception: content = "" if not content: return { "mode": "error", "response": "empty_llm_response" } # ========================= # TOOL MODE # ========================= try: tool = json.loads(content) if isinstance(tool, dict) and "tool" in tool: result = execute_tool_call(tool) self.history.append({ "input": user_input, "tool_call": tool, "result": result }) return { "mode": "tool_execution", "result": result } except Exception: pass # ========================= # NORMAL MODE # ========================= return { "mode": "normal_response", "response": content } # ===================================================== # DEBUG # ===================================================== if __name__ == "__main__": agent = Agent() print(agent.run("List files in current directory")) print(agent.run_goal("Create a simple python web server"))