Initial commit

This commit is contained in:
G0DSEND016 2025-12-12 08:41:11 +01:00
commit 2e79b97662
43 changed files with 1103 additions and 0 deletions

3
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

10
.idea/ai-lawyer-agent.iml Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.13 (ai-lawyer-agent)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,12 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="ignoredErrors">
<list>
<option value="N802" />
</list>
</option>
</inspection_tool>
</profile>
</component>

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

6
.idea/misc.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.13 (ai-lawyer-agent)" />
</component>
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/ai-lawyer-agent.iml" filepath="$PROJECT_DIR$/.idea/ai-lawyer-agent.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

18
.streamlit/config.toml Normal file
View File

@ -0,0 +1,18 @@
[browser]
serverAddress = "localhost"
gatherUsageStats = false
serverPort = 8501
[theme]
base = "light"
backgroundColor = "#E6F4FF"
secondaryBackgroundColor = "#D6EDFF"
font = "Ubuntu, sans-serif"
baseFontSize = 16
baseFontWeight = 300
headingFont = "Ubuntu, sans-serif"
baseRadius = "small"
#borderColor = "#D6EDFF"

0
README.md Normal file
View File

0
app/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

93
app/app.py Normal file
View File

@ -0,0 +1,93 @@
import asyncio
from datetime import datetime
import streamlit as st
from core.model import assistant_agent, SQLiteSession
from app.components.sidebar import add_sidebar
style_chat_message = """
<style>
.st-emotion-cache-1rs7fk9 {
background-color: #D6EDFF;
border-radius: 1rem;
}
.st-emotion-cache-1q1vt2q {
border-radius: 1rem;
}
</style>
"""
def get_time() -> str:
return datetime.now().strftime("%d.%m.%Y %H:%M:%S")
def init_session_state() -> None:
if "messages" not in st.session_state:
st.session_state.messages = []
if "chat_session" not in st.session_state:
st.session_state.chat_session = SQLiteSession(":memory:")
if "show_about" not in st.session_state:
st.session_state.show_about = True
st.markdown(style_chat_message, unsafe_allow_html=True)
def create_app() -> None:
st.set_page_config(
page_title="LawGPT",
page_icon="app/assets/images/title.png",
initial_sidebar_state="collapsed",
layout="centered",
menu_items={
'Get help': None,
'Report a bug': None,
'About': """
This is a cool educational project exploring the creation of an AI agent powered by API keys.
You can learn how to build, interact with, and experiment with AI using real API integration.
"""
}
)
add_sidebar()
init_session_state()
for message in st.session_state.messages:
with st.chat_message(message["role"], avatar=message["avatar"]):
st.markdown(message["content"])
if "time" in message:
st.caption(message["time"])
user_avatar = "app/assets/images/user.png"
assistant_avatar = "app/assets/images/assistant.png"
if request := st.chat_input("Ask anything"):
user_time = get_time()
with st.chat_message(name="user", avatar=user_avatar):
st.markdown(f"{request}")
st.caption(user_time)
user_message = {"role": "user",
"avatar": user_avatar,
"content": request,
"time": user_time}
st.session_state.messages.append(user_message)
with st.chat_message(name="assistant", avatar=assistant_avatar):
with st.spinner("Thinking..."):
try:
response = st.write_stream(assistant_agent(request, st.session_state.chat_session))
except Exception as e:
response = f"⚠️ Error: {e}"
finally:
assistant_time = get_time()
st.caption(assistant_time)
assistant_message = {"role": "assistant",
"avatar": assistant_avatar,
"content": response,
"time": assistant_time}
st.session_state.messages.append(assistant_message)
st.rerun()

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
app/assets/images/title.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
app/assets/images/user.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

Binary file not shown.

Binary file not shown.

32
app/components/sidebar.py Normal file
View File

@ -0,0 +1,32 @@
import streamlit as st
from agents import SQLiteSession
sidebar_style = """
<style>
[data-testid="stSidebar"][aria-expanded="true"]{
min-width: 300px;
max-width: 300px;
}
div.stButton > button {
background-color: #D6EDFF;
border: none;
}
div.stButton > button:hover {
background-color: #D6EDFF;
}
</style>
"""
def add_sidebar():
st.markdown(sidebar_style, unsafe_allow_html=True)
with st.sidebar:
st.title("⚖️ LawGPT")
st.markdown(":blue-badge[⚙Tool] :orange-badge[⚠Current chat will be deleted]")
if st.button(":material/note_stack_add: Create new chat"):
st.session_state.messages = []
st.session_state.chat_session = SQLiteSession(":memory:")

1
core/.env Normal file
View File

@ -0,0 +1 @@
OPENAI_API_KEY=""

0
core/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

116
core/model.py Normal file
View File

