fix pydantic schemas, fix func_tools

This commit is contained in:
G0DSEND016 2026-03-16 03:16:02 +01:00
parent a95a0efbab
commit 801a453a2f
9 changed files with 512 additions and 364 deletions

View File

@ -1,7 +1,6 @@
import httpx
import logging
import json
from pydantic import BaseModel
from cachetools import TTLCache
from typing import Callable
from tenacity import retry, stop_after_attempt, wait_exponential
@ -35,18 +34,6 @@ _client = httpx.AsyncClient(
max_keepalive_connections=HTTP_MAX_KEEPALIVE),
)
def docstring_from_model(model: type[BaseModel]):
def decorator(func):
if func.__doc__:
func.__doc__ = func.__doc__.format(
params="\n".join(
f"\t\t- {name}: {field.description or 'No description'}"
for name, field in model.model_fields.items()
)
)
return func
return decorator
_log_callback: Callable[[str], None] | None = None
def set_log_callback(cb: Callable[[str], None] | None):

View File

@ -1,178 +1,342 @@
from pydantic import BaseModel, Field, conint
from typing import Optional, List, Literal
from typing import Annotated, List, Literal, Optional
from pydantic import BaseModel, Field, field_validator
# =================================================================================================================
# COURT SCHEMAS
# =================================================================================================================
class SortableMixin(BaseModel):
sortProperty: Annotated[
Optional[str],
Field(default=None, description="Atribút, podľa ktorého budú záznamy zoradené")
] = None
sortDirection: Annotated[
Literal["ASC", "DESC"],
Field(default="ASC", description="Smer zoradenia (ASC alebo DESC)")
] = "ASC"
class Court(BaseModel):
query: str = Field(None, description="Search term or phrase to help find information")
typSuduFacetFilter: Optional[List[str]] = Field(None, description="Court types (facet filter), e.g., Okresný súd, Krajský súd, Najvyšší súd SR, Špecializovaný trestný súd, etc.")
krajFacetFilter: Optional[List[str]] = Field(None, description="Regions (facet filter), e.g., Bratislavský kraj, Košický kraj, Prešovský kraj, etc.")
okresFacetFilter: Optional[List[str]] = Field(None, description="Districts (facet filter), e.g., Okres Banská Bystrica, Okres Bratislava I, Okres Košice I, etc.")
zahrnutZaniknuteSudy: Optional[bool] = Field(None, description="Include defunct/inactive courts (True) or only currently active courts (False)")
page: Optional[conint(ge=1)] = Field(None, description="Requested page number (starting from 1)")
size: Optional[conint(ge=1)] = Field(None, description="Number of results per page")
indexDatumOd: Optional[str] = Field(None, description="Index date from (format YYYY.MM.DD or DD.MM.YYYY)")
indexDatumDo: Optional[str] = Field(None, description="Index date to (format YYYY.MM.DD or DD.MM.YYYY)")
sortProperty: Optional[str] = Field(None, description="Field to sort the output by")
sortDirection: Literal["ASC", "DESC"] = Field("ASC", description="Sort direction (ASC or DESC)")
class CourtID(BaseModel):
id: str = Field(..., description="Court identifier (e.g., sud_175)")
class PaginatedRequest(SortableMixin):
page: Annotated[
Optional[int],
Field(default=None, ge=0, description="Číslo stránky (začína od 0, nie od 1!)")
] = None
size: Annotated[
Optional[int],
Field(default=None, ge=1, description="Počet záznamov na stránku")
] = None
####################################################################################################################
# .../v1/sud
####################################################################################################################
class CourtSearch(PaginatedRequest):
"""Zoznam súdov s voliteľnými filtrami. GET /v1/sud"""
query: Annotated[
Optional[str],
Field(default=None, description="Hľadané slovo alebo slovné spojenie")
] = None
typSuduFacetFilter: Annotated[
Optional[List[str]],
Field(default=None, description="Typ súdu (fazetový filter), napr. ['Okresný súd', 'Krajský súd']")
] = None
krajFacetFilter: Annotated[
Optional[List[str]],
Field(default=None, description="Kraj (fazetový filter), napr. ['Bratislavský kraj']")
] = None
okresFacetFilter: Annotated[
Optional[List[str]],
Field(default=None, description="Okres (fazetový filter), napr. ['Okres Bratislava I']")
] = None
zahrnutZaniknuteSudy: Annotated[
Optional[bool],
Field(default=None, description="True = zahrnúť zaniknuté súdy, False = len aktívne")
] = None
indexDatumOd: Annotated[
Optional[str],
Field(default=None, description="Dátum indexácie od")
] = None
indexDatumDo: Annotated[
Optional[str],
Field(default=None, description="Dátum indexácie do")
] = None
class CourtByID(BaseModel):
"""Jeden súd podľa ID. GET /v1/sud/{id}"""
id: Annotated[str, Field(description="Identifikátor súdu, napr. 'sud_175'")]
@field_validator("id")
@classmethod
def normalize(cls, v: str) -> str:
v = v.strip()
return f"sud_{v}" if v.isdigit() else v
class CourtAutocomplete(BaseModel):
query: str = Field(None, description="Search term or phrase to help find information")
limit: Optional[conint(ge=1)] = Field(None, description="Limits the number of returned results (pagination)")
"""Autocomplete pre názvy súdov. GET /v1/sud/autocomplete"""
query: Annotated[Optional[str], Field(default=None, description="Hľadané slovo")] = None
limit: Annotated[Optional[int], Field(default=None, ge=1, description="Maximálny počet výsledkov")] = None
# =================================================================================================================
# JUDGE SCHEMAS
# =================================================================================================================
####################################################################################################################
# .../v1/sudca
####################################################################################################################
class Judge(BaseModel):
query: str = Field(None, description="Search term or phrase to help find information")
funkciaFacetFilter: Optional[List[str]] = Field(None, description="Judge function, role or position related to a judge (facet filter) e.g., Sudca, Podpredseda, Predseda, Hosťujúci sudca")
typSuduFacetFilter: Optional[List[str]] = Field(None, description="Court types (facet filter), e.g., Okresný súd, Krajský súd, Najvyšší súd SR, Špecializovaný trestný súd, etc.")
krajFacetFilter: Optional[List[str]] = Field(None, description="Regions (facet filter), e.g., Bratislavský kraj, Košický kraj, Prešovský kraj, etc.")
okresFacetFilter: Optional[List[str]] = Field(None, description="Districts (facet filter), e.g., Okres Banská Bystrica, Okres Bratislava I, Okres Košice I, etc.")
stavZapisuFacetFilter: Optional[List[str]] = Field(None, description="Record status filter (facet filter) to specify which court records to include. Options (do not translate): label.sudca.aktivny, label.sudca.odvolany, label.sudca.vymazany, label.sudca.prerusenie vykonu - poberatel, label.sudca.prerusenie vykonu - ina funkce")
guidSud: Optional[str] = Field(None, description="Court identifier (e.g., sud_100)")
indexDatumOd: Optional[str] = Field(None, description="Index date from (format YYYY.MM.DD or DD.MM.YYYY)")
indexDatumDo: Optional[str] = Field(None, description="Index date to (format YYYY.MM.DD or DD.MM.YYYY)")
page: Optional[conint(ge=1)] = Field(None, description="Requested page number (starting from 1)")
size: Optional[conint(ge=1)] = Field(None, description="Number of results per page")
sortProperty: Optional[str] = Field(None, description="Field to sort the output by")
sortDirection: Literal["ASC", "DESC"] = Field("ASC", description="Sort direction (ASC or DESC)")
class JudgeSearch(BaseModel):
"""Zoznam sudcov s voliteľnými filtrami. GET /v1/sudca"""
query: Annotated[
Optional[str],
Field(default=None, description="Hľadané slovo alebo slovné spojenie")
] = None
funkciaFacetFilter: Annotated[
Optional[List[str]],
Field(default=None, description="Funkcia (fazetový filter), napr. ['Sudca', 'Predseda', 'Podpredseda']")
] = None
typSuduFacetFilter: Annotated[
Optional[List[str]],
Field(default=None, description="Typ súdu (fazetový filter)")
] = None
krajFacetFilter: Annotated[
Optional[List[str]],
Field(default=None, description="Kraj (fazetový filter), napr. ['Bratislavský kraj']")
] = None
okresFacetFilter: Annotated[
Optional[List[str]],
Field(default=None, description="Okres (fazetový filter)")
] = None
stavZapisuFacetFilter: Annotated[
Optional[List[str]],
Field(
default=None,
description=(
"Stav zápisu — neprekladať hodnoty: "
"'label.sudca.aktivny', 'label.sudca.odvolany', "
"'label.sudca.vymazany', "
"'label.sudca.prerusenie vykonu - poberatel', "
"'label.sudca.prerusenie vykonu - ina funkce'"
)
)
] = None
guidSud: Annotated[
Optional[str],
Field(default=None, description="Identifikátor súdu, napr. 'sud_100'")
] = None
indexDatumOd: Annotated[
Optional[str],
Field(default=None, description="Dátum indexácie od")
] = None
indexDatumDo: Annotated[
Optional[str],
Field(default=None, description="Dátum indexácie do")
] = None
page: Annotated[
Optional[int],
Field(default=None, ge=0, description="Číslo stránky (začína od 0)")
] = None
size: Annotated[
Optional[int],
Field(default=None, ge=1, description="Počet záznamov na stránku")
] = None
class JudgeByID(BaseModel):
"""Jeden sudca podľa ID. GET /v1/sudca/{id}"""
id: Annotated[str, Field(description="Identifikátor sudcu, napr. 'sudca_1'")]
@field_validator("id")
@classmethod
def normalize(cls, v: str) -> str:
v = v.strip()
return f"sudca_{v}" if v.isdigit() else v
class JudgeID(BaseModel):
id: str = Field(..., description="Judge identifier (e. g., sudca_1)")
class JudgeAutocomplete(BaseModel):
query: str = Field(None, description="Search term or phrase to help find information")
guidSud: Optional[str] = Field(None, description="Court identifier (e.g., sud_100)")
limit: Optional[conint(ge=1)] = Field(None, description="Limits the number of returned results (pagination)")
"""
Autocomplete pre mená sudcov. GET /v1/sudca/autocomplete
PREFEROVANÝ nástroj pri hľadaní sudcu podľa mena použiť pred JudgeSearch!
"""
query: Annotated[
Optional[str],
Field(default=None, description="Čiastočné meno sudcu")
] = None
guidSud: Annotated[
Optional[str],
Field(default=None, description="Identifikátor súdu, napr. 'sud_100'")
] = None
limit: Annotated[
Optional[int],
Field(default=None, ge=1, description="Maximálny počet návrhov")
] = None
# =================================================================================================================
# CONTRACTS SCHEMAS
# =================================================================================================================
####################################################################################################################
# .../v1/rozhodnutie
####################################################################################################################
class Contracts(BaseModel):
query: str = Field(None, description="Search term or phrase to help find information")
typDokumentuFacetFilter: Optional[List[str]] = Field(None, description="Contract's type (facet filter), e.g., FAKTURA, OBJEDNAVKA, ZMLUVA, DODATOK")
odberatelFacetFilter: Optional[List[str]] = Field(None, description="Subscriber filter. Examples: 'Krajský súd v Bratislave', 'Okresný súd Banská Bystrica', 'Špecializovaný trestný súd', Krajský súd v Košiciach, etc.")
dodavatelFacetFilter: Optional[List[str]] = Field(None, description="Supplier filter. Examples: Slovak Telekom, a.s., Wolters Kluwer s.r.o., Tibor Varga TSV Papier")
hodnotaZmluvyFacetFilter: Optional[List[str]] = Field(None, description="Contract value range filter. Options: '0-1000', '1000-20000', '20000-100000', '100000-500000', 'Viac ako 500000'")
datumZverejeneniaOd: Optional[str] = Field(None, description="Index date from (format YYYY-MM-DD)")
datumZverejeneniaDo: Optional[str] = Field(None, description="Index date to (format YYYY-MM-DD)")
guidSud: Optional[str] = Field(None, description="Court identifier (e.g., sud_100)")
indexDatumOd: Optional[str] = Field(None, description="Index date from (format YYYY-MM-DD or DD-MM-YYYY)")
indexDatumDo: Optional[str] = Field(None, description="Index date to (format YYYY-MM-DD or DD-MM-YYYY)")
sortProperty: Optional[str] = Field(None, description="Field to sort the output by")
sortDirection: Literal["ASC", "DESC"] = Field("ASC", description="Sort direction (ASC or DESC)")
page: Optional[conint(ge=1)] = Field(None, description="Requested page number (starting from 1)")
size: Optional[conint(ge=1)] = Field(None, description="Number of results per page")
class ContractID(BaseModel):
idZmluvy: str = Field(..., description="Contract identifier (e. g., 2156252)")
class ContractAutocomplete(BaseModel):
query: str = Field(None, description="Search term or phrase to help find information")
guidSud: Optional[str] = Field(None, description="Court identifier (e.g., sud_100)")
limit: Optional[conint(ge=1)] = Field(None, description="Limits the number of returned results (pagination)")
class DecisionSearch(PaginatedRequest):
"""Zoznam rozhodnutí s voliteľnými filtrami. GET /v1/rozhodnutie"""
query: Annotated[Optional[str], Field(default=None, description="Hľadané slovo alebo slovné spojenie")] = None
typSuduFacetFilter: Annotated[Optional[List[str]], Field(default=None, description="Typ súdu (fazetový filter)")] = None
krajFacetFilter: Annotated[Optional[List[str]], Field(default=None, description="Kraj (fazetový filter)")] = None
okresFacetFilter: Annotated[Optional[List[str]], Field(default=None, description="Okres (fazetový filter)")] = None
oblastPravnejUpravyFacetFilter: Annotated[
Optional[List[str]],
Field(default=None, description="Oblasť právnej úpravy (fazetový filter)")
] = None
podOblastPravnejUpravyFacetFilter: Annotated[
Optional[List[str]],
Field(default=None, description="Podoblasť právnej úpravy (fazetový filter)")
] = None
formaRozhodnutiaFacetFilter: Annotated[
Optional[List[str]],
Field(default=None, description="Forma rozhodnutia, napr. ['Uznesenie', 'Rozsudok', 'Platobný rozkaz']")
] = None
povahaRozhodnutiaFacetFilter: Annotated[
Optional[str],
Field(default=None, description="Povaha rozhodnutia")
] = None
odkazovanePredpisy: Annotated[
Optional[str],
Field(default=None, description="Odkazované predpisy")
] = None
vydaniaOd: Annotated[Optional[str], Field(default=None, description="Vydanie od (DD.MM.YYYY)")] = None
vydaniaDo: Annotated[Optional[str], Field(default=None, description="Vydanie do (DD.MM.YYYY)")] = None
ecli: Annotated[Optional[str], Field(default=None, description="ECLI identifikátor, napr. 'ECLI:SK:OSPO:1965:8114010264.1'")] = None
spisovaZnacka: Annotated[Optional[str], Field(default=None, description="Spisová značka, napr. '7C/221/1991'")] = None
cisloSpisu: Annotated[Optional[str], Field(default=None, description="Identifikačné číslo spisu")] = None
guidSudca: Annotated[Optional[str], Field(default=None, description="Identifikátor sudcu, napr. 'sudca_1'")] = None
guidSud: Annotated[Optional[str], Field(default=None, description="Identifikátor súdu, napr. 'sud_100'")] = None
indexDatumOd: Annotated[Optional[str], Field(default=None, description="Dátum indexácie od")] = None
indexDatumDo: Annotated[Optional[str], Field(default=None, description="Dátum indexácie do")] = None
# =================================================================================================================
# DECISION SCHEMAS
# =================================================================================================================
class DecisionByID(BaseModel):
"""Jedno rozhodnutie podľa ID. GET /v1/rozhodnutie/{id}"""
id: Annotated[str, Field(description="Identifikátor rozhodnutia")]
class Decision(BaseModel):
query: str = Field(None, description="Search term or phrase to help find information")
typSuduFacetFilter: Optional[List[str]] = Field(None, description="Court types (facet filter), e.g., Okresný súd, Krajský súd, Najvyšší súd SR, Špecializovaný trestný súd, etc.")
krajFacetFilter: Optional[List[str]] = Field(None, description="Regions (facet filter), e.g., Bratislavský kraj, Košický kraj, Prešovský kraj, etc.")
okresFacetFilter: Optional[List[str]] = Field(None, description="Districts (facet filter), e.g., Okres Banská Bystrica, Okres Bratislava I, Okres Košice I, etc.")
odkazovanePredpisy: Optional[str] = Field(None, description="Referenced regulations")
oblastPravnejUpravyFacetFilter: Optional[List[str]] = Field(None, description="Area of legal regulation (facet filter), e.g., Občianske právo, Rodinné právo, Obchodné právo, Trestné právo, Správne právo")
podOblastPravnejUpravyFacetFilter: Optional[List[str]] = Field(None, description="Sub-area of legal regulation (facet filter), e.g., Ostatné, Spotrebiteľské zmluvy, Spätvzatie, Zmluvy, Rozvod, Konkurz, etc.")
formaRozhodnutiaFacetFilter: Optional[List[str]] = Field(None, description="Form of decision (facet filter), e.g., Uznesenie, Rozsudok, Platobný rozkaz, Rozhodnutie, Rozsudok pre zmeškanie, Opatrenie, Príkaz, etc.")
povahaRozhodnutiaFacetFilter: Optional[str] = Field(None, description="Nature of decision, (e.g., Prvostupňové nenapadnuté opravnými prostriedkami, Potvrdzujúce, Potvrdené, Zmenené, Odmietajúce podanie, etc.)")
vydaniaOd: Optional[str] = Field(None, description="Issue date from (format DD.MM.YYYY)")
vydaniaDo: Optional[str] = Field(None, description="Issue date to (format DD.MM.YYYY)")
ecli: Optional[str] = Field(None, description="ECLI identifier (e.g., ECLI:SK:OSPO:1965:8114010264.1)")
spisovaZnacka: Optional[str] = Field(None, description="Case reference number (e.g., 7C/221/1991, 0Er/1966/1998)")
cisloSpisu: Optional[str] = Field(None, description="File identification number (e.g., 'identifikacneCislo': '8114010264')")
guidSudca: Optional[str] = Field(None, description="Judge identifier (e.g., sudca_1)")
guidSud: Optional[str] = Field(None, description="Court identifier (e.g., sud_100)")
indexDatumOd: Optional[str] = Field(None, description="Index date from (format YYYY-MM-DD)")
indexDatumDo: Optional[str] = Field(None, description="Index date to (format YYYY-MM-DD)")
sortProperty: Optional[str] = Field(None, description="Field to sort the output by")
sortDirection: Literal["ASC", "DESC"] = Field("ASC", description="Sort direction (ASC or DESC)")
page: Optional[conint(ge=1)] = Field(None, description="Requested page number (starting from 1)")
size: Optional[conint(ge=1)] = Field(None, description="Number of results per page")
class DecisionID(BaseModel):
id: str = Field(..., description="Decision identifier (e.g., a3310194-e9ac-4e6b-bfbd-25c40f26938b:1097de02-3389-405b-98a4-df7abea3f9ec)")
class DecisionAutocomplete(BaseModel):
query: str = Field(None, description="Search term or phrase to help find information")
guidSud: Optional[str] = Field(None, description="Court identifier (e.g., sud_100)")
limit: Optional[conint(ge=1)] = Field(None, description="Limits the number of returned results (pagination)")
"""Autocomplete pre rozhodnutia. GET /v1/rozhodnutie/autocomplete"""
query: Annotated[Optional[str], Field(default=None, description="Hľadané slovo")] = None
guidSud: Annotated[Optional[str], Field(default=None, description="Identifikátor súdu")] = None
limit: Annotated[Optional[int], Field(default=None, ge=1, description="Maximálny počet výsledkov")] = None
# =================================================================================================================
# CIVIL PROCEEDINGS SCHEMAS
# =================================================================================================================
####################################################################################################################
# .../v1/zmluvy
####################################################################################################################
class CivilProceedings(BaseModel):
query: str = Field(None, description="Search term or phrase to help find information")
typSuduFacetFilter: Optional[List[str]] = Field(None, description="Court types (facet filter), e.g., Okresný súd, Krajský súd, Najvyšší súd SR, Špecializovaný trestný súd, etc.")
krajFacetFilter: Optional[List[str]] = Field(None, description="Regions (facet filter), e.g., Bratislavský kraj, Košický kraj, Prešovský kraj, etc.")
okresFacetFilter: Optional[List[str]] = Field(None, description="Districts (facet filter), e.g., Okres Banská Bystrica, Okres Bratislava I, Okres Košice I, etc.")
usekFacetFilter: Optional[List[str]] = Field(None, description="List of sections (facet filter), e.g., C, O, S")
formaUkonuFacetFilter: Optional[List[str]] = Field(None, description="List of action types (facet filter), e.g., Pojednávanie bez rozhodnutia, Pojednávanie a rozhodnutie, Verejné vyhlásenie rozsudku, Vyhlásenie rozsudku, Predbežné prejednanie sporu")
pojednavaniaOd: Optional[str] = Field(None, description="Hearing date from (DD.MM.YYYY)")
pojednavaniaDo: Optional[str] = Field(None, description="Hearing date to (DD.MM.YYYY)")
guidSudca: Optional[str] = Field(None, description="Judge identifier (e.g., sudca_1)")
guidSud: Optional[str] = Field(None, description="Court identifier (e.g., sud_100)")
spisovaZnacka: Optional[str] = Field(None, description="Case reference number (e.g., 7C/221/1991, 0Er/1966/1998)")
verejneVyhlasenie: Optional[bool] = Field(None,description="Flag indicating whether the announcement is public")
indexDatumOd: Optional[str] = Field(None, description="Index date from (format YYYY-MM-DD)")
indexDatumDo: Optional[str] = Field(None, description="Index date to (format YYYY-MM-DD)")
sortProperty: Optional[str] = Field(None, description="Field to sort the output by")
sortDirection: Literal["ASC", "DESC"] = Field("ASC", description="Sort direction (ASC or DESC)")
page: Optional[conint(ge=1)] = Field(None, description="Requested page number (starting from 1)")
size: Optional[conint(ge=1)] = Field(None, description="Number of results per page")
class ContractSearch(PaginatedRequest):
"""Zoznam zmlúv s voliteľnými filtrami. GET /v1/zmluvy"""
query: Annotated[Optional[str], Field(default=None, description="Hľadané slovo alebo slovné spojenie")] = None
typDokumentuFacetFilter: Annotated[
Optional[List[str]],
Field(default=None, description="Typ dokumentu, napr. ['FAKTURA', 'OBJEDNAVKA', 'ZMLUVA', 'DODATOK']")
] = None
odberatelFacetFilter: Annotated[
Optional[List[str]],
Field(default=None, description="Odberateľ (súd), napr. ['Krajský súd v Bratislave']")
] = None
dodavatelFacetFilter: Annotated[
Optional[List[str]],
Field(default=None, description="Dodávateľ, napr. ['Slovak Telekom, a.s.']")
] = None
hodnotaZmluvyFacetFilter: Annotated[
Optional[List[str]],
Field(default=None, description="Hodnota zmluvy: '0-1000', '1000-20000', '20000-100000', '100000-500000', 'Viac ako 500000'")
] = None
datumZverejeneniaOd: Annotated[Optional[str], Field(default=None, description="Dátum zverejnenia od")] = None
datumZverejeneniaDo: Annotated[Optional[str], Field(default=None, description="Dátum zverejnenia do")] = None
guidSud: Annotated[Optional[str], Field(default=None, description="Identifikátor súdu, napr. 'sud_100'")] = None
indexDatumOd: Annotated[Optional[str], Field(default=None, description="Dátum indexácie od")] = None
indexDatumDo: Annotated[Optional[str], Field(default=None, description="Dátum indexácie do")] = None
class ContractByID(BaseModel):
"""Jedna zmluva podľa ID. GET /v1/zmluvy/{idZmluvy}"""
idZmluvy: Annotated[str, Field(description="Identifikátor zmluvy, napr. '2156252'")]
class ContractAutocomplete(BaseModel):
"""Autocomplete pre zmluvy. GET /v1/zmluvy/autocomplete"""
query: Annotated[Optional[str], Field(default=None, description="Hľadané slovo")] = None
guidSud: Annotated[Optional[str], Field(default=None, description="Identifikátor súdu")] = None
limit: Annotated[Optional[int], Field(default=None, ge=1, description="Maximálny počet výsledkov")] = None
####################################################################################################################
# .../v1/obcianPojednavania
####################################################################################################################
class CivilProceedingsSearch(PaginatedRequest):
"""Zoznam občianskych pojednávaní. GET /v1/obcianPojednavania"""
query: Annotated[Optional[str], Field(default=None, description="Hľadané slovo alebo slovné spojenie")] = None
typSuduFacetFilter: Annotated[Optional[List[str]], Field(default=None, description="Typ súdu (fazetový filter)")] = None
krajFacetFilter: Annotated[Optional[List[str]], Field(default=None, description="Kraj (fazetový filter)")] = None
okresFacetFilter: Annotated[Optional[List[str]], Field(default=None, description="Okres (fazetový filter)")] = None
usekFacetFilter: Annotated[
Optional[List[str]],
Field(default=None, description="Úsek (fazetový filter), napr. ['C', 'O', 'S']")
] = None
formaUkonuFacetFilter: Annotated[
Optional[List[str]],
Field(default=None, description="Forma úkonu, napr. ['Pojednávanie bez rozhodnutia', 'Pojednávanie a rozhodnutie']")
] = None
pojednavaniaOd: Annotated[Optional[str], Field(default=None, description="Pojednávania od (DD.MM.YYYY)")] = None
pojednavaniaDo: Annotated[Optional[str], Field(default=None, description="Pojednávania do (DD.MM.YYYY)")] = None
guidSudca: Annotated[Optional[str], Field(default=None, description="Identifikátor sudcu, napr. 'sudca_1'")] = None
guidSud: Annotated[Optional[str], Field(default=None, description="Identifikátor súdu, napr. 'sud_100'")] = None
spisovaZnacka: Annotated[Optional[str], Field(default=None, description="Spisová značka, napr. '7C/221/1991'")] = None
verejneVyhlasenie: Annotated[Optional[bool], Field(default=None, description="Verejné vyhlásenie")] = None
indexDatumOd: Annotated[Optional[str], Field(default=None, description="Dátum indexácie od")] = None
indexDatumDo: Annotated[Optional[str], Field(default=None, description="Dátum indexácie do")] = None
class CivilProceedingsByID(BaseModel):
"""Jedno pojednávanie podľa ID. GET /v1/obcianPojednavania/{id}"""
id: Annotated[str, Field(description="Identifikátor, napr. '121e4d31-695e-41e1-9191-7c9ad5d8d484'")]
class CivilProceedingsID(BaseModel):
id: str = Field(..., description="Identifier (e.g., 121e4d31-695e-41e1-9191-7c9ad5d8d484)")
class CivilProceedingsAutocomplete(BaseModel):
query: str = Field(None, description="Search term or phrase to help find information")
guidSud: Optional[str] = Field(None, description="Court identifier (e.g., sud_100)")
guidSudca: Optional[str] = Field(None, description="Judge identifier (e.g., sudca_1)")
verejneVyhlasenie: Optional[bool] = Field(None,description="Flag indicating whether the announcement is public")
limit: Optional[conint(ge=1)] = Field(None, description="Limits the number of returned results (pagination)")
"""Autocomplete pre občianske pojednávania. GET /v1/obcianPojednavania/autocomplete"""
query: Annotated[Optional[str], Field(default=None, description="Hľadané slovo")] = None
guidSud: Annotated[Optional[str], Field(default=None, description="Identifikátor súdu")] = None
guidSudca: Annotated[Optional[str], Field(default=None, description="Identifikátor sudcu")] = None
verejneVyhlasenie: Annotated[Optional[bool], Field(default=None, description="Verejné vyhlásenie")] = None
limit: Annotated[Optional[int], Field(default=None, ge=1, description="Maximálny počet výsledkov")] = None
# =================================================================================================================
# ADMINISTRATIVE PROCEEDINGS SCHEMAS
# =================================================================================================================
####################################################################################################################
# .../v1/spravneKonanie
####################################################################################################################
class AdministrativeProceedings(BaseModel):
query: str = Field(None, description="Search term or phrase to help find information")
druhFacetFilter: Optional[List[str]] = Field(None, description="List of types (faceted filter), e.g., Konanie o inom správnom delikte podľa § 27 ods. 1 písm. b) ZZTP, onanie o inom správnom delikte podľa § 26 ods. 1 písm. a) ZZTP v znení účinnom od 1. júla 2018, etc.")
datumPravoplatnostiOd: Optional[str] = Field(None, description="Validity date from (DD.MM.YYYY)")
datumPravoplatnostiDo: Optional[str] = Field(None, description="Validity date to (DD.MM.YYYY)")
page: Optional[conint(ge=1)] = Field(None, description="Requested page number (starting from 1)")
size: Optional[conint(ge=1)] = Field(None, description="Number of results per page")
sortProperty: Optional[str] = Field(None, description="Field to sort the output by")
sortDirection: Literal["ASC", "DESC"] = Field("ASC", description="Sort direction (ASC or DESC)")
class AdminProceedingsSearch(PaginatedRequest):
"""Zoznam správnych konaní. GET /v1/spravneKonanie"""
query: Annotated[Optional[str], Field(default=None, description="Hľadané slovo alebo slovné spojenie")] = None
druhFacetFilter: Annotated[
Optional[List[str]],
Field(default=None, description="Druh konania (fazetový filter)")
] = None
datumPravoplatnostiOd: Annotated[
Optional[str],
Field(default=None, description="Dátum právoplatnosti od (DD.MM.YYYY)")
] = None
datumPravoplatnostiDo: Annotated[
Optional[str],
Field(default=None, description="Dátum právoplatnosti do (DD.MM.YYYY)")
] = None
class AdministrativeProceedingsID(BaseModel):
id: str = Field(..., description="Identifier of administrative proceedings (e.g., spravneKonanie_103)")
class AdministrativeProceedingsAutocomplete(BaseModel):
query: str = Field(None, description="Search term or phrase to help find information")
limit: Optional[conint(ge=1)] = Field(None, description="Limits the number of returned results (pagination)")
class AdminProceedingsByID(BaseModel):
"""Jedno správne konanie podľa ID. GET /v1/spravneKonanie/{id}"""
id: Annotated[str, Field(description="Identifikátor, napr. 'spravneKonanie_103'")]
@field_validator("id")
@classmethod
def normalize(cls, v: str) -> str:
v = v.strip()
return f"spravneKonanie_{v}" if v.isdigit() else v
class AdminProceedingsAutocomplete(BaseModel):
"""Autocomplete pre správne konania. GET /v1/spravneKonanie/autocomplete"""
query: Annotated[Optional[str], Field(default=None, description="Hľadané slovo")] = None
limit: Annotated[Optional[int], Field(default=None, ge=1, description="Maximálny počet výsledkov")] = None

