dawid-lorek commited on
Commit
9f06b73
·
verified ·
1 Parent(s): 9881ede

Update agent.py

Browse files
Files changed (1) hide show
  1. agent.py +79 -85
agent.py CHANGED
@@ -1,117 +1,111 @@
1
- # agent.py zaktualizowany z obsługą błędów, braków plików i bezpiecznym Pythonem
2
 
3
  import os
4
- import asyncio
5
- from llama_index.llms.openai import OpenAI
6
- from llama_index.core.agent import FunctionCallingAgent
7
- from llama_index.core.tools import FunctionTool
8
 
9
  from langchain_community.utilities.wikipedia import WikipediaAPIWrapper
10
- from langchain_community.document_loaders import YoutubeLoader
11
  from langchain_experimental.tools.python.tool import PythonREPLTool
 
12
 
13
- import whisper
14
- import openpyxl
15
-
16
- # Check OpenAI key
17
- if os.getenv("OPENAI_API_KEY"):
18
- print("✅ Detected OPENAI_API_KEY")
19
- else:
20
- print("⚠️ Missing OPENAI_API_KEY – LLM may fail")
21
-
22
- # Tool 1 — Wikipedia
23
- wiki_api = WikipediaAPIWrapper(top_k_results=1, doc_content_chars_max=1000)
24
 
25
  def search_wikipedia(query: str) -> str:
26
- """Search Wikipedia for a given query and return relevant summary."""
27
  try:
28
- return wiki_api.run(query)
 
29
  except Exception as e:
30
- return f"Tool not available. ({e})"
31
-
32
- # Tool 2 — Python safe runner
33
- python_tool = PythonREPLTool()
34
 
35
  def run_python_code(code: str) -> str:
36
- """Run Python code safely."""
37
  try:
 
38
  if 'print' not in code:
39
  code = f"print({repr(code)})"
40
- return python_tool.run(code)
41
  except Exception as e:
42
- return f"[PYTHON ERROR] {e}"
43
-
44
- # Tool 3 — YouTube transcript
45
 
46
  def get_youtube_transcript(url: str) -> str:
47
- """Get transcript from YouTube video."""
48
  try:
49
  loader = YoutubeLoader.from_youtube_url(url, add_video_info=False)
50
  docs = loader.load()
51
  return " ".join(d.page_content for d in docs)
52
  except Exception as e:
53
- return f"Tool not available. ({e})"
54
-
55
- # Tool 4 — Whisper transcription
56
 
57
- def transcribe_audio(file_path: str) -> str:
58
- if not os.path.exists(file_path):
59
- return "Tool not available. (Missing file)"
60
  try:
61
- model = whisper.load_model("base")
62
- res = model.transcribe(file_path)
63
- return res["text"]
 
 
 
64
  except Exception as e:
65
- return f"Tool not available. ({e})"
66
 
67
- # Tool 5 Excel food sum
 
 
68
 
69
- def extract_excel_total_food_sales(file_path: str) -> str:
70
- if not os.path.exists(file_path):
71
- return "Tool not available. (Missing file)"
 
 
 
 
 
 
72
  try:
73
- wb = openpyxl.load_workbook(file_path)
74
- sheet = wb.active
75
- total = 0.0
76
- for _, category, amount in sheet.iter_rows(min_row=2, values_only=True):
77
- if isinstance(category, str) and "food" in category.lower():
78
- total += float(amount or 0)
79
- return f"${total:.2f}"
 
 
80
  except Exception as e:
81
- return f"Tool not available. ({e})"
82
-
83
- # Assemble tools
84
- TOOLS = [
85
- FunctionTool.from_defaults(search_wikipedia, return_direct=True, name="search_wikipedia"),
86
- FunctionTool.from_defaults(run_python_code, return_direct=True, name="run_python"),
87
- FunctionTool.from_defaults(get_youtube_transcript, return_direct=True, name="get_youtube_transcript"),
88
- FunctionTool.from_defaults(transcribe_audio, return_direct=True, name="transcribe_audio"),
89
- FunctionTool.from_defaults(extract_excel_total_food_sales, return_direct=True, name="extract_excel_total_food_sales")
90
- ]
91
-
92
- # Build agent
93
- llm = OpenAI(model="gpt-4")
94
-
95
- agent = FunctionCallingAgent.from_tools(
96
- tools=TOOLS,
97
- llm=llm,
98
- system_prompt="""
99
- You are a highly capable AI agent completing the GAIA benchmark.
100
-
101
- You MUST:
102
- - Always use tools when available.
103
- - If a tool returns 'None' or fails, try another or say 'Tool not available'.
104
- - Return only final answer in strict format (comma-separated, numbers, names, no explanations).
105
- - Do not guess. If unsure, state 'Tool not available'.
106
- - NEVER return raw tool errors, only result or fallback.
107
- """
108
- )
109
-
110
- # Agent call wrapper
111
- async def answer_question(question: str) -> str:
112
  try:
