- 🤖 LLM usage: $14.0885 (48 commits)
- 👤 Human dev: ~$2446 (24.5h @ $100/h, 30min dedup)
Generated on 2026-06-06 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
Repozytorium zawiera dwa poziomy:
| Warstwa | Lokalizacja | Rola |
|---|---|---|
| Platforma MVP | backend/, nlp-service/, worker/ |
Workflow DSL (faktury, e-mail, raporty) w Docker |
| SDK (wydzielone) | packages/dsl-*, nlp2dsl-*, workflow-export, testql-conversations |
Kontrakty, walidacja, artefakty, eksport markpact/pactown |
| Mapa środowiska | env2llm (semcod) |
environment.doql.less, SystemMapIR, registry |
| Pakiety IR | packages/pact-ir, nlp2cmd-* |
IntentIR / ExecutionPlanIR — wspólny język z nlp2cmd i Propact |
| Narzędzie | Zadanie |
|---|---|
nlp2dsl show "query" |
Struktura zapytania (IntentIR) — bez wykonania |
nlp2cmd plan "query" |
Plan → Propact markdown; --execute → hybrid executor (Propact + nlp2cmd) |
nlp2cmd -q "query" -r |
Legacy runtime nlp2cmd (shell / browser / canvas) |
examples/*/scenario.py |
Demo platformy MVP (wymaga docker compose up; main.py = punkt wejścia) |
./scripts/setup-dev.sh # pakiety IR + SDK + nlp2cmd[integration]
# lub tylko pakiety:
./packages/install-dev.sh
export NLP2CMD_INTEGRATION=1nlp2dsl show "znajdz pliki *.py w src" # IntentIR JSON
nlp2cmd plan "znajdz pliki *.py w src" # Propact markdown
nlp2cmd plan "znajdz pliki *.py w src" --explain # + execution_route
nlp2cmd plan "znajdz pliki *.py w src" --execute # hybrid executor
NLP2CMD_SHOW_STRUCTURE=1 nlp2cmd -q "query" # analiza na wejściu nlp2cmdSzczegóły: packages/README.md · walidacja kontraktów: docs/intract-integration.md · walidacja requestu: docs/validation.md
flowchart LR
Q[NL query] --> SHOW[nlp2dsl show]
Q --> PLAN[nlp2cmd plan]
subgraph pkgs [packages/]
IR[IntentIR]
EPIR[ExecutionPlanIR]
end
SHOW --> IR
SHOW --> EPIR
PLAN --> IR --> EPIR --> MD[Propact markdown]
EPIR -.->|NLP2CMD_INTRACT_GATE| GATE[PlanStepGate w nlp2cmd]
| Narzędzie | Walidacja struktury | Kontrakty Intract |
|---|---|---|
nlp2dsl show |
Pydantic + confidence | opcjonalnie --plan + INTRACT_GATE |
nlp2cmd plan |
needs_clarification zawsze |
opcjonalnie INTRACT_GATE |
nlp2cmd -q -r |
ActionRegistry (legacy) | opcjonalnie INTRACT_GATE |
Nie wymaga ręcznej konfiguracji. Import nlp2dsl_sdk oraz CLI (nlp2dsl, nlp2dsl-demo, nlp2dsl-show) automatycznie ustawiają stdio i locale na UTF-8 (naprawia m.in. znajd? → znajdź).
Szczegóły: docs/encoding.md
Wyłączenie: NLP2DSL_UTF8=0
examples/NN-name/.nlp2dsl/ — DOQL env (env2llm), manifest/pipeline/process (nlp2dsl-artifacts), TestQL (testql-conversations).
| Pakiet | Pliki |
|---|---|
env2llm |
registry/environment.doql.less |
nlp2dsl-artifacts |
manifest.yaml, pipeline/, process/, commands.testql.toon.yaml |
workflow-export |
generated/markpact/, generated/pactown/ (examples 03, 04, 14) |
nlp2dsl-stack |
generated/docker-compose.stack.yaml, cron (example 13) |
Generowanie: bash examples/run-all.sh · docs: docs/artifacts.md · pakiety: packages/README.md
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
# Poczekaj na health (SDK robi to automatycznie w przykładach):
curl -s http://localhost:8010/health && curl -s http://localhost:8012/health && curl -s http://localhost:8004/health| Serwis | URL | Opis |
|---|---|---|
| Backend API | http://localhost:8010/docs | Gateway + workflow engine |
| NLP Service | http://localhost:8012/docs | NLP + conversation + schema |
| Worker | http://localhost:8004/docs | Executory akcji |
Port 8012 (nie 8002) — 8002 bywa zajęty przez Mullm Projector. Zmienne:
NLP2DSL_BACKEND_HOST_PORT,NLP2DSL_NLP_HOST_PORT,NLP2DSL_WORKER_HOST_PORTw.env.
Struktura zapytania (environment.doql.less / SystemMapIR) determinuje reguły walidacji w każdej fazie (preflight → DSL ready → execute → post-exec). Autonomiczna pętla naprawia brakujące dane i niepoprawne załączniki PDF zanim zapyta użytkownika.
Szczegóły: docs/validation.md · docs/process-agent.md · docs/reflection-model.md
Szczegóły (Intract vs MVP, walidacja, logi, dialog): examples/README.md
# env2llm nie jest na PyPI — najpierw lokalne pakiety (semcod/env2llm + packages/)
bash scripts/install-local-deps.sh && pip install -e .
# lub: ./scripts/setup-dev.sh
docker compose up -d
python3 examples/06-interactive-chat/main.py --interactive # rozmowa w terminalu
python3 examples/07-email-conversation/main.py # e-mail + uzupełnianie body
./examples/run-all.shSystem 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:8012/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:8012/chat
# Electron app
npm install electron
# main.js: win.loadURL('http://localhost:8012/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:8012 i dopiero potem przełącza do http://127.0.0.1:8012/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 (porty 8010/8012/8004)
├── nlp2dsl_sdk/ # SDK klienta, DOQL, walidacja, reflection
├── docs/ # Dokumentacja (indeks: docs/README.md)
├── 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
│ ├── engine.py # Workflow execution + pre-step validation
│ └── routers/chat.py # Chat proxy + auto_execute
├── nlp-service/ # NLP → DSL Pipeline
│ └── app/
│ ├── conversation/ # orchestrator, autonomous_loop, process_agent
│ ├── validation/ # step_validator, attachment, path_policy
│ ├── registry.py # Actions registry (migracja → DOQL)
│ └── ...
├── worker/ # Imperatywne executory + invoice_pdf
│ └── worker.py
├── tauri-wrapper/ # Desktop wrapper Tauri dla `/chat`
└── README.md
Pełna dokumentacja: docs/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/ | Faktura autonomiczna + PDF + walidacja strict | DOQL autofill, attachment_validation, reflection |
| 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 |
bash scripts/install-local-deps.sh && pip install -e .
docker compose up -d # backend + nlp-service + worker
python3 examples/01-invoice/main.py # czeka na /health (do 120 s)
./examples/run-all.sh # wszystkie przykłady
# lub pojedynczo:
cd examples/01-invoice && python3 main.pySDK (ensure_services) sprawdza http://localhost:8010, :8012, :8004 — nie uruchamiaj main.py w tej samej linii co compose up bez oczekiwania (race przy starcie uvicorn).
Logi serwisu NLP (z roota repo, nie examples/docker-compose.yml):
docker compose logs -f nlp-serviceSystem 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.