studio: reset Anthropic adapter cursor on auto-continue boundary
Codex P2 on #5549 flagged that the auto-continue branch yields only a `{"type":"status","text":""}` event between turns; the Anthropic streaming emitter (`AnthropicStreamEmitter`) and the non-streaming tool path (`_anthropic_tool_non_streaming`) both ignore `status` events, so their cumulative-text cursor still holds the previous turn's full length when the continuation starts streaming. Shorter continuations get dropped entirely and longer ones lose their prefix. Treat the empty-text status as an auto-continue boundary in both paths: - `AnthropicStreamEmitter`: close any open text block, open a fresh one (matches the `tool_end` reset pattern), and clear `_prev_text`. - `_anthropic_tool_non_streaming`: clear `prev_text` so the next `content` event's diff baseline is empty. Non-empty status events (tool progress text) keep their existing no-op semantics.
This commit is contained in:
parent
8503fb33ae
commit
25acc2062e
2 changed files with 27 additions and 1 deletions
|
|
@ -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 = []
|
||||
|
|
|
|||
|
|
@ -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", {})
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue