Wei Ren commited on
Commit
4b85f1d
·
1 Parent(s): 07fa31e

Refactor tools to return structured data and enable agent-driven formatting

Browse files

- Changed all Meta Ads tools to return structured data (lists of dicts) instead of pre-formatted strings
- Updated output_type from "string" to "any" for all 5 tools (GetAdAccountsTool, GetCampaignsTool, GetAdSetsTool, GetAdsTool, GetAdInsightsTool)
- Removed format_as_itemized_list() function and all its usages
- Updated CodeAgent instructions to format structured data into user-friendly markdown (tables, bullet lists)
- Enhanced system message to inform agent about structured data handling capabilities
- Added example query demonstrating data filtering: "List my ad accounts and tell me which ones are active"

Benefits:
- Agent can now filter, sort, and analyze data programmatically
- More flexible and contextual response generation
- Better support for analytical queries
- Cleaner separation between data retrieval and presentation

Files changed (2) hide show
  1. app.py +6 -2
  2. tools/meta_ads_tools.py +10 -24
app.py CHANGED
@@ -66,7 +66,10 @@ User request: {message}
66
  Instructions:
67
  - Write code in <code> tags and execute it immediately
68
  - Use the available tools: get_ad_accounts(), get_campaigns(), get_adsets(), get_ads(), get_ad_insights()
69
- - After getting results, call final_answer() with the results
 
 
 
70
  - Be direct and efficient"""
71
 
72
  # Run the agent
@@ -86,7 +89,7 @@ chatbot = gr.ChatInterface(
86
  type="messages",
87
  additional_inputs=[
88
  gr.Textbox(
89
- value="You are a Meta Ads assistant. You can help users retrieve information about their ad accounts, campaigns, ad sets, ads, and performance insights using the Meta Ads API. Use the available tools to answer user queries.",
90
  label="System message",
91
  lines=3
92
  ),
@@ -116,6 +119,7 @@ chatbot = gr.ChatInterface(
116
  """,
117
  examples=[
118
  ["Show me all my ad accounts"],
 
119
  ["Get campaigns for account act_123456789"],
120
  ["Get ad sets for campaign 123456789"],
121
  ["What are the insights for my account in the last 30 days?"],
 
66
  Instructions:
67
  - Write code in <code> tags and execute it immediately
68
  - Use the available tools: get_ad_accounts(), get_campaigns(), get_adsets(), get_ads(), get_ad_insights()
69
+ - The tools return structured data (lists of dictionaries)
70
+ - Format the results in a user-friendly markdown format before calling final_answer()
71
+ - For lists of items, use markdown tables or bullet lists with clear formatting
72
+ - Include relevant fields and make the output easy to read
73
  - Be direct and efficient"""
74
 
75
  # Run the agent
 
89
  type="messages",
90
  additional_inputs=[
91
  gr.Textbox(
92
+ value="You are a Meta Ads assistant. You can help users retrieve information about their ad accounts, campaigns, ad sets, ads, and performance insights using the Meta Ads API. The tools return structured data (lists of dictionaries) that you can process, filter, and analyze. Always format the results in user-friendly markdown (tables, bullet lists, etc.) before presenting them to the user.",
93
  label="System message",
94
  lines=3
95
  ),
 
119
  """,
120
  examples=[
121
  ["Show me all my ad accounts"],
122
+ ["List my ad accounts and tell me which ones are active"],
123
  ["Get campaigns for account act_123456789"],
124
  ["Get ad sets for campaign 123456789"],
125
  ["What are the insights for my account in the last 30 days?"],
tools/meta_ads_tools.py CHANGED
@@ -26,20 +26,6 @@ def initialize_facebook_api():
26
  )
27
 
28
 
29
- def format_as_itemized_list(data_list):
30
- """Format a list of dictionaries as an itemized list."""
31
- if not data_list:
32
- return "No results found."
33
-
34
- formatted_output = []
35
- for idx, item in enumerate(data_list, 1):
36
- formatted_output.append(f"\n--- Item {idx} ---")
37
- for key, value in item.items():
38
- formatted_output.append(f"* {key}: {value}")
39
-
40
- return "\n".join(formatted_output)
41
-
42
-
43
  class GetAdAccountsTool(Tool):
44
  name = "get_ad_accounts"
45
  description = """
@@ -52,7 +38,7 @@ class GetAdAccountsTool(Tool):
52
  accounts = get_ad_accounts()
53
  """
54
  inputs = {}
55
- output_type = "string"
56
 
57
  def forward(self):
58
  """Get all ad accounts."""
@@ -77,7 +63,7 @@ class GetAdAccountsTool(Tool):
77
  'currency': account.get(AdAccount.Field.currency, 'N/A'),
78
  })
79
 
80
- return format_as_itemized_list(result)
81
  except Exception as e:
