docs: add video vs clip comparison table + update timestamps to all 14 modules
This commit is contained in:
283
docs_v1.0/API_WORKSPACE/modules/01_auth.md
Normal file
283
docs_v1.0/API_WORKSPACE/modules/01_auth.md
Normal file
@@ -0,0 +1,283 @@
|
||||
<!-- module: auth -->
|
||||
<!-- description: Authentication — login, logout, JWT, session cookie, API key -->
|
||||
<!-- depends: -->
|
||||
|
||||
## Base URL
|
||||
|
||||
| Environment | URL | Purpose |
|
||||
|-------------|-----|---------|
|
||||
| Production | `http://localhost:3002` | Production deployment |
|
||||
| External (M5) | `https://m5api.momentry.ddns.net` | Remote access |
|
||||
|
||||
## Variables
|
||||
|
||||
All examples in this documentation use these environment variables:
|
||||
|
||||
```bash
|
||||
API="http://localhost:3002"
|
||||
KEY="your-api-key-here"
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
All endpoints under `/api/v1/*` require authentication.
|
||||
The following endpoints are public (no auth needed):
|
||||
|
||||
- `GET /health`
|
||||
- `POST /api/v1/auth/login`
|
||||
- `POST /api/v1/auth/logout`
|
||||
|
||||
### Three Authentication Modes
|
||||
|
||||
The system supports three authentication methods, checked in **priority order** by the middleware:
|
||||
|
||||
```
|
||||
Middleware priority:
|
||||
1. Session Cookie (Portal/browser)
|
||||
2. JWT Bearer (API clients, CLI)
|
||||
3. API Key Header (legacy compatibility)
|
||||
4. API Key Query Param (?api_key=)
|
||||
```
|
||||
|
||||
| Mode | Transport | Expiry | Scope | Best for |
|
||||
|------|-----------|--------|-------|----------|
|
||||
| **Session Cookie** | `Cookie: session_id=<session_id>` | 24h | per-browser session | Portal (browser) |
|
||||
| **JWT** | `Authorization: Bearer <token>` | 1h | per-login token | API clients, CLI, scripts |
|
||||
| **API Key** | `X-API-Key: <key>` | 90d | fixed key for automation | Legacy scripts, WordPress |
|
||||
|
||||
---
|
||||
|
||||
### Login
|
||||
|
||||
**Default accounts & API keys:**
|
||||
|
||||
| Username | Password | API Key | Role |
|
||||
|----------|----------|---------|------|
|
||||
| `admin` | `admin` | — | admin |
|
||||
| `demo` | `demo` | `muser_demo_key_32chars_abcdef1234567890` | user |
|
||||
|
||||
The demo API key is set via `MOMENTRY_DEMO_API_KEY` env var and can be used in place of JWT for marcom integrations:
|
||||
|
||||
```bash
|
||||
# Using API key instead of JWT
|
||||
curl -s "$API/api/v1/files/scan" -H "X-API-Key: muser_demo_key_32chars_abcdef1234567890"
|
||||
```
|
||||
|
||||
```bash
|
||||
# Login as admin
|
||||
curl -s -X POST "$API/api/v1/auth/login" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username": "admin", "password": "admin"}'
|
||||
|
||||
# Login as demo user
|
||||
curl -s -X POST "$API/api/v1/auth/login" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username": "demo", "password": "demo"}'
|
||||
```
|
||||
|
||||
#### Success Response
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"jwt": "eyJhbGciOiJIUzI1NiIs...",
|
||||
"api_key": "muser_...",
|
||||
"user": {
|
||||
"username": "admin",
|
||||
"role": "admin"
|
||||
},
|
||||
"expires_at": "2026-05-18T13:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `jwt` | string | JWT access token. Use as `Authorization: Bearer <jwt>`. Expires in 1 hour. |
|
||||
| `api_key` | string | Legacy API key. Use as `X-API-Key: <key>`. Good for 90 days. |
|
||||
| `user.username` | string | Username |
|
||||
| `user.role` | string | Role: `admin`, `user`, or `readonly` |
|
||||
| `expires_at` | string | ISO8601 timestamp of JWT expiration |
|
||||
|
||||
The login endpoint also sets a `Set-Cookie` header for browser-based clients:
|
||||
|
||||
```
|
||||
Set-Cookie: session_id=<session_id>; Path=/; HttpOnly; SameSite=Strict; Max-Age=86400
|
||||
```
|
||||
|
||||
#### Error Response (401)
|
||||
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"message": "Invalid username or password"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Using JWT
|
||||
|
||||
JWT is preferred for API clients (CLI scripts, WordPress). It is validated by the middleware without a database lookup (stateless).
|
||||
|
||||
```bash
|
||||
# Login and capture JWT
|
||||
JWT=$(curl -s -X POST "$API/api/v1/auth/login" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"admin","password":"admin"}' | python3 -c "import json,sys;print(json.load(sys.stdin)['jwt'])")
|
||||
|
||||
# Use JWT for all subsequent requests
|
||||
curl -H "Authorization: Bearer $JWT" "$API/api/v1/files/scan"
|
||||
curl -H "Authorization: Bearer $JWT" "$API/api/v1/resource/tmdb"
|
||||
```
|
||||
|
||||
JWT is short-lived (1 hour). When it expires, request a new one via login.
|
||||
|
||||
---
|
||||
|
||||
### Using Session Cookie (Browser)
|
||||
|
||||
Browser-based clients (Portal) get a session cookie automatically after login. The browser sends the cookie with every request—no manual header needed.
|
||||
|
||||
```bash
|
||||
# Login captures the session cookie from Set-Cookie header
|
||||
curl -v -X POST "$API/api/v1/auth/login" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"admin","password":"admin"}' 2>&1 | grep "Set-Cookie"
|
||||
|
||||
# Browser automatically sends: Cookie: session_id=<session_id>
|
||||
# No manual header needed for subsequent requests
|
||||
```
|
||||
|
||||
The session cookie is HttpOnly (not accessible from JavaScript) and SameSite=Strict (protected against CSRF).
|
||||
|
||||
---
|
||||
|
||||
### Using Legacy API Key
|
||||
|
||||
```bash
|
||||
curl -H "X-API-Key: $KEY" "$API/api/v1/files/scan"
|
||||
|
||||
# Also accepted via Bearer header (non-JWT format) or query parameter:
|
||||
curl -H "Authorization: Bearer $KEY" "$API/api/v1/files/scan"
|
||||
curl "$API/api/v1/files/scan?api_key=$KEY"
|
||||
```
|
||||
|
||||
API keys are validated via SHA256 hash lookup in the database. They are long-lived (90 days) and intended for automation.
|
||||
|
||||
### Obtaining an API Key (CLI)
|
||||
|
||||
```bash
|
||||
momentry api-key create "My API Key" --key-type user
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Logout
|
||||
|
||||
```bash
|
||||
# Logout using the session cookie (browser)
|
||||
curl -X POST "$API/api/v1/auth/logout" \
|
||||
-H "Cookie: session_id=<uuid>"
|
||||
```
|
||||
|
||||
#### What logout does
|
||||
|
||||
| Auth mode | Effect |
|
||||
|-----------|--------|
|
||||
| **Session Cookie** | Session deleted from database. Same cookie returns 401 on subsequent requests. |
|
||||
| **JWT** | JWT remains valid until expiry. (JWT is stateless — logout adds JWT to a blacklist only if API key mode is used.) |
|
||||
| **API Key** | API key remains valid. (Legacy keys are shared across sessions — revoking would break other clients.) |
|
||||
|
||||
#### Example: full session lifecycle
|
||||
|
||||
```bash
|
||||
# 1. Login
|
||||
SESSION_ID=$(curl -s -D - -X POST "$API/api/v1/auth/login" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"admin","password":"admin"}' | grep "Set-Cookie" | sed 's/.*session_id=\([^;]*\).*/\1/')
|
||||
|
||||
# 2. Use session (works)
|
||||
curl -s -o /dev/null -w "HTTP %{http_code}\n" "$API/api/v1/resource/tmdb" \
|
||||
-H "Cookie: session_id=$SESSION_ID"
|
||||
# → HTTP 200
|
||||
|
||||
# 3. Logout
|
||||
curl -s -X POST "$API/api/v1/auth/logout" \
|
||||
-H "Cookie: session_id=$SESSION_ID"
|
||||
# → {"success": true}
|
||||
|
||||
# 4. Use session again (rejected)
|
||||
curl -s -o /dev/null -w "HTTP %{http_code}\n" "$API/api/v1/resource/tmdb" \
|
||||
-H "Cookie: session_id=$SESSION_ID"
|
||||
# → HTTP 401
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Authentication Flow Summary
|
||||
|
||||
```
|
||||
Login Request
|
||||
│
|
||||
▼
|
||||
┌──────────────────┐
|
||||
│ 1. Check users │ ← users table (argon2 password verify)
|
||||
│ table │
|
||||
└──────┬───────────┘
|
||||
│
|
||||
┌───┴───┐
|
||||
│ match │
|
||||
└───┬───┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────┐
|
||||
│ 2. Create JWT │ ← 1h expiry, signed with JWT_SECRET
|
||||
├──────────────────┤
|
||||
│ 3. Create │ ← 24h expiry, stored in sessions table
|
||||
│ session │
|
||||
├──────────────────┤
|
||||
│ 4. Set-Cookie │ ← HttpOnly, SameSite=Strict, Path=/
|
||||
├──────────────────┤
|
||||
│ 5. Return │ ← JWT + api_key + user info to client
|
||||
└──────────────────┘
|
||||
```
|
||||
|
||||
```
|
||||
Protected Request
|
||||
│
|
||||
▼
|
||||
┌──────────────────────┐
|
||||
│ Middleware checks: │
|
||||
│ │
|
||||
│ 1. Cookie session? │ → DB lookup session → get api_key → verify
|
||||
│ │
|
||||
│ 2. JWT Bearer? │ → verify JWT signature → decode claims
|
||||
│ │
|
||||
│ 3. X-API-Key? │ → SHA256 hash → DB lookup → verify
|
||||
│ │
|
||||
│ 4. ?api_key=? │ → same as #3
|
||||
│ │
|
||||
│ 5. None → 401 │
|
||||
└──────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error Responses
|
||||
|
||||
| HTTP | When |
|
||||
|------|------|
|
||||
| `401` | Missing or invalid authentication |
|
||||
| `401` | Session expired or logged out |
|
||||
| `401` | JWT expired |
|
||||
| `401` | API key revoked or inactive |
|
||||
|
||||
---
|
||||
|
||||
### Related
|
||||
|
||||
- `POST /api/v1/resource/tmdb/check` — test authentication + TMDb API connectivity
|
||||
- `GET /health/detailed` — view auth status (integrations section)
|
||||
|
||||
---
|
||||
*Updated: 2026-05-19 12:49:24*
|
||||
@@ -185,3 +185,6 @@ curl -s "$API/health/consistency" -H "X-API-Key: $KEY" | jq '.checks[] | {check,
|
||||
| Method | Endpoint | Auth | Description |
|
||||
|--------|----------|------|-------------|
|
||||
| GET | `/api/v1/stats/sftpgo` | No | SFTPGo service status |
|
||||
|
||||
---
|
||||
*Updated: 2026-05-19 12:49:24*
|
||||
|
||||
@@ -183,3 +183,6 @@ curl -s "$API/api/v1/files/scan?sort_by=status&page_size=5" -H "X-API-Key: $KEY"
|
||||
| **Sort order** | Default (`sort_by=name`): registered files first, then alphabetically. `sort_by=status`: alphabetical by status string. |
|
||||
| **Pagination** | `page_size` and `limit` are aliases. Default: show all results. |
|
||||
| **Processing order** | `pattern` regex filter → `sort_by`/`sort_order` → `page`/`page_size` slice. |
|
||||
|
||||
---
|
||||
*Updated: 2026-05-19 12:49:24*
|
||||
|
||||
141
docs_v1.0/API_WORKSPACE/modules/04_lookup.md
Normal file
141
docs_v1.0/API_WORKSPACE/modules/04_lookup.md
Normal file
@@ -0,0 +1,141 @@
|
||||
<!-- module: lookup -->
|
||||
<!-- description: File lookup by name and unregistration -->
|
||||
<!-- depends: 01_auth, 03_register -->
|
||||
|
||||
## File Lookup
|
||||
|
||||
### `GET /api/v1/files/lookup`
|
||||
|
||||
**Auth**: Required
|
||||
**Scope**: file-level
|
||||
|
||||
Search registered files by file name. Performs a case-insensitive LIKE search on the file name column. Returns basic info about matching files.
|
||||
|
||||
#### Query Parameters
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `file_name` | string | Yes | File name to search for (partial matches supported) |
|
||||
|
||||
#### Example
|
||||
|
||||
```bash
|
||||
# Look up a specific file
|
||||
curl -s "$API/api/v1/files/lookup?file_name=video.mp4" \
|
||||
-H "X-API-Key: $KEY"
|
||||
|
||||
# Partial name search
|
||||
curl -s "$API/api/v1/files/lookup?file_name=charade" \
|
||||
-H "X-API-Key: $KEY" | jq '.matches[].file_name'
|
||||
```
|
||||
|
||||
#### Response (200)
|
||||
|
||||
```json
|
||||
{
|
||||
"file_name": "video.mp4",
|
||||
"exists": true,
|
||||
"matches": [
|
||||
{
|
||||
"file_uuid": "a03485a40b2df2d3",
|
||||
"file_name": "video.mp4",
|
||||
"file_type": "video",
|
||||
"status": "completed"
|
||||
}
|
||||
],
|
||||
"next_name": "video (2).mp4"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `file_name` | string | Searched name |
|
||||
| `exists` | boolean | Exact name match exists |
|
||||
| `matches` | array | Array of matching registered files |
|
||||
| `matches[].file_uuid` | string | 32-char hex UUID |
|
||||
| `matches[].file_name` | string | Registered file name |
|
||||
| `matches[].file_type` | string | `"video"`, `"audio"`, or `null` |
|
||||
| `matches[].status` | string | Registration/processing status |
|
||||
| `next_name` | string | Suggested name for avoiding conflicts |
|
||||
|
||||
---
|
||||
|
||||
## Unregister
|
||||
|
||||
### `POST /api/v1/unregister`
|
||||
|
||||
**Auth**: Required
|
||||
**Scope**: file-level
|
||||
|
||||
Delete a registered file from the system. Supports single file by UUID, or batch by directory + regex pattern.
|
||||
|
||||
#### What gets deleted
|
||||
|
||||
| Removed (default) | Not removed |
|
||||
|---------|-------------|
|
||||
| Database records (videos, chunks, embeddings, processor_results, pre_chunks) | The original source video file on disk |
|
||||
| Processor output JSON files (`{uuid}.*.json`) — unless `delete_output_files: false` | Temp/working directories |
|
||||
| In-memory cache entries | |
|
||||
| MongoDB cached lists | |
|
||||
|
||||
> ⚠️ Database deletion is **irreversible**. To keep output files, set `"delete_output_files": false`.
|
||||
|
||||
#### Request Parameters
|
||||
|
||||
At least one mode must be specified: either `file_uuid` alone, or `file_path` + `pattern` together.
|
||||
|
||||
| Field | Type | Required | Default | Description |
|
||||
|-------|------|----------|---------|-------------|
|
||||
| `file_uuid` | string | * | — | Single file UUID to delete |
|
||||
| `file_path` | string | * | — | Directory path (for batch delete) |
|
||||
| `pattern` | string | * | — | Regex pattern (requires `file_path`) |
|
||||
| `delete_output_files` | boolean | No | `true` | If `true`, also delete processor output JSON files (`{uuid}.*.json`). Set to `false` to keep them. |
|
||||
|
||||
#### Example
|
||||
|
||||
```bash
|
||||
# Delete a single file by UUID (default: also deletes output JSON files)
|
||||
curl -s -X POST "$API/api/v1/unregister" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-API-Key: $KEY" \
|
||||
-d '{"file_uuid": "'"$FILE_UUID"'"}'
|
||||
|
||||
# Keep output JSON files, only delete DB records
|
||||
curl -s -X POST "$API/api/v1/unregister" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-API-Key: $KEY" \
|
||||
-d '{"file_uuid": "'"$FILE_UUID"'", "delete_output_files": false}'
|
||||
|
||||
# Batch delete all mp4 files in a directory
|
||||
curl -s -X POST "$API/api/v1/unregister" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-API-Key: $KEY" \
|
||||
-d '{"file_path": "/path/to/dir", "pattern": ".*\\.mp4$"}'
|
||||
```
|
||||
|
||||
#### Response (200)
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"file_uuid": "a03485a40b2df2d3",
|
||||
"message": "Video unregistered successfully"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `success` | boolean | True if deletion succeeded |
|
||||
| `file_uuid` | string | UUID of the deleted file (single mode) |
|
||||
| `message` | string | Human-readable status |
|
||||
|
||||
#### Error Responses
|
||||
|
||||
| HTTP | When |
|
||||
|------|------|
|
||||
| `400` | Neither `file_uuid` nor `file_path`+`pattern` provided |
|
||||
| `404` | File UUID not found |
|
||||
| `401` | Missing or invalid API key |
|
||||
|
||||
---
|
||||
*Updated: 2026-05-19 12:49:24*
|
||||
239
docs_v1.0/API_WORKSPACE/modules/05_process.md
Normal file
239
docs_v1.0/API_WORKSPACE/modules/05_process.md
Normal file
@@ -0,0 +1,239 @@
|
||||
<!-- module: process -->
|
||||
<!-- description: Processing pipeline — trigger, probe, progress, jobs -->
|
||||
<!-- depends: 01_auth, 03_register -->
|
||||
|
||||
## Processing Pipeline
|
||||
|
||||
### `POST /api/v1/file/:file_uuid/process`
|
||||
|
||||
**Auth**: Required
|
||||
**Scope**: file-level
|
||||
|
||||
Trigger the processing pipeline for a registered file. Creates a monitor job that the worker picks up and processes sequentially. Returns immediately with the job info—processing runs asynchronously in the background.
|
||||
|
||||
#### Request Parameters
|
||||
|
||||
| Field | Type | Required | Default | Description |
|
||||
|-------|------|----------|---------|-------------|
|
||||
| `processors` | string[] | No | all | Specific processors to run: `["cut","asr","asrx","yolo","ocr","face","pose","visual_chunk","story","5w1h"]` |
|
||||
| `rules` | string[] | No | all | Rule names to apply (currently unused) |
|
||||
|
||||
#### Example
|
||||
|
||||
```bash
|
||||
# Run all processors
|
||||
curl -s -X POST "$API/api/v1/file/$FILE_UUID/process" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-API-Key: $KEY" -d '{}'
|
||||
|
||||
# Run specific processors only
|
||||
curl -s -X POST "$API/api/v1/file/$FILE_UUID/process" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-API-Key: $KEY" \
|
||||
-d '{"processors": ["asr", "face", "yolo"]}'
|
||||
```
|
||||
|
||||
#### Response (200)
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"job_id": 42,
|
||||
"file_uuid": "3a6c1865...",
|
||||
"status": "processing",
|
||||
"pids": [12345, 12346],
|
||||
"message": "Processing triggered for video.mp4"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `success` | boolean | Always true on 200 |
|
||||
| `job_id` | integer | Monitor job ID (for job tracking) |
|
||||
| `file_uuid` | string | 32-char hex UUID of the file |
|
||||
| `status` | string | `"processing"` |
|
||||
| `pids` | integer[] | Process IDs of started processors |
|
||||
| `message` | string | Human-readable status |
|
||||
|
||||
#### Error Responses
|
||||
|
||||
| HTTP | When |
|
||||
|------|------|
|
||||
| `404` | File UUID not found |
|
||||
| `401` | Missing or invalid API key |
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/v1/file/:file_uuid/probe`
|
||||
|
||||
**Auth**: Required
|
||||
**Scope**: file-level
|
||||
|
||||
Get ffprobe metadata for a registered file. Returns video/audio stream info, codec details, duration, resolution, and frame rate.
|
||||
|
||||
#### Example
|
||||
|
||||
```bash
|
||||
curl -s "$API/api/v1/file/$FILE_UUID/probe" -H "X-API-Key: $KEY"
|
||||
```
|
||||
|
||||
#### Response (200)
|
||||
|
||||
```json
|
||||
{
|
||||
"file_uuid": "3a6c1865...",
|
||||
"file_name": "video.mp4",
|
||||
"file_size": 794863677,
|
||||
"duration": 120.5,
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"fps": 24.0,
|
||||
"total_frames": 2892,
|
||||
"cached": true,
|
||||
"format": {
|
||||
"filename": "/path/to/video.mp4",
|
||||
"format_name": "mov,mp4,m4a,3gp",
|
||||
"duration": "120.5",
|
||||
"size": "12345678",
|
||||
"bit_rate": "819200"
|
||||
},
|
||||
"streams": [
|
||||
{
|
||||
"index": 0,
|
||||
"codec_name": "h264",
|
||||
"codec_type": "video",
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"r_frame_rate": "24/1",
|
||||
"duration": "120.5"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `file_uuid` | string | 32-char hex UUID |
|
||||
| `file_name` | string | File name |
|
||||
| `file_size` | integer | File size in bytes (from filesystem) |
|
||||
| `duration` | float | Duration in seconds |
|
||||
| `width` | integer | Video width in pixels |
|
||||
| `height` | integer | Video height in pixels |
|
||||
| `fps` | float | Frames per second |
|
||||
| `total_frames` | integer | Estimated total frames |
|
||||
| `cached` | boolean | True if result was from cached probe JSON |
|
||||
| `format` | object | Container format info (ffprobe format section) |
|
||||
| `streams` | array | Array of stream info objects |
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/v1/progress/:file_uuid`
|
||||
|
||||
**Auth**: Required
|
||||
**Scope**: file-level
|
||||
|
||||
Get real-time processing progress for a file via Redis pub/sub. Includes per-processor status, current/total frames, ETA, and system resource stats.
|
||||
|
||||
#### Pipeline Order
|
||||
|
||||
| Order | Processor | Dependencies | Description |
|
||||
|-------|-----------|-------------|-------------|
|
||||
| 1 | `cut` | — | Scene detection |
|
||||
| 2 | `asr` | cut | Speech-to-text (per scene) |
|
||||
| 3 | `asrx` | asr | Speaker diarization |
|
||||
| 4 | `yolo` | — | Object detection |
|
||||
| 5 | `ocr` | — | Text recognition |
|
||||
| 6 | `face` | — | Face detection & embedding |
|
||||
| 7 | `pose` | — | Pose estimation |
|
||||
| 8 | `visual_chunk` | yolo | Visual scene chunks |
|
||||
| 9 | `story` | asr, asrx, cut, yolo, face | Scene summaries (template) |
|
||||
| 10 | `5w1h` | story | 5W1H analysis (Gemma4 LLM) |
|
||||
|
||||
All processors except `story` and `5w1h` run concurrently when their dependencies are met. Story and 5W1H run sequentially after their prerequisites.
|
||||
|
||||
#### Example
|
||||
|
||||
```bash
|
||||
curl -s "$API/api/v1/progress/$FILE_UUID" -H "X-API-Key: $KEY" | jq '{overall_progress, processors: [.processors[] | {processor_type, status}]}'
|
||||
```
|
||||
|
||||
#### Response (200)
|
||||
|
||||
```json
|
||||
{
|
||||
"file_uuid": "3a6c1865...",
|
||||
"overall_progress": 71,
|
||||
"cpu_percent": 45.2,
|
||||
"gpu_percent": 30.1,
|
||||
"memory_percent": 62.4,
|
||||
"processors": [
|
||||
{"processor_type": "asr", "status": "complete", "progress": 100},
|
||||
{"processor_type": "yolo", "status": "running", "progress": 65},
|
||||
{"processor_type": "face", "status": "pending", "progress": 0}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `file_uuid` | string | 32-char hex UUID |
|
||||
| `overall_progress` | integer | Overall progress percentage (0–100) |
|
||||
| `processors` | array | Per-processor status list |
|
||||
| `processors[].processor_type` | string | Processor name (`asr`, `cut`, `yolo`, etc.) |
|
||||
| `processors[].status` | string | `"pending"`, `"running"`, `"complete"`, or `"failed"` |
|
||||
| `processors[].progress` | integer | Per-processor progress (0–100) |
|
||||
| `processors[].eta_seconds` | integer | Estimated seconds remaining (running processors) |
|
||||
| `processors[].current` | integer | Current frame count |
|
||||
| `processors[].total` | integer | Total frame count |
|
||||
| `cpu_percent` | float | Current CPU usage |
|
||||
| `gpu_percent` | float | Current GPU utilization |
|
||||
| `memory_percent` | float | Current memory usage |
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/v1/jobs`
|
||||
|
||||
**Auth**: Required
|
||||
**Scope**: system-level
|
||||
|
||||
List all processing jobs (monitor jobs) in the system. Shows job status, which file each job is processing, and current processor info.
|
||||
|
||||
#### Example
|
||||
|
||||
```bash
|
||||
curl -s "$API/api/v1/jobs" -H "X-API-Key: $KEY" | jq '{count, jobs: [.jobs[] | {uuid, status}]}'
|
||||
```
|
||||
|
||||
#### Response (200)
|
||||
|
||||
```json
|
||||
{
|
||||
"jobs": [
|
||||
{
|
||||
"id": 42,
|
||||
"uuid": "3a6c1865...",
|
||||
"status": "running",
|
||||
"current_processor": "yolo",
|
||||
"created_at": "2026-05-16T12:00:00Z",
|
||||
"started_at": "2026-05-16T12:01:00Z"
|
||||
}
|
||||
],
|
||||
"count": 15,
|
||||
"page": 1,
|
||||
"page_size": 20
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `jobs` | array | Array of job info objects |
|
||||
| `jobs[].id` | integer | Job ID |
|
||||
| `jobs[].uuid` | string | File UUID being processed |
|
||||
| `jobs[].status` | string | `"pending"`, `"running"`, `"completed"`, `"failed"` |
|
||||
| `jobs[].current_processor` | string | Currently active processor, or null |
|
||||
| `count` | integer | Total job count |
|
||||
| `page` | integer | Current page number |
|
||||
| `page_size` | integer | Jobs per page |
|
||||
|
||||
---
|
||||
*Updated: 2026-05-19 12:49:24*
|
||||
@@ -143,3 +143,6 @@ Search text chunks spoken by a specific identity.
|
||||
| **Endpoint** | `POST /api/v1/embeddings` on port 11436 |
|
||||
| **Dimension** | 768 |
|
||||
| **Storage** | pgvector (`chunk.embedding` column) |
|
||||
|
||||
---
|
||||
*Updated: 2026-05-19 12:49:24*
|
||||
|
||||
@@ -331,3 +331,6 @@ curl -s "$API/api/v1/identity/$IDENTITY_UUID/profile-image" \
|
||||
| `content-type` | `image/jpeg` or `image/png` |
|
||||
|
||||
|
||||
|
||||
---
|
||||
*Updated: 2026-05-19 12:49:24*
|
||||
|
||||
68
docs_v1.0/API_WORKSPACE/modules/08_identity_agent.md
Normal file
68
docs_v1.0/API_WORKSPACE/modules/08_identity_agent.md
Normal file
@@ -0,0 +1,68 @@
|
||||
<!-- module: identity_agent -->
|
||||
<!-- description: Identity agent — match from photo, match from trace -->
|
||||
<!-- depends: 01_auth, 07_identity -->
|
||||
|
||||
## Identity Agent
|
||||
|
||||
### `POST /api/v1/agents/identity/match-from-photo`
|
||||
|
||||
**Auth**: Required
|
||||
**Scope**: file-level
|
||||
|
||||
Upload a face photo to match against known identities. Detects face via InsightFace, extracts 512D embedding via CoreML FaceNet, then searches pgvector for the closest identity.
|
||||
|
||||
#### Request
|
||||
|
||||
`multipart/form-data` with field `image` (JPEG/PNG) and optional `file_uuid`.
|
||||
|
||||
#### Example
|
||||
|
||||
```bash
|
||||
curl -s -X POST "$API/api/v1/agents/identity/match-from-photo" \
|
||||
-H "Authorization: Bearer $JWT" \
|
||||
-F "image=@/path/to/face.jpg" \
|
||||
-F "file_uuid=$FILE_UUID"
|
||||
```
|
||||
|
||||
#### Response (200)
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"matches": [
|
||||
{
|
||||
"identity_uuid": "a9a90105...",
|
||||
"name": "Cary Grant",
|
||||
"similarity": 0.87
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `POST /api/v1/agents/identity/match-from-trace`
|
||||
|
||||
**Auth**: Required
|
||||
**Scope**: file-level
|
||||
|
||||
Match a face trace (tracked face across frames) against known identities. Samples 3 angles from the trace, generates embeddings, and searches pgvector.
|
||||
|
||||
#### Request Parameters
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `file_uuid` | string | Yes | File containing the trace |
|
||||
| `trace_id` | integer | Yes | Face trace ID to match |
|
||||
|
||||
#### Example
|
||||
|
||||
```bash
|
||||
curl -s -X POST "$API/api/v1/agents/identity/match-from-trace" \
|
||||
-H "Authorization: Bearer $JWT" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"file_uuid": "'"$FILE_UUID"'", "trace_id": 10}'
|
||||
```
|
||||
|
||||
---
|
||||
*Updated: 2026-05-19 12:49:24*
|
||||
175
docs_v1.0/API_WORKSPACE/modules/08_media.md
Normal file
175
docs_v1.0/API_WORKSPACE/modules/08_media.md
Normal file
@@ -0,0 +1,175 @@
|
||||
<!-- module: media -->
|
||||
<!-- description: Video streaming & frame extraction -->
|
||||
<!-- depends: 01_auth -->
|
||||
|
||||
## Video Streaming & Frame Extraction
|
||||
|
||||
All video streaming endpoints support the following common query parameters:
|
||||
|
||||
| Field | Type | Required | Default | Description |
|
||||
|-------|------|----------|---------|-------------|
|
||||
| `mode` | string | No | `normal` | `normal` or `debug` (draws detection overlays) |
|
||||
| `audio` | string | No | `on` | `on` or `off` |
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/v1/file/:file_uuid/video`
|
||||
|
||||
Stream the full video file with range support for seeking.
|
||||
|
||||
**Auth**: Required
|
||||
**Scope**: file-level
|
||||
|
||||
#### Response
|
||||
|
||||
- **200**: Video stream (`Content-Type` based on file extension)
|
||||
- **206**: Partial content (range request)
|
||||
- Supports `Range` header for seeking
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/v1/file/:file_uuid/trace/:trace_id/video`
|
||||
|
||||
Stream video with highlights for a specific face trace (follows a single person across frames with bounding box overlay).
|
||||
|
||||
**Auth**: Required
|
||||
**Scope**: file-level
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/v1/file/:file_uuid/video/bbox`
|
||||
|
||||
Stream video with bounding box overlay for all detected objects/faces.
|
||||
|
||||
**Auth**: Required
|
||||
**Scope**: file-level
|
||||
|
||||
Uses a built-in 5×7 bitmap font renderer to draw labels directly on video frames via FFmpeg `drawtext` filter.
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/v1/file/:file_uuid/thumbnail`
|
||||
|
||||
Extract a single frame from a video as JPEG image. Uses FFmpeg `select` filter.
|
||||
|
||||
**Auth**: Required
|
||||
**Scope**: file-level
|
||||
|
||||
#### Query Parameters
|
||||
|
||||
| Field | Type | Required | Default | Description |
|
||||
|-------|------|----------|---------|-------------|
|
||||
| `frame` | integer | Yes | — | Zero-based frame number to extract |
|
||||
| `x` | integer | No | — | Crop start X (left edge). Requires `y`, `w`, `h`. |
|
||||
| `y` | integer | No | — | Crop start Y (top edge). Requires `x`, `w`, `h`. |
|
||||
| `w` | integer | No | — | Crop width in pixels. Requires `x`, `y`, `h`. |
|
||||
| `h` | integer | No | — | Crop height in pixels. Requires `x`, `y`, `w`. |
|
||||
|
||||
All four crop params (`x`, `y`, `w`, `h`) must be provided together or omitted.
|
||||
|
||||
#### Example
|
||||
|
||||
```bash
|
||||
# Extract frame 1000 (full frame)
|
||||
curl -s "$API/api/v1/file/bd80fec92b0b6963d177a2c55bf713e2/thumbnail?frame=1000" \
|
||||
-H "Authorization: Bearer $JWT" -o frame_1000.jpg
|
||||
|
||||
# Extract and crop face region (x=320, y=240, w=160, h=160)
|
||||
curl -s "$API/api/v1/file/bd80fec92b0b6963d177a2c55bf713e2/thumbnail?frame=1000&x=320&y=240&w=160&h=160" \
|
||||
-H "Authorization: Bearer $JWT" -o face_crop.jpg
|
||||
```
|
||||
|
||||
#### Response
|
||||
|
||||
- **200**: `image/jpeg` binary data
|
||||
- **404**: File not found
|
||||
- **500**: FFmpeg error (e.g., frame number exceeds video duration)
|
||||
|
||||
### `GET /api/v1/file/:file_uuid/clip`
|
||||
|
||||
Extract a video clip (time range) as MPEG-TS stream. Uses FFmpeg `-ss` fast seek.
|
||||
|
||||
**Auth**: Required
|
||||
**Scope**: file-level
|
||||
|
||||
#### Query Parameters
|
||||
|
||||
| Field | Type | Required | Default | Description |
|
||||
|-------|------|----------|---------|-------------|
|
||||
| `start_frame` | integer | No* | — | Start frame (zero-based). **Frame-accurate** — use this for precision. |
|
||||
| `end_frame` | integer | No* | — | End frame (zero-based, inclusive). Requires `start_frame`. |
|
||||
| `start_time` | float | No* | — | Start time in seconds. Approximate (FPS-dependent). Fallback if frames not given. |
|
||||
| `end_time` | float | No* | — | End time in seconds. Approximate (FPS-dependent). Fallback if frames not given. |
|
||||
| `fps` | float | No | video FPS | Override frames-per-second for frame↔time calculation. Defaults to video's detected FPS. |
|
||||
| `mode` | string | No | `normal` | `normal` or `debug` (draws "CLIP" overlay) |
|
||||
| `audio` | string | No | `on` | `on` or `off` |
|
||||
|
||||
Either (`start_frame`+`end_frame`) OR (`start_time`+`end_time`) must be provided.
|
||||
|
||||
#### Example
|
||||
|
||||
```bash
|
||||
# Clip by frame range (primary)
|
||||
curl -s "$API/api/v1/file/bd80fec92b0b6963d177a2c55bf713e2/clip?start_frame=0&end_frame=47" \
|
||||
-H "Authorization: Bearer $JWT" -o clip.ts
|
||||
|
||||
# Clip by time range (fallback)
|
||||
curl -s "$API/api/v1/file/bd80fec92b0b6963d177a2c55bf713e2/clip?start_time=30&end_time=45" \
|
||||
-H "Authorization: Bearer $JWT" -o clip.ts
|
||||
```
|
||||
|
||||
#### Response
|
||||
|
||||
- **200**: `video/mp2t` MPEG-TS stream
|
||||
- **400**: Missing/invalid range parameters
|
||||
- **404**: File not found
|
||||
- **500**: FFmpeg error
|
||||
|
||||
#### Technical Notes
|
||||
|
||||
| Detail | Value |
|
||||
|--------|-------|
|
||||
| **Backend** | FFmpeg (`ffmpeg-full`) |
|
||||
| **Seek** | `-ss` before `-i` (fast keyframe seek) |
|
||||
| **Format** | MPEG-TS (`mpegts` muxer, pipe-safe) |
|
||||
| **Codec** | H.264 + AAC |
|
||||
| **Cache** | `Cache-Control: public, max-age=86400` (24h) |
|
||||
|
||||
### Video vs Clip: Quality & Format Comparison
|
||||
|
||||
Both endpoints support time range extraction, but serve different use cases:
|
||||
|
||||
| Feature | `/video` | `/clip` |
|
||||
|---------|----------|---------|
|
||||
| **No params** | Streams full file (Range seek) | Returns 400 (params required) |
|
||||
| **HTTP Range** | ✅ Supported | ❌ Not supported |
|
||||
| **Encoding** | `-c copy` (zero encoding) | `-c:v libx264 -c:a aac` (re-encode) |
|
||||
| **Quality** | Original (bit-exact, zero loss) | Compressed (default CRF ≈ 23) |
|
||||
| **Format** | `video/mp4` | `video/mp2t` (MPEG-TS) |
|
||||
| **Speed** | Fast (no computation) | Slower (encoding required) |
|
||||
| **Frame control** | Time-based (`dur = (ef-sf)/fps`) | Precise (`-vframes`) |
|
||||
| **Debug mode** | ❌ | ✅ `mode=debug` overlay |
|
||||
| **Cache** | ❌ | ✅ `max-age=86400` |
|
||||
|
||||
#### Usage Recommendation
|
||||
|
||||
| Scenario | Use |
|
||||
|----------|-----|
|
||||
| Full video streaming / player seek | `/video` |
|
||||
| Quick preview clip (zero quality loss) | `/video?start_frame=...&end_frame=...` |
|
||||
| Debug frame verification / text overlay | `/clip?mode=debug` |
|
||||
| Precise frame count control | `/clip` |
|
||||
| CDN cacheable clip | `/clip` |
|
||||
|
||||
---
|
||||
|
||||
| Detail | Value |
|
||||
|--------|-------|
|
||||
| **Backend** | FFmpeg (`ffmpeg-full`) |
|
||||
| **Filter** | `select=eq(n\,FRAME)` to select frame, optional `crop=W:H:X:Y` |
|
||||
| **Output** | Single JPEG via pipe (`image2pipe`, `mjpeg` codec) |
|
||||
| **Cache** | `Cache-Control: public, max-age=86400` (24h) |
|
||||
| **Frame number** | Zero-based (`frame=0` = first frame of video) |
|
||||
|
||||
---
|
||||
*Updated: 2026-05-19 12:49:24*
|
||||
112
docs_v1.0/API_WORKSPACE/modules/09_tmdb.md
Normal file
112
docs_v1.0/API_WORKSPACE/modules/09_tmdb.md
Normal file
@@ -0,0 +1,112 @@
|
||||
<!-- module: tmdb -->
|
||||
<!-- description: TMDb enrichment endpoints — prefetch, probe, resource, check -->
|
||||
<!-- depends: 01_auth, 03_register -->
|
||||
|
||||
## TMDb Enrichment
|
||||
|
||||
> **Offline operation**: TMDb prefetch now checks local identity files first (`identities/_index.json` + `*.tmdb.json`).
|
||||
> If local files exist, no external API call is made. Internet is only needed for initial data seeding.
|
||||
|
||||
### Overview
|
||||
|
||||
TMDb enrichment is an optional identity enrichment step that can be run after Pipeline face detection completes. The workflow is:
|
||||
|
||||
1. **Prefetch** (requires internet): Download movie cast data from TMDb API → cache to `{file_uuid}.tmdb.json`
|
||||
2. **Probe**: Read local cache → create identities for **all** cast members (`source='tmdb'`) + save `identity.json` + download profile image to `{OUTPUT}/identities/{uuid}/profile.jpg`
|
||||
3. **Match**: The worker automatically matches video faces against TMDb identities when `MOMENTRY_TMDB_PROBE_ENABLED=true`
|
||||
|
||||
### `POST /api/v1/agents/tmdb/prefetch`
|
||||
|
||||
**Auth**: Required
|
||||
**Scope**: file-level
|
||||
|
||||
Fetch TMDb cast data for a registered file and cache it locally. This is the only step requiring internet access.
|
||||
|
||||
#### Request Parameters
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `file_uuid` | string | Yes | File UUID to enrich |
|
||||
|
||||
#### Example
|
||||
|
||||
```bash
|
||||
curl -s -X POST "$API/api/v1/agents/tmdb/prefetch" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-API-Key: $KEY" \
|
||||
-d '{"file_uuid": "'"$FILE_UUID"'"}'
|
||||
```
|
||||
|
||||
#### Response (200)
|
||||
|
||||
```json
|
||||
{"success": true, "file_uuid": "...", "cache_path": "/output/...tmdb.json"}
|
||||
```
|
||||
|
||||
### `POST /api/v1/file/:file_uuid/tmdb-probe`
|
||||
|
||||
**Auth**: Required
|
||||
**Scope**: file-level
|
||||
|
||||
Read local TMDb cache and create/update identities. Requires prefetch to have been run first.
|
||||
|
||||
#### Example
|
||||
|
||||
```bash
|
||||
curl -s -X POST "$API/api/v1/file/$FILE_UUID/tmdb-probe" \
|
||||
-H "X-API-Key: $KEY" | jq '{identities_created, movie_title}'
|
||||
```
|
||||
|
||||
#### Response (200 — identities created)
|
||||
|
||||
```json
|
||||
{"success": true, "identities_created": 15, "movie_title": "Charade"}
|
||||
```
|
||||
|
||||
#### Response (200 — no cache)
|
||||
|
||||
```json
|
||||
{"success": false, "message": "No TMDb cache found. Run tmdb-prefetch first."}
|
||||
```
|
||||
|
||||
### `GET /api/v1/resource/tmdb`
|
||||
|
||||
**Auth**: Required
|
||||
**Scope**: system-level
|
||||
|
||||
View TMDb resource status including configuration, identity counts, and cache file count.
|
||||
|
||||
#### Example
|
||||
|
||||
```bash
|
||||
curl -s "$API/api/v1/resource/tmdb" -H "X-API-Key: $KEY" \
|
||||
| jq '{identities_seeded, cache_files}'
|
||||
```
|
||||
|
||||
### `POST /api/v1/resource/tmdb/check`
|
||||
|
||||
**Auth**: Required
|
||||
**Scope**: system-level
|
||||
|
||||
Ping the TMDb API to verify connectivity and measure latency.
|
||||
|
||||
#### Example
|
||||
|
||||
```bash
|
||||
curl -s -X POST "$API/api/v1/resource/tmdb/check" \
|
||||
-H "X-API-Key: $KEY" | jq '.status'
|
||||
```
|
||||
|
||||
#### Response
|
||||
|
||||
```json
|
||||
{
|
||||
"api_key_configured": true,
|
||||
"enabled": false,
|
||||
"api_reachable": true,
|
||||
"api_latency_ms": 120
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
*Updated: 2026-05-19 12:49:24*
|
||||
@@ -120,3 +120,6 @@ The following routes are defined in source code but are **NOT** currently mounte
|
||||
| `/api/v1/search/persons` | `universal_search.rs` (not mounted) |
|
||||
| `/api/v1/who` | `who.rs` |
|
||||
| `/api/v1/who/candidates` | `who.rs` |
|
||||
|
||||
---
|
||||
*Updated: 2026-05-19 12:49:24*
|
||||
|
||||
60
docs_v1.0/API_WORKSPACE/modules/11_error_codes.md
Normal file
60
docs_v1.0/API_WORKSPACE/modules/11_error_codes.md
Normal file
@@ -0,0 +1,60 @@
|
||||
<!-- module: error_codes -->
|
||||
<!-- description: Standard API error codes -->
|
||||
<!-- depends: -->
|
||||
|
||||
## Error Response Format
|
||||
|
||||
All API errors follow this JSON structure:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": {
|
||||
"code": "E001_NOT_FOUND",
|
||||
"message": "Resource not found",
|
||||
"details": {"resource": "file_uuid", "value": "abc"}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Error Code List
|
||||
|
||||
### Generic Errors (E0xx)
|
||||
|
||||
| Code | HTTP | Description |
|
||||
|------|------|-------------|
|
||||
| `E001_NOT_FOUND` | 404 | Resource not found (file, identity, chunk) |
|
||||
| `E002_DUPLICATE` | 409 | Resource already exists |
|
||||
| `E003_VALIDATION` | 400 | Request parameter validation failed |
|
||||
| `E004_UNAUTHORIZED` | 401 | Invalid API key or token |
|
||||
| `E005_INTERNAL` | 500 | Internal server error |
|
||||
|
||||
### Processor Errors (E1xx)
|
||||
|
||||
| Code | HTTP | Description |
|
||||
|------|------|-------------|
|
||||
| `E101_PROCESSOR_FAIL` | 500 | Python script execution failed |
|
||||
| `E102_TIMEOUT` | 504 | Processing timeout |
|
||||
| `E103_RESUME_FAIL` | 500 | Resume failed (checkpoint not found) |
|
||||
| `E104_NO_VIDEO` | 400 | Video file path not found |
|
||||
|
||||
### Identity Errors (E2xx)
|
||||
|
||||
| Code | HTTP | Description |
|
||||
|------|------|-------------|
|
||||
| `E201_FACE_NOT_FOUND` | 404 | Face detection not found |
|
||||
| `E202_MERGE_CONFLICT` | 409 | Identity merge conflict |
|
||||
| `E203_CANDIDATE_EMPTY` | 404 | No candidates available for confirmation |
|
||||
|
||||
### TMDb Errors (E3xx)
|
||||
|
||||
| Code | HTTP | Description |
|
||||
|------|------|-------------|
|
||||
| `E301_TMDB_NO_KEY` | 400 | `TMDB_API_KEY` environment variable not set |
|
||||
| `E302_TMDB_UNREACHABLE` | 502 | TMDb API unreachable or timed out |
|
||||
| `E303_TMDB_CACHE_NOT_FOUND` | 200 | No local TMDb cache; run prefetch first |
|
||||
| `E304_TMDB_PROBE_FAILED` | 500 | TMDb probe execution failed |
|
||||
| `E305_TMDB_MOVIE_NOT_FOUND` | 404 | No matching TMDb movie found from filename |
|
||||
|
||||
---
|
||||
*Updated: 2026-05-19 12:49:24*
|
||||
121
docs_v1.0/API_WORKSPACE/modules/12_agent.md
Normal file
121
docs_v1.0/API_WORKSPACE/modules/12_agent.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# Agent Endpoints
|
||||
|
||||
Agent endpoints provide AI-powered capabilities including translation, identity analysis, and 5W1H extraction.
|
||||
|
||||
## POST /api/v1/agents/translate
|
||||
|
||||
Translate text between languages using Gemma4 (llama.cpp, port 8082).
|
||||
|
||||
### Request
|
||||
|
||||
```json
|
||||
{
|
||||
"text": "Hello, welcome to Momentry Core.",
|
||||
"target_language": "Traditional Chinese",
|
||||
"source_language": "English"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `text` | string | ✅ | Text to translate |
|
||||
| `target_language` | string | ✅ | Target language name (e.g. "Traditional Chinese", "Japanese") |
|
||||
| `source_language` | string | ❌ | Source language (default: "auto") |
|
||||
|
||||
### Response
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"translated_text": "您好,歡迎使用 Momentry Core。",
|
||||
"source_language_detected": "English",
|
||||
"model_used": "google_gemma-4-26B-A4B-it-Q5_K_M.gguf"
|
||||
}
|
||||
```
|
||||
|
||||
### Supported Language Pairs (tested)
|
||||
|
||||
| Source | Target | Quality |
|
||||
|--------|--------|---------|
|
||||
| English | Traditional Chinese | ✅ |
|
||||
| English | Japanese | ✅ |
|
||||
| Chinese | English | ✅ |
|
||||
| English | French | ✅ |
|
||||
| Chinese | Japanese | ✅ |
|
||||
|
||||
### Model
|
||||
|
||||
- **Model**: Gemma4 26B (Q5_K_M)
|
||||
- **Engine**: llama.cpp at `localhost:8082`
|
||||
- **Endpoint**: `/v1/chat/completions` (OpenAI-compatible)
|
||||
- **Temperature**: 0.1
|
||||
- **Max tokens**: 1024
|
||||
|
||||
### Errors
|
||||
|
||||
| Status | Condition |
|
||||
|--------|-----------|
|
||||
| 500 | LLM unreachable or response parse failure |
|
||||
| 401 | Missing/invalid auth |
|
||||
|
||||
---
|
||||
|
||||
## POST /api/v1/agents/5w1h/analyze
|
||||
|
||||
Extract 5W1H (Who, What, When, Where, Why, How) from a scene. Uses Gemma4 LLM on port 8082.
|
||||
|
||||
### Request
|
||||
|
||||
```json
|
||||
{
|
||||
"file_uuid": "3abeee81d94597629ed8cb943f182e94",
|
||||
"scene_id": 42
|
||||
}
|
||||
```
|
||||
|
||||
### Response
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"5w1h": {
|
||||
"who": ["Cary Grant"],
|
||||
"what": ["discussing plans"],
|
||||
"when": ["1963"],
|
||||
"where": ["Paris"],
|
||||
"why": ["vacation"],
|
||||
"how": ["in person"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## POST /api/v1/agents/5w1h/batch
|
||||
|
||||
Batch analyze all scenes in a file for 5W1H extraction. Uses the pipeline's `parent_chunk_5w1h.py --mode llm`.
|
||||
|
||||
### Request
|
||||
|
||||
```json
|
||||
{
|
||||
"file_uuid": "3abeee81d94597629ed8cb943f182e94"
|
||||
}
|
||||
```
|
||||
|
||||
## GET /api/v1/agents/5w1h/status
|
||||
|
||||
Get status of the 5W1H agent pipeline for a file.
|
||||
|
||||
---
|
||||
|
||||
## Embedding Model
|
||||
|
||||
| Detail | Value |
|
||||
|--------|-------|
|
||||
| **Model** | EmbeddingGemma-300m |
|
||||
| **Endpoint** | `POST /v1/embeddings` on port 11436 |
|
||||
| **Dimension** | 768 |
|
||||
| **Used by** | `parent_chunk_5w1h.py --embed`, story, 5W1H, search |
|
||||
|
||||
|
||||
---
|
||||
*Updated: 2026-05-19 12:49:24*
|
||||
@@ -85,3 +85,6 @@ curl -s -X POST "$API/api/v1/config/watcher-auto-register" \
|
||||
-H "X-API-Key: $KEY" \
|
||||
-d '{"enabled": true}'
|
||||
```
|
||||
|
||||
---
|
||||
*Updated: 2026-05-19 12:49:24*
|
||||
|
||||
63
docs_v1.0/API_WORKSPACE/modules/_template.md
Normal file
63
docs_v1.0/API_WORKSPACE/modules/_template.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# {Module Name} — API Workspace Module
|
||||
|
||||
> Use this template when adding or editing API endpoint documentation modules.
|
||||
|
||||
## Module Metadata
|
||||
|
||||
Every module MUST start with:
|
||||
|
||||
```markdown
|
||||
<!-- module: <short_name> -->
|
||||
<!-- description: One-line description of what this module covers -->
|
||||
<!-- depends: <comma-separated list of dependency module names> -->
|
||||
```
|
||||
|
||||
## Endpoint Template
|
||||
|
||||
Each endpoint MUST use this structure:
|
||||
|
||||
### `METHOD /path/to/endpoint`
|
||||
|
||||
**Auth**: Required / Optional / Public
|
||||
|
||||
**Scope**: file-level / identity-level / system-level
|
||||
|
||||
#### Request Parameters
|
||||
|
||||
| Field | Type | Required | Default | Description |
|
||||
|-------|------|----------|---------|-------------|
|
||||
| `param1` | string | Yes | — | Description |
|
||||
|
||||
#### Example
|
||||
|
||||
```bash
|
||||
# brief description of what this example demonstrates
|
||||
curl -s -X METHOD "$API/path" \
|
||||
-H "X-API-Key: $KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"param1": "value"}'
|
||||
```
|
||||
|
||||
#### Response (200)
|
||||
|
||||
```json
|
||||
{ "success": true }
|
||||
```
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `success` | boolean | Always true on 200 |
|
||||
|
||||
#### Error Codes
|
||||
|
||||
| Code | HTTP | When |
|
||||
|------|------|------|
|
||||
| E0xx | 4xx | Description |
|
||||
|
||||
## Rules
|
||||
|
||||
1. Each module file covers ONE topic group (e.g., `09_tmdb.md` = all TMDb endpoints)
|
||||
2. Use `$API` and `$KEY` in all curl examples
|
||||
3. Use `$FILE_UUID`, `$IDENTITY_UUID` variables for UUID examples
|
||||
4. Module filename = `NN_topic.md` (NN = execution order, 01-99)
|
||||
5. `depends` metadata = which modules must be assembled before this one
|
||||
Reference in New Issue
Block a user