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 httpx
import logging import logging
import json import json
from pydantic import BaseModel
from cachetools import TTLCache from cachetools import TTLCache
from typing import Callable from typing import Callable
from tenacity import retry, stop_after_attempt, wait_exponential from tenacity import retry, stop_after_attempt, wait_exponential
@ -35,18 +34,6 @@ _client = httpx.AsyncClient(
max_keepalive_connections=HTTP_MAX_KEEPALIVE), 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 _log_callback: Callable[[str], None] | None = None
def set_log_callback(cb: Callable[[str], 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 Annotated, List, Literal, Optional
from typing import Optional, List, Literal from pydantic import BaseModel, Field, field_validator
# ================================================================================================================= class SortableMixin(BaseModel):
# COURT SCHEMAS 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): class PaginatedRequest(SortableMixin):
id: str = Field(..., description="Court identifier (e.g., sud_175)") 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): class CourtAutocomplete(BaseModel):
query: str = Field(None, description="Search term or phrase to help find information") """Autocomplete pre názvy súdov. GET /v1/sud/autocomplete"""
limit: Optional[conint(ge=1)] = Field(None, description="Limits the number of returned results (pagination)") 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): class JudgeSearch(BaseModel):
query: str = Field(None, description="Search term or phrase to help find information") """Zoznam sudcov s voliteľnými filtrami. GET /v1/sudca"""
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") query: Annotated[
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.") Optional[str],
krajFacetFilter: Optional[List[str]] = Field(None, description="Regions (facet filter), e.g., Bratislavský kraj, Košický kraj, Prešovský kraj, etc.") Field(default=None, description="Hľadané slovo alebo slovné spojenie")
okresFacetFilter: Optional[List[str]] = Field(None, description="Districts (facet filter), e.g., Okres Banská Bystrica, Okres Bratislava I, Okres Košice I, etc.") ] = None
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") funkciaFacetFilter: Annotated[
guidSud: Optional[str] = Field(None, description="Court identifier (e.g., sud_100)") Optional[List[str]],
indexDatumOd: Optional[str] = Field(None, description="Index date from (format YYYY.MM.DD or DD.MM.YYYY)") Field(default=None, description="Funkcia (fazetový filter), napr. ['Sudca', 'Predseda', 'Podpredseda']")
indexDatumDo: Optional[str] = Field(None, description="Index date to (format YYYY.MM.DD or DD.MM.YYYY)") ] = None
page: Optional[conint(ge=1)] = Field(None, description="Requested page number (starting from 1)") typSuduFacetFilter: Annotated[
size: Optional[conint(ge=1)] = Field(None, description="Number of results per page") Optional[List[str]],
sortProperty: Optional[str] = Field(None, description="Field to sort the output by") Field(default=None, description="Typ súdu (fazetový filter)")
sortDirection: Literal["ASC", "DESC"] = Field("ASC", description="Sort direction (ASC or DESC)") ] = 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): 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)") Autocomplete pre mená sudcov. GET /v1/sudca/autocomplete
limit: Optional[conint(ge=1)] = Field(None, description="Limits the number of returned results (pagination)") 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): class DecisionSearch(PaginatedRequest):
query: str = Field(None, description="Search term or phrase to help find information") """Zoznam rozhodnutí s voliteľnými filtrami. GET /v1/rozhodnutie"""
typDokumentuFacetFilter: Optional[List[str]] = Field(None, description="Contract's type (facet filter), e.g., FAKTURA, OBJEDNAVKA, ZMLUVA, DODATOK") query: Annotated[Optional[str], Field(default=None, description="Hľadané slovo alebo slovné spojenie")] = None
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.") typSuduFacetFilter: Annotated[Optional[List[str]], Field(default=None, description="Typ súdu (fazetový filter)")] = None
dodavatelFacetFilter: Optional[List[str]] = Field(None, description="Supplier filter. Examples: Slovak Telekom, a.s., Wolters Kluwer s.r.o., Tibor Varga TSV Papier") krajFacetFilter: Annotated[Optional[List[str]], Field(default=None, description="Kraj (fazetový filter)")] = None
hodnotaZmluvyFacetFilter: Optional[List[str]] = Field(None, description="Contract value range filter. Options: '0-1000', '1000-20000', '20000-100000', '100000-500000', 'Viac ako 500000'") okresFacetFilter: Annotated[Optional[List[str]], Field(default=None, description="Okres (fazetový filter)")] = None
datumZverejeneniaOd: Optional[str] = Field(None, description="Index date from (format YYYY-MM-DD)") oblastPravnejUpravyFacetFilter: Annotated[
datumZverejeneniaDo: Optional[str] = Field(None, description="Index date to (format YYYY-MM-DD)") Optional[List[str]],
guidSud: Optional[str] = Field(None, description="Court identifier (e.g., sud_100)") Field(default=None, description="Oblasť právnej úpravy (fazetový filter)")
indexDatumOd: Optional[str] = Field(None, description="Index date from (format YYYY-MM-DD or DD-MM-YYYY)") ] = None
indexDatumDo: Optional[str] = Field(None, description="Index date to (format YYYY-MM-DD or DD-MM-YYYY)") podOblastPravnejUpravyFacetFilter: Annotated[
sortProperty: Optional[str] = Field(None, description="Field to sort the output by") Optional[List[str]],
sortDirection: Literal["ASC", "DESC"] = Field("ASC", description="Sort direction (ASC or DESC)") Field(default=None, description="Podoblasť právnej úpravy (fazetový filter)")
page: Optional[conint(ge=1)] = Field(None, description="Requested page number (starting from 1)") ] = None
size: Optional[conint(ge=1)] = Field(None, description="Number of results per page") formaRozhodnutiaFacetFilter: Annotated[
Optional[List[str]],
class ContractID(BaseModel): Field(default=None, description="Forma rozhodnutia, napr. ['Uznesenie', 'Rozsudok', 'Platobný rozkaz']")
idZmluvy: str = Field(..., description="Contract identifier (e. g., 2156252)") ] = None
povahaRozhodnutiaFacetFilter: Annotated[
class ContractAutocomplete(BaseModel): Optional[str],
query: str = Field(None, description="Search term or phrase to help find information") Field(default=None, description="Povaha rozhodnutia")
guidSud: Optional[str] = Field(None, description="Court identifier (e.g., sud_100)") ] = None
limit: Optional[conint(ge=1)] = Field(None, description="Limits the number of returned results (pagination)") 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
# ================================================================================================================= class DecisionByID(BaseModel):
# DECISION SCHEMAS """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): class DecisionAutocomplete(BaseModel):
query: str = Field(None, description="Search term or phrase to help find information") """Autocomplete pre rozhodnutia. GET /v1/rozhodnutie/autocomplete"""
guidSud: Optional[str] = Field(None, description="Court identifier (e.g., sud_100)") query: Annotated[Optional[str], Field(default=None, description="Hľadané slovo")] = None
limit: Optional[conint(ge=1)] = Field(None, description="Limits the number of returned results (pagination)") 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): class ContractSearch(PaginatedRequest):
query: str = Field(None, description="Search term or phrase to help find information") """Zoznam zmlúv s voliteľnými filtrami. GET /v1/zmluvy"""
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.") query: Annotated[Optional[str], Field(default=None, description="Hľadané slovo alebo slovné spojenie")] = None
krajFacetFilter: Optional[List[str]] = Field(None, description="Regions (facet filter), e.g., Bratislavský kraj, Košický kraj, Prešovský kraj, etc.") typDokumentuFacetFilter: Annotated[
okresFacetFilter: Optional[List[str]] = Field(None, description="Districts (facet filter), e.g., Okres Banská Bystrica, Okres Bratislava I, Okres Košice I, etc.") Optional[List[str]],
usekFacetFilter: Optional[List[str]] = Field(None, description="List of sections (facet filter), e.g., C, O, S") Field(default=None, description="Typ dokumentu, napr. ['FAKTURA', 'OBJEDNAVKA', 'ZMLUVA', 'DODATOK']")
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") ] = None
pojednavaniaOd: Optional[str] = Field(None, description="Hearing date from (DD.MM.YYYY)") odberatelFacetFilter: Annotated[
pojednavaniaDo: Optional[str] = Field(None, description="Hearing date to (DD.MM.YYYY)") Optional[List[str]],
guidSudca: Optional[str] = Field(None, description="Judge identifier (e.g., sudca_1)") Field(default=None, description="Odberateľ (súd), napr. ['Krajský súd v Bratislave']")
guidSud: Optional[str] = Field(None, description="Court identifier (e.g., sud_100)") ] = None
spisovaZnacka: Optional[str] = Field(None, description="Case reference number (e.g., 7C/221/1991, 0Er/1966/1998)") dodavatelFacetFilter: Annotated[
verejneVyhlasenie: Optional[bool] = Field(None,description="Flag indicating whether the announcement is public") Optional[List[str]],
indexDatumOd: Optional[str] = Field(None, description="Index date from (format YYYY-MM-DD)") Field(default=None, description="Dodávateľ, napr. ['Slovak Telekom, a.s.']")
indexDatumDo: Optional[str] = Field(None, description="Index date to (format YYYY-MM-DD)") ] = None
sortProperty: Optional[str] = Field(None, description="Field to sort the output by") hodnotaZmluvyFacetFilter: Annotated[
sortDirection: Literal["ASC", "DESC"] = Field("ASC", description="Sort direction (ASC or DESC)") Optional[List[str]],
page: Optional[conint(ge=1)] = Field(None, description="Requested page number (starting from 1)") Field(default=None, description="Hodnota zmluvy: '0-1000', '1000-20000', '20000-100000', '100000-500000', 'Viac ako 500000'")
size: Optional[conint(ge=1)] = Field(None, description="Number of results per page") ] = 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): class CivilProceedingsAutocomplete(BaseModel):
query: str = Field(None, description="Search term or phrase to help find information") """Autocomplete pre občianske pojednávania. GET /v1/obcianPojednavania/autocomplete"""
guidSud: Optional[str] = Field(None, description="Court identifier (e.g., sud_100)") query: Annotated[Optional[str], Field(default=None, description="Hľadané slovo")] = None
guidSudca: Optional[str] = Field(None, description="Judge identifier (e.g., sudca_1)") guidSud: Annotated[Optional[str], Field(default=None, description="Identifikátor súdu")] = None
verejneVyhlasenie: Optional[bool] = Field(None,description="Flag indicating whether the announcement is public") guidSudca: Annotated[Optional[str], Field(default=None, description="Identifikátor sudcu")] = None
limit: Optional[conint(ge=1)] = Field(None, description="Limits the number of returned results (pagination)") 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): class AdminProceedingsSearch(PaginatedRequest):
query: str = Field(None, description="Search term or phrase to help find information") """Zoznam správnych konaní. GET /v1/spravneKonanie"""
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.") query: Annotated[Optional[str], Field(default=None, description="Hľadané slovo alebo slovné spojenie")] = None
datumPravoplatnostiOd: Optional[str] = Field(None, description="Validity date from (DD.MM.YYYY)") druhFacetFilter: Annotated[
datumPravoplatnostiDo: Optional[str] = Field(None, description="Validity date to (DD.MM.YYYY)") Optional[List[str]],
page: Optional[conint(ge=1)] = Field(None, description="Requested page number (starting from 1)") Field(default=None, description="Druh konania (fazetový filter)")
size: Optional[conint(ge=1)] = Field(None, description="Number of results per page") ] = None
sortProperty: Optional[str] = Field(None, description="Field to sort the output by") datumPravoplatnostiOd: Annotated[
sortDirection: Literal["ASC", "DESC"] = Field("ASC", description="Sort direction (ASC or DESC)") 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): class AdminProceedingsByID(BaseModel):
query: str = Field(None, description="Search term or phrase to help find information") """Jedno správne konanie podľa ID. GET /v1/spravneKonanie/{id}"""
limit: Optional[conint(ge=1)] = Field(None, description="Limits the number of returned results (pagination)") 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, from api.schemas import (AdminProceedingsSearch,
AdministrativeProceedingsID, AdminProceedingsByID,
AdministrativeProceedingsAutocomplete) AdminProceedingsAutocomplete)
from agents import function_tool from agents import function_tool
from api.config import JUSTICE_API_BASE from api.config import JUSTICE_API_BASE
class AdminProceedingsAPI: class AdminProceedingsAPI:
@function_tool @function_tool
@docstring_from_model(AdministrativeProceedings) async def admin_proceedings(self, params: AdminProceedingsSearch) -> dict:
async def admin_proceedings(self, params: AdministrativeProceedings) -> dict:
""" """
Fetch a list of administrative proceedings from the Justice API with optional filtering. Fetch a list of administrative proceedings from the Justice API with optional filtering.
Args: Args:
params (AdministrativeProceedings): Filtering and pagination parameters. params (AdminProceedingsSearch): Filtering and pagination parameters.
{params}
Returns: Returns:
dict: A dictionary containing a list of administrative proceedings and related metadata. 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)) return await fetch_api_data(icon="✒️", url=url, params=params.model_dump(exclude_none=True))
@function_tool @function_tool
@docstring_from_model(AdministrativeProceedingsID) async def admin_proceedings_id(self, params: AdminProceedingsByID) -> dict:
async def admin_proceedings_id(self, params: AdministrativeProceedingsID) -> dict:
""" """
Fetch detailed information about a specific administrative proceeding by its identifier. Fetch detailed information about a specific administrative proceeding by its identifier.
Args: Args:
params (AdministrativeProceedingsID): Unique identifier of the administrative proceeding. params (AdminProceedingsByID): Unique identifier of the administrative proceeding.
{params}
Returns: Returns:
dict: Details of the specified administrative proceeding. dict: Details of the specified administrative proceeding.
""" """
@ -43,15 +35,11 @@ class AdminProceedingsAPI:
return await fetch_api_data(icon="✒️", url=url, params={}) return await fetch_api_data(icon="✒️", url=url, params={})
@function_tool @function_tool
@docstring_from_model(AdministrativeProceedingsAutocomplete) async def admin_proceedings_autocomplete(self, params: AdminProceedingsAutocomplete) -> dict:
async def admin_proceedings_autocomplete(self, params: AdministrativeProceedingsAutocomplete) -> dict:
""" """
Fetch autocomplete suggestions for administrative proceeding search terms. Fetch autocomplete suggestions for administrative proceeding search terms.
Args: Args:
params (AdministrativeProceedingsAutocomplete): Parameters for autocomplete query (e.g., partial text). params (AdminProceedingsAutocomplete): Parameters for autocomplete query (e.g., partial text).
{params}
Returns: Returns:
dict: Suggested values matching the input query. 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.fetch_api_data import fetch_api_data
from api.schemas import (CivilProceedings, from api.schemas import (CivilProceedingsSearch,
CivilProceedingsID, CivilProceedingsByID,
CivilProceedingsAutocomplete) CivilProceedingsAutocomplete)
from agents import function_tool from agents import function_tool
from api.config import JUSTICE_API_BASE from api.config import JUSTICE_API_BASE
@ -9,15 +9,13 @@ from api.config import JUSTICE_API_BASE
class CivilProceedingsAPI: class CivilProceedingsAPI:
@function_tool @function_tool
@docstring_from_model(CivilProceedings) async def civil_proceedings(self, params: CivilProceedingsSearch) -> dict:
async def civil_proceedings(self, params: CivilProceedings) -> dict:
""" """
Fetch a list of civil proceedings and publicly announced judgments Fetch a list of civil proceedings and publicly announced judgments
from the Justice API with optional filtering. from the Justice API with optional filtering.
Args: Args:
params (CivilProceedings): Filtering and pagination parameters. params (CivilProceedingsSearch): Filtering and pagination parameters.
{params}
Returns: Returns:
dict: A dictionary containing a list of civil proceedings and related metadata. 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)) return await fetch_api_data(icon="🖊️", url=url, params=params.model_dump(exclude_none=True))
@function_tool @function_tool
@docstring_from_model(CivilProceedingsID) async def civil_proceedings_id(self, params: CivilProceedingsByID) -> dict:
async def civil_proceedings_id(self, params: CivilProceedingsID) -> dict:
""" """
Fetch detailed information about a specific civil proceeding Fetch detailed information about a specific civil proceeding
and publicly announced judgment by its identifier. and publicly announced judgment by its identifier.
Args: Args:
params (CivilProceedingsID): Unique identifier of the civil proceeding. params (CivilProceedingsByID): Unique identifier of the civil proceeding.
{params}
Returns: Returns:
dict: Details of the specified civil proceeding and judgment. dict: Details of the specified civil proceeding and judgment.
@ -45,14 +41,12 @@ class CivilProceedingsAPI:
return await fetch_api_data(icon="🖊️", url=url, params={}) return await fetch_api_data(icon="🖊️", url=url, params={})
@function_tool @function_tool
@docstring_from_model(CivilProceedingsAutocomplete)
async def civil_proceedings_autocomplete(self, params: CivilProceedingsAutocomplete) -> dict: async def civil_proceedings_autocomplete(self, params: CivilProceedingsAutocomplete) -> dict:
""" """
Fetch autocomplete suggestions for civil proceeding search terms. Fetch autocomplete suggestions for civil proceeding search terms.
Args: Args:
params (CivilProceedingsAutocomplete): Parameters for autocomplete query (e.g., partial text). params (CivilProceedingsAutocomplete): Parameters for autocomplete query (e.g., partial text).
{params}
Returns: Returns:
dict: Suggested values matching the input query. 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.fetch_api_data import fetch_api_data
from api.schemas import Contracts, ContractID, ContractAutocomplete from api.schemas import ContractSearch, ContractByID, ContractAutocomplete
from agents import function_tool from agents import function_tool
from api.config import JUSTICE_API_BASE from api.config import JUSTICE_API_BASE
class ContractsAPI: class ContractsAPI:
@function_tool @function_tool
@docstring_from_model(Contracts) async def contract(self, params: ContractSearch) -> dict:
async def contract(self, params: Contracts) -> dict:
""" """
Fetch a list of contracts from the Justice API with optional filtering. Fetch a list of contracts from the Justice API with optional filtering.
Args: Args:
params (Contracts): Filtering and pagination parameters. params (ContractSearch): Filtering and pagination parameters.
{params}
Returns: Returns:
dict: A dictionary containing a list of contracts and related metadata. dict: A dictionary containing a list of contracts and related metadata.
@ -24,14 +22,12 @@ class ContractsAPI:
@function_tool @function_tool
@docstring_from_model(ContractID) async def contract_id(self, params: ContractByID) -> dict:
async def contract_id(self, params: ContractID) -> dict:
""" """
Fetch detailed information about a specific contract by its identifier. Fetch detailed information about a specific contract by its identifier.
Args: Args:
params (ContractID): Unique identifier of the contract. params (ContractByID): Unique identifier of the contract.
{params}
Returns: Returns:
dict: Details of the specified contract. dict: Details of the specified contract.
@ -41,14 +37,12 @@ class ContractsAPI:
return await fetch_api_data(icon="📃", url=url, params={}) return await fetch_api_data(icon="📃", url=url, params={})
@function_tool @function_tool
@docstring_from_model(ContractAutocomplete)
async def contract_autocomplete(self, params: ContractAutocomplete) -> dict: async def contract_autocomplete(self, params: ContractAutocomplete) -> dict:
""" """
Fetch autocomplete suggestions for contract-related search terms. Fetch autocomplete suggestions for contract-related search terms.
Args: Args:
params (ContractAutocomplete): Parameters for autocomplete query (e.g., partial text). params (ContractAutocomplete): Parameters for autocomplete query (e.g., partial text).
{params}
Returns: Returns:
dict: Suggested values matching the input query. 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.fetch_api_data import fetch_api_data
from api.schemas import Court, CourtID, CourtAutocomplete from api.schemas import CourtSearch, CourtByID, CourtAutocomplete
from agents import function_tool from agents import function_tool
from api.config import JUSTICE_API_BASE from api.config import JUSTICE_API_BASE
class CourtsAPI: class CourtsAPI:
@function_tool @function_tool
@docstring_from_model(Court) async def court(self, params: CourtSearch) -> dict:
async def court(self, params: Court) -> dict:
""" """
Fetch a list of courts from the Justice API with optional filtering. Fetch a list of courts from the Justice API with optional filtering.
Args: Args:
params (Court): Filtering and pagination parameters. params (CourtSearch): Filtering and pagination parameters.
{params}
Returns: Returns:
dict: A dictionary containing a list of courts and related metadata. 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)) return await fetch_api_data(icon="🏛️️", url=url, params=params.model_dump(exclude_none=True))
@function_tool @function_tool
@docstring_from_model(CourtID) async def court_id(self, params: CourtByID) -> dict:
async def court_id(self, params: CourtID) -> dict:
""" """
Fetch detailed information about a specific court by its identifier. Fetch detailed information about a specific court by its identifier.
Args: Args:
params (CourtID): Unique identifier of the court. params (CourtByID): Unique identifier of the court.
{params}
Returns: Returns:
dict: Details of the specified court. dict: Details of the specified court.
""" """
@ -40,15 +32,11 @@ class CourtsAPI:
return await fetch_api_data(icon="🏛️️", url=url, params={}, remove_keys=['foto']) return await fetch_api_data(icon="🏛️️", url=url, params={}, remove_keys=['foto'])
@function_tool @function_tool
@docstring_from_model(CourtAutocomplete)
async def court_autocomplete(self, params: CourtAutocomplete) -> dict: async def court_autocomplete(self, params: CourtAutocomplete) -> dict:
""" """
Fetch autocomplete suggestions for court names. Fetch autocomplete suggestions for court names.
Args: Args:
params (CourtAutocomplete): Parameters for autocomplete. params (CourtAutocomplete): Parameters for autocomplete.
{params}
Returns: Returns:
dict: Suggested court names matching the input query. 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.fetch_api_data import fetch_api_data
from api.schemas import Decision, DecisionID, DecisionAutocomplete from api.schemas import DecisionSearch, DecisionByID, DecisionAutocomplete
from agents import function_tool from agents import function_tool
from api.config import JUSTICE_API_BASE from api.config import JUSTICE_API_BASE
class DecisionsAPI: class DecisionsAPI:
@function_tool @function_tool
@docstring_from_model(Decision) async def decision(self, params: DecisionSearch) -> dict:
async def decision(self, params: Decision) -> dict:
""" """
Fetch a list of decisions from the Justice API with optional filtering. Fetch a list of decisions from the Justice API with optional filtering.
Args: Args:
params (Decision): Filtering and pagination parameters. params (DecisionSearch): Filtering and pagination parameters.
{params}
Returns: Returns:
dict: A dictionary containing a list of decisions and related metadata. dict: A dictionary containing a list of decisions and related metadata.
""" """
@ -24,15 +20,11 @@ class DecisionsAPI:
@function_tool @function_tool
@docstring_from_model(DecisionID) async def decision_id(self, params: DecisionByID) -> dict:
async def decision_id(self, params: DecisionID) -> dict:
""" """
Fetch detailed information about a specific decision by its identifier. Fetch detailed information about a specific decision by its identifier.
Args: Args:
params (DecisionID): Unique identifier of the decision. params (DecisionByID): Unique identifier of the decision.
{params}
Returns: Returns:
dict: Details of the specified decision. dict: Details of the specified decision.
""" """
@ -41,15 +33,11 @@ class DecisionsAPI:
return await fetch_api_data(icon="⚖️️", url=url, params={}) return await fetch_api_data(icon="⚖️️", url=url, params={})
@function_tool @function_tool
@docstring_from_model(DecisionAutocomplete)
async def decision_autocomplete(self, params: DecisionAutocomplete) -> dict: async def decision_autocomplete(self, params: DecisionAutocomplete) -> dict:
""" """
Fetch autocomplete suggestions for decision-related search terms. Fetch autocomplete suggestions for decision-related search terms.
Args: Args:
params (DecisionAutocomplete): Parameters for autocomplete. params (DecisionAutocomplete): Parameters for autocomplete.
{params}
Returns: Returns:
dict: Suggested values matching the input query. 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.fetch_api_data import fetch_api_data
from api.schemas import Judge, JudgeID, JudgeAutocomplete from api.schemas import JudgeSearch, JudgeByID, JudgeAutocomplete
from agents import function_tool from agents import function_tool
from api.config import JUSTICE_API_BASE from api.config import JUSTICE_API_BASE
@ -7,15 +7,11 @@ from api.config import JUSTICE_API_BASE
class JudgesAPI: class JudgesAPI:
@function_tool @function_tool
@docstring_from_model(Judge) async def judge(self, params: JudgeSearch) -> dict:
async def judge(self, params: Judge) -> dict:
""" """
Fetch a list of judges from the Justice API with optional filtering. Fetch a list of judges from the Justice API with optional filtering.
Args: Args:
params (Judge): Filtering and pagination parameters. params (JudgeSearch): Filtering and pagination parameters.
{params}
Returns: Returns:
dict: A dictionary containing a list of judges and related metadata. dict: A dictionary containing a list of judges and related metadata.
""" """
@ -25,15 +21,11 @@ class JudgesAPI:
@function_tool @function_tool
@docstring_from_model(JudgeID) async def judge_id(self, params: JudgeByID) -> dict:
async def judge_id(self, params: JudgeID) -> dict:
""" """
Fetch detailed information about a specific judge by their identifier. Fetch detailed information about a specific judge by their identifier.
Args: Args:
params (JudgeID): Unique identifier of the judge. params (JudgeByID): Unique identifier of the judge.
{params}
Returns: Returns:
dict: Details of the specified judge. dict: Details of the specified judge.
""" """
@ -43,15 +35,11 @@ class JudgesAPI:
@function_tool @function_tool
@docstring_from_model(JudgeAutocomplete)
async def judge_autocomplete(self, params: JudgeAutocomplete) -> dict: async def judge_autocomplete(self, params: JudgeAutocomplete) -> dict:
""" """
Fetch autocomplete suggestions for judges' names. Fetch autocomplete suggestions for judges' names.
Args: Args:
params (JudgeAutocomplete): Parameters for autocomplete query (e.g., partial name). params (JudgeAutocomplete): Parameters for autocomplete query (e.g., partial name).
{params}
Returns: Returns:
dict: Suggested judge names matching the input query. dict: Suggested judge names matching the input query.
""" """