@ -0,0 +1,116 @@
from openai.types.responses import ResponseTextDeltaEvent
from agents import Agent, Runner, SQLiteSession
from agents import OpenAIChatCompletionsModel, AsyncOpenAI
from core.tools.zmluvy import ContractsAPI
from core.tools.sud import CourtAPI
from core.tools.sudca import JudgeAPI
from core.tools.rozhodnutie import DecisionAPI
from core.tools.obcianPojednavania import CivilProceedingAPI
from core.tools.spravneKonanie import AdminProceedAPI
SYSTEM_PROMPT = """
# Overview
Tento systémový prompt definuje právneho AI agenta, ktorý pracuje výhradne s integrovanými
nástrojmi API Ministerstva spravodlivosti SR. Cieľom je poskytovať presné, overené a stručné
právne informácie bez nadbytočných údajov.
# Context
- Agent pracuje len s oficiálnymi verejnými databázami SR.
- Nepoužíva internet ani vlastné domnienky.
- V odpovediach uvádza zdroj: API Ministerstva spravodlivosti SR.
- Pri nejasných dopytoch žiada o spresnenie.
- Rešpektuje GDPR a neposkytuje právne rady, iba fakty.
# Instructions
1. Všetky dotazy spracúvaj výhradne cez dostupné nástroje.
2. Pri zoznamoch vždy najprv použi autocomplete nástroj.
3. Pri detailoch používaj nástroje typu `*_id` s konkrétnym identifikátorom.
4. Dátumy vracaj vo formáte DD.MM.RRRR.
5. Pri filtroch používaj hodnoty oddelené čiarkou bez medzier.
6. Pri veľkých datasetoch používaj parametre page a size.
7. Odpovede formuluj stručne, právne presne a výhradne v slovenskom jazyku.
8. Ak nástroj nevráti výsledok, používateľovi to jasne oznám.
# Tools
- SÚDY: about_courts, get_court, court_autocomplete
- ZMLUVY SÚDOV: about_contracts, get_contract, contracts_autocomplete
- SUDCOVIA: about_judge, judge_id, judge_autocomplete
- ROZHODNUTIA: about_decision, decision_id, decision_autocomplete
- OBČIANSKE POJEDNÁVANIA: about_civil_proceeding, civil_proceeding_id, civil_proceeding_autocomplete
- SPRÁVNE KONANIA: about_admin_proceed, admin_proceed_id, admin_proceed_autocomplete, admin_proceed_attachments
# Examples
- Vstup: Vyhľadaj Okresný súd v Trnave.
- Postup: použije sa court_autocomplete get_court.
- Výstup: stručné potvrdenie s detailmi a zdrojom.
- Vstup: Nájdi rozhodnutie so spisovou značkou XY.
- Postup: decision_autocomplete decision_id.
# SOP (Standard Operating Procedure)
1. Identifikuj typ požiadavky (zoznam, detail, vyhľadávanie).
2. Použi príslušný autocomplete na zistenie identifikátorov.
3. Zavolaj detailný nástroj `*_id`.
4. Spracuj odpoveď a zhrň ju do stručného a presného výstupu.
5. Uveď zdroj dát.
6. Ak výsledok chýba, oznám to a navrhni ďalší krok (overenie názvu, filtra, dátumu).
# Final Notes
- Agent odpovedá vždy len fakticky na základe API.
- Neposkytuje interpretácie ani právne rady.
- Výstup musí byť vecný, prehľadný a stredne dlhý.
"""
async def stream_response(agent: Agent, prompt: str, session: SQLiteSession):
"""Stream agent response and update the UI."""
try:
result = Runner.run_streamed(agent, input=prompt, session=session)
async for event in result.stream_events():
if event.type == "raw_response_event" and isinstance(event.data, ResponseTextDeltaEvent):
yield event.data.delta # <-- sends the next piece of response text
except Exception as e:
yield f"⚠️ Error: {e}"
def assistant_agent(prompt: str, session):
court_api = CourtAPI()
contracts_api = ContractsAPI()
judge_api = JudgeAPI()
decision_api = DecisionAPI()
civil_proceeding_api = CivilProceedingAPI()
admin_proceeding_api = AdminProceedAPI()
model = OpenAIChatCompletionsModel(
model="gpt-oss:20b-cloud",
openai_client=AsyncOpenAI(base_url="http://localhost:11434/v1",
api_key="ollama"
)
)
agent = Agent(
name="Assistant",
instructions=SYSTEM_PROMPT,
model=model,
tools=[
court_api.about_courts, court_api.get_court, court_api.court_autocomplete,
contracts_api.get_contract, contracts_api.about_contracts, contracts_api.contracts_autocomplete,
judge_api.about_judge, judge_api.judge_id, judge_api.judge_autocomplete,
decision_api.about_decision, decision_api.decision_id, decision_api.decision_autocomplete,
civil_proceeding_api.about_civil_proceeding, civil_proceeding_api.civil_proceeding_id,
civil_proceeding_api.civil_proceeding_autocomplete,
admin_proceeding_api.about_admin_proceed, admin_proceeding_api.admin_proceed_id,
admin_proceeding_api.admin_proceed_autocomplete, admin_proceeding_api.admin_proceed_attachments,
]
)
return stream_response(agent, prompt, session)

