import { Memory } from "../../src/memory"; import { Message } from "../../src/types"; import dotenv from "dotenv"; // Load environment variables dotenv.config(); // Check for required env vars if (!process.env.OPENAI_API_KEY) { console.error("Error: OPENAI_API_KEY environment variable is required"); process.exit(1); } async function runMultihopDemo() { console.log("šŸš€ Starting Multihop Agents & Custom Instructions Demo"); // Create Memory instance 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-3.5-turbo", }, }, historyDbPath: ":memory:", }); const userId = "multihop-demo-user"; // Create a complex conversation scenario console.log("\n=== Setting up Complex Conversation Scenario ==="); const conversation1: Message[] = [ { role: "user", content: "I'm starting a new project called ProjectAlpha." }, { role: "assistant", content: "That sounds exciting! Tell me more about ProjectAlpha." }, { role: "user", content: "It's a mobile app for fitness tracking." }, { role: "assistant", content: "Great idea! What features are you planning?" }, { role: "user", content: "I want to track workouts, nutrition, and sleep patterns." }, ]; const conversation2: Message[] = [ { role: "user", content: "For ProjectAlpha, I've decided to use React Native." }, { role: "assistant", content: "React Native is a good choice for cross-platform development." }, { role: "user", content: "I'll also need a backend. Thinking about Node.js with Express." }, { role: "assistant", content: "That's a solid stack. What about the database?" }, { role: "user", content: "Probably MongoDB for storing user data and workout logs." }, ]; const conversation3: Message[] = [ { role: "user", content: "I found a great designer for ProjectAlpha - Sarah Martinez." }, { role: "assistant", content: "Having a good designer is crucial for user experience." }, { role: "user", content: "Sarah specializes in mobile UI/UX and has worked on fitness apps before." }, { role: "assistant", content: "Perfect match! When will she start?" }, { role: "user", content: "Sarah will begin next week and work on the initial mockups." }, ]; // Add conversations separately to create a realistic scenario console.log("Adding conversation 1 (project concept)..."); await memory.add(conversation1, { userId, infer: true }); console.log("Adding conversation 2 (technical stack)..."); await memory.add(conversation2, { userId, infer: true }); console.log("Adding conversation 3 (team member)..."); await memory.add(conversation3, { userId, infer: true }); // Test 1: Search without multihop console.log("\n=== Test 1: Standard Search (No Multihop) ==="); const query1 = "Tell me everything about ProjectAlpha"; const standardSearch = await memory.search(query1, { userId, useSearchAgents: true, enableMultihop: false, maxAgentSteps: 3 }); console.log(`\nšŸ” Query: "${query1}"`); console.log(`Standard search found: ${standardSearch.results.length} results`); console.log("Agent analysis:", standardSearch.agentAnalysis?.decision?.reasoning || "No analysis"); // Test 2: Search with multihop console.log("\n=== Test 2: Multihop Search Analysis ==="); const multihopSearch = await memory.search(query1, { userId, useSearchAgents: true, enableMultihop: true, maxHops: 3, maxAgentSteps: 2 }); console.log(`\nšŸ”„ Query: "${query1}" (with multihop)`); console.log(`Multihop search found: ${multihopSearch.results.length} results`); if (multihopSearch.agentAnalysis?.isMultihop && multihopSearch.agentAnalysis.multihopResults) { console.log(`\nMultihop Analysis Summary:`); multihopSearch.agentAnalysis.multihopResults.forEach((hop, index) => { console.log(` Hop ${hop.hopNumber}: ${hop.decision.reasoning}`); console.log(` - Additional steps needed: ${hop.decision.needsAdditionalSteps}`); console.log(` - Another hop needed: ${hop.decision.needsAnotherHop}`); console.log(` - Found ${hop.additionalResults.length} additional results`); }); } // Test 3: Chat without custom instructions console.log("\n=== Test 3: Standard Chat Response ==="); const chatQuery = "Summarize ProjectAlpha for a potential investor"; const standardChat = await memory.chat(chatQuery, { userId, useSearchAgents: true, enableMultihop: true, maxHops: 2 }); console.log(`\nšŸ’¬ Query: "${chatQuery}"`); console.log(`Response: ${standardChat.response}`); console.log(`Sources used: ${standardChat.metadata.sourcesCount}`); console.log(`Multihop enabled: ${standardChat.metadata.multihopEnabled}`); console.log(`Hops used: ${standardChat.metadata.hopsUsed}`); // Test 4: Chat with custom instructions console.log("\n=== Test 4: Chat with Custom Instructions ==="); const customInstructions = ` Please respond as a technical project manager preparing a brief for stakeholders. Format your response with clear sections: Overview, Technical Stack, Team, and Next Steps. Keep the tone professional but enthusiastic. Focus on the business value and technical feasibility. `; const customChat = await memory.chat(chatQuery, { userId, useSearchAgents: true, enableMultihop: true, maxHops: 2, customInstructions }); console.log(`\nšŸ’¼ Query: "${chatQuery}" (with custom instructions)`); console.log(`Custom instructions: ${customInstructions.trim()}`); console.log(`\nResponse: ${customChat.response}`); console.log(`Sources used: ${customChat.metadata.sourcesCount}`); console.log(`Custom instructions applied: ${customChat.metadata.customInstructions ? 'Yes' : 'No'}`); // Test 5: Complex multihop query console.log("\n=== Test 5: Complex Multihop Query ==="); const complexQuery = "What are the relationships between the people and technologies mentioned in my project conversations?"; const complexSearch = await memory.search(complexQuery, { userId, useSearchAgents: true, enableMultihop: true, maxHops: 3, maxAgentSteps: 3, includeContext: true }); console.log(`\n🧠 Complex Query: "${complexQuery}"`); console.log(`Found: ${complexSearch.results.length} results`); if (complexSearch.agentAnalysis?.isMultihop) { console.log(`\nComplex Multihop Analysis:`); complexSearch.agentAnalysis.multihopResults?.forEach((hop) => { console.log(` Hop ${hop.hopNumber}:`); console.log(` - Analysis: ${hop.decision.reasoning}`); console.log(` - Steps taken: ${hop.stepResults.map(s => s.action).join(', ')}`); }); } // Test 6: Chat with complex query and custom instructions console.log("\n=== Test 6: Complex Chat with Custom Instructions ==="); const complexChatInstructions = ` Act as a senior software architect reviewing this project. Analyze the technology choices, team composition, and provide recommendations. Structure your response as: Technology Analysis, Team Assessment, Risk Analysis, Recommendations. Be detailed and provide specific technical insights. `; const complexChat = await memory.chat(complexQuery, { userId, useSearchAgents: true, enableMultihop: true, maxHops: 2, customInstructions: complexChatInstructions, includeContext: true }); console.log(`\nšŸ—ļø Complex Query: "${complexQuery}" (architect perspective)`); console.log(`\nResponse: ${complexChat.response}`); // Performance comparison console.log("\n=== Performance Comparison ==="); console.log(`Standard search time: ${standardSearch.results.length} results`); console.log(`Multihop search time: ${multihopSearch.results.length} results`); console.log(`Standard chat processing: ${standardChat.metadata.processingTimeMs}ms`); console.log(`Custom chat processing: ${customChat.metadata.processingTimeMs}ms`); // Cleanup console.log("\n=== Cleanup ==="); await memory.reset(); console.log("āœ… Multihop & Custom Instructions demo completed successfully!"); } // Run the demo runMultihopDemo() .catch(error => { console.error("Error in multihop demo:", error); process.exit(1); });