# OmniSVG-Lite Локальный MVP для генерации SVG-иконок и иллюстраций через LM Studio. Gradio UI, локальная SQLite-история, валидация выхода модели через `lxml`, PNG-превью через `cairosvg`. > Контракт: см. `docs/spec.md` и `docs/design.md`. Промпт-шаблоны: `prompts/`. ## Что внутри | Файл | Назначение | |--------------------|------------------------------------------------------------------| | `app.py` | Gradio 5 UI: text/prompt → N SVG-кандидатов → PNG-превью → БД | | `lm_client.py` | httpx-клиент к OpenAI-compatible LM Studio, `generate_svg()` | | `prompts.py` | Загрузка шаблонов из `prompts/` + `build_messages()` | | `validator.py` | lxml-парсинг + проверка whitelist/тегов/href/on* | | `renderer.py` | cairosvg → PNG (graceful fallback, если cairo недоступен) | | `history.py` | SQLite WAL, контекст-менеджер `History` | | `prompts/` | system-инструкции + few-shot примеры | | `tests/` | pytest на validator (6+ кейсов) | ## Установка ```bash # 1) зависимости pip install -r requirements.txt ``` > **Важно для Windows**: `cairosvg` — это Python-биндинг к нативному `cairo`. > На Windows чистого `pip install cairosvg` обычно недостаточно — нужна > библиотека `cairo.dll`. Варианты: > > ```bash > # вариант 1: conda (рекомендуется) > conda install -c conda-forge pycairo cairo > > # вариант 2: MSYS2 / vcpkg / GTK3 runtime > ``` > > Если cairo не установлен — UI стартует, но PNG-превью будут пропущены > (в логе появится `WARNING` от renderer.py). ## Настройка LM Studio 1. Запустить LM Studio локально (`http://127.0.0.1:1234`). 2. Загрузить модель, например `qwen/qwen3.5-35b-a3b`. 3. Включить **OpenAI-compatible server** в LM Studio. Переменные окружения (опционально, все имеют дефолты): | Переменная | Дефолт | |---------------------------|-----------------------------------| | `LM_STUDIO_BASE_URL` | `http://127.0.0.1:1234/v1` | | `LM_STUDIO_API_KEY` | `lm-studio` | | `DEFAULT_MODEL` | `qwen/qwen3.5-35b-a3b` | | `REQUEST_TIMEOUT_S` | `120` | | `OMNISVG_DB_PATH` | `~/.omnisvg_lite/history.sqlite` | | `OMNISVG_PREVIEW_DIR` | `~/.omnisvg_lite/previews` | | `LOG_LEVEL` | `INFO` | ## Запуск ```bash python app.py ``` UI откроется на `http://127.0.0.1:7860`. Кнопка «Сгенерировать» отправляет промпт в LM Studio, валидирует SVG, рисует PNG-превью и сохраняет запись в SQLite. ## Тесты ```bash python -m pytest tests/ -v ``` Покрытие — `validator.py` (well-formed, viewBox, forbidden tags, http refs, on*-атрибуты). ## Smoke-тест импорта (без живого LM Studio) ```bash python -c "from app import demo, main; print('imports ok')" ``` Запускается **только импорт**, Gradio-сервер не поднимается. Если gradio не установлен, импорт `app.py` упадёт (gradio захардкожен в `import`). ## Известные ограничения (MVP) - Один пользователь, без авторизации. - Выбор «лучшего» кандидата — по минимальному размеру файла (прокси компактности, не качества). См. `spec.md §4`. - `cairosvg` на Windows без conda — см. выше; UI работает и без PNG-превью. - Размер БД не ограничен; очистка старых превью — на совести пользователя (дизайн §11, open question). ## Структура SQLite ```sql CREATE TABLE generations ( id INTEGER PRIMARY KEY AUTOINCREMENT, created_at REAL NOT NULL, prompt TEXT NOT NULL, mode TEXT NOT NULL, -- icon | illustration model TEXT NOT NULL, n_requested INTEGER NOT NULL, n_returned INTEGER NOT NULL, temperature REAL NOT NULL, status TEXT NOT NULL, -- ok | partial | failed error_reason TEXT, raw_outputs TEXT NOT NULL, -- JSON list[str] validated_outputs TEXT NOT NULL, -- JSON list[str] previews TEXT NOT NULL, -- JSON list[str] (PNG paths) best_index INTEGER ); ``` WAL-режим, индекс по `created_at DESC`.