diff --git a/mcp-server/src/legal_mcp/services/block_writer.py b/mcp-server/src/legal_mcp/services/block_writer.py index da37141..783282b 100644 --- a/mcp-server/src/legal_mcp/services/block_writer.py +++ b/mcp-server/src/legal_mcp/services/block_writer.py @@ -199,20 +199,21 @@ BLOCK_PROMPTS = { "block-yod": """כתוב את בלוק הדיון וההכרעה (בלוק י) של החלטת ועדת ערר. ## זהו הבלוק הקריטי ביותר — ליבת ההחלטה (ratio decidendi). +## אורך נדרש: **2,000-4,000 מילים לפחות**. זהו הבלוק הארוך ביותר בהחלטה (35-50%). ## מתודולוגיה — CREAC: 1. **C** (Conclusion) — פתח במסקנה: "לאחר שעיינו... מצאנו כי הערר [נדחה/מתקבל]" -2. **R** (Rule) — הצג את הכלל המשפטי הרלוונטי -3. **E** (Explanation) — צטט פסיקה שמסבירה את הכלל -4. **A** (Application) — יישם על העובדות הספציפיות +2. **R** (Rule) — הצג את הכלל המשפטי הרלוונטי עם ציטוט פסיקה +3. **E** (Explanation) — צטט פסיקה שמסבירה את הכלל (200-600 מילים לכל ציטוט) +4. **A** (Application) — יישם על העובדות הספציפיות של התיק 5. **C** (Conclusion) — מסקנת ביניים ## כללים קריטיים: - **מסקנה בפתיחה** — לא בסוף -- **מענה לכל טענה** שהוצגה בבלוק ז +- **מענה פרטני לכל טענה** שהוצגה בבלוק ז — עבור על כל טענה ברשימה והתייחס אליה בנפרד. אל תדלג על שום טענה. +- **ציטוטי פסיקה** — צטט לפחות 3-5 פסקי דין רלוונטיים. כל ציטוט עם שם התיק המלא. - **ללא כפילות** — הפנה לבלוקים קודמים: "כאמור בסעיף X לעיל" - **ללא כותרות משנה** (חריג: נושאים נפרדים לחלוטין) -- ציטוט פסיקה בבלוקים ארוכים (200-600 מילים) - מספור רציף ## כיוון מאושר (חובה): @@ -221,13 +222,13 @@ BLOCK_PROMPTS = { ## מבנה לפי תוצאה: {structure_guidance} -## טענות שצריך לענות עליהן: +## טענות שצריך לענות עליהן (חובה — כל טענה חייבת מענה): {claims_context} ## חומרי מקור: {source_context} -## פסיקה רלוונטית: +## פסיקה רלוונטית (צטט מכאן ומהידע הכללי שלך): {precedents_context} ## סגנון דפנה: @@ -349,19 +350,33 @@ async def write_block( if model_key == "opus" and temperature >= 0.3: # Extended thinking for complex blocks + # max_tokens must be > budget_tokens + kwargs["max_tokens"] = max(max_tokens, 20000) kwargs["temperature"] = 1 # Required for extended thinking kwargs["thinking"] = {"type": "enabled", "budget_tokens": 16000} else: kwargs["temperature"] = temperature - message = client.messages.create(**kwargs) + # Use streaming for long requests (opus + thinking) + use_stream = model_key == "opus" and kwargs.get("thinking") - # Extract text from response (skip thinking blocks) - content = "" - for block in message.content: - if block.type == "text": - content = block.text - break + if use_stream: + content_parts = [] + with client.messages.stream(**kwargs) as stream: + for event in stream: + pass # consume stream + response = stream.get_final_message() + for block in response.content: + if block.type == "text": + content_parts.append(block.text) + content = "\n".join(content_parts) + else: + message = client.messages.create(**kwargs) + content = "" + for block in message.content: + if block.type == "text": + content = block.text + break return _build_result(block_id, content, block_cfg) @@ -419,11 +434,14 @@ async def _build_claims_context(case_id: UUID) -> str: current_role = "" role_heb = {"appellant": "טענות העוררים", "respondent": "טענות המשיבים", "committee": "עמדת הוועדה המקומית", "permit_applicant": "עמדת מבקשי ההיתר"} + claim_num = 0 for c in claims: if c["party_role"] != current_role: current_role = c["party_role"] lines.append(f"\n### {role_heb.get(current_role, current_role)}") - lines.append(f"- {c['claim_text'][:300]}") + claim_num += 1 + lines.append(f"טענה #{claim_num}: {c['claim_text'][:400]}") + lines.append(f"\n**סה\"כ {claim_num} טענות — חובה לענות על כל אחת.**") return "\n".join(lines)