Skip to content

fix(desktop): avoid drafts from persistent agent hydration - #3900

Closed
MajorTal wants to merge 1 commit into
block:mainfrom
MajorTal:codex/fix-3376-thread-drafts
Closed

fix(desktop): avoid drafts from persistent agent hydration#3900
MajorTal wants to merge 1 commit into
block:mainfrom
MajorTal:codex/fix-3376-thread-drafts

Conversation

@MajorTal

Copy link
Copy Markdown
Contributor

Hey good people, I'm Tal and this is my first contribution to this (awesome) project. It's a bug that was bothering me while dogfooding Buzz. I hope it's in good order...

Summary

Opening a thread with Keep addressed agents active enabled hydrated the composer with programmatic agent mentions. When the thread unmounted, the normal draft lifecycle serialized those mentions as if the user had authored them, creating an Inbox draft without any user input.

This change records the exact editor state produced by persistent-agent hydration and resolves only that unchanged state to empty content when persisting a draft. Any user edit makes the content differ and is preserved normally. Existing mention-only drafts, attachment-only drafts, thread switches, and the post-send recipient state are covered by regression tests.

User impact: viewing a thread no longer creates a ghost draft, while real unsent content and attachments continue to be saved.

Related issue

Fixes #3376.

No duplicate open PRs were found for this issue.

Testing

  • . ./bin/activate-hermit && just ci
  • 10 focused StrictMode production-hook tests in MessageComposerDraftImagePersist.test.mjs
  • 8/8 Chromium tests in persistent-agent-audience.spec.ts, including the full open-thread/leave-thread draft regression
  • Manual local UI smoke test: enabled persistent agents, selected a managed agent, and sent a message through the composer

Manual verification:

  1. Enable Settings → Keep addressed agents active.
  2. Open a thread without typing, then return to Inbox.
  3. Verify the thread does not appear as a draft.
  4. Enter unsent content or add an attachment, leave the thread, and verify the authored draft is retained.

There is no visual or layout change, so a before/after screenshot would be identical; this PR changes only draft-persistence behavior.

@Chessing234

Copy link
Copy Markdown
Contributor

good catch on hydration drafts. does the same path fire for persona reloads after reconnect, or only the initial managed-agent hydrate?

Copy link
Copy Markdown
Contributor Author

Good question! The fix covers the exact composer state created by persistent-agent hydration, including after sending. A persona reload on the same thread does not trigger hydration by itself, but if reconnecting remounts the composer, it goes through the same protected path. I do not have a reconnect-specific test yet, so happy to add one if there is another path I missed.

@MajorTal
MajorTal force-pushed the codex/fix-3376-thread-drafts branch from b3fade7 to 09c8b7d Compare August 5, 2026 10:15
@MajorTal
MajorTal marked this pull request as ready for review August 7, 2026 12:41
@MajorTal
MajorTal requested a review from a team as a code owner August 7, 2026 12:41
@MajorTal
MajorTal force-pushed the codex/fix-3376-thread-drafts branch from 09c8b7d to f3dfc3d Compare August 10, 2026 10:09
Signed-off-by: Tal Weiss <major.tal@gmail.com>
@MajorTal
MajorTal force-pushed the codex/fix-3376-thread-drafts branch from f3dfc3d to 1b44b46 Compare August 12, 2026 14:59
@MajorTal

Copy link
Copy Markdown
Contributor Author

Closing this as superseded by #6315, which merged yesterday.

That PR rebuilt the persistent-agent-audience feature and deleted desktop/src/features/messages/ui/usePersistentAgentMentionHydration.ts — the hook this fix modifies. There is no longer a file to apply it to; landing it now would mean reimplementing against a different architecture rather than rebasing.

More to the point, the bug looks designed out rather than fixed. The mechanism here was that hydration wrote agent mentions into the composer content, so useDraftPersistLifecycle saw non-empty content and persisted it, producing the phantom Inbox drafts in #3376. This PR's approach was to hand the draft lifecycle a draftContentResolverRef so it could tell hydration-authored content apart from something the user typed.

After #6315, addressed agents live in a separate address tray — MessageAgentAddressPrefix renders them as InlineChips — instead of being written into the composer. I checked persistentAgentAudience.ts for any setContent / setComposerContent / insertMention / richText call and there are none. If the audience path never writes content, the draft lifecycle has nothing to persist and the class of bug can't arise.

Removing the mechanism beats compensating for it, so this is the better outcome.

Thanks @Chessing234 for the review here — the keyboard-open case you asked about is moot under the new design for the same reason.

One caveat worth stating plainly: this is a code read, not a reproduction. I can't run the desktop app against a live relay to confirm the symptom is gone, so I've commented on #3376 rather than assuming it can be closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Opening threads creates Inbox drafts when “Keep addressed agents active” is enabled

2 participants