fix(block-zayin): הפרדת-משיבים בבלוק ז' (טענות הצדדים) — השלמת #224 לשכבת-הכתיבה
בלוק ז' של טיוטת-הביניים מיזג את כל המשיבים לסעיף אחד גנרי (או השמיטם) — כי (א) _build_claims_context קיבץ רק לפי party_role, ו-(ב) ה-prompt נעל "מבנה קבוע 3 חלקים: עוררים / ועדה מקומית / מבקשי-היתר" — בלי "משיבים" בכלל. לכן בתיק 1043-02-26 המשיבים 2-3 ו-4-6 לא הופיעו כצדדים מובחנים, אף שהנתונים (129 טענות-משיבים מפוצלות לפי כתב-תשובה) תקינים ב-claims. הפרדת-המשיבים של #224 יושמה בצבירה+פאנל בלבד (PR#392) — לא בכותב-הבלוקים. - `_build_claims_context` מקבץ לפי (party_role, brief) כאשר brief=source_document ל-SPLIT_PARTIES (respondent/permit_applicant) — **אותו כלל בדיוק כמו הצבירה** (import SPLIT_PARTIES מ-argument_aggregator, G2). התוצאה: סעיף נפרד לכל כתב-תשובה ("טענות המשיבים — כתב תשובה משיבות 2 3", "— משיבים 4 6"...). - prompt בלוק ז': מבנה-צדדים דינמי לפי הכותרות בקונטקסט; הוראה מפורשת לא למזג משיבים שונים ולשקף עמדות-מנוגדות; יעד-אורך גמיש לכמה כתבי-תשובה. משפיע גם על בלוק י' (אותו _build_claims_context) — הקשר מופרד. py_compile ירוק. עבודה על MCP → דורש host reload + הרצה-מחדש כדי לראות בפועל. Invariants: G2 (נגזרת-הפרדה יחידה משותפת עם הצבירה), G1. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -192,16 +192,16 @@ BLOCK_PROMPTS = {
|
|||||||
## כללים קריטיים:
|
## כללים קריטיים:
|
||||||
- **סנתז טענות דומות** — אל תרשום כל טענה בנפרד. קבץ טענות דומות לנושא אחד. למשל: כל הטענות על הודעות → סעיף אחד, כל הטענות על רכוש משותף → סעיף אחד.
|
- **סנתז טענות דומות** — אל תרשום כל טענה בנפרד. קבץ טענות דומות לנושא אחד. למשל: כל הטענות על הודעות → סעיף אחד, כל הטענות על רכוש משותף → סעיף אחד.
|
||||||
- גוף שלישי: "העוררים טוענים כי...", "הוועדה המקומית ציינה כי..."
|
- גוף שלישי: "העוררים טוענים כי...", "הוועדה המקומית ציינה כי..."
|
||||||
- **מבנה קבוע עם 3 חלקים:**
|
- **מבנה: חלק (סעיף עם כותרת-משנה) לכל צד שמופיע בטענות שחולצו למטה** — לפי הכותרות שם (### ...). אל תמציא צדדים שאינם מופיעים ואל תשמיט צד שמופיע.
|
||||||
1. "טענות העוררים" — 8-12 סעיפים מקובצים לפי נושא
|
- "טענות העוררים" — 8-12 סעיפים מקובצים לפי נושא.
|
||||||
2. "עמדת הוועדה המקומית" — 5-8 סעיפים
|
- **צד-משיב/מתנגד: כתוב חלק נפרד לכל כתב-תשובה** שמופיע (למשל "עמדת משיבות 2-3" ו-"עמדת משיבים 4-6" בנפרד) — 5-10 סעיפים לכל אחד. **אל תמזג משיבים שונים לסעיף אחד**, ואם עמדותיהם מנוגדות — שקף זאת.
|
||||||
3. "עמדת מבקשי ההיתר" (אם יש) — 5-10 סעיפים
|
- "עמדת הוועדה המקומית" / "עמדת מבקשי ההיתר" (אם מופיעים) — 5-8 סעיפים.
|
||||||
- כותרת: "תמצית טענות הצדדים"
|
- כותרת: "תמצית טענות הצדדים"
|
||||||
- נאמנות למקור — לא להמציא טענות, אבל כן לאחד ולסכם טענות חוזרות
|
- נאמנות למקור — לא להמציא טענות, אבל כן לאחד ולסכם טענות חוזרות
|
||||||
- אין ניתוח, אין מסקנות, אין הערכה ("טענה חלשה/חזקה")
|
- אין ניתוח, אין מסקנות, אין הערכה ("טענה חלשה/חזקה")
|
||||||
- רק מכתבי טענות מקוריים (לא השלמות טיעון)
|
- רק מכתבי טענות מקוריים (לא השלמות טיעון)
|
||||||
- מספור רציף
|
- מספור רציף
|
||||||
- **יעד אורך: 800-1500 מילים**
|
- **יעד אורך: 800-1500 מילים** (יותר כשיש כמה כתבי-תשובה נפרדים — כל צד מקבל את מלוא ההתייחסות)
|
||||||
|
|
||||||
## טענות שחולצו (קבץ טענות דומות לנושאים):
|
## טענות שחולצו (קבץ טענות דומות לנושאים):
|
||||||
{claims_context}
|
{claims_context}
|
||||||
@@ -629,18 +629,44 @@ async def _build_claims_context(case_id: UUID) -> str:
|
|||||||
# Fallback to all non-block-zayin claims if no source claims exist.
|
# Fallback to all non-block-zayin claims if no source claims exist.
|
||||||
source_claims = [c for c in claims if c.get("source_document", "") != "block-zayin"] or claims
|
source_claims = [c for c in claims if c.get("source_document", "") != "block-zayin"] or claims
|
||||||
|
|
||||||
lines = []
|
# Group by (party_role, brief) so a multi-litigant side (respondent /
|
||||||
current_role = ""
|
# permit_applicant) whose claims come from distinct pleadings reads as
|
||||||
|
# SEPARATE positions — e.g. "כתב תשובה משיבות 2-3" vs "משיבים 4-6" — instead
|
||||||
|
# of one merged "טענות המשיבים" (#224). The brief label is the source
|
||||||
|
# pleading, and which sides split is SPLIT_PARTIES — the SAME rule the
|
||||||
|
# argument aggregator uses, so block ז and the arguments panel agree (G2).
|
||||||
|
from legal_mcp.services.argument_aggregator import SPLIT_PARTIES
|
||||||
|
|
||||||
role_heb = {"appellant": "טענות העוררים", "respondent": "טענות המשיבים",
|
role_heb = {"appellant": "טענות העוררים", "respondent": "טענות המשיבים",
|
||||||
"committee": "עמדת הוועדה המקומית", "permit_applicant": "עמדת מבקשי ההיתר"}
|
"committee": "עמדת הוועדה המקומית", "permit_applicant": "עמדת מבקשי ההיתר"}
|
||||||
claim_num = 0
|
role_order = ["appellant", "committee", "respondent", "permit_applicant"]
|
||||||
|
|
||||||
|
groups: dict[tuple[str, str], list[dict]] = {}
|
||||||
for c in source_claims:
|
for c in source_claims:
|
||||||
if c["party_role"] != current_role:
|
role = c.get("party_role", "") or ""
|
||||||
current_role = c["party_role"]
|
brief = (c.get("source_document", "") or "").strip() if role in SPLIT_PARTIES else ""
|
||||||
lines.append(f"\n### {role_heb.get(current_role, current_role)}")
|
groups.setdefault((role, brief), []).append(c)
|
||||||
|
|
||||||
|
def _sort_key(k: tuple[str, str]) -> tuple[int, str]:
|
||||||
|
role, brief = k
|
||||||
|
idx = role_order.index(role) if role in role_order else len(role_order)
|
||||||
|
return (idx, brief)
|
||||||
|
|
||||||
|
lines: list[str] = []
|
||||||
|
claim_num = 0
|
||||||
|
for role, brief in sorted(groups.keys(), key=_sort_key):
|
||||||
|
header = role_heb.get(role, role or "טענות נוספות")
|
||||||
|
if brief:
|
||||||
|
header = f"{header} — {brief}"
|
||||||
|
lines.append(f"\n### {header}")
|
||||||
|
for c in groups[(role, brief)]:
|
||||||
claim_num += 1
|
claim_num += 1
|
||||||
lines.append(f"טענה #{claim_num}: {c['claim_text'][:400]}")
|
lines.append(f"טענה #{claim_num}: {c['claim_text'][:400]}")
|
||||||
lines.append(f"\n**סה\"כ {claim_num} טענות. ענה על כל טענה מהותית; טענות [bundle] — אגד; טענות [skip] — ציון קצר בלבד.**")
|
lines.append(
|
||||||
|
f"\n**סה\"כ {claim_num} טענות. שמור על ההפרדה בין הצדדים לעיל — "
|
||||||
|
f"לכל צד/כתב-תשובה עמדה נפרדת (אל תמזג משיבים שונים). ענה על כל טענה "
|
||||||
|
f"מהותית; טענות [bundle] — אגד; טענות [skip] — ציון קצר בלבד.**"
|
||||||
|
)
|
||||||
return "\n".join(lines)
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user