Merge pull request #28 from hburaktasyurek/tool-limit-alignment
Tool Routing: align descriptions with runtime behavior and reduce Bedesten request overhead
This commit is contained in:
@@ -313,7 +313,7 @@ API anahtarınızı [openrouter.ai/keys](https://openrouter.ai/keys) adresinden
|
|||||||
<details>
|
<details>
|
||||||
<summary>🛠️ <strong>Kullanılabilir Araçlar (MCP Tools)</strong></summary>
|
<summary>🛠️ <strong>Kullanılabilir Araçlar (MCP Tools)</strong></summary>
|
||||||
|
|
||||||
Bu FastMCP sunucusu **24 temel MCP aracı** + **1 opsiyonel semantik arama aracı** sunar (token verimliliği için optimize edilmiş):
|
Bu FastMCP sunucusu **26 aktif MCP aracı** + **1 opsiyonel semantik arama aracı** sunar (token verimliliği için optimize edilmiş):
|
||||||
|
|
||||||
### **Yargıtay Araçları (Birleşik Bedesten API - Token Optimized)**
|
### **Yargıtay Araçları (Birleşik Bedesten API - Token Optimized)**
|
||||||
*Not: Yargıtay araçları token verimliliği için birleşik Bedesten API'ye entegre edilmiştir*
|
*Not: Yargıtay araçları token verimliliği için birleşik Bedesten API'ye entegre edilmiştir*
|
||||||
@@ -338,8 +338,8 @@ Bu FastMCP sunucusu **24 temel MCP aracı** + **1 opsiyonel semantik arama arac
|
|||||||
8. `get_anayasa_document_unified(document_url, page_number)`: AYM kararlarını birleşik belge getirme - **sayfalanmış Markdown** içeriği
|
8. `get_anayasa_document_unified(document_url, page_number)`: AYM kararlarını birleşik belge getirme - **sayfalanmış Markdown** içeriği
|
||||||
|
|
||||||
### **KİK (Kamu İhale Kurulu) Araçları**
|
### **KİK (Kamu İhale Kurulu) Araçları**
|
||||||
9. `search_kik_decisions(karar_tipi, ...)`: KİK (Kamu İhale Kurulu) kararlarını arar.
|
9. `search_kik_v2_decisions(decision_type, karar_metni, karar_no, basvuran, idare_adi, baslangic_tarihi, bitis_tarihi)`: KİK v2 API ile uyuşmazlık, düzenleyici ve mahkeme kararlarını arar.
|
||||||
10. `get_kik_document_markdown(karar_id, page_number)`: Belirli bir KİK kararını, Base64 ile encode edilmiş `karar_id`'sini kullanarak alır ve **sayfalanmış Markdown** içeriğini getirir.
|
10. `get_kik_v2_document_markdown(gundemMaddesiId)`: Arama sonucundaki `gundemMaddesiId` ile KİK karar metnini Markdown formatında getirir.
|
||||||
### **Rekabet Kurumu Araçları**
|
### **Rekabet Kurumu Araçları**
|
||||||
* `search_rekabet_kurumu_decisions(KararTuru: Literal[...], ...) -> RekabetSearchResult`: Rekabet Kurumu kararlarını arar. `KararTuru` için kullanıcı dostu isimler kullanılır (örn: "Birleşme ve Devralma").
|
* `search_rekabet_kurumu_decisions(KararTuru: Literal[...], ...) -> RekabetSearchResult`: Rekabet Kurumu kararlarını arar. `KararTuru` için kullanıcı dostu isimler kullanılır (örn: "Birleşme ve Devralma").
|
||||||
* `get_rekabet_kurumu_document(karar_id: str, page_number: Optional[int] = 1) -> RekabetDocument`: Belirli bir Rekabet Kurumu kararını `karar_id` ile alır. Kararın PDF formatındaki orijinalinden istenen sayfayı ayıklar ve Markdown formatında döndürür.
|
* `get_rekabet_kurumu_document(karar_id: str, page_number: Optional[int] = 1) -> RekabetDocument`: Belirli bir Rekabet Kurumu kararını `karar_id` ile alır. Kararın PDF formatındaki orijinalinden istenen sayfayı ayıklar ve Markdown formatında döndürür.
|
||||||
@@ -347,16 +347,12 @@ Bu FastMCP sunucusu **24 temel MCP aracı** + **1 opsiyonel semantik arama arac
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
* **Sayıştay Araçları (3 Karar Türü + 8 Daire Filtreleme):**
|
* **Sayıştay Araçları (Birleşik API, 3 Karar Türü + 8 Daire Filtreleme):**
|
||||||
* `search_sayistay_genel_kurul(karar_no, karar_tarih_baslangic, karar_tamami, ...)`: Sayıştay Genel Kurul (yorumlayıcı) kararlarını arar. **Tarih aralığı** (2006-2024) + **İçerik arama** (400 karakter)
|
* `search_sayistay_unified(decision_type, start, length, ...)`: `genel_kurul`, `temyiz_kurulu` veya `daire` kararlarını tek araçla arar. `length` 1-100 aralığındadır.
|
||||||
* `search_sayistay_temyiz_kurulu(ilam_dairesi, kamu_idaresi_turu, temyiz_karar, ...)`: Temyiz Kurulu (itiraz) kararlarını arar. **8 Daire filtreleme** + **Kurum türü** + **Konu sınıflandırması**
|
* `get_sayistay_document_unified(decision_id, decision_type)`: Birleşik arama sonucundaki karar ID'si ve karar türüyle tam metni Markdown formatında getirir.
|
||||||
* `search_sayistay_daire(yargilama_dairesi, web_karar_metni, hesap_yili, ...)`: Daire (ilk derece denetim) kararlarını arar. **8 Daire filtreleme** + **Hesap yılı** + **İçerik arama**
|
|
||||||
* `get_sayistay_genel_kurul_document_markdown(decision_id: str)`: Genel Kurul kararının tam metnini Markdown formatında getirir
|
|
||||||
* `get_sayistay_temyiz_kurulu_document_markdown(decision_id: str)`: Temyiz Kurulu kararının tam metnini Markdown formatında getirir
|
|
||||||
* `get_sayistay_daire_document_markdown(decision_id: str)`: Daire kararının tam metnini Markdown formatında getirir
|
|
||||||
|
|
||||||
* **KVKK Araçları (Brave Search API + Türkçe Arama):**
|
* **KVKK Araçları (Brave Search API + Türkçe Arama):**
|
||||||
* `search_kvkk_decisions(keywords, page, pageSize, ...)`: KVKK (Kişisel Verilerin Korunması Kurulu) kararlarını Brave Search API ile arar. **Türkçe arama** + **Site hedeflemeli** (`site:kvkk.gov.tr "karar özeti"`) + **Sayfalama desteği**
|
* `search_kvkk_decisions(keywords, page)`: KVKK (Kişisel Verilerin Korunması Kurulu) kararlarını Brave Search API ile arar. **Türkçe arama** + **Site hedeflemeli** (`site:kvkk.gov.tr "karar özeti"`) + **Sayfalama desteği**. Sonuç sayısı sunucuda 10 olarak sabitlenmiştir.
|
||||||
* `get_kvkk_document_markdown(decision_url: str, page_number: Optional[int] = 1)`: KVKK kararının tam metnini **sayfalanmış Markdown** formatında getirir (5.000 karakterlik sayfa)
|
* `get_kvkk_document_markdown(decision_url: str, page_number: Optional[int] = 1)`: KVKK kararının tam metnini **sayfalanmış Markdown** formatında getirir (5.000 karakterlik sayfa)
|
||||||
|
|
||||||
### BDDK Araçları
|
### BDDK Araçları
|
||||||
@@ -368,10 +364,15 @@ Bu FastMCP sunucusu **24 temel MCP aracı** + **1 opsiyonel semantik arama arac
|
|||||||
* `get_gib_ozelge_document_markdown(ozelge_id: int, page_number: int = 1)`: Belirli bir özelgenin tam metnini **sayfalanmış Markdown** formatında getirir (5.000 karakterlik sayfa) + **Metadata başlık bloğu** (Başlık, Sayı, Tarih, Kanun, Kaynak URL)
|
* `get_gib_ozelge_document_markdown(ozelge_id: int, page_number: int = 1)`: Belirli bir özelgenin tam metnini **sayfalanmış Markdown** formatında getirir (5.000 karakterlik sayfa) + **Metadata başlık bloğu** (Başlık, Sayı, Tarih, Kanun, Kaynak URL)
|
||||||
|
|
||||||
### Sigorta Tahkim Komisyonu Araçları (Tavily Search API + PDF)
|
### Sigorta Tahkim Komisyonu Araçları (Tavily Search API + PDF)
|
||||||
* `search_sigorta_tahkim_decisions(keywords, page, pageSize)`: Sigorta Tahkim Komisyonu kararlarını Tavily Search API ile arar. **Site hedeflemeli** (`sigortatahkim.org`) + **Sayfalama desteği**
|
* `search_sigorta_tahkim_decisions(keywords, page)`: Sigorta Tahkim Komisyonu kararlarını Tavily Search API ile arar. **Site hedeflemeli** (`sigortatahkim.org`) + **Sayfalama desteği**. Sonuç sayısı sunucuda 10 olarak sabitlenmiştir.
|
||||||
* `get_sigorta_tahkim_document_markdown(issue_number: str, page_number: int)`: Hakem Karar Dergisi sayısının PDF'ini indirip **sayfalanmış Markdown** formatında getirir (5.000 karakterlik sayfa). 64 sayı (2010-2025)
|
* `get_sigorta_tahkim_document_markdown(issue_number: str, page_number: int)`: Hakem Karar Dergisi sayısının PDF'ini indirip **sayfalanmış Markdown** formatında getirir (5.000 karakterlik sayfa). 64 sayı (2010-2025)
|
||||||
* `search_within_sigorta_tahkim_issue(issue_number: str, keyword: str, max_results: int)`: Belirli bir dergi sayısı içindeki kararları anahtar kelime ile arar. **Türkçe İ/I desteği** + **Relevance scoring** + **Excerpt** ile sonuç
|
* `search_within_sigorta_tahkim_issue(issue_number: str, keyword: str, max_results: int)`: Belirli bir dergi sayısı içindeki kararları anahtar kelime ile arar. **Türkçe İ/I desteği** + **Relevance scoring** + **Excerpt** ile sonuç
|
||||||
|
|
||||||
|
### Yardımcı ve Uyumluluk Araçları
|
||||||
|
* `check_government_servers_health()`: Yargı kaynaklarının erişilebilirliğini kontrol eder.
|
||||||
|
* `search(query)`: ChatGPT Deep Research uyumluluğu için Bedesten destekli kaynaklarda arama yapar.
|
||||||
|
* `fetch(id)`: ChatGPT Deep Research uyumluluğu için tek bir Bedesten belge ID'sinin tam metnini getirir.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -387,7 +388,7 @@ Bu FastMCP sunucusu **24 temel MCP aracı** + **1 opsiyonel semantik arama arac
|
|||||||
|
|
||||||
**GENEL İSTATİSTİKLER:**
|
**GENEL İSTATİSTİKLER:**
|
||||||
- **Toplam Mahkeme/Kurum:** 15 farklı hukuki kurum (GİB Özelgeleri ve Sigorta Tahkim Komisyonu dahil)
|
- **Toplam Mahkeme/Kurum:** 15 farklı hukuki kurum (GİB Özelgeleri ve Sigorta Tahkim Komisyonu dahil)
|
||||||
- **Toplam MCP Tool:** 24 temel araç + 1 opsiyonel semantik arama aracı
|
- **Toplam MCP Tool:** 26 aktif araç + 1 opsiyonel semantik arama aracı
|
||||||
- **Daire/Kurul Filtreleme:** 87 farklı seçenek (52 Yargıtay + 27 Danıştay + 8 Sayıştay)
|
- **Daire/Kurul Filtreleme:** 87 farklı seçenek (52 Yargıtay + 27 Danıştay + 8 Sayıştay)
|
||||||
- **Tarih Filtreleme:** Birleşik Bedesten API aracında ISO 8601 formatında tam tarih aralığı desteği
|
- **Tarih Filtreleme:** Birleşik Bedesten API aracında ISO 8601 formatında tam tarih aralığı desteği
|
||||||
- **Kesin Cümle Arama:** Birleşik Bedesten API aracında çift tırnak ile tam cümle arama (`"\"mülkiyet kararı\""` formatı)
|
- **Kesin Cümle Arama:** Birleşik Bedesten API aracında çift tırnak ile tam cümle arama (`"\"mülkiyet kararı\""` formatı)
|
||||||
|
|||||||
+83
-138
@@ -818,7 +818,10 @@ async def get_uyusmazlik_document_markdown_from_url(
|
|||||||
|
|
||||||
# --- Unified MCP Tools for Anayasa Mahkemesi ---
|
# --- Unified MCP Tools for Anayasa Mahkemesi ---
|
||||||
@app.tool(
|
@app.tool(
|
||||||
description="Use this when searching Turkish Constitutional Court decisions. Supports both norm control (legislation review) and individual applications (rights violations).",
|
description=(
|
||||||
|
"Use this when searching Turkish Constitutional Court decision records. Supports norm control decisions "
|
||||||
|
"and individual application decisions. Norm control filters include reviewed norm metadata; results are court decisions."
|
||||||
|
),
|
||||||
annotations={
|
annotations={
|
||||||
"readOnlyHint": True,
|
"readOnlyHint": True,
|
||||||
"openWorldHint": True,
|
"openWorldHint": True,
|
||||||
@@ -1095,7 +1098,11 @@ async def get_rekabet_kurumu_document(
|
|||||||
|
|
||||||
# --- MCP Tools for Bedesten (Unified Search Across All Courts) ---
|
# --- MCP Tools for Bedesten (Unified Search Across All Courts) ---
|
||||||
@app.tool(
|
@app.tool(
|
||||||
description="Use this when searching across multiple Turkish courts in a single query. Supports Yargıtay, Danıştay, Local Courts, Appeals Courts, and KYB.",
|
description=(
|
||||||
|
"Use this for Turkish court decision records from Yargıtay, Danıştay, Local Courts, Appeals Courts, and KYB via Bedesten. "
|
||||||
|
"Prefer narrow court_types over all courts. pageSize is intentionally fixed to 10 results per page. "
|
||||||
|
"Bedesten is upstream rate-limited; avoid parallel repeated calls and wait retry_after seconds after 429 responses."
|
||||||
|
),
|
||||||
annotations={
|
annotations={
|
||||||
"readOnlyHint": True,
|
"readOnlyHint": True,
|
||||||
"openWorldHint": True,
|
"openWorldHint": True,
|
||||||
@@ -1119,7 +1126,7 @@ For best results, use exact phrases with quotes for legal terms."""),
|
|||||||
description="Court types: YARGITAYKARARI, DANISTAYKARAR, YERELHUKUK, ISTINAFHUKUK, KYB"
|
description="Court types: YARGITAYKARARI, DANISTAYKARAR, YERELHUKUK, ISTINAFHUKUK, KYB"
|
||||||
),
|
),
|
||||||
# pageSize: int = Field(10, ge=1, le=10, description="Results per page (1-10)"),
|
# pageSize: int = Field(10, ge=1, le=10, description="Results per page (1-10)"),
|
||||||
pageNumber: int = Field(1, ge=1, description="Page number"),
|
pageNumber: int = Field(1, ge=1, description="Page number. Each page returns 10 results; pageSize is fixed by the server."),
|
||||||
birimAdi: BirimAdiEnum = Field("ALL", description="""
|
birimAdi: BirimAdiEnum = Field("ALL", description="""
|
||||||
Chamber filter (optional). Abbreviated values with Turkish names:
|
Chamber filter (optional). Abbreviated values with Turkish names:
|
||||||
• Yargıtay: H1-H23 (1-23. Hukuk Dairesi), C1-C23 (1-23. Ceza Dairesi), HGK (Hukuk Genel Kurulu), CGK (Ceza Genel Kurulu), BGK (Büyük Genel Kurulu), HBK (Hukuk Daireleri Başkanlar Kurulu), CBK (Ceza Daireleri Başkanlar Kurulu)
|
• Yargıtay: H1-H23 (1-23. Hukuk Dairesi), C1-C23 (1-23. Ceza Dairesi), HGK (Hukuk Genel Kurulu), CGK (Ceza Genel Kurulu), BGK (Büyük Genel Kurulu), HBK (Hukuk Daireleri Başkanlar Kurulu), CBK (Ceza Daireleri Başkanlar Kurulu)
|
||||||
@@ -1231,7 +1238,10 @@ For best results, use exact phrases with quotes for legal terms."""),
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
@app.tool(
|
@app.tool(
|
||||||
description="Use this when retrieving full text of any Bedesten-supported court decision. Returns clean Markdown format.",
|
description=(
|
||||||
|
"Use this when retrieving full text of a Bedesten search result by documentId. "
|
||||||
|
"Counts against the same Bedesten upstream rate limit as search; after 429, wait retry_after seconds before retrying."
|
||||||
|
),
|
||||||
annotations={
|
annotations={
|
||||||
"readOnlyHint": True,
|
"readOnlyHint": True,
|
||||||
"idempotentHint": True
|
"idempotentHint": True
|
||||||
@@ -2187,7 +2197,11 @@ async def get_bddk_document_markdown(
|
|||||||
|
|
||||||
# --- MCP Tools for GİB (Gelir İdaresi Başkanlığı / Revenue Administration) Özelgeler ---
|
# --- MCP Tools for GİB (Gelir İdaresi Başkanlığı / Revenue Administration) Özelgeler ---
|
||||||
@app.tool(
|
@app.tool(
|
||||||
description="Search Turkish GİB özelgeler (Revenue Administration tax rulings) - 18k+ rulings on VAT, income tax, corporate tax, stamp duty interpretations. Supports keyword, date range, and law number filtering.",
|
description=(
|
||||||
|
"Search Turkish GİB özelge records (Revenue Administration tax rulings) - 18k+ rulings on VAT, "
|
||||||
|
"income tax, corporate tax, stamp duty interpretations. kanunNo filters the related law number; "
|
||||||
|
"returned documents are özelge/tax ruling records."
|
||||||
|
),
|
||||||
annotations={
|
annotations={
|
||||||
"readOnlyHint": True,
|
"readOnlyHint": True,
|
||||||
"openWorldHint": True,
|
"openWorldHint": True,
|
||||||
@@ -2197,7 +2211,7 @@ async def get_bddk_document_markdown(
|
|||||||
async def search_gib_ozelge(
|
async def search_gib_ozelge(
|
||||||
keywords: str = Field("", description="Turkish keywords searched in title, kanunNo and description (e.g., 'KDV oranı', 'kurumlar vergisi istisna')"),
|
keywords: str = Field("", description="Turkish keywords searched in title, kanunNo and description (e.g., 'KDV oranı', 'kurumlar vergisi istisna')"),
|
||||||
ozelgeNo: str = Field("", description="Exact özelge reference number (e.g., 'E-40247694-130-15524')"),
|
ozelgeNo: str = Field("", description="Exact özelge reference number (e.g., 'E-40247694-130-15524')"),
|
||||||
kanunNo: str = Field("", description="Law number filter, e.g. '3065' for KDV, '193' for Gelir Vergisi"),
|
kanunNo: str = Field("", description="Related law number filter for özelge records, e.g. '3065' for KDV, '193' for Gelir Vergisi"),
|
||||||
ozelgeStartDate: str = Field("", description="Start date YYYY-MM-DD (e.g., '2024-01-01') or full ISO 8601"),
|
ozelgeStartDate: str = Field("", description="Start date YYYY-MM-DD (e.g., '2024-01-01') or full ISO 8601"),
|
||||||
ozelgeEndDate: str = Field("", description="End date YYYY-MM-DD (e.g., '2024-12-31') or full ISO 8601"),
|
ozelgeEndDate: str = Field("", description="End date YYYY-MM-DD (e.g., '2024-12-31') or full ISO 8601"),
|
||||||
page: int = Field(1, ge=1, description="Page number (1-indexed)"),
|
page: int = Field(1, ge=1, description="Page number (1-indexed)"),
|
||||||
@@ -2429,54 +2443,42 @@ async def search_within_sigorta_tahkim_issue(
|
|||||||
|
|
||||||
# --- ChatGPT Deep Research Compatible Tools ---
|
# --- ChatGPT Deep Research Compatible Tools ---
|
||||||
|
|
||||||
def get_preview_text(markdown_content: str, skip_chars: int = 100, preview_chars: int = 200) -> str:
|
def build_bedesten_title(decision: Any, court_name: str) -> str:
|
||||||
"""
|
"""Build a compact title from Bedesten search metadata without fetching the document."""
|
||||||
Extract a preview of document text by skipping headers and showing meaningful content.
|
title_parts = [court_name]
|
||||||
|
if getattr(decision, "birimAdi", None):
|
||||||
Args:
|
title_parts.append(str(decision.birimAdi))
|
||||||
markdown_content: Full document content in markdown format
|
if getattr(decision, "esasNo", None):
|
||||||
skip_chars: Number of characters to skip from the beginning (default: 100)
|
title_parts.append(f"Esas: {decision.esasNo}")
|
||||||
preview_chars: Number of characters to show in preview (default: 200)
|
if getattr(decision, "kararNo", None):
|
||||||
|
title_parts.append(f"Karar: {decision.kararNo}")
|
||||||
Returns:
|
if getattr(decision, "kararTarihiStr", None):
|
||||||
Preview text suitable for ChatGPT Deep Research
|
title_parts.append(f"Tarih: {decision.kararTarihiStr}")
|
||||||
"""
|
return " - ".join(title_parts) if title_parts else f"{court_name} - Document {decision.documentId}"
|
||||||
if not markdown_content:
|
|
||||||
return ""
|
|
||||||
|
def build_bedesten_metadata_preview(decision: Any, court_name: str) -> str:
|
||||||
# Remove common markdown artifacts and clean up
|
"""Return Deep Research preview text using only search-result metadata."""
|
||||||
cleaned_content = markdown_content.strip()
|
preview_parts = [f"Kaynak: {court_name}"]
|
||||||
|
if getattr(decision, "birimAdi", None):
|
||||||
# Skip the first N characters (usually headers, metadata)
|
preview_parts.append(f"Daire/Kurul: {decision.birimAdi}")
|
||||||
if len(cleaned_content) > skip_chars:
|
if getattr(decision, "esasNo", None):
|
||||||
content_start = cleaned_content[skip_chars:]
|
preview_parts.append(f"Esas No: {decision.esasNo}")
|
||||||
else:
|
if getattr(decision, "kararNo", None):
|
||||||
content_start = cleaned_content
|
preview_parts.append(f"Karar No: {decision.kararNo}")
|
||||||
|
if getattr(decision, "kararTarihiStr", None):
|
||||||
# Get the next N characters for preview
|
preview_parts.append(f"Karar Tarihi: {decision.kararTarihiStr}")
|
||||||
if len(content_start) > preview_chars:
|
preview_parts.append("Tam metin için fetch aracını bu sonucun id değeriyle çağırın.")
|
||||||
preview = content_start[:preview_chars]
|
return ". ".join(preview_parts)
|
||||||
else:
|
|
||||||
preview = content_start
|
|
||||||
|
|
||||||
# Clean up the preview - remove incomplete sentences at the end
|
|
||||||
preview = preview.strip()
|
|
||||||
|
|
||||||
# If preview ends mid-sentence, try to end at last complete sentence
|
|
||||||
if preview and not preview.endswith('.'):
|
|
||||||
last_period = preview.rfind('.')
|
|
||||||
if last_period > 50: # Only if there's a reasonable sentence
|
|
||||||
preview = preview[:last_period + 1]
|
|
||||||
|
|
||||||
# Add ellipsis if content was truncated
|
|
||||||
if len(content_start) > preview_chars:
|
|
||||||
preview += "..."
|
|
||||||
|
|
||||||
return preview.strip()
|
|
||||||
|
|
||||||
|
|
||||||
@app.tool(
|
@app.tool(
|
||||||
description="Only for ChatGPT Deep Research. Use this when searching across all Turkish legal databases in a single query. Returns results in ChatGPT Deep Research compatible format (id, title, text, url). Supports: +term (must have), -term (exclude), \"exact phrase\", term1 OR term2. Use Turkish keywords for best results.",
|
description=(
|
||||||
|
"Only for ChatGPT Deep Research. Searches Bedesten-supported Turkish court databases and returns "
|
||||||
|
"OpenAI Deep Research compatible results (id, title, text, url). For regular MCP use, prefer "
|
||||||
|
"search_bedesten_unified. This tool does not fetch document bodies during search so one query stays "
|
||||||
|
"within Bedesten upstream rate limits; call fetch only for selected result IDs."
|
||||||
|
),
|
||||||
annotations={
|
annotations={
|
||||||
"readOnlyHint": True,
|
"readOnlyHint": True,
|
||||||
"openWorldHint": True,
|
"openWorldHint": True,
|
||||||
@@ -2506,21 +2508,21 @@ async def search(
|
|||||||
try:
|
try:
|
||||||
# Search all court types via unified Bedesten API
|
# Search all court types via unified Bedesten API
|
||||||
court_types = [
|
court_types = [
|
||||||
("YARGITAYKARARI", "Yargıtay", "yargitay_bedesten"),
|
("YARGITAYKARARI", "Yargıtay"),
|
||||||
("DANISTAYKARAR", "Danıştay", "danistay_bedesten"),
|
("DANISTAYKARAR", "Danıştay"),
|
||||||
("YERELHUKUK", "Yerel Hukuk Mahkemesi", "yerel_hukuk_bedesten"),
|
("YERELHUKUK", "Yerel Hukuk Mahkemesi"),
|
||||||
("ISTINAFHUKUK", "İstinaf Hukuk Mahkemesi", "istinaf_hukuk_bedesten"),
|
("ISTINAFHUKUK", "İstinaf Hukuk Mahkemesi"),
|
||||||
("KYB", "Kanun Yararına Bozma", "kyb_bedesten")
|
("KYB", "Kanun Yararına Bozma")
|
||||||
]
|
]
|
||||||
|
|
||||||
for item_type, court_name, id_prefix in court_types:
|
for item_type, court_name in court_types:
|
||||||
try:
|
try:
|
||||||
search_results = await bedesten_client_instance.search_documents(
|
search_results = await bedesten_client_instance.search_documents(
|
||||||
BedestenSearchRequest(
|
BedestenSearchRequest(
|
||||||
data=BedestenSearchData(
|
data=BedestenSearchData(
|
||||||
phrase=query, # Use query as-is to support both regular and exact phrase searches
|
phrase=query, # Use query as-is to support both regular and exact phrase searches
|
||||||
itemTypeList=[item_type],
|
itemTypeList=[item_type],
|
||||||
pageSize=10,
|
pageSize=5,
|
||||||
pageNumber=1
|
pageNumber=1
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -2531,49 +2533,15 @@ async def search(
|
|||||||
logger.warning(f"No data returned from Bedesten API for {court_name}")
|
logger.warning(f"No data returned from Bedesten API for {court_name}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Add results from this court type (limit to top 5 per court)
|
# Add results from metadata only. Fetching every document preview
|
||||||
|
# would turn one Deep Research search into ~30 Bedesten requests.
|
||||||
for decision in search_results.data.emsalKararList[:5]:
|
for decision in search_results.data.emsalKararList[:5]:
|
||||||
# For ChatGPT Deep Research, fetch document content for preview
|
results.append({
|
||||||
try:
|
"id": decision.documentId,
|
||||||
# Fetch document content for preview
|
"title": build_bedesten_title(decision, court_name),
|
||||||
doc = await bedesten_client_instance.get_document_as_markdown(decision.documentId)
|
"text": build_bedesten_metadata_preview(decision, court_name),
|
||||||
|
"url": f"https://mevzuat.adalet.gov.tr/ictihat/{decision.documentId}"
|
||||||
# Generate preview text (skip first 100 chars, show next 200)
|
})
|
||||||
preview_text = get_preview_text(doc.markdown_content, skip_chars=100, preview_chars=200)
|
|
||||||
|
|
||||||
# Build title from metadata
|
|
||||||
title_parts = []
|
|
||||||
if decision.birimAdi:
|
|
||||||
title_parts.append(decision.birimAdi)
|
|
||||||
if decision.esasNo:
|
|
||||||
title_parts.append(f"Esas: {decision.esasNo}")
|
|
||||||
if decision.kararNo:
|
|
||||||
title_parts.append(f"Karar: {decision.kararNo}")
|
|
||||||
if decision.kararTarihiStr:
|
|
||||||
title_parts.append(f"Tarih: {decision.kararTarihiStr}")
|
|
||||||
|
|
||||||
if title_parts:
|
|
||||||
title = " - ".join(title_parts)
|
|
||||||
else:
|
|
||||||
title = f"{court_name} - Document {decision.documentId}"
|
|
||||||
|
|
||||||
# Add to results in OpenAI format
|
|
||||||
results.append({
|
|
||||||
"id": decision.documentId,
|
|
||||||
"title": title,
|
|
||||||
"text": preview_text,
|
|
||||||
"url": f"https://mevzuat.adalet.gov.tr/ictihat/{decision.documentId}"
|
|
||||||
})
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.warning(f"Could not fetch preview for document {decision.documentId}: {e}")
|
|
||||||
# Add minimal result without preview
|
|
||||||
results.append({
|
|
||||||
"id": decision.documentId,
|
|
||||||
"title": f"{court_name} - Document {decision.documentId}",
|
|
||||||
"text": "Document preview not available",
|
|
||||||
"url": f"https://mevzuat.adalet.gov.tr/ictihat/{decision.documentId}"
|
|
||||||
})
|
|
||||||
|
|
||||||
if search_results.data:
|
if search_results.data:
|
||||||
logger.info(f"Found {len(search_results.data.emsalKararList)} results from {court_name}")
|
logger.info(f"Found {len(search_results.data.emsalKararList)} results from {court_name}")
|
||||||
@@ -2592,7 +2560,7 @@ async def search(
|
|||||||
# Danıştay Official API - use search_danistay_by_keyword instead
|
# Danıştay Official API - use search_danistay_by_keyword instead
|
||||||
# Constitutional Court - use search_anayasa_norm_denetimi_decisions instead
|
# Constitutional Court - use search_anayasa_norm_denetimi_decisions instead
|
||||||
# Competition Authority - use search_rekabet_kurumu_decisions instead
|
# Competition Authority - use search_rekabet_kurumu_decisions instead
|
||||||
# Public Procurement Authority - use search_kik_decisions instead
|
# Public Procurement Authority - use search_kik_v2_decisions instead
|
||||||
# Court of Accounts - use search_sayistay_* tools instead
|
# Court of Accounts - use search_sayistay_* tools instead
|
||||||
# UYAP Emsal - use search_emsal_detailed_decisions instead
|
# UYAP Emsal - use search_emsal_detailed_decisions instead
|
||||||
# Jurisdictional Disputes Court - use search_uyusmazlik_decisions instead
|
# Jurisdictional Disputes Court - use search_uyusmazlik_decisions instead
|
||||||
@@ -2629,7 +2597,11 @@ async def search(
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
@app.tool(
|
@app.tool(
|
||||||
description="Only for ChatGPT Deep Research. Use this when retrieving a Turkish legal document by ID. Returns full document in ChatGPT Deep Research compatible format (id, title, text, url, metadata).",
|
description=(
|
||||||
|
"Only for ChatGPT Deep Research. Retrieves one Turkish legal document by numeric Bedesten ID. "
|
||||||
|
"For regular MCP use, prefer get_bedesten_document_markdown. This performs one Bedesten document request "
|
||||||
|
"and avoids an extra metadata lookup to respect upstream rate limits."
|
||||||
|
),
|
||||||
annotations={
|
annotations={
|
||||||
"readOnlyHint": True,
|
"readOnlyHint": True,
|
||||||
"openWorldHint": False, # Retrieves specific documents, not exploring
|
"openWorldHint": False, # Retrieves specific documents, not exploring
|
||||||
@@ -2664,41 +2636,13 @@ async def fetch(
|
|||||||
# Use the numeric ID directly with Bedesten API
|
# Use the numeric ID directly with Bedesten API
|
||||||
doc = await bedesten_client_instance.get_document_as_markdown(id)
|
doc = await bedesten_client_instance.get_document_as_markdown(id)
|
||||||
|
|
||||||
# Try to get additional metadata by searching for this specific document
|
|
||||||
title = f"Turkish Legal Document {id}"
|
title = f"Turkish Legal Document {id}"
|
||||||
try:
|
if doc.markdown_content:
|
||||||
# Quick search to get metadata for better title
|
for line in doc.markdown_content.splitlines():
|
||||||
search_results = await bedesten_client_instance.search_documents(
|
cleaned_line = line.strip().lstrip("#").strip()
|
||||||
BedestenSearchRequest(
|
if cleaned_line:
|
||||||
data=BedestenSearchData(
|
title = cleaned_line[:160]
|
||||||
phrase=id, # Search by document ID
|
break
|
||||||
itemTypeList=["YARGITAYKARARI", "DANISTAYKARAR", "YERELHUKUK", "ISTINAFHUKUK", "KYB"],
|
|
||||||
pageSize=1,
|
|
||||||
pageNumber=1
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if search_results.data and search_results.data.emsalKararList:
|
|
||||||
decision = search_results.data.emsalKararList[0]
|
|
||||||
if decision.documentId == id:
|
|
||||||
# Build a proper title from metadata
|
|
||||||
title_parts = []
|
|
||||||
if decision.birimAdi:
|
|
||||||
title_parts.append(decision.birimAdi)
|
|
||||||
if decision.esasNo:
|
|
||||||
title_parts.append(f"Esas: {decision.esasNo}")
|
|
||||||
if decision.kararNo:
|
|
||||||
title_parts.append(f"Karar: {decision.kararNo}")
|
|
||||||
if decision.kararTarihiStr:
|
|
||||||
title_parts.append(f"Tarih: {decision.kararTarihiStr}")
|
|
||||||
|
|
||||||
if title_parts:
|
|
||||||
title = " - ".join(title_parts)
|
|
||||||
else:
|
|
||||||
title = f"Turkish Legal Decision {id}"
|
|
||||||
except Exception as e:
|
|
||||||
logger.warning(f"Could not fetch metadata for document {id}: {e}")
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"id": id,
|
"id": id,
|
||||||
@@ -2711,7 +2655,8 @@ async def fetch(
|
|||||||
"source_url": doc.source_url,
|
"source_url": doc.source_url,
|
||||||
"mime_type": doc.mime_type,
|
"mime_type": doc.mime_type,
|
||||||
"api_source": "Bedesten Unified API",
|
"api_source": "Bedesten Unified API",
|
||||||
"chatgpt_deep_research": True
|
"chatgpt_deep_research": True,
|
||||||
|
"rate_limit_optimized": True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2775,4 +2720,4 @@ def main():
|
|||||||
logger.info(f"{app.name} server has shut down.")
|
logger.info(f"{app.name} server has shut down.")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
Reference in New Issue
Block a user