ducklm/TASK_3.md

33 KiB
Raw Blame History

Ты — senior AI systems engineer и principal backend architect.

Твоя задача: спроектировать и реализовать полноценный локальный multi-model AI agent runtime.

Это НЕ чат-бот. Это НЕ demo script. Это НЕ один большой файл с вызовами моделей и shell.

Это автономная локальная система исполнения задач с:

  • central runtime loop
  • несколькими локальными GGUF-моделями с жёсткими ролями
  • tools
  • planning
  • critic loop
  • долговременной memory
  • permission gating
  • event bus
  • state persistence
  • streaming
  • конфигурируемым runtime

Система должна быть расширяемой, тестируемой, отказоустойчивой и пригодной для дальнейшего развития.

==================================================

  1. PRODUCT GOAL ==================================================

Построить локальный AI runtime, который:

  • принимает пользовательскую задачу
  • извлекает релевантную память
  • собирает контекст
  • принимает orchestration-решение
  • при необходимости строит план
  • исполняет шаги через tools и coder
  • оценивает результаты через critic
  • сохраняет полезные результаты в memory
  • публикует события исполнения
  • поддерживает streaming клиенту
  • требует подтверждения на опасные действия
  • умеет восстанавливаться после сбоя
  • полностью управляется через конфиги

Система должна быть local-first.

================================================== 2. NON-GOALS

На первом этапе НЕ нужно:

  • строить UI frontend
  • делать distributed execution
  • делать multi-user auth
  • делать Kubernetes deployment
  • делать сложный scheduler для множества параллельных задач
  • делать self-modifying runtime

Telegram bot допускается только как thin stub.

================================================== 3. CENTRAL ARCHITECTURAL PRINCIPLE

Центр системы — Runtime Loop Controller.

Не router. Не отдельная LLM. Не execution engine.

Именно runtime loop замыкает полный цикл:

task -> state load -> context build -> orchestrator -> plan/decision -> execute -> critic -> memory policy -> state checkpoint -> next step

Целевая форма архитектуры:

Runtime Loop Controller
  -> State Store / Checkpoints
  -> Context Builder
  -> Orchestrator / Planner
  -> Router (policy + decision suggestion)
  -> Execution Engine / Scheduler
  -> Tools / Coder / Critic
  -> Memory System
  -> Event Bus / Event Store
  -> Streaming Projection
  -> back into Runtime Loop

Любой critical transition должен проходить через runtime loop.

================================================== 4. MODELS AND HARD ROLES

Используй отдельные модели с жёстким разделением ответственности.

4.1 Orchestrator / Planner

Модель:

  • LLaMA-family GGUF

Роль:

  • orchestration reasoning
  • decomposition of user task
  • decision whether planning is needed
  • plan generation in strict JSON format
  • next-step suggestion

Ограничения:

  • не выполняет tools напрямую
  • не пишет итоговый код, кроме инструкций для coder
  • не оценивает финальную корректность результата

4.2 Coder

Модель:

  • X-CODER GGUF

Роль:

  • generate_code
  • fix_code
  • refactor_code
  • generate helper scripts when explicitly requested by runtime

Ограничения:

  • не принимает orchestration-решения
  • не строит execution plan
  • не вызывает tools напрямую

4.3 Critic

Модель:

  • Gemma-family GGUF

Роль:

  • оценивает результаты tools
  • оценивает результаты coder
  • предлагает memory usefulness score
  • предлагает safety/usefulness judgment

Ограничения:

  • не планирует
  • не исполняет действия
  • не принимает финальное решение о memory write

4.4 Embeddings Engine

Модель:

  • MiniLM или совместимая embeddings model

Роль:

  • embeddings generation
  • semantic retrieval

Ограничения:

  • не участвует в reasoning
  • не участвует в planning

================================================== 5. GLOBAL RULES

Обязательные правила:

  • Все execution transitions проходят через runtime loop controller.
  • Все tool calls проходят через execution layer, permission layer и sandbox layer.
  • Все prompts и model settings вынесены в config/.
  • Все межмодульные контракты оформлены через типы/Pydantic models/dataclasses.
  • Все важные действия публикуются как события.
  • Task lifecycle не должен храниться только in-memory.
  • Система должна корректно деградировать при сбое отдельных подсистем.

