diff options
Diffstat (limited to 'agent/orchestrator/api.py')
| -rw-r--r-- | agent/orchestrator/api.py | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/agent/orchestrator/api.py b/agent/orchestrator/api.py new file mode 100644 index 0000000..c3582d4 --- /dev/null +++ b/agent/orchestrator/api.py @@ -0,0 +1,56 @@ +"""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", + } + ], + } |