0
core/tools/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,137 @@
import requests
from pydantic import BaseModel, conint
from typing import Optional, List
from enum import Enum
from agents import function_tool
API_BASE_URL = "https://obcan.justice.sk/pilot/api/ress-isu-service"
class SortDirection(str, Enum):
ASC = "ASC"
DESC = "DESC"
class CivilProceedingAPI:
class CivilProceedParams(BaseModel):
query: Optional[str] = None
typSuduFacetFilter: Optional[List[str]] = None
krajFacetFilter: Optional[List[str]] = None
okresFacetFilter: Optional[List[str]] = None
usekFacetFilter: Optional[List[str]] = None
formaUkonuFacetFilter: Optional[List[str]] = None
pojednavaniaOd: Optional[str] = None
pojednavaniaDo: Optional[str] = None
guidSudca: Optional[str] = None
guidSud: Optional[str] = None
spisovaZnacka: Optional[str] = None
verejneVyhlasenie: Optional[bool] = None
indexDatumOd: Optional[str] = None
indexDatumDo: Optional[str] = None
sortProperty: Optional[str] = None
sortDirection: SortDirection = SortDirection.ASC
page: int = 0
size: int = 20
@function_tool
def about_civil_proceeding(args: CivilProceedParams) -> dict:
"""
Načítanie zoznamu občianskoprávnych pojednávaní a verejne vyhlásených rozsudkov na základe filtrovacích kritérií
:param query: Hľadané slovo alebo slovné spojenie, podľa ktorého sa vyhľadávajú občianskoprávne pojednávania.
:param typSuduFacetFilter: Zoznam typov súdov (fazetový filter), napr. ["Okresný súd", "Krajský súd", "Mestský súd"].
:param krajFacetFilter: Zoznam krajov (fazetový filter), napr. ["Bratislavský kraj", "Košický kraj", "Prešovský kraj"].
:param okresFacetFilter: Zoznam okresov (fazetový filter), napr. ["Okres Košice I", "Okres Bratislava IV", "Okres Žilina"].
:param usekFacetFilter: Zoznam úsekov (fazetový filter), napr. ["C", "O", "S"].
:param formaUkonuFacetFilter: Zoznam foriem úkonu (fazetový filter), napr. ["Pojednávanie bez rozhodnutia", "Pojednávanie a rozhodnutie",
"Verejné vyhlásenie rozsudku"].
:param pojednavaniaOd: Dátum pojednávania OD (formát: DD.MM.RRRR), napr. "01.01.2025".
:param pojednavaniaDo: Dátum pojednávania DO (formát: DD.MM.RRRR), napr. "31.12.2025".
:param guidSudca: Identifikátor sudcu pre filtrovanie pojednávaní konkrétneho sudcu, napr. "sudca_2442".
:param guidSud: Identifikátor súdu pre filtrovanie pojednávaní konkrétneho súdu, napr. "sud_135".
:param spisovaZnacka: Spisová značka pojednávania, napr. "30P/1/2025".
:param verejneVyhlasenie: Príznak, či zahrnúť len verejne vyhlásené rozsudky. Hodnota typu boolean.
:param indexDatumOd: Dátum indexácie OD (formát: DD.MM.RRRR), napr. "01.01.2025".
:param indexDatumDo: Dátum indexácie DO (formát: DD.MM.RRRR), napr. "31.12.2025".
:param sortProperty: Názov atribútu, podľa ktorého sa majú záznamy zoradiť, napr. "datumPojednavania", "spisovaZnacka".
:param sortDirection: Smer zoradenia záznamov. Možnosti: "ASC" (predvolené) alebo "DESC".
:param page: Číslo stránky (0 = prvá stránka) pre stránkovanie výsledkov.
:param size: Počet záznamov na stránku (predvolené 20) pre stránkovanie výsledkov.
:return: Slovník (JSON) obsahujúci zoznam občianskoprávnych pojednávaní a verejne vyhlásených rozsudkov s detailnými informáciami, metadátami a filtrami.
"""
try:
url = f"{API_BASE_URL}/v1/obcianPojednavania"
response = requests.get(url, params=args.model_dump())
response.raise_for_status()
if response.status_code == 200:
data = response.json()
print(f"❗🔨\n {data}")
return {"success": True, "data": data}
else:
return {"success": False, "error": f"Unexpected status code: {response.status_code} ⚠️"}
except Exception as e:
return {"success": False, "error": f"Error get contract details: {str(e)} 🛑"}
@function_tool
def civil_proceeding_id(self, id: str) -> dict:
"""
Načítanie detailu občianskoprávneho pojednávania na základe identifikátora.
:param id: Identifikátor sudcu (povinný parameter), napr. "sudca_123", "sudca_456".
:return: Slovník (JSON) obsahujúci detailné informácie o občianskoprávnom pojednávaní na základe identifikátora.
"""
try:
url = f"{API_BASE_URL}/v1/obcianPojednavania/{id}"
response = requests.get(url)
response.raise_for_status()
if response.status_code == 200:
data = response.json()
print(f"⭕🔨\n {data}")
return {"success": True, "data": data}
else:
return {"success": False, "error": f"Unexpected status code: {response.status_code} ⚠️"}
except Exception as e:
return {"success": False, "error": f"Error : {str(e)} 🛑"}
class CivilProceedAutocomplete(BaseModel):
query: Optional[str] = None
guidSud: Optional[str] = None
giudSud: Optional[str] = None
verejneVyhlasenie: Optional[bool] = None
limit: Optional[conint(ge=0)] = None
@function_tool
def civil_proceeding_autocomplete(self, args: CivilProceedAutocomplete) -> dict:
"""
Autocomplete služba pre vyhľadávanie občianskoprávnych pojednávaní a verejne vyhlásených rozsudkov.
:param query: Hľadané slovo alebo slovné spojenie pre vyhľadávanie pojednávaní.
:param guidSud: Identifikátor súdu pre filtrovanie pojednávaní konkrétneho súdu.
:param giudSud: Duplicitný parameter - pravdepodobne chyba, použite guidSud.
:param verejneVyhlasenie: Príznak, či zahrnúť len verejne vyhlásené rozsudky.
:param limit: Maximálny počet návrhov (0 = všetky možné návrhy).
:return: Slovník (JSON) obsahujúci zoznam návrhov pre autocomplete.
"""
try:
url = f"{API_BASE_URL}/v1/obcianPojednavania/autocomplete"
response = requests.get(url, args.model_dump())
response.raise_for_status()
if response.status_code == 200:
data = response.json()
print(f"📛🔨\n {data}")
return {"success": True, "data": data}
else:
return {"success": False, "error": f"Unexpected status code: {response.status_code} ⚠️"}
except Exception as e:
return {"success": False, "error": f"Error : {str(e)} 🛑"}