Hard decision rule:

  • Все decision-producing components должны возвращать только структурированные decision objects.
  • Ни один decision-producing component не должен напрямую исполнять tools.
  • Ни один decision-producing component не должен напрямую мутировать task state.
  • Ни один decision-producing component не должен неявно вызывать другие компоненты в обход runtime loop.

Обязательная деградация:

  • если critic недоступен, runtime продолжает работу по fallback policy
  • если memory retrieval недоступен, задача выполняется без retrieval
  • если streaming недоступен, система возвращает sync response
  • если planner вернул невалидный план, runtime делает controlled replan или graceful fail

================================================== 6. IMPLEMENTATION ORDER

Реализация должна идти итерациями в таком порядке:

  1. project skeleton
  2. typed contracts
  3. runtime loop skeleton
  4. event bus + event schema
  5. state persistence + checkpoints
  6. config loader
  7. context builder skeleton
  8. FastAPI skeleton
  9. router
  10. execution engine / scheduler
  11. permission system
  12. tool sandbox layer
  13. local tools
  14. coder integration
  15. critic integration
  16. memory system
  17. memory write policy engine
  18. streaming projection
  19. CLI
  20. optional Telegram stub

После каждого шага ты обязан:

  • показать изменённые файлы
  • показать структуру директорий
  • кратко объяснить, что уже работает
  • явно указать, что ещё stub

================================================== 7. MVP BOUNDARY

Первая рабочая версия обязана поддерживать end-to-end сценарий:

  • пользователь отправляет задачу
  • runtime loop создаёт task state
  • context builder собирает контекст
  • orchestrator решает direct action или planning
  • execution engine исполняет шаги
  • shell/file tools реально работают
  • опасная команда требует подтверждения
  • critic оценивает результат
  • memory policy принимает решение о записи
  • события пишутся в event store
  • task state чекпоинтится
  • клиент получает streaming или sync результат

Минимальный набор tools для MVP:

  • shell_exec
  • file_read
  • file_write

Второй приоритет:

  • web_search
  • web_fetch

================================================== 8. REQUIRED PROJECT STRUCTURE

Ожидаемая структура:

ducklm/
  app/
    api/
    core/
    runtime/
    events/
    state/
    tools/
    memory/
    permissions/
    streaming/
    cli/
    models/
    services/
  config/
    models.json
    prompts.json
    permissions.json
    runtime.json
  data/
    memory/
    state/
    events/
    permissions/
  tests/
  main.py

Допускается разумная адаптация, но separation of concerns обязателен.

================================================== 9. REQUIRED DOMAIN CONTRACTS

Сначала зафиксируй typed contracts.

Минимально обязательны:

9.1 UserTask

{
  "task_id": "uuid",
  "session_id": "uuid",
  "input": "string",
  "context": {},
  "created_at": "iso-datetime"
}

9.2 PlanStep

{
  "id": "step-1",
  "kind": "tool|coder|memory|respond",
  "tool": "shell_exec",
  "args": {},
  "description": "human readable step description",
  "requires_confirmation": false,
  "depends_on": []
}

Rules:

  • kind обязателен
  • args всегда объект
  • depends_on обязателен, даже если пустой
  • tool обязателен только для kind=tool

9.3 ToolCall

{
  "tool": "shell_exec",
  "args": {},
  "task_id": "uuid",
  "step_id": "step-1"
}

9.4 ToolResult

{
  "tool": "shell_exec",
  "ok": true,
  "output": "stdout/stderr/parsed data",
  "error": null,
  "metadata": {
    "exit_code": 0,
    "duration_ms": 120
  }
}

9.5 CoderRequest

{
  "mode": "generate|fix|refactor",
  "instruction": "string",
  "context": {},
  "task_id": "uuid"
}

9.6 CriticScore

{
  "correctness": 0.0,
  "usefulness": 0.0,
  "safety": 0.0,
  "memory_store": true,
  "weight": 0.0,
  "explanation": "string"
}

Rules:

  • все numeric scores в диапазоне 0..1
  • weight используется как сигнал, а не как безусловная команда записи

9.7 MemoryEntry

{
  "id": "uuid",
  "text": "string",
  "kind": "tool_result|plan|critique|fact|summary|user_preference",
  "source": "tool|critic|user|system",
  "weight": 0.85,
  "task_id": "uuid",
  "session_id": "uuid",
  "metadata": {},
  "created_at": "iso-datetime",
  "embedding_model": "string",
  "embedding_dim": 384
}

