cgoncalves's picture
Add new tools and functionalities for audio transcription, code execution, document handling, image processing, and mathematical operations
d303e2f
from dotenv import load_dotenv
from langgraph.graph import START, StateGraph, MessagesState
from langgraph.prebuilt import tools_condition
from langgraph.prebuilt import ToolNode
from langchain_core.messages import SystemMessage
from tools.searchtools import wiki_search, web_search, arxiv_search, get_youtube_transcript
from tools.mathtools import multiply, add, subtract, divide, modulus, power, square_root
from tools.codetools import execute_code_multilang
from tools.documenttools import create_file_with_content, read_file_content, download_file_from_url, extract_text_from_image, analyze_csv_file, analyze_excel_file
from tools.imagetools import analyze_image, transform_image, draw_on_image, generate_simple_image, combine_images
from tools.audiotools import transcribe_audio
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_huggingface import ChatHuggingFace, HuggingFaceEndpoint
load_dotenv()
# load the system prompt from the file
with open("system_prompt.txt", "r", encoding="utf-8") as f:
system_prompt = f.read()
# System message
sys_msg = SystemMessage(content=system_prompt)
tools = [
web_search,
wiki_search,
arxiv_search,
get_youtube_transcript,
multiply,
add,
subtract,
divide,
modulus,
power,
square_root,
create_file_with_content,
read_file_content,
download_file_from_url,
extract_text_from_image,
analyze_csv_file,
analyze_excel_file,
execute_code_multilang,
analyze_image,
transform_image,
draw_on_image,
generate_simple_image,
combine_images,
transcribe_audio,
]
# Build graph function
def build_graph():
"""Build the graph"""
# Load environment variables from .env file
llm = ChatGoogleGenerativeAI(model="gemini-2.0-flash", temperature=0)
# Bind tools to LLM
llm_with_tools = llm.bind_tools(tools)
# Node
def assistant(state: MessagesState):
"""Assistant node"""
# Prepend system message to the current messages
# Ensure sys_msg is only added if not already present or if it's the first turn
current_messages = state["messages"]
if not current_messages or current_messages[0].type != "system":
# Or, if you want to ensure it's always the first message for each LLM call in this node:
# updated_messages = [sys_msg] + [m for m in current_messages if m.type != "system"]
# For simplicity, let's assume we add it if it's not the very first message overall.
# A more robust check might be needed depending on multi-turn conversation flow.
updated_messages = [sys_msg] + current_messages
else:
updated_messages = current_messages
return {"messages": [llm_with_tools.invoke(updated_messages)]}
builder = StateGraph(MessagesState)
builder.add_node("assistant", assistant)
builder.add_node("tools", ToolNode(tools))
builder.add_edge(START, "assistant")
builder.add_conditional_edges(
"assistant",
tools_condition,
)
builder.add_edge("tools", "assistant")
# Compile graph
return builder.compile()