82
  return f"Error retrieving ad accounts: {str(e)}"
83
 
@@ -102,7 +88,7 @@ class GetCampaignsTool(Tool):
102
  "description": "The ad account ID (e.g., 'act_123456789')"
103
  }
104
  }
105
- output_type = "string"
106
 
107
  def forward(self, account_id: str):
108
  """Get campaigns for an ad account."""
@@ -130,7 +116,7 @@ class GetCampaignsTool(Tool):
130
  'lifetime_budget': campaign.get(Campaign.Field.lifetime_budget, 'N/A'),
131
  })
132
 
133
- return format_as_itemized_list(result)
134
  except Exception as e:
135
  return f"Error retrieving campaigns: {str(e)}"
136
 
@@ -155,7 +141,7 @@ class GetAdSetsTool(Tool):
155
  "description": "The campaign ID"
156
  }
157
  }
158
- output_type = "string"
159
 
160
  def forward(self, campaign_id: str):
161
  """Get ad sets for a campaign."""
@@ -185,7 +171,7 @@ class GetAdSetsTool(Tool):
185
  'billing_event': adset.get(AdSet.Field.billing_event, 'N/A'),
186
  })
187
 
188
- return format_as_itemized_list(result)
189
  except Exception as e:
190
  return f"Error retrieving ad sets: {str(e)}"
191
 
@@ -210,7 +196,7 @@ class GetAdsTool(Tool):
210
  "description": "The ad set ID"
211
  }
212
  }
213
- output_type = "string"
214
 
215
  def forward(self, adset_id: str):
216
  """Get ads for an ad set."""
@@ -234,7 +220,7 @@ class GetAdsTool(Tool):
234
  'creative_id': ad.get(Ad.Field.creative, {}).get('id', 'N/A'),
235
  })
236
 
237
- return format_as_itemized_list(result)
238
  except Exception as e:
239
  return f"Error retrieving ads: {str(e)}"
240
 
@@ -265,7 +251,7 @@ class GetAdInsightsTool(Tool):
265
  "nullable": True
266
  }
267
  }
268
- output_type = "string"
269
 
270
  def forward(self, object_id: str, date_preset: str = "last_7d"):
271
  """Get insights for an ad object."""
@@ -309,7 +295,7 @@ class GetAdInsightsTool(Tool):
309
  'actions': insight.get('actions', []),
310
  })
311
 
312
- return format_as_itemized_list(result)
313
  except Exception as e:
314
  return f"Error retrieving insights: {str(e)}"
315
 
 
26
  )
27
 
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  class GetAdAccountsTool(Tool):
30
  name = "get_ad_accounts"
31
  description = """
 
38
  accounts = get_ad_accounts()
39
  """
40
  inputs = {}
41
+ output_type = "any"
42
 
43
  def forward(self):
44
  """Get all ad accounts."""
 
63
  'currency': account.get(AdAccount.Field.currency, 'N/A'),
64
  })
65
 
66
+ return result
67
  except Exception as e:
68
  return f"Error retrieving ad accounts: {str(e)}"
69
 
 
88
  "description": "The ad account ID (e.g., 'act_123456789')"
89
  }
90
  }
91
+ output_type = "any"
92
 
93
  def forward(self, account_id: str):
94
  """Get campaigns for an ad account."""
 
116
  'lifetime_budget': campaign.get(Campaign.Field.lifetime_budget, 'N/A'),
117
  })
118
 
119
+ return result
120
  except Exception as e:
121
  return f"Error retrieving campaigns: {str(e)}"
122
 
 
141
  "description": "The campaign ID"
142
  }
143
  }
144
+ output_type = "any"
145
 
146
  def forward(self, campaign_id: str):
147
  """Get ad sets for a campaign."""
 
171
  'billing_event': adset.get(AdSet.Field.billing_event, 'N/A'),
172
  })
173
 
174
+ return result
175
  except Exception as e:
176
  return f"Error retrieving ad sets: {str(e)}"
177
 
 
196
  "description": "The ad set ID"
197
  }
198
  }
199
+ output_type = "any"
200
 
201
  def forward(self, adset_id: str):
202
  """Get ads for an ad set."""
 
220
  'creative_id': ad.get(Ad.Field.creative, {}).get('id', 'N/A'),
221
  })
222
 
223
+ return result
224
  except Exception as e:
225
  return f"Error retrieving ads: {str(e)}"
226
 
 
251
  "nullable": True
252
  }
253
  }
254
+ output_type = "any"
255
 
256
  def forward(self, object_id: str, date_preset: str = "last_7d"):
257
  """Get insights for an ad object."""
 
295
  'actions': insight.get('actions', []),
296
  })
297
 
298
+ return result
299
  except Exception as e:
300
  return f"Error retrieving insights: {str(e)}"
301