9.8 PermissionDecision

{
  "action_type": "shell_command",
  "pattern": "rm",
  "decision": "allow_once|allow_always|deny|ask_always",
  "created_at": "iso-datetime"
}

9.9 RuntimeEvent

{
  "event_id": "uuid",
  "task_id": "uuid",
  "session_id": "uuid",
  "sequence": 42,
  "type": "task_received",
  "timestamp": "iso-datetime",
  "payload": {},
  "causation_id": "uuid|null",
  "correlation_id": "uuid"
}

9.10 TaskCheckpoint

{
  "task_id": "uuid",
  "status": "executing_step",
  "active_step_id": "step-2",
  "plan_snapshot": {},
  "context_snapshot": {},
  "updated_at": "iso-datetime"
}

9.11 ExecutionDirective

{
  "type": "plan|tool|coder|respond|replan|store_memory|request_permission|complete|fail|noop",
  "payload": {},
  "requires_permission": false,
  "confidence": 0.0,
  "reason": "string"
}

Rules:

  • все decision-producing components должны возвращать либо ExecutionDirective, либо коллекцию совместимых директив
  • confidence находится в диапазоне 0..1
  • payload всегда объект
  • директива описывает намерение, а не исполняет действие сама

================================================== 10. RUNTIME LOOP CONTROLLER

Создай:

  • app/runtime/runtime_loop.py
  • app/runtime/runtime_controller.py

Runtime Loop Controller — heart of system.

Он обязан:

  • принять task
  • загрузить или создать task state
  • опубликовать стартовые события
  • инициировать context assembly
  • вызвать orchestrator
  • определить direct action / planning / replan / fail
  • передать исполнение в execution engine
  • принять результаты tools/coder
  • вызвать critic
  • передать результат в memory write policy engine
  • сохранить checkpoint
  • опубликовать события
  • решить continue / replan / complete / fail

Runtime loop не должен:

  • собирать prompts inline вручную
  • содержать raw tool logic
  • подменять собой router
  • подменять собой execution engine
  • принимать policy-level решения вместо других компонентов

Runtime loop обязан:

  • применять уже возвращённые decision objects
  • переводить систему между состояниями
  • координировать вызовы между компонентами

Runtime loop не должен содержать скрытую бизнес-логику policy-уровня.

================================================== 11. CONTEXT BUILDER

Создай:

  • app/core/context_builder.py

Context builder обязан собирать:

  • user input
  • session context
  • retrieved memory
  • current task state
  • current plan or active step
  • recent tool results
  • permission state
  • runtime constraints and safety limits

Rules:

  • любой вызов orchestrator/planner идёт только через context builder
  • context builder должен быть token-budget aware
  • low-priority context должен отбрасываться при переполнении
  • prompt assembly не должна дублироваться по проекту

Минимальный результат:

{
  "system_prompt": "string",
  "task_summary": "string",
  "memory_context": [],
  "execution_context": {},
  "tool_context": [],
  "safety_context": {},
  "constraints": {}
}

================================================== 12. ORCHESTRATION, PLANNING, ROUTER

Planning — это режим orchestration model, а не отдельная модель.

Router должен быть только:

  • policy evaluator
  • decision suggester

Создай:

  • app/core/router.py

Router обязан определять:

  • нужен ли retrieval
  • нужен ли planning
  • direct step vs multi-step flow
  • когда нужен coder
  • когда нужен critic
  • когда нужен replan
  • когда требуется permission gate

Rules:

  • router должен быть pure function по контракту
  • router принимает input state + assembled context
  • router возвращает только structured decision object
  • router не имеет side effects
  • router не мутирует state
  • router не вызывает tools
  • router не управляет execution lifecycle
  • router не владеет task lifecycle
  • router не исполняет шаги
  • runtime loop применяет router decisions

Planner rules:

  • planner mode возвращает только строгий JSON
  • невалидный план не исполняется
  • runtime делает bounded retry или graceful fail

================================================== 13. TASK GRAPH MODEL

План не должен жить только как список шагов.

Даже если MVP исполняет шаги последовательно, внутренняя модель должна быть graph-compatible.

