Marek Stoj commited on
Commit
a623d90
·
1 Parent(s): b5cd936

Moah tools.

Browse files
7bd855d8-463d-4ed5-93ca-5fe35145f733.xlsx ADDED
Binary file (5.29 kB). View file
 
agent_langgraph.py CHANGED
@@ -1,30 +1,34 @@
1
  import base64
2
  import os
3
  import re
4
- from typing import Tuple, TypedDict, Annotated, Optional, cast
5
 
6
- from langchain_core.utils.function_calling import convert_to_openai_tool
7
- from langchain_core.messages import HumanMessage, SystemMessage, AIMessage
8
 
 
9
  from langchain_core.messages import AnyMessage, HumanMessage
10
  from langchain_openai import ChatOpenAI
11
-
12
  from langgraph.graph.message import add_messages
13
-
14
  from langgraph.graph import START, StateGraph
15
  from langgraph.prebuilt import ToolNode, tools_condition
16
- from IPython.display import Image, display
17
 
18
- from langchain_community.tools import DuckDuckGoSearchRun
19
- from langchain_community.tools.tavily_search import TavilySearchResults
20
- import requests
 
 
 
 
21
 
22
- MODEL_NAME = "gpt-4.1-mini"
23
  # MODEL_NAME = "gpt-4o"
 
 
24
  # MODEL_NAME = "o4-mini"
25
 
26
- # VISION_MODEL_NAME = "gpt-4o"
27
- VISION_MODEL_NAME = "gpt-4.1-mini"
 
28
  # VISION_MODEL_NAME = "o4-mini"
29
 
30
  SYSTEM_PROMPT = """\
@@ -33,12 +37,15 @@ I will ask you a question.
33
  Make sure you understand the question.
34
  Always think step by step.
35
  Double check your answer.
 
36
  Report your thoughts, and always finish your answer with the following template: FINAL ANSWER: [YOUR FINAL ANSWER].
37
  If you didn't arrive at an answer, finish your answer with: FINAL ANSWER: I don't know.
38
  YOUR FINAL ANSWER should be a number OR as few words as possible OR a comma separated list of numbers and/or strings.
39
  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.
40
  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.
41
  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.
 
 
42
  """.strip()
43
 
44
 
@@ -52,10 +59,14 @@ class BasicAgent:
52
  llm = ChatOpenAI(model=MODEL_NAME, verbose=True)
53
 
54
  tools = [
55
- # DuckDuckGoSearchRun(),
56
  TavilySearchResults(
57
  tavily_api_key="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"),
58
- self.analyze_image,
 
 
 
 
59
  ]
60
 
61
  self.llm_with_tools = llm.bind_tools(tools)
@@ -109,17 +120,21 @@ class BasicAgent:
109
  prompt += f"Attached file content:\n{file_content}\n"
110
  else:
111
  is_image, mime_type = is_image_file(file_name)
 
 
 
112
  if is_image:
113
  print("Content length:", len(response.content))
114
  image_data = base64.b64encode(response.content).decode("utf-8")
115
- # write the image data to a file
116
- with open("dupa-jasia.png", "wb") as f:
117
- f.write(response.content)
118
- with open("pierdzi-stasia.png.base64", "w") as f:
119
- f.write(image_data)
120
  prompt += f"\nImage file name: {file_name}\n"
121
  prompt += f"Image file data:\n{image_data}\n"
122
  prompt += f"Image file image mime type: {mime_type}\n"
 
 
 
 
 
 
123
 
124
  input_messages: list[AnyMessage] = [HumanMessage(content=prompt)]
125
 
@@ -127,6 +142,9 @@ class BasicAgent:
127
  {
128
  "messages": input_messages,
129
  "file_name": file_name
 
 
 
130
  }
131
  )
132
 
@@ -227,6 +245,18 @@ def is_image_file(file_name: str) -> Tuple[bool, str]:
227
  return (ext in image_extensions, mime_type)
228
 
229
 
 
 
 
 
 
 
 
 
 
 
 
 
