D3MI4N commited on
Commit
52762da
·
1 Parent(s): 5ada353

adding syntheziser

Browse files
Files changed (4) hide show
  1. app.py +8 -8
  2. qa_graph.py +44 -16
  3. requirements.txt +2 -0
  4. test_gaia.py +3 -3
app.py CHANGED
@@ -12,9 +12,9 @@ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
12
 
13
  # --- Basic Agent Definition ---
14
  # # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
15
- # class BasicAgent:
16
  # def __init__(self):
17
- # print("BasicAgent initialized.")
18
  # def __call__(self, question: str) -> str:
19
  # print(f"Agent received question (first 50 chars): {question[:50]}...")
20
  # fixed_answer = "This is a default answer."
@@ -22,7 +22,7 @@ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
22
  # return fixed_answer
23
 
24
 
25
- class BasicAgent:
26
  def __init__(self):
27
  print("Graph-based agent initialized.")
28
 
@@ -38,7 +38,7 @@ class BasicAgent:
38
 
39
  def run_and_submit_all( profile: gr.OAuthProfile | None):
40
  """
41
- Fetches all questions, runs the BasicAgent on them, submits all answers,
42
  and displays the results.
43
  """
44
  # --- Determine HF Space Runtime URL and Repo URL ---
@@ -57,7 +57,7 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
57
 
58
  # 1. Instantiate Agent ( modify this part to create your agent)
59
  try:
60
- agent = BasicAgent()
61
  except Exception as e:
62
  print(f"Error instantiating agent: {e}")
63
  return f"Error initializing agent: {e}", None
@@ -91,9 +91,9 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
91
  answers_payload = []
92
  print(f"Running agent on {len(questions_data)} questions...")
93
 
94
- MAX_QUESTIONS = 3
95
- questions_data = questions_data[:MAX_QUESTIONS]
96
- print(f"Limiting to first {MAX_QUESTIONS} questions.")
97
 
98
  for item in questions_data:
99
  task_id = item.get("task_id")
 
12
 
13
  # --- Basic Agent Definition ---
14
  # # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
15
+ # class GaiaAgent:
16
  # def __init__(self):
17
+ # print("GaiaAgent initialized.")
18
  # def __call__(self, question: str) -> str:
19
  # print(f"Agent received question (first 50 chars): {question[:50]}...")
20
  # fixed_answer = "This is a default answer."
 
22
  # return fixed_answer
23
 
24
 
25
+ class GaiaAgent:
26
  def __init__(self):
27
  print("Graph-based agent initialized.")
28
 
 
38
 
39
  def run_and_submit_all( profile: gr.OAuthProfile | None):
40
  """
41
+ Fetches all questions, runs the GaiaAgent on them, submits all answers,
42
  and displays the results.
43
  """
44
  # --- Determine HF Space Runtime URL and Repo URL ---
 
57
 
58
  # 1. Instantiate Agent ( modify this part to create your agent)
59
  try:
60
+ agent = GaiaAgent()
61
  except Exception as e:
62
  print(f"Error instantiating agent: {e}")
63
  return f"Error initializing agent: {e}", None
 
91
  answers_payload = []
92
  print(f"Running agent on {len(questions_data)} questions...")
93
 
94
+ # MAX_QUESTIONS = 5
95
+ # questions_data = questions_data[:MAX_QUESTIONS]
96
+ # print(f"Limiting to first {MAX_QUESTIONS} questions.")
97
 
98
  for item in questions_data:
99
  task_id = item.get("task_id")
qa_graph.py CHANGED
@@ -1,43 +1,71 @@
1
- # simple_qa_graph.py
2
 
3
  from typing import TypedDict
 
4
  from langgraph.graph import StateGraph, START, END
5
  from tools.calculator_tool import calculator_tool
6
  from tools.search_tool import search_tool
7
- import re
8
 
9
  # 1) Define the shape of our state
10
  class QAState(TypedDict):
11
  question: str # incoming question
12
- answer: str # place to store the tool’s output
 
 
 
 
 
 
 
 
 
 
 
13
 
14
- # 2) Define our single agent node
15
  def QAAgent(state: QAState) -> QAState:
16
  q = state["question"].strip()
17
- # if it looks like math, use the calculator, else do web search:
18
  if re.fullmatch(r"[0-9\s\+\-\*\/\.\(\)]+", q):
19
- state["answer"] = calculator_tool(q)
20
  else:
21
- state["answer"] = search_tool(q)
22
  return state
23
 
24
- # 3) Wire it up in a graph: START → QAAgent → END
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  builder = StateGraph(QAState)
26
  builder.set_entry_point("QAAgent")
27
  builder.add_node("QAAgent", QAAgent)
 
 