Используй внутреннюю task graph representation:

{
  "nodes": [
    {
      "id": "step-1",
      "kind": "tool",
      "tool": "shell_exec",
      "args": {"command": "hostnamectl"},
      "depends_on": []
    },
    {
      "id": "step-2",
      "kind": "respond",
      "depends_on": ["step-1"]
    }
  ]
}

Rules:

  • scheduler валидирует отсутствие циклов
  • planner может возвращать PlanStep[] как transport format
  • после валидации план преобразуется во внутренний task graph
  • MVP может использовать sequential DAG scheduler

================================================== 14. EXECUTION ENGINE AND SCHEDULER

Создай:

  • app/core/execution_engine.py
  • app/core/execution_scheduler.py

Execution engine работает под управлением runtime loop.

Execution engine обязан:

  • принимать валидированный task graph
  • поддерживать execution cursor
  • выбирать следующий исполнимый шаг
  • учитывать зависимости шагов
  • вызывать tools/coder через adapters
  • возвращать структурированные результаты в runtime loop
  • публиковать execution events

Минимальные состояния:

  • received
  • retrieving_memory
  • orchestrating
  • planning
  • awaiting_permission
  • executing_step
  • critic_evaluating
  • storing_memory
  • completed
  • failed

Execution engine не должен заменять runtime loop.

================================================== 15. EVENT BUS, EVENT STORE, REPLAY

Streaming events недостаточно. Нужен внутренний event backbone.

Создай:

  • app/events/event_bus.py
  • app/events/event_types.py
  • app/events/event_store.py

EventBus обязан:

  • принимать runtime domain events
  • гарантировать ordering per task
  • выдавать monotonic sequence number per task
  • публиковать события подписчикам
  • писать события в durable store
  • поддерживать projection в streaming layer

Delivery guarantees:

  • ordering guarantee per task обязателен
  • delivery model минимально at least once
  • consumer-side idempotency обязательна
  • deduplication key: task_id + sequence
  • replay не должен ломать состояние при повторном применении уже известных событий

Минимальные event types:

  • task_received
  • context_built
  • llm_called
  • llm_result_received
  • plan_created
  • step_started
  • tool_called
  • tool_completed
  • coder_called
  • coder_completed
  • critic_called
  • critic_completed
  • memory_write_suggested
  • memory_write_decided
  • memory_written
  • permission_requested
  • permission_resolved
  • checkpoint_saved
  • task_completed
  • task_failed

Event sourcing baseline:

  • каждое значимое действие должно порождать событие
  • execution history должна быть воспроизводимой
  • должна быть replay capability step-by-step

Каждое событие должно быть idempotent и deduplicatable по:

  • task_id + sequence

Streaming transport не является source of truth.

================================================== 16. STATE PERSISTENCE AND CHECKPOINTING

In-memory only state запрещён для autonomous mode.

Создай:

  • app/state/task_state_store.py
  • app/state/checkpoint_store.py

Используй:

  • SQLite как минимум для MVP

State persistence layer обязан поддерживать:

  • task creation
  • current task status
  • active step
  • current plan/task graph snapshot
  • latest context summary
  • latest safe checkpoint
  • resume after restart/crash

Обязательные правила:

  • checkpoint после critical transitions
  • periodic checkpointing
  • resume from last valid checkpoint

================================================== 17. ASYNC EXECUTION ISOLATION

Нужна явная изоляция между LLM loop и tool execution.

Обязательные требования:

  • долгие tool operations не должны блокировать runtime loop
  • блокирующие операции должны идти через async adapter / isolated runner
  • streaming и event publishing должны продолжаться во время исполнения tool

Минимум:

  • async tool runner
  • timeout wrapper
  • cancellation handling
  • bounded concurrency policy

================================================== 18. TOOL SANDBOX LAYER

Помимо permission checks нужен sandbox layer.

Особенно для:

  • shell_exec
  • web_fetch with browser fallback
  • generated helper scripts

Минимальные требования:

  • execution context isolation
  • resource caps
  • timeout enforcement
  • working directory restrictions
  • optional environment variable allowlist

Для shell нужно предусмотреть:

  • CPU / wall time limits
  • path restrictions where possible
  • запрет неявного escalation

================================================== 19. TOOLS SYSTEM

Нужен tool registry и единый tool interface.

