סוגר את הלולאה — יומון שמצביע על פס"ד בית-משפט שלא בקורפוס מזניק אחזור אוטומטי, וקושר את היומון חזרה אחרי הקליטה (INV-DIG3 + INV-CF2). - digest_library.try_autolink: בכשל-קישור, אם הציטוט מסווג כפס"ד-בימ"ש (supreme/admin) → _enqueue_court_fetch יוצר court_fetch_jobs(pending); ועדת-ערר (skip) לא מוזנק. never-raises (לא שובר קליטת-יומון). - orchestrator.drain_pending(limit): מנקז pending/failed סדרתי (cooldown, INV-CF4), fetch+ingest לכל אחד; בהצלחה מקשר את היומון ל-case_law שנקלט. - כלי-MCP court_fetch_drain + רישום ב-server.py. - X13 spec: עודכן (הפער ב-INV-CF2 סומן כמתוקן). נבדק מול ה-DB: עת"מ 46111-12-22 → job tier=admin pending digest-linked; ערר 1110/20 → לא מוזנק. כלי מקומי בלבד (ingest = claude CLI). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
67 lines
3.5 KiB
Python
67 lines
3.5 KiB
Python
"""MCP tools for the X13 court-verdict auto-fetch subsystem.
|
||
|
||
- ``court_verdict_fetch`` — classify a citation, fetch the verdict from the
|
||
matching public source (Supreme portal / נט המשפט), and ingest it into the
|
||
precedent library via the canonical pipeline. The standalone entry point
|
||
(also driven automatically from digest auto-link, see X12/X13).
|
||
- ``court_fetch_status`` — inspect the fetch-job queue (pending/failed/manual).
|
||
|
||
Local-only: ``court_verdict_fetch`` runs the ingest pipeline, which drives
|
||
halacha extraction via the local ``claude`` CLI — same constraint as
|
||
``precedent_process_pending``. Invoking it from the container will fail.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from legal_mcp.services import court_fetch_orchestrator as orch
|
||
from legal_mcp.services import db
|
||
from legal_mcp.tools.envelope import err as _err, ok as _ok
|
||
|
||
|
||
async def court_verdict_fetch(citation: str) -> str:
|
||
"""אחזור אוטומטי של פסק-דין בית-משפט וקליטה לקורפוס.
|
||
|
||
מקבל ציטוט (למשל 'עת"מ 46111-12-22' או 'עע"מ 1234/22'), מסווג את הערכאה,
|
||
מוריד את הפסק מהמקור הציבורי המתאים, וקולט אותו דרך צינור-הקליטה הקנוני.
|
||
ערר/בל"מ (ועדת-ערר) אינם ניתנים לאחזור ציבורי ויסומנו כפער.
|
||
"""
|
||
if not (citation or "").strip():
|
||
return _err("citation is required")
|
||
try:
|
||
result = await orch.fetch_and_ingest(citation.strip())
|
||
except Exception as e: # noqa: BLE001 — surfaced, not swallowed (INV-CF2)
|
||
return _err(f"אחזור נכשל: {e}")
|
||
|
||
status = result.get("status")
|
||
if status in ("done", "already_done"):
|
||
return _ok(result, message="הפסק נקלט לקורפוס")
|
||
if status == "skipped":
|
||
return _ok(result, message="ועדת-ערר — לא ניתן לאחזור ציבורי (סומן כפער)")
|
||
if status in ("manual", "awaiting_manual"):
|
||
return _ok(result, message="האחזור האוטונומי נכשל — הוסלם להורדה ידנית")
|
||
if status == "unrecognized":
|
||
return _err("הציטוט לא זוהה כמספר-תיק תקין")
|
||
return _ok(result, message=f"סטטוס: {status}")
|
||
|
||
|
||
async def court_fetch_status(case_number: str = "", status_filter: str = "") -> str:
|
||
"""סטטוס תור-האחזור. case_number לפריט יחיד, או status_filter לסינון רשימה."""
|
||
if case_number.strip():
|
||
from legal_mcp.services.court_citation import normalize_case_number
|
||
job = await db.court_fetch_job_get(normalize_case_number(case_number))
|
||
if not job:
|
||
return _ok({"job": None}, message="אין job עבור תיק זה")
|
||
return _ok({"job": job})
|
||
jobs = await db.court_fetch_job_list(status=status_filter.strip() or None)
|
||
return _ok({"jobs": jobs, "count": len(jobs)})
|
||
|
||
|
||
async def court_fetch_drain(limit: int = 10) -> str:
|
||
"""ריקון תור-האחזור: מוריד וקולט את ה-jobs הממתינים (pending/failed) שהיומונים
|
||
מילאו, וקושר כל פסק שנקלט חזרה ליומון-המקור. סדרתי. כלי מקומי בלבד."""
|
||
try:
|
||
result = await orch.drain_pending(limit=max(1, min(int(limit or 10), 50)))
|
||
except Exception as e: # noqa: BLE001
|
||
return _err(f"ריקון התור נכשל: {e}")
|
||
return _ok(result, message=f"עובדו {result.get('processed', 0)}, נקלטו {result.get('done', 0)}")
|