File size: 3,503 Bytes
c2f85cf 29bec31 c2f85cf 00a8784 4fd40c0 e5a6189 c2f85cf a380329 0745f60 00a8784 0745f60 c2f85cf a380329 c2f85cf a380329 c2f85cf 2618ebd 0501dcb d44ef49 0501dcb 5440230 2618ebd 5440230 58c57f1 a18d9f7 c592338 d44ef49 c592338 a18d9f7 3526bba 58c57f1 e1488ab f46a489 c2f85cf 640deab c2f85cf | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | from langgraph.graph.message import add_messages
from langchain_core.messages import AnyMessage, HumanMessage, AIMessage, SystemMessage
from langgraph.prebuilt import ToolNode
from langgraph.graph import START, StateGraph
from langgraph.prebuilt import tools_condition
from langchain_huggingface import HuggingFaceEndpoint, ChatHuggingFace
from tools import ExtractTextFromImage, DescribeImage, read_excel, read_python, wiki_search, web_search, arxiv_search
from langchain_openai import ChatOpenAI
from typing import TypedDict, Annotated, Optional
class AgentState(TypedDict):
messages: Annotated[list[AnyMessage], add_messages]
class BasicAgent():
def __init__(self, chat, vision_llm):
extract_text_from_image = ExtractTextFromImage(vision_llm)
describe_image = DescribeImage(vision_llm)
self.tools = [extract_text_from_image, describe_image, read_excel, read_python, wiki_search, web_search, arxiv_search]
self.chat_with_tools = chat.bind_tools(self.tools)
self._initialize_graph()
print("BasicAgent initialized.")
def _initialize_graph(self):
builder = StateGraph(AgentState)
# Define nodes
builder.add_node("assistant", self.assistant)
builder.add_node("tools", ToolNode(self.tools))
# Define edges
builder.add_edge(START, "assistant")
builder.add_conditional_edges("assistant",tools_condition)
builder.add_edge("tools", "assistant")
# Compile the graph
self.agent = builder.compile()
def __call__(self, question: str, file_name : str) -> str:
print(f"Agent received question: {question}. /nProvided file: {file_name}.")
if file_name is not None and file_name!='':
messages=[HumanMessage(content=f"{question}. The filename you have access to is {file_name}.")]
else:
messages=[HumanMessage(content=question)]
response = self.agent.invoke({"messages":messages})
answer = response['messages'][-1].content
print(f"Agent returning answer: {answer}")
return answer
def assistant(self, state: AgentState):
sys_msg = SystemMessage(content=f"""
You are a general AI assistant. I will ask you a question. Reason step by step and search for the information you need using available tools, one step at a time.
If you do not have enough information to answer, use the tools available to search for it.
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.
When providing the final answer, ONLY give [YOUR FINAL ANSWER]. Do not add anything else, no additional motivation or explanation, and do not return 'FINAL ANSWER:'.
""")
response = self.chat_with_tools.invoke([sys_msg] + state["messages"])
return {
"messages": state["messages"] + [response],
}
|