Обязательные tools для MVP:

  • shell_exec
  • file_read
  • file_write

Второй этап:

  • web_search
  • web_fetch

Требования:

  • единый base tool interface
  • единый ToolResult
  • централизованный logging
  • timeout/error isolation
  • tool execution только через tool layer

================================================== 20. TOOL SAFETY AND PERMISSIONS

Перед потенциально опасным действием система обязана проверить policy.

Источники policy:

  • config/permissions.json
  • persistent store пользовательских решений

Поддерживаемые режимы:

  • allow_once
  • allow_always
  • deny
  • ask_always

Минимум опасных shell patterns:

  • rm
  • mv в sensitive paths
  • chmod
  • chown
  • package managers
  • curl | bash
  • sudo
  • shutdown
  • reboot

Rules:

  • опасная команда не исполняется до решения пользователя
  • решения пользователя сохраняются
  • execution layer получает уже разрешённое или отклонённое действие

================================================== 21. MEMORY SYSTEM

JSON file не использовать как primary memory store.

Используй:

  • SQLite как primary metadata store
  • FAISS или hnswlib как vector index

Memory обязана поддерживать:

  • insert
  • semantic search
  • delete
  • update weight
  • filtering by kind/session/task/source
  • embedding versioning
  • reindex

Минимальные таблицы или эквивалент:

memory_items

  • id
  • text
  • kind
  • source
  • weight
  • task_id
  • session_id
  • metadata_json
  • created_at
  • updated_at

embeddings_index_map

  • memory_id
  • embedding_model
  • embedding_dim
  • vector_slot
  • created_at

Rules:

  • retrieval учитывает semantic score и memory weight
  • low-value memories не должны загрязнять context
  • смена embedding model требует reindex path

================================================== 22. MEMORY WRITE POLICY ENGINE

Critic только предлагает. Memory write policy engine решает.

Создай:

  • app/memory/write_policy.py

Policy engine должен учитывать:

  • critic score
  • thresholds из config
  • kind/source memory candidate
  • deduplication signals
  • session/task scope
  • safety constraints
  • runtime weight modifiers

Решения policy engine:

  • store
  • store_with_weight
  • skip
  • merge_with_existing

Policy engine должен быть детерминированной функцией.

Минимальная форма:

(critic_score + memory_type + runtime_weight + dedup_state + safety_state) -> decision

Нельзя ограничиваться примитивным правилом вида:

  • if score > 0.7 then store

Нужно зафиксировать:

  • threshold model
  • scoring formula or weighted rule set
  • conflict resolution for near-duplicate memories
  • merge policy for same-fact updates

================================================== 23. CRITIC LOOP

Critic получает:

  • tool result
  • coder output
  • optional execution context

Возвращает:

{
  "correctness": 0.91,
  "usefulness": 0.77,
  "safety": 1.0,
  "memory_store": true,
  "weight": 0.84,
  "explanation": "Result is correct and safe, useful for future similar tasks"
}

Critic должен вызываться:

  • после tool execution
  • после coder output
  • перед memory write suggestion

Critic failure не должен ломать execution path. Critic возвращает suggestion, а не final write decision.

================================================== 24. RETRY AND RECOVERY POLICY

Нужна явная retry/recovery стратегия.

Обязательные политики:

Planning retry:

  • ограниченное число replan attempts
  • каждый retry логируется как событие

Tool retry:

  • только для idempotent operations или явно разрешённых tools
  • policy зависит от типа ошибки

Partial failure recovery:

  • fail task
  • retry step
  • skip step
  • replan

Critic recovery:

  • critic failure переводится в fallback policy

Минимальные поля в config/runtime.json:

  • planner_retry_limit
  • tool_retry_limit
  • replan_limit
  • step_timeout_ms
  • task_timeout_ms
  • allow_recovery_replan
  • checkpoint_policy
  • event_retention_policy

================================================== 25. STREAMING SYSTEM

Требуется FastAPI WebSocket streaming.

Но streaming должен быть projection from event bus, а не отдельным источником правды.

Минимальные внешние события:

{ "type": "status", "data": "planning" }
{ "type": "token", "data": "..." }
{ "type": "plan", "data": [...] }
{ "type": "tool_start", "tool": "shell_exec", "step_id": "step-1" }
{ "type": "tool_result", "tool": "shell_exec", "data": {...} }
{ "type": "critic", "data": {...} }
{ "type": "permission_required", "data": {...} }
{ "type": "final", "data": {...} }

