feat(custom-ui): AI citation showcase over editor.doc.metadata.* (SD-3208)#3372
Merged
Merged
Conversation
Customer-facing citation demo built on the metadata.* contract from SD-3104. Customer-facing counterpart to the developer-shaped SD-3199 demo (#3370, draft); both lean on the same anchored-metadata model. What this shows: - Generate draft with sources — mocked stand-in for a chat-driven RAG pipeline. Inserts a pre-canned paragraph and attaches citations to specific phrases. - Sources sidebar grouped by sourceId, showing source title, type, provider, deep link, and the cited locations within the document. - Hover popover with displayText, locator, excerpt, provider, confidence — the verification surface so a lawyer can trust the output without leaving the doc. - Highlight overlay on cited spans using getRect.rects, so line-wrapped citations get clean per-line underlines visible through the text. - Scroll-to, Edit, Remove per citation. All six metadata.* methods exercised. What this does not show: - The button is a stand-in for a chat-driven AI workflow, not the recommended product UX. A real integration plugs a chat panel + Insert into document action. - Generation is mocked. No LLM is wired. - Verification status is a render-time concern; external verification signals can change over time, so it is not persisted in the payload.
…SD-3208) - Rename 'Generate draft with sources' to 'Insert sample cited draft' so the button doesn't overclaim — the demo is mocked, not a real AI pipeline. - Match the help text and empty-state copy. - Replace the hardcoded rgba on .citation-highlight with color-mix against --accent so the highlight tints follow theme changes.
Repeated clicks were colliding on hardcoded citation ids and surfacing 'Anchored metadata id already exists' errors in the UI. Each draft holds fixed ids (cite-001, cite-002, cite-003); the cycling-by-index logic inevitably re-inserted them on the third click and failed. Single-shot now: one click inserts every MOCK_DRAFTS paragraph and attaches every citation in one go. The button hides as soon as citations exist, so the click-collision path is unreachable. To re-run the demo, remove the citations from the sidebar or reload the page.
… partial attach (SD-3208) - mockDraft.ts: drop vendor names and the stale 'Generate draft with sources' label from the file header. Vendor/product research belongs in the PR/Linear notes, not source comments. - GenerateDraftButton: if a partial-attach failure leaves an error mid-flight, keep the component mounted (and the error message visible) instead of silently disappearing on the next render. The early-return now gates on 'has citations AND no error'.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 601e4d6468
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…on layout (SD-3208) P1: CitationEditor had its own useCitations() instance, so save() re-hydrated only the child's local citations state. Since a payload- only metadata.update doesn't change the SDT, the parent's content- controls slice doesn't tick, leaving the parent panel stale after Save. Lift update from the parent useCitations() and pass it down so save() refreshes the list being rendered. Verified in browser: locator field updates immediately on Save. P2: CitationHighlights remeasured on window scroll/resize only. Document edits that move cited spans without changing window geometry (typing above a span, paragraph reflow) left the underline rects pinned at their old positions. Added a ResizeObserver on the editor canvas (catches pagination/zoom) plus a MutationObserver on the canvas DOM (catches text edits). Both funnel through a single rAF tick so burst events collapse into one remeasure per frame. Verified in browser: 3x Enter at the document start shifts cited spans by ~1400px and the rects track them.
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.
Customer-facing citation demo built on the
metadata.*contract from #3351. Supersedes the developer-shaped SD-3199 spike (#3370, closed); this PR is the citation showcase reviewers should evaluate.The target legal-AI product pattern is generated text with source-grounded citations plus a verification UI for the lawyer. This demo shows that shape on top of SuperDoc.
What this shows
sourceId, with source title, type chip, provider, deep link, and the cited locations within the document.displayText,locator,excerpt(quoted passage),provider,confidence— the verification surface so a lawyer can trust the output without leaving the document.ui.contentControls.getRect({ id }).rects, so line-wrapped citations get clean per-line underlines visible through the text.metadata.*methods exercised (attach via insert, list + get via panel, resolve via scroll-to, update via Edit, remove via Remove).What this does not show
sourceId+providerat render time.Payload
Persisted through
editor.doc.metadata.*and survives DOCX round-trip:```
{
citationId, sourceId, // customer's foreign keys
sourceType, provider, // drives rendering + source resolution
displayText, locator?, excerpt, deepLink?, // verification surface
confidence?, // optional, rendered only when present
createdAt?
}
```
Customer-rollout gate
This PR validates the custom UI + metadata composition. Customer rollout still depends on SD-3201 (Word-in-the-loop validation): SuperDoc → DOCX → Word save / edit → SuperDoc, including the highest-risk case where a Word user edits text inside an anchored span.
Draft because reviewers should evaluate the product framing, not just the code.