#!/usr/bin/env python3 import sqlite3 import json import os import sys import time DB_PATH = '/root/.hermes/kanban/boards/research-hub/kanban.db' PROJECT_BASE = '/opt/ai-os/products/ceo/content/research/tourism_benchmarking/' MASTER_REPORTS_PATH = os.path.join(PROJECT_BASE, 'master_reports') def get_current_loop_count(sync_state_path): loop_count = 0 if os.path.exists(sync_state_path): try: with open(sync_state_path, 'r') as f: data = json.load(f) loop_count = data.get('loop_count', 0) except Exception: pass return loop_count def init_pipeline(country_code): conn = sqlite3.connect(DB_PATH) c = conn.cursor() sync_state_path_base = os.path.join(PROJECT_BASE, f'processed_sources_') # Increment loop_count for the NEW pipeline sync_state_path = f"{sync_state_path_base}{country_code.lower()}.json" current_loop_count = get_current_loop_count(sync_state_path) # Read current state new_loop_count = current_loop_count + 1 # This pipeline will be for the next loop # Update processed_sources_xx.json with the new loop_count for the *next* pipeline creation sync_data = {"processed_ids": [], "last_batch": [], "loop_count": new_loop_count} try: with open(sync_state_path, 'w') as f: json.dump(sync_data, f, indent=4) except Exception as e: print(f"Error writing sync state file {sync_state_path}: {e}", file=sys.stderr) # Define country-specific files and titles policy_report_filename = "Vietnam_tourism_policy.md" if country_code == "VN" else "Thailand_tourism_policy.md" sources_batch_filename = f"batch_{new_loop_count}_7pillar_analysis_{country_code.lower()}.md" tasks = [ { "id": f"{country_code.lower()}_p1_l{new_loop_count}_{int(time.time())}", "title": f"[{country_code}.Task 1] Scoping & Data Sync (NotebookLM)", "assignee": "r-and-d", "status": "ready", "body": f"""[CONTEXT] Luận đề: đánh giá chính sách du lịch {country_code} có tập trung (coherent) hay bị dàn trải (over-dispersed) so với năng lực thực thi. Sử dụng brief.md làm nguồn chân lý với 7 trụ cột. Ma trận benchmark: lượt quốc tế/nội địa, GDP du lịch, việc làm, phòng, chi tiêu trung bình, ngân sách xúc tiến. [PHASE 1] Đối chiếu 10 nguồn tài liệu mới với 7 trụ cột chiến lược. Phân tích xem tài liệu đề cập đến khía cạnh nào trong 7 trụ cột, đánh giá mức độ bao phủ dữ liệu, phát hiện nội dung chính sách có mâu thuẫn hay lệch pha với mục tiêu nghiên cứu gốc không. Sync Logic: Đọc processed_sources_{country_code.lower()}.json, lấy 10 source ID mới chưa có trong processed_ids (nếu chưa có file thì lấy 10 source đầu). Lưu vào last_batch. OUTPUT: Ghi file vào Project Base/sources/, ví dụ: {sources_batch_filename} COPY FILE ra master_reports/ Báo cáo Telegram: - [{sources_batch_filename}](https://vmi3427693.tail8c1aaf.ts.net/files/opt/ai-os/products/ceo/content/research/tourism_benchmarking/sources/{sources_batch_filename})""", "skills": json.dumps(["notebooklm-research"]) }, { "id": f"{country_code.lower()}_p2_l{new_loop_count}_{int(time.time())}", "title": f"[{country_code}.Task 2] RAG Analysis & Deep Finding", "assignee": "r-and-d", "status": "todo", "body": f"""[CONTEXT] Luận đề: đánh giá chính sách du lịch {country_code} có tập trung (coherent) hay bị dàn trải (over-dispersed). brief.md là nguồn chân lý. 7 trụ cột. Benchmark matrix đầy đủ. [PHASE 2] KHÔNG GHI ĐÈ. Đọc file {MASTER_REPORTS_PATH}/{policy_report_filename} (nếu có). Khai thác chuyên sâu 10 nguồn thuộc last_batch qua RAG. Thực hiện Policy Coherence Test: đánh giá sự tương thích giữa số lượng mục tiêu chính sách đề ra với nguồn lực thực thi được phân bổ (flag quá tải chương trình nghị sự). Đúc kết findings định lượng lẫn định tính. Tích hợp các findings mới vào báo cáo có sẵn, có thể bổ sung các phần mới hoặc làm sâu sắc các luận điểm cũ theo 7 trụ cột. PHẢI KẾ THỪA nội dung cũ. Scope control: Chỉ query đúng 10 source ID từ last_batch. Dùng `nlm notebook query --source-ids`. OUTPUT: Viết file rồi COPY vào master_reports/{policy_report_filename}.""", "skills": json.dumps(["notebooklm-research"]) }, { "id": f"{country_code.lower()}_p3_l{new_loop_count}_{int(time.time())}", "title": f"[{country_code}.Task 3] Critique", "assignee": "grill-qa", "status": "todo", "body": f"""[CONTEXT] Luận đề chính: policy coherence vs dispersion (brief.md). 7 trụ cột. Yêu cầu phản biện chuyên sâu. Đọc báo cáo {policy_report_filename} từ master_reports/. [PHASE 3] BẮT BUỘC SỬ DỤNG SKILL: `research/research-critism`. Đóng vai phản biện độc lập (Methodology Reviewer & Devil\'s Advocate). Áp dụng quy tắc Anti Sycophancy (tấn công ít nhất 2 luận điểm chính của Phase 2, không đồng thuận dễ dãi). Kiểm tra Hypothesis Discipline và đặt Counter argument cho các luận điểm về \"dàn trải chính sách\". Chỉ ra điểm cần R&D làm rõ hoặc bổ sung nguồn đối chứng. Trả kết quả bằng Template phê bình (Mức A/B/C). HANDOFF: GHI critique findings vào comment của task này. KHÔNG block task — set status thành done, sau đó chuyển Task 4 từ todo → ready để pipeline tiếp tục.""", "skills": json.dumps(["research-critism"]), "model_override": json.dumps({"model": "default"}) }, { "id": f"{country_code.lower()}_p4_l{new_loop_count}_{int(time.time())}", "title": f"[{country_code}.Task 4] Synthesis & Reporting", "assignee": "writers", "status": "todo", "body": f"""[CONTEXT] Luận đề trung tâm: chính sách du lịch {country_code} tập trung hay dàn trải? brief.md là nguồn chân lý. 7 trụ cột. Benchmark matrix. [PHASE 4] KHÔNG GHI ĐÈ. Đọc báo cáo {policy_report_filename} hiện có từ {MASTER_REPORTS_PATH}. Đọc COMMENT của Phase 3 (Critique) để biết các điểm phản biện. Tổng hợp dữ liệu từ các phase trước có tính đến ý kiến phê bình, điều chỉnh lập luận nếu critique hợp lý. Biên soạn theo cấu trúc Claim → Evidence → Inference → Citation (APA 7). Trả lời trực tiếp Thesis: chính sách đang tập trung hay bị phân mảnh? Làm rõ ưu tiên cốt lõi vs thứ cấp. Tinh chỉnh, làm sâu sắc và tích hợp các luận điểm mới vào báo cáo chính. PHẢI KẾ THỪA và mở rộng cấu trúc cũ. OUTPUT: Viết file {policy_report_filename} trong workspace, SAU ĐÓ COPY vào master_reports/{policy_report_filename}.""", "model_override": json.dumps({"model": "default"}) }, { "id": f"{country_code.lower()}_p5_l{new_loop_count}_{int(time.time())}", "title": f"[{country_code}.Task 5] Master Update & QA Gate", "assignee": "grill-qa", "status": "todo", "body": f"""[CONTEXT] Luận đề: policy coherence (brief.md). 7 trụ cột. Toàn bộ dữ liệu từ 4 phase trước. Đọc báo cáo {policy_report_filename} từ master_reports/. [PHASE 5] Đóng vai tổng biên tập kiểm soát chất lượng cuối cùng. Kiểm tra APA 7 cho toàn bộ in-text citations & References list; không để sót dấu gạch nối trong văn xuôi tiếng Việt. Cập nhật index.md cho các hướng nghiên cứu kế tiếp. Sync Update: Gộp last_batch vào processed_ids, tăng loop_count, clear last_batch, save JSON. Pre-loop handoff. OUTPUT: Viết file index.md trong workspace, SAU ĐÓ COPY vào master_reports/index.md (ghi đè).""", "skills": json.dumps(["research-critism"]), "model_override": json.dumps({"model": "default"}) } ] # 3. Chèn các task mới vào database for t in tasks: c.execute(""" INSERT INTO tasks (id, title, assignee, status, body, skills, model_override, created_at, goal_mode) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1) """, ( t["id"], t["title"], t["assignee"], t["status"], t["body"], t.get("skills", None), t.get("model_override", None), int(time.time()), )) conn.commit() conn.close() print(f"✅ Đã khởi tạo thành công Pipeline {country_code} Loop {new_loop_count} với đầy đủ Description và logic KẾ THỪA!") if __name__ == "__main__": if len(sys.argv) > 1: # Accepts country code as argument now country = sys.argv[1].upper() if country in ["VN", "TL"]: init_pipeline(country) else: print(f"Usage: python3 init_pipeline.py [VN|TL]", file=sys.stderr) else: print("Usage: python3 init_pipeline.py [VN|TL]", file=sys.stderr)