Add media archive and slopbot design docs

This commit is contained in:
Fisto
2026-09-16 07:47:28 +02:00
parent 677afc747f
commit b59b9db461
10 changed files with 453 additions and 197 deletions
+66
View File
@@ -0,0 +1,66 @@
# Media MCP surface
The media archive is designed for agent access. The daemon exposes one service, and the MCP tools
are thin wrappers around it. The same service backs the Web UI routes, so the two clients cannot
drift.
Status: hooks designed, implementation at checkpoint C7 in [CURRENT.md](../CURRENT.md).
## Service interface
```ts
interface MediaService {
startScrape(input: { channelId: string; mode: "links" | "download"; backend?: "auto" | "slopbot" | "puppet" }): Promise<ScrapeJob>;
getScrape(scrapeId: string): Promise<ScrapeJob | null>;
listScrapes(): Promise<ScrapeJob[]>;
stopScrape(scrapeId: string): Promise<ScrapeJob>;
deleteScrape(scrapeId: string): Promise<void>;
queryMedia(query: MediaQuery): Promise<{ items: MediaItem[]; nextCursor: string | null }>;
getMediaItem(id: string): Promise<MediaItem | null>;
storageStatus(): Promise<StorageStatus>;
}
```
`MediaQuery`: `kind`, `scrapeId`, `channelId`, `guildId`, `authorId`, `after`, `before`, `text`,
`limit`, `cursor`.
`StorageStatus`: `usedBytes`, `limitBytes`, `warnPercent`, `overrunPercent`, `byKind`,
`scrapes: [{ id, bytes, state, createdAt }]`.
## Tools
| Tool | Access | Purpose |
| --- | --- | --- |
| `scrape_media` | trusted | Start a scrape (`channelId`, `mode`) |
| `list_media_scrapes` | trusted | Every scrape with state, size, and counts |
| `get_media_scrape` | trusted | One scrape, live counters and cursor |
| `stop_media_scrape` | trusted | Stop the active scrape |
| `query_media` | trusted | Filter and page through media items |
| `get_media_item` | trusted | One item with sources and local path |
| `get_media_storage` | trusted | Usage against the limit, per-kind breakdown |
| `delete_media_scrape` | admin | Delete a scrape and its files |
Read tools are cache-only against `index.db` and the scrape registry. They never call Discord.
`scrape_media` and `stop_media_scrape` drive the same job queue as the chat command, so pacing and
the action log apply.
## Rules
- Every tool goes through the existing trust tiers. `delete_media_scrape` and `mode: "download"`
need `admin`.
- Tool calls are written to the action log like any other daemon action.
- The storage limit is enforced for the agent exactly as for the chat command: near the limit,
`scrape_media` returns the warning and needs a second call with `confirm: true`.
- Media bytes are never returned inline. Tools return metadata, the original URL, and the local
path; an agent that wants the bytes reads the file through the daemon host.
## Hooks to leave in place before C7
1. `MediaService` is constructed once in the daemon and passed to both the Web UI routes and the
MCP registration. No globals.
2. `ScrapeJob` and `MediaItem` are plain JSON-serializable objects, the same shape the Web UI
consumes.
3. The job queue exposes `start`, `stop`, `list`, and `events` so MCP and the UI can subscribe to
the same stream.
4. Storage accounting is a service method, not UI code, so the MCP limit check uses the same
numbers as the Settings bar.