unify sayıştay tools
This commit is contained in:
+178
-152
@@ -299,9 +299,12 @@ from sayistay_mcp_module.models import (
|
|||||||
GenelKurulSearchRequest, GenelKurulSearchResponse,
|
GenelKurulSearchRequest, GenelKurulSearchResponse,
|
||||||
TemyizKuruluSearchRequest, TemyizKuruluSearchResponse,
|
TemyizKuruluSearchRequest, TemyizKuruluSearchResponse,
|
||||||
DaireSearchRequest, DaireSearchResponse,
|
DaireSearchRequest, DaireSearchResponse,
|
||||||
SayistayDocumentMarkdown
|
SayistayDocumentMarkdown,
|
||||||
|
SayistayUnifiedSearchRequest, SayistayUnifiedSearchResult,
|
||||||
|
SayistayUnifiedDocumentMarkdown, SayistayDecisionTypeEnum
|
||||||
)
|
)
|
||||||
from sayistay_mcp_module.enums import DaireEnum, KamuIdaresiTuruEnum, WebKararKonusuEnum
|
from sayistay_mcp_module.enums import DaireEnum, KamuIdaresiTuruEnum, WebKararKonusuEnum
|
||||||
|
from sayistay_mcp_module.unified_client import SayistayUnifiedClient
|
||||||
|
|
||||||
# KVKK Module Imports
|
# KVKK Module Imports
|
||||||
from kvkk_mcp_module.client import KvkkApiClient
|
from kvkk_mcp_module.client import KvkkApiClient
|
||||||
@@ -1055,6 +1058,7 @@ kik_client_instance = KikApiClient()
|
|||||||
rekabet_client_instance = RekabetKurumuApiClient()
|
rekabet_client_instance = RekabetKurumuApiClient()
|
||||||
bedesten_client_instance = BedestenApiClient()
|
bedesten_client_instance = BedestenApiClient()
|
||||||
sayistay_client_instance = SayistayApiClient()
|
sayistay_client_instance = SayistayApiClient()
|
||||||
|
sayistay_unified_client_instance = SayistayUnifiedClient()
|
||||||
kvkk_client_instance = KvkkApiClient()
|
kvkk_client_instance = KvkkApiClient()
|
||||||
|
|
||||||
|
|
||||||
@@ -1843,194 +1847,215 @@ async def get_bedesten_document_markdown(
|
|||||||
|
|
||||||
# --- MCP Tools for Sayıştay (Turkish Court of Accounts) ---
|
# --- MCP Tools for Sayıştay (Turkish Court of Accounts) ---
|
||||||
|
|
||||||
@app.tool(
|
# DEACTIVATED TOOL - Use search_sayistay_unified instead
|
||||||
description="Search Sayıştay Genel Kurul decisions for audit and accountability regulations",
|
# @app.tool(
|
||||||
annotations={
|
# description="Search Sayıştay Genel Kurul decisions for audit and accountability regulations",
|
||||||
"readOnlyHint": True,
|
# annotations={
|
||||||
"openWorldHint": True,
|
# "readOnlyHint": True,
|
||||||
"idempotentHint": True
|
# "openWorldHint": True,
|
||||||
}
|
# "idempotentHint": True
|
||||||
)
|
# }
|
||||||
async def search_sayistay_genel_kurul(
|
# )
|
||||||
karar_no: str = Field("", description="Decision number to search for (e.g., '5415')"),
|
# async def search_sayistay_genel_kurul(
|
||||||
karar_ek: str = Field("", description="Decision appendix number (max 99, e.g., '1')"),
|
# karar_no: str = Field("", description="Decision number to search for (e.g., '5415')"),
|
||||||
karar_tarih_baslangic: str = Field("", description="Start date (DD.MM.YYYY)"),
|
# karar_ek: str = Field("", description="Decision appendix number (max 99, e.g., '1')"),
|
||||||
karar_tarih_bitis: str = Field("", description="End date (DD.MM.YYYY)"),
|
# karar_tarih_baslangic: str = Field("", description="Start date (DD.MM.YYYY)"),
|
||||||
karar_tamami: str = Field("", description="Full text search"),
|
# karar_tarih_bitis: str = Field("", description="End date (DD.MM.YYYY)"),
|
||||||
start: int = Field(0, description="Starting record for pagination (0-based)"),
|
# karar_tamami: str = Field("", description="Full text search"),
|
||||||
length: int = Field(10, description="Number of records per page (1-100)")
|
# start: int = Field(0, description="Starting record for pagination (0-based)"),
|
||||||
) -> GenelKurulSearchResponse:
|
# length: int = Field(10, description="Number of records per page (1-100)")
|
||||||
"""Search Sayıştay General Assembly decisions."""
|
# ) -> GenelKurulSearchResponse:
|
||||||
logger.info(f"Tool 'search_sayistay_genel_kurul' called with params: karar_no={karar_no}, karar_ek={karar_ek}, date_range={karar_tarih_baslangic}-{karar_tarih_bitis}, content={karar_tamami}")
|
# """Search Sayıştay General Assembly decisions."""
|
||||||
|
# raise ValueError("This tool is deactivated. Use search_sayistay_unified instead.")
|
||||||
try:
|
|
||||||
search_request = GenelKurulSearchRequest(
|
# DEACTIVATED TOOL - Use search_sayistay_unified instead
|
||||||
karar_no=karar_no,
|
# @app.tool(
|
||||||
karar_ek=karar_ek,
|
# description="Search Sayıştay Temyiz Kurulu decisions with chamber filtering and comprehensive criteria",
|
||||||
karar_tarih_baslangic=karar_tarih_baslangic,
|
# annotations={
|
||||||
karar_tarih_bitis=karar_tarih_bitis,
|
# "readOnlyHint": True,
|
||||||
karar_tamami=karar_tamami,
|
# "openWorldHint": True,
|
||||||
start=start,
|
# "idempotentHint": True
|
||||||
length=length
|
# }
|
||||||
)
|
# )
|
||||||
return await sayistay_client_instance.search_genel_kurul_decisions(search_request)
|
# async def search_sayistay_temyiz_kurulu(
|
||||||
except Exception as e:
|
# ilam_dairesi: DaireEnum = Field("ALL", description="Audit chamber selection"),
|
||||||
logger.exception("Error in tool 'search_sayistay_genel_kurul'")
|
# yili: str = Field("", description="Year (YYYY)"),
|
||||||
raise
|
# karar_tarih_baslangic: str = Field("", description="Start date (DD.MM.YYYY)"),
|
||||||
|
# karar_tarih_bitis: str = Field("", description="End date (DD.MM.YYYY)"),
|
||||||
|
# kamu_idaresi_turu: KamuIdaresiTuruEnum = Field("ALL", description="Public admin type"),
|
||||||
|
# ilam_no: str = Field("", description="Audit report number (İlam No, max 50 chars)"),
|
||||||
|
# dosya_no: str = Field("", description="File number for the case"),
|
||||||
|
# temyiz_tutanak_no: str = Field("", description="Appeals board meeting minutes number"),
|
||||||
|
# temyiz_karar: str = Field("", description="Appeals decision text"),
|
||||||
|
# web_karar_konusu: WebKararKonusuEnum = Field("ALL", description="Decision subject"),
|
||||||
|
# start: int = Field(0, description="Starting record for pagination (0-based)"),
|
||||||
|
# length: int = Field(10, description="Number of records per page (1-100)")
|
||||||
|
# ) -> TemyizKuruluSearchResponse:
|
||||||
|
# """Search Sayıştay Appeals Board decisions."""
|
||||||
|
# raise ValueError("This tool is deactivated. Use search_sayistay_unified instead.")
|
||||||
|
|
||||||
|
# DEACTIVATED TOOL - Use search_sayistay_unified instead
|
||||||
|
# @app.tool(
|
||||||
|
# description="Search Sayıştay Daire decisions with chamber filtering and subject categorization",
|
||||||
|
# annotations={
|
||||||
|
# "readOnlyHint": True,
|
||||||
|
# "openWorldHint": True,
|
||||||
|
# "idempotentHint": True
|
||||||
|
# }
|
||||||
|
# )
|
||||||
|
# async def search_sayistay_daire(
|
||||||
|
# yargilama_dairesi: DaireEnum = Field("ALL", description="Chamber selection"),
|
||||||
|
# karar_tarih_baslangic: str = Field("", description="Start date (DD.MM.YYYY)"),
|
||||||
|
# karar_tarih_bitis: str = Field("", description="End date (DD.MM.YYYY)"),
|
||||||
|
# ilam_no: str = Field("", description="Audit report number (İlam No, max 50 chars)"),
|
||||||
|
# kamu_idaresi_turu: KamuIdaresiTuruEnum = Field("ALL", description="Public admin type"),
|
||||||
|
# hesap_yili: str = Field("", description="Fiscal year"),
|
||||||
|
# web_karar_konusu: WebKararKonusuEnum = Field("ALL", description="Decision subject"),
|
||||||
|
# web_karar_metni: str = Field("", description="Decision text search"),
|
||||||
|
# start: int = Field(0, description="Starting record for pagination (0-based)"),
|
||||||
|
# length: int = Field(10, description="Number of records per page (1-100)")
|
||||||
|
# ) -> DaireSearchResponse:
|
||||||
|
# """Search Sayıştay Chamber decisions."""
|
||||||
|
# raise ValueError("This tool is deactivated. Use search_sayistay_unified instead.")
|
||||||
|
|
||||||
|
# DEACTIVATED TOOL - Use get_sayistay_document_unified instead
|
||||||
|
# @app.tool(
|
||||||
|
# description="Get Sayıştay Genel Kurul decision document in Markdown format",
|
||||||
|
# annotations={
|
||||||
|
# "readOnlyHint": True,
|
||||||
|
# "openWorldHint": False,
|
||||||
|
# "idempotentHint": True
|
||||||
|
# }
|
||||||
|
# )
|
||||||
|
# async def get_sayistay_genel_kurul_document_markdown(
|
||||||
|
# decision_id: str = Field(..., description="Decision ID from search_sayistay_genel_kurul results")
|
||||||
|
# ) -> SayistayDocumentMarkdown:
|
||||||
|
# """Get Sayıştay General Assembly decision as Markdown."""
|
||||||
|
# raise ValueError("This tool is deactivated. Use get_sayistay_document_unified instead.")
|
||||||
|
|
||||||
|
# DEACTIVATED TOOL - Use get_sayistay_document_unified instead
|
||||||
|
# @app.tool(
|
||||||
|
# description="Get Sayıştay Temyiz Kurulu decision document in Markdown format",
|
||||||
|
# annotations={
|
||||||
|
# "readOnlyHint": True,
|
||||||
|
# "openWorldHint": False,
|
||||||
|
# "idempotentHint": True
|
||||||
|
# }
|
||||||
|
# )
|
||||||
|
# async def get_sayistay_temyiz_kurulu_document_markdown(
|
||||||
|
# decision_id: str = Field(..., description="Decision ID from search_sayistay_temyiz_kurulu results")
|
||||||
|
# ) -> SayistayDocumentMarkdown:
|
||||||
|
# """Get Sayıştay Appeals Board decision as Markdown."""
|
||||||
|
# raise ValueError("This tool is deactivated. Use get_sayistay_document_unified instead.")
|
||||||
|
|
||||||
|
# DEACTIVATED TOOL - Use get_sayistay_document_unified instead
|
||||||
|
# @app.tool(
|
||||||
|
# description="Get Sayıştay Daire decision document in Markdown format",
|
||||||
|
# annotations={
|
||||||
|
# "readOnlyHint": True,
|
||||||
|
# "openWorldHint": False,
|
||||||
|
# "idempotentHint": True
|
||||||
|
# }
|
||||||
|
# )
|
||||||
|
# async def get_sayistay_daire_document_markdown(
|
||||||
|
# decision_id: str = Field(..., description="Decision ID from search_sayistay_daire results")
|
||||||
|
# ) -> SayistayDocumentMarkdown:
|
||||||
|
# """Get Sayıştay Chamber decision as Markdown."""
|
||||||
|
# raise ValueError("This tool is deactivated. Use get_sayistay_document_unified instead.")
|
||||||
|
|
||||||
|
# --- UNIFIED MCP Tools for Sayıştay (Turkish Court of Accounts) ---
|
||||||
|
|
||||||
@app.tool(
|
@app.tool(
|
||||||
description="Search Sayıştay Temyiz Kurulu decisions with chamber filtering and comprehensive criteria",
|
description="Search Sayıştay decisions unified across all three decision types (Genel Kurul, Temyiz Kurulu, Daire) with comprehensive filtering",
|
||||||
annotations={
|
annotations={
|
||||||
"readOnlyHint": True,
|
"readOnlyHint": True,
|
||||||
"openWorldHint": True,
|
"openWorldHint": True,
|
||||||
"idempotentHint": True
|
"idempotentHint": True
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
async def search_sayistay_temyiz_kurulu(
|
async def search_sayistay_unified(
|
||||||
ilam_dairesi: DaireEnum = Field("ALL", description="Audit chamber selection"),
|
decision_type: SayistayDecisionTypeEnum = Field(..., description="Decision type: genel_kurul, temyiz_kurulu, or daire"),
|
||||||
yili: str = Field("", description="Year (YYYY)"),
|
|
||||||
karar_tarih_baslangic: str = Field("", description="Start date (DD.MM.YYYY)"),
|
# Common pagination parameters
|
||||||
karar_tarih_bitis: str = Field("", description="End date (DD.MM.YYYY)"),
|
start: int = Field(0, ge=0, description="Starting record for pagination (0-based)"),
|
||||||
kamu_idaresi_turu: KamuIdaresiTuruEnum = Field("ALL", description="Public admin type"),
|
length: int = Field(10, ge=1, le=100, description="Number of records per page (1-100)"),
|
||||||
|
|
||||||
|
# Common search parameters
|
||||||
|
karar_tarih_baslangic: str = Field("", description="Start date (DD.MM.YYYY format)"),
|
||||||
|
karar_tarih_bitis: str = Field("", description="End date (DD.MM.YYYY format)"),
|
||||||
|
kamu_idaresi_turu: KamuIdaresiTuruEnum = Field("ALL", description="Public administration type filter"),
|
||||||
ilam_no: str = Field("", description="Audit report number (İlam No, max 50 chars)"),
|
ilam_no: str = Field("", description="Audit report number (İlam No, max 50 chars)"),
|
||||||
dosya_no: str = Field("", description="File number for the case"),
|
web_karar_konusu: WebKararKonusuEnum = Field("ALL", description="Decision subject category filter"),
|
||||||
temyiz_tutanak_no: str = Field("", description="Appeals board meeting minutes number"),
|
|
||||||
temyiz_karar: str = Field("", description="Appeals decision text"),
|
# Genel Kurul specific parameters (ignored for other types)
|
||||||
web_karar_konusu: WebKararKonusuEnum = Field("ALL", description="Decision subject"),
|
karar_no: str = Field("", description="Decision number (genel_kurul only)"),
|
||||||
start: int = Field(0, description="Starting record for pagination (0-based)"),
|
karar_ek: str = Field("", description="Decision appendix number (genel_kurul only)"),
|
||||||
length: int = Field(10, description="Number of records per page (1-100)")
|
karar_tamami: str = Field("", description="Full text search (genel_kurul only)"),
|
||||||
) -> TemyizKuruluSearchResponse:
|
|
||||||
"""Search Sayıştay Appeals Board decisions."""
|
# Temyiz Kurulu specific parameters (ignored for other types)
|
||||||
logger.info(f"Tool 'search_sayistay_temyiz_kurulu' called with params: chamber={ilam_dairesi}, year={yili}, admin_type={kamu_idaresi_turu}, subject={web_karar_konusu}")
|
ilam_dairesi: DaireEnum = Field("ALL", description="Audit chamber selection (temyiz_kurulu only)"),
|
||||||
|
yili: str = Field("", description="Year (YYYY format, temyiz_kurulu only)"),
|
||||||
|
dosya_no: str = Field("", description="File number (temyiz_kurulu only)"),
|
||||||
|
temyiz_tutanak_no: str = Field("", description="Appeals board meeting minutes number (temyiz_kurulu only)"),
|
||||||
|
temyiz_karar: str = Field("", description="Appeals decision text search (temyiz_kurulu only)"),
|
||||||
|
|
||||||
|
# Daire specific parameters (ignored for other types)
|
||||||
|
yargilama_dairesi: DaireEnum = Field("ALL", description="Chamber selection (daire only)"),
|
||||||
|
hesap_yili: str = Field("", description="Account year (daire only)"),
|
||||||
|
web_karar_metni: str = Field("", description="Decision text search (daire only)")
|
||||||
|
) -> SayistayUnifiedSearchResult:
|
||||||
|
"""Search Sayıştay decisions across all three decision types with unified interface."""
|
||||||
|
logger.info(f"Tool 'search_sayistay_unified' called with decision_type={decision_type}")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
search_request = TemyizKuruluSearchRequest(
|
search_request = SayistayUnifiedSearchRequest(
|
||||||
ilam_dairesi=ilam_dairesi,
|
decision_type=decision_type,
|
||||||
yili=yili,
|
start=start,
|
||||||
|
length=length,
|
||||||
karar_tarih_baslangic=karar_tarih_baslangic,
|
karar_tarih_baslangic=karar_tarih_baslangic,
|
||||||
karar_tarih_bitis=karar_tarih_bitis,
|
karar_tarih_bitis=karar_tarih_bitis,
|
||||||
kamu_idaresi_turu=kamu_idaresi_turu,
|
kamu_idaresi_turu=kamu_idaresi_turu,
|
||||||
ilam_no=ilam_no,
|
ilam_no=ilam_no,
|
||||||
|
web_karar_konusu=web_karar_konusu,
|
||||||
|
karar_no=karar_no,
|
||||||
|
karar_ek=karar_ek,
|
||||||
|
karar_tamami=karar_tamami,
|
||||||
|
ilam_dairesi=ilam_dairesi,
|
||||||
|
yili=yili,
|
||||||
dosya_no=dosya_no,
|
dosya_no=dosya_no,
|
||||||
temyiz_tutanak_no=temyiz_tutanak_no,
|
temyiz_tutanak_no=temyiz_tutanak_no,
|
||||||
temyiz_karar=temyiz_karar,
|
temyiz_karar=temyiz_karar,
|
||||||
web_karar_konusu=web_karar_konusu,
|
|
||||||
start=start,
|
|
||||||
length=length
|
|
||||||
)
|
|
||||||
return await sayistay_client_instance.search_temyiz_kurulu_decisions(search_request)
|
|
||||||
except Exception as e:
|
|
||||||
logger.exception("Error in tool 'search_sayistay_temyiz_kurulu'")
|
|
||||||
raise
|
|
||||||
|
|
||||||
@app.tool(
|
|
||||||
description="Search Sayıştay Daire decisions with chamber filtering and subject categorization",
|
|
||||||
annotations={
|
|
||||||
"readOnlyHint": True,
|
|
||||||
"openWorldHint": True,
|
|
||||||
"idempotentHint": True
|
|
||||||
}
|
|
||||||
)
|
|
||||||
async def search_sayistay_daire(
|
|
||||||
yargilama_dairesi: DaireEnum = Field("ALL", description="Chamber selection"),
|
|
||||||
karar_tarih_baslangic: str = Field("", description="Start date (DD.MM.YYYY)"),
|
|
||||||
karar_tarih_bitis: str = Field("", description="End date (DD.MM.YYYY)"),
|
|
||||||
ilam_no: str = Field("", description="Audit report number (İlam No, max 50 chars)"),
|
|
||||||
kamu_idaresi_turu: KamuIdaresiTuruEnum = Field("ALL", description="Public admin type"),
|
|
||||||
hesap_yili: str = Field("", description="Fiscal year"),
|
|
||||||
web_karar_konusu: WebKararKonusuEnum = Field("ALL", description="Decision subject"),
|
|
||||||
web_karar_metni: str = Field("", description="Decision text search"),
|
|
||||||
start: int = Field(0, description="Starting record for pagination (0-based)"),
|
|
||||||
length: int = Field(10, description="Number of records per page (1-100)")
|
|
||||||
) -> DaireSearchResponse:
|
|
||||||
"""Search Sayıştay Chamber decisions."""
|
|
||||||
logger.info(f"Tool 'search_sayistay_daire' called with params: chamber={yargilama_dairesi}, admin_type={kamu_idaresi_turu}, subject={web_karar_konusu}, content={web_karar_metni}")
|
|
||||||
|
|
||||||
try:
|
|
||||||
search_request = DaireSearchRequest(
|
|
||||||
yargilama_dairesi=yargilama_dairesi,
|
yargilama_dairesi=yargilama_dairesi,
|
||||||
karar_tarih_baslangic=karar_tarih_baslangic,
|
|
||||||
karar_tarih_bitis=karar_tarih_bitis,
|
|
||||||
ilam_no=ilam_no,
|
|
||||||
kamu_idaresi_turu=kamu_idaresi_turu,
|
|
||||||
hesap_yili=hesap_yili,
|
hesap_yili=hesap_yili,
|
||||||
web_karar_konusu=web_karar_konusu,
|
web_karar_metni=web_karar_metni
|
||||||
web_karar_metni=web_karar_metni,
|
|
||||||
start=start,
|
|
||||||
length=length
|
|
||||||
)
|
)
|
||||||
return await sayistay_client_instance.search_daire_decisions(search_request)
|
return await sayistay_unified_client_instance.search_unified(search_request)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception("Error in tool 'search_sayistay_daire'")
|
logger.exception("Error in tool 'search_sayistay_unified'")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
@app.tool(
|
@app.tool(
|
||||||
description="Get Sayıştay Genel Kurul decision document in Markdown format",
|
description="Get Sayıştay decision document in Markdown format for any decision type",
|
||||||
annotations={
|
annotations={
|
||||||
"readOnlyHint": True,
|
"readOnlyHint": True,
|
||||||
"openWorldHint": False,
|
"openWorldHint": False,
|
||||||
"idempotentHint": True
|
"idempotentHint": True
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
async def get_sayistay_genel_kurul_document_markdown(
|
async def get_sayistay_document_unified(
|
||||||
decision_id: str = Field(..., description="Decision ID from search_sayistay_genel_kurul results")
|
decision_id: str = Field(..., description="Decision ID from search_sayistay_unified results"),
|
||||||
) -> SayistayDocumentMarkdown:
|
decision_type: SayistayDecisionTypeEnum = Field(..., description="Decision type: genel_kurul, temyiz_kurulu, or daire")
|
||||||
"""Get Sayıştay General Assembly decision as Markdown."""
|
) -> SayistayUnifiedDocumentMarkdown:
|
||||||
logger.info(f"Tool 'get_sayistay_genel_kurul_document_markdown' called for ID: {decision_id}")
|
"""Get Sayıştay decision document as Markdown for any decision type."""
|
||||||
|
logger.info(f"Tool 'get_sayistay_document_unified' called for ID: {decision_id}, type: {decision_type}")
|
||||||
|
|
||||||
if not decision_id or not decision_id.strip():
|
if not decision_id or not decision_id.strip():
|
||||||
raise ValueError("Decision ID must be a non-empty string.")
|
raise ValueError("Decision ID must be a non-empty string.")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return await sayistay_client_instance.get_document_as_markdown(decision_id, "genel_kurul")
|
return await sayistay_unified_client_instance.get_document_unified(decision_id, decision_type)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception("Error in tool 'get_sayistay_genel_kurul_document_markdown'")
|
logger.exception("Error in tool 'get_sayistay_document_unified'")
|
||||||
raise
|
|
||||||
|
|
||||||
@app.tool(
|
|
||||||
description="Get Sayıştay Temyiz Kurulu decision document in Markdown format",
|
|
||||||
annotations={
|
|
||||||
"readOnlyHint": True,
|
|
||||||
"openWorldHint": False,
|
|
||||||
"idempotentHint": True
|
|
||||||
}
|
|
||||||
)
|
|
||||||
async def get_sayistay_temyiz_kurulu_document_markdown(
|
|
||||||
decision_id: str = Field(..., description="Decision ID from search_sayistay_temyiz_kurulu results")
|
|
||||||
) -> SayistayDocumentMarkdown:
|
|
||||||
"""Get Sayıştay Appeals Board decision as Markdown."""
|
|
||||||
logger.info(f"Tool 'get_sayistay_temyiz_kurulu_document_markdown' called for ID: {decision_id}")
|
|
||||||
|
|
||||||
if not decision_id or not decision_id.strip():
|
|
||||||
raise ValueError("Decision ID must be a non-empty string.")
|
|
||||||
|
|
||||||
try:
|
|
||||||
return await sayistay_client_instance.get_document_as_markdown(decision_id, "temyiz_kurulu")
|
|
||||||
except Exception as e:
|
|
||||||
logger.exception("Error in tool 'get_sayistay_temyiz_kurulu_document_markdown'")
|
|
||||||
raise
|
|
||||||
|
|
||||||
@app.tool(
|
|
||||||
description="Get Sayıştay Daire decision document in Markdown format",
|
|
||||||
annotations={
|
|
||||||
"readOnlyHint": True,
|
|
||||||
"openWorldHint": False,
|
|
||||||
"idempotentHint": True
|
|
||||||
}
|
|
||||||
)
|
|
||||||
async def get_sayistay_daire_document_markdown(
|
|
||||||
decision_id: str = Field(..., description="Decision ID from search_sayistay_daire results")
|
|
||||||
) -> SayistayDocumentMarkdown:
|
|
||||||
"""Get Sayıştay Chamber decision as Markdown."""
|
|
||||||
logger.info(f"Tool 'get_sayistay_daire_document_markdown' called for ID: {decision_id}")
|
|
||||||
|
|
||||||
if not decision_id or not decision_id.strip():
|
|
||||||
raise ValueError("Decision ID must be a non-empty string.")
|
|
||||||
|
|
||||||
try:
|
|
||||||
return await sayistay_client_instance.get_document_as_markdown(decision_id, "daire")
|
|
||||||
except Exception as e:
|
|
||||||
logger.exception("Error in tool 'get_sayistay_daire_document_markdown'")
|
|
||||||
raise
|
raise
|
||||||
|
|
||||||
# --- Application Shutdown Handling ---
|
# --- Application Shutdown Handling ---
|
||||||
@@ -2056,6 +2081,7 @@ def perform_cleanup():
|
|||||||
globals().get('rekabet_client_instance'),
|
globals().get('rekabet_client_instance'),
|
||||||
globals().get('bedesten_client_instance'),
|
globals().get('bedesten_client_instance'),
|
||||||
globals().get('sayistay_client_instance'),
|
globals().get('sayistay_client_instance'),
|
||||||
|
globals().get('sayistay_unified_client_instance'),
|
||||||
globals().get('kvkk_client_instance')
|
globals().get('kvkk_client_instance')
|
||||||
]
|
]
|
||||||
async def close_all_clients_async():
|
async def close_all_clients_async():
|
||||||
|
|||||||
@@ -1,9 +1,16 @@
|
|||||||
# sayistay_mcp_module/models.py
|
# sayistay_mcp_module/models.py
|
||||||
|
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
from typing import Optional, List, Union
|
from typing import Optional, List, Union, Dict, Any
|
||||||
|
from enum import Enum
|
||||||
from .enums import DaireEnum, KamuIdaresiTuruEnum, WebKararKonusuEnum
|
from .enums import DaireEnum, KamuIdaresiTuruEnum, WebKararKonusuEnum
|
||||||
|
|
||||||
|
# --- Unified Enums ---
|
||||||
|
class SayistayDecisionTypeEnum(str, Enum):
|
||||||
|
GENEL_KURUL = "genel_kurul"
|
||||||
|
TEMYIZ_KURULU = "temyiz_kurulu"
|
||||||
|
DAIRE = "daire"
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# Genel Kurul (General Assembly) Models
|
# Genel Kurul (General Assembly) Models
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
@@ -155,6 +162,59 @@ class SayistayDocumentMarkdown(BaseModel):
|
|||||||
decision_id: str = Field(..., description="Unique decision identifier")
|
decision_id: str = Field(..., description="Unique decision identifier")
|
||||||
decision_type: str = Field(..., description="Value")
|
decision_type: str = Field(..., description="Value")
|
||||||
source_url: str = Field(..., description="Original URL where the document was retrieved")
|
source_url: str = Field(..., description="Original URL where the document was retrieved")
|
||||||
markdown_content: str = Field("", description="Full decision text converted to Markdown format")
|
markdown_content: Optional[str] = Field(None, description="Full decision text converted to Markdown format")
|
||||||
retrieval_date: str = Field("", description="Date when document was retrieved (ISO format)")
|
retrieval_date: Optional[str] = Field(None, description="Date when document was retrieved (ISO format)")
|
||||||
error_message: str = Field("", description="Error message if document retrieval failed")
|
error_message: Optional[str] = Field(None, description="Error message if document retrieval failed")
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Unified Models
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
class SayistayUnifiedSearchRequest(BaseModel):
|
||||||
|
"""Unified search request for all Sayıştay decision types."""
|
||||||
|
decision_type: SayistayDecisionTypeEnum = Field(..., description="Decision type: genel_kurul, temyiz_kurulu, or daire")
|
||||||
|
|
||||||
|
# Common pagination parameters
|
||||||
|
start: int = Field(0, ge=0, description="Starting record for pagination (0-based)")
|
||||||
|
length: int = Field(10, ge=1, le=100, description="Number of records per page (1-100)")
|
||||||
|
|
||||||
|
# Common search parameters
|
||||||
|
karar_tarih_baslangic: str = Field("", description="Start date (DD.MM.YYYY format)")
|
||||||
|
karar_tarih_bitis: str = Field("", description="End date (DD.MM.YYYY format)")
|
||||||
|
kamu_idaresi_turu: KamuIdaresiTuruEnum = Field("ALL", description="Public administration type filter")
|
||||||
|
ilam_no: str = Field("", description="Audit report number (İlam No, max 50 chars)")
|
||||||
|
web_karar_konusu: WebKararKonusuEnum = Field("ALL", description="Decision subject category filter")
|
||||||
|
|
||||||
|
# Genel Kurul specific parameters (ignored for other types)
|
||||||
|
karar_no: str = Field("", description="Decision number (genel_kurul only)")
|
||||||
|
karar_ek: str = Field("", description="Decision appendix number (genel_kurul only)")
|
||||||
|
karar_tamami: str = Field("", description="Full text search (genel_kurul only)")
|
||||||
|
|
||||||
|
# Temyiz Kurulu specific parameters (ignored for other types)
|
||||||
|
ilam_dairesi: DaireEnum = Field("ALL", description="Audit chamber selection (temyiz_kurulu only)")
|
||||||
|
yili: str = Field("", description="Year (YYYY format, temyiz_kurulu only)")
|
||||||
|
dosya_no: str = Field("", description="File number (temyiz_kurulu only)")
|
||||||
|
temyiz_tutanak_no: str = Field("", description="Appeals board meeting minutes number (temyiz_kurulu only)")
|
||||||
|
temyiz_karar: str = Field("", description="Appeals decision text search (temyiz_kurulu only)")
|
||||||
|
|
||||||
|
# Daire specific parameters (ignored for other types)
|
||||||
|
yargilama_dairesi: DaireEnum = Field("ALL", description="Chamber selection (daire only)")
|
||||||
|
hesap_yili: str = Field("", description="Account year (daire only)")
|
||||||
|
web_karar_metni: str = Field("", description="Decision text search (daire only)")
|
||||||
|
|
||||||
|
class SayistayUnifiedSearchResult(BaseModel):
|
||||||
|
"""Unified search result containing decisions from any Sayıştay decision type."""
|
||||||
|
decision_type: SayistayDecisionTypeEnum = Field(..., description="Type of decisions returned")
|
||||||
|
decisions: List[Dict[str, Any]] = Field(default_factory=list, description="Decision list (structure varies by type)")
|
||||||
|
total_records: int = Field(0, description="Total number of records found")
|
||||||
|
total_filtered: int = Field(0, description="Number of records after filtering")
|
||||||
|
draw: int = Field(1, description="DataTables draw counter")
|
||||||
|
|
||||||
|
class SayistayUnifiedDocumentMarkdown(BaseModel):
|
||||||
|
"""Unified document model for all Sayıştay decision types."""
|
||||||
|
decision_type: SayistayDecisionTypeEnum = Field(..., description="Type of document")
|
||||||
|
decision_id: str = Field(..., description="Decision ID")
|
||||||
|
source_url: str = Field(..., description="Source URL of the document")
|
||||||
|
document_data: Dict[str, Any] = Field(default_factory=dict, description="Document content and metadata")
|
||||||
|
markdown_content: Optional[str] = Field(None, description="Markdown content")
|
||||||
|
error_message: Optional[str] = Field(None, description="Error message if retrieval failed")
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
# sayistay_mcp_module/unified_client.py
|
||||||
|
# Unified client for all three Sayıştay decision types
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from typing import Optional, Dict, Any
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
from .models import (
|
||||||
|
SayistayUnifiedSearchRequest,
|
||||||
|
SayistayUnifiedSearchResult,
|
||||||
|
SayistayUnifiedDocumentMarkdown,
|
||||||
|
SayistayDecisionTypeEnum,
|
||||||
|
GenelKurulSearchRequest,
|
||||||
|
TemyizKuruluSearchRequest,
|
||||||
|
DaireSearchRequest
|
||||||
|
)
|
||||||
|
from .client import SayistayApiClient
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class SayistayUnifiedClient:
|
||||||
|
"""Unified client that handles all three Sayıştay decision types."""
|
||||||
|
|
||||||
|
def __init__(self, request_timeout: float = 60.0):
|
||||||
|
self.client = SayistayApiClient(request_timeout)
|
||||||
|
|
||||||
|
async def search_unified(self, params: SayistayUnifiedSearchRequest) -> SayistayUnifiedSearchResult:
|
||||||
|
"""Unified search that routes to appropriate search method based on decision_type."""
|
||||||
|
|
||||||
|
if params.decision_type == SayistayDecisionTypeEnum.GENEL_KURUL:
|
||||||
|
# Convert to genel kurul request
|
||||||
|
genel_kurul_params = GenelKurulSearchRequest(
|
||||||
|
karar_no=params.karar_no,
|
||||||
|
karar_ek=params.karar_ek,
|
||||||
|
karar_tarih_baslangic=params.karar_tarih_baslangic,
|
||||||
|
karar_tarih_bitis=params.karar_tarih_bitis,
|
||||||
|
karar_tamami=params.karar_tamami,
|
||||||
|
start=params.start,
|
||||||
|
length=params.length
|
||||||
|
)
|
||||||
|
|
||||||
|
result = await self.client.search_genel_kurul_decisions(genel_kurul_params)
|
||||||
|
|
||||||
|
# Convert to unified format
|
||||||
|
decisions_list = [decision.model_dump() for decision in result.decisions]
|
||||||
|
|
||||||
|
return SayistayUnifiedSearchResult(
|
||||||
|
decision_type=SayistayDecisionTypeEnum.GENEL_KURUL,
|
||||||
|
decisions=decisions_list,
|
||||||
|
total_records=result.total_records,
|
||||||
|
total_filtered=result.total_filtered,
|
||||||
|
draw=result.draw
|
||||||
|
)
|
||||||
|
|
||||||
|
elif params.decision_type == SayistayDecisionTypeEnum.TEMYIZ_KURULU:
|
||||||
|
# Convert to temyiz kurulu request
|
||||||
|
temyiz_params = TemyizKuruluSearchRequest(
|
||||||
|
ilam_dairesi=params.ilam_dairesi,
|
||||||
|
yili=params.yili,
|
||||||
|
karar_tarih_baslangic=params.karar_tarih_baslangic,
|
||||||
|
karar_tarih_bitis=params.karar_tarih_bitis,
|
||||||
|
kamu_idaresi_turu=params.kamu_idaresi_turu,
|
||||||
|
ilam_no=params.ilam_no,
|
||||||
|
dosya_no=params.dosya_no,
|
||||||
|
temyiz_tutanak_no=params.temyiz_tutanak_no,
|
||||||
|
temyiz_karar=params.temyiz_karar,
|
||||||
|
web_karar_konusu=params.web_karar_konusu,
|
||||||
|
start=params.start,
|
||||||
|
length=params.length
|
||||||
|
)
|
||||||
|
|
||||||
|
result = await self.client.search_temyiz_kurulu_decisions(temyiz_params)
|
||||||
|
|
||||||
|
# Convert to unified format
|
||||||
|
decisions_list = [decision.model_dump() for decision in result.decisions]
|
||||||
|
|
||||||
|
return SayistayUnifiedSearchResult(
|
||||||
|
decision_type=SayistayDecisionTypeEnum.TEMYIZ_KURULU,
|
||||||
|
decisions=decisions_list,
|
||||||
|
total_records=result.total_records,
|
||||||
|
total_filtered=result.total_filtered,
|
||||||
|
draw=result.draw
|
||||||
|
)
|
||||||
|
|
||||||
|
elif params.decision_type == SayistayDecisionTypeEnum.DAIRE:
|
||||||
|
# Convert to daire request
|
||||||
|
daire_params = DaireSearchRequest(
|
||||||
|
yargilama_dairesi=params.yargilama_dairesi,
|
||||||
|
karar_tarih_baslangic=params.karar_tarih_baslangic,
|
||||||
|
karar_tarih_bitis=params.karar_tarih_bitis,
|
||||||
|
ilam_no=params.ilam_no,
|
||||||
|
kamu_idaresi_turu=params.kamu_idaresi_turu,
|
||||||
|
hesap_yili=params.hesap_yili,
|
||||||
|
web_karar_konusu=params.web_karar_konusu,
|
||||||
|
web_karar_metni=params.web_karar_metni,
|
||||||
|
start=params.start,
|
||||||
|
length=params.length
|
||||||
|
)
|
||||||
|
|
||||||
|
result = await self.client.search_daire_decisions(daire_params)
|
||||||
|
|
||||||
|
# Convert to unified format
|
||||||
|
decisions_list = [decision.model_dump() for decision in result.decisions]
|
||||||
|
|
||||||
|
return SayistayUnifiedSearchResult(
|
||||||
|
decision_type=SayistayDecisionTypeEnum.DAIRE,
|
||||||
|
decisions=decisions_list,
|
||||||
|
total_records=result.total_records,
|
||||||
|
total_filtered=result.total_filtered,
|
||||||
|
draw=result.draw
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Unsupported decision type: {params.decision_type}")
|
||||||
|
|
||||||
|
async def get_document_unified(self, decision_id: str, decision_type: SayistayDecisionTypeEnum) -> SayistayUnifiedDocumentMarkdown:
|
||||||
|
"""Unified document retrieval for all Sayıştay decision types."""
|
||||||
|
|
||||||
|
# Convert enum to string for backend client
|
||||||
|
decision_type_str = decision_type.value
|
||||||
|
|
||||||
|
# Use existing client method
|
||||||
|
result = await self.client.get_document_as_markdown(decision_id, decision_type_str)
|
||||||
|
|
||||||
|
return SayistayUnifiedDocumentMarkdown(
|
||||||
|
decision_type=decision_type,
|
||||||
|
decision_id=result.decision_id,
|
||||||
|
source_url=result.source_url,
|
||||||
|
document_data=result.model_dump(),
|
||||||
|
markdown_content=result.markdown_content,
|
||||||
|
error_message=result.error_message
|
||||||
|
)
|
||||||
|
|
||||||
|
async def close_client_session(self):
|
||||||
|
"""Close the underlying client session."""
|
||||||
|
if hasattr(self.client, 'close_client_session'):
|
||||||
|
await self.client.close_client_session()
|
||||||
Reference in New Issue
Block a user