feat(a2ui-playground): add per-conversation share button#2770
Conversation
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds end-to-end conversation sharing: a shared publish utility for durable preview URLs, a Share button in the conversation list, a share handler in AIChatPage that loads/publishes snapshots and copies a render URL, and DemosPage updated to use the shared publisher. ChangesConversation sharing and durable URL generation
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/genui/a2ui-playground/src/pages/AIChatPage.tsx (1)
188-197: 💤 Low valueConsider extracting
isDevHostto the shared utility.This function is now duplicated verbatim in
utils/publishPayload.ts. You could export it from there and import it here for consistency, reducing the maintenance surface.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/genui/a2ui-playground/src/pages/AIChatPage.tsx` around lines 188 - 197, Extract the duplicated isDevHost logic into the shared utility by exporting the existing isDevHost function from utils/publishPayload.ts and replacing the local definition in AIChatPage.tsx with an import of that exported function; update the AIChatPage.tsx file to import { isDevHost } from the utils module, remove the inline isDevHost function, and ensure any other files using the duplicate (e.g., utils/publishPayload.ts) keep a single exported implementation to avoid duplication.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/genui/a2ui-playground/src/pages/AIChatPage.tsx`:
- Around line 188-197: Extract the duplicated isDevHost logic into the shared
utility by exporting the existing isDevHost function from
utils/publishPayload.ts and replacing the local definition in AIChatPage.tsx
with an import of that exported function; update the AIChatPage.tsx file to
import { isDevHost } from the utils module, remove the inline isDevHost
function, and ensure any other files using the duplicate (e.g.,
utils/publishPayload.ts) keep a single exported implementation to avoid
duplication.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 85944996-5b71-4ec3-ba6d-8523d155a646
📒 Files selected for processing (4)
packages/genui/a2ui-playground/src/components/ConversationListPanel.tsxpackages/genui/a2ui-playground/src/pages/AIChatPage.tsxpackages/genui/a2ui-playground/src/pages/DemosPage.tsxpackages/genui/a2ui-playground/src/utils/publishPayload.ts
a934e5d to
33b4f0a
Compare
Merging this PR will degrade performance by 14.75%
|
| Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|
| ❌ | transform 1000 view elements |
40.2 ms | 47.2 ms | -14.75% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing PupilTong:claude/trusting-heyrovsky-9fcd5b (dfae83e) with main (af38400)2
Footnotes
-
26 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩
-
No successful run was found on
main(8895853) during the generation of this report, so af38400 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report. ↩
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/genui/a2ui-playground/src/pages/AIChatPage.tsx (2)
1810-1818:⚠️ Potential issue | 🟠 Major | ⚡ Quick winReuse the existing history reconstruction fallback before giving up.
If a stored conversation has neither
previewPayloadUrlsnorsnapshot.previewMessages, Share just falls through to failure, even though the page can already rebuild preview data from message history viabuildPreviewMessagesFromHistory(...)on Lines 1206-1208. That means older/incomplete snapshots can still render after opening the conversation but cannot be shared directly from the list. Please fall back to reconstructing fromrecord.messagesbefore returningshowCopyToast(false).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/genui/a2ui-playground/src/pages/AIChatPage.tsx` around lines 1810 - 1818, If neither urls.messagesUrl nor snapshot.previewMessages produce fallbackMessages, call the existing buildPreviewMessagesFromHistory(record.messages) to reconstruct preview messages from history (the same logic used earlier) and assign its result to fallbackMessages before falling back to showCopyToast(false); update the branch around urls.messagesUrl / fallbackMessages checks (referencing urls.messagesUrl, snapshot.previewMessages, fallbackMessages, record.messages, and buildPreviewMessagesFromHistory) so reconstructed previews are used for sharing when available.
1786-1790:⚠️ Potential issue | 🟠 Major | ⚡ Quick winDon't trust the cached payload URL for the active preview unconditionally.
For the active conversation, this branch assumes
latestPreviewPayloadUrlsRef.currentstill matches the preview currently on screen. It doesn't after local-only replacements likehandleLoadExample()on Line 1731, which updateslatestPreviewMessagesRefbut never clears the payload URL ref. In that state, Share copies the previous turn's durable URL instead of the example the user is looking at. Clear the cached URLs whenever preview content is replaced without a publish, or force this path to republishfallbackMessageswhen the active preview is known to be unpublished.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/genui/a2ui-playground/src/pages/AIChatPage.tsx` around lines 1786 - 1790, The active-preview branch uses latestPreviewPayloadUrlsRef.current unconditionally causing stale durable URLs after local-only updates (e.g., handleLoadExample) which updates latestPreviewMessagesRef but never clears payload URLs; update the logic so that handlers that perform local-only preview replacements (handleLoadExample and any similar functions that mutate latestPreviewMessagesRef) also clear latestPreviewPayloadUrlsRef.current (set to null/undefined) and/or mark the preview as unpublished, and in the id === activeId branch (where urls and fallbackMessages are set) detect a missing/cleared latestPreviewPayloadUrlsRef.current and either trigger the existing republish/generate-durable-url routine (e.g., call publishPreview/publishPayload/generateDurableUrl with fallbackMessages) before assigning urls or fall back to forcing republish of fallbackMessages so Share never uses a stale URL; update references in AIChatPage.tsx to latestPreviewPayloadUrlsRef, latestPreviewMessagesRef, handleLoadExample, and the id === activeId branch accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@packages/genui/a2ui-playground/src/pages/AIChatPage.tsx`:
- Around line 1810-1818: If neither urls.messagesUrl nor
snapshot.previewMessages produce fallbackMessages, call the existing
buildPreviewMessagesFromHistory(record.messages) to reconstruct preview messages
from history (the same logic used earlier) and assign its result to
fallbackMessages before falling back to showCopyToast(false); update the branch
around urls.messagesUrl / fallbackMessages checks (referencing urls.messagesUrl,
snapshot.previewMessages, fallbackMessages, record.messages, and
buildPreviewMessagesFromHistory) so reconstructed previews are used for sharing
when available.
- Around line 1786-1790: The active-preview branch uses
latestPreviewPayloadUrlsRef.current unconditionally causing stale durable URLs
after local-only updates (e.g., handleLoadExample) which updates
latestPreviewMessagesRef but never clears payload URLs; update the logic so that
handlers that perform local-only preview replacements (handleLoadExample and any
similar functions that mutate latestPreviewMessagesRef) also clear
latestPreviewPayloadUrlsRef.current (set to null/undefined) and/or mark the
preview as unpublished, and in the id === activeId branch (where urls and
fallbackMessages are set) detect a missing/cleared
latestPreviewPayloadUrlsRef.current and either trigger the existing
republish/generate-durable-url routine (e.g., call
publishPreview/publishPayload/generateDurableUrl with fallbackMessages) before
assigning urls or fall back to forcing republish of fallbackMessages so Share
never uses a stale URL; update references in AIChatPage.tsx to
latestPreviewPayloadUrlsRef, latestPreviewMessagesRef, handleLoadExample, and
the id === activeId branch accordingly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: ea9dbaea-065e-4f50-b381-d32570105c98
📒 Files selected for processing (2)
packages/genui/a2ui-playground/src/pages/AIChatPage.tsxpackages/genui/a2ui-playground/src/utils/publishPayload.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/genui/a2ui-playground/src/utils/publishPayload.ts
Rebased onto upstream/main and re-integrated the Share action into the new icon-button system (lynx-family#2776): a Share2 icon Button in the conversation list that copies a durable Supabase-backed render link. Includes the shared publishPayload util (dedupes DemosPage), the snapshot/history URL resolution, the stale-URL fix on example load, and the playground README.
5c4aaae to
dfae83e
Compare
Summary by CodeRabbit
New Features
Refactor
Documentation
What
Adds a Share action to every conversation in the GenUI playground's Create page. Clicking it copies a durable, Supabase-backed
render.htmllink for that conversation's generated UI to the clipboard, with the existing copy toast — the same artifactPreviewPanelalready produces via "Copy render URL", now available per conversation.Why
Conversations could be renamed and deleted, but not shared. The server already publishes each turn's A2UI payload to Supabase Storage (#2743) and the playground persists the resulting
previewPayloadUrlson each conversation snapshot, so a durable shareable link is essentially already available — it just wasn't surfaced.How it works
handleShareConversation(id)resolves a durablemessagesUrl:previewPayloadUrlspersisted on the conversation snapshot (or the most recent message that has them).POST /a2ui/payload.buildRenderUrl()then turns themessagesUrlinto the shareable link.Changes
src/utils/publishPayload.ts— shared client→Supabase publish helper, extracted fromDemosPage.ConversationListPanel.tsx—onShareprop + a Share pill (reuses existing styling).AIChatPage.tsx—handleShareConversation+ wiring.DemosPage.tsx— refactored to import the shared helper.Checklist
a2ui-playgroundis private; changesets skip private packages)