Media library¶
Unified Media library for images and videos as first-class research evidence (not attachments on articles). Disabled by default via the media feature toggle (Console → Feature toggles).
Concepts¶
| Artifact | Description |
|---|---|
| Media channel | Tree-structured collection (like document/article channels). Settings: metadata schema, default image/video generation models. |
| Media asset | One image or video file + title, markdown description, captured time, location, structured metadata. |
Assets use channel ACL only (media_channel resource type) — same pattern as articles.
API¶
| Method | Path | Notes |
|---|---|---|
| GET/POST | /api/media-channels |
Tree list / create |
| PUT/DELETE | /api/media-channels/{id} |
Update / delete (empty only) |
| GET | /api/media |
List (channel_id, media_kind, search) |
| POST | /api/media/upload |
Multipart: channel_id, file, optional title, description |
| GET/PATCH/DELETE | /api/media/{id} |
CRUD |
| GET | /api/media/{id}/files/{path} |
Presigned redirect (url_only=true for JSON) |
| POST | /api/media/generate |
Queue Zhipu async image/video generation job |
All routes return 404 when the media feature toggle is off.
AI generation¶
Register provider models with api_kind:
image-generate— e.g. Zhipuglm-image→POST .../async/images/generationsvideo-generate— e.g.cogvideox-3→POST .../videos/generations
Worker task run_media_generation polls GET .../async-result/{id}, downloads the result, stores under media/{asset_id}/, generates thumbnail/poster in the same job, and inserts the asset row. Uploads still enqueue a separate generate_media_derivatives job. The generation job appears in Job runs (run_media_generation; target ID = media channel) with worker logs on success or failure.
Storage¶
UI¶
Routes (when toggle on): /media, /media/channels, /media/channels/:id, /media/view/:id.
- Collection grid — upload, bulk delete, filter by kind; Create image / Create video open the shared channel upload modal pattern (
documents-upload-modal-*). Buttons are disabled when no registeredimage-generate/video-generatemodels exist; the dialog uses a model<select>(collection default → category default → first model). - Image detail — viewer + sticky metadata sidebar (title, captured time, location, description).
- Video detail — YouTube-style layout: theater player (centered, no stretch letterboxing) + caption row; sidebar tabs for Description vs Details (technical metadata grid).
Permissions: media:read, media:write.
Integrations¶
- Knowledge Map — link
resource_type: media_channel - Global search —
types=media(respects toggle) - Model registry — test playground submits async generation tasks