From a59f24ac87660b9695df2a317a5b5497bd59a5e7 Mon Sep 17 00:00:00 2001 From: jnjpng Date: Mon, 23 Feb 2026 11:21:49 -0800 Subject: [PATCH] fix(core): ensure buffered Anthropic tool chunks always include otid (#9516) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix(core): ensure otid exists when flushing buffered anthropic tool chunks Anthropic TOOL_USE buffering can emit buffered tool_call/approval chunks on content block stop before otid is assigned in the normal inner_thoughts_complete path. Ensure flush-time chunks get a deterministic otid so streaming clients can reliably correlate deltas. 👾 Generated with [Letta Code](https://letta.com) Co-authored-by: Letta --- letta/interfaces/anthropic_streaming_interface.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/letta/interfaces/anthropic_streaming_interface.py b/letta/interfaces/anthropic_streaming_interface.py index 8dfd872f..dcb8d4e7 100644 --- a/letta/interfaces/anthropic_streaming_interface.py +++ b/letta/interfaces/anthropic_streaming_interface.py @@ -593,9 +593,15 @@ class AnthropicStreamingInterface: pass elif isinstance(event, BetaRawContentBlockStopEvent): # If we're exiting a tool use block and there are still buffered messages, - # we should flush them now + # we should flush them now. + # Ensure each flushed chunk has an otid before yielding. if self.anthropic_mode == EventMode.TOOL_USE and self.tool_call_buffer: for buffered_msg in self.tool_call_buffer: + if not buffered_msg.otid: + if prev_message_type and prev_message_type != buffered_msg.message_type: + message_index += 1 + buffered_msg.otid = Message.generate_otid_from_id(buffered_msg.id, message_index) + prev_message_type = buffered_msg.message_type yield buffered_msg self.tool_call_buffer = []