create tools.py

This commit is contained in:
G0DSEND016 2026-03-16 05:19:48 +01:00
parent 801a453a2f
commit 397cc2158e
11 changed files with 356 additions and 361 deletions

284
api/tools.py Normal file
View File

@ -0,0 +1,284 @@
from agents import function_tool
from api.fetch_api_data import fetch_api_data
from api.schemas import (
CourtSearch, CourtByID, CourtAutocomplete,
JudgeSearch, JudgeByID, JudgeAutocomplete,
DecisionSearch, DecisionByID, DecisionAutocomplete,
ContractSearch, ContractByID, ContractAutocomplete,
CivilProceedingsSearch, CivilProceedingsByID, CivilProceedingsAutocomplete,
AdminProceedingsSearch, AdminProceedingsByID, AdminProceedingsAutocomplete,
)
from api.config import JUSTICE_API_BASE
####################################################################################################################
# .../v1/sud
####################################################################################################################
@function_tool
async def court_search(params: CourtSearch) -> dict:
"""
Fetch a list of courts from the Justice API with optional filtering.
Args:
params (CourtSearch): Filtering and pagination parameters.
Returns:
dict: A dictionary containing a list of courts and related metadata.
"""
url = f"{JUSTICE_API_BASE}/v1/sud"
return await fetch_api_data(icon="🏛️️", url=url, params=params.model_dump(exclude_none=True))
@function_tool
async def court_id(params: CourtByID) -> dict:
"""
Fetch detailed information about a specific court by its identifier.
Args:
params (CourtByID): Unique identifier of the court.
Returns:
dict: Details of the specified court.
"""
url = f"{JUSTICE_API_BASE}/v1/sud/{params.id}"
return await fetch_api_data(icon="🏛️️", url=url, params={}, remove_keys=['foto'])
@function_tool
async def court_autocomplete(params: CourtAutocomplete) -> dict:
"""
Fetch autocomplete suggestions for court names.
Args:
params (CourtAutocomplete): Parameters for autocomplete.
Returns:
dict: Suggested court names matching the input query.
"""
url = f"{JUSTICE_API_BASE}/v1/sud/autocomplete"
return await fetch_api_data(icon="🏛️️", url=url, params=params.model_dump(exclude_none=True))
####################################################################################################################
# .../v1/sudca
####################################################################################################################
@function_tool
async def judge_search(params: JudgeSearch) -> dict:
"""
Fetch a list of judges from the Justice API with optional filtering.
Args:
params (JudgeSearch): Filtering and pagination parameters.
Returns:
dict: A dictionary containing a list of judges and related metadata.
"""
url = f"{JUSTICE_API_BASE}/v1/sudca"
return await fetch_api_data(icon="🧑‍⚖️", url=url, params=params.model_dump(exclude_none=True), remove_keys=['sudcaMapList'])
@function_tool
async def judge_id(params: JudgeByID) -> dict:
"""
Fetch detailed information about a specific judge by their identifier.
Args:
params (JudgeByID): Unique identifier of the judge.
Returns:
dict: Details of the specified judge.
"""
url = f"{JUSTICE_API_BASE}/v1/sudca/{params.id}"
return await fetch_api_data(icon="🧑‍⚖️", url=url, params={})
@function_tool
async def judge_autocomplete(params: JudgeAutocomplete) -> dict:
"""
Fetch autocomplete suggestions for judges' names.
Args:
params (JudgeAutocomplete): Parameters for autocomplete query (e.g., partial name).
Returns:
dict: Suggested judge names matching the input query.
"""
url = f"{JUSTICE_API_BASE}/v1/sudca/autocomplete"
return await fetch_api_data(icon="🧑‍⚖️", url=url, params=params.model_dump(exclude_none=True))
####################################################################################################################
# .../v1/rozhodnutie
####################################################################################################################
@function_tool
async def decision_search(params: DecisionSearch) -> dict:
"""
Fetch a list of decisions from the Justice API with optional filtering.
Args:
params (DecisionSearch): Filtering and pagination parameters.
Returns:
dict: A dictionary containing a list of decisions and related metadata.
"""
url = f"{JUSTICE_API_BASE}/v1/rozhodnutie"
return await fetch_api_data(icon="⚖️️", url=url, params=params.model_dump(exclude_none=True))
@function_tool
async def decision_id(params: DecisionByID) -> dict:
"""
Fetch detailed information about a specific decision by its identifier.
Args:
params (DecisionByID): Unique identifier of the decision.
Returns:
dict: Details of the specified decision.
"""
url = f"{JUSTICE_API_BASE}/v1/rozhodnutie/{params.id}"
return await fetch_api_data(icon="⚖️️", url=url, params={})
@function_tool
async def decision_autocomplete(params: DecisionAutocomplete) -> dict:
"""
Fetch autocomplete suggestions for decision-related search terms.
Args:
params (DecisionAutocomplete): Parameters for autocomplete.
Returns:
dict: Suggested values matching the input query.
"""
url = f"{JUSTICE_API_BASE}/v1/rozhodnutie/autocomplete"
return await fetch_api_data(icon="⚖️️", url=url, params=params.model_dump(exclude_none=True))
####################################################################################################################
# .../v1/zmluvy
####################################################################################################################
@function_tool
async def contract_search(params: ContractSearch) -> dict:
"""
Fetch a list of contracts from the Justice API with optional filtering.
Args:
params (ContractSearch): Filtering and pagination parameters.
Returns:
dict: A dictionary containing a list of contracts and related metadata.
"""
url = f"{JUSTICE_API_BASE}/v1/zmluvy"
return await fetch_api_data(icon="📃", url=url, params=params.model_dump(exclude_none=True))
@function_tool
async def contract_id(params: ContractByID) -> dict:
"""
Fetch detailed information about a specific contract by its identifier.
Args:
params (ContractByID): Unique identifier of the contract.
Returns:
dict: Details of the specified contract.
"""
url = f"{JUSTICE_API_BASE}/v1/zmluvy/{params.idZmluvy}"
return await fetch_api_data(icon="📃", url=url, params={})
@function_tool
async def contract_autocomplete(params: ContractAutocomplete) -> dict:
"""
Fetch autocomplete suggestions for contract-related search terms.
Args:
params (ContractAutocomplete): Parameters for autocomplete query (e.g., partial text).
Returns:
dict: Suggested values matching the input query.
"""
url = f"{JUSTICE_API_BASE}/v1/zmluvy/autocomplete"
return await fetch_api_data(icon="📃", url=url, params=params.model_dump(exclude_none=True))
####################################################################################################################
# .../v1/obcianPojednavania
####################################################################################################################
@function_tool
async def civil_proceedings_search(params: CivilProceedingsSearch) -> dict:
"""
Fetch a list of civil proceedings and publicly announced judgments
from the Justice API with optional filtering.
Args:
params (CivilProceedingsSearch): Filtering and pagination parameters.
Returns:
dict: A dictionary containing a list of civil proceedings and related metadata.
"""
url = f"{JUSTICE_API_BASE}/v1/obcianPojednavania"
return await fetch_api_data(icon="🖊️", url=url, params=params.model_dump(exclude_none=True))
@function_tool
async def civil_proceedings_id(params: CivilProceedingsByID) -> dict:
"""
Fetch detailed information about a specific civil proceeding
and publicly announced judgment by its identifier.
Args:
params (CivilProceedingsByID): Unique identifier of the civil proceeding.
Returns:
dict: Details of the specified civil proceeding and judgment.
"""
url = f"{JUSTICE_API_BASE}/v1/obcianPojednavania/{params.id}"
return await fetch_api_data(icon="🖊️", url=url, params={})
@function_tool
async def civil_proceedings_autocomplete(params: CivilProceedingsAutocomplete) -> dict:
"""
Fetch autocomplete suggestions for civil proceeding search terms.
Args:
params (CivilProceedingsAutocomplete): Parameters for autocomplete query (e.g., partial text).
Returns:
dict: Suggested values matching the input query.
"""
url = f"{JUSTICE_API_BASE}/v1/obcianPojednavania/autocomplete"
return await fetch_api_data(icon="🖊️", url=url, params=params.model_dump(exclude_none=True))
####################################################################################################################
# .../v1/spravneKonanie
####################################################################################################################
@function_tool
async def admin_proceedings_search(params: AdminProceedingsSearch) -> dict:
"""
Fetch a list of administrative proceedings from the Justice API with optional filtering.
Args:
params (AdminProceedingsSearch): Filtering and pagination parameters.
Returns:
dict: A dictionary containing a list of administrative proceedings and related metadata.
"""
url = f"{JUSTICE_API_BASE}/v1/spravneKonanie"
return await fetch_api_data(icon="✒️", url=url, params=params.model_dump(exclude_none=True))
@function_tool
async def admin_proceedings_id(params: AdminProceedingsByID) -> dict:
"""
Fetch detailed information about a specific administrative proceeding by its identifier.
Args:
params (AdminProceedingsByID): Unique identifier of the administrative proceeding.
Returns:
dict: Details of the specified administrative proceeding.
"""
url = f"{JUSTICE_API_BASE}/v1/spravneKonanie/{params.id}"
return await fetch_api_data(icon="✒️", url=url, params={})
@function_tool
async def admin_proceedings_autocomplete(params: AdminProceedingsAutocomplete) -> dict:
"""
Fetch autocomplete suggestions for administrative proceeding search terms.
Args:
params (AdminProceedingsAutocomplete): Parameters for autocomplete query (e.g., partial text).
Returns:
dict: Suggested values matching the input query.
"""
url = f"{JUSTICE_API_BASE}/v1/spravneKonanie/autocomplete"
return await fetch_api_data(icon="✒️", url=url, params=params.model_dump(exclude_none=True))
ALL_TOOLS = [
court_search, court_id, court_autocomplete,
judge_search, judge_id, judge_autocomplete,
decision_search, decision_id, decision_autocomplete,
contract_search, contract_id, contract_autocomplete,
civil_proceedings_search, civil_proceedings_id, civil_proceedings_autocomplete,
admin_proceedings_search, admin_proceedings_id, admin_proceedings_autocomplete,
]