230
  def ground_truth_answer(question: str) -> str:
231
  """
232
  Returns the answer corresponding to the given question,
 
1
  import base64
2
  import os
3
  import re
4
+ import requests
5
 
6
+ from typing import Tuple, TypedDict, Annotated, Optional
 
7
 
8
+ from langchain_core.messages import HumanMessage, SystemMessage, AIMessage
9
  from langchain_core.messages import AnyMessage, HumanMessage
10
  from langchain_openai import ChatOpenAI
11
+ from langchain_community.tools.tavily_search import TavilySearchResults
12
  from langgraph.graph.message import add_messages
 
13
  from langgraph.graph import START, StateGraph
14
  from langgraph.prebuilt import ToolNode, tools_condition
 
15
 
16
+ from agent_tools import transcribe_youtube_video
17
+ from agent_tools import transcribe_audio_file
18
+ from agent_tools import read_excel_file
19
+ from agent_tools import download_webpage_content
20
+
21
+ from agent_tools import multiply, add, subtract, divide, modulus, power
22
+
23
 
 
24
  # MODEL_NAME = "gpt-4o"
25
+ MODEL_NAME = "gpt-4.1"
26
+ # MODEL_NAME = "gpt-4.1-mini"
27
  # MODEL_NAME = "o4-mini"
28
 
29
+ VISION_MODEL_NAME = "gpt-4o"
30
+ # VISION_MODEL_NAME = "gpt-4.1"
31
+ # VISION_MODEL_NAME = "gpt-4.1-mini"
32
  # VISION_MODEL_NAME = "o4-mini"
33
 
34
  SYSTEM_PROMPT = """\
 
37
  Make sure you understand the question.
38
  Always think step by step.
39
  Double check your answer.
40
+ Double check your calculations.
41
  Report your thoughts, and always finish your answer with the following template: FINAL ANSWER: [YOUR FINAL ANSWER].
42
  If you didn't arrive at an answer, finish your answer with: FINAL ANSWER: I don't know.
43
  YOUR FINAL ANSWER should be a number OR as few words as possible OR a comma separated list of numbers and/or strings.
44
  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.
45
  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.
46
  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.
47
+ If you are asked to alphabetize a list, sort the list items alphabetically.
48
+ When the result is a currency number, don't include the currency symbol, just the number itself.
49
  """.strip()
50
 
51
 
 
59
  llm = ChatOpenAI(model=MODEL_NAME, verbose=True)
60
 
61
  tools = [
62
+ multiply, add, subtract, divide, modulus, power,
63
  TavilySearchResults(
64
  tavily_api_key="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"),
65
+ # self.analyze_image,
66
+ transcribe_youtube_video,
67
+ transcribe_audio_file,
68
+ read_excel_file,
69
+ download_webpage_content,
70
  ]
71
 
72
  self.llm_with_tools = llm.bind_tools(tools)
 
120
  prompt += f"Attached file content:\n{file_content}\n"
121
  else:
122
  is_image, mime_type = is_image_file(file_name)
123
+ is_audio = is_audio_file(file_name)
124
+ is_excel = is_excel_file(file_name)
125
+
126
  if is_image:
127
  print("Content length:", len(response.content))
128
  image_data = base64.b64encode(response.content).decode("utf-8")
 
 
 
 
 
129
  prompt += f"\nImage file name: {file_name}\n"
130
  prompt += f"Image file data:\n{image_data}\n"
131
  prompt += f"Image file image mime type: {mime_type}\n"
132
+ elif is_audio:
133
+ audio_url = f"https://agents-course-unit4-scoring.hf.space/files/{task_id}"
134
+ prompt += f"\nAudio URL: {audio_url}\n"
135
+ elif is_excel:
136
+ excel_file_url = f"https://agents-course-unit4-scoring.hf.space/files/{task_id}"
137
+ prompt += f"\nExcel file URL: {excel_file_url}\n"
138
 
139
  input_messages: list[AnyMessage] = [HumanMessage(content=prompt)]
140
 
 
142
  {
143
  "messages": input_messages,
144
  "file_name": file_name
145
+ },
146
+ config={
147
+ "recursion_limit": 100,
148
  }
149
  )
150
 
 
245
  return (ext in image_extensions, mime_type)
246
 
247
 
248
+ def is_audio_file(file_name: str) -> bool:
249
+ plain_text_extensions = {'.mp3'}
250
+ ext = os.path.splitext(file_name)[1].lower()
251
+ return ext in plain_text_extensions
252
+
253
+
254
+ def is_excel_file(file_name: str) -> bool:
255
+ excel_extensions = {'.xlsx', '.xls', '.xlsm'}
256
+ ext = os.path.splitext(file_name)[1].lower()
257
+ return ext in excel_extensions
258
+
259
+
260
  def ground_truth_answer(question: str) -> str:
261
  """
