temporality
Изменить страницу↗
Инженерные документы

Межагентное взаимодействие: заметки к реализации (docs/temporality-agent-collaboration-spec.md)

Сопроводительные заметки к ТЗ: решения, принятые при встраивании в существующую кодовую базу, и границы первого этапа. Обновляется по мере развития.

#1. Что реализовано

#2. Ключевые решения

Решение Почему
Состояние запроса — только журнал + история workflow (без новой таблицы) Сигналы Temporal живут в event history: переживают рестарт worker/kernel в пределах гарантий инфраструктуры (§5); journal-only — устоявшаяся альтернатива (сага устроена так же). Отдельный стор дал бы вторую истину
request_id = req- + hash(operationID) Стабилен при ретраях одного вызова (тот же operationID), уникален для нового вызова
Адресация: agent:<id> / run:<id> / голый run id agent:<id> резолвится в ран агента в скоупе саги (последний по времени старта). Живой ран получает сообщение сигналом; завершённый — релейный follow-up run (см. ниже); новый ран не стартуется только если агент вообще не резолвится
Релей-ран для завершённых агентов (<target>/ask/NN) Делегированные дети завершаются быстро — без релея задавать вопросы можно было бы только живому лиду. Релей — это дочерний AgentRun того же агента (ActivityResolveAgent + ExecuteChildWorkflow, механика делегирования): короткий бюджет (6 ходов перекрывают floor clamp после резолва), prompt самодостаточен (кто спросил, request_id, payload, указание ответить answer_agent и закончить), ParentRunID = исходный ран (линейность и сага по task), DelegationDepth = MaxDelegationDepth (ask-run не может делегировать), IncomingAsks в RunInput — request_id валиден с первого хода без гонки сигналов, ParentClosePolicy: ABANDON (asker может завершиться раньше). Файловый снапшот наследуется от инициатора (как у делегирования — §6: за пределами унаследованной области прав не прибавляется)
Адресат проверяется kernel-side (ResolveCollaborator) §6: доверять to от модели нельзя; резолвер ограничен задачами саги просящего run'а — чужой агент не резолвится в принципе
GetVersion("agent-collaboration") гейтит drain'ы и рекламу тулов Реплей-совместимость: in-flight раны со старой историей не видят ни сигналов, ни тулов (docs/failure-model.md)
ask_agent/answer_agent/get_collaborators в policySafeTools Approval round-trip на каждый шаг диалога убил бы механизм (§8); deny через карточку агента (ToolAllowlist/DenyTools) остаётся оружием политики
Ответы «не по адресу» не теряются awaitAgentReply не выбрасывает чужие ответы (в отличие от awaitApproval): они пере-очередуются и фреймятся на следующей границе хода. В relay-wait селекторе то же: child future ∥ reply-канал ∥ таймер

#3. События журнала

agent.asked → agent.message.received (получатель) → agent.replied (получатель) → agent.answer.received (отправитель); терминальные: agent.ask_expired (таймаут wait-режима), agent.ask_undeliverable (адресат не найден / релей не стартовал). В agent.asked при релее добавляются relay: true и relay_run. Payload усечён до 4096 (как user-note). Каталог UI: группа «Межагентное взаимодействие» в eventCatalog.

#4. Границы первого этапа (осознанные)