forked from BasedHardware/omi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbackfill_legacy_memories.py
More file actions
95 lines (82 loc) · 3.42 KB
/
Copy pathbackfill_legacy_memories.py
File metadata and controls
95 lines (82 loc) · 3.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
"""Admin entrypoint for WS-C legacy → canonical memory backfill (single uid).
Non-destructive: reads legacy ``users/{uid}/memories`` only; writes canonical ``memory_items``.
The operator must name one UID explicitly; this command never discovers accounts.
Usage:
cd backend
python scripts/backfill_legacy_memories.py --uid YOUR_UID
python scripts/backfill_legacy_memories.py --uid YOUR_UID --apply
python scripts/backfill_legacy_memories.py --uid YOUR_UID --apply --no-resume
"""
from __future__ import annotations
import argparse
import getpass
import json
import sys
from pathlib import Path
BACKEND_DIR = Path(__file__).resolve().parents[1]
if str(BACKEND_DIR) not in sys.path:
sys.path.insert(0, str(BACKEND_DIR))
from utils.memory.legacy_backfill import LegacyBackfillBucket, backfill_user, backfill_user_bucketed
BUCKET_CHOICES = [bucket.value for bucket in LegacyBackfillBucket]
def _build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(description="Backfill one user's legacy memories into canonical store")
parser.add_argument("--uid", required=True, help="Firebase uid to backfill")
mode = parser.add_mutually_exclusive_group()
mode.add_argument("--apply", action="store_true", help="Persist the repair (default is dry-run)")
mode.add_argument("--dry-run", action="store_true", help="Explicitly select the default non-mutating mode")
parser.add_argument("--batch-size", type=int, default=50, help="Checkpoint interval (default: 50)")
parser.add_argument("--no-resume", action="store_true", help="Ignore prior checkpoint and start from 0")
parser.add_argument(
"--strategy",
choices=["stage-all-for-admission", "bucketed"],
default="stage-all-for-admission",
help="Migration strategy (default: all rows enter canonical admission staging)",
)
parser.add_argument(
"--bucket",
choices=BUCKET_CHOICES,
default=None,
help="Bucket to dry-run/apply when --strategy bucketed. Omit for inventory-only dry-run.",
)
parser.add_argument(
"--operator-context",
default=None,
help="Operator identity for audit logs (default: current OS user)",
)
return parser
def main(argv: list[str] | None = None) -> int:
args = _build_parser().parse_args(argv)
dry_run = not args.apply
operator_context = args.operator_context or getpass.getuser()
if args.strategy == "bucketed":
if args.bucket is None and not dry_run:
print(
"--strategy bucketed without --bucket is inventory-only; pass --dry-run or choose a bucket",
file=sys.stderr,
)
return 2
report = backfill_user_bucketed(
args.uid,
bucket=args.bucket,
dry_run=dry_run,
operator_context=operator_context,
)
else:
if args.bucket is not None:
print("--bucket requires --strategy bucketed", file=sys.stderr)
return 2
report = backfill_user(
args.uid,
dry_run=dry_run,
batch_size=args.batch_size,
resume=not args.no_resume,
operator_context=operator_context,
)
print(json.dumps(report.__dict__, default=str, indent=2))
if report.errors:
return 1
if not report.dry_run and not report.completed:
return 1
return 0
if __name__ == "__main__":
sys.exit(main())