View File

@ -1,23 +1,19 @@
from api.fetch_api_data import fetch_api_data, docstring_from_model
from api.fetch_api_data import fetch_api_data
from api.schemas import (AdministrativeProceedings,
AdministrativeProceedingsID,
AdministrativeProceedingsAutocomplete)
from api.schemas import (AdminProceedingsSearch,
AdminProceedingsByID,
AdminProceedingsAutocomplete)
from agents import function_tool
from api.config import JUSTICE_API_BASE
class AdminProceedingsAPI:
@function_tool
@docstring_from_model(AdministrativeProceedings)
async def admin_proceedings(self, params: AdministrativeProceedings) -> dict:
async def admin_proceedings(self, params: AdminProceedingsSearch) -> dict:
"""
Fetch a list of administrative proceedings from the Justice API with optional filtering.
Args:
params (AdministrativeProceedings): Filtering and pagination parameters.
{params}
params (AdminProceedingsSearch): Filtering and pagination parameters.
Returns:
dict: A dictionary containing a list of administrative proceedings and related metadata.
"""
@ -26,15 +22,11 @@ class AdminProceedingsAPI:
return await fetch_api_data(icon="✒️", url=url, params=params.model_dump(exclude_none=True))
@function_tool
@docstring_from_model(AdministrativeProceedingsID)
async def admin_proceedings_id(self, params: AdministrativeProceedingsID) -> dict:
async def admin_proceedings_id(self, params: AdminProceedingsByID) -> dict:
"""
Fetch detailed information about a specific administrative proceeding by its identifier.
Args:
params (AdministrativeProceedingsID): Unique identifier of the administrative proceeding.
{params}
params (AdminProceedingsByID): Unique identifier of the administrative proceeding.
Returns:
dict: Details of the specified administrative proceeding.
"""
@ -43,15 +35,11 @@ class AdminProceedingsAPI:
return await fetch_api_data(icon="✒️", url=url, params={})
@function_tool
@docstring_from_model(AdministrativeProceedingsAutocomplete)
async def admin_proceedings_autocomplete(self, params: AdministrativeProceedingsAutocomplete) -> dict:
async def admin_proceedings_autocomplete(self, params: AdminProceedingsAutocomplete) -> dict:
"""
Fetch autocomplete suggestions for administrative proceeding search terms.
Args:
params (AdministrativeProceedingsAutocomplete): Parameters for autocomplete query (e.g., partial text).
{params}
params (AdminProceedingsAutocomplete): Parameters for autocomplete query (e.g., partial text).
Returns:
dict: Suggested values matching the input query.
"""

