wt002 commited on
Commit
0b28c6a
Β·
verified Β·
1 Parent(s): d17ef16

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +171 -18
app.py CHANGED
@@ -1,41 +1,194 @@
1
  import os
2
  import gradio as gr
3
  import requests
4
- import inspect
 
 
 
 
 
 
5
  import pandas as pd
6
- from langchain_core.messages import HumanMessage
7
- from agent import build_graph
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
 
16
 
17
  class BasicAgent:
18
  def __init__(self):
19
- print("BasicAgent initialized.")
20
- def __call__(self, question: str) -> str:
21
- print(f"Agent received question (first 50 chars): {question[:50]}...")
22
- fixed_answer = "This is a default answer."
23
- print(f"Agent returning fixed answer: {fixed_answer}")
24
- return fixed_answer
25
 
26
- class BasicAgent:
27
- """A langgraph agent."""
28
- def __init__(self):
29
  print("BasicAgent initialized.")
30
- self.graph = build_graph()
31
 
32
  def __call__(self, question: str) -> str:
33
  print(f"Agent received question (first 50 chars): {question[:50]}...")
34
- # Wrap the question in a HumanMessage from langchain_core
35
- messages = [HumanMessage(content=question)]
36
- messages = self.graph.invoke({"messages": messages})
37
- answer = messages['messages'][-1].content
38
- return answer[14:]
39
 
40
  def run_and_submit_all( profile: gr.OAuthProfile | None):
