import os from smolagents import CodeAgent, LiteLLMModel, load_tool, ToolCollection, HfApiModel, InferenceClientModel, TransformersModel, OpenAIServerModel from smolagents import ToolCallingAgent, PythonInterpreterTool, tool, WikipediaSearchTool from smolagents import DuckDuckGoSearchTool, FinalAnswerTool, VisitWebpageTool, SpeechToTextTool from mcp import StdioServerParameters from huggingface_hub import HfApi, login from dotenv import load_dotenv from typing import Optional from models.gemini_model import GeminiModel import requests import re import string import random import textwrap import nltk import spacy DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space" @tool def download_file(task_id: str) -> str: """ Returns the file path of the downloaded file. Args: task_id: the ID of the task to download the file for. """ # Implement your file download logic here data = requests.get(f"{DEFAULT_API_URL}/files/{task_id}") if data.status_code == 200: file_path = f"/tmp/{task_id}" with open(file_path, "wb") as file: file.write(data.content) return file_path else: raise Exception(f"Failed to download file: {data.status_code}") @tool def get_file_content_as_text(task_id: str) -> str: """ Returns the content of the file as text. Args: task_id: the ID of the task to get the file content for. """ # Implement your file content retrieval logic here data = requests.get(f"{DEFAULT_API_URL}/files/{task_id}") if data.status_code == 200: return data.text else: raise Exception(f"Failed to get file content: {data.status_code}") def load_hf_model(modelName: str): """ Lädt ein Hugging Face Modell und gibt den Agenten zurück. :param modelName: Name des Modells :return: model """ load_dotenv() # Lädt automatisch .env im Projektordner hf_token = os.getenv("hugging_face") login(token=hf_token) # Authentifizierung bei Hugging Face # Modell initialisieren model = HfApiModel(model_id=modelName) return model def load_ollama_model(modelName: str): """ Lädt ein Ollama Modell und gibt den Agenten zurück. :param modelName: Name des Modells :return: model """ # Modell initialisieren model = OpenAIServerModel(model_id=modelName, api_base="http://localhost:11434/v1") return model def load_lmStudio_model(modelName: str): """ Lädt ein LM Studio Modell und gibt den Agenten zurück. :param modelName: Name des Modells :return: model """ # Modell initialisieren #model = LiteLLMModel(model_id=modelName, api_base="http://localhost:1234") model = OpenAIServerModel(model_id=modelName, api_base="http://localhost:1234/v1") return model def load_gemini_model(): """ Lädt ein Gemini Modell und gibt den Agenten zurück. :return: model """ try: print(f"Gemini API Key: {os.getenv('GEMINI_API_KEY')}") model = LiteLLMModel(model_id="gemini/gemini-2.0-flash-exp", api_key=os.getenv("GEMINI_API_KEY")) #model = GeminiModel(api_key=os.getenv("GEMINI_API_KEY")) return model except Exception as e: print("Error loading Gemini model:", e) return None def get_agent(model_name:str, model_type:str) -> Optional[CodeAgent]: # Modell initialisieren match model_type: case "hugging face": model = load_hf_model(model_name) case "Ollama": model = load_ollama_model(model_name) case "Gemini": model = load_gemini_model() case "LMStudio": model = load_lmStudio_model(model_name) case _: print("Model type not supported.") return None #model = load_lmStudio_model("gemma-3-4b-it") #model = load_gemini_model() #mopip del = HfApiModel() #model=InferenceClientModel(model_id="meta-llama/Meta-Llama-3.1-8B-Instruct") #model = TransformersModel(model_id="HuggingFaceTB/SmolLM-135M-Instruct") # Tools laden web_search_tool = DuckDuckGoSearchTool() final_answer_tool = FinalAnswerTool() visit_webpage_tool = VisitWebpageTool() #speech_to_text_tool = SpeechToTextTool() #transcript_tool = load_tool("maguid28/TranscriptTool", trust_remote_code=True) #mcp_tool_collection = ToolCollection.from_mcp(server_parameters, trust_remote_code=True) #with ToolCollection.from_mcp(server_parameters, trust_remote_code=True) as tool_collection: # mcp_tool_agent = CodeAgent(tools=[*tool_collection.tools], add_base_tools=True) #server_parameters = StdioServerParameters( # command="uv", # args=["--quiet", "pubmedmcp@0.1.3"], # env={"UV_PYTHON": "3.12", **os.environ}, #) # #with ToolCollection.from_mcp(server_parameters, trust_remote_code=True) as tool_collection: # mcp_agent = CodeAgent(tools=[*tool_collection.tools], model=model, add_base_tools=True) variation_agent = CodeAgent( model=model, tools=[PythonInterpreterTool()], name="variation_agent", description="Get the user question and checks if the given question makes sense at all, if not, we try to modify the text like reverse. Provide the content / the questin as the 'task' argument." \ "The agent can write professional python code, focused on modifiying texts." \ "It has access to the following libraries: re, string, random, textwrap, nltk and spacy." \ "The goal is to find out, if a user question is a trick, and we might modify the content.", additional_authorized_imports=[ "re", "string", "random", "textwrap", "nltk", "spacy" ] ) variation_agent.system_prompt = "You are a text variation agent. You can write professional python code, focused on modifiying texts." \ "You can use the following libraries: re, string, random, textwrap, nltk and spacy." \ "Your goal is to find out, if a user question is a trick, and we might modify the content." code_agent = CodeAgent( name="code_agent", description="Can generate code an run it. It provides the possibility to download additional files if needed.", model=model, tools=[download_file, PythonInterpreterTool(), get_file_content_as_text], additional_authorized_imports=[ "geopandas", "plotly", "shapely", "json", "pandas", "numpy", ], verbosity_level=2, #final_answer_checks=[FinalAnswerTool()], max_steps=5, ) final_answer_tool = FinalAnswerTool() final_answer_tool.description = "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." tool_agent = CodeAgent( model=model, tools=[web_search_tool, visit_webpage_tool, WikipediaSearchTool(), final_answer_tool], verbosity_level=2, max_steps=15, managed_agents=[code_agent, variation_agent], planning_interval=5, ) return tool_agent # return tool_agent manager_agent = CodeAgent( #model=HfApiModel("deepseek-ai/DeepSeek-R1", provider="together", max_tokens=8096), model=model, tools=[web_search_tool, visit_webpage_tool], # managed_agents=[mcp_tool_agent], additional_authorized_imports=[ "geopandas", "plotly", "shapely", "json", "pandas", "numpy", ], planning_interval=5, verbosity_level=2, #final_answer_checks=[FinalAnswerTool()], max_steps=15 ) return manager_agent