262
  Returns the answer corresponding to the given question,
agent_tools.py ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import requests
3
+ import pandas as pd
4
+ from langchain.tools import tool
5
+ from pytube import extract
6
+ from langchain_core.tools import tool
7
+ from openai import OpenAI
8
+ from youtube_transcript_api._api import YouTubeTranscriptApi
9
+
10
+
11
+ @tool
12
+ def transcribe_youtube_video(video_url: str) -> str:
13
+ """Get the transcript of a YouTube video.
14
+ Args:
15
+ video_url (str): YouTube URL of the video
16
+ """
17
+ video_id = extract.video_id(video_url)
18
+
19
+ ytt_api = YouTubeTranscriptApi()
20
+
21
+ transcript = ytt_api.fetch(video_id)
22
+
23
+ txt = "\n".join([s.text for s in transcript.snippets])
24
+
25
+ return txt
26
+
27
+
28
+ @tool
29
+ def transcribe_audio_file(audio_url: str) -> str:
30
+ """Transcribe an audio file to text.
31
+
32
+ Args:
33
+ audio_url (str): The URL of the audio file
34
+ """
35
+ response = requests.get(audio_url)
36
+ response.raise_for_status()
37
+
38
+ file_extension = "mp3"
39
+ file_name = f"audio-file.{file_extension}"
40
+
41
+ with open(file_name, 'wb') as file:
42
+ file.write(response.content)
43
+
44
+ openai_client = OpenAI()
45
+
46
+ with open(file_name, "rb") as audio_file:
47
+ transcription = \
48
+ openai_client.audio.transcriptions.create(
49
+ model="whisper-1",
50
+ file=audio_file
51
+ )
52
+
53
+ os.remove(file_name)
54
+
55
+ return transcription.text
56
+
57
+
58
+ @tool
59
+ def read_excel_file(excel_file_url: str) -> str:
60
+ """Read an Excel file and return as string.
61
+ Args:
62
+ excel_file_url (str): The URL of the Excel file
63
+ """
64
+ response = requests.get(excel_file_url)
65
+ response.raise_for_status()
66
+
67
+ file_extension = "xlsx"
68
+ excel_file_name = f"excel-file.{file_extension}"
69
+
70
+ with open(excel_file_name, "wb") as file:
71
+ file.write(response.content)
72
+
73
+ df = pd.read_excel(excel_file_name)
74
+
75
+ text = df.to_string()
76
+
77
+ os.remove(excel_file_name)
78
+
79
+ return text
80
+
81
+
82
+ @tool
83
+ def download_webpage_content(page_url: str) -> str:
84
+ """Load a web page and return its content as text.
85
+ Args:
86
+ page_url (str): the URL of web page to get
87
+ """
88
+ response = requests.get(page_url)
89
+
90
+ response.raise_for_status()
91
+
92
+ return response.text
93
+
94
+
95
+ @tool
96
+ def multiply(a: float, b: float) -> float:
97
+ """Multiplies two numbers.
98
+ Args:
99
+ a (float): the first number
100
+ b (float): the second number
101
+ """
102
+ return a * b
103
+
104
+
105
+ @tool
106
+ def add(a: float, b: float) -> float:
107
+ """Adds two numbers.
108
+ Args:
109
+ a (float): the first number
110
+ b (float): the second number
111
+ """
112
+ return a + b
113
+
114
+
115
+ @tool
116
+ def subtract(a: float, b: float) -> float:
117
+ """Subtracts two numbers.
118
+ Args:
119
+ a (float): the first number
120
+ b (float): the second number
121
+ """
122
+ return a - b
123
+
124
+
125
+ @tool
126
+ def divide(a: float, b: float) -> float:
127
+ """Divides two numbers.
128
+ Args:
129
+ a (float): the first float number
130
+ b (float): the second float number
131
+ """
132
+ if b == 0:
133
+ raise ValueError("Cannot divided by zero.")
134
+ return a / b
135
+
136
+
137
+ @tool
138
+ def modulus(a: int, b: int) -> int:
139
+ """Get the modulus of two numbers.
140
+ Args:
141
+ a (int): the first number
142
+ b (int): the second number
143
+ """
144
+ return a % b
145
+
146
+
147
+ @tool
148
+ def power(a: float, b: float) -> float:
149
+ """Get the power of two numbers.
150
+ Args:
151
+ a (float): the first number
152
+ b (float): the second number
153
+ """
154
+ return a**b
app_local.py CHANGED
@@ -5,10 +5,10 @@ import asyncio
5
  from agent_langgraph import BasicAgent
