ducklm/CURRENT_STATE.md

163 lines
8.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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.
- Tool observations компактируются перед повторной подачей в model context; полные outputs остаются в event/audit log.
- Duplicate tool actions в рамках одной задачи пропускаются, чтобы модель не выполняла одну и ту же команду повторно.
- VectorMemory adapter для Qdrant с локальной embedding-моделью или remote embeddings endpoint.
- Recall-фильтрация памяти через `recall` role.
- Reflection через `critic` role доступна, но выключена по умолчанию в API (`DUCK_ENABLE_REFLECTION=0`), чтобы не забивать single-slot llama во время интерактивного чата.
- 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` и `scripts/duck-mtp.sh` управляют всем локальным стеком: Qdrant, llama-server и DuckLM API.
- `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 от мусора модели.
- Live E2E выявил и исправил два runtime-дефекта: большие stdout больше не раздувают следующий planning prompt, повторяющиеся identical actions больше не исполняются повторно.
- Critic reflection по умолчанию выключена для API/WebChat, потому что на одном `llama-server --parallel 1` она конкурировала с пользовательскими запросами и вызывала timeouts.
## Соответствие этапам из 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.
- `DUCK_ENABLE_REFLECTION=1` включает critic reflection после задач, но для single-slot llama это может заметно тормозить последующие запросы.
- 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. Добавить WebChat runtime/status panel поверх `/v1/status?probe=true`.
5. При необходимости заменить keyword skill selection на LLM-based selection.
6. Позже мигрировать FastAPI startup на lifespan.