"""Model discovery for assistants exposed through the public API.""" from __future__ import annotations from db.models import Assistant from db.session import SessionLocal from fastapi import APIRouter, Depends, Request from services.openai_api import ( PUBLIC_API_BEARER, PUBLIC_ERROR_RESPONSES, REQUEST_ID_RESPONSE_HEADERS, openai_error_response, ) from services.openai_realtime.auth import ( RealtimeAuthError, authenticate_bearer, bearer_from_authorization, ) from services.openai_responses.schemas import ModelList from sqlalchemy import select PUBLIC_ASSISTANT_TYPES = {"prompt", "workflow", "dify", "fastgpt"} router = APIRouter( prefix="/v1/models", tags=["openai-models"], dependencies=[Depends(PUBLIC_API_BEARER)], ) async def _authenticate(request: Request) -> None: token = bearer_from_authorization(request.headers.get("authorization")) async with SessionLocal() as db: credential = await authenticate_bearer(db, token) if credential.ephemeral: raise RealtimeAuthError("A long-lived API key is required") def _capabilities(assistant: Assistant) -> list[str]: capabilities = ["realtime"] if assistant.runtime_mode == "pipeline": capabilities.insert(0, "responses") return capabilities @router.get( "", response_model=ModelList, responses={ 200: {"headers": REQUEST_ID_RESPONSE_HEADERS}, **PUBLIC_ERROR_RESPONSES, }, summary="List assistants available through the public API", ) async def list_models(request: Request): try: await _authenticate(request) async with SessionLocal() as db: assistants = ( await db.execute( select(Assistant) .where( Assistant.type.in_(PUBLIC_ASSISTANT_TYPES), Assistant.runtime_mode.in_(("pipeline", "realtime")), ) .order_by(Assistant.created_at.asc(), Assistant.id.asc()) ) ).scalars().all() return { "object": "list", "data": [ { "id": f"assistant:{assistant.id}", "object": "model", "created": int(assistant.created_at.timestamp()), "owned_by": "interactive-media", "name": assistant.name, "capabilities": _capabilities(assistant), "assistant_id": assistant.id, "assistant_type": assistant.type, "runtime_mode": assistant.runtime_mode, } for assistant in assistants ], } except RealtimeAuthError as exc: return openai_error_response( str(exc), code="invalid_api_key", status_code=401, )