Локальная агентская система для генерации Lua-кода по C4-архитектуре из задания.
Chat with DeepWiki to get answers about this repo:
- FastAPI endpoint
POST /generate - FastAPI endpoint
POST /generate/stream(SSE, пошаговые события) - Агентный цикл: normalize -> clarify -> retrieve -> generate -> validate -> refine
- Role-based subagents: explorer -> generator -> validator
- Permission слой
allow/deny/askдля внутренних действий агента - Context compaction для длинных сессий
- Локальный вызов Ollama (
/api/generate) - Валидация через
luac -pиluacheck(если установлены) - Локальные Lua-шаблоны в
kb/templates - Гибридный retriever: lexical + опционально spaCy + опционально embeddings/reranker + graph boost (NetworkX)
- Опциональная Qdrant-поддержка для cosine-векторного поиска по file-first индексу кодовой базы
api/— HTTP слой и схемыagent/— оркестратор и компонентная логикаvalidator/— проверка Lua-кодаkb/— локальная база шаблонов
- Создайте
.envиз.env.example. - Установите зависимости:
pip install -r requirements.txt- (Рекомендуется) Загрузите модель spaCy для русского языка:
python -m spacy download ru_core_news_md- Запустите API:
uvicorn api.main:app --reload --host 0.0.0.0 --port 8080- Запустите UI:
streamlit run ui/app.pyUI будет доступен по адресу http://127.0.0.1:8501.
Retriever не захардкожен: все ключевые параметры вынесены в .env.
RETRIEVER_CPU_ONLY=true— форсирует запуск моделей на CPURETRIEVER_USE_SPACY=true— включает лемматизацию spaCyRETRIEVER_USE_EMBEDDINGS=true— включает BGE-light эмбеддерRETRIEVER_USE_RERANKER=true— включает BGE rerankerRETRIEVER_SPACY_MODEL=<название spaCy модели>RETRIEVER_SPACY_FALLBACK_MODELS=model1,model2RETRIEVER_EMBEDDING_MODEL=<HF model id>RETRIEVER_RERANKER_MODEL=<HF model id>RETRIEVER_ENABLE_CODE_GRAPH=true— включает граф кодовой базы (NetworkX)RETRIEVER_GRAPH_WEIGHT=0.15— вклад графового сигнала в итоговый скорRETRIEVER_GRAPH_MAX_HOPS=2— глубина графового распространения релевантностиRETRIEVER_SYNONYMS_PATH=kb/retriever/synonyms.jsonRETRIEVER_IGNORE_DIRS_PATH=kb/retriever/ignore_dirs.txt
Если модели spaCy/BGE не установлены или не загрузились, retriever автоматически переключается на lexical fallback и продолжает работу без падения сервиса.
- Multi-stage
Dockerfile: build-инструменты (gcc,make,luarocks) остаются только вbuilder-слое. - Разделение зависимостей: тяжелые пакеты вынесены в
requirements-heavy.txtи устанавливаются доrequirements.txt. - Опциональный ML-слой:
requirements-ml.txt(включаетsentence-transformers) ставится только приINSTALL_ML=true. - BuildKit cache mounts для
aptиpipуменьшают время повторных сборок. - Облегченный runtime-образ: в финальном слое только
lua5.3,luacheck, venv и приложение.
По умолчанию docker compose build собирает быстрый профиль без ML-зависимостей.
Если нужны embeddings/reranker внутри контейнера:
INSTALL_ML=true docker compose build api| Профиль | Описание | Команда |
|---|---|---|
full |
Полный стек (API + Ollama + Qdrant) | docker compose --profile full up -d |
api |
Только API сервис | docker compose up -d |
no-ai |
Алиас для API-only режима | docker compose up -d api |
ollama |
Только Ollama модель | docker compose --profile ollama up -d |
qdrant |
Только Qdrant векторная БД | docker compose --profile qdrant up -d |
# Windows
run.bat full # Полный стек
run.bat no-ai # API без локального ИИ
run.bat ollama # Только модель
# Linux/Mac
./run.sh full # Полный стек
./run.sh no-ai # API без локального ИИ
./run.sh ollama # Только модельДля полного профиля после первого запуска загрузите модель внутрь Ollama-контейнера:
docker exec localscript-ollama ollama pull qwen2.5-coder:3b-instruct-q4_K_M- API:
http://localhost:8080 - Ollama:
http://localhost:11434 - Qdrant:
http://localhost:6333
curl -sS http://localhost:8080/health
curl -sS http://localhost:11434/api/tags
curl -sS http://localhost:6333/collectionsПроверка изнутри API-контейнера (внутренние DNS-имена compose):
docker exec localscript-api python -c "import httpx; print(httpx.get('http://ollama:11434/api/tags', timeout=10).status_code); print(httpx.get('http://qdrant:6333/collections', timeout=10).status_code)"Retriever индексирует проект по файлам и чанкам строк:
- корень индекса:
RETRIEVER_INDEX_ROOT - расширения файлов:
RETRIEVER_INDEX_EXTENSIONS - размер чанка:
RETRIEVER_INDEX_CHUNK_LINES - перекрытие чанков:
RETRIEVER_INDEX_CHUNK_OVERLAP_LINES
Индексация и upsert в Qdrant выполняются лениво при первом retrieval-запросе. Отдельный шаг python -m kb.ingest формирует embeddings + артефакт графа кодовой базы.
RETRIEVER_ENABLE_QDRANT=true— включить векторный бэкенд QdrantRETRIEVER_QDRANT_URL=<url>RETRIEVER_QDRANT_COLLECTION=<collection>
Если Qdrant недоступен, retriever автоматически работает в локальном режиме (lexical + локальные embeddings).
Запуск:
python tools/retrieval_eval.pyСкрипт считает MRR@k и NDCG@k на базовых эталонных запросах.
ollama pull qwen2.5-coder:3b-instruct-q4_K_MПараметры для демо/проверки по ТЗ:
ollama run qwen2.5-coder:3b-instruct-q4_K_M --num_ctx 4096 --num_predict 256 --batch 1В runtime API эти значения задаются через .env: OLLAMA_NUM_CTX=4096, OLLAMA_NUM_PREDICT=256, OLLAMA_BATCH=1, OLLAMA_PARALLEL=1.
Для настройки под ваше железо используйте переменные окружения:
OLLAMA_NUM_THREADS— кол-во CPU потоков (0 = авто)OLLAMA_NUM_GPU_LAYERS— слои на GPU (0 = выкл, для AMD GPU рекомендуется 0)
Гибкая настройка весов поиска:
RETRIEVER_STEM_MATCH_SCORE=2.5— вес за стеммингRETRIEVER_TOKEN_MATCH_SCORE=1.25— вес за токеныRETRIEVER_BLOB_MATCH_SCORE=0.5— вес за blob совпаденияRETRIEVER_LENGTH_NORM_DIVISOR=200.0— нормализация длины
Ускорение embedding на CPU через OpenVINO:
RETRIEVER_EMBEDDING_BACKEND=openvino— бэкенд (по умолчанию)RETRIEVER_EMBEDDING_USE_QUANTIZED=true— использовать квантованную модель
curl -X POST http://localhost:8080/generate \
-H "Content-Type: application/json" \
-d '{"prompt": "Напиши функцию factorial(n) на Lua"}'Если политика возвращает ask, API отдаст status=need_permission и список permission_requests.
Повторный вызов выполняется с подтверждением:
curl -X POST http://localhost:8080/generate \
-H "Content-Type: application/json" \
-d '{
"prompt": "Напиши функцию factorial(n) на Lua",
"permission_replies": {"task.generate": "allow", "session.compact": "allow"}
}'curl -N -X POST http://localhost:8080/generate/stream \
-H "Content-Type: application/json" \
-d '{"prompt":"Сделай Lua функцию sum(a,b)","permission_replies":{"task.generate":"allow"}}'События включают: session.status, phase.started, phase.completed, task.started, task.completed, message.part.delta, validation.updated, permission.asked, permission.replied, context.compacted, response.final, затем data: [DONE].
CONTEXT_COMPACT_MAX_CHARS— порог длины истории для сжатия (по умолчанию7000)CONTEXT_COMPACT_KEEP_RECENT— сколько последних сообщений оставлять без сжатия (по умолчанию4)SESSION_PERSIST_ENABLED— включает файловое хранение сессий вdata/sessions(по умолчаниюfalse)
Интеграция памяти вынесена в отдельный слой agent/core/memory_layer.py.
Провайдер, модель и хранилище задаются только через .env, без хардкода в коде.
MEMORY_ENABLED— включить/выключить memory слой (true/false)MEMORY_PROVIDER— локальный провайдер MemLayer:ollamaилиlmstudioMEMORY_MODEL— модель провайдера (напримерgpt-4.1-mini)MEMORY_STORAGE_PATH— путь для персистентного хранилища памятиMEMORY_USER_ID_PREFIX— префикс user id для изоляции сессийMEMORY_OPERATION_MODE— режим MemLayer:local,online,lightweightMEMORY_PROVIDER_HOST— host для локальных провайдеров (ollama/lmstudio)
Текущий статус интеграции:
- Модуль памяти и env-параметры присутствуют в проекте.
- В текущем
agent/core/orchestrator.pymemory-layer не подключен в активный runtime-пайплайн. - Поэтому генерация сейчас работает без memory-контекста, пока интеграция не включена в оркестратор.
Добавлены unit-тесты под ограничения LowCode и публичные примеры (last email, try_count, initVariables, запрет JsonPath).
Запуск:
pytest