Tasks API¶
Celery job audit records are exposed under /tasks. Each ingest dispatch creates a task_audit row tracked through pipeline stages until success or failed.
Implementation: eagle_rag/api/ingest.py (task routes share the ingest router tag).
GET /tasks¶
List task audit records with filtering and pagination.
Query parameters¶
| Param | Type | Description |
|---|---|---|
pipeline |
string |
Filter: router, knowhere, pixelrag, or compound |
status |
string |
Raw backend status (pending, rendering, success, …) |
q |
string |
Fuzzy match on job_id or document_id |
kb_name |
string |
Multi-tenant filter |
limit |
int |
1–500, default 50 |
offset |
int |
≥ 0 |
Response — TaskListResponse¶
{
"items": [
{
"job_id": "abc-123",
"document_id": "doc_xyz",
"name": "report.pdf",
"source_uri": "kb/finance/report.pdf",
"pipeline": "knowhere",
"status": "embedding",
"status_phase": "running",
"progress": 65,
"current": 13,
"total": 20,
"error": null,
"logs": [],
"created_at": "2025-07-05T01:00:00Z",
"updated_at": "2025-07-05T01:02:00Z",
"kb_name": "finance"
}
],
"limit": 50,
"offset": 0,
"error": null
}
status vs status_phase¶
status (raw) |
status_phase (normalized) |
|---|---|
pending, queued |
pending |
rendering, embedding, indexing, processing, parsing, retrying |
running |
success, done, ready |
success |
failed, error |
failed |
The frontend status.ts maps status_phase to pill colours — keep new backend statuses mapped in _STATUS_PHASE_MAP (schemas/ingest.py).
Degraded mode¶
Database failure → HTTP 200 with items: [] and error: "database unavailable". UI should surface the hint.
GET /tasks/{job_id}¶
Single TaskAuditOut. 404 if not found. 503 if database down.
GET /tasks/{job_id}/stream (SSE)¶
Live progress subscription for one job.
Events¶
| Event | Payload |
|---|---|
progress |
Full audit dict (same shape as TaskAuditOut source row) |
timeout |
{ job_id, reason: "no change timeout", seconds } |
Behaviour¶
- Poll interval: 1.5 s (
_SSE_POLL_INTERVAL) - Emits
progresson every poll while status ∉{success, failed} - Terminal: stream closes after
successorfailedprogress event - Timeout: no
updated_atchange for 300 s →timeoutevent then close
Wire example¶
No token or step events — task SSE is audit-snapshot only.
Frontend consumer¶
frontend/lib/api/sse.ts → streamTaskProgress(jobId, onEvent) using generated streamTaskTasksJobIdStreamGet.
GET /tasks/{job_id}/logs¶
Returns TaskLogsResponse:
TaskLogEntry allows extra JSONB keys (ConfigDict(extra="allow")).
POST /tasks/{job_id}/retry¶
Re-dispatch a failed task to its original Celery queue.
Pipeline → queue mapping¶
pipeline key |
Celery task | Queue |
|---|---|---|
router |
eagle_rag.ingest.router.ingest_router |
router_queue |
knowhere |
eagle_rag.tasks.knowhere_parse |
knowhere_queue |
pixelrag |
eagle_rag.tasks.pixelrag_build |
pixelrag_queue |
Recovery logic¶
- Load audit + document registry row
- Restore
object_key/source_uri/source_type_hintfromdocumentstable local_pathintentionally null (temp file gone)- Reset audit to
PENDINGbeforesend_task(race avoidance)
Response — TaskRetryResponse¶
| HTTP | Condition |
|---|---|
200 |
Dispatched |
404 |
Unknown job |
502 |
send_task failure |
503 |
Database unavailable |
Idempotency: Each retry creates a new execution attempt on the same job_id row (status reset). Not safe to spam — may duplicate Milvus writes if prior partial index exists.
DELETE /tasks/{job_id}¶
Deletes audit record only (does not delete indexed document). 404 if missing.
Multi-tenancy¶
kb_name on each audit row; filter list with ?kb_name=finance. Retry passes kb_name in Celery kwargs.
Related documentation¶
- Ingest — dispatch entry point
- Documents —
document_idlifecycle - Task queue (backend) — worker configuration