diff --git a/README.md b/README.md index 96bab61..65738c6 100644 --- a/README.md +++ b/README.md @@ -1,89 +1,132 @@ # Právny AI Asistent – integrácia s API -## POPIS +## Popis -Právny AI Asistent je inteligentný asistent integrovaný s oficiálnymi verejnými API Ministerstva spravodlivosti -Slovenskej republiky. Systém poskytuje užívateľom prístup k štruktúrovaným právnym informáciám prostredníctvom -prirodzeného jazyka. +Právny AI Asistent je inteligentný asistent integrovaný s oficiálnymi verejnými API Ministerstva spravodlivosti Slovenskej republiky. Systém poskytuje užívateľom prístup k štruktúrovaným právnym informáciám prostredníctvom prirodzeného jazyka. **Hlavné funkcie:** + - Interpretácia užívateľských otázok v prirodzenom jazyku - Automatická extrakcia a validácia parametrov - Načítavanie dát výlučne cez oficiálne API - Prezentácia výsledkov v zrozumiteľnom formáte v slovenskom jazyku -## POUŽITÉ KNIŽNICE A TECHNOLÓGIE +--- -- **Python** – hlavný programovací jazyk -- **openai-agent** – tvorba AI agentov od OpenAI -- **httpx** – asynchrónna komunikácia s API -- **Chainlit** – framework pre chat rozhranie -- **Ollama** – lokálne používanie AI modelov -- **Docker** – kontajnerizácia aplikácie -- a **iné** +## Použité knižnice a technológie + +### Jadro aplikácie + +| Technológia | Účel | +|---|---| +| **Python 3.11** | Hlavný programovací jazyk | +| **openai-agents** | Tvorba AI agentov a streamovanie odpovedí | +| **openai** | Python klient pre OpenAI / Ollama API | +| **Chainlit** | Framework pre chat rozhranie | +| **Ollama** | Lokálne spúšťanie AI modelov | +| **Docker** | Kontajnerizácia aplikácie | +| **python-dotenv** | Načítavanie premenných prostredia zo súboru `.env` | + +### API a sieť + +| Technológia | Účel | +|---|---| +| **httpx** | Asynchrónna HTTP komunikácia s API | +| **pydantic** | Validácia a serializácia vstupných parametrov (schémy) | +| **cachetools** | TTL cache pre API odpovede | +| **tenacity** | Automatické opakovanie požiadaviek pri chybách (retry) | + +### Testovanie + +| Technológia | Účel | +|---|---| +| **pytest** | Testovací framework | +| **pytest-asyncio** | Podpora asynchrónnych testov | +| **respx** | Mockovanie HTTP požiadaviek (httpx) | +| **pytest-html** | Generovanie HTML reportov z testov | +| **pytest-cov** | Meranie pokrytia kódu testami | + +--- + +## Štruktúra projektu -## ŠTRUKTÚRA PROJEKTU ``` -ai-lawyer-agent/ +ai-lawyer-agent/ +├── .chainlit/ # Konfigurácia Chainlit ├── api/ # API logika -│ └── tools/ # API nástroje -│ ├── __init__.py -│ ├── fetch_api_data.py # Spracovanie API -│ └── schemas.py # Pydantic schémy +│ ├── __init__.py +│ ├── fetch_api_data.py # Spracovanie API +│ ├── config.py # Konfigurácia API +│ ├── schemas.py # Pydantic schémy +│ └── tools.py # API nástroje (function tools pre agenta) ├── core/ │ ├── __init__.py -│ ├── initialize_agent.py # Inicializácia AI agenta +│ ├── config.py # Konfigurácia agenta (modely, parametre) +│ ├── init_agent.py # Inicializácia AI agenta │ ├── stream_response.py # Streamovanie odpovedí │ └── system_prompt.py # Systémový prompt ├── public/ # Verejné zdroje -│ ├── icon/ # Ikony a logá -│ │ ├── favicon.png -│ │ ├── logo_dark.png -│ │ └── logo_light.png -│ ├── img/ -│ ├── styles.css # Štýly rozhrania -│ └── theme.json # Nastavenia témy -├── .chainlit/ # Markdown pre Chainlit -└── app.py # Hlavný súbor aplikácie (Сhainlit + spracovanie API) +├── testing/ # Testy a testovacie nástroje +│ ├── tests/ +│ │ ├── test_api.py # Integračné testy voči reálnemu API +│ │ ├── test_fetch.py # Unit testy pre fetch_api_data +│ │ ├── test_llm_compare.py # LLM benchmark testy +│ │ ├── test_project.py # LLM extrakcia parametrov (DB testy) +│ │ ├── test_schemas.py # Unit testy Pydantic schém +│ │ ├── test_sys_prompt.py # Unit testy systémového promptu +│ │ └── test_tools.py # Unit testy API nástrojov +│ ├── charts/ # Výstupné reporty a coverage (generované) +│ ├── test_cases.db # SQLite databáza testovacích prípadov +│ └── run_tests.py # Spúšťač testov (pytest + HTML report + coverage) +├── app.py # Hlavný súbor aplikácie (Chainlit + spracovanie API) +├── chainlit.md # Uvítacia obrazovka (default Chainlit) +└── chainlit_en-US.md # Uvítacia obrazovka (Legal AI Assistant) ``` +--- -## INŠTRUKCIA PRE INŠTALÁCIU +## Testovanie + +Projekt obsahuje automatizované testy pokrývajúce unit testy schém, API nástrojov, fetchovania dát, systémového promptu a integračné testy voči reálnemu API Ministerstva spravodlivosti. LLM testy overujú správnosť extrakcie parametrov z prirodzeného jazyka oproti 54 referenčným prípadom uloženým v SQLite databáze. + +![Test Report](testing/images/coverage_and_test_session.png) + +--- -### **Inštalácia cez Git** +## Inštrukcia pre inštaláciu -### 1. **Naklonovanie repozitára** +### Inštalácia cez Git + +#### 1. Naklonovanie repozitára ```bash git clone git@git.kemt.fei.tuke.sk:od059jr/ai-lawyer-agent.git ``` -### 2. **Vytvorenie virtuálneho prostredia** +#### 2. Vytvorenie virtuálneho prostredia -#### Pre Windows +**Windows:** ```bash python -m venv venv - venv\Scripts\activate ``` -#### Pre macOS/Linux -``` +**macOS / Linux:** +```bash python3 -m venv venv - source venv/bin/activate ``` -### 3. **Inštalácia závislostí** +#### 3. Inštalácia závislostí + ```bash pip install -r requirements.txt ``` -### 4. **Sťahovanie inštalátora Ollama** +#### 4. Stiahnutie inštalátora Ollama -https://ollama.com/download +Stiahnite si Ollama z oficiálnej stránky: https://ollama.com/download - -### 5. **Sťahovanie modelov** +#### 5. Stiahnutie modelov ```bash ollama pull qwen3.5:cloud @@ -93,12 +136,14 @@ ollama pull qwen3.5:cloud ollama pull gpt-oss:20b-cloud ``` +--- -### **Inštalácia cez DOCKER** +### Inštalácia cez Docker -### 1. Inštalácia Docker a Docker Desktop +#### 1. Inštalácia Docker a Docker Desktop -### 2. Nainštalujte a spustite aplikáciu +Stiahnite a nainštalujte Docker Desktop: https://www.docker.com/products/docker-desktop -https://hub.docker.com/r/alexgott0616/ai-lawyer-agent +#### 2. Nainštalujte a spustite aplikáciu +Obraz je dostupný na Docker Hub: https://hub.docker.com/r/alexgott0616/ai-lawyer-agent \ No newline at end of file diff --git a/testing/tests/test_schemas.py b/testing/tests/test_schemas.py index 75100a0..f4b4301 100644 --- a/testing/tests/test_schemas.py +++ b/testing/tests/test_schemas.py @@ -169,9 +169,7 @@ class TestModelDumpExcludeNone: def test_empty_schema_excludes_none_fields_only(self): dumped = CourtSearch().model_dump(exclude_none=True) - # sortDirection='ASC' is a real default, not None — correctly kept assert dumped.get("sortDirection") == "ASC" - # None fields are excluded assert "page" not in dumped assert "size" not in dumped assert "query" not in dumped diff --git a/testing/tests/test_tools.py b/testing/tests/test_tools.py index 51f49be..80f5800 100644 --- a/testing/tests/test_tools.py +++ b/testing/tests/test_tools.py @@ -143,7 +143,6 @@ class TestDecisionTools: @respx.mock async def test_decision_id_calls_correct_url(self): - """Covers missing lines 128-130 in tools.py""" mock = respx.get(f"{JUSTICE_API_BASE}/v1/rozhodnutie/rozhodnutie_99").mock( return_value=httpx.Response(200, json={"id": "rozhodnutie_99"}) ) @@ -152,7 +151,6 @@ class TestDecisionTools: @respx.mock async def test_decision_autocomplete_calls_correct_url(self): - """Covers missing lines 141-143 in tools.py""" mock = respx.get(f"{JUSTICE_API_BASE}/v1/rozhodnutie/autocomplete").mock( return_value=make_response() ) @@ -181,7 +179,6 @@ class TestContractTools: @respx.mock async def test_contract_id_calls_correct_url(self): - """Covers missing lines 172-174 in tools.py""" mock = respx.get(f"{JUSTICE_API_BASE}/v1/zmluvy/2156252").mock( return_value=httpx.Response(200, json={"idZmluvy": "2156252"}) ) @@ -190,7 +187,6 @@ class TestContractTools: @respx.mock async def test_contract_autocomplete_calls_correct_url(self): - """Covers missing lines 185-187 in tools.py""" mock = respx.get(f"{JUSTICE_API_BASE}/v1/zmluvy/autocomplete").mock( return_value=make_response() ) @@ -211,7 +207,6 @@ class TestCivilAndAdminTools: @respx.mock async def test_civil_proceedings_id_calls_correct_url(self): - """Covers missing lines 217-219 in tools.py""" uid = "121e4d31-695e-41e1-9191-7c9ad5d8d484" mock = respx.get(f"{JUSTICE_API_BASE}/v1/obcianPojednavania/{uid}").mock( return_value=httpx.Response(200, json={"id": uid}) @@ -221,7 +216,6 @@ class TestCivilAndAdminTools: @respx.mock async def test_civil_proceedings_autocomplete_calls_correct_url(self): - """Covers missing lines 230-232 in tools.py""" mock = respx.get(f"{JUSTICE_API_BASE}/v1/obcianPojednavania/autocomplete").mock( return_value=make_response() ) @@ -238,7 +232,6 @@ class TestCivilAndAdminTools: @respx.mock async def test_admin_proceedings_id_calls_correct_url(self): - """Covers missing lines 260-262 in tools.py""" mock = respx.get(f"{JUSTICE_API_BASE}/v1/spravneKonanie/spravneKonanie_103").mock( return_value=httpx.Response(200, json={"id": "spravneKonanie_103"}) ) @@ -247,7 +240,6 @@ class TestCivilAndAdminTools: @respx.mock async def test_admin_proceedings_autocomplete_calls_correct_url(self): - """Covers missing lines 273-275 in tools.py""" mock = respx.get(f"{JUSTICE_API_BASE}/v1/spravneKonanie/autocomplete").mock( return_value=make_response() )