#!/usr/bin/env python3 """ Egregore Brain Service - AI reasoning API Provides HTTP API for conversation processing with Claude. Runs on port 8081. """ import os from typing import Optional from fastapi import FastAPI, HTTPException from pydantic import BaseModel from dotenv import load_dotenv import anthropic from tools import TOOLS, execute_tool from prompts import get_system_prompt from conversation import process_conversation # Load environment load_dotenv("/home/admin/.env") ANTHROPIC_API_KEY = os.getenv("ANTHROPIC_API_KEY") if not ANTHROPIC_API_KEY: raise ValueError("ANTHROPIC_API_KEY not set") app = FastAPI(title="Egregore Brain Service", docs_url="/docs") # Initialize Anthropic client client = anthropic.AsyncAnthropic(api_key=ANTHROPIC_API_KEY) # Request models class ProcessRequest(BaseModel): model: str = "claude-sonnet-4-20250514" history: list # Conversation history in Claude API format max_iterations: int = 10 class ToolRequest(BaseModel): name: str input: dict # Endpoints @app.post("/process") async def api_process(req: ProcessRequest): """Process a conversation with tool use loop""" try: response_blocks = await process_conversation( client=client, model=req.model, history=req.history, max_iterations=req.max_iterations ) return {"blocks": response_blocks} except anthropic.APIError as e: raise HTTPException(status_code=500, detail=str(e)) @app.post("/tool") async def api_execute_tool(req: ToolRequest): """Execute a single tool directly""" result = await execute_tool(req.name, req.input) return {"result": result} @app.get("/tools") async def api_get_tools(): """Get available tool definitions""" return {"tools": TOOLS} @app.get("/prompt") async def api_get_prompt(): """Get current system prompt with context""" prompt = await get_system_prompt() return {"prompt": prompt} @app.get("/health") async def health(): """Health check endpoint""" return {"status": "ok", "service": "brain"} if __name__ == "__main__": import uvicorn uvicorn.run(app, host="127.0.0.1", port=8081)