razumelo commited on
Commit
5482135
·
verified ·
1 Parent(s): 81917a3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +181 -9
app.py CHANGED
@@ -4,20 +4,192 @@ import requests
4
  import inspect
5
  import pandas as pd
6
 
 
 
 
 
 
 
 
7
  # (Keep Constants as is)
8
  # --- Constants ---
9
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
10
 
11
- # --- Basic Agent Definition ---
12
- # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
13
- class BasicAgent:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  def __init__(self):
15
- print("BasicAgent initialized.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  def __call__(self, question: str) -> str:
17
- print(f"Agent received question (first 50 chars): {question[:50]}...")
18
- fixed_answer = "This is a default answer."
19
- print(f"Agent returning fixed answer: {fixed_answer}")
20
- return fixed_answer
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
  def run_and_submit_all( profile: gr.OAuthProfile | None):
23
  """
@@ -40,7 +212,7 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
40
 
41
  # 1. Instantiate Agent ( modify this part to create your agent)
42
  try:
43
- agent = BasicAgent()
44
  except Exception as e:
45
  print(f"Error instantiating agent: {e}")
46
  return f"Error initializing agent: {e}", None
 
4
  import inspect
5
  import pandas as pd
6
 
7
+ # LangChain & LangGraph imports
8
+ from langchain_core.messages import BaseMessage, HumanMessage, AIMessage, SystemMessage
9
+ from langchain_core.tools import tool
10
+ from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
11
+ from langgraph.prebuilt import create_react_agent
12
+ from langchain_openai import ChatOpenAI
13
+
14
  # (Keep Constants as is)
15
  # --- Constants ---
16
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
17
 
18
+ # --- Tool Definitions ---
19
+ @tool
20
+ def search_wikipedia(query: str) -> str:
21
+ """Search Wikipedia for information. Use this for factual questions about people, places, events, etc."""
22
+ try:
23
+ import wikipediaapi
24
+ wiki = wikipediaapi.Wikipedia(
25
+ language='en',
26
+ user_agent='MyLangGraphAgent/1.0 (contact: itay@razum.com)'
27
+ )
28
+ page = wiki.page(query)
29
+ if page.exists():
30
+ return page.summary[:500]
31
+ else:
32
+ return f"No Wikipedia page found for '{query}'. Try a different search term."
33
+ except Exception as e:
34
+ return f"Error searching Wikipedia: {str(e)}"
35
+
36
+ @tool
37
+ def web_search(query: str) -> str:
38
+ """Search the web for general information. Use this when Wikipedia is not sufficient."""
39
+ try:
40
+ from duckduckgo_search import DDGS
41
+ with DDGS() as ddgs:
42
+ results = list(ddgs.text(query, max_results=3))
43
+ if results:
44
+ formatted = "\n\n".join([
45
+ f"Title: {r['title']}\nSnippet: {r['body']}\nURL: {r['href']}"
46
+ for r in results
47
+ ])
48
+ return formatted
49
+ return "No results found."
50
+ except Exception as e:
51
+ return f"Error performing web search: {str(e)}"
52
+
53
+ @tool
54
+ def calculator(expression: str) -> str:
55
+ """Evaluate mathematical expressions. Example: '15 + 27' or '2 * (3 + 4)'."""
56
+ try:
57
+ result = eval(expression, {"__builtins__": {}}, {})
58
+ return str(result)
59
+ except Exception as e:
60
+ return f"Error calculating: {str(e)}"
61
+
62
+ @tool
63
+ def reverse_text(text: str) -> str:
64
+ """Reverse a string of text. Useful for decoding reversed messages."""
65
+ return text[::-1]
66
+
67
+ @tool
68
+ def visit_page(url: str, query: str = "") -> str:
69
+ """Visit a specific URL and extract/summarize content based on a query.
70
+
71
+ Args:
72
+ url: The URL to visit and extract content from
73
+ query: Optional focus query to guide what information to extract
74
+
75
+ Returns:
76
+ Summarized content relevant to the query, or full page summary if no query provided
77
+ """
78
+ try:
79
+ from bs4 import BeautifulSoup
80
+
81
+ headers = {
82
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
83
+ }
84
+ response = requests.get(url, headers=headers, timeout=10)
85
+ response.raise_for_status()
86
+
87
+ soup = BeautifulSoup(response.content, 'html.parser')
88
+
89
+ for script in soup(["script", "style", "nav", "footer", "header"]):
90
+ script.decompose()
91
+
92
+ text = soup.get_text(separator=' ', strip=True)
93
+ lines = (line.strip() for line in text.splitlines())
94
+ chunks = (phrase.strip() for line in lines for phrase in line.split(" "))
95
+ text = ' '.join(chunk for chunk in chunks if chunk)
96
+
97
+ max_length = 3000
98
+ if len(text) > max_length:
99
+ text = text[:max_length]
100
+
101
+ return f"Content from {url}:\n\n{text[:1000]}..."
102
+
103
+ except requests.Timeout:
104
+ return f"Error: Timeout while trying to access {url}"
105
+ except requests.RequestException as e:
106
+ return f"Error fetching {url}: {str(e)}"
107
+ except Exception as e:
108
+ return f"Error processing {url}: {str(e)}"
109
+
110
+ # --- LangGraph Agent Definition ---
111
+ # ----- THIS IS WHERE YOU CAN BUILD WHAT YOU WANT ------
112
+ class LangGraphAgent:
113
+ """LangGraph ReAct agent with tools for question answering."""
114
+
115
  def __init__(self):
116
+ print("Initializing LangGraph Agent...")
117
+
118
+ # Configure LangSmith tracing if API key is available
119
+ if os.getenv("LANGCHAIN_API_KEY"):
120
+ os.environ["LANGCHAIN_TRACING_V2"] = "true"
121
+ os.environ["LANGCHAIN_PROJECT"] = "agent-benchmark-production"
122
+ print("🔍 LangSmith tracing enabled")
123
+
124
+ # Set up LLM
125
+ api_key = os.getenv("OPENAI_API_KEY")
126
+ if not api_key:
127
+ raise ValueError("OPENAI_API_KEY environment variable not set!")
128
+
129
+ self.llm = ChatOpenAI(
130
+ model="gpt-4o-mini",
131
+ temperature=0,
132
+ api_key=api_key
133
+ )
134
+
135
+ # Define tools
136
+ self.tools = [search_wikipedia, web_search, calculator, reverse_text, visit_page]
137
+
138
+ # System prompt
139
+ system_message = SystemMessage(
140
+ content="""You are a helpful AI assistant that can answer questions by using various tools.
141
+
142
+ When answering questions:
143
+ 1. Think step-by-step about what information you need
144
+ 2. Use the appropriate tools to gather information
145
+ - search_wikipedia: For factual questions about people, places, events
146
+ - web_search: For general web searches
147
+ - calculator: For mathematical calculations
148
+ - reverse_text: For reversing text strings
149
+ - visit_page: For extracting content from specific URLs
150
+ 3. Provide clear, concise, and accurate answers
151
+ 4. If you're not sure, say so rather than making up information
152
+ 5. The answer should be short - for example, if asked how many awards someone won, answer with just the number
153
+ 6. Write only the final answer without extra explanation
154
+ 7. Simplify complex tasks into subtasks and think about which tool to use for each"""
155
+ )
156
+
157
+ # Create prompt template
158
+ prompt = ChatPromptTemplate.from_messages([
159
+ system_message,
160
+ MessagesPlaceholder(variable_name="messages")
161
+ ])
162
+
163
+ # Create ReAct agent
164
+ self.agent = create_react_agent(
165
+ self.llm,
166
+ self.tools,
167
+ prompt=prompt
168
+ )
169
+
170
+ print(f"✅ Agent initialized with {len(self.tools)} tools")
171
+ print(" Model: gpt-4o-mini")
172
+
173
  def __call__(self, question: str) -> str:
174
+ """Process a question and return an answer."""
175
+ print(f"Agent processing question: {question[:100]}...")
176
+
177
+ try:
178
+ result = self.agent.invoke({
179
+ "messages": [HumanMessage(content=question)]
180
+ })
181
+
182
+ # Extract final answer
183
+ final_message = result["messages"][-1]
184
+ answer = final_message.content
185
+
186
+ print(f"Agent answer: {answer[:100]}...")
187
+ return answer
188
+
189
+ except Exception as e:
190
+ error_msg = f"Error processing question: {str(e)}"
191
+ print(f"❌ {error_msg}")
192
+ return error_msg
193
 
194
  def run_and_submit_all( profile: gr.OAuthProfile | None):
195
  """
 
212
 
213
  # 1. Instantiate Agent ( modify this part to create your agent)
214
  try:
215
+ agent = LangGraphAgent()
216
  except Exception as e:
217
  print(f"Error instantiating agent: {e}")
218
  return f"Error initializing agent: {e}", None