Add media archive and slopbot design docs
This commit is contained in:
@@ -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.
|
||||
Reference in New Issue
Block a user