from langchain.messages import SystemMessage, HumanMessage from modules import model_open_router import os import re # ✅ System Prompt optimized (بديل الدليل الضخم) SYSTEM_PROMPT = """ You are an expert in APA 7th edition reference formatting. STRICT RULES: - Output ONLY the formatted reference (no explanations). - Each reference must be on a new line. - Do NOT invent missing data. - Use (n.d.) if date is missing. - Keep original language (Arabic stays Arabic, English stays English). GENERAL FORMAT RULES: 1. Author: - Format: Last name, Initial(s). - Multiple authors: - 2 authors: Author1, A. A., & Author2, B. B. - 3+ authors: Author1, A. A., et al. 2. Year: - Must be in parentheses: (2023) 3. Title: - Sentence case (only first word capitalized in English) - Italicize book/journal titles conceptually 4. Books: Author. (Year). Title (Edition). City: Publisher. 5. Journal articles: Author. (Year). Title. Journal Name, Volume(Issue), pages. 6. Conference papers: Author. (Year). Title. Conference Name, Location, Date. 7. Theses: Author. (Year). Title [Thesis type], Institution. 8. Websites: - With author: Author. (Year). Title. URL - Without author: Title. (Year). URL 9. Arabic references: - Keep Arabic format - Use same structure: المؤلف. (السنة). العنوان. المدينة: الناشر. 10. Page numbers: - Use pp. for English - Use ص for Arabic 11. Missing data: - Use (n.d.) - Use [Missing Info] only if critical 12. Fix: - spelling - punctuation - ordering OUTPUT: - Clean APA formatted references only - No bullets - No numbering """ # ✅ تحسين: batching أصغر + fallback def normalize_references_batch(refs_list, model,batch_size=2): batches = [] for i in range(0, len(refs_list), batch_size): chunk = refs_list[i : i + batch_size] batches.append("\n".join(chunk)) results = [] for batch in batches: try: messages = [ SystemMessage(content=SYSTEM_PROMPT), HumanMessage(content=f"Format in APA 7:\n{batch}"), ] response = model.invoke(messages) formatted = [ line.strip() for line in response.content.split("\n") if line.strip() ] results.extend(formatted) except Exception as e: print(f"Error in batch: {e}") # fallback: رجعهم زي ما هم results.extend(batch.split("\n")) return results # ✅ استخراج المراجع def extract_references(book_json): refs = [] for chapter in book_json.get("chapters", []): for section in chapter.get("sections", []): for plan in section.get("plans", {}).values(): for chunk in plan.get("rag_context", {}).get("chunks", []): ref = chunk.get("reference_apa") if ref: refs.append(ref) book_name = book_json.get("book_title", "") return refs, book_name # ✅ إزالة التكرار def remove_duplicates(refs): return list(dict.fromkeys(refs)) # ✅ HTML cleaner def save_refs_to_html(refs_list, book_name): """ تحويل قائمة المراجع إلى ملف HTML منسق أكاديمياً مع اسم الكتاب """ html_content = f""" قائمة المراجع - APA 7th Edition
{book_name}

قائمة المراجع (APA 7th Edition)

""" return html_content # ✅ Main pipeline def run_references(book_json): refs, book_name = extract_references(book_json) print(f"Extracted: {len(refs)}") refs = remove_duplicates(refs) print(f"Unique: {len(refs)}") # ✅ Model (يفضل موديل أسرع) model = model_open_router() fixed = normalize_references_batch(refs, model) print(f"Formatted: {len(fixed)}") html = save_refs_to_html(fixed, book_name) return html