View File

View File

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

View File

@ -1,56 +0,0 @@
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
class CivilProceedingsAPI:
@function_tool
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 (CivilProceedingsSearch): Filtering and pagination parameters.
Returns:
dict: A dictionary containing a list of civil proceedings and related metadata.
"""
url = f"{JUSTICE_API_BASE}/v1/obcianPojednavania"
return await fetch_api_data(icon="🖊️", url=url, params=params.model_dump(exclude_none=True))
@function_tool
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 (CivilProceedingsByID): Unique identifier of the civil proceeding.
Returns:
dict: Details of the specified civil proceeding and judgment.
"""
url = f"{JUSTICE_API_BASE}/v1/obcianPojednavania/{params.id}"
return await fetch_api_data(icon="🖊️", url=url, params={})
@function_tool
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).
Returns:
dict: Suggested values matching the input query.
"""
url = f"{JUSTICE_API_BASE}/v1/obcianPojednavania/autocomplete"
return await fetch_api_data(icon="🖊️", url=url, params=params.model_dump(exclude_none=True))

View File

@ -1,52 +0,0 @@
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
async def contract(self, params: ContractSearch) -> dict:
"""
Fetch a list of contracts from the Justice API with optional filtering.
Args:
params (ContractSearch): Filtering and pagination parameters.
Returns:
dict: A dictionary containing a list of contracts and related metadata.
"""
url = f"{JUSTICE_API_BASE}/v1/zmluvy"
return await fetch_api_data(icon="📃", url=url, params=params.model_dump(exclude_none=True))
@function_tool
async def contract_id(self, params: ContractByID) -> dict:
"""
Fetch detailed information about a specific contract by its identifier.
Args:
params (ContractByID): Unique identifier of the contract.
Returns:
dict: Details of the specified contract.
"""
url = f"{JUSTICE_API_BASE}/v1/zmluvy/{params.idZmluvy}"
return await fetch_api_data(icon="📃", url=url, params={})
@function_tool
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).
Returns:
dict: Suggested values matching the input query.
"""
url = f"{JUSTICE_API_BASE}/v1/zmluvy/autocomplete"
return await fetch_api_data(icon="📃", url=url, params=params.model_dump(exclude_none=True))

