feat: cleanup endpoint, auto-extraction on capture, daily cron script

- POST /admin/backup/cleanup — retention cleanup via API (dry-run by default)
- record_interaction() accepts extract=True to auto-extract candidate
  memories from response text using the Phase 9C rule-based extractor
- POST /interactions accepts extract field to enable extraction on capture
- deploy/dalidou/cron-backup.sh — daily backup + cleanup for cron

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-11 10:28:32 -04:00
parent 2829d5ec1c
commit 0b1742770a
3 changed files with 103 additions and 0 deletions

View File

@@ -49,6 +49,7 @@ from atocore.memory.service import (
)
from atocore.observability.logger import get_logger
from atocore.ops.backup import (
cleanup_old_backups,
create_runtime_backup,
list_runtime_backups,
validate_backup,
@@ -511,6 +512,7 @@ class InteractionRecordRequest(BaseModel):
chunks_used: list[str] = []
context_pack: dict | None = None
reinforce: bool = True
extract: bool = False
@router.post("/interactions")
@@ -536,6 +538,7 @@ def api_record_interaction(req: InteractionRecordRequest) -> dict:
chunks_used=req.chunks_used,
context_pack=req.context_pack,
reinforce=req.reinforce,
extract=req.extract,
)
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
@@ -731,6 +734,25 @@ def api_list_backups() -> dict:
}
class BackupCleanupRequest(BaseModel):
confirm: bool = False
@router.post("/admin/backup/cleanup")
def api_cleanup_backups(req: BackupCleanupRequest | None = None) -> dict:
"""Apply retention policy to old backup snapshots.
Dry-run by default. Pass ``confirm: true`` to actually delete.
Retention: last 7 daily, last 4 weekly (Sundays), last 6 monthly (1st).
"""
payload = req or BackupCleanupRequest()
try:
return cleanup_old_backups(confirm=payload.confirm)
except Exception as e:
log.error("admin_cleanup_failed", error=str(e))
raise HTTPException(status_code=500, detail=f"Cleanup failed: {e}")
@router.get("/admin/backup/{stamp}/validate")
def api_validate_backup(stamp: str) -> dict:
"""Validate that a previously created backup is structurally usable."""