Интеллектуальный инструмент для работы с проектами, документами и AI-ассистентом. Поддерживает загрузку документов, автоматическую анонимизацию PII данных, общение с AI моделями и создание артефактов.
- Управление проектами — создание, редактирование, организация проектов
- Работа с документами — загрузка PDF, DOCX, TXT файлов с автоматической анонимизацией
- AI-чат — общение с DeepSeek/OpenRouter моделями на основе документов проекта
- Артефакты — сохранение результатов работы AI в структурированном виде
- Безопасность — шифрование API ключей, опциональная аутентификация
- Кастомизация — темы, настройки AI параметров, шаблоны промптов
- Бэкенд: FastAPI (Python 3.11+), асинхронный SQLite через
aiosqlite - Фронтенд: один статический HTML-файл с Vanilla JavaScript (без фреймворков)
- Парсинг документов: на клиенте (PDF.js для PDF, FileReader для TXT)
- Анонимизация: на клиенте, использует регулярные выражения из Chrome-расширения
- AI-клиент: поддержка OpenAI-совместимых API с потоковой передачей
git clone https://github.com/Vitalymt/AI-project-chat-anonimaizer.git
cd AI-project-chat-anonimaizer
chmod +x setup.sh
./setup.shПосле запуска открой URL с портом из .env (PORT, по умолчанию 8000):
http://localhost:<PORT>- или
http://<IP_машины>:<PORT>
- Первая сборка может занять 3-10 минут.
- Это нормально: подтягиваются Python-зависимости и языковая модель spaCy (
ru_core_news_sm). - Повторные перезапуски значительно быстрее.
-
Создайте
.envиз шаблона:cp .env.example .env
-
Укажите в
.envминимум:AI_PROVIDER- API ключ выбранного провайдера
PORT(по умолчанию 8000)
-
Запустите через Docker Compose:
docker compose up -d --build
-
Проверьте здоровье сервиса:
curl -sS http://localhost:<PORT>/api/health
- По умолчанию используется
AUTH_ENABLED=false(подходит для личного локального использования). - Если включить
AUTH_ENABLED=true, endpoint/api/healthтребует Basic Auth. - Для проверок используйте:
curl -u "$AUTH_USERNAME:$AUTH_PASSWORD" -sS http://localhost:<PORT>/api/health
- Создайте проект.
- Загрузите документы и дождитесь обезличивания.
- ИИ использует обезличенный контекст и формирует структурную память в Obsidian.
- Продолжайте работу в чате: план, риски, вопросы заказчику, транскрипты встреч.
- Переключайтесь между проектами — память и записи строго изолированы по
project_id.
- Нажмите "Новый проект" в левой панели
- Укажите название и цель проекта
- Проект создастся с папками для оригинальных файлов и артефактов
- Перейдите на вкладку "Документы"
- Нажмите "Загрузить документ"
- Выберите PDF или TXT файл
- Файл будет обработан на клиенте:
- Текст извлекается (PDF.js для PDF)
- PII данные анонимизируются
- Анонимизированный текст отправляется на сервер
- Оригинальный файл сохраняется локально
- На вкладке "Чаты" создайте новый чат
- Введите сообщение - ответ будет приходить потоково
- AI использует контекст загруженных документов
- История сообщений сохраняется
- В правой панели нажмите "Сохранить"
- Сохраните важные результаты как артефакты
- Артефакты сохраняются в БД и в файлы
- Документы — входные источники контекста (файлы, которые вы загружаете в проект).
- Артефакты — результаты работы внутри ProjectChat (заметки/выводы в интерфейсе сервиса).
- Vault (Obsidian) — внешняя долговременная память проекта, синхронизируемая через WebDAV.
auto— структурная автозапись артефактов (по policy и confidence).manual— разовая ручная запись ответа кнопкойСохранить в Vault (ручное).observe— пошаговая запись для визуального контроля в Obsidian (Пошаговая запись в Obsidian).
Примечание: прямой tool-вызов write_note из auto-loop отключен, чтобы не смешивать свободную запись и структурную память.
- Нажмите "Настройки" в верхней панели
- Выберите провайдера (OpenRouter/DeepSeek)
- Введите API ключ (валидируется при проверке и сохранении)
- Выберите модель из пресетов или укажите вручную
- При переключении провайдера не нужно вводить ключ повторно, если он уже сохранен
- Параметр
Автозапись в Vaultуправляет поведением памяти:off— без автозаписи,summary— только_summary.md,structured— summary + структурные артефакты.
- Ключи OpenRouter и DeepSeek хранятся отдельно.
- Поле ключа в UI всегда открывается пустым: это защищает от отправки маски
****xxxxобратно на сервер. - Если поле ключа пустое при сохранении, текущий ключ не меняется.
- Маскированные значения вида
****xxxxсервер отклоняет с ошибкой валидации. - Для очистки ключа предусмотрен отдельный backend-флаг (
CLEAR_*_API_KEY), пустая строка без флага не перетирает ключ.
GET /api/settingsтеперь возвращает:OPENROUTER_API_KEY_CONFIGURED,DEEPSEEK_API_KEY_CONFIGUREDOPENROUTER_API_KEY_SOURCE,DEEPSEEK_API_KEY_SOURCE(envилиdb)
GET /api/settings/provider-healthпоказывает активного провайдера, модель и наличие ключа по каждому провайдеру.POST /api/settings/validate-keyвыполняет реальную проверку ключа через API провайдера.
VAULT_AUTOSAVE_MODE=off— автозапись отключена.VAULT_AUTOSAVE_MODE=summary— обновляется толькоProjects/<project-id>/_summary.md.VAULT_AUTOSAVE_MODE=structured— summary + структурные артефакты (risks/decisions/analysis).
- Проверьте
.env:OBSIDIAN_ENABLED=true - Перезапустите сервис:
docker compose --profile vault up -d --build - Откройте
GET /api/settingsи убедитесь, чтоOBSIDIAN_ENABLED=true - Откройте
GET /api/vault/statusи смотритеaction_hint - Если vault выключен, в интерфейсе появится баннер с подсказкой, как включить
- Preflight на VM
OBSIDIAN_ENABLED=trueв.env- WebDAV поднят (
docker compose --profile vault up -d) GET /api/vault/statusвозвращаетvault_runtime_enabled=true
- Preflight в Obsidian (Windows)
- Установите Community plugin
Remotely Save Remote Service: WebDAVServer URL: http://<VM_IP>:<WEBDAV_PORT>Username/Password: из.env(WEBDAV_USER/WEBDAV_PASSWORD)
- Установите Community plugin
- Режим наблюдения
- В чате нажмите
Наблюдать в Obsidianпод ответом AI - Агент пишет заметку порциями в режиме
append - В интерфейсе появляется статус записи и путь файла
- В чате нажмите
- Когда ждать обновление
- Обновления появляются после sync-цикла плагина
- Для мгновенного эффекта нажмите
Syncвручную - Это near-real-time, а не посимвольный стрим
- Разница между кнопками
Сохранить в Vault (ручное)— разовая ручная запись текущего ответа в выбранный путь.Пошаговая запись в Obsidian— запись крупного ответа частями для визуального контроля наполнения заметки.Автозапись(если включена) работает отдельно по policy из настроек.
write_mode—auto|manual|observe.artifact_type— тип структурной записи (summary,risks,decisions,analysis).links_created— какие wikilinks добавлены в hub-note.artifact_written.warning— диагностические предупреждения post-write.
- Переключение чатов во время генерации
- Отправьте сообщение в чате A и сразу перейдите в чат B.
- Ожидание: в B видно статус фоновой генерации, ответ не пропадает и сохраняется в A.
- Проверьте возврат в A: сообщение ассистента на месте, без повторной перерисовки чужой истории.
- Timeout/abort без технического шума
- Нажмите
Отменаво время ответа ИИ. - Ожидание: показывается понятное сообщение (
Запрос отменен), без текстаBodyStreamBuffer was aborted. - Для длинного ответа проверьте idle-timeout: пользователь видит понятный timeout-текст.
- Нажмите
- Вкладка Документы без глобального затухания
- Переключайтесь между
ЧатыиДокументынесколько раз. - Ожидание: нет полноэкранного overlay, только локальное состояние списка документов.
- Переключайтесь между
- Проверка ENABLE_STREAMING
- Выключите
ENABLE_STREAMINGв настройках и отправьте сообщение. - Ожидание: ответ приходит цельным блоком (без по-чанковой отрисовки), но корректно сохраняется в БД.
- Включите обратно и убедитесь, что ответ снова идет постепенно.
- Выключите
- Vault project-scope
- Вызовы
/api/vault/tree|search|note|reindexдолжны выполняться только сproject_id. - Путь/папка вне
Projects/<project-id>должны возвращать403.
- Вызовы
- Откройте ответ ИИ и раскройте блок
Что читал AI:- видны tool-вызовы, аргументы, длительность и статусы
ok/error, - видно решение
write/skip,artifact_type,artifact_confidence,decision_reason.
- видны tool-вызовы, аргументы, длительность и статусы
- Если решение
write, в trace будет:- путь записанной заметки,
- список созданных связей (
wikilinks) между hub-note и артефактом.
- Если решение
skip, ИИ не пишет в Vault и объясняет причину в trace.
- Автозапись: возникает без кнопки, только для структурных артефактов (
analysis/risks/decisions/summary/meeting-notes) при confidence выше порога. - Ручная запись: инициируется кнопкой
Сохранить в vaultили явной командой пользователя. - Для автозаписи используются канонические пути в
Projects/<project>/...и обновляется/_summary.mdсо связями.
Если при туннеле с Windows:
ssh -N -L 8002:localhost:8002 -p 2222 openclaw@<VM_IP>
видите:
channel X: open failed: connect failed: Connection refused
это означает, что SSH-подключение к VM есть, но приложение на VM не слушает localhost:8002.
Проверьте и исправьте на VM:
ss -tlnp | awk '$4 ~ /:8002$/ || $4 ~ /:8081$/ || $4 ~ /:2222$/'
curl -sS -m 5 http://localhost:8002/api/healthЕсли API не поднят:
./.venv/bin/uvicorn main:app --host 0.0.0.0 --port 8002Если нужен Vault sync и нет WebDAV:
docker compose --profile vault up -d webdavПосле этого снова запускайте SSH-туннель.
Сделать сервис пригодным для регулярного использования: предсказуемое сохранение настроек, стабильная авторизация к AI-провайдерам, прозрачная диагностика и быстрый smoke-прогон.
- Сохранение настроек
- Изменение неключевых настроек работает без повторного ввода API-ключа.
- Пустой API-ключ не перетирает существующий ключ.
- Маскированные ключи запрещены к сохранению.
- Провайдеры и модели
- Ключи OpenRouter/DeepSeek независимы.
- Модели выбираются через пресеты + ручной ввод.
- Переключение провайдера не сбрасывает сохраненные ключи.
- Диагностика 401
- При отсутствии ключа пользователь получает понятную подсказку до вызова модели.
- При
401 Unauthorizedвозвращается actionable-сообщение с инструкцией проверить ключ.
- Проверка ключа
- В UI кнопка "Проверить ключ" делает реальный API-запрос к backend.
- Ошибки проверки отображаются явно в модальном окне настроек.
- Открыть настройки, изменить только
MAX_TOKENS, сохранить, убедиться чтоPOST /api/settingsвозвращаетok=true. - Нажать "Проверить ключ" с некорректным ключом, получить внятную ошибку.
- Сохранить настройки с маской
****xxxx, убедиться что сервер отклоняет запрос. - Сохранить с пустым ключом, убедиться что ключ не стирается (или сервер возвращает "нет изменений").
- Запустить чат и убедиться, что ответ от AI приходит без 401 для валидного ключа.
- Проверить
GET /api/settings/provider-health.
project-chat/
├── main.py # FastAPI приложение и все роуты
├── ai_client.py # Клиент для DeepSeek / OpenRouter (SSE)
├── database.py # Инициализация БД и CRUD-функции
├── config/
│ └── settings.py # Чтение .env и глобальные константы
├── static/
│ ├── index.html # Весь фронтенд (три панели)
│ ├── patterns.js # Регулярные выражения PII
│ ├── anonymizer.js # Логика анонимизации на клиенте
│ ├── app.js # Основная логика фронтенда
│ └── style.css # Стили в темной теме
├── data/ # Директория данных
│ ├── database.db # SQLite база
│ └── projects/ # Файлы проектов
├── Dockerfile
├── requirements.txt
├── setup.sh # Интерактивный скрипт установки
└── README.md
-- Проекты
CREATE TABLE projects (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
goal TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
-- Документы
CREATE TABLE documents (
id TEXT PRIMARY KEY,
project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
name TEXT NOT NULL,
description TEXT,
filename TEXT NOT NULL,
file_type TEXT NOT NULL,
original_path TEXT,
anonymized_text TEXT,
anonymization_log TEXT,
created_at TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'ready'
);
-- Чаты
CREATE TABLE chats (
id TEXT PRIMARY KEY,
project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
name TEXT NOT NULL,
created_at TEXT NOT NULL
);
-- Сообщения
CREATE TABLE messages (
id TEXT PRIMARY KEY,
chat_id TEXT NOT NULL REFERENCES chats(id) ON DELETE CASCADE,
role TEXT NOT NULL,
content TEXT NOT NULL,
created_at TEXT NOT NULL
);
-- Артефакты
CREATE TABLE artifacts (
id TEXT PRIMARY KEY,
project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
chat_id TEXT,
name TEXT NOT NULL,
content TEXT NOT NULL,
file_path TEXT,
created_at TEXT NOT NULL
);
-- Настройки
CREATE TABLE settings (
key TEXT PRIMARY KEY,
value TEXT NOT NULL
);Приложение использует клиентскую анонимизацию с регулярными выражениями для:
- Российских телефонов
- Email адресов
- ИНН, СНИЛС
- Паспортных данных
- Банковских карт
- Адресов
- И других персональных данных
Процесс:
- Файл обрабатывается на клиенте
- PII заменяются на маркеры
[PII_TYPE_N] - Создается карта замен
- На сервер отправляется анонимизированный текст + карта
- Оригинальный файл хранится локально
GET /api/projects- список проектовPOST /api/projects- создать проектGET /api/projects/{id}- детали проекта + документы + чатыDELETE /api/projects/{id}- удалить проект
POST /api/projects/{id}/documents- загрузить документGET /api/projects/{id}/documents- список документовDELETE /api/projects/{id}/documents/{doc_id}- удалить документ
POST /api/projects/{id}/chats- создать чатGET /api/projects/{id}/chats- список чатовGET /api/projects/{id}/chats/{chat_id}/messages- история сообщенийPOST /api/projects/{id}/chats/{chat_id}/messages- отправить сообщение (SSE)
POST /api/projects/{id}/artifacts- сохранить артефактGET /api/projects/{id}/artifacts- список артефактов
GET /api/settings- текущие настройкиPOST /api/settings- обновить настройки
- Все ID - UUID v4
- Анонимизация PII на клиенте
- Валидация API ключей при сохранении
- Ограничение размера файлов (50 MB)
- Проверка существования ресурсов
- SQL инъекции предотвращаются параметризованными запросами
- Python 3.11+
- Node.js (для разработки фронтенда)
- Docker (для контейнеризации)
# Клонирование
git clone <repository-url>
cd project-chat
# Виртуальное окружение
python -m venv venv
source venv/bin/activate # Linux/Mac
# или venv\Scripts\activate # Windows
# Зависимости
pip install -r requirements.txt
# Запуск
uvicorn main:app --host 0.0.0.0 --port 8000 --reloadФронтенд реализован на Vanilla JavaScript с использованием:
- marked.js - рендеринг Markdown
- highlight.js - подсветка кода
- PDF.js - обработка PDF файлов
- CSS Grid/Flexbox - трехпанельный интерфейс
- Для регрессионной проверки сценариев H1/H2/H5/H3-H4 используйте чеклист:
docs/state-stability-checklist.md
MIT
Для сообщений об ошибках и предложений создавайте issue в репозитории проекта.