View File

@ -1,45 +0,0 @@
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
async def court(self, params: CourtSearch) -> dict:
"""
Fetch a list of courts from the Justice API with optional filtering.
Args:
params (CourtSearch): Filtering and pagination parameters.
Returns:
dict: A dictionary containing a list of courts and related metadata.
"""
url = f"{JUSTICE_API_BASE}/v1/sud"
return await fetch_api_data(icon="🏛️️", url=url, params=params.model_dump(exclude_none=True))
@function_tool
async def court_id(self, params: CourtByID) -> dict:
"""
Fetch detailed information about a specific court by its identifier.
Args:
params (CourtByID): Unique identifier of the court.
Returns:
dict: Details of the specified court.
"""
url = f"{JUSTICE_API_BASE}/v1/sud/{params.id}"
return await fetch_api_data(icon="🏛️️", url=url, params={}, remove_keys=['foto'])
@function_tool
async def court_autocomplete(self, params: CourtAutocomplete) -> dict:
"""
Fetch autocomplete suggestions for court names.
Args:
params (CourtAutocomplete): Parameters for autocomplete.
Returns:
dict: Suggested court names matching the input query.
"""
url = f"{JUSTICE_API_BASE}/v1/sud/autocomplete"
return await fetch_api_data(icon="🏛️️", url=url, params=params.model_dump(exclude_none=True))

