Spaces:
Build error
Build error
Download backup/agent.py from errchh/hfagentscourse-finalassignment: direct link, hf CLI and curl.
- Browser
- Download file 5.1 kB
-
https://huggingface.co/spaces/errchh/hfagentscourse-finalassignment/resolve/main/backup/agent.py
- Command line
-
hf download hf://spaces/errchh/hfagentscourse-finalassignment/backup/agent.py
-
curl -L -o agent.py https://huggingface.co/spaces/errchh/hfagentscourse-finalassignment/resolve/main/backup/agent.py
5.1 kB
| # import libraries for langgraph, huggingface | |
| import os | |
| from dotenv import load_dotenv | |
| from typing import TypedDict, List, Dict, Any, Optional, Annotated | |
| from langchain_huggingface import ChatHuggingFace, HuggingFaceEndpoint, HuggingFaceEmbeddings | |
| from langgraph.graph import StateGraph, MessagesState, START, END | |
| from langgraph.graph.message import add_messages | |
| from langchain_core.messages import SystemMessage, HumanMessage, AnyMessage, AIMessage | |
| from langchain_core.messages.ai import subtract_usage | |
| from langchain.tools import Tool | |
| from langchain_core.tools import tool | |
| from langchain_community.tools import WikipediaQueryRun | |
| from langchain_community.utilities import WikipediaAPIWrapper | |
| from langchain_community.utilities import SerpAPIWrapper | |
| from langchain_community.utilities import ArxivAPIWrapper | |
| from langchain_community.retrievers import BM25Retriever | |
| from langgraph.prebuilt import ToolNode, tools_condition | |
| # load environment variables | |
| load_dotenv() | |
| HUGGINGFACEHUB_API_TOKEN = os.getenv("HUGGINGFACEHUB_API_TOKEN") | |
| # maths tool | |
| def add(a:int, b:int) -> int: | |
| """add two numbers. | |
| args: | |
| a: first int | |
| b: second int | |
| """ | |
| return a + b | |
| def subtract(a:int, b:int) -> int: | |
| """subtract two numbers. | |
| args: | |
| a: first int | |
| b: second int | |
| """ | |
| return a - b | |
| def multiply(a:int, b:int) -> int: | |
| """multiply two numbers. | |
| args: | |
| a: first int | |
| b: second int | |
| """ | |
| return a * b | |
| def divide(a:int, b:int) -> float: | |
| """divide two numbers. | |
| args: | |
| a: first int | |
| b: second int | |
| """ | |
| try: | |
| # Attempt the division | |
| result = a / b | |
| return result | |
| except ZeroDivisionError: | |
| # Handle the case where b is zero | |
| raise ValueError("Cannot divide by zero.") | |
| def modulus(a:int, b:int) -> int: | |
| """modulus remainder of two numbers. | |
| args: | |
| a: first int | |
| b: second int | |
| """ | |
| return a % b | |
| # wikipedia search tool | |
| def search_wiki(query: str) -> Dict[str, str]: | |
| """search wikipedia with a query | |
| args: | |
| query: a search query | |
| """ | |
| docs = WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper()) | |
| docs.run(query) | |
| formatted_result = f'<Document source="{docs.metadata["source"]}" page="{docs.metadata.get("page", "")}"/>\n{docs.page_content}\n</Document>' | |
| return {"wiki_results": formatted_result} | |
| # internet search tool | |
| def search_web(query: str) -> Dict[str, str]: | |
| """search internet with a query | |
| args: | |
| query: a search query | |
| """ | |
| docs = SerpAPIWrapper() | |
| docs.run(query) | |
| formatted_result = f'<Document source="{docs.metadata["source"]}" page="{docs.metadata.get("page", "")}"/>\n{docs.page_content}\n</Document>' | |
| return {"wiki_results": formatted_result} | |
| # ArXiv search tool | |
| def search_arxiv(query: str) -> Dict[str, str]: | |
| """search ArXiv for the paper with the given identifier | |
| args: | |
| query: a search identifier | |
| """ | |
| arxiv = ArxivAPIWrapper() | |
| docs = arxiv.run(query) | |
| formatted_result = f'<Document source="{docs.metadata["source"]}" page="{docs.metadata.get("page", "")}"/>\n{docs.page_content}\n</Document>' | |
| return {"wiki_results": formatted_result} | |
| # build retriever | |
| # bm25_retriever = BM25Retriever.from_documents(docs) | |
| # load system prompt from file | |
| with open("system_prompt.txt", "r", encoding="utf-8") as f: | |
| system_prompt = f.read() | |
| # init system message | |
| sys_msg = SystemMessage(content=system_prompt) | |
| tools = [ | |
| add, | |
| subtract, | |
| multiply, | |
| divide, | |
| modulus, | |
| search_wiki, | |
| search_web, | |
| search_arxiv | |
| ] | |
| # build graph function | |
| def build_graph(): | |
| # llm | |
| llm = HuggingFaceEndpoint( | |
| repo_id = "microsoft/Phi-4-reasoning-plus", | |
| huggingfacehub_api_token=HUGGINGFACEHUB_API_TOKEN, | |
| ) | |
| chat = ChatHuggingFace(llm=llm, verbose=False) | |
| # bind tools to llm | |
| chat_with_tools = chat.bind_tools(tools) | |
| # generate AgentState and Agent graph | |
| class AgentState(TypedDict): | |
| messages: Annotated[list[AnyMessage], add_messages] | |
| def assistant(state: AgentState): | |
| return { | |
| "messages": [chat_with_tools.invoke(state["messages"])], | |
| } | |
| # build graph | |
| builder = StateGraph(AgentState) | |
| # define nodes | |
| builder.add_node("assistant", assistant) | |
| builder.add_node("tools", ToolNode(tools)) | |
| # define edges | |
| builder.add_edge(START, "assistant") | |
| builder.add_conditional_edges( | |
| "assistant", | |
| # If the latest message requires a tool, route to tools | |
| # Otherwise, provide a direct response | |
| tools_condition, | |
| ) | |
| builder.add_edge("tools", "assistant") | |
| return builder.compile() | |
| if __name__ == "__main__": | |
| question = "When was a picture of St. Thomas Aquinas first added to the Wikipedia page on the Principle of double effect?" | |
| graph = build_graph() | |
| messages = [HumanMessage(content=question)] | |
| messages = graph.invoke({"messages": messages}) | |
| for m in messages["messages"]: | |
| m.pretty_print() | |