141
core/tools/rozhodnutie.py Normal file
View File

@ -0,0 +1,141 @@
import requests
from pydantic import BaseModel, conint
from typing import Optional, List
from enum import Enum
from agents import function_tool
API_BASE_URL = "https://obcan.justice.sk/pilot/api/ress-isu-service"
class SortDirection(str, Enum):
ASC = "ASC"
DESC = "DESC"
class DecisionAPI:
class AboutDecision(BaseModel):
query: Optional[str] = None
typSuduFacetFilter: Optional[List[str]] = None
krajFacetFilter: Optional[List[str]] = None
okresFacetFilter: Optional[List[str]] = None
odkazovanePredpisy: Optional[str] = None
oblastPravnejUpravyFacetFilter: Optional[List[str]] = None
podOblastPravnejUpravyFacetFilter: Optional[List[str]] = None
formaRozhodnutiaFacetFilter: Optional[List[str]] = None
povahaRozhodnutiaFacetFilter: Optional[str] = None
vydaniaOd: Optional[str] = None
vydaniaDo: Optional[str] = None
ecli: Optional[str] = None
spisovaZnacka: Optional[str] = None
cisloSpisu: Optional[str] = None
guidSudca: Optional[str] = None
guidSud: Optional[str] = None
indexDatumOd: Optional[str] = None
indexDatumDo: Optional[str] = None
sortProperty: Optional[str] = None
sortDirection: SortDirection = SortDirection.ASC
page: Optional[int] = None
size : conint(ge=0) = 20
@function_tool
def about_decision(self, args: AboutDecision) -> dict:
"""
Načítanie zoznamu rozhodnutí na základe filtrovacích kritérií
:param query: Hľadané slovo alebo slovné spojenie, podľa ktorého sa vyhľadávajú rozhodnutia.
:param typSuduFacetFilter: Zoznam typov súdov (fazetový filter), napr. ["Okresný súd", "Krajský súd", "Mestský súd"].
:param krajFacetFilter: Zoznam krajov (fazetový filter), napr. ["Košický kraj", "Bratislavský kraj", "Banskobystrický kraj"].
:param okresFacetFilter: Zoznam okresov (fazetový filter), napr. ["Okres Banská Bystrica", "Okres Košice I", "Okres Bratislava I"].
:param odkazovanePredpisy: Odkazované predpisy, na ktoré sa rozhodnutie odvoláva.
:param oblastPravnejUpravyFacetFilter: Zoznam oblastí právnej úpravy (fazetový filter), napr. ["Občianske právo",
"Rodinné právo", "Obchodné právo"].
:param podOblastPravnejUpravyFacetFilter: Zoznam podoblastí právnej úpravy
(fazetový filter), napr. ["Exekúcia a výkon rozhodnutí",
"Spotrebiteľské zmluvy", "Vyživovacie povinnosti"].
:param formaRozhodnutiaFacetFilter: Zoznam foriem rozhodnutia (fazetový filter), napr. ["Uznesenie", "Rozsudok", "Platobný rozkaz"].
:param povahaRozhodnutiaFacetFilter: Povaha rozhodnutia, napr. "Prvostupňové nenapadnuté opravnými prostriedkami".
:param vydaniaOd: Dátum vydania OD (formát: DD.MM.RRRR), napr. "01.01.2020".
:param vydaniaDo: Dátum vydania DO (formát: DD.MM.RRRR), napr. "31.12.2025".
:param ecli: ECLI identifikátor rozhodnutia.
:param spisovaZnacka: Spisová značka rozhodnutia, napr. "4T/20/2014".
:param cisloSpisu: Identifikačné číslo spisu.
:param guidSudca: Identifikátor sudcu pre filtrovanie rozhodnutí konkrétneho sudcu, napr. "sudca_1600".
:param guidSud: Identifikátor súdu pre filtrovanie rozhodnutí konkrétneho súdu, napr. "sud_156".
:param indexDatumOd: Dátum indexácie OD (formát: DD.MM.RRRR), napr. "01.01.2025".
:param indexDatumDo: Dátum indexácie DO (formát: DD.MM.RRRR), napr. "31.12.2025".
:param sortProperty: Názov atribútu, podľa ktorého sa majú záznamy zoradiť, napr. "datumVydania", "spisovaZnacka".
:param sortDirection: Smer zoradenia záznamov. Možnosti: "ASC" (predvolené) alebo "DESC".
:param page: Číslo stránky (0 = prvá stránka) pre stránkovanie výsledkov.
:param size: Počet záznamov na stránku (predvolené 20) pre stránkovanie výsledkov.
:return: Slovník (JSON) obsahujúci zoznam rozhodnutí s detailnými informáciami, metadátami a filtrami.
"""
try:
url = f"{API_BASE_URL}/v1/rozhodnutie"
response = requests.get(url, params=args.model_dump())
response.raise_for_status()
if response.status_code == 200:
data = response.json()
print(f"⭕📃\n {data}")
return {"success": True, "data": data}
else:
return {"success": False, "error": f"Unexpected status code: {response.status_code} ⚠️"}
except Exception as e:
return {"success": False, "error": f"Error : {str(e)} 🛑"}
@function_tool
def decision_id(self, id: str) -> dict:
"""
Načítanie rozhodnutia na základe id
:param id: Identifikátor sudu (povinný parameter), napr. "sud_123", "sud_456".
:return: Slovník (JSON) obsahujúci detailné informácie o rozhodnutií na základe id
"""
try:
url = f"{API_BASE_URL}/v1/rozhodnutie/{id}"
response = requests.get(url)
response.raise_for_status()
if response.status_code == 200:
data = response.json()
print(f"⛔📃\n {data}")
return {"success": True, "data": data}
else:
return {"success": False, "error": f"Unexpected status code: {response.status_code} ⚠️"}
except Exception as e:
return {"success": False, "error": f"Error : {str(e)} 🛑"}
class DecisionAutocomplete(BaseModel):
query: Optional[str] = None
guidSud: Optional[str] = None
limit: Optional[conint(ge=0)] = None
@function_tool
def decision_autocomplete(self, args: DecisionAutocomplete) -> dict:
"""
Autocomplete služba pre načítanie rozhodnutia.
:param query: Hľadané slovo alebo slovné spojenie
:param guidSud: Identifikátor súdu, napr. "sud_123", "sud_456".
:param limit: Maximálny počet rozhodnutie, ktoré sa majú vrátiť.
:return: Slovník (JSON) obsahujúci zoznam rozhodnutie pre autocomplete.
"""
try:
url = f"{API_BASE_URL}/v1/rozhodnutie/autocomplete"
response = requests.get(url, params=args.model_dump())
response.raise_for_status()
if response.status_code == 200:
data = response.json()
print(f"📛📃\n {data}")
return {"success": True, "data": data }
else:
return { "success": False, "error": f"Unexpected status code: {response.status_code} ⚠️"}
except Exception as e:
return { "success": False, "error": f"Error get contract details: {str(e)} 🛑" }

