О проекте
Команда: Data Hungry
Кейс HackAlem.ai: Торговля — Электрокомплект · ekt.kz
Стадия: Доведённый продукт
Задача кейса: AI-консультант по каталогу ekt.kz: товары, аналоги, цены, остатки, корзина
Суть
Встраиваемый чат-виджет для покупателей ekt.kz: ищет товары по артикулу или спецификации (фото, аудио, Excel, Word, PDF), показывает цены и остатки из API партнёра, предлагает аналоги, отвечает по оплате и доставке и собирает корзину только после подтверждения.
Как устроено
Каталог (15 035 товаров из API ekt.kz) индексируется в SQLite FTS5 и в векторной коллекции E5 (multilingual-e5-large-instruct, 1024 измерения). Гибридная выдача пересортировывается Qwen3-Reranker-8B, обе модели работают локально на H200 через vLLM, точный артикул в приоритете. Агент на sgr-agent-core (Schema-Guided Reasoning) с OpenAI tool calling (gpt-4.1-mini) вызывает инструменты поиска, аналогов, базы знаний и корзины. Серверный шлюз подтверждения отделяет предложение товара от изменения корзины и заново проверяет живой остаток. Вложения распознаются локальными парсерами и OpenAI OCR/ASR с кэшем по SHA-256.
Ключевые решения
- hybrid search FTS5 + dense embeddings
- cross-encoder reranking
- Schema-Guided Reasoning (sgr-agent-core)
- function calling
- confirmation gate
- streaming responses
- SHA-256 attachment cache
Особенности
Собственные эмбеддер и реранкер на GPU через vLLM вместе с внешним LLM-агентом. Серверный шлюз не даёт LLM менять корзину без явного согласия и перепроверяет остаток через живой API. Команда полностью проверила карточки каталога и убрала синтетические сертификаты. Демо развёрнуто на двух доменах.
Стек
Python 3.12 · FastAPI · SQLite FTS5 · vLLM · Docker · uv · httpx · PyMuPDF · openpyxl · python-docx · Caddy · nginx · systemd · JavaScript (Shadow DOM widget)
Модели
gpt-4.1-mini · gpt-5.6-luna (OCR) · gpt-transcribe · intfloat/multilingual-e5-large-instruct · Qwen3-Reranker-8B · Anthropic (Claude Agent SDK) · llm.nitec.kz
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-59e3f91b-data-hungry.
README
README.mdИИ-ассистент для ekt.kz — Data Hungry
Запасной адрес для проверки — ekt-assistant.orau.kz
Прототип чат-консультанта для покупателей электротехнической продукции ekt.kz (кейс ТОО «Электрокомплект» на HACKALEM AI). Он ищет товары, показывает характеристики и наличие, предлагает аналоги, отвечает на вопросы об условиях покупки и помогает собрать корзину. Ассистент меняет корзину только после подтверждения в чате; нажатие покупателем кнопки «В корзину» на карточке товара само является явным действием.
Что реализовано
- Гибридный поиск товаров по эмбеддингам E5 (1024 измерения) и индексу SQLite FTS5 с одним реранком общей выдачи через Qwen3 Reranker 8B; обе модели запущены локально на NVIDIA H200 через vLLM. Точный артикул имеет приоритет.
- Получение детальной карточки, цены и остатков по складам из API ekt.kz. При недоступности API может показываться датированный локальный снимок; подтверждение корзины всегда требует нового ответа API.
- База знаний по оплате, доставке, возврату и контактам на основе страниц ekt.kz.
- Загрузка фото, аудио, Excel, Word и PDF. Локальные парсеры извлекают текст Office/PDF, OpenAI обрабатывает изображения и аудио. Результат кэшируется по SHA-256 файла и версии обработчика.
- Асинхронная загрузка вложений в виджете: видны этапы распознавания, отправка в чат доступна после готовности текста.
- Агент на
sgr-agent-coreс OpenAI tool calling, а также альтернативные провайдеры; серверный шлюз подтверждения отделяет предложение добавить товар от изменения корзины. - Потоковый ответ SGR: текст
answer_customerпоявляется по мере генерации, до него видны этапы поиска и проверки. Служебные рассуждения и аргументы других инструментов в чат не передаются. - Встраиваемый виджет для десктопа и мобильного браузера, локальная страница демо и лаборатория распознавания файлов.
Пользовательский сценарий
Покупатель пишет артикул или прикладывает спецификацию. Бэкенд извлекает текст вложения, ищет позиции в индексе и получает детали товара. Агент отвечает с карточками и источниками; если позиции нет, ищет аналоги. По просьбе покупателя агент создаёт предложение добавить найденные позиции. Только после кнопки «Подтвердить» или однозначного текстового согласия сервер повторно проверяет остаток и меняет корзину. Отдельная кнопка «В корзину» на карточке товара добавляет товар сразу по явному нажатию покупателя, также с проверкой остатка. Оба сценария возвращают ссылку на корзину прототипа.
На внешнем демо-домене корзина прототипа отделена от корзины ekt.kz: переход на ekt.kz не переносит товары автоматически. Для покупки на ekt.kz можно открыть настоящую карточку товара по ссылке. Синхронизация с корзиной сайта возможна только при размещении виджета на самом ekt.kz с доступом к сессии покупателя; она требует совместной проверки с партнёром.
Архитектура и технологии
widget/widget.js (Shadow DOM, RU/KZ)
→ FastAPI: backend/app/main.py
├─ upload_jobs.py → attachments.py / recognition.py → SQLite-кэш вложений
├─ agent.py → sgr_chat.py → OpenAI function tools
│ ├─ hybrid_search.py → SQLite FTS5 + E5 embeddings → Qwen3 rerank → ekt_api.py
│ ├─ analogs.py / knowledge.py
│ └─ cart.py → подтверждение в чате или прямой клик → корзина прототипа
└─ альтернативные циклы: agent_openai.py / agent_sdk.py / Anthropic
Python 3.11+, FastAPI, SQLite/FTS5, sgr-agent-core, OpenAI API, httpx, LiteParse, PyMuPDF, openpyxl и python-docx. В backend/.env.example перечислены провайдеры и модели. Для SGR-чата по умолчанию используется gpt-4.1-mini, для OpenAI OCR — gpt-5.6-luna, для транскрибации — gpt-transcribe. Настройки можно менять без правки кода. API партнёра не предоставляет подтверждённых файлов сертификатов по товарам; ассистент предлагает запросить нужный документ у менеджера и не показывает вымышленные ссылки. Если карточка подтверждает соответствие ГОСТ/ТР, агент сообщает это со ссылкой на данные карточки и сохраняет область утверждения; простое упоминание стандарта не превращается в выданный сертификат.
Каталог и интеграции
Источник — защищённые Basic Auth API партнёра: GET /api/products?page=N и GET /api/products/detail?id=ID. Пагинация дала 15 035 уникальных товаров. Отдельный аудит запросил детальную карточку каждого товара: в локальной базе аудита на 23.09.2026 сохранены 15 035 деталей, ошибок детализации нет. Это не только выгрузка страниц списка. Отчёт о покрытии полей и стратегии точного/полнотекстового/семантического поиска — reports/ekt_catalog_audit.md.
Поисковый индекс строится из списка. Детальные данные запрашиваются при ответе, кэшируются и могут сохраняться как датированные снимки. Остатки из снимка не считаются текущими при подтверждении корзины. Индекс и база аудита генерируются локально и не коммитятся. Семантическая коллекция строится из названия, категории, описания и характеристик и участвует в поиске API и чат-агента вместе с FTS5. Один реранк пересортировывает первые 30 товаров после объединения. Для гибридного режима нужны файл backend/data/semantic_catalog.sqlite и локальные серверы E5 и Qwen3 на GPU VM. В текущем демо используются http://127.0.0.1:8891/v1 и http://127.0.0.1:8892/v1. При сбое реранкера сохраняется гибридный порядок.
Установка и запуск
Все команды ниже выполняются из корня репозитория, если явно не указано иное. Нужны Python 3.12 и uv. Для чата, OCR и речи нужен доступ к OpenAI, для актуальных цен и остатков — к API ekt.kz. Для эмбеддингов и реранка нужна NVIDIA GPU: текущая установка проверена на H200. Обе модели выполняются на этой GPU локально, а FastAPI обращается к ним по loopback. SGR-агент, OCR и распознавание речи используют внешний OpenAI API.
1. Код, зависимости и ключи
git clone https://github.com/BAITC-Hacks/hack-59e3f91b-data-hungry.git ekt-assistant
cd ekt-assistant
uv python install 3.12
uv sync --project backend --locked --extra dev
cp backend/.env.example backend/.env
chmod 600 backend/.env
При повторной установке сохраните существующий .env, вместо того чтобы перезаписывать его. Откройте backend/.env в редакторе и заполните значения:
LLM_PROVIDER=sgr
OPENAI_API_KEY=YOUR_OPENAI_API_KEY
OPENAI_API_BASE_URL=https://api.openai.com/v1
SGR_CHAT_MODEL=gpt-4.1-mini
SGR_CHAT_MAX_TOKENS=2500
SGR_CHAT_TIMEOUT=55
OPENAI_OCR_MODEL=gpt-5.6-luna
OPENAI_ASR_MODEL=gpt-transcribe
EKT_API_USER=YOUR_EKT_API_USER
EKT_API_PASS=YOUR_EKT_API_PASSWORD
PUBLIC_BASE_URL=http://localhost:8000
ENABLE_FILE_LAB=0
YOUR_… — места для ваших значений, а не рабочие ключи. Учётные данные EKT выдаёт партнёр; без них нельзя проверить свежие остатки или подтвердить корзину. Один OPENAI_API_KEY используется для SGR, OCR и распознавания речи; выбранные модели должны быть доступны вашему проекту OpenAI. .env, загруженные файлы и базы исключены из Git. Для старых Office-форматов .doc/.xls/.ppt и конвертации через LiteParse дополнительно установите LibreOffice; .xlsx/.docx/.pptx имеют собственные парсеры.
2. Локальные эмбеддер и реранкер на NVIDIA H200
Локальные модели на NVIDIA GPU. На GPU-сервере заранее должны работать nvidia-smi, Docker и NVIDIA Container Toolkit (docker run --gpus all). Скрипт проверен на H200; он не устанавливает драйверы и не рассчитан на сервер без GPU. Из корня копии проекта на этой VM:
bash deploy/vm_models.sh
docker logs --tail 30 ekt-embed-e5
docker logs --tail 30 ekt-rerank-qwen
curl -fsS http://127.0.0.1:8891/v1/models
curl -fsS http://127.0.0.1:8892/v1/models
Дождитесь загрузки обеих моделей: первая установка скачивает образ и веса. Скрипт запускает два контейнера vllm/vllm-openai:v0.22.1: E5 на 127.0.0.1:8891 и Qwen3 Reranker 8B на 127.0.0.1:8892. Кэш весов — ~/ekt-model-cache; контейнеры имеют --restart unless-stopped. Для Qwen3 нужен поставляемый deploy/qwen3_reranker.jinja: скрипт подключает его автоматически. Этим же скриптом можно перезапустить только один контейнер через MODEL_TARGET=embed или MODEL_TARGET=rerank.
В .env приложения на той же VM задайте:
EKT_EMBEDDING_BASE_URL=http://127.0.0.1:8891/v1
EKT_RERANK_BASE_URL=http://127.0.0.1:8892/v1
EKT_RERANK_ENABLED=1
Эмбеддер intfloat/multilingual-e5-large-instruct (1024 измерения) и реранкер Qwen/Qwen3-Reranker-8B выполняются на GPU этой VM. Порты моделей доступны только внутри VM. Сервисы OpenAI для SGR/OCR/речи остаются внешними. Приложение запускается через uv/systemd; готового Docker Compose для всего приложения в репозитории нет.
3. Каталог, полнотекстовый индекс и векторная коллекция
Это три разных файла:
| Файл | Назначение |
|---|---|
data/ekt_catalog.sqlite3 | Исходная выгрузка списка и детальных карточек для построения коллекции |
backend/data/catalog.sqlite | Рабочий каталог, FTS5 и импортированные датированные детали |
backend/data/semantic_catalog.sqlite | Тексты фрагментов и векторы E5, используемые приложением |
Они не входят в git clone. Перенесите готовые базы из доверенной копии проекта либо создайте их. Для полной исходной выгрузки:
uv run --project backend python scripts/ekt_catalog_audit.py --db data/ekt_catalog.sqlite3
uv run --project backend python backend/scripts/build_index.py --audit-db data/ekt_catalog.sqlite3
uv run --project backend python backend/scripts/import_details.py --audit-db data/ekt_catalog.sqlite3
Первый скрипт запрашивает EKT-логин и скрыто пароль; он не читает backend/.env, а для неинтерактивного запуска использует EKT_API_USER и EKT_API_PASSWORD (у приложения пароль называется EKT_API_PASS). Полная выгрузка деталей занимает время, прогресс сохраняется в SQLite; после прерывания можно повторить команду. import_details.py нужен для резервных снимков; подтверждение корзины всё равно проверяет живой API. Повторная сборка build_index.py заменяет рабочую базу: после неё снова импортируйте детали.
Для быстрой проверки только каталога/FTS5 можно вместо полного аудита скачать одну страницу:
uv run --project backend python backend/scripts/dump_catalog.py --pages 1
uv run --project backend python backend/scripts/build_index.py
Это не создаёт полную базу аудита и не строит эмбеддинги. Для следующего шага нужен data/ekt_catalog.sqlite3 с тем же набором товаров, что и рабочий каталог.
Построение через локальный E5 на GPU-сервере:
EKT_EMBEDDING_BASE_URL=http://127.0.0.1:8891/v1 EKT_EMBEDDING_API_KEY=local \
uv run --project backend python backend/scripts/semantic_catalog.py build \
--model intfloat/multilingual-e5-large-instruct --strategy full --evaluate
Сборщик обращается к локальному E5 по 127.0.0.1:8891. local — непустое значение для CLI, а не секрет: у локального vLLM авторизация не включена. Выходной файл — backend/data/semantic_catalog.sqlite. Сборка возобновляется, но при смене модели, стратегии или сервера эмбеддингов используйте новый файл (--db backend/data/semantic_benchmark/rebuilt.sqlite) и после проверки задайте его абсолютный путь через EKT_SEMANTIC_DB_PATH. Не дописывайте в старую коллекцию векторы другой модели. Одинаковая размерность сама по себе не гарантирует совместимость; при переносе коллекции с другого сервера проверяйте одинаковые тексты либо пересобирайте коллекцию целиком локальным E5.
Проверка обеих поисковых моделей с текущим .env:
uv run --project backend python backend/scripts/hybrid_search.py search \
'светильник с датчиком движения' --rerank --limit 3
В выдаче должны быть числовые cosine и rerank_score, без исключений. HTTP 200 на обычном поиске этого не доказывает: при сбое модели приложение может перейти на FTS5. Сравнение стратегий compact/full/split и моделей: semantic_catalog.py benchmark --sample-size 2000; результаты предыдущих экспериментов — в отчёте.
4. Запуск приложения
uv run --project backend uvicorn --app-dir backend app.main:app \
--host 127.0.0.1 --port 8000 --workers 1
Откройте локальное демо, OpenAPI или health. Нужен один worker: сессии и корзины пока находятся в памяти процесса. Для локальной лаборатории распознавания задайте ENABLE_FILE_LAB=1 и откройте lab; на публичном сервере оставьте 0.
Потоковый чат принимает тот же JSON, что и /api/chat:
curl -N http://127.0.0.1:8000/api/chat/stream \
-H 'Content-Type: application/json' \
-d '{"message":"Какие условия доставки?","lang":"ru"}'
SSE-события: session, status, answer_delta, при необходимости answer_reset, затем done с полным ответом, карточками и корзиной. Настоящие текстовые дельты доступны у SGR, работающего через OpenAI; детерминированные ответы и остальные провайдеры возвращаются целиком в done. Подтверждение корзины остаётся отдельным серверным действием. Одновременный запрос в занятую сессию получает 409, пустой запрос без вложения — 400; обычный /api/chat сохранён. При разрыве потока принятый запрос завершится на сервере, поэтому виджет не повторяет его автоматически.
5. Запуск на Ubuntu с автозапуском и HTTPS
Подготовьте зависимости, .env и базы на сервере по шагам выше. Для нового сервера с пользователем ubuntu и копией проекта /home/ubuntu/ekt-assistant можно использовать имеющийся systemd-шаблон. Из корня этой копии:
ln -s "$PWD" "$HOME/ekt-current"
sudo cp deploy/ekt-assistant.service /etc/systemd/system/ekt-assistant.service
sudo systemctl daemon-reload
sudo systemctl enable --now ekt-assistant
curl -fsS http://127.0.0.1:8000/api/health
sudo journalctl -u ekt-assistant -n 30 --no-pager
Если ekt-current уже существует, это действующий релиз: сначала проверьте его, не заменяйте ссылку вслепую. При другом пользователе/пути измените User, WorkingDirectory, PATH и ExecStart в unit-файле. Имя шаблона не ограничивает провайдера — URL моделей берутся из .env. Перед установкой убедитесь, что порт 8000 не занят предыдущим ручным запуском. Перезапуск после изменения .env: sudo systemctl restart ekt-assistant.
Для публичного адреса назначьте домен серверу, обеспечьте входящие 80/443 и настройте HTTPS-прокси на 127.0.0.1:8000. Например, блок существующего Caddyfile для вашего домена:
demo.example.kz {
reverse_proxy 127.0.0.1:8000 {
flush_interval -1
}
}
Если Caddy ещё не установлен, используйте официальную инструкцию установки. Настройка flush_interval описана в документации потокового проксирования. Замените demo.example.kz своим доменом, проверьте конфигурацию (sudo caddy validate --config /etc/caddy/Caddyfile) и перезагрузите Caddy (sudo systemctl reload caddy). Для nginx отключите proxy_buffering/proxy_cache и поставьте достаточный proxy_read_timeout; пример HTTP-прокси есть в deploy/nginx.conf. TLS для этого nginx-примера настраивается отдельно. Не публикуйте порты моделей 8891/8892.
После внешней проверки HTTPS задайте PUBLIC_BASE_URL=https://ВАШ-ДОМЕН в .env и перезапустите приложение: этот адрес используется в ссылках на корзину. Проверьте демо, /api/health, поток /api/chat/stream и поиск с реранком с самого сервера. Health подтверждает загрузку процесса, каталога и наличие настройки ключа; доступность OpenAI и локальных моделей на GPU проверяется реальными запросами.
Для уже настроенной Brev есть отдельный сценарий. deploy/push_to_vm.sh переносит только текущий коммит и перезаписывает удалённый .env локальным; векторную коллекцию нужно переносить отдельно. Не используйте этот скрипт поверх установки под systemd: его vm_run.sh запускает другой процесс через nohup и не обеспечивает автозапуск бэкенда. catalog.sqlite и semantic_catalog.sqlite переносите согласованной парой после завершения сборки, а .env создавайте для конкретного сервера с правами 600.
Как проверить
- В демо спросите: «Есть ли в наличии 027228 Legrand?» — ответ должен опираться на детальную карточку, показать остаток/характеристики или честно указать, если живой API недоступен.
- Спросите об оплате или доставке — ответ должен брать условия из базы знаний.
- Прикрепите файл из
backend/tests/fixtures/, дождитесь статуса «готово», затем отправьте вопрос о его содержимом. - Попросите ассистента добавить товар: до подтверждения корзина пуста; после явного подтверждения количество не превышает проверенный остаток и появляется ссылка на корзину прототипа. Отдельно нажмите «В корзину» на карточке: товар добавится сразу, без второго подтверждения.
- Автоматические проверки из корня:
uv run --project backend pytest -c backend/pyproject.toml backend/tests -q -m 'not network'иnode --test widget/tests/*.test.cjs. Для JS-тестов нужен Node.js, дополнительных npm-пакетов нет. Тесты с меткойnetworkобращаются к живому API ekt.kz.
Ограничения
- В тестовом API доступно 15 035 товаров, не заявленный полный промышленный каталог. Цена и остатки меняются; датированный снимок нельзя выдавать за живые данные.
- Сертификаты не доступны в каталожном API: ссылки на документы появятся только после получения и проверки данных партнёра. Корзина внешнего демо не является корзиной ekt.kz; интеграция с настоящей корзиной Bitrix на живом сайте требует размещения виджета на ekt.kz и отдельной проверки.
- Сессии, предложения корзины и задачи распознавания хранятся в памяти процесса и теряются после перезапуска. Кэш вложений локальный, автоматической очистки нет; публичный стенд не предназначен для персональных документов.
- Распознавание может ошибаться на плохих снимках и сложной верстке; старые
.doc/.xlsтребуют LibreOffice. OpenAI OCR не выдаёт проверенных координат для сканов. - Гибридный поиск требует доступности сервиса эмбеддингов для каждого нового запроса и реранкера для финальной сортировки; без эмбеддингов используется локальный поиск FTS5, без реранкера — гибридный порядок. Потоковая выдача текста подключена к SGR; остальные провайдеры сохраняют обычный полный ответ. Сохранение истории авторизованного пользователя пока не реализовано.
Дополнительно: контракт API, агент SGR, деплой на VM, подключение к GPU VM.
Авторы коммитов
История коммитов
- 2026-09-23 17:58Use provider-neutral local model setup in READMEJulian
- 2026-09-23 17:56Clarify that demo search models run locally on NVIDIA H200Julian
- 2026-09-23 17:55Document complete setup with local search models and OpenAIJulian
- 2026-09-23 17:40Add backup demo address for reviewersJulian
- 2026-09-23 17:27Remove widget screenshot from READMEJulian
- 2026-09-23 17:26Add current demo link below README titleJulian
- 2026-09-23 17:25Remove deployment announcements from README introductionJulian
- 2026-09-23 17:23Use OpenAI exclusively for OCR and speech transcriptionJulian
Все коммиты (68)
- 2026-09-23 17:22chore: heartbeat 17:22Kydyrali Abibullaev
- 2026-09-23 17:21Document temporary H200 demo and local retrieval modelsJulian
- 2026-09-23 17:17Preserve product standards and configure NITEC VM deploymentJulian
- 2026-09-23 17:12chore: heartbeat 17:12Kydyrali Abibullaev
- 2026-09-23 17:10chore: heartbeat 17:10Kydyrali Abibullaev
- 2026-09-23 17:05deploy: backend as systemd service (auto-restart), vm_run uses systemctlKydyrali Abibullaev
- 2026-09-23 17:02chore: heartbeat 17:02Kydyrali Abibullaev
- 2026-09-23 16:54Refresh demo cart state and bust widget cacheJulian
- 2026-09-23 16:52chore: heartbeat 16:52Kydyrali Abibullaev
- 2026-09-23 16:50Fix explicit cart actions and clarify EKT demo checkoutJulian
- 2026-09-23 16:42chore: heartbeat 16:42Kydyrali Abibullaev
- 2026-09-23 16:32chore: heartbeat 16:32Kydyrali Abibullaev
- 2026-09-23 16:25fix: keep explicit IP matches in assistant product cardsJulian
- 2026-09-23 16:22chore: heartbeat 16:22Kydyrali Abibullaev
- 2026-09-23 16:21fix: serve Qwen reranker correctly and demo EKT homepageJulian
- 2026-09-23 16:12chore: heartbeat 16:12Kydyrali Abibullaev
- 2026-09-23 16:02chore: heartbeat 16:02Kydyrali Abibullaev
- 2026-09-23 16:01feat: serve catalog models locally on Brev GPU VMJulian
- 2026-09-23 15:55feat: hybrid EKT search with NITEC rerankingJulian
- 2026-09-23 15:53chore: heartbeat 15:53Kydyrali Abibullaev
- 2026-09-23 15:52deploy: direct key-only SSH access documentedKydyrali Abibullaev
- 2026-09-23 15:48fix: bypass cached demo assets after certificate removalJulian
- 2026-09-23 15:46fix: keep catalog search deployable without uncommitted hybrid moduleJulian
- 2026-09-23 15:46chore: ignore .claude/ worktrees; heartbeat 15:46Kydyrali Abibullaev
- 2026-09-23 15:45Merge branch 'main' into worktree-agent-ab5926151f10985b2Kydyrali Abibullaev
- 2026-09-23 15:44Merge branch 'main' into worktree-agent-ab5926151f10985b2Kydyrali Abibullaev
- 2026-09-23 15:44fix: remove synthetic product certificatesJulian
- 2026-09-23 15:44root path redirects to the demo pageKydyrali Abibullaev
- 2026-09-23 15:43docs: demo on https://ekt-assistant.orau.kzKydyrali Abibullaev
- 2026-09-23 15:41Merge remote-tracking branch 'origin/main' into worktree-agent-ab5926151f10985b2Kydyrali Abibullaev
- 2026-09-23 15:40merge: partner's SGR agent + file recognition into kydyrali-work (tests green)Kydyrali Abibullaev
- 2026-09-23 15:36fix: support HEAD checks on demo rootJulian
- 2026-09-23 15:35chore: prepare dedicated HTTPS domain for EKT demoJulian
- 2026-09-23 15:34deploy: Caddy defaults to ekt-assistant.orau.kzKydyrali Abibullaev
- 2026-09-23 15:32docs: jury demo script and sample Excel specificationKydyrali Abibullaev
- 2026-09-23 15:30docs: https demo URLKydyrali Abibullaev
- 2026-09-23 15:28docs: public demo URL on the Brev VMKydyrali Abibullaev
- 2026-09-23 15:25feat: bypass LLM for cart button and deploy demo on Brev VMJulian
- 2026-09-23 15:23deploy: keep the VM's own .env unless FORCE_ENV=1Kydyrali Abibullaev
- 2026-09-23 15:20demo page uses the widget's own origin as API base; health/log show the effective modelKydyrali Abibullaev
- 2026-09-23 15:13feat: add SGR OpenAI chat agent and async file recognition statusJulian
- 2026-09-23 15:13fix: integrate SGR agent with current provider and detail snapshotsJulian
- 2026-09-23 15:12docs: consolidated README for the jury (architecture, providers, run, data, criteria, deploy)Kydyrali Abibullaev
- 2026-09-23 15:05config: 15-minute display cache for details (ekt.kz answers in 6-9 s under throttling); confirm stays liveKydyrali Abibullaev
- 2026-09-23 15:03feat: OpenAI-compatible LLM provider (OpenAI / llm.nitec.kz) with function calling; provider in /api/healthKydyrali Abibullaev
- 2026-09-23 15:01feat: LLM provider selection (anthropic / claude_code via Agent SDK), persistent detail snapshot cache with stale noteKydyrali Abibullaev
- 2026-09-23 14:59merge: partner's OpenAI media recognition + file labKydyrali Abibullaev
- 2026-09-23 14:59fix: review findings (confirmation gate, live-only stock at confirm, search normalization, analog specs, session locks) + agent_sdk provider, import_details scriptKydyrali Abibullaev
- 2026-09-23 14:42widget: ekt.kz design tokens, real logo, demo page as ekt.kz product cardKydyrali Abibullaev
- 2026-09-23 14:38feat: add OpenAI media recognition and local file labJulian
- 2026-09-23 14:33deploy: respect SSH config port for the Brev aliasKydyrali Abibullaev
- 2026-09-23 14:30deploy: Caddy script for orau.kz HTTPS reverse proxyKydyrali Abibullaev
- 2026-09-23 14:27merge: partner's OCR/ASR attachments (nitec.kz) with integrated backendKydyrali Abibullaev
- 2026-09-23 14:26feat: integrated backend + widget; tests green (64), certificates route, refusal fallbacksKydyrali Abibullaev
- 2026-09-23 14:24feat: recognize and cache chat attachments with NITEC OCR/ASRJulian
- 2026-09-23 14:19deploy: scripts for the Brev VM (setup, run, push from laptop)Kydyrali Abibullaev
- 2026-09-23 14:11docs: design guide with ekt.kz tokens and logoKydyrali Abibullaev
- 2026-09-23 14:08feat: backend skeleton, API contract, frontend spec, knowledge baseKydyrali Abibullaev
- 2026-09-23 13:50feat: audit EKT catalog search fieldsJulian
- 2026-09-23 11:29docs: add evidence-based Russian READMEJulian
Структура репозитория (88 файлов)
.gitignore README.md backend/.env.example backend/app/__init__.py backend/app/agent.py backend/app/agent_openai.py backend/app/agent_sdk.py backend/app/analogs.py backend/app/attachment_cache.py backend/app/attachments.py backend/app/brands.py backend/app/cart.py backend/app/catalog.py backend/app/config.py backend/app/ekt_api.py backend/app/extractor.py backend/app/hybrid_search.py backend/app/knowledge.py backend/app/main.py backend/app/openai_media.py backend/app/product_standards.py backend/app/recognition.py backend/app/schemas.py backend/app/sessions.py backend/app/sgr_chat.py backend/app/templates/cart.html backend/app/templates/file_lab.html backend/app/upload_jobs.py backend/data/knowledge/company.md backend/data/knowledge/contacts.txt backend/data/knowledge/delivery.md backend/data/knowledge/faq.json backend/data/knowledge/howto.txt backend/data/knowledge/payment.md backend/data/knowledge/returns.txt backend/pyproject.toml backend/scripts/build_index.py backend/scripts/dump_catalog.py backend/scripts/hybrid_search.py backend/scripts/import_details.py backend/scripts/semantic_catalog.py backend/tests/__init__.py backend/tests/fixtures/make_fixtures.py backend/tests/fixtures/photo.png backend/tests/fixtures/semantic_queries.json backend/tests/fixtures/spec.docx backend/tests/fixtures/spec.pdf backend/tests/fixtures/spec.xlsx backend/tests/test_api.py backend/tests/test_attachments.py backend/tests/test_cart.py backend/tests/test_catalog.py backend/tests/test_gate.py backend/tests/test_hybrid_search.py backend/tests/test_import_details.py backend/tests/test_knowledge.py backend/tests/test_openai_media.py backend/tests/test_product_standards.py backend/tests/test_recognition_cache.py backend/tests/test_sgr_chat.py backend/tests/test_upload_jobs.py backend/uv.lock deploy/README.md deploy/VM_NITEC.md deploy/ekt-assistant-nitec.service deploy/ekt-assistant.service deploy/nginx.conf deploy/push_to_vm.sh deploy/qwen3_reranker.jinja deploy/vm_caddy.sh deploy/vm_models.sh deploy/vm_run.sh deploy/vm_setup.sh docs/API_CONTRACT.md docs/DESIGN.md docs/FRONTEND.md docs/SGR_AGENT.md docs/VM.md docs/design/logo.svg reports/ekt_catalog_audit.md reports/ekt_semantic_benchmark.md scripts/analyze_ekt_catalog.py scripts/ekt_catalog_audit.py widget/README.md widget/bookmarklet.js widget/demo/index.html widget/demo/product.html widget/widget.js
Ветки (3)
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.