View File

@ -1,106 +1,163 @@
def get_system_prompt(model_name: str) -> str: def get_system_prompt(model_name: str) -> str:
system_prompt = f""" return f"""
# Legal AI Assistant Slovak Ministry of Justice API # Legal AI Assistant Slovak Ministry of Justice API
**Powered by:** {model_name}
## Role ## 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**. 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.
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
- 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
--- ---
## Operational Constraints ## Supported Legal Domains
- You **can** briefly explain your AI model, its creator, and how it differs from others Judges (Sudcovia) : search, search by ID, autocomplete
- You **can** list what you are not allowed to disclose if the user wants to know. Courts (Súdy) : search, search by ID, autocomplete
- Use **only data returned by official Ministry of Justice APIs** Decisions (Rozhodnutia) : search, search by ID, autocomplete
- Do **not** use external legal knowledge Contracts (Zmluvy) : search, search by ID, autocomplete
- Do **not** infer, speculate, or fill gaps beyond API responses Civil Proceedings (Občianske konania) : search, search by ID, autocomplete
- Do **not** mention APIs, tools, schemas, function names, or internal logic in final answers Administrative Proceedings (Správne konania) : search, search by ID, autocomplete
--- **Rule:** Always use the most specific tool available. Prefer autocomplete for name-based lookups.
## Supported Legal Domains ---
You may process queries related to:
- Judges
- Courts
- Judicial Decisions
- Contracts
- Civil Proceedings
- Administrative Proceedings
Each domain provides: ## Mandatory Processing Workflow
- General search
- Search by ID
- Autocomplete / suggestion search
**Rule:** Always use the most specific tool available. ### 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`
## Mandatory Processing Workflow ### Step 3 — Name Search Strategy (CRITICAL)
1. **Intent Detection** When searching by person name, ALWAYS follow this order:
Identify the legal domain and user intent. 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+
2. **Parameter Extraction** ### Step 4 — Diacritics Handling (CRITICAL)
Extract names, IDs, keywords, court levels, regions, dates, statuses, and filters. 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
3. **Input Normalization** ### Step 5 — Pagination Handling
Automatically normalize common user errors when possible: - Default API page size is 20. Total results may be 2365+ for broad queries.
- `Okresný súd v Košice` `Okresný súd v Košiciach` - When total results > available results shown, always inform the user there are more
- `12 decembra 2024` `12.12.2024` - Suggest filtering by region (kraj), court type, or status to narrow results
- `175` `sud_175` - Never silently show only page 1 without mentioning it's a subset
4. **Validation** ### Step 6 — Parameter Validation
Validate parameters against expected schemas. 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)
5. **Tool Invocation** ### Step 7 — Tool Invocation
Call the appropriate registered API tool. 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
6. **Result Handling** ### Step 8 — Result Handling
- Success summarize results clearly Results found : Summarize clearly, show structured list
- Empty result explain that no data was found Empty results : Explain calmly, suggest alternatives
- Error explain the issue politely and clearly 📄 Partial results (paginated) : Show what was found, mention total count, suggest filtering
API error : Inform user politely, suggest retry
7. **Response Generation** ### Step 9 — Response Generation
Produce a **final response in Slovak**, understandable to non-experts. 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
--- ---
## Response Requirements ## Error Recovery Playbook
Final responses must: Name not found on page 0 -> Use autocomplete, do NOT report "not found"
- Be written **only in Slovak** Diacritics mismatch -> Try both forms, report which was used
- Be friendly, clear, and concise Too many results (>100) -> Ask user to specify region, court, or time period
- Use emojis **sparingly** for readability Unknown court name -> Use court autocomplete to find correct name
- Present multiple results as lists or structured sections Date format unclear -> Ask user to confirm or infer from context
- Never expose internal system details ID format wrong -> Normalize automatically (add prefix)
--- ---
## Error Recovery Guidance ## Response Format Examples
If no data is found:
- Calmly explain the reason
- Suggest corrected spellings, formats, or rephrasing when applicable
--- **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
```
## Example Behavior **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)
...
```
**User:** **Paginated results:**
Find judge Novák in Bratislava ```
Celkovo: 2 365 výsledkov. Zobrazujem prvých 10.
Pre presnejšie výsledky uveďte kraj alebo typ súdu.
**Expected Handling:** 1. JUDr. Alena Adamcová Najvyšší súd SR (aktívny)
- Domain: Judges ...
- Use autocomplete or filtered search ```
- Return a list of matching judges with court, status, and region
- Output in Slovak with clear formatting **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
""" """
return system_prompt