2026-06-10 08:32:20 +03:00
2026-06-10 08:32:20 +03:00
2026-06-10 08:23:45 +03:00
2026-06-09 15:57:59 +03:00
2026-06-09 09:36:48 +03:00
2026-06-09 12:47:13 +03:00
2026-06-09 09:36:48 +03:00
2026-06-10 08:23:45 +03:00

Home AI Assistant

Домашний ИИ-ассистент с REST API, веб-интерфейсом и помидоро-таймером. LLM — OpenRouter (по умолчанию DeepSeek).

Возможности (MVP)

  • Чат с потоковыми ответами (SSE)
  • Управление помидоро из чата через tool calling
  • REST API для внешних клиентов (Telegram-бот, мобильное приложение)
  • Веб-морда: вкладки «Чат» и «Помидоро»

Быстрый старт

1. Настройка окружения

cp .env.example .env

Заполните в .env:

OPENROUTER_API_KEY=sk-or-v1-...
BACKEND_PORT=8080
FRONTEND_PORT=3080

Если порт занят (например, 3000 уже используется Gitea), смените FRONTEND_PORT на свободный.

2. Запуск через Docker

docker compose up --build

Порты в .env:

Переменная По умолчанию Назначение
BACKEND_PORT 8080 API с хоста
FRONTEND_PORT 3080 Веб-морда с хоста
VITE_DEV_PORT 5173 Frontend при npm run dev
TAIGA_PORT 9000 Taiga (фаза 2)
GITEA_PORT 3000 Gitea HTTP (фаза 2)
GITEA_SSH_PORT 222 Gitea SSH (фаза 2)
QDRANT_PORT 6333 Qdrant HTTP (фаза 3)

3. Локальная разработка

Backend:

cd backend
python -m venv .venv
.venv\Scripts\activate   # Windows
pip install -r requirements.txt
uvicorn app.main:app --reload --port 8080

Frontend:

cd frontend
npm install
npm run dev

Vite dev-server: http://localhost:5173 (проксирует /api на backend).

REST API

Method Path Описание
GET /api/v1/health Healthcheck
POST /api/v1/chat/sessions Создать чат-сессию
GET /api/v1/chat/sessions Список сессий
GET /api/v1/chat/sessions/{id} История сообщений
POST /api/v1/chat/sessions/{id}/messages Отправить сообщение (SSE)
DELETE /api/v1/chat/sessions/{id} Удалить сессию
GET /api/v1/pomodoro/status Статус таймера
POST /api/v1/pomodoro/start Старт {duration_min, task_note}
POST /api/v1/pomodoro/pause Пауза
POST /api/v1/pomodoro/resume Продолжить
POST /api/v1/pomodoro/stop Стоп {result, completed}
GET /api/v1/pomodoro/history История сессий
GET /api/v1/projects Проекты Taiga + привязка Gitea
POST /api/v1/projects/sync-taiga Синхронизировать проекты из Taiga
PUT /api/v1/projects/{slug}/gitea Привязать Gitea repo
POST /api/v1/work-items Создать фичу/баг → Taiga + Gitea
GET /api/v1/work-items Список work items
POST /api/v1/webhooks/gitea Webhook для автозакрытия по push

Taiga + Gitea (фаза 2)

Taiga и Gitea работают на хосте (не в Docker):

  • Taiga: 127.0.0.1:9000taiga.grigowashere.ru
  • Gitea: 127.0.0.1:3000git.grigowashere.ru

Контейнер backend достучится через host.docker.internal (настроено в docker-compose.yml).

Настройка .env

TAIGA_BASE_URL=http://host.docker.internal:9000
TAIGA_USERNAME=...
TAIGA_PASSWORD=...
TAIGA_PUBLIC_URL=https://taiga.grigowashere.ru

GITEA_BASE_URL=http://host.docker.internal:3000
GITEA_TOKEN=...          # Settings → Applications → Generate Token
GITEA_PUBLIC_URL=https://git.grigowashere.ru
GITEA_WEBHOOK_SECRET=... # произвольная строка

Первый запуск

# 1. Синхронизировать проекты Taiga (ID подтянутся автоматически)
curl -X POST http://localhost:8080/api/v1/projects/sync-taiga

# 2. Привязать Gitea repo к проекту Taiga
curl -X PUT http://localhost:8080/api/v1/projects/home-assistant/gitea \
  -H "Content-Type: application/json" \
  -d '{"gitea_owner":"Grigo","gitea_repo":"Home_assistant","default_branch":"main"}'

Gitea webhook

В репозитории: Settings → Webhooks → Add Webhook:

  • URL (выбери один вариант):
    • Рекомендуется: https://assistant.example.com/api/v1/webhooks/gitea — nginx → 127.0.0.1:${BACKEND_PORT}
    • Если Gitea в Docker: http://172.17.0.1:${BACKEND_PORT}/api/v1/webhooks/gitea — не 127.0.0.1 (это localhost контейнера Gitea)
  • Content type: application/json
  • Secret: значение GITEA_WEBHOOK_SECRET
  • Events: Push

Проверка из контейнера Gitea: docker exec gitea wget -qO- http://172.17.0.1:8202/api/v1/health
Test delivery в Gitea должен вернуть 200, не 0.

Автозакрытие по коммиту

В сообщении коммита:

fix: кнопка сохранения
Closes gitea #12, taiga #45

Закроются Gitea issue #12 и Taiga story #45 (если только один ref — второй найдётся по связи в БД).

Чат

«Заведи баг: кнопка не сохраняет настройки» → create_work_item → Taiga story + Gitea issue + ветка feature/45-....

Структура проекта

backend/     FastAPI, OpenRouter, SQLite, помидоро
frontend/    React + Vite, чат и таймер
data/        SQLite БД (создаётся автоматически)

Память и контекст (фаза 3a)

Долгосрочная память в SQLite, без векторов:

Слой Что хранит
Профиль имя, timezone, language, notes
Факты устойчивые знания с категорией и важностью
Сводка чата краткое содержание длинной сессии

В system prompt на каждый ответ: персонаж → память → помидоро → проекты.
История чата обрезается до 40 последних сообщений; раннее — в session_summaries.

Tools

  • remember_fact — «запомни, что…»
  • recall_memories — поиск по памяти
  • forget_memory — удалить факт по id
  • update_profile — имя, часовой пояс и т.д.
  • update_session_summary — сжать тему длинного чата

API

Method Path Описание
GET /api/v1/memory снимок памяти (+ ?session_id=)
GET/PUT /api/v1/profile профиль
GET/POST /api/v1/memory/facts список / создать факт
DELETE /api/v1/memory/facts/{id} забыть
PUT /api/v1/memory/sessions/{id}/summary сводка чата

Следующие фазы

  • Qdrant: семантический поиск по фактам и документам
  • RAG: загрузка файлов, search_documents
  • Проактивные чаты по расписанию
  • Фитнес-трекер

Модель

По умолчанию: deepseek/deepseek-chat через OpenRouter. Альтернатива для болтовни: google/gemini-2.0-flash.

S
Description
No description provided
Readme 1.8 MiB
Languages
Python 73.3%
TypeScript 21.5%
CSS 5%
Dockerfile 0.1%