ameglei-external commited on
Commit
8371f52
·
verified ·
1 Parent(s): 586c4d6

Add agent MVP

Browse files
Files changed (1) hide show
  1. app.py +54 -63
app.py CHANGED
@@ -1,5 +1,5 @@
1
  import os
2
- from typing import TypedDict, List, Dict, Any, Optional
3
 
4
  import gradio as gr
5
  import requests
@@ -11,12 +11,14 @@ from langgraph.graph.message import add_messages
11
  from langgraph.prebuilt import ToolNode, tools_condition
12
 
13
  from langchain_openai import ChatOpenAI
 
14
  from langchain_core.messages import AnyMessage, SystemMessage, HumanMessage
15
 
16
  # (Keep Constants as is)
17
  # --- Constants ---
18
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
19
- os.environ["OPENAI_API_KEY"] = "sk-xxxxx"
 
20
 
21
 
22
  class State(TypedDict):
@@ -30,77 +32,66 @@ class BasicAgent:
30
 
31
  def __init__(self):
32
 
33
- # self.graph = StateGraph(State)
34
- # self.graph.add_node("search_tool", self.search_tool)
35
- # self.graph.add_node("image_analyze", self.image_analyze)
36
- # self.graph.add_node("generic_reasoning", self.generic_reasoning)
37
- # self.graph.add_node("file_operating", self.file_operating)
38
-
39
- # # Start the edges
40
- # self.graph.add_edge(START, "read_email")
41
- # # Add edges - defining the flow
42
- # self.graph.add_edge("read_email", "classify_email")
43
-
44
- # # Add conditional branching from classify_email
45
- # self.graph.add_conditional_edges(
46
- # "classify_email",
47
- # route_email,
48
- # {
49
- # "spam": "handle_spam",
50
- # "legitimate": "draft_response"
51
- # }
52
- # )
53
-
54
- # # Add the final edges
55
- # self.graph.add_edge("handle_spam", END)
56
- # self.graph.add_edge("draft_response", "notify_mr_hugg")
57
- # self.graph.add_edge("notify_mr_hugg", END)
58
 
59
- # # Compile the graph
60
- # self.compiled_graph = self.graph.compile()
61
- self.tools = [self.search_tool, self.image_analyze_tool, self.file_operating_tool]
62
-
63
- # self.model = ChatOpenAI(model="gpt-4o", temperature=0)
64
- # self.model_with_tools = self.model.bind_tools(self.tools, parallel_tool_calls=False)
65
 
66
  print("BasicAgent initialized.")
67
 
68
- def __call__(self, question: str) -> str:
69
  print(f"Agent received question (first 50 chars): {question[:50]}...")
70
- fixed_answer = "This is a default answer."
 
71
  print(f"Agent returning fixed answer: {fixed_answer}")
72
- return fixed_answer
73
 
74
- # def assistant(state: AgentState):
75
- # # System message
76
- # textual_description_of_tool="""
77
- # extract_text(img_path: str) -> str:
78
- # Extract text from an image file using a multimodal model.
79
 
80
- # Args:
81
- # img_path: A local image file path (strings).
82
 
83
- # Returns:
84
- # A single string containing the concatenated text extracted from each image.
85
- # divide(a: int, b: int) -> float:
86
- # Divide a and b
87
- # """
88
- # image=state["input_file"]
89
- # sys_msg = SystemMessage(content=f"You are a helpful butler named Alfred that serves Mr. Wayne and Batman. You can analyse documents and run computations with provided tools:\n{textual_description_of_tool} \n You have access to some optional images. Currently the loaded image is: {image}")
90
-
91
- # return {
92
- # "messages": [self.model_with_tools.invoke([sys_msg] + state["messages"])],
93
- # "question": state["question"]
94
- # }
95
-
96
- def search_tool(state):
97
- pass
98
 
99
- def image_analyze_tool(state):
100
- pass
101
-
102
- def file_operating_tool(state):
103
- pass
 
 
 
 
 
 
 
 
 
 
104
 
105
 
106
  def run_and_submit_all( profile: gr.OAuthProfile | None):
 
1
  import os
2
+ from typing import TypedDict, List, Dict, Any, Optional, Tuple
3
 
4
  import gradio as gr
5
  import requests
 
11
  from langgraph.prebuilt import ToolNode, tools_condition
12
 
13
  from langchain_openai import ChatOpenAI
14
+ from langchain_community.tools import DuckDuckGoSearchRun
15
  from langchain_core.messages import AnyMessage, SystemMessage, HumanMessage
16
 
17
  # (Keep Constants as is)
18
  # --- Constants ---
19
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
20
+ os.environ["OPENAI_API_KEY"] = "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
21
+ "
22
 
23
 
24
  class State(TypedDict):
 
32
 
33
  def __init__(self):
34
 
35
+ self.tools = [
36
+ self.search_tool,
37
+ # self.image_analyze_tool,
38
+ # self.file_operating_tool
39
+ ]
40
+
41
+ self.model = ChatOpenAI(model="gpt-4o", temperature=0)
42
+ self.model_with_tools = self.model.bind_tools(self.tools, parallel_tool_calls=False)
43
+
44
+ self.graph = StateGraph(State)
45
+ self.graph.add_node("assistant", self.assistant)
46
+ self.graph.add_node("tools", ToolNode(self.tools))
47
+
48
+ # Start the edges
49
+ self.graph.add_edge(START, "assistant")
50
+ self.graph.add_conditional_edges(
51
+ "assistant",
52
+ tools_condition
53
+ )
54
+ self.graph.add_edge("tools", "assistant")
 
 
 
 
 
55
 
56
+ # Compile the graph
57
+ self.compiled_graph = self.graph.compile()
 
 
 
 
58
 
59
  print("BasicAgent initialized.")
60
 
61
+ def __call__(self, question: str) -> Tuple[str, TypedDict]:
62
  print(f"Agent received question (first 50 chars): {question[:50]}...")
63
+ state = State(question=question, messages=[HumanMessage(content=question)])
64
+ fixed_answer = self.assistant(state)
65
  print(f"Agent returning fixed answer: {fixed_answer}")
66
+ return fixed_answer, state
67
 
68
+ def assistant(state: AgentState):
69
+ # System message
70
+ textual_description_of_tool="""
71
+ search_tool(question: str) -> str:
72
+ Search info in the web.
73
 
74
+ Args:
75
+ question: Question string
76
 
77
+ Returns:
78
+ A single string containing the info from the web.
 
 
 
 
 
 
 
 
 
 
 
 
 
79
 
80
+ """
81
+
82
+ sys_msg = SystemMessage(
83
+ content=f"""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.
84
+ You can use provided tools:\n{textual_description_of_tool}"""
85
+ )
86
+
87
+ return {
88
+ "messages": [self.model_with_tools.invoke([sys_msg] + state.get("messages", []))],
89
+ "question": state["question"]
90
+ }
91
+
92
+ def search_tool(question: str, max_length: int = 1024) -> str:
93
+ search = DuckDuckGoSearchRun()
94
+ return search.invoke(question)[:max_length]
95
 
96
 
97
  def run_and_submit_all( profile: gr.OAuthProfile | None):