Files
ai-video-fullstack/backend/routes/openai_models.py
T

93 lines
2.8 KiB
Python
Raw Normal View History

2026-09-07 14:25:48 +08:00
"""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,
)