Proposal: Reviewable Agent Edits with Native Track Changes and MCP Approval Feedback #326
Replies: 3 comments 1 reply
|
Hi! This is a complicated feature but I agree it is interesting and worth doing, in spite of being a pain. Here's my notes:
Standard tool response shape MCP vs sidebar — same core, two shells One thing that's tricky about making it an optional feature is you need to handle it being turned on and off at any time. Please make sure to handle that case and doing something reasonable. Will need to keep track of whether track changes was turned on by the user. Okay if that sounds good, go for it, make a PR and I'll review! Regards, -Keith |
|
No problem about being busy. That result looks great! It is a complicated feature but I'm glad you didn't get discouraged. Note you found some good issues, we should look into more later. No one has to fix everything, but as long as it commented, the issues won't get forgotten about. You can put code or docs and ideally both. Send PR when ready. I'm about to make a new release and I'll put it in there. |
|
Alright, I put your PR in there. I next moved the setting to the Doc tab, converted the two checkboxes into a dropdown, and hid the timeout value for now since few people will want to adjust it. I'll make other little changes, if it causes any issues, make a PR. Thanks! BTW, please make sure Claude reads AGENTS.md before any task, do you do that? |
Uh oh!
There was an error while loading. Please reload this page.
Hey Keith! I'm back to the idea of letting people approve or reject agent edits. I've been organizing my thoughts and running experiments, and the trickier parts actually work, including the wait-for-approval flow over MCP.
What I'm going for
The agent shouldn't silently change the document. Every edit the agent makes should be something the user can look at and accept or reject, seeing the old and the new before deciding.
The things I treat as non-negotiable for this to actually be useful:
How I think we do it
Native Track Changes, like you suggested. There's a setting that, when on, makes the agent's edits get recorded as tracked changes, so the user reviews them with the accept/reject UI they already know, inline. Mechanically it just turns
RecordChangeson around the agent's edit and restores your previous setting afterward, so your own typing isn't affected. I wired it into the places the agent actually edits: the main edit tool, the edit-selection rewrite, and the script/vision result insertion.(If you'd already turned Track Changes on yourself, the agent leaves it on, it doesn't flip it off and on behind your back. The only spot it briefly toggles is the streaming rewrite: it records with tracking off and then re-applies the result as one clean change, so you don't get a redline per typed word — but you end up exactly where you started, tracking-wise.)
The hard parts, and how I'm thinking about them
Paragraph styles don't track. LibreOffice records text and character formatting (bold, color, size…) as tracked changes, but not a paragraph-style change (turning something into Heading or Caption). I tried faking it — delete the text and re-insert it so the change rides a real tracked edit — but on reject the text comes back and the new style stays, which is worse than not tracking at all (silently wrong). So for now: style changes apply directly, and the agent just tells the user it changed a style (the text edits in the same turn are still reviewable). I don't have a clean way to make style changes truly reviewable yet, so I'm setting that aside for now.
The agent knowing what you decided — and it works over MCP. The review itself is native LibreOffice, so accepting/rejecting is identical whether the agent runs in the in-app chat or over MCP. The part I wanted to nail is the agent learning the outcome. The flow: the agent makes one call that edits the document and then doesn't return — it waits while you accept/reject in LibreOffice, and only once you've gone through its changes does the call hand back, telling the agent what you kept. That fits MCP fine — one request, one response; the response just comes back after you've reviewed.
I wired up a quick version and tested it over MCP, and it's not hypothetical: the agent's write call stayed open until I'd reviewed — other tool calls kept working normally in the meantime (the server didn't freeze) — and it came back with a per-change result. When I accepted two of the changes and rejected one, the response correctly labeled each one accepted or rejected.
Two things I had to work out:
One gotcha worth flagging for the implementati** Tracked changes live inside the document, so they only survive a close/reopen if the file is saved. Since the whole point is reviewing the agent's edits — maybe not right this second — I'd have it save automatically after the agent's changes when review mode is on, so they're waiting for you the next time you open the file. It's safe: they stay tracked changes, so you can still accept or reject them after reopening — saving doesn't commit them. (One open case: a brand-new document that's never been saved has no filename yet — there we'd either prompt for a location or hold off on the auto-save until it's been saved once.)on: to hold a call open like this, the tool has to run on a background thread — and since LibreOffice's API isn't thread-safe, any actual document edits inside it have to be handed back to the main thread. The framework already enforces this (it refuses a background tool that touches the document directly), and a couple of existing long-running tools already follow the pattern, so it's a known shape — just something to get right.
The one practical limit is a very long wait vs. the client's timeout: if you walk away mid-review, we don't want the call to just hang. So after a sensible max-wait it returns to the agent "you haven't reviewed these yet," and the agent can then nudge you to accept or reject the changes before it carries on — I tested this too: with nothing reviewed, it came back at the timeout asking the user to go review. (A keepalive could stretch the wait, but the simple timeout-and-nudge is probably enough.)
"Extend selection" writes gradually. This is the one feature that streams the AI's text into the doc bit by bit, so recording it naively would give you a redline per chunk. I experimented with it and it works cleanly: stream it live with tracking off (you still see it appear), then at the end record just the appended text as a single tracked insertion. In my test that produced exactly one change — reject restored the original, accept kept it. Same shape as the rewrite path, just needs wiring in.
Attribution. To make the agent's changes show up as the agent's (not yours), I'd briefly set the author name to "WriterAgent" during the edit and restore it after. It works, but it's a global setting for that moment, so I'd scope it tightly — set it, edit, put it back. If that feels too invasive, the fallback is tagging each change with a comment instead of renaming the author — your call.
Persistence — saving so you can review later. Tracked changes live inside the document, so they only survive a close/reopen if the file is saved. Since the whole point is reviewing the agent's edits — maybe not right this second — I'd have it save automatically after the agent's changes when review mode is on, so they're waiting for you the next time you open the file. It's safe: they stay tracked changes, so you can still accept or reject them after reopening — saving doesn't commit them. (One open case: a brand-new document that's never been saved has no filename yet — there we'd either prompt for a location or hold off on the auto-save until it's been saved once.)
What do you think? Any suggestions?
All reactions