🚀 Traylinx Cortex v2.2.0 - Frontend Integration Guide¶
What's New¶
Cortex v2.2.0 introduces automatic memory deduplication to prevent storing redundant information. The system now automatically detects and prevents duplicate facts like:
- ❌ "User's name is Sebastian" (stored 5 times)
- ❌ "User has a dog named Olivia" (stored 7 times)
- ❌ "User is interested in the current date and time" (stored 4 times)
✅ Now each fact is stored only once, keeping the oldest version.
🎯 What You Need to Implement¶
Option 1: Add Cleanup Feature (Recommended for Existing Users)¶
Add a one-time cleanup button to help users clean up existing duplicates.
Where to add it: - Settings page - Memory management section - Admin panel
What it does: 1. Shows users how many duplicate memories they have 2. Lets them merge duplicates with one click 3. Displays results (e.g., "Deleted 15 duplicate memories")
📋 Implementation Steps¶
Step 1: Add "Find Duplicates" Button¶
// React/TypeScript example
async function findDuplicates() {
const response = await fetch(
`${API_BASE_URL}/v1/memory/duplicates?app_id=${appId}`,
{
headers: {
'Authorization': `Bearer ${userToken}`
}
}
);
const data = await response.json();
// data.groups = array of duplicate groups
// data.total_duplicates = total count
return data;
}
Response format:
{
"groups": [
{
"canonical_id": "uuid-1",
"canonical_content": "User's name is Sebastian",
"duplicates": [
{
"id": "uuid-2",
"content": "User is called Sebastian",
"created_at": "2025-12-02T14:30:00Z",
"similarity_to_canonical": 0.92
}
]
}
],
"total_duplicates": 15
}
Step 2: Show Preview (Optional but Recommended)¶
Display what will be merged:
{duplicateGroups.map(group => (
<div key={group.canonical_id} className="duplicate-group">
<div className="canonical">
✅ Keep: {group.canonical_content}
</div>
{group.duplicates.map(dup => (
<div key={dup.id} className="duplicate">
❌ Delete: {dup.content} (similarity: {(dup.similarity_to_canonical * 100).toFixed(0)}%)
</div>
))}
</div>
))}
Step 3: Add "Merge Duplicates" Button¶
async function mergeDuplicates() {
const response = await fetch(
`${API_BASE_URL}/v1/memory/deduplicate?app_id=${appId}`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${userToken}`
}
}
);
const result = await response.json();
// result.deleted_count = number of memories deleted
// result.groups_merged = number of groups merged
return result;
}
Response format:
🎨 UI/UX Recommendations¶
Simple Approach (Minimal UI)¶
┌─────────────────────────────────────┐
│ Memory Cleanup │
├─────────────────────────────────────┤
│ Found 15 duplicate memories │
│ │
│ [Clean Up Duplicates] │
└─────────────────────────────────────┘
Advanced Approach (With Preview)¶
┌─────────────────────────────────────┐
│ Memory Cleanup │
├─────────────────────────────────────┤
│ Found 5 groups with 15 duplicates │
│ │
│ Group 1: │
│ ✅ Keep: User's name is Sebastian │
│ ❌ Delete: User is called Sebastian │
│ ❌ Delete: User is referred to as...│
│ │
│ [Show All Groups] [Merge All] │
└─────────────────────────────────────┘
📝 Sample Code (Complete Component)¶
import { useState } from 'react';
interface DuplicateGroup {
canonical_id: string;
canonical_content: string;
duplicates: Array<{
id: string;
content: string;
similarity_to_canonical: number;
}>;
}
export function MemoryCleanup({ token, appId }: { token: string; appId: string }) {
const [loading, setLoading] = useState(false);
const [groups, setGroups] = useState<DuplicateGroup[]>([]);
const [totalDuplicates, setTotalDuplicates] = useState(0);
const [result, setResult] = useState<{ deleted: number; merged: number } | null>(null);
async function findDuplicates() {
setLoading(true);
try {
const response = await fetch(
`https://api.traylinx.com/v1/memory/duplicates?app_id=${appId}`,
{ headers: { 'Authorization': `Bearer ${token}` } }
);
const data = await response.json();
setGroups(data.groups);
setTotalDuplicates(data.total_duplicates);
} catch (error) {
console.error('Failed to find duplicates:', error);
} finally {
setLoading(false);
}
}
async function mergeDuplicates() {
if (!confirm(`Delete ${totalDuplicates} duplicate memories?`)) return;
setLoading(true);
try {
const response = await fetch(
`https://api.traylinx.com/v1/memory/deduplicate?app_id=${appId}`,
{
method: 'POST',
headers: { 'Authorization': `Bearer ${token}` }
}
);
const data = await response.json();
setResult({ deleted: data.deleted_count, merged: data.groups_merged });
setGroups([]);
setTotalDuplicates(0);
} catch (error) {
console.error('Failed to merge duplicates:', error);
} finally {
setLoading(false);
}
}
return (
<div className="memory-cleanup">
<h2>Memory Cleanup</h2>
{!groups.length && !result && (
<button onClick={findDuplicates} disabled={loading}>
{loading ? 'Scanning...' : 'Find Duplicates'}
</button>
)}
{groups.length > 0 && (
<>
<p>Found {totalDuplicates} duplicate memories in {groups.length} groups</p>
<button onClick={mergeDuplicates} disabled={loading}>
{loading ? 'Merging...' : 'Clean Up Duplicates'}
</button>
</>
)}
{result && (
<div className="success">
✅ Deleted {result.deleted} duplicate memories ({result.merged} groups merged)
</div>
)}
</div>
);
}
🔧 Configuration (Optional)¶
If you want to expose deduplication settings to admins, these are the backend env vars:
MEMORY_DEDUP_SIMILARITY_THRESHOLD=0.85 # How similar = duplicate (0-1)
MEMORY_DEDUP_LLM_CHECK_ENABLED=true # Use AI to verify borderline cases
You don't need to expose these in the UI - defaults work well.
✅ Testing Checklist¶
- [ ] Can find duplicates (GET endpoint works)
- [ ] Shows correct count of duplicates
- [ ] Can merge duplicates (POST endpoint works)
- [ ] Shows success message after merge
- [ ] Handles errors gracefully
- [ ] Works with user authentication
- [ ] Respects app_id filtering
📚 Documentation References¶
- Full API Docs:
docs/./api_reference.md(search for "duplicates") - Quick Reference:
docs/memory/README.md(see "Memory Deduplication" section) - Changelog:
docs/memory/CHANGELOG.md(v2.2.0 section)
🎯 Priority¶
Low Priority - This is a cleanup feature for existing users. New facts are automatically deduplicated, so this is only needed to clean up historical duplicates.
Suggested Timeline: - Week 1: Add simple "Find & Merge" button - Week 2: Add preview UI (optional) - Week 3: Add to settings/admin panel
❓ Questions?¶
- Check
docs/./api_reference.mdfor complete endpoint documentation - See
docs/memory/README.mdfor code examples - Backend is already deployed and working - just add the UI!
TL;DR: Add two buttons: "Find Duplicates" (GET) and "Clean Up" (POST). Show count and success message. That's it! 🎉