bobobert4 commited on
Commit
ee4ab6d
·
1 Parent(s): 728aee3

style: applied formatting and types for some env variables

Browse files
Files changed (3) hide show
  1. agent.py +9 -16
  2. app.py +70 -49
  3. tools.py +9 -11
agent.py CHANGED
@@ -1,34 +1,27 @@
1
- import os
2
  from pathlib import Path
3
  from typing import TypedDict, Annotated
4
  from uuid import uuid4
 
5
  import requests
6
 
7
- from langgraph.graph.message import add_messages
8
  from langchain_core.messages import AnyMessage, HumanMessage, AIMessage, SystemMessage
9
- from langgraph.prebuilt import ToolNode
10
- from langgraph.graph import START, StateGraph
11
  from langgraph.checkpoint.memory import MemorySaver
 
 
 
12
  from langgraph.prebuilt import tools_condition
13
-
14
- # from langchain_huggingface import HuggingFaceEndpoint, ChatHuggingFace
15
- from langchain_google_genai import ChatGoogleGenerativeAI
16
- from langchain_core.rate_limiters import InMemoryRateLimiter
17
  from smolagents import CodeAgent, HfApiModel
18
 
19
  # Import our custom tools from their modules
20
  from tools import basic_tools
21
 
22
- # HF Chat interface
23
- # llm = HuggingFaceEndpoint(
24
- # repo_id="Qwen/Qwen2.5-Coder-32B-Instruct",
25
- # huggingfacehub_api_token=os.environ["HUGGINGFACEHUB_API_TOKEN"],
26
- # )
27
- # chat = ChatHuggingFace(llm=llm, verbose=True)
28
 
29
  # Google's chat interface
30
- RPM = os.environ.get("AGENT_MODEL_RPM", 9)
31
- TPM = os.environ.get("AGENT_MODEL_TPM", 250000)
32
  FILES_ENDPOINT = os.environ.get(
33
  "FILES_ENDPOINT", "https://agents-course-unit4-scoring.hf.space"
34
  )
 
 
1
  from pathlib import Path
2
  from typing import TypedDict, Annotated
3
  from uuid import uuid4
4
+ import os
5
  import requests
6
 
 
7
  from langchain_core.messages import AnyMessage, HumanMessage, AIMessage, SystemMessage
8
+ from langchain_core.rate_limiters import InMemoryRateLimiter
9
+ from langchain_google_genai import ChatGoogleGenerativeAI
10
  from langgraph.checkpoint.memory import MemorySaver
11
+ from langgraph.graph import START, StateGraph
12
+ from langgraph.graph.message import add_messages
13
+ from langgraph.prebuilt import ToolNode
14
  from langgraph.prebuilt import tools_condition
 
 
 
 
15
  from smolagents import CodeAgent, HfApiModel
16
 
17
  # Import our custom tools from their modules
18
  from tools import basic_tools
19
 
20
+ ChatHuggingFace(llm=llm, verbose=True)
 
 
 
 
 
21
 
22
  # Google's chat interface
23
+ RPM = int(os.environ.get("AGENT_MODEL_RPM", 8))
24
+ TPM = int(os.environ.get("AGENT_MODEL_TPM", 200000))
25
  FILES_ENDPOINT = os.environ.get(
26
  "FILES_ENDPOINT", "https://agents-course-unit4-scoring.hf.space"
27
  )
app.py CHANGED
@@ -1,36 +1,34 @@
1
- import os
 
 
 
 
 
 
 
 
 
2
  import gradio as gr
3
- import requests
4
  import inspect
 
5
  import pandas as pd
6
- from pprint import pprint
7
- from agent import builder, HumanMessage, memory, create_config, get_system_prompt, insert_file_into_query, download_requested_file
8
 
9
  # (Keep Constants as is)
10
  # --- Constants ---
11
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
12
 
13
- # --- Basic Agent Definition ---
14
- # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
15
- class BasicAgent:
16
- def __init__(self):
17
- print("BasicAgent initialized.")
18
- def __call__(self, question: str) -> str:
19
- print(f"Agent received question (first 50 chars): {question[:50]}...")
20
- fixed_answer = "This is a default answer."
21
- print(f"Agent returning fixed answer: {fixed_answer}")
22
- return fixed_answer
23
-
24
- def run_and_submit_all( profile: gr.OAuthProfile | None):
25
  """
26
  Fetches all questions, runs the BasicAgent on them, submits all answers,
27
  and displays the results.
28
  """
29
  # --- Determine HF Space Runtime URL and Repo URL ---