View File

@ -0,0 +1,142 @@
import requests
from pydantic import BaseModel, conint
from typing import List, Optional
from enum import Enum
from agents import function_tool
API_BASE_URL = "https://obcan.justice.sk/pilot/api/ress-isu-service"
class SortDirection(str, Enum):
ASC = "ASC"
DESC = "DESC"
class AdminProceedAPI:
class AdminProceed(BaseModel):
query: Optional[str] = None
druhFacetFilter: Optional[List[str]] = None
datumPravoplatnostiOd : Optional[str] = None
datumPravoplatnostiDo : Optional[str] = None
page: Optional[int] = None
size : conint(ge=0) = 20
sortProperty: Optional[str] = None
sortDirection: SortDirection = SortDirection.ASC
@function_tool
def about_admin_proceed(self, args: AdminProceed) -> dict:
"""
:param query: Hľadané slovo alebo slovné spojenie.
:param druhFacetFilter: Zoznam druhov správnych konaní (fazetový filter).
:param datumPravoplatnostiOd: Dátum právoplatnosti OD (formát: DD.MM.RRRR).
Príklad: "15.03.2023", "01.01.2020"
:param datumPravoplatnosiDo: Dátum právoplatnosti DO (formát: DD.MM.RRRR).
Príklad: "15.03.2023", "01.01.2020"
:param page: Číslo stránky (0 = prvá stránka).
Poznámka: Zmena 'page' zobrazí ĎALŠIE konania, nie tie isté.
Príklad: 'page=0' konania 1-20, 'page=1' konania 21-40.
:param size: Počet záznamov na stránku (predvolené 20).
Príklad: 'size=10' 10 konaní na stránke.
:param sortProperty: Atribút pre zoradenie výsledkov.
:param sortDirection: Smer zoradenia (ASC alebo DESC).
:return: Slovník s výsledkami vyhľadávania správnych konaní.
"""
try:
url = f"{API_BASE_URL}/v1/spravneKonanie"
response = requests.get(url, params=args.model_dump())
response.raise_for_status()
if response.status_code == 200:
data = response.json()
print(f"⭕👨\n {data}")
return {"success": True, "data": data}
else:
return {"success": False, "error": f"Unexpected status code: {response.status_code} ⚠️"}
except Exception as e:
return {"success": False, "error": f"Error : {str(e)} 🛑"}
@function_tool
def admin_proceed_id(self, id: str) -> dict:
"""
Načítanie binárneho obsahu prílohy správneho konania na základe ID.
:param id: Unikátny identifikátor administratívneho konania (povinný parameter).
Príklad: sud_175
:return: Slovník (JSON) obsahujúci binárne dáta prílohy a metainformácie.
"""
try:
url = f"{API_BASE_URL}/v1/spravneKonanie/{id}"
response = requests.get(url)
response.raise_for_status()
if response.status_code == 200:
data = response.json()
print(f"📛👨\n {data}")
return {"success": True, "data": data}
else:
return {"success": False, "error": f"Unexpected status code: {response.status_code} ⚠️"}
except Exception as e:
return {"success": False, "error": f"Error : {str(e)} 🛑"}
@function_tool
def admin_proceed_attachments(self, id: str) -> dict:
"""
Načítanie správneho konania na základe id
:param id: Unikátny identifikátor administratívneho konania (povinný parameter).
Príklad: sud_175
:return: Slovník (JSON) obsahujúci detailné informácie o správnom konaní na základe id.
"""
try:
url = f"{API_BASE_URL}/v1/spravneKonanie/priloha/{id}"
response = requests.get(url)
response.raise_for_status()
if response.status_code == 200:
data = response.json()
print(f"❗👨\n {data}")
return {"success": True, "data": data}
else:
return {"success": False, "error": f"Unexpected status code: {response.status_code} ⚠️"}
except Exception as e:
return {"success": False, "error": f"Error : {str(e)} 🛑"}
class AdminProceedAutocomplete(BaseModel):
query: Optional[str] = None
limit: Optional[conint(ge=1)] = None
@function_tool
def admin_proceed_autocomplete(self, args: AdminProceedAutocomplete) -> dict:
"""
Autocomplete služba pre vyhľadávanie správnych konaní.
:param query: Hľadané slovo alebo slovné spojenie pre vyhľadávanie správnych konaní.
:param limit: Maximálny počet návrhov, ktoré sa majú vrátiť.
None API vráti 5 dokumentov (predvolená hodnota).
Hodnota 0 spôsobí chybu API, preto použite None namiesto 0
:return: Slovník (JSON) obsahujúci zoznam návrhov pre autocomplete.
"""
try:
url = f"{API_BASE_URL}/v1/spravneKonanie/autocomplete"
response = requests.get(url, args.model_dump())
response.raise_for_status()
if response.status_code == 200:
data = response.json()
print(f"\n {data}")
return {"success": True, "data": data}
else:
return {"success": False, "error": f"Unexpected status code: {response.status_code} ⚠️"}
except Exception as e:
return {"success": False, "error": f"Error : {str(e)} 🛑"}

