Spaces:
Sleeping
Sleeping
| from typing import Any, Optional | |
| from smolagents.tools import Tool | |
| import io | |
| import openpyxl | |
| import os | |
| from smolagents import tool | |
| import requests | |
| from PIL import Image | |
| simplify_system_message = """ | |
| You are a general AI assistant. I will give you a question and answer, you should simplify answer. Your 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. | |
| """ | |
| def ToolReverseString(text: str) -> str: | |
| """ | |
| Use this tool only if you encounter text that seems to be written backwards | |
| Args: | |
| text: The string to reverse. | |
| """ | |
| return text[::-1] | |
| def ToolReadFiles(filepath: str) -> str: | |
| """ | |
| Downloads a .py or .xlsx file from a remote URL and returns its contents as plain text. | |
| Raises a recoverable exception if the file does not end with .py or .xlsx. | |
| Args: | |
| filepath: The path to the Python (.py) or Excel (.xlsx) file. | |
| """ | |
| root_url = "https://agents-course-unit4-scoring.hf.space/files/" | |
| # Strip the file extension from the url before downloading | |
| import os | |
| base, ext = os.path.splitext(filepath) | |
| url = root_url + base | |
| if filepath.endswith('.py'): | |
| response = requests.get(url) | |
| if response.status_code != 200: | |
| raise Exception(f"Recoverable: Failed to download file from {url}") | |
| return response.text | |
| elif filepath.endswith('.xlsx'): | |
| response = requests.get(url) | |
| if response.status_code != 200: | |
| raise Exception(f"Recoverable: Failed to download file from {url}") | |
| wb = openpyxl.load_workbook(io.BytesIO(response.content), data_only=True) | |
| result = [] | |
| for sheet in wb.worksheets: | |
| result.append(f"# Sheet: {sheet.title}") | |
| for row in sheet.iter_rows(values_only=True): | |
| result.append(','.join([str(cell) if cell is not None else '' for cell in row])) | |
| return '\n'.join(result) | |
| else: | |
| raise Exception("Recoverable: Only .py and .xlsx files can be read with this tool.") | |
| def ToolDownloadImage(filepath: str) -> str: | |
| """ | |
| Downloads an image file (.png, .jpg, .jpeg) from a remote URL and returns useful information about the image. | |
| This includes the image URL and basic metadata like dimensions and format. | |
| Raises a recoverable exception if the file is not a supported image type. | |
| Args: | |
| filepath: The path to the image file. | |
| """ | |
| root_url = "https://agents-course-unit4-scoring.hf.space/files/" | |
| base, ext = os.path.splitext(filepath) | |
| url = root_url + base | |
| if ext.lower() in ['.png', '.jpg', '.jpeg']: | |
| response = requests.get(url) | |
| if response.status_code != 200: | |
| raise Exception(f"Recoverable: Failed to download image from {url}") | |
| # Get image metadata using Pillow | |
| try: | |
| img = Image.open(io.BytesIO(response.content)) | |
| width, height = img.size | |
| format = img.format | |
| mode = img.mode | |
| # Return useful information about the image | |
| return f"Image URL: {url}\nFormat: {format}\nDimensions: {width}x{height}\nMode: {mode}" | |
| except ImportError: | |
| # Fallback if PIL is not available | |
| content_type = response.headers.get('Content-Type', 'unknown') | |
| content_length = response.headers.get('Content-Length', 'unknown') | |
| return f"Content-Type: {content_type}\nSize: {content_length} bytes" | |
| else: | |
| raise Exception("Recoverable: Only .png, .jpg, and .jpeg files can be processed with this tool.") | |
| #class FinalAnswerTool(Tool): | |
| # name = "final_answer" | |
| # description = "Provides a final answer to the given problem." | |
| # inputs = {'answer': {'type': 'any', 'description': 'The final answer to the problem'}} | |
| # output_type = "any" | |
| # def forward(self, answer: Any) -> Any: | |
| # return answer | |
| # def __init__(self, *args, **kwargs): | |
| # self.is_initialized = False | |
| class FinalAnswerTool(Tool): | |
| name = "simplify_answer" | |
| description = ( | |
| "Simplify the final answer." | |
| "Be sure to use this as the last step to prepare the final answer." | |
| ) | |
| inputs = { | |
| "question": { | |
| "type": "string", | |
| "description": "The question from the user.", | |
| }, | |
| "answer": { | |
| "type": "string", | |
| "description": "The existing answer to be simplified.", | |
| } | |
| } | |
| output_type = "string" | |
| def __init__(self, api_model): | |
| super().__init__() | |
| self.api_model = api_model | |
| def forward(self, question: str, answer: str) -> str: | |
| try: | |
| response_message = self.api_model(messages=[ | |
| {"role": MessageRole.SYSTEM, "content": [{"type": "text", "text": simplify_system_message }]}, | |
| {"role": MessageRole.ASSISTANT, "content": [{"type": "text", "text": f"QUESTION: {question}"}]}, | |
| {"role": MessageRole.ASSISTANT, "content": [{"type": "text", "text": f"ANSWER: {answer}"}]} | |
| ]) | |
| return response_message.content | |
| except requests.exceptions.Timeout: | |
| return "The request timed out. Please try again later or check the URL." | |
| except RequestException as e: | |
| return f"Error fetching the webpage: {str(e)}" | |
| except Exception as e: | |
| return f"An unexpected error occurred: {str(e)}" | |