pub fn record(
chat: &mut Chat,
store: &Chats,
text: &str,
attachments: Vec<Attachment>,
) -> Result<String>Expand description
Append the operator’s turn and flush it, without invoking anything.
Split out of say so a caller that answers the operator before the agent
has replied can still promise the message is on disk. POST /api/chats/{id}/say
does exactly that: holding an HTTP connection for the 23-to-90 seconds a
real turn takes is a coin flip on a phone, and the browser reporting
“Failed to fetch” while the server quietly finished the turn is the worst
of both answers.
Returns the trimmed text, so the caller and the agent see the same string.
Re-reads the record under Chats::guard and Chats::claim rather
than trusting the caller’s copy of chat’s status: web::chat_say
reads the chat, then awaits config discovery before calling this - a gap
a concurrent POST /api/chats/{id}/abandon, or a magi plan --abandon
running as its own process, can land in. Re-reading without both would
only narrow that window, not close it - see crate::talk::record,
which this mirrors for the in-process half.
attachments may be non-empty while text is empty - a turn that is
only images is a normal thing to send - but not both empty, the same rule
this always enforced for text alone.