30
- space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
31
 
32
  if profile:
33
- username= f"{profile.username}"
34
  print(f"User logged in: {username}")
35
  else:
36
  print("User not logged in.")
@@ -43,26 +41,28 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
43
  # 1. Instantiate Agent ( modify this part to create your agent)
44
  try:
45
  # agent = builder.compile(checkpointer=memory)
46
- agent = builder.compile() # Memory less
47
  agent_config = create_config()
48
  system_prompt = get_system_prompt()
49
  except Exception as e:
50
  print(f"Error instantiating agent: {e}")
51
  return f"Error initializing agent: {e}", None
52
 
53
- # define function to call agent
54
  def run_agent(query: str, file_name: str = ""):
55
  separator = "-" * 20 + "\n"
56
- print(separator + f"Agent received question (first 50 chars): {query[:50]}...")
57
  if file_name != "":
58
  query = insert_file_into_query(query, file_name)
59
  response = agent.invoke(
60
  {"messages": [system_prompt, HumanMessage(content=query)]},
61
- )
62
  # Print debug message
63
  print("All messages >>")
64
- pprint(response["messages"])
65
- text_response = str(response["messages"][-1].content).split("FINAL ANSWER:")[-1].strip()
 
 
66
  print(f"Agent returning answer: {text_response}\n" + separator)
67
  return text_response
68
 
@@ -77,16 +77,16 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
77
  response.raise_for_status()
78
  questions_data = response.json()
79
  if not questions_data:
80
- print("Fetched questions list is empty.")
81
- return "Fetched questions list is empty or invalid format.", None
82
  print(f"Fetched {len(questions_data)} questions.")
83
  except requests.exceptions.RequestException as e:
84
  print(f"Error fetching questions: {e}")
85
  return f"Error fetching questions: {e}", None
86
  except requests.exceptions.JSONDecodeError as e:
87
- print(f"Error decoding JSON response from questions endpoint: {e}")
88
- print(f"Response text: {response.text[:500]}")
89
- return f"Error decoding server response for questions: {e}", None
90
  except Exception as e:
91
  print(f"An unexpected error occurred fetching questions: {e}")
92
  return f"An unexpected error occurred fetching questions: {e}", None
@@ -101,7 +101,7 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
101
  if not task_id or question_text is None:
102
  print(f"Skipping item with missing task_id or question: {item}")
103
  continue
104
-
105
  # Get task file if any
106
  question_file = item.get("file_name", "")
107
  try:
@@ -113,12 +113,26 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
113
  question_file = str(file_path) if file_path is not None else ""
114
  try:
115
  submitted_answer = run_agent(question_text, question_file)
116
- answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
117
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
 
 
 
 
 
 
 
 
118
  except Exception as e:
119
- print(f"Error running agent on task {task_id}: {e}")
120
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
121
-
 
 
 
 
 
 
122
  # Clean files
123
  if file_path is not None:
124
  os.remove(file_path)
@@ -127,8 +141,12 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
127
  print("Agent did not produce any answers to submit.")
128
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
129
 
130
- # 4. Prepare Submission
131
- submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
 
 
 
 
132
  status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
133
  print(status_update)
134
 
@@ -198,20 +216,19 @@ with gr.Blocks() as demo:
198
 
199
  run_button = gr.Button("Run Evaluation & Submit All Answers")
200
 
201
- status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
 
 
202
  # Removed max_rows=10 from DataFrame constructor
203
  results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
204
 
205
- run_button.click(
206
- fn=run_and_submit_all,
207
- outputs=[status_output, results_table]
208
- )
209
 
210
  if __name__ == "__main__":
211
- print("\n" + "-"*30 + " App Starting " + "-"*30)
212
  # Check for SPACE_HOST and SPACE_ID at startup for information
213
  space_host_startup = os.getenv("SPACE_HOST")
214
- space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
215
 
216
  if space_host_startup:
217
  print(f"✅ SPACE_HOST found: {space_host_startup}")
@@ -219,14 +236,18 @@ if __name__ == "__main__":
219
  else:
220
  print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
221
 
222
- if space_id_startup: # Print repo URLs if SPACE_ID is found
223
  print(f"✅ SPACE_ID found: {space_id_startup}")
224
  print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
225
- print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
 
 
226
  else:
227
- print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
 
 
228
 
229
- print("-"*(60 + len(" App Starting ")) + "\n")
230
 
231
  print("Launching Gradio Interface for Basic Agent Evaluation...")
232
- demo.launch(debug=True, share=False)
 
