Skip to content

Stop DedupConversationFilter from keeping retweets of mid-thread replies - #75

Closed
Pitchfork-and-Torch wants to merge 19 commits into
mainfrom
cursor/convo-collapse-rt-reply-clean-8d87
Closed

Stop DedupConversationFilter from keeping retweets of mid-thread replies#75
Pitchfork-and-Torch wants to merge 19 commits into
mainfrom
cursor/convo-collapse-rt-reply-clean-8d87

Conversation

@Pitchfork-and-Torch

Copy link
Copy Markdown
Owner

DedupConversationFilter keys replies by min(ancestors) and ancestor-less retweets by get_original_tweet_id(). That only collapses a retweet of the root. A retweet of a mid-thread reply keys to the reply id, so the RT and the rest of the thread both survive post-selection.

Proof

  • Entry: DedupConversationFilter::get_conversation_id (phoenix post-selection)
  • Sink: For You TopK after VF; one kept post per conversation_id
  • Break: RT of reply 11 with ancestors [2, 1] keys to 11; the reply keys to 1
  • Viewer: a viral reply-RT and another post from the same thread both take For You slots
  • Twin: existing tests already collapse RT-of-root (retweeted_tweet_id == min(ancestors)); Thunder fills ancestors on replies, not on retweets

This is not xai-org#97/xai-org#102 (gap expansion / unhydrated grandparents). Not xai-org#99 (self-reply chains). Not xai-org#101/xai-org#111 (muted/blocked ancestors). Not xai-org#179 (seen/served parent). Not xai-org#180 (Phoenix VF parents).

Fix: map each slate tweet and ancestor onto the smallest conversation root already present. Ancestor-less retweets use that root when the original is on the slate as a reply or as someone's ancestor. Unrelated originals stay on their own tweet id. Replies still key by min(ancestors), so shallow [2] vs [2, 1] stay two conversations.

One file on current main. Replaces contaminated xai-org#189 (19 files, behind main).

Tests: RT of the reply itself, RT of a reply listed as a sibling ancestor, unrelated RT unchanged, existing root-RT and multi-conversation cases unchanged.

cargo test cannot run here. Public dump has no Home Mixer manifest. Standalone rustc model of old vs new keying passed 5/5.

Open in Web Open in Cursor 

CI agent and others added 19 commits August 14, 2026 20:55
in_network_ids is passed to the VF client without deduplication, while
oon_ids is deduped four lines below. retweeted_tweet_id is pushed for
every candidate that has one, so the same ID repeats once per retweet of
a given post — most often when that post is going viral.

Neither VfClient implementation dedupes its input: StratoVfClient builds
one call per element, and XaiVfClient chunks by XAI_VF_MAX_BATCH_SIZE, so
duplicates consume batch slots and can force an extra round trip.

Not a correctness issue — results collapse into a HashMap keyed by tweet
ID — but redundant work on the For You serving path.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Deduplicate in_network_ids before VF lookup
DedupConversationFilter keyed ancestor-less retweets by original tweet id,
so an RT of a mid-thread reply did not share the thread's min(ancestors)
key and both survived post-selection. Map slate tweets and ancestors to
the smallest conversation root already present, then use that root for
retweets of those posts.

Co-authored-by: Jon Bailey <Pitchfork-and-Torch@users.noreply.github.com>
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.

4 participants