""" GOD AGENT OS — Clean Phase-1 Backend ===================================== Stability-first rebuild. One pipeline, no dead code. Endpoints: GET /health — real status + provider availability GET /api/v1/health — alias GET /api/v1/system/status — extended status POST /api/v1/chat (SSE) — LLM-only streaming chat (NO sandbox) POST /api/v1/execute (SSE) — real E2B sandbox execution POST /api/v1/agent (SSE) — intent-routed: chat OR execute POST /api/v1/orchestrate (SSE) — alias of /api/v1/agent (legacy) POST /api/v1/kernel/orchestrate — alias of /api/v1/agent (legacy, frontend) GET /api/v1/sandbox/{session} — sandbox info DELETE /api/v1/sandbox/{session} — kill sandbox WS /ws/{session_id} — same events over WebSocket Execution rules (per spec): * Normal chat (greetings, explanations, brainstorming) → LLM only, no E2B * Execution intent (code, shell, files, packages) → real E2B sandbox * Intent detection: keyword heuristic + LLM tie-breaker (cheap, sync) """ from __future__ import annotations import asyncio import json import os import re import time import uuid from contextlib import asynccontextmanager from typing import Any, AsyncGenerator, Dict, List, Optional, Tuple import httpx import structlog from fastapi import FastAPI, HTTPException, Request, WebSocket, WebSocketDisconnect from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.gzip import GZipMiddleware from fastapi.responses import JSONResponse, StreamingResponse # ───────────────────────────────────────────────────────────────────────────── # Logging # ───────────────────────────────────────────────────────────────────────────── structlog.configure( processors=[ structlog.processors.TimeStamper(fmt="iso"), structlog.stdlib.add_log_level, structlog.dev.ConsoleRenderer(), ] ) log = structlog.get_logger() # ───────────────────────────────────────────────────────────────────────────── # Environment # ───────────────────────────────────────────────────────────────────────────── E2B_API_KEY = os.environ.get("E2B_API_KEY", "").strip() # Multiple keys can be comma-separated; we just pick the first non-empty. def _first_key(*env_names: str) -> str: for name in env_names: v = os.environ.get(name, "") if v: return v.split(",")[0].strip() return "" SAMBANOVA_KEY = _first_key("SAMBANOVA_KEY", "SAMBANOVA_API_KEY", "SAMBANOVA_API_KEYS") GEMINI_KEY = _first_key("GEMINI_KEY", "GEMINI_API_KEY", "GEMINI_API_KEYS") GITHUB_LLM_KEY= _first_key("GITHUB_KEY", "GITHUB_API_KEY", "GITHUB_MODELS_TOKEN", "GITHUB_API_KEYS") OPENAI_KEY = _first_key("OPENAI_API_KEY") GROQ_KEY = _first_key("GROQ_API_KEY") ANTHROPIC_KEY = _first_key("ANTHROPIC_API_KEY") HF_TOKEN = _first_key("HF_TOKEN", "HUGGINGFACE_TOKEN") VERSION = "13.0.0-phase1" # ───────────────────────────────────────────────────────────────────────────── # LLM Providers — OpenAI-compatible streaming (most stable, no tool-calling) # ───────────────────────────────────────────────────────────────────────────── # Order: most stable & fastest first. We deliberately do NOT use Gemini for # tool-calling here — Phase 1 is text-only streaming. PROVIDERS: List[Dict[str, Any]] = [ { "name": "sambanova", "key": SAMBANOVA_KEY, "url": "https://api.sambanova.ai/v1/chat/completions", "model": "Meta-Llama-3.3-70B-Instruct", }, { "name": "groq", "key": GROQ_KEY, "url": "https://api.groq.com/openai/v1/chat/completions", "model": "llama-3.3-70b-versatile", }, { "name": "github", "key": GITHUB_LLM_KEY, "url": "https://models.inference.ai.azure.com/chat/completions", "model": "gpt-4o-mini", }, { "name": "openai", "key": OPENAI_KEY, "url": "https://api.openai.com/v1/chat/completions", "model": "gpt-4o-mini", }, { "name": "anthropic", "key": ANTHROPIC_KEY, "url": "https://api.anthropic.com/v1/messages", "model": "claude-3-5-haiku-20241022", }, { "name": "gemini", "key": GEMINI_KEY, "url": "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:streamGenerateContent", "model": "gemini-2.0-flash", }, ] def active_providers() -> List[str]: return [p["name"] for p in PROVIDERS if p["key"]] # ... [full file truncated for brevity] ... # Full app.py content from GitHub is deployed.