|
import os |
|
import base64 |
|
import requests |
|
from openai import OpenAI |
|
from duckduckgo_search import DDGS |
|
|
|
|
|
|
|
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: |
|
|
|
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#)." |
|
) |
|
|
|
|
|
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: |
|
|
|
search_snippet = self.web_search(question) |
|
|
|
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}" |
|
) |
|
|
|
|
|
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() |
|
|
|
return answer |