aboutsummaryrefslogtreecommitdiff
path: root/agent/orchestrator/api.py
diff options
context:
space:
mode:
Diffstat (limited to 'agent/orchestrator/api.py')
-rw-r--r--agent/orchestrator/api.py56
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",
+ }
+ ],
+ }