dawid-lorek's picture
Update agent.py
02c61e8 verified
raw
history blame
4.05 kB
import os
import base64
import requests
from openai import OpenAI
from duckduckgo_search import DDGS
# You can expand with image/audio/etc tools as needed
class BasicAgent:
def __init__(self):
self.llm = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
print("BasicAgent initialized.")
def web_search(self, query: str, max_results: int = 5) -> str:
"""Search the web using DuckDuckGo for current information."""
try:
with DDGS() as ddgs:
results = list(ddgs.text(query, max_results=max_results))
if not results:
return f"No results found for query: {query}"
formatted_results = f"Web search results for '{query}':\n\n"
for i, result in enumerate(results, 1):
title = result.get('title', 'No title')
body = result.get('body', 'No description')
href = result.get('href', 'No URL')
formatted_results += f"{i}. {title}\n"
formatted_results += f" URL: {href}\n"
formatted_results += f" Description: {body}\n\n"
return formatted_results
except Exception as e:
return f"Error performing web search: {str(e)}"
def fetch_file(self, task_id):
DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
try:
url = f"{DEFAULT_API_URL}/files/{task_id}"
r = requests.get(url, timeout=10)
r.raise_for_status()
return url, r.content, r.headers.get("Content-Type", "")
except:
return None, None, None
def describe_image(self, img_path: str) -> str:
# This is optional: image-based chess move recognition
try:
r = requests.get(img_path, timeout=10)
image_bytes = r.content
image_base64 = base64.b64encode(image_bytes).decode("utf-8")
prompt = (
"You're a chess assistant. Answer only with the best move in algebraic notation (e.g., Qd1#)."
)
# In this template, you'd need your LLM to accept vision input.
# If not, just return an error or a stub.
return "[Image analysis not implemented in this agent.]"
except Exception as e:
return f"Error extracting text: {str(e)}"
def __call__(self, question: str, task_id: str = None) -> str:
# Step 1: Always web search and build prompt
search_snippet = self.web_search(question)
# Step 2: Compose the mandated prompt exactly as specified
full_prompt = (
"You are a general AI assistant. I will ask you a question. "
"Report your thoughts, and finish your answer with the following template: "
"FINAL ANSWER: [YOUR FINAL ANSWER]. YOUR FINAL ANSWER should be a number OR as few words as possible OR a comma separated list of numbers and/or strings. "
"If you are asked for a number, don't use comma to write your number neither use units such as $ or percent sign unless specified otherwise. "
"If you are asked for a string, don't use articles, neither abbreviations (e.g. for cities), and write the digits in plain text unless specified otherwise. "
"If you are asked for a comma separated list, apply the above rules depending of whether the element to be put in the list is a number or a string.\n\n"
f"Here are web search results and the question:\n{search_snippet}\n\nQuestion: {question}"
)
# Step 3: Get answer from OpenAI, temperature 0 for max determinism
response = self.llm.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": full_prompt},
],
temperature=0.0,
max_tokens=512,
)
answer = response.choices[0].message.content.strip()
# You may want to extract just the "FINAL ANSWER: ..." line, or you can return as is
return answer