114
core/tools/sud.py Normal file
View File

@ -0,0 +1,114 @@
import requests
from pydantic import BaseModel, conint
from typing import List, Optional
from enum import Enum
from agents import function_tool
API_BASE_URL = "https://obcan.justice.sk/pilot/api/ress-isu-service"
class SortDirection(str, Enum):
ASC = "ASC"
DESC = "DESC"
class CourtAPI:
class ListCourts(BaseModel):
query: Optional[str] = None
typSuduFacetFilter: List[str] = []
krajFacetFilter: List[str] = []
zahrnutZaniknuteSudy: Optional[bool] = None
sortProperty: Optional[str] = None
sortDirection: SortDirection = SortDirection.ASC
@function_tool
def about_courts(args: ListCourts) -> dict:
"""
Načítanie zoznamu súdov na základe filtrovacích kritérii
:param query: Hľadané slovo alebo slovné spojenie, podľa ktorého sa vyhľadávajú súdy.
:param typSuduFacetFilter: Zoznam typov súdov (fazetový filter), napr. ["Okresný súd", "Krajský súd"].
:param krajFacetFilter: Zoznam krajov (fazetový filter), napr. ["Bratislavský kraj", "Košický kraj"].
:param zahrnutZaniknuteSudy: Príznak, či zahrnúť aj zaniknuté súdy. Hodnota typu boolean.
:param sortProperty: Názov atribútu, podľa ktorého sa majú záznamy zoradiť.
:param sortDirection: Smer zoradenia záznamov. Možnosti: "ASC" (predvolené) alebo "DESC".
:return: Slovník (JSON) obsahujúci detailné informácie s detailnými informáciami, metadátami a filtrami.
"""
try:
url = f"{API_BASE_URL}/v1/sud"
response = requests.get(url, params=args.model_dump())
response.raise_for_status()
if response.status_code == 200:
data = response.json()
print(f"⭕🏛️\n {data}")
return {"success": True, "data": data}
else:
return {"success": False, "error": f"Unexpected status code: {response.status_code} ⚠️"}
except Exception as e:
return {"success": False, "error": f"Error get contract details: {str(e)} 🛑"}
class CourtDetail(BaseModel):
idSudu: Optional[str] = None
@function_tool
def get_court(args: CourtDetail) -> dict:
"""
Načítanie detailnej informácie o súde na základe jeho ID.
:param idSudu: Identifikátor súdu.
:return: Slovník (JSON) obsahujúci detailné informácie sudov.
"""
try:
url = f"{API_BASE_URL}/v1/sud/{args.idSudu}"
response = requests.get(url)
response.raise_for_status()
if response.status_code == 200:
data = response.json()
data.pop("foto", None)
print(f"❗🏛️\n {data}")
return {"success": True, "data": data}
else:
return {"success": False, "error": f"Unexpected status code: {response.status_code} ⚠️"}
except Exception as e:
return {"success": False, "error": f"Error get contract details: {str(e)} 🛑"}
class CourtAutocomplete(BaseModel):
query: Optional[str] = None
limit: Optional[conint(ge=0)] = None
@function_tool
def court_autocomplete(args: CourtAutocomplete) -> dict:
"""
Autocomplete pre vyhľadávanie súdu.
:param query: Hľadané slovo alebo slovné spojenie, podľa ktorého sa majú hľadať súdy.
:param limit: Maximálny počet návrhov súdov, ktoré sa majú vrátiť. Ak je 0, vráti všetky možné návrhy.
:return: Slovník (JSON) obsahujúci zoznam návrhov súdov pre autocomplete.
"""
try:
url = f"{API_BASE_URL}/v1/sud/autocomplete"
response = requests.get(url, params=args.model_dump())
response.raise_for_status()
if response.status_code == 200:
data = response.json()
print(f"📛🏛️\n {data}")
return {"success": True, "data": data }
else:
return { "success": False, "error": f"Unexpected status code: {response.status_code} ⚠️"}
except Exception as e:
return { "success": False, "error": f"Error get contract details: {str(e)} 🛑" }