1
+ from agent import (
2
+ builder,
3
+ HumanMessage,
4
+ memory,
5
+ create_config,
6
+ get_system_prompt,
7
+ insert_file_into_query,
8
+ download_requested_file,
9
+ )
10
+ from pprint import pprint
11
  import gradio as gr
 
12
  import inspect
13
+ import os
14
  import pandas as pd
15
+ import requests
 
16
 
17
  # (Keep Constants as is)
18
  # --- Constants ---
19
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
20
 
21
+
22
+ def run_and_submit_all(profile: gr.OAuthProfile | None):
 
 
 
 
 
 
 
 
 
 
23
  """
24
  Fetches all questions, runs the BasicAgent on them, submits all answers,
25
  and displays the results.
26
  """
27
  # --- Determine HF Space Runtime URL and Repo URL ---
28
+ space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
29
 
30
  if profile:
31
+ username = f"{profile.username}"
32
  print(f"User logged in: {username}")
33
  else:
34
  print("User not logged in.")
 
41
  # 1. Instantiate Agent ( modify this part to create your agent)
42
  try:
43
  # agent = builder.compile(checkpointer=memory)
44
+ agent = builder.compile() # Memory less
45
  agent_config = create_config()
46
  system_prompt = get_system_prompt()
47
  except Exception as e:
48
  print(f"Error instantiating agent: {e}")
49
  return f"Error initializing agent: {e}", None
50
 
51
+ # define function to call agent
52
  def run_agent(query: str, file_name: str = ""):
53
  separator = "-" * 20 + "\n"
54
+ print(separator + f"Agent received question (first 100 chars): {query[:100]}...")
55
  if file_name != "":
56
  query = insert_file_into_query(query, file_name)
57
  response = agent.invoke(
58
  {"messages": [system_prompt, HumanMessage(content=query)]},
59
+ )
60
  # Print debug message
61
  print("All messages >>")
62
+ pprint(response["messages"], compact=False)
63
+ text_response = (
64
+ str(response["messages"][-1].content).split("FINAL ANSWER:")[-1].strip()
65
+ )
66
  print(f"Agent returning answer: {text_response}\n" + separator)
67
  return text_response
68
 
 
77
  response.raise_for_status()
78
  questions_data = response.json()
79
  if not questions_data:
80
+ print("Fetched questions list is empty.")
81
+ return "Fetched questions list is empty or invalid format.", None
82
  print(f"Fetched {len(questions_data)} questions.")
83
  except requests.exceptions.RequestException as e:
84
  print(f"Error fetching questions: {e}")
85
  return f"Error fetching questions: {e}", None
86
  except requests.exceptions.JSONDecodeError as e:
87
+ print(f"Error decoding JSON response from questions endpoint: {e}")
88
+ print(f"Response text: {response.text[:500]}")
89
+ return f"Error decoding server response for questions: {e}", None
90
  except Exception as e:
91
  print(f"An unexpected error occurred fetching questions: {e}")
92
  return f"An unexpected error occurred fetching questions: {e}", None
 
101
  if not task_id or question_text is None:
102
  print(f"Skipping item with missing task_id or question: {item}")
103
  continue
104
+
105
  # Get task file if any
106
  question_file = item.get("file_name", "")
107
  try:
 
113
  question_file = str(file_path) if file_path is not None else ""
114
  try:
115
  submitted_answer = run_agent(question_text, question_file)
116
+ answers_payload.append(
117
+ {"task_id": task_id, "submitted_answer": submitted_answer}
118
+ )
119
+ results_log.append(
120
+ {
121
+ "Task ID": task_id,
122
+ "Question": question_text,
123
+ "Submitted Answer": submitted_answer,
124
+ }
125
+ )
126
  except Exception as e:
127
+ print(f"Error running agent on task {task_id}: {e}")
128
+ results_log.append(
129
+ {
130
+ "Task ID": task_id,
131
+ "Question": question_text,
132
+ "Submitted Answer": f"AGENT ERROR: {e}",
133
+ }
134
+ )
135
+
136
  # Clean files
137
  if file_path is not None:
138
  os.remove(file_path)
 
141
  print("Agent did not produce any answers to submit.")
142
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
143
 
144
+ # 4. Prepare Submission
145
+ submission_data = {
146
+ "username": username.strip(),
147
+ "agent_code": agent_code,
148
+ "answers": answers_payload,
149
+ }
150
  status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
151
  print(status_update)
152
 
 
216
 
217
  run_button = gr.Button("Run Evaluation & Submit All Answers")
218
 
