from smolagents import CodeAgent, InferenceClientModel, OpenAIServerModel import yaml from tools.final_answer import FinalAnswerTool from tools.visit_webpage import VisitWebpageTool from tools.web_search import DuckDuckGoSearchTool from tools.crypto_token_info_retriever_tool import CryptoTokenInfoRetrieverTool from tools.instructions_crypto_token_report import InstructionsCryptoTokenReportTool from tools.get_recent_prices_for_crypto_token import GetRecentPricesForCryptoTokenTool from Gradio_UI import GradioUI # These imports are for LangFuse import os from langfuse import get_client from openinference.instrumentation.smolagents import SmolagentsInstrumentor # These imports are for the RAG system from langchain_community.docstore.document import Document from langchain_text_splitters import RecursiveCharacterTextSplitter web_agent_model_id = 'Qwen/Qwen2.5-Coder-32B-Instruct' web_agent_model_provider = 'nscale' # web_agent_model_id = 'Qwen/Qwen3-Coder-30B-A3B-Instruct' # web_agent_model_provider = 'scaleway' # !!! Do NOT use un-priced inference models!!! # !!! NO !!! manager_agent_model_id = 'moonshotai/Kimi-K2-Thinking' manager_agent_model_id = 'Qwen/Qwen3-Next-80B-A3B-Thinking' manager_agent_model_provider = 'hyperbolic' # manager_agent_model_provider = 'ovhcloud' ### Load the Retrieval Augmented Generation (RAG) system with simulated data # This information is web pages about crypto tokens indicating the # origin location, date, and time # Simulate a knowledge base crypto_token_info = [ {"text": "Chainlink creation date: Sep 20, 2017 at 20:54 (UTC+3)", "source": "ICO Drops: Chainlink", "url":"https://icodrops.com/chainlink/"}, {"text": "Tokemak location: Santa Monica, California, United States", "source": "Crunchbase: Tokemak", "url":"https://www.crunchbase.com/organization/tokemak"}, {"text": "1inch location: Old Road Town, Saint Thomas Middle Island, Saint Kitts and Nevis", "source": "Crunchbase: 1inch", "url":"https://www.crunchbase.com/organization/1inch-limited"}, {"text": "Algorand creation date: 19 Jun 2019", "source": "Crypto Potato: algorand", "url":"https://cryptopotato.com/algorand/"}, {"text": "Tokemak creation date: Aug 3, 2021 at 00:00 (UTC+3)", "source": "ICO Drops: Tokemak", "url":"https://icodrops.com/tokemak/"}, {"text": "1inch creation date: Dec 25, 2020 at 00:00 (UTC+3)", "source": "ICO Drops: 1inch.exchange", "url":"https://icodrops.com/1inch-exchange/"}, {"text": "API3 creation date: Nov 30, 2020 at 00:00 (UTC+3)", "source": "ICO Drops: API3", "url":"https://icodrops.com/api3/"}, {"text": "Chainlink location: 90 North Church Street George Town Cayman Islands", "source": "Craft: Chainlink", "url":"https://craft.co/chainlink"}, {"text": "API3 location: George Town, Cayman Islands", "source": "BTCC Academy: Where is API3 located?", "url":"https://www.btcc.com/en-US/questions/detail/1820285960362004480"}, {"text": "Ripple Labs, Inc. (XRP) location: San Francisco, California, United States", "source": "Wikipedia: Ripple Labs", "url":"https://en.wikipedia.org/wiki/Ripple_Labs"}, {"text": "Ripple Labs, Inc. (XRP) creation date: June 2, 2012", "source": "U.Today: XRP Turns 9. Here's How It All Started", "url":"https://u.today/xrp-turns-9-heres-how-it-all-started"}, {"text": "Avalanche (AVAX) creation date: September 21, 2020", "source": "CEX.IO Spotlight: Avalanche (AVAX)", "url":"https://blog.cex.io/spotlight/cex-io-spotlight-avalanche-avax-31538"}, {"text": "Avalanche (AVAX) location: New York City, New York", "source": "Ava Labs: Careers", "url":"https://www.avalabs.org/careers"}, {"text": "Stacks (STX) creation date: October 30, 2018", "source": "Kraken: What is Stacks (STX)?", "url":"https://www.kraken.com/learn/what-is-stacks-stx"}, {"text": "Stacks (STX) location: 101 W. 23rd Street, Suite 224 New York, NY 10011", "source": "UNITED STATES SECURITIES AND EXCHANGE COMMISSION FORM 1-K", "url":"https://www.sec.gov/Archives/edgar/data/1693656/000119312521134674/d41884dpartii.htm"}, {"text": "Bitcoin creation date: January 3, 2009 at 18:15:05 UTC", "source": "Blockchain Council: The Genesis Block", "url":"https://www.blockchain-council.org/blockchain/genesis-block/"}, # {"text": """ # """, # "source": "", # "url":""}, ] source_docs = [ Document(page_content=doc["text"], metadata={"source": doc["source"], "url": doc["url"]}) for doc in crypto_token_info ] # Split the documents into smaller chunks for more efficient search text_splitter = RecursiveCharacterTextSplitter( chunk_size=500, chunk_overlap=50, add_start_index=True, strip_whitespace=True, separators=["\n\n", "\n", ".", " ", ""], ) docs_processed = text_splitter.split_documents(source_docs) # Create all the tools at once. Use the same instances for all agents. instructions_crypto_token_report = InstructionsCryptoTokenReportTool() crypto_token_info_retriever = CryptoTokenInfoRetrieverTool(docs_processed) get_recent_prices_for_crypto_token = GetRecentPricesForCryptoTokenTool() # These are classes were provided by HuggingFace for this course final_answer = FinalAnswerTool() visit_webpage = VisitWebpageTool() web_search = DuckDuckGoSearchTool() with open("prompts.yaml", 'r') as stream: prompt_templates = yaml.safe_load(stream) # Instrument with LangFuse, which makes debugging possible os.environ["LANGFUSE_PUBLIC_KEY"] = os.getenv("LANGFUSE_PUBLIC_KEY") os.environ["LANGFUSE_SECRET_KEY"] = os.getenv("LANGFUSE_SECRET_KEY") os.environ["LANGFUSE_HOST"] = os.getenv("LANGFUSE_BASE_URL") langfuse = get_client() if langfuse.auth_check(): print("Langfuse client is authenticated and ready!") else: #print("Authentication failed. Please check your credentials and host.") raise BaseException("LangFuse authentication failed. Halting processing now.") SmolagentsInstrumentor().instrument() # This is a "shabti" agent, specialized for web research, # particularly (but not exclusively) for gathering information # to write reports about crypto tokens. # # It is not intended to interact directly with end users. # Rather, it is designed to operate in the background, # performing tasks on behalf of other agents or systems. # # This "shabti" agent will be most effective if it is managed # by a "manager agent" (which should probably be smarter). web_agent = CodeAgent( model=InferenceClientModel( max_tokens=2096, temperature=0.5, model_id=web_agent_model_id, provider=web_agent_model_provider, custom_role_conversions=None, ), tools=[instructions_crypto_token_report, crypto_token_info_retriever, get_recent_prices_for_crypto_token, visit_webpage, web_search, final_answer ], ## add your tools here (don't remove final answer) additional_authorized_imports=['re'], max_steps=12, verbosity_level=1, # grammar=None, planning_interval=4, name="web_agent", description="Browses the web to find information", prompt_templates=prompt_templates ) # This tool is used only by the manager agent to check the work # of the web research shabti agent. def check_reasoning_and_sources(final_answer, agent_memory): """ This function is used by a manager agent to assess the reasoning process and results generated by a managed agent. It uses a separate, more powerful model to evaluate the quality of the work done by the managed agent. The manager agent can then decide to accept the results or ask the managed agent to try again. This function will print PASS if the reasoning and sources are satisfactory, FAIL otherwise. If it prints FAIL, it will also raise an exception with the feedback from the model, which can be used by the manager agent to understand what went wrong and how to improve. Args: final_answer (str): The final answer generated by the managed agent. This is the information which is going to be evaluated for quality and correctness. agent_memory (AgentMemory): The memory of the managed agent, which contains the steps taken and sources used to arrive at the final answer. """ multimodal_model = OpenAIServerModel("gpt-4o", max_tokens=8096) prompt = (f""" Here is a user-given task and the steps taken by the web agent: {agent_memory.get_succinct_steps()} Now here is the final answer from the web agent: {final_answer} Please check that the reasoning process and source urls are correct: do they correctly answer the given task? First list reasons why yes/no, then write your final decision: PASS in caps lock if it is satisfactory, FAIL if it is not. Don't be harsh: if the final answer from the web agent mostly solves the task, it should pass. """) messages = [ { "role": "user", "content": [ { "type": "text", "text": prompt, } ] } ] output = multimodal_model(messages).content print("Feedback: ", output) if "FAIL" in output: raise Exception(output) return True manager_agent = CodeAgent( model=InferenceClientModel( model_id=manager_agent_model_id, provider=manager_agent_model_provider, max_tokens=8096), tools=[ # instructions_crypto_token_report, # crypto_token_info_retriever, # get_recent_prices_for_crypto_token, visit_webpage, # web_search ], managed_agents=[web_agent], # additional_authorized_imports=[ # "re", # "geopandas", # "plotly", # "shapely", # "json", # "pandas", # "numpy", # ], additional_authorized_imports=['re'], name=None, description=None, planning_interval=5, verbosity_level=2, final_answer_checks=[check_reasoning_and_sources], max_steps=15, ) # GradioUI(manager_agent).launch() GradioUI(web_agent).launch()