Files
Home_assistant/README.md
T
2026-06-10 08:23:45 +03:00

209 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Home AI Assistant
Домашний ИИ-ассистент с REST API, веб-интерфейсом и помидоро-таймером. LLM — OpenRouter (по умолчанию DeepSeek).
## Возможности (MVP)
- Чат с потоковыми ответами (SSE)
- Управление помидоро из чата через tool calling
- REST API для внешних клиентов (Telegram-бот, мобильное приложение)
- Веб-морда: вкладки «Чат» и «Помидоро»
## Быстрый старт
### 1. Настройка окружения
```bash
cp .env.example .env
```
Заполните в `.env`:
```env
OPENROUTER_API_KEY=sk-or-v1-...
BACKEND_PORT=8080
FRONTEND_PORT=3080
```
Если порт занят (например, 3000 уже используется Gitea), смените `FRONTEND_PORT` на свободный.
### 2. Запуск через Docker
```bash
docker compose up --build
```
- Backend API: http://localhost:${BACKEND_PORT:-8080}
- Web UI: http://localhost:${FRONTEND_PORT:-3080}
- Healthcheck: http://localhost:8080/api/v1/health
Порты в `.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:**
```bash
cd backend
python -m venv .venv
.venv\Scripts\activate # Windows
pip install -r requirements.txt
uvicorn app.main:app --reload --port 8080
```
**Frontend:**
```bash
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:9000``taiga.grigowashere.ru`
- Gitea: `127.0.0.1:3000``git.grigowashere.ru`
Контейнер backend достучится через `host.docker.internal` (настроено в `docker-compose.yml`).
### Настройка `.env`
```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=... # произвольная строка
```
### Первый запуск
```bash
# 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`.