diff --git a/studio/backend/core/inference/anthropic_compat.py b/studio/backend/core/inference/anthropic_compat.py index 263718c540..8e1c939e55 100644 --- a/studio/backend/core/inference/anthropic_compat.py +++ b/studio/backend/core/inference/anthropic_compat.py @@ -253,9 +253,28 @@ class AnthropicStreamEmitter: elif etype == "metadata": self._usage = event.get("usage", {}) return [] - # status events — no Anthropic equivalent + elif etype == "status" and not event.get("text"): + # Auto-continue boundary marker emitted by + # generate_chat_completion_with_tools — the next "content" + # event resets to a fresh cumulative baseline, so close any + # open text block and clear the diff cursor. Without this + # the next continuation gets diffed against the previous + # turn's length (shorter continuations are dropped, longer + # ones lose their prefix). + return self._handle_boundary() + # Other status events (tool progress text) have no Anthropic + # equivalent. return [] + def _handle_boundary(self) -> list[str]: + events = [] + if self._text_block_open: + events.append(self._close_block()) + self.block_index += 1 + events.extend(self._open_text_block()) + self._prev_text = "" + return events + def finish(self, stop_reason: str = "end_turn") -> list[str]: """Close any open block and emit message_delta + message_stop.""" events = [] diff --git a/studio/backend/routes/inference.py b/studio/backend/routes/inference.py index 607245467c..6b4c2f0268 100644 --- a/studio/backend/routes/inference.py +++ b/studio/backend/routes/inference.py @@ -4370,6 +4370,13 @@ async def _anthropic_tool_non_streaming(run_gen, message_id, model_name): ) elif etype == "tool_end": prev_text = "" + elif etype == "status" and not event.get("text"): + # Auto-continue boundary marker: the next content event + # restarts the cumulative diff baseline, so reset prev_text + # the same way tool_end does. Without this a shorter + # continuation gets dropped entirely and a longer one + # loses its prefix. + prev_text = "" elif etype == "metadata": usage = event.get("usage", {})