Endpointy, Integracje i Bezpieczeństwo
Publiczne
| Method | Path | Blueprint | Opis |
|---|---|---|---|
| GET | / |
public_bp |
Strona główna. |
| POST | / |
public_bp |
Handler prostej interakcji typu 0. |
| GET | /livenez |
public_bp |
Healthcheck. |
| GET | /terms_of_service |
public_bp |
Regulamin. |
| GET | /privacy_policy |
public_bp |
Polityka prywatności. |
| GET | /public/ping |
public_bp |
Prosty ping publiczny. |
| GET | /docs |
docs_bp |
Renderowanie domyślnej strony dokumentacji. |
| GET | /docs/<page> |
docs_bp |
Renderowanie dozwolonej strony dokumentacji Markdown. |
| GET | /register_page |
auth |
Strona rejestracji. |
| GET | /login_page |
auth |
Strona logowania. |
| POST | /register |
auth |
Rejestracja użytkownika. |
| POST | /login |
auth |
Logowanie użytkownika. |
| GET | /auth/oauth2/callback |
auth_discord |
Discord OAuth2 callback. |
| POST | /azure/boards/add_task |
bug_report |
Utworzenie zgłoszenia błędu. |
Chronione Logowaniem
| Method | Path | Blueprint | Opis |
|---|---|---|---|
| GET | /chat_page |
chat_bp |
Widok chatu. |
| POST | /logout |
auth |
Wylogowanie. |
| GET | /users |
users_bp |
Lista użytkowników. |
| GET | /users/<user_id> |
users_bp |
Pobranie użytkownika. |
| PUT | /users/<user_id> |
users_bp |
Aktualizacja danych użytkownika. |
| PUT | /users/<user_id>/update_password |
users_bp |
Aktualizacja hasła. |
| DELETE | /users/<user_id>/delete |
users_bp |
Usunięcie użytkownika. |
| POST | /chat/ask |
chat_bp |
Wysłanie promptu do asystenta. |
| POST | /chat/conversations/add |
chat_bp |
Utworzenie konwersacji. |
| GET | /chat/conversations/<conversation_id> |
chat_bp |
Pobranie historii konwersacji. |
| GET | /chat/conversations/all |
chat_bp |
Pobranie listy konwersacji użytkownika. |
| PUT | /chat/conversations/<conversation_id>/set_context |
chat_bp |
Ustawienie kontekstu konwersacji. |
| POST | /update_config |
chat_bp |
Aktualizacja konfiguracji chatu. |
| GET | /get_config |
chat_bp |
Pobranie konfiguracji chatu. |
| GET | /get_models |
chat_bp |
Lista dostępnych modeli. |
| GET | /get_languages |
chat_bp |
Lista dostępnych języków. |
| GET | /speech/config |
speech_bp |
Konfiguracja Speaches, dostępne modele i głosy. |
| POST | /speech/synthesize |
speech_bp |
Synteza TTS przez Speaches. |
Integracje Zewnętrzne
OpenAI
Logika OpenAI znajduje się w backend/services/openai_service.py.
Główne funkcje:
get_openai_client(),get_conversation_history(conversation_id, limit),save_conversation_history(prompt, generated_response, conversation_id, used_tokens),get_conversation_by_id(conversation_id),get_chat_configuration_data(user_id),generate_response(user_input, model, conversation_id, temperature, n).
generate_response():
- Pobiera historię konwersacji dla aktualnego użytkownika.
- Pobiera memory context z
ConversationSummaryiMemoryItem. - Buduje prompt z pamięci, ostatnich wpisów historii i promptu użytkownika.
- Wywołuje OpenAI Chat Completions.
- Konwertuje odpowiedź Markdown do HTML.
- Zapisuje historię do bazy.
- Wrzuca job pamięci do Redis queue
jarvis:memory:jobs. - Zwraca HTML odpowiedzi.
Klient OpenAI jest tworzony leniwie, a nie przy imporcie modułu.
Memory Service
Logika pamięci znajduje się w:
backend/services/memory_service.py,backend/services/memory_extractors.py,backend/workers/memory_worker.py.
web zapisuje historię i wrzuca lekki job do Redis. memory-worker pobiera job w tle, aktualizuje conversation_summary i zapisuje przefiltrowane memory_items. Lokalny extractor może korzystać z modelu qwen2.5:3b-instruct przez OpenAI-compatible endpoint Ollamy. Jeśli extractor nie odpowie albo zwróci niepoprawny JSON, worker używa fallbacku heurystycznego.
Redis
Redis jest wspólną zależnością runtime dla:
- server-side sessions,
- rate limitów,
- cache TTS,
- kolejki
jarvis:memory:jobs.
W testach i poza Compose dopuszczalny jest fallback memory:// dla rate limitów, ale w Compose REDIS_URL, SESSION_REDIS_URL i RATELIMIT_STORAGE_URI powinny wskazywać na kontener Redis.
Speaches
Integracja speech znajduje się w:
backend/blueprints/speech.py,backend/services/speech_service.py,backend/data/speaches-voices.json.
GET /speech/config zwraca aktualną konfigurację użytkownika oraz listę wspieranych modeli i głosów. POST /speech/transcribe przyjmuje nagranie z web voice mode i przekazuje je do Speaches endpoint /v1/audio/transcriptions. POST /internal/speech/transcribe używa tej samej ścieżki dla Discord bota, ale jest chroniony service tokenem. POST /speech/synthesize waliduje model i głos, sprawdza czy Speaches jest włączony dla użytkownika, korzysta z cache Redis, a następnie wywołuje Speaches endpoint /v1/audio/speech.
STT używa limitera współbieżności SPEECH_STT_MAX_CONCURRENT_REQUESTS. Gdy wszystkie sloty są zajęte dłużej niż timeout STT, endpoint zwraca 503, zamiast budować niekontrolowany backlog CPU.
Azure Boards
Integracja znajduje się w backend/blueprints/bug_report.py.
Klient Azure DevOps jest tworzony tylko wtedy, gdy endpoint bug reportu jest faktycznie używany. Jeśli konfiguracja Azure nie istnieje, endpoint zwraca 503.
Discord
Discord występuje w dwóch miejscach:
- OAuth2 callback w
backend/services/auth_discord.py, - bug report webhook w
backend/blueprints/bug_report.py.
Webhook bug reportów jest opcjonalny. Brak webhooka nie powinien przerywać tworzenia zgłoszenia w Azure Boards.
Panel Discord Admin czyta dane administracyjne z bazy bota Discord przez:
DISCORD_BOT_DATABASE_URI,DISCORD_BOT_DB_SCHEMA.
Te wartości muszą wskazywać na tę samą bazę i schemat, w których bot zapisuje discord_admin_users oraz discord_bot_config. Jeżeli bot odpowiada na /grant_admin <member> albo /allow_text_channel, że wpis już istnieje, a web panel nadal pokazuje brak dostępu albo brak serwerów, najpierw sprawdź te dwie zmienne w środowisku web containera.
Rejestracja po Discord OAuth zapisuje powiązanie w dwóch miejscach webowej bazy:
users.discord_id,discord_accounts.
Dzięki temu web ma lokalny rekord powiązania niezależnie od tego, czy użytkownik połączył Discord z istniejącym kontem, czy założył nowe konto przez Discord OAuth.
Avatar serwera w panelu jest możliwy, jeśli bot zapisuje w discord_bot_config jedną z opcjonalnych kolumn:
guild_icon_url- pełny URL ikony,guild_icon- hash ikony Discorda; web zbuduje URL CDN na podstawieguild_id.
Jeżeli żadna z tych kolumn nie istnieje, panel pokazuje fallback z pierwszą literą nazwy serwera.
reCAPTCHA
Rejestracja korzysta z reCAPTCHA. Wymagane są:
CAPTCHA_SITE_KEY,CAPTCHA_SECRET_KEY,CAPTCHA_VERIFY_URL.
CAPTCHA_VERIFY_URL musi wskazywać na endpoint backendowej weryfikacji tokenu, np. https://www.google.com/recaptcha/api/siteverify. Ustawienie go na https://www.google.com/recaptcha/api.js albo enterprise.js?... spowoduje błąd HTTP Error 405: Method Not Allowed, bo backend wysyła tam żądanie POST z tokenem.
W środowiskach testowych można używać MockServer lub mocków w testach.
Obserwowalność i Logowanie
Logowanie
Logowanie jest konfigurowane w backend/__init__.py przez logging.basicConfig.
Logi trafiają do:
./logs/app.log,- stdout/stderr.
SQLAlchemy engine i pool są ustawione na poziom WARNING.
OpenTelemetry
backend/observability.py instrumentuje:
- Flask,
- SQLAlchemy,
- requests.
Jeśli OTEL_ENDPOINT jest ustawiony, aplikacja konfiguruje OTLP exporter dla
traces, metrics i logs. Poszczególne sygnały można wyłączyć zmiennymi
OTEL_TRACES_ENABLED, OTEL_METRICS_ENABLED i OTEL_LOGS_ENABLED.
Metryki STT
Backend emituje metryki OpenTelemetry dla wspólnego serwisu STT używanego przez web i Discord:
| Metryka | Typ | Opis |
|---|---|---|
speech.stt.requests |
counter | Liczba requestów STT według statusu. |
speech.stt.queue_wait_ms |
histogram | Czas oczekiwania na slot limitera STT. |
speech.stt.elapsed_ms |
histogram | Czas wywołania Speaches /audio/transcriptions. |
speech.stt.audio_bytes |
histogram | Rozmiar audio przekazanego do STT. |
speech.stt.audio_duration_ms |
histogram | Czas audio zwrócony przez provider, jeśli dostępny. |
speech.stt.transcript_chars |
histogram | Długość zwróconego transkryptu. |
Wspólne atrybuty to source (web albo discord), provider, model, language i status. Statusy obejmują między innymi started, success, no_speech, busy, timeout, error i transport_error.
Nie dodawaj guild_id, user_id ani channel_id jako atrybutów metryk OTEL/Prometheus. Dla paneli adminów Discorda używaj osobnej agregacji per guild w DB/Redis, żeby uniknąć wysokiej krotności labeli w Grafanie.
Bezpieczeństwo
Najważniejsze zasady dla tego repo:
- nie commitować sekretów,
DISCORD_BUG_REPORT_WEBHOOKtrzymać w secret variables,AZURE_PERSONAL_ACCESS_TOKENtrzymać w secret store,OPENAI_API_KEYtrzymać poza repo,- produkcyjnie ustawić mocny
FLASK_SECRET_KEY, - produkcyjnie ustawić
SESSION_COOKIE_SECURE=trueza HTTPS, - nie używać
AUTO_CREATE_DB=truew produkcji, - nie trzymać narzędzi developerskich w finalnym obrazie produkcyjnym,
- walidować dane wejściowe po stronie backendu, nie tylko w JS.
- nie zapisywać sekretów ani danych wrażliwych jako
MemoryItem.
Znane Ograniczenia
Aktualny stan nadal ma kilka obszarów do poprawy:
auth.pynadal miesza HTTP, walidację, reCAPTCHA i logikę tworzenia użytkownika.chat.pynadal zawiera część logiki HTTP i konfiguracji użytkownika w jednym pliku.- Brakuje dedykowanych serwisów domenowych typu
AuthService,UserService,ChatService. - Brakuje repozytoriów/warstwy dostępu do danych.
- Brakuje centralnego mechanizmu walidacji requestów.
- Brakuje jednolitego formatu błędów API.
- Memory vector search jest jeszcze na roadmapie; aktualnie wybór memory items jest heurystyczny.
requirements.txtnie ma przypiętych wersji zależności runtime.pyproject.tomltargetuje Python 3.11, pipeline używa 3.12, Dockerfile używa 3.13.- Frontend nie ma wspólnego
base.html. - Część plików CSS/JS wygląda na starsze warianty lub duplikaty.