carolinacon commited on
Commit
b4f9800
·
1 Parent(s): 86368de

Refactoring and started filling in the README file

Browse files
Files changed (3) hide show
  1. README.md +90 -0
  2. core/messages.py +3 -26
  3. nodes/nodes.py +1 -1
README.md CHANGED
@@ -12,4 +12,94 @@ hf_oauth: true
12
  hf_oauth_expiration_minutes: 480
13
  ---
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
12
  hf_oauth_expiration_minutes: 480
13
  ---
14
 
15
+ # General AI Assistant
16
+
17
+ ## Background
18
+ Created as a final project for the HuggingFace Agents course ( https://huggingface.co/learn/agents-course).
19
+ Aims to answer Level 1 questions from the **GAIA** validation set. It was tested on 20 such questions with a success rate of 65%.
20
+ ### GAIA
21
+
22
+ GAIA is a benchmark for AI assistants evaluation on real-world tasks that require a combination of capabilities—such
23
+ as reasoning, multimodal understanding, web browsing, and proficient tool use (see https://huggingface.co/learn/agents-course/unit4/what-is-gaia).
24
+
25
+ GAIA was introduced in the paper [”GAIA: A Benchmark for General AI Assistants”](https://arxiv.org/abs/2311.12983).
26
+
27
+
28
+ The questions challenge AI systems in several ways:
29
+
30
+ - Involve multimodal reasoning (e.g., analyzing images, audio, documents)
31
+ - Demand multi-hop retrieval of interdependent facts
32
+ - Involve running python code
33
+ - Require a structured response format
34
+
35
+
36
+ ## Implementation Highlights
37
+
38
+
39
+
40
+ **The agent** is implemented using the LangGraph framework.
41
+
42
+ **Nodes**:
43
+
44
+
45
+ **Tools**
46
+
47
+ 🔎 **Web Search**: uses `tavily` search and extract tools.
48
+
49
+ - **Chunking**: The content returned by the exact might be too large to be further analyzed at once by a model (depending on the chosen model context window size or on the rate limitation),
50
+ so if its size exceeds a pre-configured threshold, it will be chunked and only the most relevant chunks will be analyzed.
51
+ - **Text Splitting**: First by markdown (used Langchain's `MarkdownHeaderTextSplitter`) and then further by size with a sliding window (used LangChain's `RecursiveCharacterTextSplitter`).
52
+ - **Embeddings**: langchain_community.embeddings.OpenAIEmbeddings
53
+ - **Vector DB**: FAISS vector db.
54
+ - **Retrieval**: FAISS similarity search
55
+
56
+ Updated the original extract tool response message content only with the relevant chunks content.
57
+
58
+ 🔉 **Audio**: uses `gpt-4o-audio-preview` to analyze the input
59
+
60
+ 🧮 **Math problems**: this is a subagent that uses `gpt-5` equipped with the following tools:
61
+
62
+ - **Pyhton code executor**: executes a snipped of python code provided as input
63
+ - **Think tool**: used for strategic reflection on the progress of the solving process
64
+
65
+ **The Math Agent States:**
66
+
67
+
68
+ 🧩 **Python code**
69
+ This tool can run either a snippet of python code or a python file. The python file is executed in a sub-process.
70
+
71
+ 📊 **Spreadsheets**
72
+ In order to analyze `excel` files this tool uses the pandas dataframe agent
73
+ `langchain_experimental.agents import create_pandas_dataframe_agent`
74
+ It uses `gpt-4.1` model.
75
+
76
+ ♟️ **Chess**
77
+ Given a chess board and the active color, this tool is able to suggest the best move to be performed by the active color.
78
+
79
+ - **Picture analysis**: the tool must detect
80
+
81
+ 🎥 **Videos**
82
+
83
+
84
+
85
+ ## Challenges
86
+
87
+
88
+
89
+ ## Future improvements
90
+ #### 1. Evaluation
91
+ #### 2. Chunking
92
+ #### 3. Audio Analysis
93
+ #### 3. Video Analysis
94
+ #### 4. Chessboard Images analysis
95
+
96
+ ## References:
97
+ https://github.com/langchain-ai/open_deep_research
98
+
99
+
100
+
101
+
102
+
103
+
104
+
105
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
core/messages.py CHANGED
@@ -40,28 +40,11 @@ class AttachmentHandler:
40
  def __init__(self, supported_types: list):
41
  self.supported_types = supported_types
42
 
43
- def get_attachment_representation(self, attachment: Attachment) -> dict:
44
- if attachment.type not in self.supported_types:
45
- raise Exception(f"Invalid attachment type{attachment.type}")
46
-
47
- if attachment.type == "image":
48
- return {"type": "image_url",
49
- "image_url": {"url": f"data:{attachment.mime_type};base64," + attachment.get_encoded_content_b64()}}
50
-
51
- if attachment.type == "audio":
52
- return {"type": "text",
53
- "text": attachment.get_encoded_content_b64()}
54
- if attachment.type == "text":
55
- return {"type": attachment.type, "data": attachment.content, "mime_type": attachment.mime_type}
56
-
57
- # The remaining types are image, file, audio
58
- return {"type": attachment.type, "source": "base64", "data": attachment.get_encoded_content_b64(),
59
- "mime_type": attachment.mime_type}
60
-
61
  def get_representation(self, type: str, content: bytes, format: str, mime_type) -> dict:
62
- base64_content = base64.b64encode(content).decode("utf-8")
63
  if type not in self.supported_types:
64
  raise Exception(f"Invalid attachment type{type}")
 
 
65
  if type == "audio":
66
  return {"type": "input_audio",
67
  "input_audio": {"data": base64_content, "format": format}}
@@ -72,18 +55,12 @@ class AttachmentHandler:
72
  raise Exception(f"Cannot extract a representation for type {type}")
73
 
74
  def fetch_file_from_reference(self, file_reference: str) -> bytes:
75
- """Fetches file bytes from a reference (e.g., S3, local path, URL)."""
76
-
77
  # It's a local file path
78
  file = Path(file_reference)
79
  if file_reference.startswith("/") or file_reference.startswith("./") or file.exists():
80
  return file.read_bytes()
81
-
82
-
83
- # Example 3: It's an ID in your database (pseudocode)
84
  else:
85
- # file_bytes = database.lookup_file_bytes(file_reference)
86
- # return file_bytes
87
  raise ValueError(
88
  f"Could not resolve file reference: {file_reference}. Implement 'fetch_file_from_reference' for your "
89
  f"storage system.")
 
40
  def __init__(self, supported_types: list):
41
  self.supported_types = supported_types
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  def get_representation(self, type: str, content: bytes, format: str, mime_type) -> dict:
 
44
  if type not in self.supported_types:
45
  raise Exception(f"Invalid attachment type{type}")
46
+ base64_content = base64.b64encode(content).decode("utf-8")
47
+
48
  if type == "audio":
49
  return {"type": "input_audio",
50
  "input_audio": {"data": base64_content, "format": format}}
 
55
  raise Exception(f"Cannot extract a representation for type {type}")
56
 
57
  def fetch_file_from_reference(self, file_reference: str) -> bytes:
58
+ """Fetches file bytes from a reference """
 
59
  # It's a local file path
60
  file = Path(file_reference)
61
  if file_reference.startswith("/") or file_reference.startswith("./") or file.exists():
62
  return file.read_bytes()
 
 
 
63
  else:
 
 
64
  raise ValueError(
65
  f"Could not resolve file reference: {file_reference}. Implement 'fetch_file_from_reference' for your "
66
  f"storage system.")
nodes/nodes.py CHANGED
@@ -66,7 +66,7 @@ def assistant(state: State):
66
  response = model.invoke([sys_msg] + state["messages"])
67
  except Exception as e:
68
  if "429" in str(e):
69
- time.sleep(5)
70
  print("Retrying after receiving 429 error")
71
  response = model.invoke([sys_msg] + state["messages"])
72
  return {"messages": [response]}
 
66
  response = model.invoke([sys_msg] + state["messages"])
67
  except Exception as e:
68
  if "429" in str(e):
69
+ time.sleep(20)
70
  print("Retrying after receiving 429 error")
71
  response = model.invoke([sys_msg] + state["messages"])
72
  return {"messages": [response]}