View File

@ -1,46 +0,0 @@
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
async def decision(self, params: DecisionSearch) -> dict:
"""
Fetch a list of decisions from the Justice API with optional filtering.
Args:
params (DecisionSearch): Filtering and pagination parameters.
Returns:
dict: A dictionary containing a list of decisions and related metadata.
"""
url = f"{JUSTICE_API_BASE}/v1/rozhodnutie"
return await fetch_api_data(icon="⚖️️", url=url, params=params.model_dump(exclude_none=True))
@function_tool
async def decision_id(self, params: DecisionByID) -> dict:
"""
Fetch detailed information about a specific decision by its identifier.
Args:
params (DecisionByID): Unique identifier of the decision.
Returns:
dict: Details of the specified decision.
"""
url = f"{JUSTICE_API_BASE}/v1/rozhodnutie/{params.id}"
return await fetch_api_data(icon="⚖️️", url=url, params={})
@function_tool
async def decision_autocomplete(self, params: DecisionAutocomplete) -> dict:
"""
Fetch autocomplete suggestions for decision-related search terms.
Args:
params (DecisionAutocomplete): Parameters for autocomplete.
Returns:
dict: Suggested values matching the input query.
"""
url = f"{JUSTICE_API_BASE}/v1/rozhodnutie/autocomplete"
return await fetch_api_data(icon="⚖️️", url=url, params=params.model_dump(exclude_none=True))

View File

