Appending a tool result twice appends it once
An agent loop that retries a step, or an orchestrator that re-delivers a result, must not double the conversation. The buffer decides by the tool call's id, so a repeat is a no-op rather than a second turn.
The rule
- Appending to a conversation buffer is idempotent by tool call id.
- A
tool-role message whose tool call id already appears anywhere in the buffer (already stored, or added earlier in the same append) is dropped rather than appended, and the reported message count reflects the deduplicated buffer. - The one exception is an id currently held by a synthetic healed placeholder, which is replaced rather than deduplicated.
What it means
A retried step or a re-delivered result carries the same tool call id it carried the first time, so the buffer can tell a repeat from a second call without any cooperation from whatever is retrying. The count reported back is the deduplicated count, not a running total, so a re-fire is invisible to anything reading it afterward.
The exception is the clause worth reading twice: an id currently held by a synthetic healed placeholder is not deduplicated against — it is replaced. Without that exception, a real result landing after MEM-3 healed its call would be dropped as a duplicate of its own placeholder, and the buffer would keep telling the model the call was interrupted after it had in fact returned.
Example
A buffer already holds a turn that declared tool call c1 and a result that
answered it.
{ "role": "tool", "content": "re-fired result", "tool_call_id": "c1" }{ "role": "tool", "content": "second result", "tool_call_id": "c2" }Now the same id is held only by a synthetic placeholder, not a real result:
{ "role": "tool", "content": "Tool call was interrupted; no result.", "metadata": { "tool_call_id": "c1", "healed": true } }{ "role": "tool", "content": "Found 3 cats", "tool_call_id": "c1" }