wip: 04-matrix-mvp-shared-agent-context-and-context-management-comma paused at task 3/3

This commit is contained in:
Mikhail Putilovskij 2026-04-23 14:53:30 +03:00
parent 7d58dd1caf
commit be4607b422
2 changed files with 56 additions and 96 deletions

View file

@ -1,6 +1,6 @@
{ {
"version": "1.0", "version": "1.0",
"timestamp": "2026-04-21T22:33:11.666Z", "timestamp": "2026-04-23T11:46:45.938Z",
"phase": "04", "phase": "04",
"phase_name": "Matrix MVP: shared agent context and context management commands", "phase_name": "Matrix MVP: shared agent context and context management commands",
"phase_dir": ".planning/phases/04-matrix-mvp-shared-agent-context-and-context-management-comma", "phase_dir": ".planning/phases/04-matrix-mvp-shared-agent-context-and-context-management-comma",
@ -17,91 +17,74 @@
}, },
{ {
"id": 2, "id": 2,
"name": "Перевести transport layer на thin adapter над pinned upstream AgentApi и обновить тесты/документацию", "name": "Локализовать missing-first-chunk bug, оформить финальный bug report и очистить runtime до thin upstream integration boundary",
"status": "done", "status": "done",
"commit": "0c2884c" "commit": "0c2884c"
}, },
{ {
"id": 3, "id": 3,
"name": ровести финальную локализацию streaming bug и зафиксировать platform-side diagnosis в подробном отчёте", "name": ерейти на direct upstream AgentApi per request, убрать local wrapper из prod path и зафиксировать AGENT_BASE_URL как основной runtime contract",
"status": "done", "status": "done",
"commit": "0c2884c" "commit": "7d58dd1"
} }
], ],
"remaining_tasks": [ "remaining_tasks": [
{ {
"id": 4, "id": 4,
"name": "Передать платформенной команде финальный bug report и дождаться triage/fix proposal", "name": "Решить, закрываем ли Phase 04 окончательно или продолжаем Matrix через live smoke в реальном окружении",
"status": "not_started" "status": "not_started"
}, },
{ {
"id": 5, "id": 5,
"name": "После ответа платформы решить follow-up phase для surfaces hardening: tokens_used optional, bounded session cache, import/config cleanup, protocol contract tests", "name": "Если двигаемся дальше по Matrix, прогнать text/tool/file smoke на direct AgentApi per-request path и проверить отсутствие regressions",
"status": "not_started" "status": "not_started"
}, },
{ {
"id": 6, "id": 6,
"name": "После platform fix повторно прогнать Matrix live smoke на text/tool/file/image сценариях", "name": "Если начинаем новую surface, открыть follow-up phase для prod messenger architecture без собственного transport layer",
"status": "not_started" "status": "not_started"
} }
], ],
"blockers": [ "blockers": [
{ {
"description": "После tool/file flow начало ответа может пропадать; raw logs показывают, что первый повреждённый MsgEventTextChunk уже рождается внутри platform-agent до websocket-клиента", "description": "В worktree остаётся посторонний локальный diff в core/handlers/message.py, не связанный с direct AgentApi fix",
"type": "external", "type": "technical",
"workaround": "Только документирование и platform bug report; локально больше не лечить transport hacks" "workaround": "Не смешивать с runtime/surface работой без отдельной задачи; handoff commit этот файл не включает"
},
{
"description": "platform-agent отправляет duplicate END",
"type": "external",
"workaround": "Не чинить в surfaces; держать как известный platform-side дефект до upstream исправления"
},
{
"description": "Image path падает на больших data URI (>10 MB) и сопровождается WS 1009",
"type": "external",
"workaround": "Удалять oversized staged attachments и предупреждать пользователя; root fix только на платформе"
},
{
"description": "tokens_used остаётся 0, потому что pinned platform-agent_api.AgentApi не публикует MsgEventEnd наружу",
"type": "external",
"workaround": "Считать текущее значение неизвестным; не городить локальные костыли"
} }
], ],
"human_actions_pending": [ "human_actions_pending": [
{ {
"action": "Отправить платформенной команде финальный отчёт docs/reports/2026-04-22-platform-streaming-final-bug-report-ru.md", "action": "Выбрать следующий трек: Matrix live validation или планирование новой prod surface вроде Telegram/Max",
"context": "Это основной артефакт с итоговым аудиторским выводом и raw evidence", "context": "Кодовый фикс уже сделан и запушен; дальше работа зависит от продуктового направления, а не от transport-debug",
"blocking": true "blocking": false
}, },
{ {
"action": "Решить, оформлять ли отдельную follow-up phase в roadmap под production cleanup surfaces после platform triage", "action": "При следующем отдельном planning/cleanup коммите привести STATE/roadmap в полное соответствие с direct upstream per-request решением",
"context": "Сейчас реализация признана рабочей, но проблемной; часть hardening-задач осознанно отложена", "context": "Локальный STATE уже обновлён как checkpoint, но handoff WIP commit включает только HANDOFF и .continue-here",
"blocking": false "blocking": false
} }
], ],
"decisions": [ "decisions": [
{ {
"decision": "Не патчить vendored platform repos для рабочей реализации; все platform-side изменения использовались только как временная локальная диагностика и были откатаны", "decision": "Для prod path Matrix surface больше не держит собственный transport layer; используется прямой upstream AgentApi с fresh connection per request",
"rationale": "Нужна чистая граница ответственности между surfaces и платформой", "rationale": "Это убрало reuse-sensitive загрязнение между запросами, после чего missing-first-chunk симптом перестал воспроизводиться локально",
"phase": "04" "phase": "04"
}, },
{ {
"decision": "Оставить transport layer максимально thin: AgentApiWrapper только строит клиента на chat_id, а stream semantics принадлежат upstream AgentApi", "decision": "AGENT_BASE_URL принят как основной runtime contract; AGENT_WS_URL оставлен только как backward-compat fallback в env wiring",
"rationale": "Так проще локализовать баги и не смешивать platform bugs с локальными workaroundами", "rationale": "Так surface говорит с платформой по их реальному API contract, а не через локальный ws shim",
"phase": "04" "phase": "04"
}, },
{ {
"decision": "Считать текущую Matrix real integration рабочей, но проблемной из-за upstream streaming/image bugs", "decision": "Для следующих surfaces не строить custom transport wrapper поверх платформы",
"rationale": "Live flow в целом работает, однако после tool/file path есть подтверждённые platform-side дефекты", "rationale": "Surface должна владеть integration/session boundary, а не альтернативной stream semantics",
"phase": "04"
},
{
"decision": "Не лечить missing-first-chunk локальными transport hacks повторно",
"rationale": "После cleanup и raw tracing корень локализован на стороне platform-agent; дальнейшие локальные обходы только размоют диагностику",
"phase": "04" "phase": "04"
} }
], ],
"uncommitted_files": [], "uncommitted_files": [
"next_action": "Начать с отправки финального bug report платформенной команде; до их triage не менять transport semantics в surfaces повторно", ".planning/STATE.md",
"context_notes": "Сессия завершилась полной очисткой transport layer до thin adapter, обновлением README, финальным bug report и подтверждением через raw logs, что повреждённый первый chunk рождается внутри platform-agent до websocket-клиента. Рабочая ветка clean, последние meaningful commits: 0c2884c и 4524a6a. Если продолжать работу в surfaces без ответа платформы, единственный разумный фронт — инфраструктурный hardening вокруг known limitations, а не ещё одна попытка локально чинить поток." "core/handlers/message.py"
],
"next_action": "При возобновлении сначала прочитать обновлённый handoff, затем выбрать один из двух треков: либо Matrix live smoke на direct AgentApi per-request path, либо новая phase/spec для prod surface без собственного transport layer",
"context_notes": "Старый checkpoint про platform triage устарел. После диалога с платформой runtime переведён на прямой upstream AgentApi с fresh connection per request, локальный wrapper убран из prod path, tests прошли, commit 7d58dd1 запушен в origin/feat/matrix-direct-agent-prototype. Важный вывод для будущей архитектуры surfaces: upstream transport считать authoritative, а локально держать только lifecycle, serialization, attachment forwarding, error mapping и reconciliation."
} }

