import argparse import glob as glob_module import logging import os import sys if sys.stdout.encoding and sys.stdout.encoding.lower() == "gbk": sys.stdout.reconfigure(encoding="utf-8") logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s", datefmt="%H:%M:%S", ) logger = logging.getLogger(__name__) def cmd_process(args): from meeting_processor import meeting_processor filepath = args.file if not os.path.exists(filepath): print(f"错误:文件不存在 {filepath}") sys.exit(1) print(f"正在处理会议文件:{filepath}") archive_path = meeting_processor.process_meeting_file(filepath, force=getattr(args, "force", False)) if archive_path: print("\n处理完成") print(f"原文归档:{archive_path}") else: print("\n处理失败或已跳过") sys.exit(1) def cmd_text(args): from meeting_processor import meeting_processor print("正在处理会议文本...") archive_path = meeting_processor.process_meeting_text(args.text, force=getattr(args, "force", False)) if archive_path: print("\n处理完成") print(f"原文归档:{archive_path}") else: print("\n处理失败或已跳过") def cmd_query(args): from meeting_processor import meeting_processor print(f"查询:{args.question}") print("-" * 40) result = meeting_processor.query(args.question, top_k=args.top_k) print(result if result else "未找到相关信息") def cmd_stats(args): from meeting_processor import meeting_processor stats = meeting_processor.stats() print("会议记忆系统统计") print("-" * 40) print(f"向量节点数:{stats.get('vector_index', {}).get('node_count', 0)}") print(f"Neo4j 启用:{stats.get('graph', {}).get('enabled', False)}") print(f"图谱会议数:{stats.get('graph', {}).get('meetings', 0)}") print(f"图谱实体数:{stats.get('graph', {}).get('entities', 0)}") print(f"行动项数:{stats.get('state', {}).get('action_items_tracked', 0)}") print(f"指标数:{stats.get('state', {}).get('metrics_tracked', 0)}") print(f"会议系列数:{stats.get('state', {}).get('meeting_series', 0)}") print(f"原文归档目录:{stats.get('raw_dir', '')}") print(f"状态文件:{stats.get('state_path', '')}") def cmd_batch(args): from meeting_processor import meeting_processor files = glob_module.glob(args.pattern, recursive=True) if not files: print(f"未匹配到任何文件:{args.pattern}") sys.exit(1) print(f"找到 {len(files)} 个文件,开始批量处理...") success = 0 for path in files: try: print(f"\n处理:{path}") result = meeting_processor.process_meeting_file(path, force=getattr(args, "force", False)) if result: success += 1 except Exception as exc: logger.error("处理失败: %s - %s", path, exc) print(f"\n批量处理完成:{success}/{len(files)} 成功") def cmd_interactive(): from meeting_processor import meeting_processor print("会议纪要长期记忆系统") print("=" * 50) print("可用命令:") print(" query <问题> 语义查询会议记忆") print(" process <路径> 处理会议文件") print(" stats 查看统计") print(" help 显示帮助") print(" exit/quit 退出") print("=" * 50) while True: try: line = input("\n> ").strip() except (EOFError, KeyboardInterrupt): print() break if not line: continue if line in ("exit", "quit", "q"): break if line == "help": print(" query <问题>") print(" process <路径>") print(" stats") print(" exit/quit") continue if line == "stats": cmd_stats(None) continue if line.startswith("process "): filepath = line[8:].strip() if not os.path.exists(filepath): print(f"文件不存在:{filepath}") continue result = meeting_processor.process_meeting_file(filepath) print(f"完成:{result}" if result else "处理失败或已跳过") continue question = line[6:].strip() if line.startswith("query ") else line result = meeting_processor.query(question, top_k=3) print(result if result else "未找到相关信息") print("bye!") def main(): parser = argparse.ArgumentParser(description="会议纪要长期记忆系统") subparsers = parser.add_subparsers(dest="command") p_process = subparsers.add_parser("process", help="处理会议 markdown 文件") p_process.add_argument("file", help="会议文件路径") p_process.add_argument("-f", "--force", action="store_true", help="发现重复时自动覆盖") p_text = subparsers.add_parser("text", help="直接处理一段会议文本") p_text.add_argument("text", help="会议文本内容") p_text.add_argument("-f", "--force", action="store_true", help="发现重复时自动覆盖") p_query = subparsers.add_parser("query", help="语义查询会议记忆") p_query.add_argument("question", help="查询问题") p_query.add_argument("--top-k", type=int, default=3, help="返回结果数量") subparsers.add_parser("stats", help="查看统计") p_batch = subparsers.add_parser("batch", help="批量处理会议文件") p_batch.add_argument("pattern", help="glob 模式,如 meetings/*.md") p_batch.add_argument("-f", "--force", action="store_true", help="发现重复时自动覆盖") args = parser.parse_args() if args.command == "process": cmd_process(args) elif args.command == "text": cmd_text(args) elif args.command == "query": cmd_query(args) elif args.command == "stats": cmd_stats(args) elif args.command == "batch": cmd_batch(args) else: cmd_interactive() if __name__ == "__main__": main()