6
 
7
 
8
- # # # Answer: 3
9
- # task_id="8e867cd7-cff9-4e6c-867a-ff5ddc2550be"
10
- # question="How many studio albums were published by Mercedes Sosa between 2000 and 2009 (included)? You can use the latest 2022 version of english wikipedia."
11
- # file_name=None
12
 
13
  # # Answer: 3
14
  # task_id="a1e91b78-d3d8-4675-bb8d-62741b4b68a6"
@@ -21,9 +21,9 @@ from agent_langgraph import BasicAgent
21
  # file_name = None
22
 
23
  # # Answer: Rd5
24
- task_id="cca530fc-4052-43b2-b130-b30968d8aa44"
25
- question="Review the chess position provided in the image. It is black's turn. Provide the correct next move for black which guarantees a win. Please provide your response in algebraic notation."
26
- file_name="cca530fc-4052-43b2-b130-b30968d8aa44.png"
27
 
28
  # # Answer: FunkMonk
29
  # task_id="4fc2f1ae-8625-45b5-ab34-ad4433bc21f8"
@@ -35,7 +35,7 @@ file_name="cca530fc-4052-43b2-b130-b30968d8aa44.png"
35
  # question="Given this table defining * on the set S = {a, b, c, d, e}\n\n|*|a|b|c|d|e|\n|---|---|---|---|---|---|\n|a|a|b|c|b|d|\n|b|b|c|a|e|c|\n|c|c|a|b|b|a|\n|d|b|e|b|e|d|\n|e|d|b|a|d|c|\n\nprovide the subset of S involved in any possible counter-examples that prove * is not commutative. Provide your answer as a comma separated list of the elements in the set in alphabetical order."
36
  # file_name=None
37
 
38
- # # Answer: Extremely
39
  # task_id="9d191bce-651d-4746-be2d-7ef8ecadb9c2"
40
  # question="Examine the video at https://www.youtube.com/watch?v=1htKBjuUWec.\n\nWhat does Teal'c say in response to the question \"Isn't that hot?\""
41
  # file_name=None
@@ -80,7 +80,7 @@ file_name="cca530fc-4052-43b2-b130-b30968d8aa44.png"
80
  # question="On June 6, 2023, an article by Carolyn Collins Petersen was published in Universe Today. This article mentions a team that produced a paper about their observations, linked at the bottom of the article. Find this paper. Under what NASA award number was the work performed by R. G. Arendt supported by?"
81
  # file_name=None
82
 
83
- # # Answer: Saint Petersburg
84
  # task_id="bda648d7-d618-4883-88f4-3466eabd860e"
