Repository navigation
Chat: own-words edit proposals; My Words text prototype folds into Chat - #698
Merged
Merged
Conversation
…le ChatCompletions API
It was yucky that we had to have these custom wrappers, but we already litigated that and ended up with vercel/ai#17974
…erwriting the initial message.
…e corpus, if overlap is at least two words. Also remove `as` as a stitch word, since it reads LLM-y.
Walkthrough/Propose, their interaction/ seam, and the scripted demo page are gone: Chat's own-words edits replace Propose. My Words is now the voice prototype alone, on the shared docTools/. The mock editor moves to __fixtures__ for the voice tests. Docs that described the removed code point at docs/chat-document-tools.md. Co-Authored-By: Claude Opus 5.5 <[email protected]>
10 tasks
- Edit tools' `execute` now throws instead of applying. The app writes every proposal's result itself, so the SDK never runs it; if that invariant ever breaks, the proposal fails visibly rather than editing from a second path. Drop the unreachable 'applying' status: an approval without a result now reads as 'failed', never 'pending' (which would offer Accept again). - A new proposal no longer selects its target in the document, which could replace the selection with the writer's next keystroke and made the next turn's context report a selection the writer never made. The card gets a "Show in document" link instead, using the doctext jump's trimming so long paragraphs still resolve in Word. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_017KwGFirZNMaz3WBQCU4Xor
Undoing a `move` puts the paragraph back with a splice that removes nothing, so it had no text to relocate by and went back at its recorded index. After a later edit added or removed a paragraph above it, the paragraph silently landed in the wrong place. Record the neighbors on such splices (`prevParagraph`/`nextParagraph`, the fields #589 plans for hosts to enforce) and re-anchor between them: exactly one match, or refuse. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_017KwGFirZNMaz3WBQCU4Xor
The previous commit matched a put-back's whole neighbor paragraphs exactly, so any edit anywhere in either neighbor blocked the undo, and blank neighbors made it ambiguous. Undo data is long-lived, so anchor it the way #589's TextAnchor does: ~32 characters on each side of the gap, counted across paragraph breaks (blank paragraphs included literally), matched as far as a window cut short by the document's edge goes. The anchors live on an undo-only `UndoSplice` (captured by `captureUndo`), not on `ParagraphSplice`, whose neighbor fields #589 reserves for exact host preconditions; hosts get plain splices. A comment on `contextAt` records the skip-blank-lines alternative in case refusals cluster around blank lines. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_017KwGFirZNMaz3WBQCU4Xor
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.
Closes #583. Chat becomes a coach that can also propose edits to the document, under the My Words rule: it may only place the writer's own words, and every edit needs the writer's approval. The My Words text prototype (Walkthrough/Propose) is removed; Voice stays as a prototype on the shared code.
Design write-up:
docs/chat-document-tools.md.What changed
Shared code. The My Words tool logic moved to
frontend/src/docTools/(ops, the word-bank check, apply and report, plus the new edit note, preview and undo).EditorAPI.applyEditis now optional;canEdit(editor)decides whether edit tools are offered. Google Docs omits it (#590); Word and the standalone editor have it.Chat context (supersedes #249). The transcript is the model's own
ModelMessage[], tool calls included. Each writer turn carries a<document_context>block:The writer never sees this block.
viewre-reads the document on demand.Proposals.
str_replace,insertandmoveare gated intoolApproval. Each must dry-run cleanly against the current document and pass the word-bank check; otherwise it's denied with a reason the model can act on. A proposal that passes gets an approval card (summary, a trimmed preview of the change, Accept or Decline). Undo can then revert any applied edit, in any order, and refuses if the text has changed since.Word bank:
Runs of content words may be stitched together from pieces that overlap by two or more words.
aswas dropped from the glue words because it can mean "because".Logging. New
chatLog.editevents for the proposal lifecycle (schema version 6). Content goes inproposalandoffending, which are document-level in the consent gate.Departures from #583's plan
applyEditexists, including Word, rather than standalone only. Word may still pick the wrong text to edit (Send hosts ranges, not needles: one text-matching implementation across editors #589).Testing
npm run typecheck,npx vitest run(270 passing), eslint.Follow-ups: #699.
🤖 Generated with Claude Code