feat: complete image console and add verified REST and MCP workflows
This commit is contained in:
@@ -0,0 +1 @@
|
||||
"""路由包。"""
|
||||
@@ -0,0 +1,34 @@
|
||||
"""画廊 API。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from fastapi import APIRouter, HTTPException
|
||||
|
||||
from ..services import gallery as svc
|
||||
from ..providers import ProviderError
|
||||
|
||||
router = APIRouter(prefix="/api/galleries", tags=["gallery"])
|
||||
|
||||
|
||||
@router.get("")
|
||||
def list_galleries():
|
||||
return svc.list_galleries()
|
||||
|
||||
|
||||
@router.get("/{profile_name}")
|
||||
def list_gallery(profile_name: str):
|
||||
try:
|
||||
return svc.list_gallery(profile_name)
|
||||
except ProviderError as exc:
|
||||
raise HTTPException(status_code=exc.status, detail=exc.message)
|
||||
|
||||
|
||||
@router.delete("/{profile_name}/{filename}")
|
||||
def delete_gallery_item(profile_name: str, filename: str):
|
||||
try:
|
||||
svc.delete_gallery_item(profile_name, filename)
|
||||
except FileNotFoundError as exc:
|
||||
raise HTTPException(status_code=404, detail=str(exc))
|
||||
except ProviderError as exc:
|
||||
raise HTTPException(status_code=exc.status, detail=exc.message)
|
||||
return {"ok": True}
|
||||
@@ -0,0 +1,33 @@
|
||||
"""出图 API。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from fastapi import APIRouter, HTTPException
|
||||
|
||||
from ..providers import ProviderError
|
||||
from ..schemas import GenerateIn
|
||||
from ..services import generation as svc
|
||||
|
||||
router = APIRouter(prefix="/api", tags=["generate"])
|
||||
|
||||
|
||||
@router.post("/generate")
|
||||
def generate(payload: GenerateIn):
|
||||
try:
|
||||
return svc.generate(
|
||||
provider_id=payload.provider_id,
|
||||
model=payload.model,
|
||||
prompt=payload.prompt,
|
||||
size=payload.size,
|
||||
ratio=payload.ratio,
|
||||
n=payload.n,
|
||||
images=payload.images,
|
||||
profile_name=payload.profile_name,
|
||||
)
|
||||
except ProviderError as exc:
|
||||
raise HTTPException(status_code=exc.status, detail=exc.message)
|
||||
|
||||
|
||||
@router.get("/generations")
|
||||
def list_generations():
|
||||
return svc.list_generations()
|
||||
@@ -0,0 +1,33 @@
|
||||
"""模型 API。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from fastapi import APIRouter, HTTPException
|
||||
|
||||
from ..providers import ProviderError
|
||||
from ..schemas import ModelBulkIn, ModelPatchIn
|
||||
from ..services import providers as svc
|
||||
|
||||
router = APIRouter(prefix="/api/models", tags=["models"])
|
||||
|
||||
|
||||
@router.get("")
|
||||
def list_models(provider_id: str | None = None):
|
||||
return svc.list_models(provider_id)
|
||||
|
||||
|
||||
@router.patch("/{model_id:path}")
|
||||
def patch_model(model_id: str, payload: ModelPatchIn):
|
||||
try:
|
||||
if payload.enabled is not None:
|
||||
svc.set_model_enabled(model_id, payload.enabled)
|
||||
if payload.note is not None:
|
||||
svc.set_model_note(model_id, payload.note)
|
||||
return svc.get_model(model_id)
|
||||
except ProviderError as exc:
|
||||
raise HTTPException(status_code=exc.status, detail=exc.message)
|
||||
|
||||
|
||||
@router.post("/bulk")
|
||||
def bulk_models(payload: ModelBulkIn):
|
||||
return svc.set_models_enabled(payload.ids, payload.enabled)
|
||||
@@ -0,0 +1,65 @@
|
||||
"""供应商与模型 API。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from fastapi import APIRouter, HTTPException
|
||||
|
||||
from ..providers import ProviderError
|
||||
from ..schemas import DiscoverIn, ModelUpsertIn, ProviderIn
|
||||
from ..services import providers as svc
|
||||
|
||||
router = APIRouter(prefix="/api/providers", tags=["providers"])
|
||||
|
||||
|
||||
@router.get("")
|
||||
def list_providers():
|
||||
return svc.list_providers()
|
||||
|
||||
|
||||
@router.post("")
|
||||
def save_provider(payload: ProviderIn):
|
||||
try:
|
||||
return svc.save_provider(payload.model_dump())
|
||||
except ProviderError as exc:
|
||||
raise HTTPException(status_code=exc.status, detail=exc.message)
|
||||
|
||||
|
||||
@router.delete("/{provider_id}")
|
||||
def delete_provider(provider_id: str):
|
||||
svc.delete_provider(provider_id)
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
@router.post("/discover")
|
||||
def discover_with_credentials(payload: DiscoverIn):
|
||||
"""尚未保存供应商时,用手填的 Base URL + Key 临时拉取模型清单。"""
|
||||
try:
|
||||
return svc.discover_with_credentials(
|
||||
payload.adapter, payload.base_url.rstrip("/"), payload.api_key
|
||||
)
|
||||
except ProviderError as exc:
|
||||
raise HTTPException(status_code=exc.status, detail=exc.message)
|
||||
|
||||
|
||||
@router.post("/{provider_id}/discover")
|
||||
def discover_provider_models(provider_id: str):
|
||||
"""按已保存的供应商拉取上游模型(命中规则:模型 ID 含 image)。"""
|
||||
try:
|
||||
return svc.discover(provider_id)
|
||||
except ProviderError as exc:
|
||||
raise HTTPException(status_code=exc.status, detail=exc.message)
|
||||
|
||||
|
||||
@router.post("/{provider_id}/models")
|
||||
def upsert_provider_models(provider_id: str, payload: ModelUpsertIn):
|
||||
"""保存勾选的模型,并设置启用状态(未勾选的自动停用)。"""
|
||||
try:
|
||||
return svc.upsert_models(
|
||||
provider_id,
|
||||
payload.model_ids,
|
||||
enabled=payload.enabled,
|
||||
note=payload.note or "自动发现",
|
||||
exclusive=True,
|
||||
)
|
||||
except ProviderError as exc:
|
||||
raise HTTPException(status_code=exc.status, detail=exc.message)
|
||||
@@ -0,0 +1,20 @@
|
||||
"""SKILL.md API。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from fastapi import APIRouter
|
||||
from fastapi.responses import PlainTextResponse
|
||||
|
||||
from ..services import skill_doc
|
||||
|
||||
router = APIRouter(prefix="/api", tags=["skills"])
|
||||
|
||||
|
||||
@router.get("/skills")
|
||||
def get_skills():
|
||||
return skill_doc.get_skill()
|
||||
|
||||
|
||||
@router.get("/skills/raw", response_class=PlainTextResponse)
|
||||
def get_skills_raw():
|
||||
return skill_doc.get_skill()["body"]
|
||||
Reference in New Issue
Block a user