41
  """
 
1
  import os
2
  import gradio as gr
3
  import requests
4
+ import openai
5
+ from smolagents import OpenAIServerModel, DuckDuckGoSearchTool, CodeAgent, WikipediaSearchTool
6
+ from pathlib import Path
7
+ import tempfile
8
+ from smolagents.tools import PipelineTool, Tool
9
+ import pathlib
10
+ from typing import Union, Optional
11
  import pandas as pd
12
+ from tabulate import tabulate # pragma: no cover – fallback path
13
+ import re
14
 
15
  # (Keep Constants as is)
16
  # --- Constants ---
17
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
18
 
19
+
20
+ class SpeechToTextTool(PipelineTool):
21
+ """
22
+ Transcribes an audio file to text using the OpenAI Whisper API.
23
+ Only local file paths are supported.
24
+ """
25
+ default_checkpoint = "openai/whisper-1" # purely informational here
26
+ description = (
27
+ "This tool sends an audio file to OpenAI Whisper and returns the "
28
+ "transcribed text."
29
+ )
30
+ name = "transcriber"
31
+ inputs = {
32
+ "audio": {
33
+ "type": "string",
34
+ "description": "Absolute or relative path to a local audio file.",
35
+ }
36
+ }
37
+ output_type = "string"
38
+
39
+ # ──────────────────────────────────────────────────────────────────────────
40
+ # Public interface
41
+ # ──────────────────────────────────────────────────────────────────────────
42
+ def __call__(self, audio: str) -> str:
43
+ """
44
+ Convenience wrapper so the tool can be used like a regular function:
45
+ text = SpeechToTextTool()(path_to_audio)
46
+ """
47
+ return self._transcribe(audio)
48
+
49
+ # ──────────────────────────────────────────────────────────────────────────
50
+ # Internal helpers
51
+ # ──────────────────────────────────────────────────────────────────────────
52
+ @staticmethod
53
+ def _transcribe(audio_path: str) -> str:
54
+ # ----- validation ----------------------------------------------------
55
+ if not isinstance(audio_path, str):
56
+ raise TypeError(
57
+ "Parameter 'audio' must be a string containing the file path."
58
+ )
59
+ path = Path(audio_path).expanduser().resolve()
60
+ if not path.is_file():
61
+ raise FileNotFoundError(f"No such audio file: {path}")
62
+
63
+ # ----- API call ------------------------------------------------------
64
+ with path.open("rb") as fp:
65
+ response = openai.audio.transcriptions.create(
66
+ file=fp,
67
+ model="whisper-1", # currently the only Whisper model
68
+ response_format="text" # returns plain text instead of JSON
69
+ )
70
+
71
+ # For response_format="text", `response` is already the raw transcript
72
+ return response
73
+
74
+ class ExcelToTextTool(Tool):
75
+ """Render an Excel worksheet as Markdown text."""
76
+
77
+ # ------------------------------------------------------------------
78
+ # Required smol‑agents metadata
79
+ # ------------------------------------------------------------------
80
+ name = "excel_to_text"
81
+ description = (
82
+ "Read an Excel file and return a Markdown table of the requested sheet. "
83
+ "Accepts either the sheet name or the zero-based index."
84
+ )
85
+
86
+ inputs = {
87
+ "excel_path": {
88
+ "type": "string",
89
+ "description": "Path to the Excel file (.xlsx / .xls).",
90
+ },
91
+ "sheet_name": {
92
+ "type": "string",
93
+ "description": (
94
+ "Worksheet name or zero‑based index *as a string* (optional; default first sheet)."
95
+ ),
96
+ "nullable": True,
97
+ },
98
+ }
99
+
100
+ output_type = "string"
101
+
102
+ # ------------------------------------------------------------------
103
+ # Core logic
104
+ # ------------------------------------------------------------------
105
+ def forward(
106
+ self,
107
+ excel_path: str,
108
+ sheet_name: Optional[str] = None,
109
+ ) -> str:
110
+ """Load *excel_path* and return the sheet as a Markdown table."""
111
+
112
+ path = pathlib.Path(excel_path).expanduser().resolve()
113
+ if not path.exists():
114
+ return f"Error: Excel file not found at {path}"
115
+
116
+ try:
117
+ # Interpret sheet identifier -----------------------------------
118
+ sheet: Union[str, int]
119
+ if sheet_name is None or sheet_name == "":
120
+ sheet = 0 # first sheet
121
+ else:
122
+ # If the user passed a numeric string (e.g. "1"), cast to int
123
+ sheet = int(sheet_name) if sheet_name.isdigit() else sheet_name
124
+
125
+ # Load worksheet ----------------------------------------------
126
+ df = pd.read_excel(path, sheet_name=sheet)
127
+
128
+ # Render to Markdown; fall back to tabulate if needed ---------
129
+ if hasattr(pd.DataFrame, "to_markdown"):
130
+ return df.to_markdown(index=False)
131
+ from tabulate import tabulate # pragma: no cover – fallback path
132
+
133
+ return tabulate(df, headers="keys", tablefmt="github", showindex=False)
134
+
135
+ except Exception as exc: # broad catch keeps the agent chat‑friendly
136
+ return f"Error reading Excel file: {exc}"
137
+
138
+
139
+ def download_file_if_any(base_api_url: str, task_id: str) -> str | None:
140
+ """
141
+ Try GET /files/{task_id}.
142
+ β€’ On HTTP 200 β†’ save to a temp dir and return local path.
143
+ β€’ On 404 β†’ return None.
144
+ β€’ On other errors β†’ raise so caller can log / handle.
145
+ """
146
+ url = f"{base_api_url}/files/{task_id}"
147
+ try:
148
+ resp = requests.get(url, timeout=30)
149
+ if resp.status_code == 404:
150
+ return None # no file
151
+ resp.raise_for_status() # raise on 4xx/5xx β‰  404
152
+ except requests.exceptions.HTTPError as e:
153
+ # propagate non-404 errors (403, 500, …)
154
+ raise e
155
+
156
+ # β–Έ Save bytes to a named file inside the system temp dir
157
+ # Try to keep original extension from Content-Disposition if present.
158
+ cdisp = resp.headers.get("content-disposition", "")
159
+ filename = task_id # default base name
160
+ if "filename=" in cdisp:
161
+ m = re.search(r'filename="([^"]+)"', cdisp)
162
+ if m:
163
+ filename = m.group(1) # keep provided name
164
+
165
+ tmp_dir = Path(tempfile.gettempdir()) / "gaia_files"
166
+ tmp_dir.mkdir(exist_ok=True)
167
+ file_path = tmp_dir / filename
168
+ with open(file_path, "wb") as f:
169
+ f.write(resp.content)
170
+ return str(file_path)
171
+
172
  # --- Basic Agent Definition ---
173
  # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
174
 
175
 
176
  class BasicAgent:
177
  def __init__(self):
178
+ self.agent = CodeAgent(
179
+ model=OpenAIServerModel(model_id="gpt-4o"),
180
+ tools=[DuckDuckGoSearchTool(), WikipediaSearchTool(), SpeechToTextTool(), ExcelToTextTool()],
181
+ add_base_tools=True,
182
+ additional_authorized_imports=['pandas','numpy','csv','subprocess']
183
+ )
184
 
 
 
 
185
  print("BasicAgent initialized.")
 
186
 
187
  def __call__(self, question: str) -> str:
188
  print(f"Agent received question (first 50 chars): {question[:50]}...")
189
+ fixed_answer = self.agent.run(question)
190
+ print(f"Agent returning answer: {fixed_answer}")
191
+ return fixed_answer
 
 
192
 
193
  def run_and_submit_all( profile: gr.OAuthProfile | None):
194
  """