datdevsteve commited on
Commit
261e847
·
verified ·
1 Parent(s): 83a50ac

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +14 -178
app.py CHANGED
@@ -4,198 +4,32 @@ import requests
4
  import pandas as pd
5
  from langchain.agents import create_agent
6
  from langchain_google_genai import ChatGoogleGenerativeAI
7
- from langchain_openai import ChatOpenAI
8
- from langchain.tools import tool
9
  from dotenv import load_dotenv
10
- from langchain_community.document_loaders import ArxivLoader, WikipediaLoader
11
- from ddgs import DDGS
12
 
13
  # Load environment variables
14
- # load_dotenv()
15
 
16
  # --- Constants ---
17
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
18
 
19
  # --- Agent Setup ---
20
- #openai_key = os.getenv("OPENAI_API_KEY")
21
  googleai_key = os.getenv("GOOGLE_API_KEY")
22
 
23
- # Initialize the model
24
- model = ChatGoogleGenerativeAI(
25
- model="gemini-2.5-flash",
26
- temperature=0,
27
- max_tokens=5000,
28
- timeout=None,
29
- max_retries=2,
30
- )
31
 
32
- # --- Tools Definition ---
33
- @tool
34
- def multiply(a: int, b: int) -> int:
35
- """Multiply two numbers.
36
- Args:
37
- a: first int
38
- b: second int
39
- """
40
- return a * b
41
-
42
- @tool
43
- def add(a: int, b: int) -> int:
44
- """Add two numbers.
45
-
46
- Args:
47
- a: first int
48
- b: second int
49
- """
50
- return a + b
51
-
52
- @tool
53
- def subtract(a: int, b: int) -> int:
54
- """Subtract two numbers.
55
-
56
- Args:
57
- a: first int
58
- b: second int
59
- """
60
- return a - b
61
-
62
- @tool
63
- def divide(a: int, b: int) -> int:
64
- """Divide two numbers.
65
-
66
- Args:
67
- a: first int
68
- b: second int
69
- """
70
- if b == 0:
71
- raise ValueError("Cannot divide by zero.")
72
- return a / b
73
-
74
- @tool
75
- def modulus(a: int, b: int) -> int:
76
- """Get the modulus of two numbers.
77
-
78
- Args:
79
- a: first int
80
- b: second int
81
- """
82
- return a % b
83
-
84
- @tool
85
- def wiki_search(query: str) -> str:
86
- """Search Wikipedia for a query and return maximum 2 results.
87
-
88
- Args:
89
- query: The search query."""
90
- search_docs = WikipediaLoader(query=query, load_max_docs=2).load()
91
- formatted_search_docs = "\n\n---\n\n".join(
92
- [
93
- f'<Document source="{doc.metadata["source"]}" page="{doc.metadata.get("page", "")}"/>\n{doc.page_content}\n</Document>'
94
- for doc in search_docs
95
- ])
96
- return {"wiki_results": formatted_search_docs}
97
 
98
- @tool
99
- def web_search(query: str) -> str:
100
- """Search DDGS for a query and return maximum 3 results.
101
-
102
- Args:
103
- query: The search query."""
104
- search_docs = DDGS().text(query,max_results=3)
105
- formatted_search_docs = "\n\n---\n\n".join(
106
- [
107
- f'Title:{doc["title"]}\nContent:{doc["body"]}\n--\n'
108
- for doc in search_docs
109
- ])
110
- return formatted_search_docs
111
-
112
- @tool
113
- def arvix_search(query: str) -> str:
114
- """Search Arxiv for a query and return maximum 3 result.
115
-
116
- Args:
117
- query: The search query."""
118
- search_docs = ArxivLoader(query=query, load_max_docs=3).load()
119
- formatted_search_docs = "\n\n---\n\n".join(
120
- [
121
- f'<Document source="{doc.metadata["source"]}" page="{doc.metadata.get("page", "")}"/>\n{doc.page_content[:1000]}\n</Document>'
122
- for doc in search_docs
123
- ])
124
- return {"arvix_results": formatted_search_docs}
125
-
126
- @tool
127
- def image_search(query: str) -> str:
128
- """Searches DDGS for an image query and returns maximum 10 image results"""
129
- search_images = DDGS().images(query=query)
130
- formatted_result = "\n\n---\n\n".join(
131
- [
132
- f'Image Title:{image["title"]}\nImage URL: {image["url"]}'
133
- for image in search_images
134
- ])
135
 
136
 
