Add chat_edit() - #11
Merged
Merged
Conversation
The foundation for a progress message: post once, then keep replacing it, instead of narrating into the channel one message per tool call. Matrix builds m.new_content plus an m.replace relation on top of mx_send()'s extra hook -- no mx.api change needed. The fallback body keeps the conventional "* " prefix, because a client too old to understand edits renders the event as an ordinary message and the asterisk is what tells a reader it is a correction rather than the bot repeating itself. Markdown renders into both copies; carrying it in only one shows markup on old clients and loses it on new ones. Encrypted rooms refuse, and capabilities report edits = FALSE on an e2ee client to match -- the same bargain attachments get. An edit carries its replacement text in an ordinary event, and crypto_ops$send() takes text, msgtype, markdown and mentions with nowhere to put a relation, so the Megolm path cannot carry one either. The default throws rather than returning quietly. Stale text is worse than a visible failure: a reader cannot tell that what they are looking at is no longer true.
A room can now be shown a collapsible <details> block, which is the whole reason chat_edit() exists -- a progress trail nobody can collapse is a wall of text that grows. There was no way to express one. markup = "markdown" renders through mx_markdown_to_html(), which escapes raw HTML: correct for a conservative subset, and a dead end for a caller that has markup the subset cannot reach. So `rich` carries a fragment the adapter passes through as formatted_body, and `text` stays required as the body. That is Matrix's own model, and it is load-bearing rather than tidy: text is what a client too old to render the markup shows, what a push notification carries, and what every other transport gets. Ignored rather than refused where unsupported, on chat_typing()'s reasoning -- the text is the message, the markup is decoration. chat_capabilities()$rich_markup names what an adapter accepts, and is empty on an e2ee client: the Megolm path builds its own HTML from markdown and has nowhere to put a supplied fragment. Placed last in the signature, after notify, so nothing calling positionally past `text` shifts.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Groundwork for a progress message in a room: post once, then keep replacing it, instead of narrating into the channel one message per tool call. corteza's room surface currently emits typing-on, a wall of prose, typing-off — there is no way to show work as it happens without this.
Matrix
Builds
m.new_contentplus anm.replacerelation on top ofmx_send()'sextrahook, so no mx.api change was needed.The fallback body keeps the conventional
*prefix. A client too old to understand edits renders the event as an ordinary message, and the asterisk is what tells a reader it is a correction rather than the bot repeating itself.Markdown renders into both copies. Carrying it in only one shows raw markup on old clients and loses it on new ones — exactly backwards.
Encrypted rooms refuse
edits = FALSEon an e2ee client, the same bargain attachments get. An edit carries its replacement text in an ordinary event, so sending one puts it on the homeserver in the clear, in the room whose whole point is that it is not. The Megolm path cannot carry it either:crypto_ops$send()takes text, msgtype, markdown and mentions, with nowhere to put a relation.The default throws
Stale text is worse than a visible failure. A reader cannot tell that what they are looking at is no longer true, so an edit that quietly did nothing is the one failure mode with no symptom.
Slack, loopback, IRC
Slack maps to
chat.updateand returns the sametsit was given; Matrix mints a new event for the edit and returns that. The contract promises "the id of the thing that happened", not that adapters agree on which thing that is — documented on the generic.Loopback replaces in place and raises on an unknown id: a consumer editing a message it never sent has lost track of itself, and the reference adapter is where that should be loudest.
IRC has none — a line is on the wire and gone.
Verification
881/881.
What this does not do yet
The consumer. Rendering an activity trail (
Ran 3 commands, read 2 files ›with<details><summary>, diff stats, PR chips) is corteza-side work and lands separately.