import requests import json from config import Config def create_plan(goal: str): """ Robust AI planner: - safe LLM call - strict JSON parsing - fallback protection """ prompt = f""" You are a planning agent. Break the goal into executable steps. GOAL: {goal} RULES: - Output ONLY valid JSON - NO explanation - NO markdown - NO extra text - steps must be simple actionable instructions FORMAT: {{ "steps": [ "step 1", "step 2", "step 3" ] }} """ try: # ========================= # CALL LLM # ========================= res = requests.post( Config.LLM_API_URL, headers={ "Authorization": f"Bearer {Config.LLM_API_KEY}", "Content-Type": "application/json" }, json={ "model": Config.MODEL, "messages": [ {"role": "user", "content": prompt} ], "temperature": 0.2 }, timeout=30 ) # ========================= # HTTP CHECK # ========================= if res.status_code != 200: return {"steps": [goal]} # ========================= # JSON PARSE SAFE # ========================= try: data = res.json() except Exception: return {"steps": [goal]} if not isinstance(data, dict): return {"steps": [goal]} # ========================= # EXTRACT CONTENT # ========================= choices = data.get("choices") if not choices or not isinstance(choices, list): return {"steps": [goal]} message = choices[0].get("message", {}) content = message.get("content", "") if not content: return {"steps": [goal]} # ========================= # PARSE PLAN JSON # ========================= try: parsed = json.loads(content) if ( isinstance(parsed, dict) and "steps" in parsed and isinstance(parsed["steps"], list) and len(parsed["steps"]) > 0 ): return parsed except Exception: pass # ========================= # FALLBACK (SAFE) # ========================= return {"steps": [goal]} except Exception: # HARD FAIL SAFE return {"steps": [goal]}