memory_cli.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. memory_cli.py — MemoryContract CLI 入口。
  5. 提供 load-context / query-entity / query-rules / read-summary /
  6. get-open-loops / get-timeline 六个子命令,输出 JSON。
  7. """
  8. from __future__ import annotations
  9. import argparse
  10. import json
  11. import sys
  12. from pathlib import Path
  13. from runtime_compat import enable_windows_utf8_stdio
  14. def _ensure_scripts_path() -> None:
  15. scripts_dir = Path(__file__).resolve().parent
  16. if str(scripts_dir) not in sys.path:
  17. sys.path.insert(0, str(scripts_dir))
  18. _ensure_scripts_path()
  19. from data_modules.config import DataModulesConfig
  20. from data_modules.memory_contract_adapter import MemoryContractAdapter
  21. def _adapter(project_root: str) -> MemoryContractAdapter:
  22. cfg = DataModulesConfig.from_project_root(project_root)
  23. return MemoryContractAdapter(cfg)
  24. def _json_out(data) -> None:
  25. print(json.dumps(data, ensure_ascii=False, indent=2))
  26. def cmd_load_context(args: argparse.Namespace) -> None:
  27. adapter = _adapter(args.project_root)
  28. pack = adapter.load_context(args.chapter)
  29. _json_out(pack.to_dict())
  30. def cmd_query_entity(args: argparse.Namespace) -> None:
  31. adapter = _adapter(args.project_root)
  32. snap = adapter.query_entity(args.id)
  33. if snap is None:
  34. _json_out({"error": "not_found", "entity_id": args.id})
  35. else:
  36. _json_out(snap.to_dict())
  37. def cmd_query_rules(args: argparse.Namespace) -> None:
  38. adapter = _adapter(args.project_root)
  39. rules = adapter.query_rules(domain=args.domain or "")
  40. _json_out([r.to_dict() for r in rules])
  41. def cmd_read_summary(args: argparse.Namespace) -> None:
  42. adapter = _adapter(args.project_root)
  43. text = adapter.read_summary(args.chapter)
  44. _json_out({"chapter": args.chapter, "summary": text})
  45. def cmd_get_open_loops(args: argparse.Namespace) -> None:
  46. adapter = _adapter(args.project_root)
  47. loops = adapter.get_open_loops(status=args.status or "active")
  48. _json_out([l.to_dict() for l in loops])
  49. def cmd_get_timeline(args: argparse.Namespace) -> None:
  50. adapter = _adapter(args.project_root)
  51. events = adapter.get_timeline(args.from_ch, args.to_ch)
  52. _json_out([e.to_dict() for e in events])
  53. def main() -> None:
  54. parser = argparse.ArgumentParser(description="MemoryContract CLI")
  55. parser.add_argument("--project-root", required=True, help="项目根目录")
  56. sub = parser.add_subparsers(dest="command")
  57. p_load = sub.add_parser("load-context", help="加载章节上下文基础包")
  58. p_load.add_argument("--chapter", type=int, required=True)
  59. p_entity = sub.add_parser("query-entity", help="查询实体快照")
  60. p_entity.add_argument("--id", required=True, help="实体 ID")
  61. p_rules = sub.add_parser("query-rules", help="查询世界规则")
  62. p_rules.add_argument("--domain", default="", help="按 domain 过滤")
  63. p_summary = sub.add_parser("read-summary", help="读取章节摘要")
  64. p_summary.add_argument("--chapter", type=int, required=True)
  65. p_loops = sub.add_parser("get-open-loops", help="查询未闭合伏笔")
  66. p_loops.add_argument("--status", default="active", help="状态过滤")
  67. p_timeline = sub.add_parser("get-timeline", help="查询时间线事件")
  68. p_timeline.add_argument("--from", type=int, required=True, dest="from_ch", help="起始章节")
  69. p_timeline.add_argument("--to", type=int, required=True, dest="to_ch", help="结束章节")
  70. args = parser.parse_args()
  71. if not args.command:
  72. parser.print_help()
  73. sys.exit(1)
  74. dispatch = {
  75. "load-context": cmd_load_context,
  76. "query-entity": cmd_query_entity,
  77. "query-rules": cmd_query_rules,
  78. "read-summary": cmd_read_summary,
  79. "get-open-loops": cmd_get_open_loops,
  80. "get-timeline": cmd_get_timeline,
  81. }
  82. dispatch[args.command](args)
  83. if __name__ == "__main__":
  84. if sys.platform == "win32":
  85. enable_windows_utf8_stdio()
  86. main()