yoda1976's picture
Add google chat
004a8b0
from typing import List, TypedDict, Annotated, Optional, Dict, Union
from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage, HumanMessage, AnyMessage
from langgraph.graph.message import add_messages
from langchain_community.vectorstores import SupabaseVectorStore
from supabase.client import create_client
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_huggingface import HuggingFaceEmbeddings, ChatHuggingFace, HuggingFaceEndpoint
from serpapi import GoogleSearch
from dotenv import load_dotenv
import os
load_dotenv()
class AgentState(TypedDict):
"""Agent state to be passed to the tool."""
messages: Annotated[List[AnyMessage], add_messages]
def add(a: Union[float , int], b: Union[float , int]) -> Union[float , int]:
"""Add two numbers."""
return a + b
def subtract(a: Union[float , int], b: Union[float , int]) -> Union[float , int]:
"""Subtract two numbers."""
return a - b
def multiply(a: Union[float , int], b: Union[float , int]) -> Union[float , int]:
"""Multiply two numbers."""
return a * b
def divide(a: Union[float , int], b: Union[float , int]) -> Union[float , int , None]:
"""Divide two numbers."""
if b == 0:
return None
return a / b
def web_search(query: str) -> str:
"""Perform a web search using SerpAPI."""
params = {
"engine": "google",
"q": query,
"api_key": os.getenv("SERPAPI_KEY"),
"num": 5
}
search = GoogleSearch(params)
results = search.get_dict()["organic_results"]
context = "\n---\n".join([
"Title: " + result['title'] + "\nLink: " + result['link'] + "\nSnippet: " + result.get('snippet', 'No snippet available')
for result in results if 'title' in result and 'link' in result
]
)
return context if context else "No results found."
# llm = ChatHuggingFace(llm = HuggingFaceEndpoint(
# repo_id = "meta-llama/Llama-2-7b-chat-hf",
# temperature=0,
# huggingfacehub_api_token=os.environ.get("HUGGING_FACE_API_KEY")))
tools = [add, subtract, divide, web_search]
llm =ChatGoogleGenerativeAI(model = "gemini-2.0-flash")
llm_with_tools = llm.bind_tools(tools)
def retriever(state: AgentState) -> Dict:
"""
Retrieve the answer fom vector database instead of searching if we found a user query similar to which is already found in the dataset
"""
supabase_url = os.environ.get("SUPABASE_URL")
supabase_key = os.environ.get("SUPABASE_KEY")
supabase = create_client(supabase_url, supabase_key)
embeddings = HuggingFaceEmbeddings(model_name = "sentence-transformers/all-mpnet-base-v2")
vector_store = SupabaseVectorStore(
embedding=embeddings,
client=supabase,
table_name="documents",
query_name="match_documents",
)
docs = vector_store.similarity_search(query = state["messages"][-1].content, k = 1)
humanmessage = HumanMessage(content = f"Here are some of the questions and answers relevant to user query \n\n {docs[0].page_content}")
return {"messages":[humanmessage]}
def assistant(state: AgentState) -> Dict:
system_message = """
You are a helpful assistant tasked with answering questions using a set of tools.
Now, I will ask you a question. Report your thoughts, and finish your answer with the following template:
FINAL ANSWER: [YOUR FINAL ANSWER].
YOUR FINAL ANSWER should be a number OR as few words as possible OR a comma separated list of numbers and/or strings. If you are asked for a number, don't use comma to write your number neither use units such as $ or percent sign unless specified otherwise. If you are asked for a string, don't use articles, neither abbreviations (e.g. for cities), and write the digits in plain text unless specified otherwise. If you are asked for a comma separated list, apply the above rules depending of whether the element to be put in the list is a number or a string.
Your answer should only start with "FINAL ANSWER: ", then follows with the answer.
"""
tools_description = """
You have the following tools available to perform actions
websearch(query: str) -> str:
Args:
query: Search query
Returns:
A string containing 5 relevant search results
add(a: Union[float , int], b: Union[float , int]) -> Union[float , int]:
Add two numbers
subtract(a: Union[float , int], b: Union[float , int]) -> Union[float , int]:
Subtract two numbers
multiply(a: Union[float , int], b: Union[float , int]) -> Union[float , int]:
Multiply two numbers
divide(a: Union[float , int], b: Union[float , int]) -> Union[float , int , None]:
Divide two numbers
"""
sys_msg = SystemMessage(content=system_message + tools_description)
return {"messages": [llm_with_tools.invoke([sys_msg] + state["messages"])]}