О проекте
Команда: Nexora
Кейс HackAlem.ai: Инновации — Самрук-Казына
Стадия: Рабочий MVP
Задача кейса: «Хаттама»: протокол и поручения по аудиозаписи совещания (каз./рус./смешанная речь)
Суть
Self-hosted платформа LAN-конференций (WebRTC) с записью и локальным ИИ: Whisper распознаёт речь на RU/KK, Ollama формирует промежуточную и итоговую сводку и поручения с цитатой-основанием. Есть контроль сроков, экспорт PDF/DOCX/WAV и граф корпоративной памяти.
Как устроено
Участники общаются в браузере через WebRTC mesh, сигналинг идёт по WebSocket через FastAPI. Организатор включает запись, аудиофрагменты каждого участника ставятся в очередь, и live-worker отправляет их в self-hosted faster-whisper large-v3. Реплики подписываются по отдельным потокам участников вместо диаризации. Ollama (qwen3:8b) выдаёт сводку и поручения (исполнитель, срок, цитата), человек их проверяет. Данные хранятся в PostgreSQL с миграциями Alembic, HTTPS для LAN обеспечивает Caddy. Отдельно сохранён API загрузки файлов с pyannote.
Ключевые решения
- faster-whisper large-v3
- Ollama
- WebRTC mesh
- WebSocket signaling
- атрибуция спикеров по аудиопотокам
- pyannote (старый API)
- граф корпоративной памяти
- what-changed
- Alembic миграции
Особенности
Задача диаризации обойдена архитектурно: команда сделала собственную LAN-конференцию, где у каждого участника отдельный микрофонный поток, поэтому имя привязывается к реплике без биометрии. Всё self-hosted, Whisper и Ollama можно вынести на отдельный ПК в сети. Демо-данные удалены: при недоступности ИИ интерфейс честно это показывает.
Стек
React 19 · TypeScript · Vinext/Vite · FastAPI · SQLAlchemy · PostgreSQL · Alembic · WebRTC · Docker Compose · Caddy
Модели
Whisper large-v3 (faster-whisper) · Ollama qwen3:8b · pyannote
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-d13e095c-nexora.
README
README.mdПротокол · Nexora
Совещание → протокол → поручения → контроль исполнения
Рабочее пространство для конференций по LAN и подготовки протоколов с локальным ИИ. Участники общаются в браузере, организатор включает запись, Whisper распознаёт речь, а Ollama формирует сводку и поручения для проверки человеком.
Текущий статус: MVP. Frontend подключён к FastAPI и PostgreSQL. Деморежим и генераторы примерных данных удалены. Для распознавания и анализа необходимы доступные self-hosted Whisper и Ollama.
Быстрый старт · Возможности · Архитектура · Проверки
Быстрый старт
1. Что установить
- На ПК с сайтом: Git и Docker Desktop (Windows/macOS) либо Docker Engine с Compose v2 (Linux). Запустите Docker. Node.js, Python и PostgreSQL отдельно устанавливать не нужно.
- На ПК с моделями: Ollama. Это может быть тот же компьютер, где запущен сайт, или отдельный компьютер в той же LAN.
2. Скачать модель на ПК с Ollama
ollama pull qwen3:8b
Если Ollama расположен на отдельном ПК, задайте для процесса Ollama переменную окружения OLLAMA_HOST=0.0.0.0:11434, перезапустите Ollama и разрешите доступ к TCP 11434 из вашей LAN. Если Ollama запущен на том же ПК, внешний порт 11434 открывать не нужно.
3. Скачать проект и настроить адреса на ПК с сайтом
git clone https://github.com/BAITC-Hacks/hack-d13e095c-nexora.git
cd hack-d13e095c-nexora
cp .env.conference.example .env
Если проект уже скачан — выполните git pull origin main. Существующий .env сохраните. В PowerShell для копирования можно использовать Copy-Item.
Откройте .env и замените адреса на свои:
SITE_HOST=192.168.1.100
OLLAMA_URL=http://192.168.1.101:11434
OLLAMA_MODEL=qwen3:8b
SPEECH_URL=http://speech:8001
Здесь .100 — ПК с сайтом, .101 — ПК с Ollama. Для существующей базы сохраните прежний POSTGRES_PASSWORD.
Если Ollama и Docker работают на одном ПК, используйте OLLAMA_URL=http://host.docker.internal:11434.
PowerShell: настройка .env
Не вставляйте URL как Markdown-ссылку: значение должно быть обычным текстом http://.... Пример для IP 10.19.16.77 и Ollama на этом же ПК:
Copy-Item .env.conference.example .env -Force
$config = Get-Content .env
$config = $config -replace 'SITE_HOST=.*', 'SITE_HOST=10.19.16.77'
$config = $config -replace 'OLLAMA_URL=.*', 'OLLAMA_URL=http://host.docker.internal:11434'
$config | Set-Content .env
4. Запустить всё
docker compose --profile speech up -d --build
Команда запускает сайт, API, базу, обработчик, HTTPS и Whisper. При первом запуске Whisper автоматически скачает large-v3 — несколько ГБ; дождитесь завершения. HF-токен не нужен. Ollama продолжает работать на другом ПК. Whisper по умолчанию использует CPU и может не успевать за разговором.
Если Whisper тоже нужен на другом ПК: настройте его по инструкции, задайте SPEECH_URL и одинаковый SPEECH_API_KEY на обоих ПК; сайт запускайте командой docker compose up -d --build без профиля speech. Там же описан запуск с NVIDIA GPU.
5. Открыть сайт и начать встречу
Для камеры и микрофона по LAN установите сертификат сервера на каждом компьютере участника. Получить его:
docker compose cp gateway:/data/caddy/pki/authorities/local/root.crt ./conference-root.crt
Импортируйте conference-root.crt в доверенные корневые сертификаты (как установить), разрешите TCP 8443 на ПК с сайтом и откройте https://192.168.1.100:8443, заменив IP на свой.
Начать совещание → создать → войти → пригласить коллег → включить «Запись и ИИ». Кнопка «Проверить ИИ» покажет доступность Whisper и Ollama.
Проверка контейнеров: docker compose ps. Остановка с сохранением данных: docker compose down.
Подробности и проверка двумя участниками: CONFERENCES.md.
Диагностика Docker и LAN
Проверить запуск
docker compose ps
docker compose logs --tail=100
Нормальный результат: api и db имеют статус healthy; gateway, frontend, live-worker и speech имеют статус Up.
PostgreSQL работает в Docker на ПК с сайтом. База не опубликована в LAN: к ней обращается только API через внутреннюю сеть Compose. Данные сохраняются после docker compose down; команда docker compose down -v удаляет том базы.
Сайт не открывается у коллег
Проверьте, что все устройства в одной сети, Docker Desktop запущен, а TCP-порт 8443 разрешён в брандмауэре Windows. На ПК с сайтом порт можно проверить командой:
netstat -ano | findstr :8443
Для быстрой проверки интерфейса без сертификата используйте http://ВАШ_IP:8080. Этот адрес не подходит для микрофона, камеры и демонстрации экрана: браузеры разрешают их в LAN только по доверенному HTTPS.
ERR_SSL_PROTOCOL_ERROR при https://ВАШ_IP:8443
Для LAN-IP Caddy должен иметь default_sni; он уже добавлен в deploy/Caddyfile. После обновления репозитория перезапустите gateway:
git pull origin main
docker compose up -d --build gateway
docker compose logs gateway --tail=100
В SITE_HOST указывайте только IP или DNS-имя: без http://, https://, номера порта, квадратных скобок и Markdown-разметки.
Микрофон и камера недоступны
Экспортируйте корневой сертификат Caddy:
docker compose cp gateway:/data/caddy/pki/authorities/local/root.crt .\conference-root.crt
Импортируйте conference-root.crt в доверенные корневые центры сертификации ОС на каждом устройстве, полностью перезапустите браузер и откройте https://ВАШ_IP:8443. Затем разрешите браузеру доступ к микрофону и камере.
ИИ недоступен
ollama list
Invoke-WebRequest http://127.0.0.1:11434/api/tags
docker compose logs live-worker --tail=100
Для Ollama на том же ПК используйте OLLAMA_URL=http://host.docker.internal:11434; для отдельного ПК — его LAN-IP, например OLLAMA_URL=http://192.168.1.101:11434.
Возможности
| Область | Реализация MVP |
|---|---|
| Конференции | Создание, планирование, приглашения, до 8 одновременных участников |
| Общение | WebRTC-аудио и видео, демонстрация экрана, чат |
| Запись | Явное включение организатором, уведомление участников, очередь аудиофрагментов |
| Расшифровка | Self-hosted Whisper, RU/KK, имена по отдельным потокам участников |
| Анализ | Удалённая локальная Ollama: промежуточная сводка, поручения и итоговый анализ |
| Поручения | Исполнитель, срок, цитата-основание, редактирование и статусы |
| Документы | Экспорт PDF, DOCX и аудиозаписи WAV |
| Напоминания | Сроки и просрочка в приложении; уведомления браузера при открытом сайте |
| Хранение | PostgreSQL и Docker-том записей; локальная очередь неотправленного аудио в браузере |
Начальные списки пустые. Встречи создаются пользователями, а реплики и результаты появляются после реальной обработки. Недоступность ИИ отображается в интерфейсе без подстановки примерного текста.
Архитектура
- Frontend: React 19, TypeScript, Vinext / Vite.
- Backend: FastAPI, SQLAlchemy, PostgreSQL, Alembic.
- Медиа: WebRTC mesh; FastAPI предоставляет WebSocket-сигналинг.
- ИИ: отдельный сервис faster-whisper и Ollama на вашем сервере.
- Развёртывание: Docker Compose, Caddy HTTPS, один API-процесс и один live-worker.
Старый API обработки загруженных файлов с pyannote остаётся отдельным сценарием: backend/README.md. Его worker не запускается в корневом стеке живых конференций.
Разработка
Node.js 22.13 или новее:
npm ci
npm run dev
Backend запускается отдельно или через Docker. Dev-сервер проксирует запросы конференций к локальному API.
Проверки
npx tsc --noEmit
node scripts/test-live-audio.mjs
npm run build
Серверные тесты находятся в backend/tests.
При реализации проверены Docker-сборка и запуск, миграция PostgreSQL, HTTPS, 85 серверных тестов и 2 теста аудиокодирования/завершения записи. Тесты ИИ используют контролируемые ответы и проверяют обработку данных, а не качество моделей.
Реальный звонок между двумя физическими ПК, скорость обработки и качество русской, казахской и смешанной речи требуют проверки на вашем оборудовании. Сценарий приёмки включён в CONFERENCES.md.
Ограничения и дальнейшее развитие
- Каждый участник использует свой микрофон: подпись по имени не является биометрическим распознаванием личности.
- Скорость зависит от оборудования и моделей; CPU может не успевать за разговором.
- Доступ осуществляется по приглашению и персональному токену браузера; корпоративный SSO не реализован.
- Напоминания требуют открытого приложения. Email/Telegram и внешняя СЭД пока не подключены.
- В сетях без прямой связности участников необходим собственный TURN-сервер.
Разработано командой Nexora.
Авторы коммитов
История коммитов
- 2026-09-23 17:58fix: configure LAN HTTPS and document Docker troubleshootingFloUrenzz
- 2026-09-23 17:48feat: add corporate memory graphhilrein
- 2026-09-23 17:32dadadadahilrein
- 2026-09-23 17:15docs: add concise installation and startup guidehilrein
- 2026-09-23 17:14feat: add real LAN conferences and local AI processing, remove demo datahilrein
- 2026-09-23 17:11Update NewyorkErzhan Ikramov
- 2026-09-23 16:58docs: оформить README проекта Протокол / NexoraRenzzy
- 2026-09-23 16:28Simplify meeting workspace UI and add Docker setuphilrein
Все коммиты (26)
- 2026-09-23 16:25Update NewyorkErzhan Ikramov
- 2026-09-23 16:24Update NewyorkRenzzy
- 2026-09-23 15:59feat: add local meeting processing backendSkyWalkerE13
- 2026-09-23 15:57Update NewyorkErzhan Ikramov
- 2026-09-23 15:57add frontend skills for codexhilrein
- 2026-09-23 15:47Update NewyorkRenzzy
- 2026-09-23 15:15Update NewyorkErzhan Ikramov
- 2026-09-23 15:14Add new line to Newyork fileRenzzy
- 2026-09-23 15:13add some skillshilrein
- 2026-09-23 15:00Update NewyorkRenzzy
- 2026-09-23 15:00Create NewyorkErzhan Ikramov
- 2026-09-23 14:56Revise FastAPI patterns documentation for claritySanzhar Turabaev
- 2026-09-23 14:48Create FastAPI patterns documentationSanzhar Turabaev
- 2026-09-23 14:27feat: добавить прототип СЭД для протоколирования совещанийRenzzy
- 2026-09-23 14:05Update README.mdRenzzy
- 2026-09-23 13:50Add meeting notes for chemical industry and safetyErzhan Ikramov
- 2026-09-23 13:30Update README with project goalsSanzhar Turabaev
- 2026-09-23 13:21Update README.mdRenzzy
Структура репозитория (309 файлов)
.agents/skills/.impeccable/config.local.json .agents/skills/brandkit/SKILL.md .agents/skills/design-taste-frontend-v1/SKILL.md .agents/skills/design-taste-frontend/SKILL.md .agents/skills/full-output-enforcement/SKILL.md .agents/skills/gpt-taste/SKILL.md .agents/skills/high-end-visual-design/SKILL.md .agents/skills/image-to-code/SKILL.md .agents/skills/imagegen-frontend-mobile/SKILL.md .agents/skills/imagegen-frontend-web/SKILL.md .agents/skills/impeccable/SKILL.md .agents/skills/impeccable/agents/impeccable_asset_producer.toml .agents/skills/impeccable/agents/impeccable_documenter.toml .agents/skills/impeccable/agents/impeccable_finish_reviewer.toml .agents/skills/impeccable/agents/impeccable_manual_edit_applier.toml .agents/skills/impeccable/agents/openai.yaml .agents/skills/impeccable/reference/adapt.md .agents/skills/impeccable/reference/adapt.native.md .agents/skills/impeccable/reference/android.md .agents/skills/impeccable/reference/animate.md .agents/skills/impeccable/reference/audit.md .agents/skills/impeccable/reference/audit.native.md .agents/skills/impeccable/reference/bolder.md .agents/skills/impeccable/reference/clarify.md .agents/skills/impeccable/reference/colorize.md .agents/skills/impeccable/reference/craft-floor.md .agents/skills/impeccable/reference/craft.md .agents/skills/impeccable/reference/critique.md .agents/skills/impeccable/reference/degraded/asset-producer.md .agents/skills/impeccable/reference/degraded/documenter.md .agents/skills/impeccable/reference/degraded/finish-reviewer.md .agents/skills/impeccable/reference/degraded/manual-edit-applier.md .agents/skills/impeccable/reference/delight.md .agents/skills/impeccable/reference/distill.md .agents/skills/impeccable/reference/doctor.md .agents/skills/impeccable/reference/document.md .agents/skills/impeccable/reference/extract.md .agents/skills/impeccable/reference/harden.md .agents/skills/impeccable/reference/hooks.md .agents/skills/impeccable/reference/init.md .agents/skills/impeccable/reference/ios.md .agents/skills/impeccable/reference/layout.md .agents/skills/impeccable/reference/live-setup.md .agents/skills/impeccable/reference/live.md .agents/skills/impeccable/reference/new-work.md .agents/skills/impeccable/reference/onboard.md .agents/skills/impeccable/reference/operate.md .agents/skills/impeccable/reference/optimize.md .agents/skills/impeccable/reference/overdrive.md .agents/skills/impeccable/reference/polish.md .agents/skills/impeccable/reference/quieter.md .agents/skills/impeccable/reference/routing.md .agents/skills/impeccable/reference/shape.md .agents/skills/impeccable/reference/typeset.md .agents/skills/impeccable/reference/visualize.md .agents/skills/impeccable/scripts/VERSION .agents/skills/impeccable/scripts/bin/darwin-arm64/impeccable .agents/skills/impeccable/scripts/command-metadata.json .agents/skills/impeccable/scripts/data/font-index-failures.json .agents/skills/impeccable/scripts/data/font-index.json .agents/skills/impeccable/scripts/impeccable .agents/skills/impeccable/scripts/impeccable.cmd .agents/skills/impeccable/scripts/live-browser-dom.js .agents/skills/impeccable/scripts/live-browser-ignores.js .agents/skills/impeccable/scripts/live-browser-session.js .agents/skills/impeccable/scripts/live-browser.js .agents/skills/impeccable/scripts/modern-screenshot.umd.js .agents/skills/industrial-brutalist-ui/SKILL.md .agents/skills/minimalist-ui/SKILL.md .agents/skills/redesign-existing-projects/SKILL.md .agents/skills/stitch-design-taste/DESIGN.md .agents/skills/stitch-design-taste/SKILL.md .dockerignore .env.conference.example .gitignore .impeccable/design.json .npmrc .openai/hosting.json CONFERENCES.md DESIGN.md Dockerfile HackAlem AI_ Система автопротоколирования совещаний с фиксацией поручений.md Newyork PRODUCT.md README.md VERIFICATION.md app/chatgpt-auth.ts app/conference-app.tsx app/conference-room.tsx app/conference.css app/globals.css app/icons.tsx app/layout.tsx app/memory-graph.css app/memory-graph.tsx app/page.tsx app/redesign.css app/what-changed.css app/what-changed.tsx backend/.dockerignore backend/.env.example backend/.gitignore backend/Dockerfile backend/README.md backend/VERIFICATION.md backend/alembic.ini backend/alembic/env.py backend/alembic/script.py.mako backend/alembic/versions/.gitkeep backend/alembic/versions/0001_initial_meeting_backend.py backend/alembic/versions/0002_live_conferences.py backend/alembic/versions/0003_what_changed.py backend/alembic/versions/0004_corporate_memory.py backend/app/__init__.py backend/app/api/__init__.py backend/app/api/briefings.py backend/app/api/conferences.py backend/app/api/deps.py backend/app/api/exports.py backend/app/api/health.py backend/app/api/meetings.py backend/app/api/memory.py backend/app/api/participants.py backend/app/api/router.py backend/app/api/tasks.py backend/app/config.py backend/app/db/__init__.py backend/app/db/base.py backend/app/db/session.py backend/app/live_worker.py backend/app/main.py backend/app/models/__init__.py backend/app/models/briefing.py backend/app/models/conference.py backend/app/models/enums.py backend/app/models/job.py backend/app/models/meeting.py backend/app/models/memory.py backend/app/models/participant.py backend/app/models/speaker.py backend/app/models/task.py backend/app/models/transcript.py backend/app/repositories/__init__.py backend/app/repositories/meeting_repository.py backend/app/repositories/participant_repository.py backend/app/repositories/task_repository.py backend/app/schemas/__init__.py backend/app/schemas/analysis.py backend/app/schemas/briefing.py backend/app/schemas/common.py backend/app/schemas/meeting.py backend/app/schemas/participant.py backend/app/schemas/task.py backend/app/schemas/transcript.py backend/app/services/__init__.py backend/app/services/audio_service.py backend/app/services/briefing_service.py backend/app/services/conference_service.py backend/app/services/diarization_service.py backend/app/services/export_service.py backend/app/services/job_service.py backend/app/services/live_audio_export.py backend/app/services/llm_service.py backend/app/services/meeting_processor.py backend/app/services/memory_extraction.py backend/app/services/memory_graph.py backend/app/services/speaker_service.py backend/app/services/speech_client.py backend/app/services/summary_service.py backend/app/services/task_extraction_service.py backend/app/services/transcript_merge_service.py backend/app/services/transcription_service.py backend/app/speech_server.py backend/app/utils/__init__.py backend/app/utils/dates.py backend/app/utils/errors.py backend/app/utils/files.py backend/app/worker.py backend/docker-compose.external-ollama.yml backend/docker-compose.gpu.yml backend/docker-compose.offline.yml backend/docker-compose.yml backend/models/.gitkeep backend/pyproject.toml backend/requirements-ai.txt backend/requirements-dev.txt backend/requirements-speech.txt backend/requirements.txt backend/scripts/bootstrap_models.py backend/scripts/bootstrap_speech.py backend/scripts/smoke_http.py backend/scripts/verify_exports.py backend/storage/.gitkeep backend/tests/__init__.py backend/tests/conftest.py backend/tests/helpers.py backend/tests/test_alignment_dates.py backend/tests/test_analysis.py backend/tests/test_audio.py backend/tests/test_briefings.py backend/tests/test_conferences.py backend/tests/test_memory.py backend/tests/test_model_adapters.py backend/tests/test_pipeline_api.py backend/tests/test_upload_security.py cloudflare-env.d.ts components.json components/ui/accordion.tsx components/ui/alert-dialog.tsx components/ui/alert.tsx components/ui/aspect-ratio.tsx components/ui/attachment.tsx components/ui/avatar.tsx components/ui/badge.tsx components/ui/breadcrumb.tsx components/ui/bubble.tsx components/ui/button-group.tsx components/ui/button.tsx components/ui/calendar.tsx components/ui/card.tsx components/ui/carousel.tsx components/ui/chart.tsx components/ui/checkbox.tsx components/ui/collapsible.tsx components/ui/combobox.tsx components/ui/command.tsx components/ui/context-menu.tsx components/ui/dialog.tsx components/ui/direction.tsx components/ui/drawer.tsx components/ui/dropdown-menu.tsx components/ui/empty.tsx components/ui/field.tsx components/ui/form.tsx components/ui/hover-card.tsx components/ui/input-group.tsx components/ui/input-otp.tsx components/ui/input.tsx components/ui/item.tsx components/ui/kbd.tsx components/ui/label.tsx components/ui/marker.tsx components/ui/menubar.tsx components/ui/message-scroller.tsx components/ui/message.tsx components/ui/native-select.tsx components/ui/navigation-menu.tsx components/ui/pagination.tsx components/ui/popover.tsx components/ui/progress.tsx components/ui/radio-group.tsx components/ui/resizable.tsx components/ui/scroll-area.tsx components/ui/select.tsx components/ui/separator.tsx components/ui/sheet.tsx components/ui/sidebar.tsx components/ui/skeleton.tsx components/ui/slider.tsx components/ui/sonner.tsx components/ui/spinner.tsx components/ui/switch.tsx components/ui/table.tsx components/ui/tabs.tsx components/ui/textarea.tsx components/ui/toggle-group.tsx components/ui/toggle.tsx components/ui/tooltip.tsx compose.speech.gpu.yml compose.speech.yml db/index.ts db/schema.ts deploy/Caddyfile design/meeting-workspace.md docker-compose.yml drizzle.config.ts drizzle/meta/_journal.json eslint.config.mjs examples/d1/app/api/notes/route.ts examples/d1/db/schema.ts hooks/use-mobile.ts lib/conference-api.ts lib/conference-call.ts lib/live-audio.ts lib/memory-api.ts lib/utils.ts meeting1.txt next-env.d.ts next.config.ts package-lock.json package.json postcss.config.mjs public/conference-recorder.js public/favicon.svg scripts/build-verified.sh scripts/execution-profile.mjs scripts/install-ci.mjs scripts/install-ci.sh scripts/install-pnpm.sh scripts/npm-install.mjs scripts/pnpm-install.mjs scripts/run-framework.mjs scripts/sites-env.mjs scripts/sites-env.sh scripts/test-live-audio.mjs skills-lock.json tests/live-audio.test.ts tsconfig.json vite.config.ts
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.