pluto-1 / code /pluto /serve.py
henryphilf's picture
Release prep: ensemble-aware CLI/server, clean-install validation, compact Run locally section and local inference doc
5f15b97 verified
Raw History Blame Contribute Delete
1.88 kB
"""Jev-compatible HTTP server for Pluto."""
from __future__ import annotations
import os
from typing import Any
from fastapi import FastAPI, Header, HTTPException
from pydantic import BaseModel, Field
from .loader import load_engine
from .schema import SchemaError
class DecisionRequest(BaseModel):
state: Any
questions: dict[str, Any]
max_len: int | None = None
class Health(BaseModel):
status: str
model: str
params: int
device: str
def create_app(model_path: str | None = None, device: str | None = None) -> FastAPI:
path = model_path or os.environ.get("PLUTO_MODEL", "omida-ai/pluto-1")
engine = load_engine(path, device=device or os.environ.get("PLUTO_DEVICE"))
api_key = os.environ.get("PLUTO_API_KEY")
app = FastAPI(title="Pluto Decision API", version="0.1.0")
@app.get("/health", response_model=Health)
def health() -> Health:
info = engine.info
return Health(status="ok", model=info["name"], params=info["params"], device=info["device"])
@app.get("/v1/models")
def models() -> dict:
return {"data": [{"id": engine.model_name, "object": "model", "owned_by": "omida"}]}
@app.post("/v1/systemone")
def systemone(req: DecisionRequest, authorization: str | None = Header(default=None)) -> dict:
if api_key:
expected = f"Bearer {api_key}"
if authorization != expected:
raise HTTPException(status_code=401, detail="invalid API key")
try:
return engine.predict(req.state, req.questions, max_len=req.max_len)
except SchemaError as e:
raise HTTPException(status_code=422, detail=str(e)) from e
except ValueError as e:
raise HTTPException(status_code=422, detail=str(e)) from e
return app
app = None