"""OpenAI-compatible HTTP API for Sénia. Open WebUI (and other OpenAI-API clients) talks to this endpoint set. We accept the standard `/v1/chat/completions` shape, translate to internal types, hand off to the orchestrator, and translate the response back to OpenAI shape. """ from fastapi import FastAPI, HTTPException from pydantic import BaseModel, ConfigDict from .loop import handle_turn from .models import Message app = FastAPI(title="Sénia") class ChatMessage(BaseModel): role: str content: str class ChatCompletionRequest(BaseModel): model_config = ConfigDict(extra="allow") model: str messages: list[ChatMessage] @app.get("/v1/models") def list_models(): return { "object": "list", "data": [{"id": "senia", "object": "model", "owned_by": "local"}], } @app.post("/v1/chat/completions") def chat_completions(req: ChatCompletionRequest): try: response_text = handle_turn( messages=[Message(role=m.role, content=m.content) for m in req.messages], ) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) return { "id": "chat-1", "object": "chat.completion", "model": req.model, "choices": [ { "index": 0, "message": {"role": "assistant", "content": response_text}, "finish_reason": "stop", } ], }