113
- response = await agent.achat(question)
114
- return response.response.strip()
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  except Exception as e:
116
- print("❌ Agent error:", e)
117
- return "[ERROR] " + str(e)
 
1
+ # agent.py HybridAgent: GAIA-style fallback + tools + no errors
2
 
3
  import os
4
+ import requests
5
+ import openai
6
+ import traceback
 
7
 
8
  from langchain_community.utilities.wikipedia import WikipediaAPIWrapper
 
9
  from langchain_experimental.tools.python.tool import PythonREPLTool
10
+ from langchain_community.document_loaders import YoutubeLoader
11
 
12
+ # Set OpenAI API key
13
+ openai.api_key = os.getenv("OPENAI_API_KEY")
 
 
 
 
 
 
 
 
 
14
 
15
  def search_wikipedia(query: str) -> str:
 
16
  try:
17
+ wiki = WikipediaAPIWrapper(top_k_results=1, doc_content_chars_max=1200)
18
+ return wiki.run(query)
19
  except Exception as e:
20
+ return f"[TOOL ERROR] Wikipedia: {e}"
 
 
 
21
 
22
  def run_python_code(code: str) -> str:
 
23
  try:
24
+ tool = PythonREPLTool()
25
  if 'print' not in code:
26
  code = f"print({repr(code)})"
27
+ return tool.run(code)
28
  except Exception as e:
29
+ return f"[TOOL ERROR] Python: {e}"
 
 
30
 
31
  def get_youtube_transcript(url: str) -> str:
 
32
  try:
33
  loader = YoutubeLoader.from_youtube_url(url, add_video_info=False)
34
  docs = loader.load()
35
  return " ".join(d.page_content for d in docs)
36
  except Exception as e:
37
+ return f"[TOOL ERROR] YouTube: {e}"
 
 
38
 
39
+ def fetch_file_context(task_id: str) -> str:
 
 
40
  try:
41
+ url = f"https://agents-course-unit4-scoring.hf.space/files/{task_id}"
42
+ resp = requests.get(url, timeout=10)
43
+ resp.raise_for_status()
44
+ if "text" in resp.headers.get("Content-Type", ""):
45
+ return resp.text[:3000] # Truncate to stay safe
46
+ return f"[Unsupported file type]"
47
  except Exception as e:
48
+ return f"[FILE ERROR] {e}"
49
 
50
+ def build_prompt(question: str, context: str = "") -> str:
51
+ return f"""
52
+ You are a highly skilled research assistant completing factual benchmark questions.
53
 
54
+ If any tools are required, try to simulate reasoning or summarize fallback.
55
+ Return a concise factual answer only – no explanations.
56
+
57
+ {context.strip()}
58
+
59
+ Question: {question.strip()}
60
+ Answer:"""
61
+
62
+ def ask_openai(prompt: str) -> str:
63
  try:
64
+ response = openai.ChatCompletion.create(
65
+ model="gpt-4-turbo",
66
+ messages=[
67
+ {"role": "system", "content": "Answer factually. Return only final result."},
68
+ {"role": "user", "content": prompt},
69
+ ],
70
+ temperature=0.0
71
+ )
72
+ return response.choices[0].message.content.strip()
73
  except Exception as e:
74
+ return f"[OPENAI ERROR] {e}"
75
+
76
+ # === Unified entry point ===
77
+
78
+ def answer_question(question: str, task_id: str = None) -> str:
79
+ try:
80
+ file_context = fetch_file_context(task_id) if task_id else ""
81
+
82
+ # Optional: tool-based enhancement
83
+ if "wikipedia" in question.lower():
84
+ wiki = search_wikipedia(question)
85
+ file_context += f"\n[Wikipedia] {wiki}"
86
+ elif "youtube.com" in question:
87
+ yt = get_youtube_transcript(question)
88
+ file_context += f"\n[YouTube Transcript] {yt}"
89
+ elif "* on the set" in question and file_context:
90
+ # Parse table to extract non-commutative elements
91
+ import re
92
+ import pandas as pd
93
+
 
 
 
 
 
 
 
 
 
 
 
94
  try:
95
+ table_lines = [line.strip() for line in file_context.splitlines() if '|' in line and '*' not in line[:2]]
96
+ headers = re.split(r'\|+', table_lines[0])[1:-1]
97
+ data_rows = [re.split(r'\|+', row)[1:-1] for row in table_lines[1:]]
98
+ index = [row[0] for row in data_rows]
99
+ matrix = [row[1:] for row in data_rows]
100
+ df = pd.DataFrame(matrix, index=index, columns=headers)
101
+
102
+ non_comm = set()
103
+ for a in df.index:
104
+ for b in df.columns:
105
+ if df.at[a, b] != df.at[b, a]:
106
+ non_comm.add(a)
107
+ non_comm.add(b)
108
+ result = ", ".join(sorted(non_comm))
109
+ file_context += f"\n[Parsed Non-Commutative Set] {result}"
110
  except Exception as e:
111
+ file_context += f"\n[Table Parse Error] {e}"