137
- # Tools list
138
- tools = [
139
- multiply, add, subtract, divide, modulus,
140
- wiki_search, web_search, arvix_search, image_search
141
- ]
142
-
143
- # System prompt
144
- sys_prompt = """You are a helpful agent, please provide clear and concise answers to asked questions.
145
- Keep your word limit for answers as minimum as you can. You are equipped with the following tools:
146
- 1. [multiply], [add], [subtract], [divide], [modulus] - basic calculator operations.
147
- 2. [wiki_search] - search Wikipedia and return up to 2 documents as text.
148
- 3. [web_search] - perform a web search and return up to 3 documents as text.
149
- 4. [arxiv_search] - search arXiv and return up to 3 documents as text.
150
- 5. [image_search] - Searches the internet for an image query and returns maximum 10 image results
151
-
152
- Under any circumstances, if you fail to provide the accurate answer expected by the user, you may say the same to the user and provide a similar answer which is approximately the closest. Disregard spelling mistakes and provide answer with results retreived from the correct spelling.
153
-
154
- For every tool you use, append a single line at the end of your response exactly in this format:
155
- [TOOLS USED: (tool_name)]
156
- When no tools are used, append:
157
- [TOOLS USED WERE NONE]"""
158
-
159
- # --- Agent Class ---
160
- class GAIAAgent:
161
- def __init__(self):
162
- print("GAIAAgent initialized with LangChain agent.")
163
- try:
164
- self.agent = create_agent(model, tools=tools, system_prompt=sys_prompt)
165
- print("Agent created successfully.")
166
- except Exception as e:
167
- print(f"Error creating agent: {e}")
168
- raise
169
-
170
- def __call__(self, question: str) -> str:
171
- print(f"Agent received question (first 100 chars): {question[:100]}...")
172
- try:
173
- result = self.agent.invoke({
174
- "messages": [{"role": "user", "content": question}]
175
- })
176
-
177
- # Get the content from the last message
178
- raw_content = result["messages"][-1].content
179
-
180
- # Parse the response format: list of dicts with 'text' key
181
- if isinstance(raw_content, list) and len(raw_content) > 0:
182
- if isinstance(raw_content[0], dict) and 'text' in raw_content[0]:
183
- answer = raw_content[0]['text']
184
- else:
185
- # Fallback: convert list to string
186
- answer = str(raw_content)
187
- elif isinstance(raw_content, str):
188
- answer = raw_content
189
- else:
190
- answer = str(raw_content)
191
-
192
- print(f"Agent returning answer (first 100 chars): {answer[:100]}...")
193
- return answer
194
- except Exception as e:
195
- print(f"Error in agent execution: {e}")
196
- import traceback
197
- traceback.print_exc()
198
- return f"Error: {str(e)}"
199
 
200
  def run_and_submit_all(profile: gr.OAuthProfile | None):
201
  """
@@ -372,6 +206,7 @@ if __name__ == "__main__":
372
  space_host_startup = os.getenv("SPACE_HOST")
373
  space_id_startup = os.getenv("SPACE_ID")
374
  google_api_key = os.getenv("GOOGLE_API_KEY")
 
375
 
376
  if space_host_startup:
377
  print(f"✅ SPACE_HOST found: {space_host_startup}")
@@ -390,6 +225,7 @@ if __name__ == "__main__":
390
  print("✅ GOOGLE_API_KEY found")
391
  else:
392
  print("⚠️ GOOGLE_API_KEY not found - agent will not work without it!")
 
393
  print("-"*(60 + len(" App Starting ")) + "\n")
394
 
395
  print("Launching Gradio Interface for GAIA Agent Evaluation...")
 
4
  import pandas as pd
5
  from langchain.agents import create_agent
6
  from langchain_google_genai import ChatGoogleGenerativeAI
7
+ # Agent implementation is moved to gaia_agent.py
8
+ from gaia_agent import GAIAAgent
9
  from dotenv import load_dotenv
 
 
10
 
11
  # Load environment variables
12
+ load_dotenv()
13
 
14
  # --- Constants ---
15
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
16
 
17
  # --- Agent Setup ---
18
+ openai_key = os.getenv("OPENAI_API_KEY")
19
  googleai_key = os.getenv("GOOGLE_API_KEY")
20
 
21
+ # Use OpenRouter via LangChain's ChatOpenAI
22
+ openrouter_key = os.getenv("OPENROUTER_API_KEY")
23
+ if not openrouter_key:
24
+ raise RuntimeError("Set OPENROUTER_API_KEY in your .env (OpenRouter API key)")
 
 
 
 
25
 
26
+ # model is created inside gaia_agent module
27
+ # (gaia_agent.py will initialize the ChatOpenAI model using OPENROUTER_API_KEY)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
 
31
+ # The tools and GAIAAgent implementation live in gaia_agent.py now. This file
32
+ # imports GAIAAgent and uses it in run_and_submit_all.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
  def run_and_submit_all(profile: gr.OAuthProfile | None):
35
  """
 
206
  space_host_startup = os.getenv("SPACE_HOST")
207
  space_id_startup = os.getenv("SPACE_ID")
208
  google_api_key = os.getenv("GOOGLE_API_KEY")
209
+ tavily_api_key = os.getenv("TAVILY_API_KEY")
210
 
211
  if space_host_startup:
212
  print(f"✅ SPACE_HOST found: {space_host_startup}")
 
225
  print("✅ GOOGLE_API_KEY found")
226
  else:
227
  print("⚠️ GOOGLE_API_KEY not found - agent will not work without it!")
228
+
229
  print("-"*(60 + len(" App Starting ")) + "\n")
230
 
231
  print("Launching Gradio Interface for GAIA Agent Evaluation...")