feat(mcp): FU-14 GAP-48 פרוסה 1 — envelope אחיד (SSoT) + משפחת-חיפוש
INV-TOOL1: כלי-ה-MCP החזירו 3 מוסכמות סותרות (raw payload / {error} /
{status,message} אד-הוק) + 5 עותקי _ok/_err משוכפלים. נוצר tools/envelope.py
כמקור-אמת יחיד: ok/empty/err → {status,data,message}, כש-status מבחין
מפורשות הצלחה/ריק/שגיאה.
פרוסה 1 ממירה את משפחת-החיפוש (search_decisions, search_case_documents,
find_similar_cases, search_internal_decisions). web/app.py מפרק את המעטפת
דרך envelope_unwrap כדי לשמר את חוזה-ה-UI↔API (X6) ללא-שינוי — תשובת ה-HTTP
זהה (list על hits, {"message"} על ריק/שגיאה). טסט test_search_domain_scope
עודכן לחוזה החדש (5/5 עוברים).
החלטה: הדרגתי לפי-משפחה ולא big-bang. מפת-צרכנים: server.py pass-through,
web-ui מבודד (/api/*), רק 17 כלים נצרכים ישירות מ-app.py → סיכון מינימלי
לסוכנים החיים. ~73 כלים נותרו לפרוסות הבאות.
Invariants: מקדם INV-TOOL1 (envelope עקבי) + G2 (SSoT, ביטול כפילות _ok/_err).
לא נוגע ב-G1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,7 @@ import httpx
|
||||
from legal_mcp import config
|
||||
from legal_mcp.services import chunker, db, embeddings, extractor, git_sync, metrics as metrics_service, processor, proofreader, research_md
|
||||
from legal_mcp.tools import cases as cases_tools, search as search_tools, workflow as workflow_tools, drafting as drafting_tools, precedents as precedents_tools
|
||||
from legal_mcp.tools.envelope import envelope_unwrap
|
||||
|
||||
# Import integration clients (same directory)
|
||||
_web_dir = Path(__file__).resolve().parent
|
||||
@@ -2095,7 +2096,9 @@ async def api_search(query: str, limit: int = 10, section_type: str = ""):
|
||||
"""Semantic search across decisions and documents."""
|
||||
result = await search_tools.search_decisions(query, limit, section_type)
|
||||
try:
|
||||
return json.loads(result)
|
||||
# GAP-48: tool now returns the {status,data,message} envelope; unwrap it
|
||||
# to preserve the legacy API shape (list on hits, {"message"} otherwise).
|
||||
return envelope_unwrap(json.loads(result))
|
||||
except json.JSONDecodeError:
|
||||
return {"message": result}
|
||||
|
||||
@@ -2105,7 +2108,8 @@ async def api_case_search(case_number: str, query: str, limit: int = 10):
|
||||
"""Semantic search within a specific case's documents."""
|
||||
result = await search_tools.search_case_documents(case_number, query, limit)
|
||||
try:
|
||||
return json.loads(result)
|
||||
# GAP-48: unwrap the tool envelope, keep the legacy API shape.
|
||||
return envelope_unwrap(json.loads(result))
|
||||
except json.JSONDecodeError:
|
||||
return {"message": result}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user