diff --git a/bootstraprag/templates/mem0/langchain_with_memory/.env b/bootstraprag/templates/mem0/langchain_with_memory/.env new file mode 100644 index 0000000..84f07f1 --- /dev/null +++ b/bootstraprag/templates/mem0/langchain_with_memory/.env @@ -0,0 +1,9 @@ +QDRANT_API_KEY=th3s3cr3tk3y +QDRANT_URL=http://localhost:6333 +COLLECTION_NAME=langchain-agent-with-memory + +OLLAMA_MODEL=llama3.2:latest +OLLAMA_EMBED_MODEL=nomic-embed-text:latest + +USER_ID=pavan_mantha + diff --git a/bootstraprag/templates/mem0/langchain_with_memory/__init__.py b/bootstraprag/templates/mem0/langchain_with_memory/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bootstraprag/templates/mem0/langchain_with_memory/chat_agent_with_memory.py b/bootstraprag/templates/mem0/langchain_with_memory/chat_agent_with_memory.py new file mode 100644 index 0000000..aadf828 --- /dev/null +++ b/bootstraprag/templates/mem0/langchain_with_memory/chat_agent_with_memory.py @@ -0,0 +1,150 @@ +import logging +import os + +from typing import List, Dict +from langchain_ollama import ChatOllama +from langchain_core.messages import SystemMessage, HumanMessage +from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder +from mem0 import Memory +from dotenv import load_dotenv, find_dotenv + +load_dotenv(find_dotenv()) + +# Configure logging +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + + +class TravelAgentAI: + def __init__(self, config: Dict): + self.config = config + + # Initialize LLM and Memory + logger.info("Initializing LLM and Memory...") + self.llm = ChatOllama(model=config["llm"]["config"]["model"]) + self.memory = Memory.from_config(config_dict=config) + logger.info("LLM and Memory initialized successfully.") + + # Define the prompt + logger.info("Defining prompt...") + self.prompt = ChatPromptTemplate.from_messages([ + SystemMessage(content="""You are a helpful travel agent AI. Use the provided context to personalize your responses and remember user preferences and past interactions. + Provide travel recommendations, itinerary suggestions, and answer questions about destinations. + If you don't have specific information, you can make general suggestions based on common travel knowledge."""), + MessagesPlaceholder(variable_name="context"), + HumanMessage(content="{input}") + ]) + logger.info("Prompt defined successfully.") + + def retrieve_context(self, query: str, user_id: str) -> List[Dict]: + """Retrieve relevant context from Memory.""" + logger.info(f"Retrieving context for query: {query}, user_id: {user_id}") + memories = self.memory.search(query, user_id=user_id) + serialized_memories = ' '.join([mem["memory"] for mem in memories]) + logger.info(f"Serialized memories: {serialized_memories}") + context = [ + { + "role": "system", + "content": f"Relevant information: {serialized_memories}" + }, + { + "role": "user", + "content": query + } + ] + logger.info(f"Context retrieved: {context}") + return context + + def generate_response(self, input: str, context: List[Dict]) -> str: + """Generate a response using the language model.""" + logger.info(f"Generating response for input: {input} with context: {context}") + chain = self.prompt | self.llm + response = chain.invoke({ + "context": context, + "input": input + }) + logger.info(f"Generated response: {response.content}") + return response.content + + def save_interaction(self, user_id: str, user_input: str, assistant_response: str): + """Save the interaction to Memory.""" + logger.info(f"Saving interaction for user_id: {user_id}") + interaction = [ + { + "role": "user", + "content": user_input + }, + { + "role": "assistant", + "content": assistant_response + } + ] + self.memory.add(interaction, user_id=user_id) + logger.info(f"Interaction saved: {interaction}") + + def chat_turn(self, user_input: str, user_id: str) -> str: + """Handle a single turn of chat.""" + logger.info(f"Starting chat turn for user_id: {user_id} with input: {user_input}") + + # Retrieve context + context = self.retrieve_context(user_input, user_id) + + # Generate response + response = self.generate_response(user_input, context) + + # Save interaction + self.save_interaction(user_id, user_input, response) + + logger.info(f"Chat turn completed. Response: {response}") + return response + + +if __name__ == "__main__": + logger.info("Welcome to your personal Travel Agent Planner! How can I assist you with your travel plans today?") + user_id = os.environ.get("USER_ID") + + # Load the configuration + logger.info("Loading configuration...") + config = { + "vector_store": { + "provider": "qdrant", + "config": { + "collection_name": "langchain-agent-with-memory", + "url": "http://localhost:6333", + "api_key": "th3s3cr3tk3y", + "embedding_model_dims": 768, + }, + }, + "llm": { + "provider": "ollama", + "config": { + "model": "llama3.2:latest", + "temperature": 0, + "max_tokens": 8000, + "ollama_base_url": "http://localhost:11434", + }, + }, + "embedder": { + "provider": "ollama", + "config": { + "model": "nomic-embed-text:latest", + "ollama_base_url": "http://localhost:11434", + }, + }, + } + logger.info("Configuration loaded successfully.") + + # Instantiate the TravelAgentAI class + logger.info("Instantiating TravelAgentAI...") + travel_agent_ai = TravelAgentAI(config) + logger.info("TravelAgentAI instantiated successfully.") + + while True: + user_input = input("You: ") + if user_input.lower() in ['quit', 'exit', 'bye']: + logger.info("Travel Agent: Thank you for using our travel planning service. Have a great trip!") + break + + logger.info(f"Processing user input: {user_input}") + response = travel_agent_ai.chat_turn(user_input, user_id) + logger.info(f"Travel Agent: {response}") diff --git a/bootstraprag/templates/mem0/langchain_with_memory/mem0_configs.py b/bootstraprag/templates/mem0/langchain_with_memory/mem0_configs.py new file mode 100644 index 0000000..7b7ee57 --- /dev/null +++ b/bootstraprag/templates/mem0/langchain_with_memory/mem0_configs.py @@ -0,0 +1,38 @@ +import os +import logging +from dotenv import load_dotenv, find_dotenv + +load_dotenv(find_dotenv()) +# Configure logging +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +logger.info("Loading the configuration") + +config = { + "vector_store": { + "provider": "qdrant", + "config": { + "collection_name": os.environ.get("COLLECTION_NAME"), + "url": os.environ.get("QDRANT_URL"), + "api_key": os.environ.get("QDRANT_API_KEY"), + "embedding_model_dims": 768, + }, + }, + "llm": { + "provider": "ollama", + "config": { + "model": os.environ.get("OLLAMA_MODEL"), + "temperature": 0, + "max_tokens": 8000, + "ollama_base_url": "http://localhost:11434", + }, + }, + "embedder": { + "provider": "ollama", + "config": { + "model": os.environ.get("OLLAMA_EMBED_MODEL"), + "ollama_base_url": "http://localhost:11434", + }, + }, +} \ No newline at end of file diff --git a/bootstraprag/templates/mem0/langchain_with_memory/requirements.txt b/bootstraprag/templates/mem0/langchain_with_memory/requirements.txt new file mode 100644 index 0000000..13528c4 --- /dev/null +++ b/bootstraprag/templates/mem0/langchain_with_memory/requirements.txt @@ -0,0 +1,4 @@ +langchain +langchain-ollama +mem0ai +python-dotenv \ No newline at end of file diff --git a/bootstraprag/templates/mem0/react_agent_with_memory/.env b/bootstraprag/templates/mem0/react_agent_with_memory/.env index d967bcc..e577fc6 100644 --- a/bootstraprag/templates/mem0/react_agent_with_memory/.env +++ b/bootstraprag/templates/mem0/react_agent_with_memory/.env @@ -21,6 +21,6 @@ DEBUG = 10 NOTSET = 0 LIT_SERVER_PORT=8000 -LIT_SERVER_WORKERS_PER_DEVICE=4 +LIT_SERVER_WORKERS_PER_DEVICE=1 IS_EVALUATION_NEEDED=true diff --git a/bootstraprag/templates/mem0/react_agent_with_memory/mem0_configs.py b/bootstraprag/templates/mem0/react_agent_with_memory/mem0_configs.py deleted file mode 100644 index bc227db..0000000 --- a/bootstraprag/templates/mem0/react_agent_with_memory/mem0_configs.py +++ /dev/null @@ -1,36 +0,0 @@ -import os -import uuid -from dotenv import load_dotenv, find_dotenv - -load_dotenv(find_dotenv()) - -context = { - "user_id": "pavan_mantha", - "agent_id": "react_agent", - "run_id": str(uuid.uuid4()), -} - -config = { - "vector_store": { - "provider": "qdrant", - "config": { - "collection_name": os.environ.get('COLLECTION_NAME'), - "url": os.environ.get('QDRANT_URL'), - "api_key": os.environ.get('QDRANT_API_KEY'), - "embedding_model_dims": 768, # Change this according to your local model's dimensions - }, - }, - "llm": { - "provider": "ollama", - "config": { - "model": "llama3.2:latest", - "temperature": 0.2, - "max_tokens": 1500, - }, - }, - "embedder": { - "provider": "ollama", - "config": {"model": "nomic-embed-text:latest"}, - }, - "version": "v1.1", -} \ No newline at end of file diff --git a/bootstraprag/templates/mem0/react_agent_with_memory/react_agent_with_query_engine.py b/bootstraprag/templates/mem0/react_agent_with_memory/react_agent_with_query_engine.py index 10c6fc9..491c3e5 100644 --- a/bootstraprag/templates/mem0/react_agent_with_memory/react_agent_with_query_engine.py +++ b/bootstraprag/templates/mem0/react_agent_with_memory/react_agent_with_query_engine.py @@ -12,11 +12,11 @@ from llama_index.core.base.response.schema import Response, StreamingResponse, AsyncStreamingResponse, PydanticResponse from dotenv import load_dotenv, find_dotenv from typing import Union -from mem0_configs import config, context from llama_index.memory.mem0 import Mem0Memory import qdrant_client import logging import os +import uuid _ = load_dotenv(find_dotenv()) @@ -30,7 +30,7 @@ class ReActWithQueryEngine: ] def __init__(self, input_dir: str, similarity_top_k: int = 3, chunk_size: int = 128, chunk_overlap: int = 100, - show_progress: bool = False, no_of_iterations: int = 5, required_exts: list[str] = ['.pdf', '.txt']): + show_progress: bool = False, no_of_iterations: int = 20, required_exts: list[str] = ['.pdf', '.txt']): self.index_loaded = False self.similarity_top_k = similarity_top_k self.input_dir = input_dir @@ -43,6 +43,38 @@ def __init__(self, input_dir: str, similarity_top_k: int = 3, chunk_size: int = self.required_exts = required_exts # the mem0 configs for llamaindex + context = { + "user_id": "pavan_mantha", + "agent_id": "react_agent", + "run_id": str(uuid.uuid4()), + } + + config = { + "vector_store": { + "provider": "qdrant", + "config": { + "collection_name": "react-agent-with-memory", + "url": "http://localhost:6333", + "api_key": "th3s3cr3tk3y", + "embedding_model_dims": 768 + }, + }, + "llm": { + "provider": "ollama", + "config": { + "model": "llama3.2:latest", + "temperature": 0.2, + "max_tokens": 1500, + }, + }, + "embedder": { + "provider": "ollama", + "config": { + "model": "nomic-embed-text:latest" + }, + } + } + self.memory = Mem0Memory.from_config( context=context, config=config,