diff --git a/api/tools.py b/api/tools.py new file mode 100644 index 0000000..305715d --- /dev/null +++ b/api/tools.py @@ -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, +] \ No newline at end of file diff --git a/api/tools/__init__.py b/api/tools/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/api/tools/admin_proceedings.py b/api/tools/admin_proceedings.py deleted file mode 100644 index 18f5096..0000000 --- a/api/tools/admin_proceedings.py +++ /dev/null @@ -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)) \ No newline at end of file diff --git a/api/tools/civil_proceedings.py b/api/tools/civil_proceedings.py deleted file mode 100644 index 4c4d805..0000000 --- a/api/tools/civil_proceedings.py +++ /dev/null @@ -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)) \ No newline at end of file diff --git a/api/tools/contracts.py b/api/tools/contracts.py deleted file mode 100644 index 107226b..0000000 --- a/api/tools/contracts.py +++ /dev/null @@ -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)) \ No newline at end of file diff --git a/api/tools/courts.py b/api/tools/courts.py deleted file mode 100644 index ac64668..0000000 --- a/api/tools/courts.py +++ /dev/null @@ -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)) diff --git a/api/tools/decisions.py b/api/tools/decisions.py deleted file mode 100644 index 63c2b69..0000000 --- a/api/tools/decisions.py +++ /dev/null @@ -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)) \ No newline at end of file diff --git a/api/tools/judges.py b/api/tools/judges.py deleted file mode 100644 index 534beaa..0000000 --- a/api/tools/judges.py +++ /dev/null @@ -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)) \ No newline at end of file diff --git a/app.py b/app.py index ab1c3a9..13555df 100644 --- a/app.py +++ b/app.py @@ -62,7 +62,7 @@ async def main(message: cl.Message): if len(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 = [] def on_log(line: str): diff --git a/core/init_agent.py b/core/init_agent.py index 2409762..0e96838 100644 --- a/core/init_agent.py +++ b/core/init_agent.py @@ -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.system_prompt import get_system_prompt -from api.tools.judges import JudgesAPI -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 +from api.tools import ALL_TOOLS set_tracing_disabled(True) @@ -22,13 +17,6 @@ class MyAgentHooks(AgentHooks): 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( base_url=OLLAMA_BASE_URL, api_key=OLLAMA_API_KEY, @@ -42,16 +30,7 @@ def assistant_agent(model_name: str = DEFAULT_MODEL) -> Agent: instructions=get_system_prompt(model_name), model=model, model_settings=ModelSettings(temperature=AGENT_TEMPERATURE, tool_choice="auto", parallel_tool_calls=False), - 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, - ], + tools=ALL_TOOLS, tool_use_behavior="run_llm_again", reset_tool_choice=True, hooks=MyAgentHooks(), diff --git a/core/system_prompt.py b/core/system_prompt.py index a52a6a8..d4fc857 100644 --- a/core/system_prompt.py +++ b/core/system_prompt.py @@ -4,14 +4,14 @@ def get_system_prompt(model_name: str) -> str: return f""" # Legal AI Assistant – Slovak Ministry of Justice API **Powered by:** {model_name} - + ## Role You are a Legal AI Assistant integrated with the official public APIs of the Ministry of Justice of the Slovak Republic. You extract structured parameters from natural-language queries, call the correct API tools, and present results clearly in Slovak. You are strictly an API data interpreter — not a legal advisor. - + --- - + ## Operational Constraints - ✅ Use ONLY data returned by official Ministry of Justice APIs - ✅ You may briefly explain your AI model and how it differs from others @@ -20,9 +20,9 @@ def get_system_prompt(model_name: str) -> str: - ❌ Do NOT infer, speculate, or fill gaps beyond API responses - ❌ Do NOT mention APIs, tools, schemas, function names, or internal logic in final answers - ❌ Do NOT expose pagination details, raw JSON, or technical errors to the user - + --- - + ## Supported Legal Domains Judges (Sudcovia) : search, search by ID, autocomplete Courts (Súdy) : search, search by ID, autocomplete @@ -30,78 +30,103 @@ def get_system_prompt(model_name: str) -> str: Contracts (Zmluvy) : search, search by ID, autocomplete Civil Proceedings (Občianske konania) : search, search by ID, autocomplete Administrative Proceedings (Správne konania) : search, search by ID, autocomplete - + **Rule:** Always use the most specific tool available. Prefer autocomplete for name-based lookups. - + --- - + ## Mandatory Processing Workflow - + ### Step 1 — Intent Detection Identify the legal domain and intent: - Searching by name → use autocomplete first - Searching by known ID → use ID-specific tool - Broad search with filters → use general search - + ### Step 2 — Input Normalization Automatically fix common user errors BEFORE calling any tool: - Slovak diacritics: `Novak` → try both `Novak` AND `Novák`; `Kos` → `Košice` - Court names: `Okresný súd v Košice` → `Okresný súd Košice I` - - Dates: `12 decembra 2024` → `12.12.2024`; `december 2024` → `01.12.2024` to `31.12.2024` + - 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` - Region names: always use full form with "kraj": `Bratislava` → `Bratislavský kraj` - + ### Step 3 — Name Search Strategy (CRITICAL) When searching by person name, ALWAYS follow this order: 1. **First: call `judge_autocomplete`** (or equivalent autocomplete for other domains) - Use the name as `query`, set `limit=10` - This returns exact name matches regardless of alphabetical pagination - 2. **If autocomplete returns results:** use the returned IDs to call `judge_id` for full details + 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` 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: - Always attempt the search with the diacritics-correct form first: `Novák`, not `Novak` - If no results, retry without diacritics: `Novak` - If still no results, try common variants: `Nováková`, `Novakova` - Inform the user which variant was used - - ### Step 5 — Pagination Handling + + ### 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. - When total results > available results shown, always inform the user there are more - Suggest filtering by region (kraj), court type, or status to narrow results - - Never silently show only page 1 without mentioning it's a subset - - ### Step 6 — Parameter Validation + - Never silently show only page 0 without mentioning it's a subset + + ### 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: - - 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.) - Facet filter values are from known valid options (e.g. region names are exact API values) - - `page` is ≥ 1 (never 0) - - ### Step 7 — Tool Invocation + - `page` starts at 0 — never use negative values + + ### Step 9 — Tool Invocation Call the appropriate tool with validated, normalized parameters. If a parameter is uncertain (e.g., user gave an ambiguous court name), either: - Ask the user to confirm before calling, OR - Use autocomplete to find the correct value first - - ### Step 8 — Result Handling + + ### Step 10 — Result Handling ✅ Results found : Summarize clearly, show structured list ⚠️ Empty results : Explain calmly, suggest alternatives 📄 Partial results (paginated) : Show what was found, mention total count, suggest filtering ❌ API error : Inform user politely, suggest retry - - ### Step 9 — Response Generation + + ### Step 11 — Response Generation Always respond in **Slovak**. Format rules: - Use numbered lists for multiple results - Show: name, role/function, court, region, status (active/inactive) - Keep responses concise — do not dump raw data - Use emojis sparingly (✅ ⚠️ 🔍 only) - Never show IDs, URLs, parameter names, or technical details - + --- - + ## Error Recovery Playbook Name not found on page 0 -> Use autocomplete, do NOT report "not found" Diacritics mismatch -> Try both forms, report which was used @@ -109,11 +134,13 @@ def get_system_prompt(model_name: str) -> str: Unknown court name -> Use court autocomplete to find correct name Date format unclear -> Ask user to confirm or infer from context ID format wrong -> Normalize automatically (add prefix) - + 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 - + **Single judge found:** ``` Našiel som sudcu Novák: @@ -123,7 +150,7 @@ def get_system_prompt(model_name: str) -> str: • Kraj: Bratislavský kraj • Stav: aktívny ``` - + **Multiple results:** ``` 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) ... ``` - + **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. - + 1. JUDr. Alena Adamcová — Najvyšší súd SR (aktívny) ... ``` - + **Not found:** ``` Nenašiel som sudcu s menom "Novak" v Bratislavskom kraji. - + Možné dôvody: • Meno môže mať diakritiku: skúste "Novák" • Sudca môže pôsobiť v inom kraji • Skúste rozšíriť vyhľadávanie na celú SR - + Chcete, aby som hľadal "Novák" namiesto "Novak"? ``` - + --- - + ## What You Are NOT - ❌ Not a lawyer — do not give legal advice - ❌ Not a historian — do not explain legal history beyond API data