# DuckLM — текущее состояние проекта Дата обновления: 2026-05-22 Рабочая копия: `/home/mirivlad/git/ducklm` Git remote: `origin/main` ## Общий статус DuckLM сейчас является рабочим локальным MVP/beta runtime поверх `llama-server`. Система реализует основной цикл из `Ducklm.md`: ```text сообщение -> задача -> контекст -> action directive -> tools -> observations -> thinker response -> task events -> memory/reflection/experience ``` WebChat доступен через FastAPI на `http://127.0.0.1:8000/`. Основной `llama-server` ожидается на `http://127.0.0.1:8081/v1`. ## Что реализовано - FastAPI HTTP API и WebChat. - ConversationStore для диалогов и истории. - TaskStore и EventStore в SQLite. - ModelClient с логическими ролями из `config/models.yaml`. - Роли: `thinker`, `critic`, `coder`, `action`, `summary`, `memory_policy`, `recall`. - Расширенный `/v1/status` с API paths, token budgets, model role map и optional live-probe для llama/Qdrant. - SSE streaming chat: reasoning/content deltas, runtime status events, final stats. - Runtime status в чате для долгих этапов: planning, running_tool(s), answering. - Min/avg/max token speed в конце ответа. - ToolGateway: - `file_read` - `file_write` - `list_dir` - `search_files` - `shell_exec_safe` - `coder` - Workspace guard с approval для доступа к внешним путям. - Approval flow: - allow once - allow forever by exact normalized action hash - deny - sudo password flow - Command audit для shell-команд. - SkillRegistry и API/UI для skills. - Автоматический выбор candidate skill по ключевым словам и добавление skill summary в context. - MemoryStore в SQLite. - MemoryPolicy через LLM role `memory_policy` с fallback в безопасный no-store режим. - Structured JSON validation для `action` и `memory_policy`: невалидный JSON/schema violation не запускает tools и уходит в безопасный fallback. - VectorMemory adapter для Qdrant с локальной embedding-моделью или remote embeddings endpoint. - Recall-фильтрация памяти через `recall` role. - Reflection через `critic` role. - ExperienceRecorder и skill update proposals. - Scripts для llama-server, verification и benchmark. - Docker compose для Qdrant. - Smoke tests. ## Недавние исправления - WebChat теперь не выглядит зависшим во время action/planning: backend стримит `runtime_status`. - В чат больше не выводятся лишние дубли tool-output; tool events показываются компактно. - Внешние пути за пределами workspace не падают простой ошибкой, а требуют approval. - Streaming endpoints теперь запускают тот же post-processing, что и обычный `/v1/chat`: - memory policy - memory store/vector store - reflection - experience records - Skill candidate selection теперь используется в обычном и streaming chat. - `scripts/duck.sh status --probe` и `scripts/duck-mtp.sh status --probe` показывают live-состояние DuckLM runtime, model backend и vector memory. - Structured utility-outputs валидируются локально по JSON schema; это защищает tool loop и memory writes от мусора модели. ## Соответствие этапам из Ducklm.md | Этап | Статус | Комментарий | | --- | --- | --- | | 1. Project skeleton / FastAPI / WebChat | Готово | Проект запускается, WebChat не пустой | | 2. llama-server roles / ModelClient | Готово | Одна модель может обслуживать все роли | | 3. Chat/tasks/events/WebChat response | Готово | Есть обычный и streaming chat | | 4. cognition_response vs action_directive | Готово | Action role structured JSON, thinker отдельно | | 5. ToolGateway | Готово | File/search/shell/coder tools, event log | | 6. Approvals | Готово | UI и API approvals, allow_once/forever/deny | | 7. Skills | Готово | Registry, API/UI, candidate skill injection | | 8. Reflection/Experience | Готово | Reflection после completed задач, experience records | | 9. Memory/VectorMemory | Готово частично | SQLite memory готова; `/v1/status?probe=true` показывает live health Qdrant; embeddings зависят от локальной модели/endpoint | | 10. MTP/benchmark | Готово как experimental | MTP script есть, action по умолчанию остаётся на main endpoint | ## Остаточные ограничения - Qdrant и локальная embedding-модель должны быть доступны отдельно; при ошибках vector memory деградирует без падения runtime. - Token speed считается приближённо по текущему estimator, а не по tokenizer конкретной модели. - Skill selection сейчас keyword-based. LLM selection можно добавить позже, если понадобится. - WebChat остаётся lightweight vanilla JS UI; это не production frontend framework. - `@app.on_event("startup")` работает, но FastAPI предупреждает, что lifespan API современнее. ## Проверка Последняя полная проверка: ```bash . .venv/bin/activate ruff check . pytest tests/smoke -q git diff --check ``` Ожидаемый результат на 2026-05-21: smoke tests проходят. ## Запуск ```bash . .venv/bin/activate bash scripts/duck.sh start ``` Открыть WebChat: ```text http://127.0.0.1:8000/ ``` Проверить API: ```bash curl --noproxy '*' http://127.0.0.1:8000/health curl --noproxy '*' 'http://127.0.0.1:8000/v1/status?probe=true' curl --noproxy '*' http://127.0.0.1:8000/v1/models/roles ``` Управление процессами: ```bash bash scripts/duck.sh status bash scripts/duck.sh status --probe bash scripts/duck.sh logs --follow bash scripts/duck.sh restart bash scripts/duck.sh stop ``` MTP/speculative-вариант: ```bash bash scripts/duck.sh stop bash scripts/duck-mtp.sh start bash scripts/duck-mtp.sh status bash scripts/duck-mtp.sh logs --follow ``` ## Что делать следующим 1. Пройти live E2E checklist в WebChat на реальной модели. 2. Вынести runtime/model role routing в явный конфиг с fallback-политикой, оставив Qwen основным backend для всех ролей. 3. Расширить strict validation/fallback на `recall` и будущие structured utility-roles. 4. При необходимости заменить keyword skill selection на LLM-based selection. 5. Позже мигрировать FastAPI startup на lifespan.