What happens
In a conversation where the agent asks the reader something with ask_user, the
transcript renders out of order: every message the reader sent appears above every
message the agent sent, so the answers sit above the questions they answer.
Read back from a real cluster, ListTasks returns this for one such task:
TASK 01a03efd-bfea state=COMPLETED history=3 artifacts=7
history[0] user "ask me a question"
history[1] user "Personal development" <- 1st answer
history[2] user "none" <- 2nd answer
artifact[0] agent ask_user called
artifact[1] agent ask_user result (pending)
artifact[2] agent ask_user result (answered)
artifact[3] agent ask_user called
artifact[4] agent ask_user result (pending)
artifact[5] agent ask_user result (answered)
artifact[6] agent "Thank you for sharing..."
Every message the reader sent is in history; every message the agent produced is in
artifacts. They are two parallel lists, and nothing in the response says how to
interleave them.
Why a client cannot fix it properly
- Timestamps do not separate them. Every message in a task carries the task's
single status.timestamp, so a client sorting by time gets one bucket.
- Only one side is time-ordered by id. Artifact ids are UUIDv7 and sort correctly
(01a03efd-c565 ... 01a03efe-0482). Message ids in history are minted by the
client that sent them and are UUIDv4, carrying no time.
- The correlation ids do not match across the two lists. An answer in
history
carries {"type":"ask_user_response","id":"adk-c9f53704-..."} in its metadata under
https://kagent.dev/extensions/hitl/v1. The ask_user call it answers carries the
model's own id, call_kEdJ3FU3x0W6rHytuDznM732. Neither list names the other.
So the order can be guessed from position, and that is all.
What would fix it
Any one of these, in preference order:
- Interleave server-side — return one ordered sequence per task, rather than
history and artifacts as separate lists a caller has to reassemble.
- A per-entry sequence number on messages and artifacts, monotonic within a task.
- A per-entry timestamp, distinct from the task's status timestamp.
Any of the three lets a client render a task in the order it happened without
inferring anything.
Separately: the prose question is never persisted
When the agent parks on ask_user, the question also arrives as prose on the status
message, and the reader sees it during the turn. It is in neither history nor
artifacts afterwards, so it is gone on the next read. That is visible as a question
that sits at the foot of the transcript until a refresh, then vanishes -- and it means
a conversation replayed from ListTasks is missing the questions it was about.
Where the client stands meanwhile
ui/src/api/chat/a2aGrpcChatClient.ts (messagesFromTask) concatenates
history -> status message -> artifacts, which is what produces the ordering above. It
now interleaves by position as an approximation, and the note there points at this
issue. That approximation should be deleted once any of the three fixes lands.
🤖 written by Claude
What happens
In a conversation where the agent asks the reader something with
ask_user, thetranscript renders out of order: every message the reader sent appears above every
message the agent sent, so the answers sit above the questions they answer.
Read back from a real cluster,
ListTasksreturns this for one such task:Every message the reader sent is in
history; every message the agent produced is inartifacts. They are two parallel lists, and nothing in the response says how tointerleave them.
Why a client cannot fix it properly
single
status.timestamp, so a client sorting by time gets one bucket.(
01a03efd-c565...01a03efe-0482). Message ids inhistoryare minted by theclient that sent them and are UUIDv4, carrying no time.
historycarries
{"type":"ask_user_response","id":"adk-c9f53704-..."}in its metadata underhttps://kagent.dev/extensions/hitl/v1. Theask_usercall it answers carries themodel's own id,
call_kEdJ3FU3x0W6rHytuDznM732. Neither list names the other.So the order can be guessed from position, and that is all.
What would fix it
Any one of these, in preference order:
historyandartifactsas separate lists a caller has to reassemble.Any of the three lets a client render a task in the order it happened without
inferring anything.
Separately: the prose question is never persisted
When the agent parks on
ask_user, the question also arrives as prose on the statusmessage, and the reader sees it during the turn. It is in neither
historynorartifactsafterwards, so it is gone on the next read. That is visible as a questionthat sits at the foot of the transcript until a refresh, then vanishes -- and it means
a conversation replayed from
ListTasksis missing the questions it was about.Where the client stands meanwhile
ui/src/api/chat/a2aGrpcChatClient.ts(messagesFromTask) concatenateshistory -> status message -> artifacts, which is what produces the ordering above. It
now interleaves by position as an approximation, and the note there points at this
issue. That approximation should be deleted once any of the three fixes lands.
🤖 written by Claude