@ -1,48 +0,0 @@
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
class JudgesAPI:
@function_tool
async def judge(self, params: JudgeSearch) -> dict:
"""
Fetch a list of judges from the Justice API with optional filtering.
Args:
params (JudgeSearch): Filtering and pagination parameters.
Returns:
dict: A dictionary containing a list of judges and related metadata.
"""
url = f"{JUSTICE_API_BASE}/v1/sudca"
return await fetch_api_data(icon="🧑‍⚖️", url=url, params=params.model_dump(exclude_none=True), remove_keys=['sudcaMapList'])
@function_tool
async def judge_id(self, params: JudgeByID) -> dict:
"""
Fetch detailed information about a specific judge by their identifier.
Args:
params (JudgeByID): Unique identifier of the judge.
Returns:
dict: Details of the specified judge.
"""
url = f"{JUSTICE_API_BASE}/v1/sudca/{params.id}"
return await fetch_api_data(icon="🧑‍⚖️", url=url, params={})
@function_tool
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).
Returns:
dict: Suggested judge names matching the input query.
"""
url = f"{JUSTICE_API_BASE}/v1/sudca/autocomplete"
return await fetch_api_data(icon="🧑‍⚖️", url=url, params=params.model_dump(exclude_none=True))

2
app.py
View File

@ -62,7 +62,7 @@ async def main(message: cl.Message):
if len(history) > MAX_HISTORY: if len(history) > MAX_HISTORY:
history = history[-MAX_HISTORY:] history = history[-MAX_HISTORY:]
async with cl.Step(name="🔍 Fetching data...") as step: async with cl.Step(name="🔍 Fetching data...", type="run") as step:
log_lines = [] log_lines = []
def on_log(line: str): def on_log(line: str):

View File

@ -4,12 +4,7 @@ from agents import set_tracing_disabled
from core.config import DEFAULT_MODEL, OLLAMA_BASE_URL, OLLAMA_API_KEY, OLLAMA_TIMEOUT, AGENT_TEMPERATURE from core.config import DEFAULT_MODEL, OLLAMA_BASE_URL, OLLAMA_API_KEY, OLLAMA_TIMEOUT, AGENT_TEMPERATURE
from core.system_prompt import get_system_prompt from core.system_prompt import get_system_prompt
from api.tools.judges import JudgesAPI from api.tools import ALL_TOOLS
from api.tools.courts import CourtsAPI
from api.tools.contracts import ContractsAPI
from api.tools.decisions import DecisionsAPI
from api.tools.admin_proceedings import AdminProceedingsAPI
from api.tools.civil_proceedings import CivilProceedingsAPI
set_tracing_disabled(True) set_tracing_disabled(True)
@ -22,13 +17,6 @@ class MyAgentHooks(AgentHooks):
def assistant_agent(model_name: str = DEFAULT_MODEL) -> Agent: def assistant_agent(model_name: str = DEFAULT_MODEL) -> Agent:
judge_api = JudgesAPI()
court_api = CourtsAPI()
contract_api = ContractsAPI()
decision_api = DecisionsAPI()
admin_proceedings_api = AdminProceedingsAPI()
civil_proceedings_api = CivilProceedingsAPI()
client = AsyncOpenAI( client = AsyncOpenAI(
base_url=OLLAMA_BASE_URL, base_url=OLLAMA_BASE_URL,
api_key=OLLAMA_API_KEY, api_key=OLLAMA_API_KEY,
@ -42,16 +30,7 @@ def assistant_agent(model_name: str = DEFAULT_MODEL) -> Agent:
instructions=get_system_prompt(model_name), instructions=get_system_prompt(model_name),
model=model, model=model,
model_settings=ModelSettings(temperature=AGENT_TEMPERATURE, tool_choice="auto", parallel_tool_calls=False), model_settings=ModelSettings(temperature=AGENT_TEMPERATURE, tool_choice="auto", parallel_tool_calls=False),
tools=[ tools=ALL_TOOLS,
judge_api.judge, judge_api.judge_id, judge_api.judge_autocomplete,
court_api.court, court_api.court_id, court_api.court_autocomplete,
contract_api.contract, contract_api.contract_id, contract_api.contract_autocomplete,
decision_api.decision, decision_api.decision_id, decision_api.decision_autocomplete,
admin_proceedings_api.admin_proceedings, admin_proceedings_api.admin_proceedings_id,
admin_proceedings_api.admin_proceedings_autocomplete,
civil_proceedings_api.civil_proceedings, civil_proceedings_api.civil_proceedings_id,
civil_proceedings_api.civil_proceedings_autocomplete,
],
tool_use_behavior="run_llm_again", tool_use_behavior="run_llm_again",
reset_tool_choice=True, reset_tool_choice=True,
hooks=MyAgentHooks(), hooks=MyAgentHooks(),

View File

@ -4,14 +4,14 @@ def get_system_prompt(model_name: str) -> str:
return f""" return f"""
# Legal AI Assistant Slovak Ministry of Justice API # Legal AI Assistant Slovak Ministry of Justice API
**Powered by:** {model_name} **Powered by:** {model_name}
## Role ## Role
You are a Legal AI Assistant 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 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. You are strictly an API data interpreter not a legal advisor.
--- ---
## Operational Constraints ## Operational Constraints
- Use ONLY data returned by official Ministry of Justice APIs - 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 briefly explain your AI model and how it differs from others
@ -20,9 +20,9 @@ def get_system_prompt(model_name: str) -> str:
- Do NOT infer, speculate, or fill gaps beyond API responses - 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 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 - Do NOT expose pagination details, raw JSON, or technical errors to the user
--- ---
## Supported Legal Domains ## Supported Legal Domains
Judges (Sudcovia) : search, search by ID, autocomplete Judges (Sudcovia) : search, search by ID, autocomplete
Courts (Súdy) : search, search by ID, autocomplete Courts (Súdy) : search, search by ID, autocomplete
@ -30,78 +30,103 @@ def get_system_prompt(model_name: str) -> str:
Contracts (Zmluvy) : search, search by ID, autocomplete Contracts (Zmluvy) : search, search by ID, autocomplete
Civil Proceedings (Občianske konania) : 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 Administrative Proceedings (Správne konania) : search, search by ID, autocomplete
**Rule:** Always use the most specific tool available. Prefer autocomplete for name-based lookups. **Rule:** Always use the most specific tool available. Prefer autocomplete for name-based lookups.
--- ---
## Mandatory Processing Workflow ## Mandatory Processing Workflow
### Step 1 — Intent Detection ### Step 1 — Intent Detection
Identify the legal domain and intent: Identify the legal domain and intent:
- Searching by name use autocomplete first - Searching by name use autocomplete first
- Searching by known ID use ID-specific tool - Searching by known ID use ID-specific tool
- Broad search with filters use general search - Broad search with filters use general search
### Step 2 — Input Normalization ### Step 2 — Input Normalization
Automatically fix common user errors BEFORE calling any tool: Automatically fix common user errors BEFORE calling any tool:
- Slovak diacritics: `Novak` try both `Novak` AND `Novák`; `Kos` `Košice` - 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` - 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` - Dates: `12 decembra 2024` `12.12.2024`; `december 2024` `01.12.2024` to `31.12.2024`; `január 2024` `01.01.2024` to `31.01.2024`
- IDs: `175` `sud_175`; `sudca 42` `sudca_42` - IDs: `175` `sud_175`; `sudca 42` `sudca_42`
- Region names: always use full form with "kraj": `Bratislava` `Bratislavský kraj` - Region names: always use full form with "kraj": `Bratislava` `Bratislavský kraj`
### Step 3 — Name Search Strategy (CRITICAL) ### Step 3 — Name Search Strategy (CRITICAL)
When searching by person name, ALWAYS follow this order: When searching by person name, ALWAYS follow this order:
1. **First: call `judge_autocomplete`** (or equivalent autocomplete for other domains) 1. **First: call `judge_autocomplete`** (or equivalent autocomplete for other domains)
- Use the name as `query`, set `limit=10` - Use the name as `query`, set `limit=10`
- This returns exact name matches regardless of alphabetical pagination - 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 2. **If autocomplete returns results:** use the returned IDs to call `judge_by_id` for full details
3. **If autocomplete returns nothing:** fall back to general search with `query=name` and `size=50` 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+ 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) ### Step 4 — Court-to-Filter Chaining (CRITICAL)
When a user mentions a specific court by name AND requests data from another domain (judges, contracts, proceedings):
1. First call `court_autocomplete` to find the court and get its ID (e.g. `sud_123`)
2. Then pass that ID as `guidSud` in the next search call
3. NEVER search judges/contracts/proceedings without `guidSud` when the user specified a court
Example:
- User: "Zmluvy Krajského súdu v Bratislave"
- Step 1: court_autocomplete(query="Krajský súd v Bratislave") returns id: "sud_7"
- Step 2: contract_search(guidSud="sud_7")
- WRONG: contract_search() without guidSud
### Step 5 — Diacritics Handling (CRITICAL)
Slovak names with special characters (á, é, í, ó, ú, ý, ä, č, ď, ě, ľ, ĺ, ň, ô, ŕ, š, ť, ž) must be handled carefully: Slovak names with special characters (á, é, í, ó, ú, ý, ä, č, ď, ě, ľ, ĺ, ň, ô, ŕ, š, ť, ž) must be handled carefully:
- Always attempt the search with the diacritics-correct form first: `Novák`, not `Novak` - Always attempt the search with the diacritics-correct form first: `Novák`, not `Novak`
- If no results, retry without diacritics: `Novak` - If no results, retry without diacritics: `Novak`
- If still no results, try common variants: `Nováková`, `Novakova` - If still no results, try common variants: `Nováková`, `Novakova`
- Inform the user which variant was used - Inform the user which variant was used
### Step 5 — Pagination Handling ### Step 6 — Pagination Handling (CRITICAL)
- **page starts at 0, NOT 1. First page = page=0. Second page = page=1.**
- Default API page size is 20. Total results may be 2365+ for broad queries. - 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 - 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 - Suggest filtering by region (kraj), court type, or status to narrow results
- Never silently show only page 1 without mentioning it's a subset - Never silently show only page 0 without mentioning it's a subset
### Step 6 — Parameter Validation ### Step 7 — Date Parameters (CRITICAL)
Always extract AND pass date parameters when the user mentions any time period:
- "v januári 2024" `pojednavaniaOd="01.01.2024"`, `pojednavaniaDo="31.01.2024"`
- "december 2024" `vydaniaOd="01.12.2024"`, `vydaniaDo="31.12.2024"`
- "v roku 2023" use full year range Od="01.01.2023", Do="31.12.2023"
- NEVER ignore a date or time period mentioned by the user
- Each endpoint uses a different date field use the correct one per domain:
- Civil proceedings: `pojednavaniaOd` / `pojednavaniaDo`
- Decisions: `vydaniaOd` / `vydaniaDo`
- Contracts: `datumZverejeneniaOd` / `datumZverejeneniaDo`
- Administrative proceedings: `datumPravoplatnostiOd` / `datumPravoplatnostiDo`
### Step 8 — Parameter Validation
Before calling any tool, validate: Before calling any tool, validate:
- Date formats match the expected format for that endpoint (DD.MM.YYYY or YYYY-MM-DD check per tool) - Date formats match the expected format for that endpoint (DD.MM.YYYY check per tool)
- IDs follow the correct prefix pattern (sud_, sudca_, spravneKonanie_, etc.) - 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) - Facet filter values are from known valid options (e.g. region names are exact API values)
- `page` is 1 (never 0) - `page` starts at 0 never use negative values
### Step 7 — Tool Invocation ### Step 9 — Tool Invocation
Call the appropriate tool with validated, normalized parameters. Call the appropriate tool with validated, normalized parameters.
If a parameter is uncertain (e.g., user gave an ambiguous court name), either: If a parameter is uncertain (e.g., user gave an ambiguous court name), either:
- Ask the user to confirm before calling, OR - Ask the user to confirm before calling, OR
- Use autocomplete to find the correct value first - Use autocomplete to find the correct value first
### Step 8 — Result Handling ### Step 10 — Result Handling
Results found : Summarize clearly, show structured list Results found : Summarize clearly, show structured list
Empty results : Explain calmly, suggest alternatives Empty results : Explain calmly, suggest alternatives
📄 Partial results (paginated) : Show what was found, mention total count, suggest filtering 📄 Partial results (paginated) : Show what was found, mention total count, suggest filtering
API error : Inform user politely, suggest retry API error : Inform user politely, suggest retry
### Step 9 — Response Generation ### Step 11 — Response Generation
Always respond in **Slovak**. Format rules: Always respond in **Slovak**. Format rules:
- Use numbered lists for multiple results - Use numbered lists for multiple results
- Show: name, role/function, court, region, status (active/inactive) - Show: name, role/function, court, region, status (active/inactive)
- Keep responses concise do not dump raw data - Keep responses concise do not dump raw data
- Use emojis sparingly ( 🔍 only) - Use emojis sparingly ( 🔍 only)
- Never show IDs, URLs, parameter names, or technical details - Never show IDs, URLs, parameter names, or technical details
--- ---
## Error Recovery Playbook ## Error Recovery Playbook
Name not found on page 0 -> Use autocomplete, do NOT report "not found" Name not found on page 0 -> Use autocomplete, do NOT report "not found"
Diacritics mismatch -> Try both forms, report which was used Diacritics mismatch -> Try both forms, report which was used
@ -109,11 +134,13 @@ def get_system_prompt(model_name: str) -> str:
Unknown court name -> Use court autocomplete to find correct name Unknown court name -> Use court autocomplete to find correct name
Date format unclear -> Ask user to confirm or infer from context Date format unclear -> Ask user to confirm or infer from context
ID format wrong -> Normalize automatically (add prefix) ID format wrong -> Normalize automatically (add prefix)
Court mentioned but guidSud missing -> Always resolve court ID via autocomplete first
Date mentioned but not passed -> Always extract and pass date parameters
--- ---
## Response Format Examples ## Response Format Examples
**Single judge found:** **Single judge found:**
``` ```
Našiel som sudcu Novák: Našiel som sudcu Novák:
@ -123,7 +150,7 @@ def get_system_prompt(model_name: str) -> str:
Kraj: Bratislavský kraj Kraj: Bratislavský kraj
Stav: aktívny Stav: aktívny
``` ```
**Multiple results:** **Multiple results:**
``` ```
Našiel som 5 sudcov s menom Novák (zobrazujem všetkých 5): Našiel som 5 sudcov s menom Novák (zobrazujem všetkých 5):
@ -131,30 +158,30 @@ def get_system_prompt(model_name: str) -> str:
2. JUDr. Peter Novák Krajský súd Košice (aktívny) 2. JUDr. Peter Novák Krajský súd Košice (aktívny)
... ...
``` ```
**Paginated results:** **Paginated results:**
``` ```
Celkovo: 2 365 výsledkov. Zobrazujem prvých 10. Celkovo: 2 365 výsledkov. Zobrazujem prvých 20.
Pre presnejšie výsledky uveďte kraj alebo typ súdu. Pre presnejšie výsledky uveďte kraj alebo typ súdu.
1. JUDr. Alena Adamcová Najvyšší súd SR (aktívny) 1. JUDr. Alena Adamcová Najvyšší súd SR (aktívny)
... ...
``` ```
**Not found:** **Not found:**
``` ```
Nenašiel som sudcu s menom "Novak" v Bratislavskom kraji. Nenašiel som sudcu s menom "Novak" v Bratislavskom kraji.
Možné dôvody: Možné dôvody:
Meno môže mať diakritiku: skúste "Novák" Meno môže mať diakritiku: skúste "Novák"
Sudca môže pôsobiť v inom kraji Sudca môže pôsobiť v inom kraji
Skúste rozšíriť vyhľadávanie na celú SR Skúste rozšíriť vyhľadávanie na celú SR
Chcete, aby som hľadal "Novák" namiesto "Novak"? Chcete, aby som hľadal "Novák" namiesto "Novak"?
``` ```
--- ---
## What You Are NOT ## What You Are NOT
- Not a lawyer do not give legal advice - Not a lawyer do not give legal advice
- Not a historian do not explain legal history beyond API data - Not a historian do not explain legal history beyond API data