219
+ status_output = gr.Textbox(
220
+ label="Run Status / Submission Result", lines=5, interactive=False
221
+ )
222
  # Removed max_rows=10 from DataFrame constructor
223
  results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
224
 
225
+ run_button.click(fn=run_and_submit_all, outputs=[status_output, results_table])
 
 
 
226
 
227
  if __name__ == "__main__":
228
+ print("\n" + "-" * 30 + " App Starting " + "-" * 30)
229
  # Check for SPACE_HOST and SPACE_ID at startup for information
230
  space_host_startup = os.getenv("SPACE_HOST")
231
+ space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
232
 
233
  if space_host_startup:
234
  print(f"✅ SPACE_HOST found: {space_host_startup}")
 
236
  else:
237
  print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
238
 
239
+ if space_id_startup: # Print repo URLs if SPACE_ID is found
240
  print(f"✅ SPACE_ID found: {space_id_startup}")
241
  print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
242
+ print(
243
+ f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main"
244
+ )
245
  else:
246
+ print(
247
+ "ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined."
248
+ )
249
 
250
+ print("-" * (60 + len(" App Starting ")) + "\n")
251
 
252
  print("Launching Gradio Interface for Basic Agent Evaluation...")
253
+ demo.launch(debug=True, share=False)
tools.py CHANGED
@@ -1,18 +1,16 @@
1
- # Tools extracted from one of leader repos > https://huggingface.co/spaces/baixianger/RobotPai/blob/main/agent.py
2
-
3
- from langchain_tavily import TavilySearch
4
- from langchain_community.document_loaders import WikipediaLoader
5
  from langchain_community.document_loaders import ArxivLoader
 
6
  from langchain_community.vectorstores import SupabaseVectorStore
7
  from langchain_core.messages import SystemMessage, HumanMessage
 
8
  from langchain_core.tools import tool
 
9
  from langchain.tools.retriever import create_retriever_tool
10
- from langchain_core.messages import ToolMessage
11
- from urllib.parse import urlparse
12
- from typing import Dict
13
  from markitdown import MarkItDown
14
  from pathlib import Path
15
- from google import genai
 
16
  import os
17
 
18
 
@@ -75,12 +73,12 @@ def modulus(a: int, b: int) -> int:
75
 
76
  @tool(parse_docstring=True)
77
  def wiki_search(query: str) -> Dict[str, list]:
78
- """Search Wikipedia for a query and return maximum 2 results.
79
 
80
  Args:
81
  query: The search query.
82
  """
83
- search_docs = WikipediaLoader(query=query, load_max_docs=2).load()
84
  formatted_search_docs = "\n\n---\n\n".join(
85
  [
86
  f'<Document source="{doc.metadata["source"]}" page="{doc.metadata.get("page", "")}"/>\n{doc.page_content}\n</Document>'
@@ -97,7 +95,7 @@ def web_search(query: str) -> ToolMessage:
97
  Args:
98
  query: The search query.
99
  """
100
- return TavilySearch(max_results=4, include_images=False).invoke({"query": query})
101
 
102
 
103
  @tool(parse_docstring=True)
 
1
+ from google import genai
 
 
 
2
  from langchain_community.document_loaders import ArxivLoader
3
+ from langchain_community.document_loaders import WikipediaLoader
4
  from langchain_community.vectorstores import SupabaseVectorStore
5
  from langchain_core.messages import SystemMessage, HumanMessage
6
+ from langchain_core.messages import ToolMessage
7
  from langchain_core.tools import tool
8
+ from langchain_tavily import TavilySearch
9
  from langchain.tools.retriever import create_retriever_tool
 
 
 
10
  from markitdown import MarkItDown
11
  from pathlib import Path
12
+ from typing import Dict
13
+ from urllib.parse import urlparse
14
  import os
15
 
16
 
 
73
 
74
  @tool(parse_docstring=True)
75
  def wiki_search(query: str) -> Dict[str, list]:
76
+ """Search Wikipedia for a query and return maximum 3 results.
77
 
78
  Args:
79
  query: The search query.
80
  """
81
+ search_docs = WikipediaLoader(query=query, load_max_docs=3).load()
82
  formatted_search_docs = "\n\n---\n\n".join(
83
  [
84
  f'<Document source="{doc.metadata["source"]}" page="{doc.metadata.get("page", "")}"/>\n{doc.page_content}\n</Document>'
 
95
  Args:
96
  query: The search query.
97
  """
98
+ return TavilySearch(max_results=5, include_images=False).invoke({"query": query})
99
 
100
 
101
  @tool(parse_docstring=True)