85
  # question="Where were the Vietnamese specimens described by Kuznetzov in Nedoshivina's 2010 paper eventually deposited? Just give me the city name without abbreviations."
86
  # file_name=None
 
5
  from agent_langgraph import BasicAgent
6
 
7
 
8
+ # # Answer: 3
9
+ task_id="8e867cd7-cff9-4e6c-867a-ff5ddc2550be"
10
+ question="How many studio albums were published by Mercedes Sosa between 2000 and 2009 (included)? You can use the latest 2022 version of english wikipedia."
11
+ file_name=None
12
 
13
  # # Answer: 3
14
  # task_id="a1e91b78-d3d8-4675-bb8d-62741b4b68a6"
 
21
  # file_name = None
22
 
23
  # # Answer: Rd5
24
+ # task_id="cca530fc-4052-43b2-b130-b30968d8aa44"
25
+ # question="Review the chess position provided in the image. It is black's turn. Provide the correct next move for black which guarantees a win. Please provide your response in algebraic notation."
26
+ # file_name="cca530fc-4052-43b2-b130-b30968d8aa44.png"
27
 
28
  # # Answer: FunkMonk
29
  # task_id="4fc2f1ae-8625-45b5-ab34-ad4433bc21f8"
 
35
  # question="Given this table defining * on the set S = {a, b, c, d, e}\n\n|*|a|b|c|d|e|\n|---|---|---|---|---|---|\n|a|a|b|c|b|d|\n|b|b|c|a|e|c|\n|c|c|a|b|b|a|\n|d|b|e|b|e|d|\n|e|d|b|a|d|c|\n\nprovide the subset of S involved in any possible counter-examples that prove * is not commutative. Provide your answer as a comma separated list of the elements in the set in alphabetical order."
36
  # file_name=None
37
 
38
+ # Answer: Extremely
39
  # task_id="9d191bce-651d-4746-be2d-7ef8ecadb9c2"
40
  # question="Examine the video at https://www.youtube.com/watch?v=1htKBjuUWec.\n\nWhat does Teal'c say in response to the question \"Isn't that hot?\""
41
  # file_name=None
 
80
  # question="On June 6, 2023, an article by Carolyn Collins Petersen was published in Universe Today. This article mentions a team that produced a paper about their observations, linked at the bottom of the article. Find this paper. Under what NASA award number was the work performed by R. G. Arendt supported by?"
81
  # file_name=None
82
 
83
+ # # Answer: Saint Petersburgu
84
  # task_id="bda648d7-d618-4883-88f4-3466eabd860e"
85
  # question="Where were the Vietnamese specimens described by Kuznetzov in Nedoshivina's 2010 paper eventually deposited? Just give me the city name without abbreviations."
86
  # file_name=None
audio_transcribe.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ from agent_tools import transcribe_audio_file
2
+
3
+ audio_url = "https://agents-course-unit4-scoring.hf.space/files/99c9cc74-fdc8-46c6-8f8d-3ce2d3bfeea3"
4
+
5
+ print(transcribe_audio_file(audio_url))
excel_read.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ from agent_tools import read_excel_file
2
+
3
+
4
+ excel_file_url = "https://agents-course-unit4-scoring.hf.space/files/7bd855d8-463d-4ed5-93ca-5fe35145f733"
5
+
6
+ print(read_excel_file(excel_file_url))
requirements.txt CHANGED
@@ -17,3 +17,8 @@ langchain_core
17
  langchain-community
18
  duckduckgo-search
19
  tavily-python
 
 
 
 
 
 
17
  langchain-community
18
  duckduckgo-search
19
  tavily-python
20
+
21
+ youtube_transcript_api
22
+ pytube
23
+ pandas
24
+ openpyxl
youtube_transcribe.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ from agent_tools import transcribe_youtube_video
2
+
3
+
4
+ video_url = "https://www.youtube.com/watch?v=1htKBjuUWec"
5
+
6
+ print(transcribe_youtube_video(video_url))