Skip to content

Commit bb68d7b

Browse files
committed
feat(retention): add export/clean/rehydrate endpoints for task content
Adds an operational surface for bounded retention of task chat content in shared infrastructure. Callers can snapshot a task's content, delete it from the shared stores, and later restore it byte-identically from the snapshot — preserving message IDs and timestamps so tool-call and reasoning references remain valid. Three new endpoints under /tasks/{task_id}: - GET /export — returns a self-contained snapshot (messages + task_states) - POST /clean — deletes content across Mongo messages, Mongo task_states, Postgres events; resets agent_task_tracker cursors; sets tasks.cleaned_at - POST /rehydrate — restores content from a snapshot, clears cleaned_at Domain layer lives in TaskRetentionService so the eventual scheduled sweep workflow and the HTTP endpoints share the same code path. Cleanup uses a "Mongo deletes first, Postgres marker last" order so retries after partial failure converge correctly. The active-task, idle-threshold, and unprocessed-events guards refuse cleanup when the task isn't safe to drop. Schema: - New nullable tasks.cleaned_at column (TIMESTAMPTZ, metadata-only ALTER) - No new audit table — cleanup operations emit structured log lines Other changes: - adapter_mongodb.batch_create now translates pymongo BulkWriteError with all-duplicate-key sub-errors into DuplicateItemError (HTTP 400) instead of letting it surface as ServiceError (HTTP 500) - New EventRepository.delete_by_task_id and AgentTaskTrackerRepository.reset_cursors_for_task methods Tests: 13 integration tests covering happy paths, all precondition guards, and the byte-identical export → clean → rehydrate round-trip.
1 parent 8adca83 commit bb68d7b

18 files changed

Lines changed: 1544 additions & 2 deletions

File tree

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"""adding task cleaned at
2+
3+
Revision ID: 6c942325c828
4+
Revises: a9959ebcbe98
5+
Create Date: 2026-05-19 19:29:34.858692
6+
7+
"""
8+
from typing import Sequence, Union
9+
10+
from alembic import op
11+
import sqlalchemy as sa
12+
13+
14+
# revision identifiers, used by Alembic.
15+
revision: str = '6c942325c828'
16+
down_revision: Union[str, None] = 'a9959ebcbe98'
17+
branch_labels: Union[str, Sequence[str], None] = None
18+
depends_on: Union[str, Sequence[str], None] = None
19+
20+
21+
def upgrade() -> None:
22+
op.add_column('tasks', sa.Column('cleaned_at', sa.DateTime(timezone=True), nullable=True))
23+
24+
25+
def downgrade() -> None:
26+
op.drop_column('tasks', 'cleaned_at')

agentex/database/migrations/migration_history.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
9ff3ee32c81b -> e9c4ff9e6542 (head), add_tasks_metadata_gin_index
1+
a9959ebcbe98 -> 6c942325c828 (head), adding task cleaned at
2+
e9c4ff9e6542 -> a9959ebcbe98, finalize_spans_task_id
3+
9ff3ee32c81b -> e9c4ff9e6542, add_tasks_metadata_gin_index
24
57c5ed4f59ae -> 9ff3ee32c81b, uppercase deployment status enum labels
35
4a9b7787ccd7 -> 57c5ed4f59ae, add_task_id_to_spans
46
d1a6cde41b3f -> 4a9b7787ccd7, deployments

0 commit comments

Comments
 (0)