126
core/tools/sudca.py Normal file
View File

@ -0,0 +1,126 @@
import requests
from pydantic import BaseModel, conint
from typing import List, Optional
from enum import Enum
from agents import function_tool
API_BASE_URL = "https://obcan.justice.sk/pilot/api/ress-isu-service"
class SortDirection(str, Enum):
ASC = "ASC"
DESC = "DESC"
class JudgeAPI:
class JudgeParams(BaseModel):
query: Optional[str] = None
funkciaFacetFilter: Optional[List[str]] = None
typSuduFacetFilter: Optional[List[str]] = None
krajFacetFilter: Optional[List[str]] = None
okresFacetFilter: Optional[List[str]] = None
stavZapisuFacetFilter: Optional[List[str]] = None
guidSud: Optional[str] = None
page: Optional[int] = None
size: Optional[conint(ge=0)] = None
sortProperty: Optional[str] = None
sortDirection: SortDirection = SortDirection.ASC
@function_tool
def about_judge(self, args: JudgeParams):
"""
Načítanie zoznamu sudcov na základe filtrovacích kritérii
:param query: Hľadané slovo alebo slovné spojenie pre vyhľadávanie sudcov.
:param funkciaFacetFilter: Zoznam funkcií sudcov: ["Sudca", "Predseda", "Podpredseda", "Hosťujúci sudca", "a ine"].
:param typSuduFacetFilter: Zoznam typov súdov: ["Okresný súd", "Krajský súd", "Mestský súd",
"Najvyšší súd SR", "Správny súd",
"Špecializovaný trestný súd"].
:param krajFacetFilter: Zoznam krajov: ["Bratislavský kraj", "Košický kraj", "Banskobystrický kraj",
"Prešovský kraj", "Žilinský kraj", "Trnavský kraj", "Nitriansky kraj",
"Trenčiansky kraj"].
:param okresFacetFilter: Zoznam okresov: ["Okres [mesto Slovenska]"] napr. "Okres Bratislava I", "Okres Košice I".
:param stavZapisuFacetFilter: Zoznam stavov zápisu: ["prerusenie vykonu - poberatel", "aktivity",
"odvolany", "vymazany", "prerusenie vykonu - ina funkce"].
:param guidSud: Identifikátor súdu pre filtrovanie sudcov konkrétneho súdu, napr. "sud_101".
:param page: Číslo stránky (0 = prvá stránka) pre stránkovanie výsledkov.
:param size: Počet záznamov na stránku (predvolené 20) pre stránkovanie výsledkov.
:param sortProperty: Atribút pre zoradenie výsledkov, napr. "priezvisko", "meno".
:param sortDirection: Smer zoradenia záznamov: "ASC" (predvolené) alebo "DESC".
:return: Slovník (JSON) obsahujúci zoznam sudcov s detailnými informáciami, metadátami a filtrami.
:return: Slovník (JSON) obsahujúci zoznam súdov na základe filtrovacích kritérii
"""
try:
url = f"{API_BASE_URL}/v1/sudca"
response = requests.get(url, params=args.model_dump())
response.raise_for_status()
if response.status_code == 200:
data = response.json()
print(f"📛🧑‍⚖️\n {data}")
return {"success": True, "data": data}
else:
return {"success": False, "error": f"Unexpected status code: {response.status_code} ⚠️"}
except Exception as e:
return {"success": False, "error": f"Error : {str(e)} 🛑"}
@function_tool
def judge_id(self, id: str) -> dict:
"""
Načítanie detailu sudcu na základe identifikátora.
:param id: Identifikátor sudcu (povinný parameter), napr. "sudca_123", "sudca_456".
:return: Slovník (JSON) obsahujúci detailné informácie o sudcovi na základe identifikátora.
"""
try:
url = f"{API_BASE_URL}/v1/sudca/{id}"
response = requests.get(url)
response.raise_for_status()
if response.status_code == 200:
data = response.json()
print(f"⛔🧑‍⚖️\n {data}")
return {"success": True, "data": data}
else:
return {"success": False, "error": f"Unexpected status code: {response.status_code} ⚠️"}
except Exception as e:
return {"success": False, "error": f"Error : {str(e)} 🛑"}
class JudgeAutocomplete(BaseModel):
query: Optional[str] = None
guidSud: Optional[str] = None
limit: Optional[conint(ge=1)] = None
@function_tool
def judge_autocomplete(self, args: JudgeAutocomplete) -> dict:
"""
Autocomplete služba pre vyhľadávanie sudcov.
:param query: Hľadané slovo alebo slovné spojenie.
:param guidSud: Identifikátor súdu pre filtrovanie sudcov konkrétneho súdu.
Príklad: "sud_175"
:param limit: Maximálny počet návrhov, ktoré sa majú vrátiť.
None API vráti 5 dokumentov (predvolená hodnota).
Hodnota 0 spôsobí chybu API, preto použite None namiesto 0
:return: Slovník (JSON) obsahujúci zoznam návrhov sudcov pre autocomplete.
"""
try:
url = f"{API_BASE_URL}/v1/sudca/autocomplete"
response = requests.get(url, args.model_dump())
response.raise_for_status()
if response.status_code == 200:
data = response.json()
print(f"⭕🧑‍⚖️\n {data}")
return {"success": True, "data": data}
else:
return {"success": False, "error": f"Unexpected status code: {response.status_code} ⚠️"}
except Exception as e:
return {"success": False, "error": f"Error : {str(e)} 🛑"}

