fix(memory): dedupe Composio sources to the latest authorization per identity#2843
Conversation
…identity Memory Sources (Intelligence -> Memory) was rendering every Composio connection row returned by the backend, including superseded re-authorizations. For a user with 3 historical Gmail auths (1 ACTIVE plus 2 EXPIRED), 3 Notion auths, etc., the panel showed 9 zombie rows where only 3 reflected current truth. Group connections in buildRows by (toolkit + identity) and keep the row with the largest createdAt. Identity uses accountEmail ?? workspace ?? username; when the backend does not populate any of those (current Composio passthrough), the group collapses by toolkit alone. Once identity fields ship, two genuinely distinct accounts on the same toolkit will automatically keep separate rows. isMoreRecentConnection is pure recency: larger createdAt wins. An earlier draft used a status-priority rule (ACTIVE/CONNECTED beats EXPIRED regardless of createdAt) but that is wrong: if a user re-authorizes and the fresh authorization then expires, the new EXPIRED is the actual current truth -- they need to re-auth. A stale 'still marked ACTIVE' row from a superseded authorization should not win. A regression test pins this. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThis PR exports and refactors ChangesMemory sources connection deduplication
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested labels
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. Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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.
Inline comments:
In `@app/src/components/intelligence/MemorySources.test.tsx`:
- Around line 24-27: Rename the snake_case local variables in the test to
camelCase: change older_active and newer_expired to olderActive and newerExpired
wherever they are declared and used (the conn(...) calls and the
isMoreRecentConnection(...) assertions) so the variables follow the repo naming
rules; ensure you update both instances in the test that reference conn and
isMoreRecentConnection to use the new names.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 22a88b6b-565c-4c92-9888-4997eb29130f
📒 Files selected for processing (2)
app/src/components/intelligence/MemorySources.test.tsxapp/src/components/intelligence/MemorySources.tsx
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Actionable comments posted: 0 |
graycyrus
left a comment
There was a problem hiding this comment.
@sanil-23 hey! the code looks good to me — the dedupe logic is solid and the test suite is thorough (especially the regression guard pinning that a newer EXPIRED beats an older ACTIVE). CI is still pending on several checks (Frontend Unit Tests, Frontend Coverage, Build Tauri App, all E2E suites), so i'll hold off on approving until those are green. once CI passes, i'll come back and approve this. let me know if anything comes up.
jainsanil18
left a comment
There was a problem hiding this comment.
LGTM — small, well-tested cleanup of zombie Composio rows in Memory sources.
Summary
buildRowsby(toolkit + identity)and keep the largestcreatedAtper group.Problem
composio.list_connectionsreturns every connection record the Composio tenant has ever held for that account — including auths the user has since superseded by re-authorizing. The frontend dropped these intobuildRowsunchanged, so the Memory sources panel grew a row per historical authorization. On one tester's account this expanded to 9 rows (1 ACTIVE + 7 EXPIRED + 1 REVOKED across gmail/github/notion) where only 3 reflected anything actionable. Every duplicate row also shared the same per-toolkitMemorySyncStatusblock, repeating the same "2 chunks · 1d ago" multiple times.Solution
Two-stage filter in
buildRows:${toolkit}::${identity}when identity (accountEmail ?? workspace ?? username) is non-null; otherwise by toolkit alone. Within a group, keep the connection with the largestcreatedAt.isMoreRecentConnectionis pure recency. An earlier draft preferredACTIVE/CONNECTEDover other statuses regardless of timestamp, but that loses the right answer in one critical case: when a user re-authorizes and the fresh auth then expires, the newEXPIREDis the user's current state — the older row that is "still ACTIVE" is stale data from a superseded authorization. A regression test pins this.Once the backend starts populating identity fields, two genuinely different accounts on the same toolkit (e.g. two Gmail addresses) will automatically keep separate rows without further code changes.
Submission Checklist
diff-cover) meet the gate enforced by.github/workflows/coverage.yml. Runpnpm test:coverageandpnpm test:rustlocally; PRs below 80% on changed lines will not merge.docs/TEST-COVERAGE-MATRIX.md, so the matrix doesn't need an update.## Related.docs/RELEASE-MANUAL-SMOKE.mdsurfaces.Impact
app/src/change, no Rust, no schema, no backend.Map<string, ComposioConnection>lookup.accountEmail/workspace/username, distinct accounts on the same toolkit will automatically keep separate rows without further code changes.Related
AI Authored PR Metadata (required for Codex/Linear PRs)
Linear Issue
Commit & Branch
fix/memory-sources-dedupe-by-latestff0dd265🤖 Generated with Claude Code
Summary by CodeRabbit
Tests
Bug Fixes