28
  builder.add_edge(START, "QAAgent")
29
- builder.add_edge("QAAgent", END)
 
30
 
31
  graph = builder.compile()
32
 
33
- # 4) Run it locally
34
  if __name__ == "__main__":
35
- # try a math question
36
  s1: QAState = {"question": "2 + 2", "answer": ""}
37
- out1 = graph.invoke(s1)
38
- print("Q:", s1["question"], " A:", out1["answer"])
39
 
40
- # try a search question
41
  s2: QAState = {"question": "What is the capital of France?", "answer": ""}
42
- out2 = graph.invoke(s2)
43
- print("Q:", s2["question"], " A:", out2["answer"])
 
1
+ # qa_graph.py
2
 
3
  from typing import TypedDict
4
+ import re
5
  from langgraph.graph import StateGraph, START, END
6
  from tools.calculator_tool import calculator_tool
7
  from tools.search_tool import search_tool
8
+ from transformers import pipeline
9
 
10
  # 1) Define the shape of our state
11
  class QAState(TypedDict):
12
  question: str # incoming question
13
+ answer: str # to store tool output or synthesized answer
14
+
15
+ # 2) Use text2text-generation for T5 models like flan-t5
16
+ synthesizer = pipeline(
17
+ "text2text-generation",
18
+ model="google/flan-t5-small",
19
+ device=-1, # CPU; change to 0 for GPU
20
+ max_new_tokens=100,
21
+ do_sample=True,
22
+ top_p=0.95,
23
+ temperature=0.7
24
+ )
25
 
26
+ # 3) Tool agent: calculator for math, search for other
27
  def QAAgent(state: QAState) -> QAState:
28
  q = state["question"].strip()
 
29
  if re.fullmatch(r"[0-9\s\+\-\*\/\.\(\)]+", q):
30
+ state["answer"] = calculator_tool.invoke(q)
31
  else:
32
+ state["answer"] = search_tool.invoke(q) # update to `.invoke(q)` only if search_tool is a LangChain tool
33
  return state
34
 
35
+ # 4) Synthesis agent to generate final response
36
+ def SynthesisAgent(state: QAState) -> QAState:
37
+ question = state["question"]
38
+ tool_out = state["answer"]
39
+ prompt = (
40
+ f"Question: {question}\n"
41
+ f"Tool output: {tool_out}\n"
42
+ "Answer in a comma-separated list (no extra text):"
43
+ )
44
+ outputs = synthesizer(prompt)
45
+ completion = outputs[0]["generated_text"].strip()
46
+ state["answer"] = completion
47
+ return state
48
+
49
+ # 5) Build the graph: START -> QAAgent -> SynthesisAgent -> END
50
  builder = StateGraph(QAState)
51
  builder.set_entry_point("QAAgent")
52
  builder.add_node("QAAgent", QAAgent)
53
+ builder.add_node("SynthesisAgent", SynthesisAgent)
54
+
55
  builder.add_edge(START, "QAAgent")
56
+ builder.add_edge("QAAgent", "SynthesisAgent")
57
+ builder.add_edge("SynthesisAgent", END)
58
 
59
  graph = builder.compile()
60
 
61
+ # 6) Local testing
62
  if __name__ == "__main__":
63
+ # Math example
64
  s1: QAState = {"question": "2 + 2", "answer": ""}
65
+ o1 = graph.invoke(s1)
66
+ print("Q:", s1["question"], "-> A:", o1["answer"])
67
 
68
+ # Search + synthesis example
69
  s2: QAState = {"question": "What is the capital of France?", "answer": ""}
70
+ o2 = graph.invoke(s2)
71
+ print("Q:", s2["question"], "-> A:", o2["answer"])
requirements.txt CHANGED
@@ -10,3 +10,5 @@ huggingface_hub
10
  transformers
11
  langchain-huggingface
12
  IPython
 
 
 
10
  transformers
11
  langchain-huggingface
12
  IPython
13
+ numpy<2.0
14
+
test_gaia.py CHANGED
@@ -3,6 +3,6 @@ import requests
3
  import pandas as pd
4
 
5
  QUESTIONS = requests.get("https://agents-course-unit4-scoring.hf.space/questions").json()
6
- for q in QUESTIONS[:3]:
7
- ans = graph.invoke({"question":q["question"],"answer":""})["answer"]
8
- print(q["task_id"], ans)
 
3
  import pandas as pd
4
 
5
  QUESTIONS = requests.get("https://agents-course-unit4-scoring.hf.space/questions").json()
6
+ for q in QUESTIONS[:5]:
7
+ out = graph.invoke({"question": q["question"], "answer": ""})
8
+ print(q["task_id"], out["answer"])