import { Memory } from "../../src/memory"; import dotenv from "dotenv"; // Load environment variables dotenv.config(); async function dateDeeductionDemo() { console.log("šŸ“… Date Deduction Agent Demo"); console.log("=" .repeat(50)); if (!process.env.OPENAI_API_KEY) { console.error("Error: OPENAI_API_KEY environment variable is required"); process.exit(1); } const memory = new Memory({ embedder: { provider: "openai", config: { apiKey: process.env.OPENAI_API_KEY, model: "text-embedding-3-small", }, }, vectorStore: { provider: "memory", config: { dimension: 1536, }, }, llm: { provider: "openai_structured", config: { apiKey: process.env.OPENAI_API_KEY, model: "gpt-4o-mini", }, }, historyDbPath: ":memory:", }); const userId = "date-demo-user"; console.log("\nšŸ“ Setting up test scenario with temporal references..."); // Add memories with various temporal references const temporalMemories = [ // Explicit dates { role: "user", content: "On March 15th, 2024, I had my performance review with Sarah" }, { role: "assistant", content: "That sounds important! How did it go?" }, // Relative dates (these need context to determine actual dates) { role: "user", content: "Yesterday I finished the project proposal" }, { role: "user", content: "Last Tuesday we had the team meeting about budget" }, { role: "user", content: "Earlier this week I spoke with the client" }, // Events with contextual timing { role: "user", content: "The server went down during the demo" }, { role: "assistant", content: "Oh no! What happened?" }, { role: "user", content: "It was right when we were showing the new features to the investors" }, // Mixed temporal references { role: "user", content: "I submitted my report three days ago, just before the deadline" }, { role: "user", content: "The client called this morning about the contract changes" }, // Events without explicit timing { role: "user", content: "I got promoted to senior developer" }, { role: "assistant", content: "Congratulations! That's fantastic news!" }, { role: "user", content: "Thanks! It's been a long journey since I started here" }, ]; // Add memories with realistic timing gaps to simulate real conversation for (let i = 0; i < temporalMemories.length; i++) { await memory.add([temporalMemories[i]], { userId }); // Small delay to create different timestamps await new Promise(resolve => setTimeout(resolve, 100)); } console.log(`āœ… Added ${temporalMemories.length} temporal memories`); // Test scenarios for date deduction const dateQueries = [ { query: "When did I have my performance review?", description: "Explicit date query - should find exact date", expectedOutcome: "Should identify March 15th, 2024 from explicit mention" }, { query: "When did I finish the project proposal?", description: "Relative date query - needs context to determine actual date", expectedOutcome: "Should analyze 'yesterday' relative to message timestamp" }, { query: "What date was the team meeting about budget?", description: "Relative day reference - needs week context", expectedOutcome: "Should calculate 'last Tuesday' from context" }, { query: "When did the server go down?", description: "Event timing without explicit date - needs inference", expectedOutcome: "Should deduce from conversation context about demo timing" }, { query: "When did I get promoted?", description: "Event without temporal references - challenging case", expectedOutcome: "Should indicate uncertainty but provide estimated timeframe" } ]; for (let i = 0; i < dateQueries.length; i++) { const testCase = dateQueries[i]; console.log(`\n=== Test ${i + 1}: ${testCase.description} ===`); console.log(`šŸ” Query: "${testCase.query}"`); console.log(`šŸ“‹ Expected: ${testCase.expectedOutcome}`); try { // Search for memories and use agents to deduce dates const searchResult = await memory.search(testCase.query, { userId, useSearchAgents: true, enableMultihop: false, // Focus on single-hop for date deduction maxAgentSteps: 4, // Allow more steps for thorough date analysis limit: 5, reasoningCustomInstructions: `Focus on finding temporal information and dates. If you find relevant memories, always use deduce_memory_date to extract specific timing information. Prioritize date deduction for any memory that could contain temporal references.` }); console.log(`šŸ“Š Initial Results: ${searchResult.results.length} memories found`); // Display initial results searchResult.results.slice(0, 2).forEach((result, idx) => { console.log(` ${idx + 1}. ${(result.memory || '[No content]').substring(0, 80)}... (Score: ${result.score?.toFixed(3)})`); }); // Analyze agent activity for date deduction if (searchResult.agentAnalysis) { console.log(`\nšŸ¤– Agent Analysis:`); if (searchResult.agentAnalysis.decision) { console.log(` - Additional steps needed: ${searchResult.agentAnalysis.decision.needsAdditionalSteps}`); console.log(` - Reasoning: ${searchResult.agentAnalysis.decision.reasoning}`); // Look for date deduction steps const dateSteps = searchResult.agentAnalysis.stepResults?.filter(step => step.action === 'deduce_memory_date' ) || []; if (dateSteps.length > 0) { console.log(` šŸ“… Date Deduction Performed: ${dateSteps.length} analysis(es)`); dateSteps.forEach((step, stepIdx) => { console.log(` šŸ”¬ Analysis ${stepIdx + 1}:`); console.log(` • Success: ${step.success}`); if (step.success && step.results && step.results.length > 0) { const analysis = step.results[0]; if (analysis.type === 'date_analysis') { console.log(` • Memory: ${analysis.originalMemory.substring(0, 60)}...`); console.log(` • Deduced Date: ${analysis.analysis.actualDate || 'Unable to determine'}`); console.log(` • Confidence: ${analysis.analysis.confidence}`); console.log(` • Reasoning: ${analysis.analysis.reasoning}`); if (analysis.analysis.evidence && analysis.analysis.evidence.length > 0) { console.log(` • Evidence: ${analysis.analysis.evidence.slice(0, 2).join(', ')}`); } if (analysis.analysis.relativeReferences && analysis.analysis.relativeReferences.length > 0) { console.log(` • Relative refs: ${analysis.analysis.relativeReferences.join(', ')}`); } if (analysis.analysis.timeRange && (analysis.analysis.timeRange.start || analysis.analysis.timeRange.end)) { console.log(` • Time range: ${analysis.analysis.timeRange.start || 'unknown'} to ${analysis.analysis.timeRange.end || 'unknown'}`); } } } }); } else { console.log(` šŸ“… No date deduction performed`); } } } else { console.log(` - No agent analysis available`); } } catch (error) { console.error(`āŒ Test ${i + 1} failed:`, error); } // Add delay between tests await new Promise(resolve => setTimeout(resolve, 1500)); } // Test comprehensive date analysis with chat console.log(`\n=== Comprehensive Chat Test with Date Analysis ===`); try { const chatResult = await memory.chat( "Give me a timeline of the key events that happened recently, with specific dates when possible", { userId, enableMultihop: true, maxHops: 2, maxAgentSteps: 5, responseCustomInstructions: `Create a timeline format with dates. For each event, include: - The specific date if determined - The confidence level in that date - The original context or reference Be explicit about which dates are exact vs. estimated.`, reasoningCustomInstructions: `Focus on temporal analysis: - Use deduce_memory_date for any memory that might contain timing information - Look for both explicit and relative date references - Prioritize finding actual dates over general event descriptions` } ); console.log(`šŸ’¬ Timeline Analysis Response:`); console.log("─".repeat(60)); console.log(chatResult.response); console.log("─".repeat(60)); console.log(`\nšŸ“Š Chat Metadata:`); console.log(` - Sources used: ${chatResult.metadata.sourcesCount}`); console.log(` - Processing time: ${chatResult.metadata.processingTimeMs}ms`); console.log(` - Hops used: ${chatResult.metadata.hopsUsed}`); // Show date analysis results if any const dateAnalysisResults = chatResult.sources.filter(source => (source as any).type === 'date_analysis' || source.metadata?.source === 'date_deduction_agent' ); if (dateAnalysisResults.length > 0) { console.log(`\nšŸ“… Date Analysis Summary: ${dateAnalysisResults.length} temporal analysis(es)`); dateAnalysisResults.forEach((result, idx) => { console.log(` ${idx + 1}. ${result.metadata?.actualDate || 'Date unknown'} - ${result.metadata?.confidence || 'Low'} confidence`); if (result.metadata?.reasoning) { console.log(` Reasoning: ${result.metadata.reasoning.substring(0, 100)}...`); } }); } } catch (error) { console.error("āŒ Comprehensive chat test failed:", error); } // Clean up await memory.reset(); console.log("\nāœ… Date Deduction Agent demo completed!"); console.log("\nšŸŽÆ Key Features Demonstrated:"); console.log(" • Automatic date deduction from memory content"); console.log(" • Analysis of relative time references ('yesterday', 'last week')"); console.log(" • Context-aware temporal reasoning using conversation flow"); console.log(" • Confidence scoring for date accuracy"); console.log(" • Integration with search agents for temporal queries"); console.log(" • Timeline creation with specific dates when possible"); } // Run the demo if (require.main === module) { dateDeeductionDemo().catch(console.error); } export { dateDeeductionDemo };