Next-generation AI companion platform with advanced emotional intelligence, real-time chat, and immersive digital relationships.
Girlfriend.cx is a sophisticated AI companionship platform that showcases advanced full-stack development capabilities, integrating cutting-edge AI technologies with modern web development practices. Built with Next.js 14 and TypeScript, this platform demonstrates complex system architecture, real-time communications, distributed computing, and advanced AI integrations.
Built a sophisticated memory system using vector embeddings to maintain conversation context and personality consistency across sessions, enabling truly personalized AI relationships.
// Advanced memory system with semantic search
const storeMemory = async (aiModelId: string, userId: string, content: string) => {
// Generate high-dimensional embeddings for semantic similarity
const embedding = await openai.embeddings.create({
model: "text-embedding-ada-002",
input: content,
encoding_format: "float"
});
// Store in Pinecone with metadata for filtering
await pinecone.upsert({
id: `${aiModelId}-${userId}-${Date.now()}`,
values: embedding.data[0].embedding,
metadata: {
content,
timestamp: Date.now(),
emotional_tone: analyzeSentiment(content),
topic_tags: extractTopics(content),
relationship_stage: determineRelationshipStage(userId)
}
});
};
const retrieveMemories = async (aiModelId: string, userId: string, query: string) => {
// Generate query embedding for similarity search
const queryEmbedding = await openai.embeddings.create({
model: "text-embedding-ada-002",
input: query
});
// Semantic similarity search with contextual filtering
const results = await pinecone.query({
vector: queryEmbedding.data[0].embedding,
topK: 5,
filter: {
aiModelId,
userId,
// Boost recent memories with time decay
timestamp: { $gte: Date.now() - (30 * 24 * 60 * 60 * 1000) }
},
includeMetadata: true
});
// Apply relevance scoring and memory decay
const relevantMemories = results.matches
.filter(match => match.score > 0.8) // High similarity threshold
.map(match => ({
content: match.metadata.content,
relevance: match.score,
recency: calculateRecencyScore(match.metadata.timestamp),
emotional_context: match.metadata.emotional_tone
}))
.sort((a, b) => (b.relevance + b.recency) - (a.relevance + a.recency));
return relevantMemories.slice(0, 3); // Top 3 most relevant memories
};
// Sophisticated conversation context management
class ConversationManager {
private contextWindows = new Map<string, ConversationContext>();
async processMessage(message: string, contextId: string): Promise<AIResponse> {
const context = this.getOrCreateContext(contextId);
// Update conversation state with multi-dimensional analysis
context.addMessage(message);
context.updateMood(await analyzeSentiment(message));
context.extractTopics(await extractNamedEntities(message));
context.trackRelationshipProgression(message);
// Retrieve contextually relevant memories
const relevantMemories = await this.retrieveRelevantMemories(context);
// Generate response with personality consistency
const response = await this.generateResponse({
message,
context,
memories: relevantMemories,
personality: context.aiModel.personality,
mood: context.currentMood,
relationship_stage: context.relationshipStage
});
// Store new interaction for future reference
await this.storeConversationMemory(response, context);
return response;
}
}
// Custom SSE hook with advanced error handling and reconnection
export const useSSEConnection = ({
url, onMessage, maxRetries = 5, retryDelay = 2000
}: SSEOptions) => {
const [isConnected, setIsConnected] = useState(false);
const [retryCount, setRetryCount] = useState(0);
const [connectionQuality, setConnectionQuality] = useState<'excellent' | 'good' | 'poor'>('excellent');
const eventSourceRef = useRef<EventSource | null>(null);
const heartbeatTimeoutRef = useRef<NodeJS.Timeout | null>(null);
const reconnectTimeoutRef = useRef<NodeJS.Timeout | null>(null);
// Exponential backoff with jitter for connection resilience
const backoffDelay = retryDelay * Math.pow(2, retryCount) + (Math.random() * 1000);
// Advanced connection monitoring with heartbeat
const resetHeartbeat = useCallback(() => {
if (heartbeatTimeoutRef.current) {
clearTimeout(heartbeatTimeoutRef.current);
}
heartbeatTimeoutRef.current = setTimeout(() => {
console.warn('SSE heartbeat timeout - reconnecting...');
setConnectionQuality('poor');
eventSourceRef.current?.close();
connect(); // Auto-reconnect on timeout
}, 30000); // 30 second heartbeat timeout
}, []);
// Sophisticated connection management
const connect = useCallback(() => {
if (eventSourceRef.current) {
eventSourceRef.current.close();
}
const eventSource = new EventSource(url);
eventSourceRef.current = eventSource;
eventSource.onopen = () => {
setIsConnected(true);
setRetryCount(0);
setConnectionQuality('excellent');
resetHeartbeat();
};
eventSource.onmessage = (event) => {
try {
const data = JSON.parse(event.data);
// Handle different message types
switch (data.type) {
case 'heartbeat':
resetHeartbeat();
break;
case 'ai_response_chunk':
onMessage?.(data);
break;
case 'typing_indicator':
handleTypingIndicator(data);
break;
case 'connection_quality':
setConnectionQuality(data.quality);
break;
}
} catch (error) {
console.error('Failed to parse SSE message:', error);
}
};
eventSource.onerror = (error) => {
setIsConnected(false);
setConnectionQuality('poor');
if (retryCount < maxRetries) {
console.log(`SSE connection failed, retrying (${retryCount + 1}/${maxRetries})...`);
setRetryCount(prev => prev + 1);
reconnectTimeoutRef.current = setTimeout(() => {
connect();
}, backoffDelay);
} else {
console.error('Max SSE retry attempts reached');
}
};
}, [url, retryCount, maxRetries, onMessage, resetHeartbeat, backoffDelay]);
// Message queuing during disconnections
const [messageQueue, setMessageQueue] = useState<any[]>([]);
const sendMessage = useCallback((message: any) => {
if (isConnected) {
// Send immediately if connected
fetch('/api/chat/send', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(message)
});
} else {
// Queue message for retry when reconnected
setMessageQueue(prev => [...prev, message]);
}
}, [isConnected]);
// Process queued messages on reconnection
useEffect(() => {
if (isConnected && messageQueue.length > 0) {
messageQueue.forEach(sendMessage);
setMessageQueue([]);
}
}, [isConnected, messageQueue, sendMessage]);
return {
isConnected,
connectionQuality,
retryCount,
sendMessage,
reconnect: connect
};
};
// Real-time AI response streaming with typing indicators
const processAIResponseStream = async (userMessage: string, contextId: string) => {
const response = await fetch('/api/ai/stream', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: userMessage, contextId })
});
const reader = response.body?.getReader();
let aiResponse = '';
// Send typing indicator
broadcastTypingIndicator(contextId, true);
try {
while (reader) {
const { done, value } = await reader.read();
if (done) break;
const chunk = new TextDecoder().decode(value);
const lines = chunk.split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = line.slice(6);
if (data === '[DONE]') return;
try {
const parsed = JSON.parse(data);
if (parsed.choices?.[0]?.delta?.content) {
const deltaContent = parsed.choices[0].delta.content;
aiResponse += deltaContent;
// Broadcast incremental response via SSE
broadcastToRoom(contextId, {
type: 'ai_response_chunk',
content: deltaContent,
full_response: aiResponse,
timestamp: Date.now()
});
}
} catch (parseError) {
console.error('Failed to parse AI response chunk:', parseError);
}
}
}
}
} finally {
broadcastTypingIndicator(contextId, false);
}
};
Real-time AI response delivery
Resilient connection handling
Offline message handling
Real-time presence updates
// Distributed service architecture
βββββββββββββββββββ βββββββββββββββββββ
β Main App β β Queue Worker β
β (Vercel) β β (Railway) β
β β β β
β β’ Web Interface βββββΊβ β’ Job Processor β
β β’ API Routes β β β’ Redis Consumerβ
β β’ Real-time SSE β β β’ Status Updatesβ
βββββββββββββββββββ βββββββββββββββββββ
β β
βββββββββββββββββββββββββΌβββββββ
β
βββββββββββββββββββ
β Redis Job Queue β
β (Upstash) β
β β
β β’ Task Queue β
β β’ Rate Limiting β
β β’ Session Store β
βββββββββββββββββββ
// Solana blockchain integration
const processSolanaPayment = async (amount: number, userId: string) => {
const connection = new Connection(process.env.SOLANA_RPC_URL);
const wallet = new PublicKey(userWalletAddress);
const transaction = new Transaction().add(
SystemProgram.transfer({
fromPubkey: wallet,
toPubkey: new PublicKey(process.env.TREASURY_WALLET),
lamports: amount * LAMPORTS_PER_SOL,
})
);
// Sign and confirm transaction
const signature = await sendAndConfirmTransaction(
connection,
transaction,
[payerKeypair]
);
// Update user token balance
await prisma.tokenTransaction.create({
data: {
userId,
amount,
type: 'PURCHASE',
blockchainTxId: signature,
status: 'COMPLETED'
}
});
return signature;
};
Semantic conversation memory using Pinecone vector database for persistent AI relationships
Advanced SSE implementation with connection resilience and message queuing
RunPod integration for scalable AI model training with progress tracking
Solana-based token system with MoonPay integration for seamless payments
Girlfriend.cx demonstrates cutting-edge AI companionship platform development combining vector databases, real-time streaming, blockchain integration, and distributed systems. This project showcases advanced concepts in AI memory systems, microservices architecture, and high-performance real-time communication at scale.