View File

@ -1,6 +1,6 @@
from api.fetch_api_data import fetch_api_data, docstring_from_model
from api.schemas import (CivilProceedings,
CivilProceedingsID,
from api.fetch_api_data import fetch_api_data
from api.schemas import (CivilProceedingsSearch,
CivilProceedingsByID,
CivilProceedingsAutocomplete)
from agents import function_tool
from api.config import JUSTICE_API_BASE
@ -9,15 +9,13 @@ from api.config import JUSTICE_API_BASE
class CivilProceedingsAPI:
@function_tool
@docstring_from_model(CivilProceedings)
async def civil_proceedings(self, params: CivilProceedings) -> dict:
async def civil_proceedings(self, params: CivilProceedingsSearch) -> dict:
"""
Fetch a list of civil proceedings and publicly announced judgments
from the Justice API with optional filtering.
Args:
params (CivilProceedings): Filtering and pagination parameters.
{params}
params (CivilProceedingsSearch): Filtering and pagination parameters.
Returns:
dict: A dictionary containing a list of civil proceedings and related metadata.
@ -27,15 +25,13 @@ class CivilProceedingsAPI:
return await fetch_api_data(icon="🖊️", url=url, params=params.model_dump(exclude_none=True))
@function_tool
@docstring_from_model(CivilProceedingsID)
async def civil_proceedings_id(self, params: CivilProceedingsID) -> dict:
async def civil_proceedings_id(self, params: CivilProceedingsByID) -> dict:
"""
Fetch detailed information about a specific civil proceeding
and publicly announced judgment by its identifier.
Args:
params (CivilProceedingsID): Unique identifier of the civil proceeding.
{params}
params (CivilProceedingsByID): Unique identifier of the civil proceeding.
Returns:
dict: Details of the specified civil proceeding and judgment.
@ -45,14 +41,12 @@ class CivilProceedingsAPI:
return await fetch_api_data(icon="🖊️", url=url, params={})
@function_tool
@docstring_from_model(CivilProceedingsAutocomplete)
async def civil_proceedings_autocomplete(self, params: CivilProceedingsAutocomplete) -> dict:
"""
Fetch autocomplete suggestions for civil proceeding search terms.
Args:
params (CivilProceedingsAutocomplete): Parameters for autocomplete query (e.g., partial text).
{params}
Returns:
dict: Suggested values matching the input query.

View File

@ -1,19 +1,17 @@
from api.fetch_api_data import fetch_api_data, docstring_from_model
from api.schemas import Contracts, ContractID, ContractAutocomplete
from api.fetch_api_data import fetch_api_data
from api.schemas import ContractSearch, ContractByID, ContractAutocomplete
from agents import function_tool
from api.config import JUSTICE_API_BASE
class ContractsAPI:
@function_tool
@docstring_from_model(Contracts)
async def contract(self, params: Contracts) -> dict:
async def contract(self, params: ContractSearch) -> dict:
"""
Fetch a list of contracts from the Justice API with optional filtering.
Args:
params (Contracts): Filtering and pagination parameters.
{params}
params (ContractSearch): Filtering and pagination parameters.
Returns:
dict: A dictionary containing a list of contracts and related metadata.
@ -24,14 +22,12 @@ class ContractsAPI:
@function_tool
@docstring_from_model(ContractID)
async def contract_id(self, params: ContractID) -> dict:
async def contract_id(self, params: ContractByID) -> dict:
"""
Fetch detailed information about a specific contract by its identifier.
Args:
params (ContractID): Unique identifier of the contract.
{params}
params (ContractByID): Unique identifier of the contract.
Returns:
dict: Details of the specified contract.
@ -41,14 +37,12 @@ class ContractsAPI:
return await fetch_api_data(icon="📃", url=url, params={})
@function_tool
@docstring_from_model(ContractAutocomplete)
async def contract_autocomplete(self, params: ContractAutocomplete) -> dict:
"""
Fetch autocomplete suggestions for contract-related search terms.
Args:
params (ContractAutocomplete): Parameters for autocomplete query (e.g., partial text).
{params}
Returns:
dict: Suggested values matching the input query.

View File

@ -1,20 +1,16 @@
from api.fetch_api_data import fetch_api_data, docstring_from_model
from api.schemas import Court, CourtID, CourtAutocomplete
from api.fetch_api_data import fetch_api_data
from api.schemas import CourtSearch, CourtByID, CourtAutocomplete
from agents import function_tool
from api.config import JUSTICE_API_BASE
class CourtsAPI:
@function_tool
@docstring_from_model(Court)
async def court(self, params: Court) -> dict:
async def court(self, params: CourtSearch) -> dict:
"""
Fetch a list of courts from the Justice API with optional filtering.
Args:
params (Court): Filtering and pagination parameters.
{params}
params (CourtSearch): Filtering and pagination parameters.
Returns:
dict: A dictionary containing a list of courts and related metadata.
"""
@ -23,15 +19,11 @@ class CourtsAPI:
return await fetch_api_data(icon="🏛️️", url=url, params=params.model_dump(exclude_none=True))
@function_tool
@docstring_from_model(CourtID)
async def court_id(self, params: CourtID) -> dict:
async def court_id(self, params: CourtByID) -> dict:
"""
Fetch detailed information about a specific court by its identifier.
Args:
params (CourtID): Unique identifier of the court.
{params}
params (CourtByID): Unique identifier of the court.
Returns:
dict: Details of the specified court.
"""
@ -40,15 +32,11 @@ class CourtsAPI:
return await fetch_api_data(icon="🏛️️", url=url, params={}, remove_keys=['foto'])
@function_tool
@docstring_from_model(CourtAutocomplete)
async def court_autocomplete(self, params: CourtAutocomplete) -> dict:
"""
Fetch autocomplete suggestions for court names.
Args:
params (CourtAutocomplete): Parameters for autocomplete.
{params}
Returns:
dict: Suggested court names matching the input query.
"""

View File

@ -1,20 +1,16 @@
from api.fetch_api_data import fetch_api_data, docstring_from_model
from api.schemas import Decision, DecisionID, DecisionAutocomplete
from api.fetch_api_data import fetch_api_data
from api.schemas import DecisionSearch, DecisionByID, DecisionAutocomplete
from agents import function_tool
from api.config import JUSTICE_API_BASE
class DecisionsAPI:
@function_tool
@docstring_from_model(Decision)
async def decision(self, params: Decision) -> dict:
async def decision(self, params: DecisionSearch) -> dict:
"""
Fetch a list of decisions from the Justice API with optional filtering.
Args:
params (Decision): Filtering and pagination parameters.
{params}
params (DecisionSearch): Filtering and pagination parameters.
Returns:
dict: A dictionary containing a list of decisions and related metadata.
"""
@ -24,15 +20,11 @@ class DecisionsAPI:
@function_tool
@docstring_from_model(DecisionID)
async def decision_id(self, params: DecisionID) -> dict:
async def decision_id(self, params: DecisionByID) -> dict:
"""
Fetch detailed information about a specific decision by its identifier.
Args:
params (DecisionID): Unique identifier of the decision.
{params}
params (DecisionByID): Unique identifier of the decision.
Returns:
dict: Details of the specified decision.
"""
@ -41,15 +33,11 @@ class DecisionsAPI:
return await fetch_api_data(icon="⚖️️", url=url, params={})
@function_tool
@docstring_from_model(DecisionAutocomplete)
async def decision_autocomplete(self, params: DecisionAutocomplete) -> dict:
"""
Fetch autocomplete suggestions for decision-related search terms.
Args:
params (DecisionAutocomplete): Parameters for autocomplete.
{params}
Returns:
dict: Suggested values matching the input query.
"""

View File

@ -1,5 +1,5 @@
from api.fetch_api_data import fetch_api_data, docstring_from_model
from api.schemas import Judge, JudgeID, JudgeAutocomplete
from api.fetch_api_data import fetch_api_data
from api.schemas import JudgeSearch, JudgeByID, JudgeAutocomplete
from agents import function_tool
from api.config import JUSTICE_API_BASE
@ -7,15 +7,11 @@ from api.config import JUSTICE_API_BASE
class JudgesAPI:
@function_tool
@docstring_from_model(Judge)
async def judge(self, params: Judge) -> dict:
async def judge(self, params: JudgeSearch) -> dict:
"""
Fetch a list of judges from the Justice API with optional filtering.
Args:
params (Judge): Filtering and pagination parameters.
{params}
params (JudgeSearch): Filtering and pagination parameters.
Returns:
dict: A dictionary containing a list of judges and related metadata.
"""
@ -25,15 +21,11 @@ class JudgesAPI:
@function_tool
@docstring_from_model(JudgeID)
async def judge_id(self, params: JudgeID) -> dict:
async def judge_id(self, params: JudgeByID) -> dict:
"""
Fetch detailed information about a specific judge by their identifier.
Args:
params (JudgeID): Unique identifier of the judge.
{params}
params (JudgeByID): Unique identifier of the judge.
Returns:
dict: Details of the specified judge.
"""
@ -43,15 +35,11 @@ class JudgesAPI:
@function_tool
@docstring_from_model(JudgeAutocomplete)
async def judge_autocomplete(self, params: JudgeAutocomplete) -> dict:
"""
Fetch autocomplete suggestions for judges' names.
Args:
params (JudgeAutocomplete): Parameters for autocomplete query (e.g., partial name).
{params}
Returns:
dict: Suggested judge names matching the input query.
"""

View File

@ -1,106 +1,163 @@
def get_system_prompt(model_name: str) -> str:
system_prompt = f"""
# Legal AI Assistant Slovak Ministry of Justice API
## Role
You are a **Legal AI Assistant** powered by {model_name}, integrated with the **official public APIs of the Ministry of Justice of the Slovak Republic**.
Your primary responsibility is to:
- Extract **structured parameters** from **natural-language user queries**
- Validate those parameters
- Retrieve data **exclusively** via registered API tools
- Present results in a **clear, human-friendly Slovak language format**
You act strictly as an **API data interpreter**, not as a legal advisor.
---
## Operational Constraints
- You **can** briefly explain your AI model, its creator, and how it differs from others
- You **can** list what you are not allowed to disclose if the user wants to know.
- Use **only data returned by official Ministry of Justice APIs**
- Do **not** use external legal knowledge
- Do **not** infer, speculate, or fill gaps beyond API responses
- Do **not** mention APIs, tools, schemas, function names, or internal logic in final answers
---
## Supported Legal Domains
You may process queries related to:
- Judges
- Courts
- Judicial Decisions
- Contracts
- Civil Proceedings
- Administrative Proceedings
Each domain provides:
- General search
- Search by ID
- Autocomplete / suggestion search
**Rule:** Always use the most specific tool available.
---
## Mandatory Processing Workflow
1. **Intent Detection**
Identify the legal domain and user intent.
2. **Parameter Extraction**
Extract names, IDs, keywords, court levels, regions, dates, statuses, and filters.
3. **Input Normalization**
Automatically normalize common user errors when possible:
- `Okresný súd v Košice` `Okresný súd v Košiciach`
- `12 decembra 2024` `12.12.2024`
- `175` `sud_175`
4. **Validation**
Validate parameters against expected schemas.
5. **Tool Invocation**
Call the appropriate registered API tool.
6. **Result Handling**
- Success summarize results clearly
- Empty result explain that no data was found
- Error explain the issue politely and clearly
7. **Response Generation**
Produce a **final response in Slovak**, understandable to non-experts.
---
## Response Requirements
Final responses must:
- Be written **only in Slovak**
- Be friendly, clear, and concise
- Use emojis **sparingly** for readability
- Present multiple results as lists or structured sections
- Never expose internal system details
---
## Error Recovery Guidance
If no data is found:
- Calmly explain the reason
- Suggest corrected spellings, formats, or rephrasing when applicable
---
## Example Behavior
**User:**
Find judge Novák in Bratislava
**Expected Handling:**
- Domain: Judges
- Use autocomplete or filtered search
- Return a list of matching judges with court, status, and region
- Output in Slovak with clear formatting
"""
return system_prompt
return f"""
# Legal AI Assistant Slovak Ministry of Justice API
**Powered by:** {model_name}
## Role
You are a Legal AI Assistant integrated with the official public APIs of the Ministry of Justice of the Slovak Republic.
You extract structured parameters from natural-language queries, call the correct API tools, and present results clearly in Slovak.
You are strictly an API data interpreter not a legal advisor.
---
## Operational Constraints
- Use ONLY data returned by official Ministry of Justice APIs
- You may briefly explain your AI model and how it differs from others
- You may list what you are not allowed to disclose
- Do NOT use external legal knowledge or training data to answer legal questions
- Do NOT infer, speculate, or fill gaps beyond API responses
- Do NOT mention APIs, tools, schemas, function names, or internal logic in final answers
- Do NOT expose pagination details, raw JSON, or technical errors to the user
---
## Supported Legal Domains
Judges (Sudcovia) : search, search by ID, autocomplete
Courts (Súdy) : search, search by ID, autocomplete
Decisions (Rozhodnutia) : search, search by ID, autocomplete
Contracts (Zmluvy) : search, search by ID, autocomplete
Civil Proceedings (Občianske konania) : search, search by ID, autocomplete
Administrative Proceedings (Správne konania) : search, search by ID, autocomplete
**Rule:** Always use the most specific tool available. Prefer autocomplete for name-based lookups.
---
## Mandatory Processing Workflow
### Step 1 — Intent Detection
Identify the legal domain and intent:
- Searching by name use autocomplete first
- Searching by known ID use ID-specific tool
- Broad search with filters use general search
### Step 2 — Input Normalization
Automatically fix common user errors BEFORE calling any tool:
- Slovak diacritics: `Novak` try both `Novak` AND `Novák`; `Kos` `Košice`
- Court names: `Okresný súd v Košice` `Okresný súd Košice I`
- Dates: `12 decembra 2024` `12.12.2024`; `december 2024` `01.12.2024` to `31.12.2024`
- IDs: `175` `sud_175`; `sudca 42` `sudca_42`
- Region names: always use full form with "kraj": `Bratislava` `Bratislavský kraj`
### Step 3 — Name Search Strategy (CRITICAL)
When searching by person name, ALWAYS follow this order:
1. **First: call `judge_autocomplete`** (or equivalent autocomplete for other domains)
- Use the name as `query`, set `limit=10`
- This returns exact name matches regardless of alphabetical pagination
2. **If autocomplete returns results:** use the returned IDs to call `judge_id` for full details
3. **If autocomplete returns nothing:** fall back to general search with `query=name` and `size=50`
4. **Never** rely on page 0 of general search results when looking for a specific name results are alphabetical and the person may be on page 10+
### Step 4 — Diacritics Handling (CRITICAL)
Slovak names with special characters (á, é, í, ó, ú, ý, ä, č, ď, ě, ľ, ĺ, ň, ô, ŕ, š, ť, ž) must be handled carefully:
- Always attempt the search with the diacritics-correct form first: `Novák`, not `Novak`
- If no results, retry without diacritics: `Novak`
- If still no results, try common variants: `Nováková`, `Novakova`
- Inform the user which variant was used
### Step 5 — Pagination Handling
- Default API page size is 20. Total results may be 2365+ for broad queries.
- When total results > available results shown, always inform the user there are more
- Suggest filtering by region (kraj), court type, or status to narrow results
- Never silently show only page 1 without mentioning it's a subset
### Step 6 — Parameter Validation
Before calling any tool, validate:
- Date formats match the expected format for that endpoint (DD.MM.YYYY or YYYY-MM-DD check per tool)
- IDs follow the correct prefix pattern (sud_, sudca_, spravneKonanie_, etc.)
- Facet filter values are from known valid options (e.g. region names are exact API values)
- `page` is 1 (never 0)
### Step 7 — Tool Invocation
Call the appropriate tool with validated, normalized parameters.
If a parameter is uncertain (e.g., user gave an ambiguous court name), either:
- Ask the user to confirm before calling, OR
- Use autocomplete to find the correct value first
### Step 8 — Result Handling
Results found : Summarize clearly, show structured list
Empty results : Explain calmly, suggest alternatives
📄 Partial results (paginated) : Show what was found, mention total count, suggest filtering
API error : Inform user politely, suggest retry
### Step 9 — Response Generation
Always respond in **Slovak**. Format rules:
- Use numbered lists for multiple results
- Show: name, role/function, court, region, status (active/inactive)
- Keep responses concise do not dump raw data
- Use emojis sparingly ( 🔍 only)
- Never show IDs, URLs, parameter names, or technical details
---
## Error Recovery Playbook
Name not found on page 0 -> Use autocomplete, do NOT report "not found"
Diacritics mismatch -> Try both forms, report which was used
Too many results (>100) -> Ask user to specify region, court, or time period
Unknown court name -> Use court autocomplete to find correct name
Date format unclear -> Ask user to confirm or infer from context
ID format wrong -> Normalize automatically (add prefix)
---
## Response Format Examples
**Single judge found:**
```
Našiel som sudcu Novák:
Meno: JUDr. Ján Novák
Funkcia: Sudca
Súd: Okresný súd Bratislava I
Kraj: Bratislavský kraj
Stav: aktívny
```
**Multiple results:**
```
Našiel som 5 sudcov s menom Novák (zobrazujem všetkých 5):
1. JUDr. Ján Novák Okresný súd Bratislava I (aktívny)
2. JUDr. Peter Novák Krajský súd Košice (aktívny)
...
```
**Paginated results:**
```
Celkovo: 2 365 výsledkov. Zobrazujem prvých 10.
Pre presnejšie výsledky uveďte kraj alebo typ súdu.
1. JUDr. Alena Adamcová Najvyšší súd SR (aktívny)
...
```
**Not found:**
```
Nenašiel som sudcu s menom "Novak" v Bratislavskom kraji.
Možné dôvody:
Meno môže mať diakritiku: skúste "Novák"
Sudca môže pôsobiť v inom kraji
Skúste rozšíriť vyhľadávanie na celú SR
Chcete, aby som hľadal "Novák" namiesto "Novak"?
```
---
## What You Are NOT
- Not a lawyer do not give legal advice
- Not a historian do not explain legal history beyond API data
- Not a search engine only search within Ministry of Justice API
- Not multilingual by default always respond in Slovak unless explicitly asked otherwise
"""