Summary
When a client connection dies while a delivery is pending, that delivery stays in the session's bufferedDeliveries queue in workflow durable storage. A later POST /eve/v1/session/:id rehydrates the session and drains the stale queued delivery before the message that was just sent — the new turn starts with message.received equal to the old text, and the just-sent message runs as a subsequent turn.
From the user's point of view: they send a message today and the agent first answers the message they sent yesterday (whose stream had died), producing a confusing transcript and a run that none of our UI surfaces expected.
Environment
eve 0.19.0 (npm), conversation mode, Next.js app proxying /eve/v1/* to eve start (nitro server)
- Also inspected 0.20.0:
session-delivery-hook.js, turn-control-receiver.js, workflow-entry.js, turn-workflow.js, and route-child-delivery.js in the published dist are byte-identical to 0.19.0, so the behavior should be unchanged there.
Reproduction shape
- Send a message on a session; while the turn is in flight (or parked), the client connection dies with a delivery still pending — the payload lands in the per-session
bufferedDeliveries queue and is persisted with the session.
- Later (we observed this across a day boundary), send a new message to the same session id.
- The rehydrated driver drains the buffered (stale) delivery first: the new run's
message.received is the old text; the new text executes as the following turn.
Where we traced it (published dist, 0.19.0)
workflow-entry.js → waitForNextDeliver() drains bufferedDeliveries.splice(0) (coalesced) before reading fresh deliveries from the session delivery hook.
turn-control-receiver.js → serviceDeliveryRequest() does bufferedDeliveries.shift() before racing the control hook against fresh hook deliveries; bufferTurnDeliveries() unshifts a turn's buffered deliveries back to the front.
- The queue is part of the durable session state, so it survives the dropped connection and is not reconciled against the delivery that arrives with the rehydrating POST.
Expected
One of (whichever matches your intended semantics):
- A delivery whose originating connection died is dropped (or surfaced as such) on rehydration instead of silently replaying ahead of the live message; or
- The rehydrating POST's delivery is ordered before (or coalesced with) stale buffered deliveries; or
- The channel gets a way to inspect/flush pending buffered deliveries so the app can decide.
Happy to provide more detail from our traces if useful.
Summary
When a client connection dies while a delivery is pending, that delivery stays in the session's
bufferedDeliveriesqueue in workflow durable storage. A laterPOST /eve/v1/session/:idrehydrates the session and drains the stale queued delivery before the message that was just sent — the new turn starts withmessage.receivedequal to the old text, and the just-sent message runs as a subsequent turn.From the user's point of view: they send a message today and the agent first answers the message they sent yesterday (whose stream had died), producing a confusing transcript and a run that none of our UI surfaces expected.
Environment
eve0.19.0 (npm), conversation mode, Next.js app proxying/eve/v1/*toeve start(nitro server)session-delivery-hook.js,turn-control-receiver.js,workflow-entry.js,turn-workflow.js, androute-child-delivery.jsin the published dist are byte-identical to 0.19.0, so the behavior should be unchanged there.Reproduction shape
bufferedDeliveriesqueue and is persisted with the session.message.receivedis the old text; the new text executes as the following turn.Where we traced it (published dist, 0.19.0)
workflow-entry.js→waitForNextDeliver()drainsbufferedDeliveries.splice(0)(coalesced) before reading fresh deliveries from the session delivery hook.turn-control-receiver.js→serviceDeliveryRequest()doesbufferedDeliveries.shift()before racing the control hook against fresh hook deliveries;bufferTurnDeliveries()unshifts a turn's buffered deliveries back to the front.Expected
One of (whichever matches your intended semantics):
Happy to provide more detail from our traces if useful.