121
core/tools/zmluvy.py Normal file
View File

@ -0,0 +1,121 @@
import requests
from pydantic import BaseModel, conint
from typing import List, Optional
from enum import Enum
from agents import function_tool
API_BASE_URL = "https://obcan.justice.sk/pilot/api/ress-isu-service"
class SortDirection(str, Enum):
ASC = "ASC"
DESC = "DESC"
class ContractsAPI:
class ContractsList(BaseModel):
query : Optional[str] = None
typDokumentuFacetFilter: Optional[List[str]] = None
odberatelFacetFilter: Optional[List[str]] = None
dodavatelFacetFilter: Optional[List[str]] = None
hodnotaZmluvyFacetFilter: Optional[List[str]] = None
guidSud: Optional[str] = None
sortProperty: Optional[str] = None
sortDirection: SortDirection = SortDirection.ASC
page: Optional[int] = None
size : conint(ge=0) = 20
@function_tool
def about_contracts(args: ContractsList) -> dict:
"""
Načítanie zoznamu zmlúv podľa zadaných filtrov.
:param query: Hľadaný výraz, podľa ktorého sa vyhľadávajú zmluvy.
:param typDokumentuFacetFilter: Typy dokumentov ako fazetový filter (napr. ["ZMLUVA","FAKTURA"]).
:param odberatelFacetFilter: Odberatelia pre fazetový filter.
:param dodavatelFacetFilter: Dodávatelia pre fazetový filter.
:param hodnotaZmluvyFacetFilter: Hodnoty zmlúv (filtrovacie intervaly).
:param guidSud: Identifikátor súdu (napr. "sud_101").
:param sortProperty: Atribút na triedenie výsledkov.
:param sortDirection: ASC alebo DESC.
:param page: Číslo strany (0 = prvá strana).
:param size: Počet výsledkov na strane.
:return: JSON so zoznamom zmlúv a metadátami.
"""
try:
url = f"{API_BASE_URL}/v1/zmluvy"
response = requests.get(url, params=args.model_dump())
response.raise_for_status()
if response.status_code == 200:
data = response.json()
print(f"⭕🖇️\n {data}")
return {"success": True, "data": data}
else:
return {"success": False, "error": f"Unexpected status code: {response.status_code} ⚠️"}
except Exception as e:
return {"success": False, "error": f"Error get contract details: {str(e)} 🛑"}
class ContractDetail(BaseModel):
idZmluvy: str
@function_tool
def get_contract(args: ContractDetail) -> dict:
"""
Načítanie detailu zmluvy podľa jej identifikátora.
:param idZmluvy: Jedinečný identifikátor zmluvy.
:return: JSON slovník obsahujúci detailné informácie o zmluve.
"""
try:
url = f"{API_BASE_URL}/v1/zmluvy/{args.idZmluvy}"
response = requests.get(url)
response.raise_for_status()
if response.status_code == 200:
data = response.json()
print(f"⛔🖇️\n {data}")
return {"success": True, "data": data }
else:
return { "success": False, "error": f"Unexpected status code: {response.status_code} ⚠️"}
except Exception as e:
return { "success": False, "error": f"Error get contract details: {str(e)} 🛑" }
class ContractsAutocomplete(BaseModel):
query : Optional[str] = None
guidSud: Optional[str] = None
limit: Optional[conint(ge=1)] = None
@function_tool
def contracts_autocomplete(args: ContractsAutocomplete) -> dict:
"""
Autocomplete pre vyhľadávanie zmlúv.
:param query: Hľadaný text alebo výraz na vyhľadanie zmlúv.
:param guidSud: Identifikátor súdu (napr. "sud_101") na filtrovanie zmlúv konkrétneho súdu.
:param limit: Maximálny počet výsledkov.
None = predvolených 5 výsledkov.
Hodnota 0 spôsobí chybu API použite radšej None.
:return: JSON slovník obsahujúci zoznam návrhov zmlúv pre autocomplete.
"""
try:
url = f"{API_BASE_URL}/v1/zmluvy/autocomplete"
response = requests.get(url, params=args.model_dump())
response.raise_for_status()
if response.status_code == 200:
data = response.json()
print(f"📛🖇️\n {data}")
return {"success": True, "data": data}
else:
return {"success": False, "error": f"Unexpected status code: {response.status_code} ⚠️"}
except Exception as e:
return {"success": False, "error": f"Error get contract details: {str(e)} 🛑"}

7
main.py Normal file
View File

@ -0,0 +1,7 @@
from app.app import create_app
def main():
create_app()
if __name__ == "__main__":
main()

4
requirements.txt Normal file
View File

@ -0,0 +1,4 @@
openai-agents
python-dotenv
streamlit
requests

Binary file not shown.

BIN
test/latex_problem.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 KiB