feat(models): implement model routing and management pages with dynamic imports
This commit is contained in:
165
backend/app/api/model_registry.py
Normal file
165
backend/app/api/model_registry.py
Normal file
@@ -0,0 +1,165 @@
|
||||
"""API routes for gateway model registry and provider-auth management."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from uuid import UUID
|
||||
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
|
||||
from app.api.deps import require_org_admin
|
||||
from app.db.session import get_session
|
||||
from app.schemas.common import OkResponse
|
||||
from app.schemas.llm_models import (
|
||||
GatewayModelPullResult,
|
||||
GatewayModelSyncResult,
|
||||
LlmModelCreate,
|
||||
LlmModelRead,
|
||||
LlmModelUpdate,
|
||||
LlmProviderAuthCreate,
|
||||
LlmProviderAuthRead,
|
||||
LlmProviderAuthUpdate,
|
||||
)
|
||||
from app.services.openclaw.model_registry_service import GatewayModelRegistryService
|
||||
from app.services.organizations import OrganizationContext
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from sqlmodel.ext.asyncio.session import AsyncSession
|
||||
|
||||
router = APIRouter(prefix="/model-registry", tags=["model-registry"])
|
||||
|
||||
SESSION_DEP = Depends(get_session)
|
||||
ORG_ADMIN_DEP = Depends(require_org_admin)
|
||||
GATEWAY_ID_QUERY = Query(default=None)
|
||||
|
||||
|
||||
@router.get("/provider-auth", response_model=list[LlmProviderAuthRead])
|
||||
async def list_provider_auth(
|
||||
gateway_id: UUID | None = GATEWAY_ID_QUERY,
|
||||
session: AsyncSession = SESSION_DEP,
|
||||
ctx: OrganizationContext = ORG_ADMIN_DEP,
|
||||
) -> list[LlmProviderAuthRead]:
|
||||
"""List provider auth records for the active organization."""
|
||||
service = GatewayModelRegistryService(session)
|
||||
return await service.list_provider_auth(ctx=ctx, gateway_id=gateway_id)
|
||||
|
||||
|
||||
@router.post("/provider-auth", response_model=LlmProviderAuthRead)
|
||||
async def create_provider_auth(
|
||||
payload: LlmProviderAuthCreate,
|
||||
session: AsyncSession = SESSION_DEP,
|
||||
ctx: OrganizationContext = ORG_ADMIN_DEP,
|
||||
) -> LlmProviderAuthRead:
|
||||
"""Create a provider auth record and sync gateway config."""
|
||||
service = GatewayModelRegistryService(session)
|
||||
return await service.create_provider_auth(payload=payload, ctx=ctx)
|
||||
|
||||
|
||||
@router.patch("/provider-auth/{provider_auth_id}", response_model=LlmProviderAuthRead)
|
||||
async def update_provider_auth(
|
||||
provider_auth_id: UUID,
|
||||
payload: LlmProviderAuthUpdate,
|
||||
session: AsyncSession = SESSION_DEP,
|
||||
ctx: OrganizationContext = ORG_ADMIN_DEP,
|
||||
) -> LlmProviderAuthRead:
|
||||
"""Patch a provider auth record and sync gateway config."""
|
||||
service = GatewayModelRegistryService(session)
|
||||
return await service.update_provider_auth(
|
||||
provider_auth_id=provider_auth_id,
|
||||
payload=payload,
|
||||
ctx=ctx,
|
||||
)
|
||||
|
||||
|
||||
@router.delete("/provider-auth/{provider_auth_id}", response_model=OkResponse)
|
||||
async def delete_provider_auth(
|
||||
provider_auth_id: UUID,
|
||||
session: AsyncSession = SESSION_DEP,
|
||||
ctx: OrganizationContext = ORG_ADMIN_DEP,
|
||||
) -> OkResponse:
|
||||
"""Delete a provider auth record and sync gateway config."""
|
||||
service = GatewayModelRegistryService(session)
|
||||
await service.delete_provider_auth(provider_auth_id=provider_auth_id, ctx=ctx)
|
||||
return OkResponse()
|
||||
|
||||
|
||||
@router.get("/models", response_model=list[LlmModelRead])
|
||||
async def list_models(
|
||||
gateway_id: UUID | None = GATEWAY_ID_QUERY,
|
||||
session: AsyncSession = SESSION_DEP,
|
||||
ctx: OrganizationContext = ORG_ADMIN_DEP,
|
||||
) -> list[LlmModelRead]:
|
||||
"""List gateway model catalog entries for the active organization."""
|
||||
service = GatewayModelRegistryService(session)
|
||||
return await service.list_models(ctx=ctx, gateway_id=gateway_id)
|
||||
|
||||
|
||||
@router.post("/models", response_model=LlmModelRead)
|
||||
async def create_model(
|
||||
payload: LlmModelCreate,
|
||||
session: AsyncSession = SESSION_DEP,
|
||||
ctx: OrganizationContext = ORG_ADMIN_DEP,
|
||||
) -> LlmModelRead:
|
||||
"""Create a model catalog entry and sync gateway config."""
|
||||
service = GatewayModelRegistryService(session)
|
||||
return await service.create_model(payload=payload, ctx=ctx)
|
||||
|
||||
|
||||
@router.patch("/models/{model_id}", response_model=LlmModelRead)
|
||||
async def update_model(
|
||||
model_id: UUID,
|
||||
payload: LlmModelUpdate,
|
||||
session: AsyncSession = SESSION_DEP,
|
||||
ctx: OrganizationContext = ORG_ADMIN_DEP,
|
||||
) -> LlmModelRead:
|
||||
"""Patch a model catalog entry and sync gateway config."""
|
||||
service = GatewayModelRegistryService(session)
|
||||
return await service.update_model(model_id=model_id, payload=payload, ctx=ctx)
|
||||
|
||||
|
||||
@router.delete("/models/{model_id}", response_model=OkResponse)
|
||||
async def delete_model(
|
||||
model_id: UUID,
|
||||
session: AsyncSession = SESSION_DEP,
|
||||
ctx: OrganizationContext = ORG_ADMIN_DEP,
|
||||
) -> OkResponse:
|
||||
"""Delete a model catalog entry and sync gateway config."""
|
||||
service = GatewayModelRegistryService(session)
|
||||
await service.delete_model(model_id=model_id, ctx=ctx)
|
||||
return OkResponse()
|
||||
|
||||
|
||||
@router.post("/gateways/{gateway_id}/sync", response_model=GatewayModelSyncResult)
|
||||
async def sync_gateway_models(
|
||||
gateway_id: UUID,
|
||||
session: AsyncSession = SESSION_DEP,
|
||||
ctx: OrganizationContext = ORG_ADMIN_DEP,
|
||||
) -> GatewayModelSyncResult:
|
||||
"""Push provider auth + model catalog + agent model links to a gateway."""
|
||||
service = GatewayModelRegistryService(session)
|
||||
gateway = await service.require_gateway(
|
||||
gateway_id=gateway_id,
|
||||
organization_id=ctx.organization.id,
|
||||
)
|
||||
return await service.sync_gateway_config(
|
||||
gateway=gateway,
|
||||
organization_id=ctx.organization.id,
|
||||
)
|
||||
|
||||
|
||||
@router.post("/gateways/{gateway_id}/pull", response_model=GatewayModelPullResult)
|
||||
async def pull_gateway_models(
|
||||
gateway_id: UUID,
|
||||
session: AsyncSession = SESSION_DEP,
|
||||
ctx: OrganizationContext = ORG_ADMIN_DEP,
|
||||
) -> GatewayModelPullResult:
|
||||
"""Pull provider auth + model catalog + agent model links from a gateway."""
|
||||
service = GatewayModelRegistryService(session)
|
||||
gateway = await service.require_gateway(
|
||||
gateway_id=gateway_id,
|
||||
organization_id=ctx.organization.id,
|
||||
)
|
||||
return await service.pull_gateway_config(
|
||||
gateway=gateway,
|
||||
organization_id=ctx.organization.id,
|
||||
)
|
||||
Reference in New Issue
Block a user