View file

@ -3,83 +3,60 @@ phase: 04-matrix-mvp-shared-agent-context-and-context-management-comma
task: 3 task: 3
total_tasks: 3 total_tasks: 3
status: paused status: paused
last_updated: 2026-04-21T22:33:11.666Z last_updated: 2026-04-23T11:46:45.938Z
--- ---
<current_state> <current_state>
Phase 04 как MVP-фаза по сути закрыта: Matrix real backend работает, transport layer очищен до thin adapter над pinned upstream `platform-agent_api.AgentApi`, ветка чистая и запушенная. Текущее состояние зафиксировано как "working but problematic": после tool/file flow остаётся подтверждённый upstream bug платформы, из-за которого начало ответа может пропадать. Phase 04 кодово стабилизирована вокруг direct upstream `AgentApi` per request. Коммит `7d58dd1` уже запушен в `origin/feat/matrix-direct-agent-prototype`. Старый checkpoint в этом файле устарел: после обратной связи от платформы мы убрали extra wrapper из prod path, перестали переиспользовать один websocket между запросами и после этого missing-first-chunk симптом перестал воспроизводиться локально.
Ключевой результат последней сессии: raw tracing показал, что первый повреждённый `MsgEventTextChunk` появляется уже внутри `platform-agent` до websocket-клиента. Это сняло основное подозрение с `surfaces`.
</current_state> </current_state>
<completed_work> <completed_work>
- Переведён `sdk/agent_api_wrapper.py` в тонкий factory/shim без собственной stream-semantics. - Весь ранее собранный Matrix MVP контекст остаётся валидным: numeric `platform_chat_id`, staged attachments, shared workspace, context commands и Docker packaging уже на месте.
- Переведён `sdk/real.py` на pinned upstream contract: без post-END drain, без custom listener, без локальной реконструкции стрима. - Продовый runtime path переведён на direct upstream client через `sdk/upstream_agent_api.py`; локальный `sdk/agent_api_wrapper.py` удалён из runtime path.
- Обновлены тесты под новый transport layer: - `sdk/real.py` теперь на каждый `send_message` и `stream_message` создаёт новый `AgentApi`, делает `connect()`, читает stream и сразу `close()`.
- `tests/platform/test_real.py` - `AGENT_BASE_URL` зафиксирован как основной runtime contract; `AGENT_WS_URL` оставлен только как backward-compat fallback в env wiring.
- `tests/adapter/matrix/test_dispatcher.py` - Добавлена регрессия на reuse-sensitive missing-first-chunk сценарий и обновлены runtime/integration tests; `uv run pytest tests -q` прошёл (`196 passed`), `ruff` на затронутых файлах clean.
- `tests/core/test_integration.py` - Кодовый фикс закоммичен и запушен: `7d58dd1` (`fix: use direct agent api per request`).
- README обновлён под новое состояние интеграции и known limitations. - В сессионных выводах зафиксирован новый архитектурный принцип для следующих surfaces: не строить свой transport layer, держать только thin integration/session boundary над upstream transport.
- Создан финальный отчёт: `docs/reports/2026-04-22-platform-streaming-final-bug-report-ru.md`.
- Временная диагностика в vendored `platform-agent` и `platform-agent_api` была использована только для расследования и полностью удалена; nested repos снова clean.
- Последний кодовый commit с рабочим состоянием: `0c2884c` (`refactor: use thin upstream transport adapter`).
</completed_work> </completed_work>
<remaining_work> <remaining_work>
- Передать платформенной команде финальный отчёт и дождаться triage/fix proposal. - Перед следующим кодом выбрать направление:
- После ответа платформы решить, открываем ли отдельную follow-up phase для production hardening в `surfaces`. - если продолжаем Matrix, прогнать live smoke в реальном окружении на text/tool/file flow и проверить отсутствие regressions на direct per-request path;
- После platform fix повторить live smoke: - если переходим к Telegram/Max-подобной работе, открыть новую phase/spec под prod surface architecture.
- text-only - Привести `.planning/STATE.md` и roadmap в полностью каноничное состояние отдельным planning/cleanup шагом, если хотим закрепить этот checkpoint не только через handoff.
- staged attachments - Не смешивать дальнейшую surface/runtime работу с отдельным локальным diff в `core/handlers/message.py`, пока это не станет явной задачей.
- tool/file flow
- large image failure path
</remaining_work> </remaining_work>
<decisions_made> <decisions_made>
- Больше не трогать vendored platform repos ради рабочей реализации. - Matrix prod path должен использовать прямой upstream `AgentApi`, а не surface-owned wrapper с кастомной stream semantics.
- Больше не добавлять локальные transport hacks, маскирующие streaming bug. - Fresh connection per request принят как дефолтный lifecycle для этой surface, потому что именно reuse websocket оказался чувствительной точкой для missing-first-chunk симптома.
- Считать текущий missing-first-chunk баг platform-side дефектом до опровержения raw evidence. - `AGENT_BASE_URL` это честный runtime contract; ws URL normalization допустим только как backward-compat env fallback.
- Оставить `tokens_used=0` как честное ограничение current upstream contract, не симулировать это значение локально. - Для следующих surfaces надо думать терминами `integration boundary` и `runtime contract`, а не терминами "написать свой transport layer".
</decisions_made> </decisions_made>
<blockers> <blockers>
- Platform-side streaming bug: после tool/file flow начало ответа может пропадать. - Подтверждённого локального Matrix blocker после `7d58dd1` больше нет; дальше это вопрос product direction и live validation, а не active transport-firefight.
- Duplicate `END` на стороне платформы. - В worktree остаётся посторонний локальный diff в `core/handlers/message.py`; не смешивать его с будущими surface/runtime изменениями без отдельной задачи.
- Image path на больших вложениях падает с `data-uri > 10 MB` и `WS 1009`.
- Без ответа платформенной команды дальнейший transport-layer surgery в `surfaces` не имеет инженерного смысла.
</blockers> </blockers>
<context> <context>
Важная ментальная модель: Важная ментальная модель теперь такая:
- `surfaces` сейчас максимально близок к upstream transport semantics. - upstream transport authoritative; `surfaces` владеет только lifecycle, serialization, attachment forwarding, error mapping и reconciliation.
- Если снова полезет corruption чанков, исходная презумпция должна быть "сначала смотреть platform-agent", а не придумывать новый локальный workaround. - Старый narrative "ждём platform triage перед любыми transport changes" больше не актуален; transport change уже сделан и дал положительный эффект.
- Главные артефакты для чтения перед продолжением: - Предыдущий handoff и текущий `STATE.md` были написаны до этого решения, поэтому их надо читать как исторический контекст, а не как последнюю истину.
1. `README.md` - Проверка на false completion ничего критичного не показала: grep задел только фразу "compatibility placeholder" в `04-01-SUMMARY.md`, а не реальный незаполненный summary.
2. `docs/reports/2026-04-22-platform-streaming-final-bug-report-ru.md` - Текущие локальные non-handoff diff: `.planning/STATE.md` и `core/handlers/message.py`.
3. `sdk/agent_api_wrapper.py`
4. `sdk/real.py`
5. `tests/platform/test_real.py`
Если придётся продолжать без платформы, разумные задачи уже не про баг с чанками, а про clean/prod-ready улучшения вокруг него:
- сделать `tokens_used` optional в локальном контракте
- развести `RealPlatformClient` на pool/adapter слои
- добавить bounded session cache / idle eviction
- убрать `sys.path` import hack в пользу нормальной dependency wiring
- переименовать конфиг `AGENT_WS_URL` в более честный `AGENT_BASE_URL`
- добавить protocol contract tests против fake WS server
</context> </context>
<next_action> <next_action>
Start with: Start with:
1. Открыть `docs/reports/2026-04-22-platform-streaming-final-bug-report-ru.md` 1. Открыть этот обновлённый handoff, а не опираться на старый checkpoint про platform triage.
2. Отправить этот отчёт платформенной команде как основной артефакт 2. Выбрать трек: Matrix live smoke или новая prod-surface phase.
3. Не менять transport layer до получения их ответа 3. Если снова полезем в runtime, не возвращать custom transport wrapper и persistent shared websocket без очень сильной причины и регрессионных тестов.
Если работа продолжается автономно без ответа платформы, следующий допустимый шаг — оформлять отдельную follow-up phase на hardening `surfaces`, а не повторно "чинить" стрим локальными обходами.
</next_action> </next_action>