grady / tools.py
bstraehle's picture
Update tools.py
24cc8ee verified
raw
history blame
10.7 kB
# Automatic function calling
# https://ai.google.dev/gemini-api/docs/function-calling
from crewai.tools import tool
#from crewai_tools import StagehandTool
from google import genai
from google.genai import types
WEB_SEARCH_MODEL = "gemini-2.5-flash-preview-04-17"
IMAGE_ANALYSIS_MODEL = "gemini-2.5-flash-preview-04-17"
AUDIO_ANALYSIS_MODEL = "gemini-2.5-flash-preview-04-17"
VIDEO_ANALYSIS_MODEL = "gemini-2.5-flash-preview-04-17"
YOUTUBE_ANALYSIS_MODEL = "gemini-2.5-flash-preview-04-17"
DOCUMENT_ANALYSIS_MODEL = "gemini-2.5-flash-preview-04-17"
ARITHMETIC_MODEL = "gemini-2.5-flash-preview-04-17"
CODE_GENERATION_MODEL = "gemini-2.5-flash-preview-04-17"
CODE_EXECUTION_MODEL = "gemini-2.5-flash-preview-04-17"
@tool("Web Search Tool")
def web_search_tool(question: str) -> str:
"""Given a question only, search the web to answer the question.
Args:
question (str): Question to answer
Returns:
str: Answer to the question
Raises:
RuntimeError: If processing fails"""
try:
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
response = client.models.generate_content(
model=WEB_SEARCH_MODEL,
contents=question,
config=types.GenerateContentConfig(
tools=[types.Tool(google_search=types.GoogleSearchRetrieval())]
)
)
return response.text
except Exception as e:
raise RuntimeError(f"Processing failed: {str(e)}")
@tool("Image Analysis Tool")
def image_analysis_tool(question: str, file_path: str) -> str:
"""Given a question and image file, analyze the image to answer the question.
Args:
question (str): Question about an image file
file_path (str): The image file path
Returns:
str: Answer to the question about the image file
Raises:
RuntimeError: If processing fails"""
try:
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
file = client.files.upload(file=file_path)
response = client.models.generate_content(
model=IMAGE_ANALYSIS_MODEL,
contents=[file, question]
)
return response.text
except Exception as e:
raise RuntimeError(f"Processing failed: {str(e)}")
@tool("Audio Analysis Tool")
def audio_analysis_tool(question: str, file_path: str) -> str:
"""Given a question and audio file, analyze the audio to answer the question.
Args:
question (str): Question about an audio file
file_path (str): The audio file path
Returns:
str: Answer to the question about the audio file
Raises:
RuntimeError: If processing fails"""
try:
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
file = client.files.upload(file=file_path)
response = client.models.generate_content(
model=AUDIO_ANALYSIS_MODEL,
contents=[file, question]
)
return response.text
except Exception as e:
raise RuntimeError(f"Processing failed: {str(e)}")
@tool("Video Analysis Tool")
def video_analysis_tool(question: str, file_path: str) -> str:
"""Given a question and video file, analyze the video to answer the question.
Args:
question (str): Question about a video file
file_path (str): The video file path
Returns:
str: Answer to the question about the video file
Raises:
RuntimeError: If processing fails"""
try:
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
file = client.files.upload(file=file_path)
response = client.models.generate_content(
model=VIDEO_ANALYSIS_MODEL,
contents=[file, question]
)
return response.text
except Exception as e:
raise RuntimeError(f"Processing failed: {str(e)}")
@tool("YouTube Analysis Tool")
def youtube_analysis_tool(question: str, url: str) -> str:
"""Given a question and YouTube URL, analyze the video to answer the question.
Args:
question (str): Question about a YouTube video
url (str): The YouTube URL
Returns:
str: Answer to the question about the YouTube video
Raises:
RuntimeError: If processing fails"""
try:
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
return client.models.generate_content(
model=YOUTUBE_ANALYSIS_MODEL,
contents=types.Content(
parts=[types.Part(file_data=types.FileData(file_uri=url)),
types.Part(text=question)]
)
)
except Exception as e:
raise RuntimeError(f"Processing failed: {str(e)}")
@tool("Document Analysis Tool")
def document_analysis_tool(question: str, file_path: str) -> str:
"""Given a question and document file, analyze the document to answer the question.
Args:
question (str): Question about a document file
file_path (str): The document file path
Returns:
str: Answer to the question about the document file
Raises:
RuntimeError: If processing fails"""
try:
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
contents = []
if is_ext(file_path, ".docx"):
text_data = read_docx_text(file_path)
contents = [f"{question}\n{text_data}"]
print(f"=> Text data:\n{text_data}")
elif is_ext(file_path, ".pptx"):
text_data = read_pptx_text(file_path)
contents = [f"{question}\n{text_data}"]
print(f"=> Text data:\n{text_data}")
else:
file = client.files.upload(file=file_path)
contents = [file, question]
response = client.models.generate_content(
model=DOCUMENT_ANALYSIS_MODEL,
contents=contents
)
return response.text
except Exception as e:
raise RuntimeError(f"Processing failed: {str(e)}")
@tool("Arithmetic Tool")
def arithmetic_tool(question: str, a: float, b: float) -> float:
"""Given a question and two numbers, perform the calculation to answer the question.
Args:
question (str): Question to answer
a (float): First number
b (float): Second number
Returns:
float: Result number
Raises:
RuntimeError: If processing fails"""
try:
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
response = client.models.generate_content(
model=ARITHMETIC_MODEL,
contents=question,
config=types.GenerateContentConfig(
tools=[add, subtract, multiply, divide, modulus]
)
)
return response.text
except Exception as e:
raise RuntimeError(f"Processing failed: {str(e)}")
@tool("Code Execution Tool")
def code_execution_tool(question: str, file_path: str) -> str:
"""Given a question and Python file, execute the file to answer the question.
Args:
question (str): Question to answer
file_path (str): The Python file path
Returns:
str: Answer to the question
Raises:
RuntimeError: If processing fails"""
try:
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
file = client.files.upload(file=file_path)
response = client.models.generate_content(
model=CODE_EXECUTION_MODEL,
contents=[file, question],
config=types.GenerateContentConfig(
tools=[types.Tool(code_execution=types.ToolCodeExecution)]
),
)
for part in response.candidates[0].content.parts:
if part.code_execution_result is not None:
return part.code_execution_result.output
except Exception as e:
raise RuntimeError(f"Processing failed: {str(e)}")
@tool("Code Generation Tool")
def code_generation_tool(question: str, json_data: str) -> str:
"""Given a question and JSON data, generate and execute code to answer the question.
Args:
question (str): Question to answer
file_path (str): The JSON data
Returns:
str: Answer to the question
Raises:
RuntimeError: If processing fails"""
try:
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
response = client.models.generate_content(
model=CODE_GENERATION_MODEL,
contents=[f"{question}\n{json_data}"],
config=types.GenerateContentConfig(
tools=[types.Tool(code_execution=types.ToolCodeExecution)]
),
)
for part in response.candidates[0].content.parts:
if part.code_execution_result is not None:
return part.code_execution_result.output
except Exception as e:
raise RuntimeError(f"Processing failed: {str(e)}")
# Arithmetic functions
@tool("Addition Tool")
def add(a: float, b: float) -> float:
"""Add two numbers.
Args:
a: First number
b: Second number
Returns:
Result number
"""
return a + b
@tool("Subtraction Tool")
def subtract(a: float, b: float) -> float:
"""Subtract two numbers.
Args:
a: First number
b: Second number
Returns:
Result number
"""
return a - b
@tool("Multiplication Tool")
def multiply(a: float, b: float) -> float:
"""Multiply two numbers.
Args:
a: First number
b: Second number
Returns:
Result number
"""
return a * b
@tool("Division Tool")
def divide(a: float, b: float) -> float:
"""Divide two numbers.
Args:
a: First number
b: Second number
Returns:
Result number
"""
if b == 0:
raise ValueError("Cannot divide by zero.")
return a / b
@tool("Modulus Tool")
def modulus(a: float, b: float) -> float:
"""Get the modulus of two numbers.
Args:
a: First number
b: Second number
Returns:
Result number
"""
return a % b
# TODO: Other functions