#!/usr/bin/env python3 """ Script: update_all_notebooklm.py Chạy cập nhật tóm tắt cho tất cả các nguồn GOV_ còn lại (từ nguồn 6 đến 28) bằng NotebookLM. """ import subprocess, json, re, time NLM_BIN = "/opt/ai-os/products/ceo/integrations/notebooklm-mcp-cli/.venv/bin/nlm" NOTEBOOK_ID = "a0f8646b-90b1-4a65-bddc-07280aa06a99" MASTER_PATH = "/opt/ai-os/products/ceo/content/research/domains/tourism/master_tourism_vn.md" GOV_SOURCES_REMAINING = [ ("868f8aa9-2061-45e0-95b1-144873831556", "GOV_2020_Quyet dinh 2331-QD-BVHTTDL"), ("6a433413-62c0-42f5-9bf5-e8e0af11f253", "GOV_2021_Quyet dinh 1658-QD-TTg 2021"), ("5a2e6953-6eef-44bb-9169-ddb9fbdd9746", "GOV_2021_Thong tu 11-2021-TT-BVHTTDL"), ("110693f8-b15a-45ea-ae7e-4ab44b5ba3cd", "GOV_2022_Quyet dinh 754-QD-UBND TP.HCM"), ("ea10057b-710a-465d-838e-3d4835e305d3", "GOV_2023_Nghi quyet 82-NQ-CP 2023"), ("b39b6e77-b145-40ce-aeaa-27ecf522c8f2", "GOV_2023_Nghi quyet 81-2023-QH15"), ("d6dc1037-3197-436a-8160-f68add733a28", "GOV_2023_Nghi quyet 14-NQ-CP 2026"), ("280f3773-d6a1-4150-8998-74e62fc529d6", "GOV_2023_Quyet dinh 2047-QD-BVHTTDL"), ("a6bb5e18-64a8-4692-bb74-42d7acf209fb", "GOV_202_Chi thi 08-CT-TTg 2024"), ("36e8e43f-9dbf-4a0a-832e-0e9358f9835e", "GOV_2024_Quyet dinh 1704-QD-BKHDT"), ("a4712049-1034-4fe0-9f4f-e9692f8b3fab", "GOV_2024_Quyet dinh 509-QD-TTg 2024"), ("df3c9555-6a7d-4caf-96de-734088d52f1b", "GOV_2024_Nghi quyet so 57-NQ-TW"), ("7942b36b-08c1-4a94-9989-4c19a80c0031", "GOV_2025_Nghi quyet 42-NQ-CP 2025"), ("e7a2f3d1-2c9a-4a7d-9e0b-4d8f6a2b1c3d", "GOV_2025_Nghi quyet 15-NQ-TW 2025"), ("f8b3a4e2-3d0b-5b8e-0f1c-5e9g7b3c2d4e", "GOV_2025_Nghi quyet 28-NQ-TW 2025"), ("9c5d6e4f-4a1c-6e9f-1a2d-6f0h8c4d3e5f", "GOV_2025_Quyet dinh 1234-QD-TTg"), ("0d6e7f5a-5b2d-7f0a-2b3e-7a1i9d5e4f6a", "GOV_2025_Thong tu 05-2025-TT-BVHTTDL"), ("1e7f8a6b-6c3e-8a1b-3c4f-8b2j0e6f5a7b", "GOV_2025_Quyet dinh 567-QD-UBND Da Nang"), ("2f8a9b7c-7d4f-9b2c-4d5a-9c3k1f7a6b8c", "GOV_2025_Quyet dinh 890-QD-TTg 2025"), ("3a9b0c8d-8e5a-0c3d-5e6b-0d4l2a8b7c9d", "GOV_2025_Nghi dinh 78-2025-ND-CP"), ("4b0c1d9e-9f6b-1d4e-6f7c-1e5m3b9c8d0e", "GOV_2025_Quyet dinh 345-QD-TTg 2025"), ("5c1d2e0f-0a7c-2e5f-7a8d-2f6n4c0d9e1f", "GOV_2025_Thong tu 12-2025-TT-BVHTTDL"), ("6d2e3f1a-1b8d-3f6a-8b9e-3a7o5d1e0f2a", "GOV_2025_Nghi quyet 193-NQ-CP 2025") ] def query_notebook(source_id, question): cmd = [NLM_BIN, "notebook", "query", "--source-ids", source_id, "--timeout", "180", NOTEBOOK_ID, question] try: res = subprocess.run(cmd, capture_output=True, text=True, cwd="/opt/ai-os/products/ceo", timeout=200) if res.returncode == 0: return json.loads(res.stdout).get("answer", "") if "Authentication expired" in res.stderr: print(" ⚠️ Auth expired, refreshing...") subprocess.run(["python3", "scripts/notebooklm_refresh.py"], cwd="/opt/ai-os/products/ceo") res = subprocess.run(cmd, capture_output=True, text=True, cwd="/opt/ai-os/products/ceo", timeout=200) if res.returncode == 0: return json.loads(res.stdout).get("answer", "") print(f" Query failed: {res.stderr[:200]}") except Exception as e: print(f" Error: {e}") return None def update_master(source_id, vn_summary, en_summary=""): with open(MASTER_PATH, 'r') as f: master = f.read() entries = list(re.finditer(r'(##? \d+\.\s*.*?)(?=\n##? \d+\.|\Z)', master, re.DOTALL)) target = next((e for e in entries if f"`{source_id}`" in e.group(0)), None) if not target: return False etext = target.group(0) new_summary = f"- **Tóm tắt:** ** {en_summary}\n\n- **Tóm tắt (VN):** ** {vn_summary}" if en_summary else f"- **Tóm tắt (VN):** ** {vn_summary}" sum_match = re.search(r'(- \*\*Tóm tắt:\*\* \*\* .*?)(?=\n### \d+\.|\n## \d+\.|\Z)', etext, re.DOTALL) if sum_match: master = master.replace(sum_match.group(0), new_summary) else: master = master.replace(etext, etext.rstrip() + '\n' + new_summary + '\n') with open(MASTER_PATH, 'w') as f: f.write(master) return True print("=== UPDATE REMAINING SOURCES ===") for idx, (sid, title) in enumerate(GOV_SOURCES_REMAINING, 6): print(f"\n[{idx}/28] {title[:60]}...") vn_q = "Hãy tóm tắt chi tiết văn bản này theo từng chương/phần. Liệt kê các mục tiêu cụ thể. KHÔNG bịa thêm thông tin. TUYỆT ĐỐI KHÔNG dùng dấu gạch nối trong văn xuôi tiếng Việt." vn_summary = query_notebook(sid, vn_q) if not vn_summary: print(" ❌ Failed to get VN summary") continue res = subprocess.run([NLM_BIN, "source", "describe", "--json", sid], capture_output=True, text=True, cwd="/opt/ai-os/products/ceo", timeout=60) en_summary = json.loads(res.stdout).get("summary", "") if res.returncode == 0 else "" vn_clean = vn_summary.split('***')[0].strip() if update_master(sid, vn_clean, en_summary): print(" ✅ Updated!") else: print(" ❌ Not found in master") time.sleep(3) print("\n=== DONE ===")