================================================== 26. CONFIG SYSTEM

Всё должно жить в config/.

Обязательные файлы:

config/models.json

  • model paths
  • model roles
  • inference params
  • context sizes

config/prompts.json

  • orchestration prompt
  • planning prompt
  • coder prompt
  • critic prompt

config/permissions.json

  • dangerous command policies
  • sensitive paths
  • default approval behavior

config/runtime.json

  • timeouts
  • streaming settings
  • critic fallback policy
  • memory thresholds
  • retrieval top_k
  • replan limits
  • max execution steps
  • checkpoint policy
  • event retention policy

Hard rule:

  • никаких хардкодов prompts и critical thresholds в коде

================================================== 27. API SERVER

Сделай FastAPI backend.

Минимальные endpoints:

  • POST /chat
  • WS /stream
  • POST /tool/execute
  • GET /memory/search
  • DELETE /memory/item/{id}
  • GET /health

Требования:

  • Pydantic request/response models
  • единый error handling
  • dependency injection where разумно

================================================== 28. CODER MODULE

Создай:

  • app/core/coder.py

Минимальный интерфейс:

  • generate_code()
  • fix_code()
  • refactor_code()

Используется только coder model.

================================================== 29. CLI

Добавить CLI для локального использования.

Минимум:

  • отправить задачу
  • получить sync result
  • показать streaming mode
  • выполнить memory search

================================================== 30. TELEGRAM BOT

Только optional stub.

Если реализуешь:

  • не связывай core runtime с Telegram-specific code
  • делай только thin adapter layer

================================================== 31. RELIABILITY AND TESTING

Обязательные инженерные требования:

  • structured logging
  • typed exceptions
  • timeout handling
  • graceful failures
  • no silent pass
  • no giant mixed-responsibility files

Минимальные тесты:

  • runtime loop transitions
  • event ordering
  • checkpoint save/load
  • replay path
  • plan validation
  • permission policy checks
  • tool registry
  • shell safety path
  • memory insert/search
  • memory write policy
  • router basic flow

================================================== 32. FORBIDDEN SHORTCUTS

Запрещено:

  • single-model architecture
  • hardcoded prompts in code
  • bypassing runtime loop
  • bypassing router for policy decisions
  • tool execution outside tool layer
  • dangerous command execution without permission check
  • JSON file as primary memory store
  • in-memory-only task lifecycle for autonomous mode
  • direct streaming transport as substitute for event bus
  • critic-only memory write decision path
  • accepting invalid planner JSON as-is
  • giant monolithic runtime file

================================================== 33. DEFINITION OF DONE

Работа считается выполненной, если:

  1. Есть модульная структура проекта.
  2. Есть typed contracts для core entities.
  3. Есть Runtime Loop Controller как центральный control loop.
  4. Есть Context Builder.
  5. Есть Router как policy evaluator / decision suggester.
  6. Есть Execution Engine / Scheduler.
  7. Есть EventBus + EventStore + replay-capable history.
  8. Есть state persistence + checkpointing + resume.
  9. Есть permission-gated tools.
  10. Есть tool sandbox layer.
  11. Есть coder integration.
  12. Есть critic integration.
  13. Есть memory на SQLite + vector index.
  14. Есть memory write policy engine.
  15. Есть FastAPI API.
  16. Есть streaming как projection от event bus.
  17. Есть CLI.
  18. Есть базовые тесты critical path.

================================================== 34. REQUIRED DELIVERY STYLE

Работай итеративно.

После каждого шага:

  • показывай код
  • показывай структуру файлов
  • кратко объясняй решение
  • явно отмечай допущения
  • прямо помечай stubs

Не перескакивай к финальному “всё готово”, если каркас ещё не выстроен.

Начни с:

  1. project structure
  2. typed contracts
  3. runtime loop skeleton
  4. event bus skeleton
  5. state persistence skeleton
  6. config loader
  7. context builder skeleton
  8. FastAPI skeleton
  9. router
  10. execution engine / scheduler

Сначала построй правильный каркас. Потом наполняй его логикой.

КОНЕЦ ЗАДАНИЯ.