File size: 3,414 Bytes
4d5727a
 
12a6c9a
4d5727a
 
12a6c9a
 
 
4d5727a
 
 
 
 
 
 
 
 
 
 
 
 
 
12a6c9a
4d5727a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12a6c9a
 
4d5727a
 
 
 
12a6c9a
4d5727a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
96
97
98
99
100
#!/usr/bin/env python3
"""
agentcache CLI entrypoint.

Commands:
  agentcache serve [--port PORT] [--host HOST]
  agentcache migrate [--dry-run]
  agentcache export [--output FILE]
"""

import argparse
import json
import os
import sys


def cmd_serve(args) -> None:
    """Start the Flask server."""
    os.environ.setdefault("III_REST_PORT", str(args.port))
    sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
    from app import create_app
    flask_app = create_app()
    print(f"[cli] Starting agentcache on {args.host}:{args.port}")
    flask_app.run(host=args.host, port=args.port, debug=False)


def cmd_migrate(args) -> None:
    """Run session → folder migration."""
    sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
    from db import StateKV
    from functions import migrate_sessions_to_folders
    kv = StateKV()
    result = migrate_sessions_to_folders(kv, dry_run=args.dry_run)
    print(json.dumps(result, indent=2))
    if args.dry_run:
        print(f"\n[cli] Dry run — no changes made. "
              f"{result['migrated_sessions']} sessions, "
              f"{result['migrated_observations']} observations would be migrated.")
    else:
        print(f"\n[cli] Migration complete: "
              f"{result['migrated_sessions']} sessions, "
              f"{result['migrated_observations']} observations migrated.")
    if result.get("errors"):
        print(f"[cli] {len(result['errors'])} errors:")
        for e in result["errors"]:
            print(f"  - {e}")


def cmd_export(args) -> None:
    """Export all data as JSON."""
    sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
    from db import StateKV
    from functions import export_data
    kv = StateKV()
    data = export_data(kv, {})
    output = json.dumps(data, indent=2, ensure_ascii=False)
    if args.output:
        with open(args.output, "w", encoding="utf-8") as f:
            f.write(output)
        print(f"[cli] Exported to {args.output}")
        total_obs = sum(len(folder.get("observations", [])) for folder in data.get("folders", []))
        print(f"[cli] {len(data.get('folders', []))} folders, {total_obs} observations, "
              f"{len(data.get('memories', []))} memories")
    else:
        print(output)


def main() -> None:
    parser = argparse.ArgumentParser(
        prog="agentcache",
        description="agentcache — AI agent cache server",
    )
    subparsers = parser.add_subparsers(dest="command", required=True)

    # serve
    serve_parser = subparsers.add_parser("serve", help="Start the cache server")
    serve_parser.add_argument("--port", type=int, default=int(os.getenv("III_REST_PORT", "3111")))
    serve_parser.add_argument("--host", default="0.0.0.0")

    # migrate
    migrate_parser = subparsers.add_parser("migrate", help="Migrate legacy session data to folder-based storage")
    migrate_parser.add_argument("--dry-run", action="store_true", help="Preview without writing")

    # export
    export_parser = subparsers.add_parser("export", help="Export all data as JSON")
    export_parser.add_argument("--output", "-o", help="Output file path (default: stdout)")

    args = parser.parse_args()

    if args.command == "serve":
        cmd_serve(args)
    elif args.command == "migrate":
        cmd_migrate(args)
    elif args.command == "export":
        cmd_export(args)


if __name__ == "__main__":
    main()