- 🤖 LLM usage: $2.1000 (14 commits)
- 👤 Human dev: ~$846 (8.5h @ $100/h, 30min dedup)
Generated on 2026-04-08 using openrouter/qwen/qwen3-coder-next
System kompilujący intencje biznesowe (język naturalny) do wykonywalnych procesów w kontenerach Docker — z konwersacyjnym AI i dynamicznym UI.
Użytkownik (tekst / głos / GUI)
│
▼
┌──────────────────────────┐
│ NLP Service │
│ ├─ Parser (rules/LLM) │ ← rozumie język naturalny
│ ├─ Mapper (determ.) │ ← buduje DSL
│ ├─ Orchestrator │ ← conversation loop
│ └─ Schema generator │ ← dynamic UI forms
└──────────┬───────────────┘
▼
┌──────────────────┐ ┌──────────────┐
│ Backend │────▶│ Worker │
│ (API Gateway) │ │ (Executors) │
│ DSL Engine │ └──────────────┘
└──────┬───────────┘
│
┌────┴────┐
│ Postgres│
└─────────┘
Zasada: LLM rozumie → Pydantic waliduje → Mapper buduje → Docker wykonuje
git clone <repo-url> && cd nlp2dsl
cp .env.example .env
# Uzupełnij klucze API (opcjonalne - system działa z parserem reguł)
docker compose up --build| Serwis | URL | Opis |
|---|---|---|
| Backend API | http://localhost:8010/docs | Gateway + workflow engine |
| NLP Service | http://localhost:8002/docs | NLP + conversation + schema |
| Worker | http://localhost:8004/docs | Executory akcji |
System prowadzi konwersację, dopytuje o brakujące dane i generuje dynamiczny formularz UI.
# Tekst
curl -X POST http://localhost:8010/workflow/chat/start \
-H "Content-Type: application/json" \
-d '{"text": "Chcę wysłać fakturę"}'
# Audio (STT via Deepgram)
curl -X POST http://localhost:8010/workflow/chat/start \
-F "audio=@nagranie.wav"Odpowiedź (brakujące dane):
{
"conversation_id": "a1b2c3d4e5f6",
"status": "in_progress",
"message": "Podaj: kwotę, adres e-mail odbiorcy",
"missing": ["send_invoice.amount", "send_invoice.to"],
"form": {
"action": "send_invoice",
"fields": [
{"name": "amount", "type": "number", "label": "Kwota", "required": true},
{"name": "to", "type": "email", "label": "Adres e-mail odbiorcy", "required": true},
{"name": "currency", "type": "select", "label": "Waluta", "required": false, "options": ["PLN","EUR","USD","GBP"]}
]
}
}# Tekst
curl -X POST http://localhost:8010/workflow/chat/message \
-H "Content-Type: application/json" \
-d '{"conversation_id": "a1b2c3d4e5f6", "text": "1500 PLN na klient@firma.pl"}'
# Audio (STT via Deepgram)
curl -X POST http://localhost:8010/workflow/chat/message \
-F "conversation_id=a1b2c3d4e5f6" \
-F "audio=@odpowiedz.wav"curl -X POST http://localhost:8010/workflow/chat/message \
-H "Content-Type: application/json" \
-d '{"conversation_id": "a1b2c3d4e5f6", "text": "uruchom"}'Backend generuje schematy formularzy dynamicznie z rejestru akcji:
# Wszystkie akcje
curl http://localhost:8010/workflow/actions/schema
# Konkretna akcja
curl http://localhost:8010/workflow/actions/schema/send_invoiceFrontend renderuje formularze automatycznie z tych schematów — zero ręcznych formularzy.
# Generuj DSL
curl -X POST http://localhost:8010/workflow/from-text \
-H "Content-Type: application/json" \
-d '{"text": "Co tydzień generuj raport sprzedaży w PDF i wyślij email do manager@firma.pl"}'
# Generuj + wykonaj
curl -X POST http://localhost:8010/workflow/from-text \
-H "Content-Type: application/json" \
-d '{"text": "Wyślij fakturę na 1500 PLN do klient@firma.pl", "execute": true}'curl -X POST http://localhost:8010/workflow/run \
-H "Content-Type: application/json" \
-d '{
"name": "invoice_and_email",
"steps": [
{"action": "send_invoice", "config": {"amount": 1500, "to": "klient@firma.pl", "currency": "PLN"}},
{"action": "send_email", "config": {"to": "klient@firma.pl", "subject": "Faktura wystawiona"}}
]
}'| Akcja | Wymagane | Aliasy PL |
|---|---|---|
send_invoice |
amount, to |
faktura, rachunek |
send_email |
to |
email, maila, napisz |
generate_report |
report_type |
raport, zestawienie |
crm_update |
entity |
aktualizuj crm |
notify_slack |
channel |
powiadom, slack |
invoice_and_notify · invoice_and_email · report_and_email · full_invoice_flow · full_report_flow
| Mode | Opis |
|---|---|
rules |
Offline, regex + aliasy (domyślny) |
llm |
LLM API (OpenAI / Anthropic / Ollama) |
auto |
Rules first, LLM fallback |
System obsługuje wejście głosowe w Conversation Loop:
# Konfiguracja w .env
DEEPGRAM_API_KEY=
# Użycie
curl -X POST http://localhost:8010/workflow/chat/start \
-F "audio=@nagranie.wav"- WAV, MP3, M4A, OGG, FLAC
- Język: polski (domyślny), konfigurowalny
- Model: nova-3-general (Deepgram)
Dla konwersacji w czasie rzeczywistym użyj WebSocket:
from audio_parser import StreamingSTT
stt = StreamingSTT(language="pl")
await stt.start()
await stt.send_audio(chunk)
transcript = await stt.get_transcript()System zawiera gotowy interfejs webowy z obsługą głosową:
# Otwórz w przeglądarce
http://localhost:8002/chat- 🎤 Voice input - kliknij Start Voice i mów
- 📝 Text input - wpisz wiadomość ręcznie
- 🔄 Real-time - WebSocket streaming
- 📱 PWA - instaluj jako aplikację mobilną/desktopową
<!-- Auto-connect i auto-voice na onload -->
<body onload="initVoice()"># Chrome kiosk
chrome --kiosk --autoplay-policy=no-user-gesture-required http://localhost:8002/chat
# Electron app
npm install electron
# main.js: win.loadURL('http://localhost:8002/chat')Jeśli chcesz desktopową powłokę zamiast samej przeglądarki, użyj wrappera w tauri-wrapper/.
Ten projekt otwiera istniejący backendowy ekran /chat, więc nie duplikuje logiki STT/TTS.
W trybie dev wrapper uruchamia lokalny launcher na http://127.0.0.1:1420, a potem przechodzi do backendowego czatu, gdy /health odpowie OK.
Jeśli na Twoim Linuxie Tauri blokują brakujące biblioteki WebKitGTK/GTK, użyj browserowego fallbacku:
cd tauri-wrapper && npm run desktop albo bash ./desktop.sh.
Otwiera on ten sam /chat w Chrome/Chromium w trybie --app.
Na Linuxie Tauri v1 wymaga systemowych bibliotek WebKitGTK/GTK. Jeśli npm run dev kończy się błędem z brakującymi libsoup-2.4 albo javascriptcoregtk-4.0, doinstaluj:
sudo apt install build-essential curl wget file libssl-dev libgtk-3-dev \
libwebkit2gtk-4.0-dev libsoup2.4-dev libjavascriptcoregtk-4.0-dev \
libayatana-appindicator3-dev librsvg2-devJeśli używasz innej dystrybucji, zainstaluj odpowiednie odpowiedniki pakietów deweloperskich WebKitGTK/GTK.
cd tauri-wrapper
npm install
npm run devJeśli nie chcesz instalować bibliotek systemowych albo Tauri nie startuje, użyj:
cd tauri-wrapper
npm run desktopLauncher sprawdza backend pod http://127.0.0.1:8002 i dopiero potem przełącza do http://127.0.0.1:8002/chat.
cd tauri-wrapper
npm run buildJeśli chcesz ominąć Tauri na danym systemie, użyj tauri-wrapper/desktop.sh.
Skrypt czeka na backend, a potem otwiera voice chat w Chrome/Chromium w trybie --app.
To dobre rozwiązanie, gdy środowisko nie ma wymaganych bibliotek WebKitGTK dla Tauri.
Konfiguracja LLM:
- Skopiuj
.env.example→.env - Uzupełnij klucz API wybranego providera:
# OpenRouter (domyślny)
OPENROUTER_API_KEY=
LLM_MODEL=openrouter/openai/gpt-5-mini
# Speech-to-Text (Deepgram)
DEEPGRAM_API_KEY=
# Lub OpenAI
OPENAI_API_KEY=
LLM_MODEL=gpt-4o-mini
# Lub Anthropic
ANTHROPIC_API_KEY=
LLM_MODEL=claude-sonnet-4-...
# Lub Ollama (lokalny)
OLLAMA_API_BASE=http://localhost:11434
LLM_MODEL=ollama/llama3Zmienne są automatycznie przekazywane do kontenerów w docker-compose.yml.
nlp2dsl/
├── docker-compose.yml
├── .env.example # Konfiguracja LLM i serwisów
├── examples/ # Przykłady użycia
│ ├── 01-invoice/
│ ├── 02-email/
│ ├── 03-report-and-notify/
│ ├── 04-scheduled-report/
│ ├── 05-conversation-flow/
│ ├── README.md
│ ├── EXECUTION_REPORT.md
│ └── MISSING_CONFIGURATION.md
├── backend/ # API Gateway + Workflow Engine
│ └── app/
│ ├── main.py
│ ├── schemas.py # DSL models (Pydantic)
│ └── workflow.py # Engine + Chat proxy + Schema proxy
├── nlp-service/ # NLP → DSL Pipeline
│ └── app/
│ ├── main.py # FastAPI endpoints
│ ├── schemas.py # NLP + DSL + Conversation + UI schemas
│ ├── registry.py # Actions registry (source of truth)
│ ├── parser_rules.py # Rule-based parser (offline)
│ ├── parser_llm.py # LLM-based parser (API)
│ ├── mapper.py # Deterministic NLP → DSL mapper
│ └── orchestrator.py # Conversation loop + schema-driven UI
├── worker/ # Imperatywne executory
│ └── worker.py
├── tauri-wrapper/ # Desktop wrapper Tauri dla `/chat`
└── README.md
Zobacz examples/README.md dla pełnej listy przykładów:
Jeśli chcesz od razu uruchomić gotowy scenariusz bez tworzenia wrappera, użyj pakietowego CLI:
nlp2dsl-demo --list
nlp2dsl-demo gallery# Uruchom wszystkie przykłady
cd examples
for dir in */; do
echo "Testing $dir"
cd "$dir"
python3 main.py
cd - > /dev/null
done| Przykład | Link | Opis | Koncepcje |
|---|---|---|---|
| 01-invoice | 📁 examples/01-invoice/ | Wysyłanie faktur z kwotą i odbiorcą | One-shot API, DSL |
| 02-email | 📁 examples/02-email/ | Różne sposoby wysyłania e-maili | Aliasy komend, parametry |
| 03-report-and-notify | 📁 examples/03-report-and-notify/ | Raporty + powiadomienia na wiele kanałów | Composite intents, multi-step |
| 04-scheduled-report | 📁 examples/04-scheduled-report/ | Zaplanowane raporty (daily/weekly/monthly) | Triggers, schedule |
| 05-conversation-flow | 📁 examples/05-conversation-flow/ | Pełny cykl konwersacyjny od startu do wykonania | Chat API, state management |
cd examples/01-invoice
python3 main.pySystem jest odporny na brakującą konfigurację:
- Brak kluczy LLM: Automatycznie używa parsera reguł
- Brak Redis: In-memory storage (utrata danych przy restarcie)
- Brak bazy: Ograniczone funkcje (brak historii)
- Mock integracje: Worker zwraca symulowane odpowiedzi
Szczegóły w examples/MISSING_CONFIGURATION.md.
Każdy przykład zawiera:
Dockerfile- konteneryzacjarequirements.txt- zależności Python.env.example- szablon konfiguracji
Opcjonalne serwisy pomocnicze:
docker compose -f examples/docker-compose.yml --profile email up -d smtp-mock
docker compose -f examples/docker-compose.yml --profile storage up -d minionlp-service/app/registry.py— dodaj doACTIONS_REGISTRYworker/worker.py— dodaj handler@action("nazwa")docker compose up --build
Licensed under Apache-2.0.