| |
| import os |
| import requests |
| import pandas as pd |
| import google.genai as genai |
| import base64 |
| from openai import OpenAI |
| from smolagents import Tool |
|
|
| |
| from consts import DEFAULT_API_URL |
|
|
| |
| try: |
| from app import _SELECTED_MODEL_ID |
| if not _SELECTED_MODEL_ID: |
| raise ImportError("Model ID not set in app.py") |
| except ImportError: |
| _SELECTED_MODEL_ID = "gpt-4.1-mini" |
|
|
| class GetTaskFileTool(Tool): |
| name = "get_task_file_tool" |
| description = """This tool downloads the file content associated with the given task_id if exists. Returns absolute file path""" |
| inputs = { |
| "task_id": {"type": "string", "description": "Task id"}, |
| "file_name": {"type": "string", "description": "File name"}, |
| } |
| output_type = "string" |
|
|
| def forward(self, task_id: str, file_name: str) -> str: |
| response = requests.get(f"{DEFAULT_API_URL}/files/{task_id}", timeout=15) |
| response.raise_for_status() |
| with open(file_name, 'wb') as file: |
| file.write(response.content) |
| return os.path.abspath(file_name) |
|
|
| class LoadXlsxFileTool(Tool): |
| name = "load_xlsx_file_tool" |
| description = """This tool loads xlsx file into pandas and returns it""" |
| inputs = { |
| "file_path": {"type": "string", "description": "File path"} |
| } |
| output_type = "object" |
|
|
| def forward(self, file_path: str) -> object: |
| return pd.read_excel(file_path) |
|
|
| class LoadTextFileTool(Tool): |
| name = "load_text_file_tool" |
| description = """This tool loads any text file""" |
| inputs = { |
| "file_path": {"type": "string", "description": "File path"} |
| } |
| output_type = "string" |
|
|
| def forward(self, file_path: str) -> object: |
| with open(file_path, 'r', encoding='utf-8') as file: |
| return file.read() |
|
|
| class AnalyzeImageTool(Tool): |
| name = "analyze_image_tool" |
| description = """This tool performs a custom analysis of the provided image and returns the corresponding result.""" |
| inputs = { |
| "image_path": {"type": "string", "description": "Image path"}, |
| "task": {"type": "string", "description": "Task to perform on the image, be detailed and clear"}, |
| } |
| output_type = "string" |
| |
| def __init__(self, model_id=None): |
| super().__init__() |
| self.model_id = model_id or "gpt-4.1-mini" |
| |
| def forward(self, image_path: str, task: str) -> str: |
| """ |
| Analyze the image at `image_path` according to `task` and return the textual result. |
| """ |
| header = "Image analysis result:\n\n" |
| llm_instruction = ( |
| "You are a highly capable image analysis tool, designed to examine images and deliver detailed descriptions, " |
| "insights, and relevant interpretations based on the task at hand.\n\n" |
| "Approach the task methodically and provide a thorough and well-reasoned response to the following:\n\n---\nTask:\n" |
| f"{task}\n\n" |
| ) |
| try: |
| if "gemini" in self.model_id: |
| return header + self._analyze_with_gemini(image_path, llm_instruction) |
| return header + self._analyze_with_openai(image_path, llm_instruction) |
| except Exception as e: |
| return f"Error analyzing image: {e}.\nPlease try again." |
|
|
| def _analyze_with_gemini(self, image_path: str, task: str) -> str: |
| api_key = os.getenv("GOOGLEAI_API_KEY") |
| if not api_key: |
| raise ValueError("Environment variable GOOGLEAI_API_KEY is not set.") |
| client = genai.Client(api_key=api_key) |
|
|
| with open(image_path, "rb") as f: |
| image_data = f.read() |
|
|
| contents = [ |
| {"inline_data": {"mime_type": "image/jpeg", "data": image_data}}, |
| {"text": task}, |
| ] |
| response = client.models.generate_content(model=self.model_id, contents=contents) |
| return response.candidates[0].content.parts[0].text |
|
|
| def _analyze_with_openai(self, image_path: str, task: str) -> str: |
| client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) |
|
|
| with open(image_path, "rb") as f: |
| encoded_image = base64.b64encode(f.read()).decode("utf-8") |
|
|
| payload = [ |
| { |
| "role": "user", |
| "content": [ |
| {"type": "input_text", "text": task}, |
| {"type": "input_image", "image_url": f"data:image/jpeg;base64,{encoded_image}"}, |
| ], |
| } |
| ] |
| response = client.responses.create(model=self.model_id, input=payload) |
| return response.output[0].content[0].text |
|
|