surfaces/.planning/phases/04-matrix-mvp-shared-agent-context-and-context-management-comma/04-CONTEXT.md

7.7 KiB
Raw Blame History

Phase 4: Matrix MVP — Agent Context + Context Management — Context

Gathered: 2026-04-16 Status: Ready for planning Source: Conversation context (2026-04-16 design session)

## Phase Boundary

Привести Matrix-бот к рабочему состоянию для MVP-деплоя в контейнер:

  • Убрать наш кастомный AgentSessionClient и thread_id патч из platform-agent, перейти на актуальный origin/main платформы с AgentApi из lambda_agent_api
  • Добавить 4 команды управления контекстом агента: !save, !load, !reset, !context
  • Упаковать Matrix-бот в Docker-контейнер

НЕ входит в фазу:

  • Изменения в platform-agent (это задача команды платформы)
  • Telegram адаптер
  • E2EE
  • Skills system (ждём платформу)
## Implementation Decisions

Архитектура платформы (locked)

  • Один контейнер = один чат: AgentService с thread_id = "default" — намеренная архитектура. Изоляция на уровне контейнеров, не thread_id. Не менять.
  • Убрать thread_id патч: наш коммит 1dca2c1 в external/platform-agent удаляем. Переходим на origin/main platform-agent.
  • Удалить build_thread_key: функция больше не нужна. Убрать из sdk/agent_session.py и sdk/real.py.
  • Заменить AgentSessionClient на AgentApi: использовать AgentApi из external/platform-agent_api/lambda_agent_api/agent_api.py. Он уже правильно обрабатывает все event-типы (неизвестные → logger.warning, без краша).

!save (locked)

  • Синтаксис: !save (автоимя по дате/времени) или !save [имя]
  • Механизм: Matrix-бот посылает агенту текстовое сообщение "Summarize our conversation and save to /workspace/contexts/[name].md. Reply only with: Saved: [name]"
  • Имена сохранений хранятся в PrototypeStateStore (список для !load)
  • Агент сам пишет файл через свои инструменты (write_file)

!load (locked)

  • !load без аргументов → бот показывает нумерованный список сохранений
  • Пользователь вводит число (1, 2, 3...) для выбора
  • Выход из состояния: 0 или !cancel
  • После выбора: бот посылает агенту "Load context from /workspace/contexts/[name].md and use it as background for our conversation. Reply: Loaded: [name]"
  • Состояние ожидания выбора хранится в Matrix store (аналогично pending_confirm)

!reset (locked)

  • Показывает confirmation-диалог:
    Сбросить контекст агента? Выбери:
      !yes — сбросить
      !save [имя] — сохранить и сбросить
      !no — отмена
    
  • !yes → вызвать POST {AGENT_BASE_URL}/reset (resets AgentService singleton)
  • !save имя → сначала выполняется логика !save, затем POST /reset
  • !no → отмена
  • Fallback если /reset endpoint недоступен (404): вернуть пользователю "Reset endpoint недоступен. Обратитесь к администратору."
  • AGENT_BASE_URL — новая env переменная (HTTP base URL агента, отдельно от AGENT_WS_URL)

!context (locked)

  • Показывает: имя текущей сессии (если загружали через !load), токены из последнего ответа (tokens_used из MsgEventEnd), список сохранений (имена + даты)
  • Не делает никаких вызовов к агенту

Dockerfile + docker-compose (locked)

  • Dockerfile для Matrix-бота (adapter/matrix/bot.py)
  • docker-compose.yml с сервисом matrix-bot
  • Env переменные через .env файл
  • Platform-agent запускается отдельно (не входит в compose этой фазы)

Claude's Discretion

  • Структура хранения saved sessions в PrototypeStateStore (dict name→timestamp)
  • Формат автоимени для !save без аргументов
  • HTTP клиент для POST /reset (aiohttp или httpx)
  • Точный формат промптов к агенту для save/load

<canonical_refs>

Canonical References

Downstream agents MUST read these before planning or implementing.

Platform клиент (заменяем)

  • sdk/agent_session.py — текущий AgentSessionClient, УДАЛЯЕМ/ЗАМЕНЯЕМ
  • sdk/real.py — RealPlatformClient, обновляем под AgentApi
  • external/platform-agent_api/lambda_agent_api/agent_api.py — новый клиент AgentApi
  • external/platform-agent_api/lambda_agent_api/server.py — типы сообщений (MsgStatus, MsgEventTextChunk, MsgEventEnd, etc.)
  • external/platform-agent_api/lambda_agent_api/client.py — MsgUserMessage

Matrix адаптер (расширяем)

  • adapter/matrix/bot.py — точка входа, MatrixBot, build_runtime
  • adapter/matrix/handlers/ — существующие обработчики команд
  • adapter/matrix/store.py — get_room_meta, set_pending_confirm (паттерн для !load state)
  • sdk/prototype_state.py — PrototypeStateStore, расширяем для saved sessions

Состояние платформы

  • .planning/threads/matrix-dev-prototype-agent-platform-state.md — исследование от 2026-04-14

Существующая архитектура команд

  • core/protocol.py — IncomingCommand, OutgoingMessage, OutgoingUI
  • core/handlers/ — паттерны регистрации обработчиков

</canonical_refs>

## Specific Ideas
  • AgentApi требует явного connect() при старте и close() при завершении — lifecycle нужно встроить в MatrixBot
  • AgentApi.send_message() — AsyncIterator, возвращает MsgEventTextChunk чанки и MsgEventEnd
  • Для !load состояние "ожидаем число" хранить по ключу load_pending:{matrix_user_id}:{room_id} в store (аналог pending_confirm)
  • AGENT_BASE_URL — HTTP URL, например http://127.0.0.1:8000; AGENT_WS_URL = ws://127.0.0.1:8000/agent_ws/
  • platform-agent origin/main: POST /reset эндпоинта нет — это нужно запросить у команды платформы. До тех пор !reset возвращает "Reset endpoint недоступен"
## Deferred Ideas
  • Замена PrototypeStateStore на реальный control-plane из platform-master (Phase 3)
  • Skills интеграция через SkillsMiddleware (ждём платформу)
  • E2EE для Matrix
  • !reset через docker restart (заменяется на /reset endpoint когда платформа добавит)
  • Суммаризация контекста (агент сам решает как писать в файл)

Phase: 04-matrix-mvp-shared-agent-context-and-context-management-comma Context gathered: 2026-04-16 via conversation design session