1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//! Where a turn's final answer goes when it is written back to the chat.
//!
//! `complete_response` overwrites the last assistant row with the final
//! answer whenever an intermediate text arrived earlier in the turn. That is
//! only correct when no tool group ran after that row. If tools ran after it,
//! the overwrite moves the answer above those tools, and the fold then hides
//! it inside the working-out group. The answer must instead be a new row
//! after the tool groups.
use crateDisplayMessage;
/// True when the newest assistant row sits before a tool group, meaning tools
/// ran after the last visible text and a final answer must not overwrite it.
pub
/// True when `new` may be written over a row that already holds `existing`
/// text.
///
/// Only an extension counts: the same text, or the same text with more behind
/// it. A row holding a delivered report must never be replaced by a later,
/// shorter closing line, because the report the user already read then reads as
/// vanished while the database still holds it (#2165). When this returns false
/// the answer becomes its own row instead, which loses nothing.
pub
/// True when the response text is already on screen as this turn's assistant
/// row, so appending it again would render the same answer twice.
///
/// A turn that halts on an option-surface tool (`suggest_options`) streams its
/// answer first and calls the tool after, so the answer row sits BEFORE the
/// tool group and `last_text_precedes_tool_group` says to append. The response
/// the tool loop synthesizes on that halt carries the same text again, which
/// would show the answer a second time under the group. The DB keeps one row
/// per turn, so a reload never shows the pair; only the live path does.
///
/// Only a row from the current turn counts. An assistant row that sits before
/// the newest user row belongs to an earlier turn, and an answer that repeats
/// it is a real answer, not a duplicate.
///
/// The row compared against is the last one that actually CARRIES TEXT, not the
/// last assistant row outright. Most agentic turns push a reasoning-only row
/// (`content` empty, the thinking in `details`) after the text and before the
/// tool group, so comparing against that row compared against `""` and the
/// dedupe never fired: the answer rendered twice, once capped as intermediate
/// narration and once in full (#2165).
pub