fix: preserve A2A transcript order - #2591
Conversation
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Design context: why conversion happens in
|
| Hook | Limitation |
|---|---|
| Model callbacks | Modify model requests/responses, not A2A event types |
| Tool callbacks | Modify tool arguments/results only |
| Agent callbacks | Add or replace agent content, which is still converted to an artifact |
Plugin OnEventCallback |
Can replace a session.Event, but artifact conversion happens afterwards |
GenAIPartConverter |
Converts individual parts only |
A2A AfterEventCallback |
Receives an already-created TaskArtifactUpdateEvent and cannot replace it |
| Custom runner/provider | Still feeds session events into the same artifact-only processor |
| A2A call interceptor | Can replace the outbound streamed event, but runs after the task store processed the original artifact, so replay would remain wrong |
Marking a tool as long-running is only correct when execution must enter input-required; using it for ordinary tool calls/results would change task semantics.
Therefore the AgentExecutor decorator is the earliest public seam where kagent can replace the concrete A2A event before the A2A SDK persists it. The cleaner long-term solution is upstream support for an event converter that returns a general a2a.Event (or an artifact/message/status transform), at which point this local conversion can be removed.
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Summary
Testing
Closes #2584