fix(office-ui): stop progress-row flicker and surface native role replies end to end
Two user-visible defects in company mode, root-caused via project 6666/8888 DB forensics: Progress-row flicker (thinking preview appearing/disappearing): progress entries were broadcast to clients before reaching the persistence buffer, so a tool_call-triggered session_detail snapshot rebuilt from the DB erased freshly streamed entries from the live log. Buffer now fills before the broadcast and session_detail flushes it before reading. Native role transcripts incomplete (thinking only at start, no narration, no final summary — external agents unaffected): - thinking deltas shared one stream id per conversation turn while seq reset per iteration, collapsing all iterations into one entry and silently dropping live thinking from iteration 2 on; now keyed per iteration like assistant deltas - assistant_delta events were mapped to None; company mode now surfaces them as streaming 'assistant' progress entries (rendered as Reply cards, merged like thinking, excluded from inline chat rows) - thinking was persisted one row per token, flooding the 1000-entry cap and evicting interleaved tool history; append_progress now folds streaming deltas per (type, turn, stream) with seq dedup - the terminal company turn was hidden at summary detail and, worse, its id-keyed backfill merge kept the first-inserted intermediate content, so the final reply never reached any channel; terminal turns are now flagged company_final_turn, visible at summary detail, and carry their own ui_message_id so they insert as fresh rows - appendProgressEntry applied its seq guard against unrelated entries when the stream key was absent from the log, killing the first delta of any fresh stream; the guard now only applies within the same stream Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -230,6 +230,11 @@ def _transcript_message_hidden_from_ui(
|
||||
) -> bool:
|
||||
metadata = dict(getattr(message, "metadata", {}) or {})
|
||||
kind = str(metadata.get("kind", "") or "").strip()
|
||||
if metadata.get("company_final_turn"):
|
||||
# The role's final reply of a company turn is the user-visible result
|
||||
# (intake/aggregate turns have no engine-recorded result surface, so
|
||||
# hiding this would drop the reply from the chat entirely).
|
||||
return False
|
||||
return detail_level != "full" and kind in _FULL_DETAIL_ONLY_TRANSCRIPT_KINDS
|
||||
|
||||
|
||||
@@ -1122,7 +1127,11 @@ def _transcript_item_to_ui_message(
|
||||
"role": role,
|
||||
"task_id": task_id,
|
||||
"transcript_kind": kind,
|
||||
"detail_visibility": _transcript_message_visibility(kind),
|
||||
"detail_visibility": (
|
||||
"summary"
|
||||
if message_metadata.get("company_final_turn")
|
||||
else _transcript_message_visibility(kind)
|
||||
),
|
||||
**({"type": "system"} if kind == "runtime_v2_user_turn" else {}),
|
||||
**({"verification_verdict": verification_footer} if verification_footer else {}),
|
||||
**({"runtime_thinking": runtime_thinking} if runtime_thinking else {}),
|
||||
|
||||
Reference in New Issue
Block a user