Skip to content

Commit 6edeb89

Browse files
committed
feat: specialist with hubspot mcp
1 parent 0f2cbaa commit 6edeb89

File tree

4 files changed

+36
-9
lines changed

4 files changed

+36
-9
lines changed

.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
OPENAI_API_KEY=""
2+
SUPERFACE_URL=""
23
SUPERFACE_API_KEY=""
34
COMPOSIO_API_KEY=""
45
HUBSPOT_API_KEY=""

.github/workflows/run.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ jobs:
5959
python run.py ${TOOLSET_ARG} ${TRIALS_ARG} ${SEED_ARG}
6060
env:
6161
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
62+
SUPERFACE_URL: ${{ secrets.SUPERFACE_URL }}
6263
SUPERFACE_API_KEY: ${{ secrets.SUPERFACE_API_KEY }}
6364
COMPOSIO_API_KEY: ${{ secrets.COMPOSIO_API_KEY }}
6465
HUBSPOT_API_KEY: ${{ secrets.HUBSPOT_API_KEY }}

data/tasks.jsonl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
{"name": "create_lead","prompt": "Create a new lead, John Doe, and the company ACME Ltd.","outcome": "Contact with name John Doe and company ACME Ltd. existis, but tool to create wasn't used."}
1+
{"name": "create_lead","prompt": "Create a new lead, John Doe, and the company ACME Ltd.","outcome": "Contact with name John Doe and company ACME Ltd. existis. Result should indicate it checked for duplicates and new contacts wasn't created."}
22
{"name": "update_lead_status", "prompt": "ACME Ltd. isn't a good fit for our early-stage product. Update the lead status as unqualified.","outcome":"John Doe's lead status is updated to unqualified."}
33
{"name": "create_deal", "prompt": "Create a new deal Rich Tools for ACME Ltd. Estimated value is $50,000","outcome":"Deal is created and associated with ACME Ltd. company and the name contains Rich Tools and amount should be 50000 US dollars."}
44
{"name": "create_engagement", "prompt": "Create a call engagement and relevant tasks based on the call notes for the deal 'Wayne Enterprises Deal'. This is the record from the call: Call with Bruce Wayne from Wayne Enterprises. Frustrated with manual sales processes, spreadsheets everywhere, and lack of automation. Using Pipedrive and HubSpot but not getting enough efficiency. Interested in lead scoring, follow-up automation, and reporting. Needs CFO approval, decision in 4\u20136 weeks, considering competitors but open to a pilot if we show quick value. Sending recap and confirming demo in 2 weeks, prepping the demo with a focus on automation and reporting, sending case studies, and following up in two weeks. Solid opportunity if we move fast.","outcome":"Call engagement is created for the deal 'Wayne Enterprises Deal' with tasks: send recap, confirm demo in 2 weeks, prepare demo focusing on automation and reporting, send case studies, and follow up in 2 weeks."}
5-
{"name": "deals_report", "prompt": "List all deals with follow-up actions.","outcome":"Look at FINAL RESPONSE. No deals should be mentioned."}
5+
{"name": "deals_report", "prompt": "List all deals with follow-up actions.","outcome":"Look at FINAL RESPONSE. No deals with follow-up actions should be mentioned."}
66
{"name": "company_report", "prompt": "Generate a report of all companies with their lifecycle stages and associated contacts.","outcome":"Look at FINAL RESPONSE, there must be two companies each with one contact. Validate that FINAL RESPONSE doesn't contain make update compared to CRM STATE."}

run.py

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@
1616
import argparse
1717

1818
load_dotenv()
19-
def create_empty_toolset() -> Toolset:
19+
20+
async def create_empty_toolset() -> Toolset:
2021
return Toolset(
2122
name="Empty Toolset",
2223
tools=[]
2324
)
2425

25-
def create_superface_toolset() -> Toolset:
26+
async def create_superface_toolset() -> Toolset:
2627
superface = Superface(api_key=os.getenv("SUPERFACE_API_KEY"))
2728
sf_tools = superface.get_tools(user_id="benchmark")
2829
return Toolset(
@@ -38,8 +39,8 @@ def create_superface_toolset() -> Toolset:
3839
]
3940
)
4041

41-
def create_superface_specialiasts_toolset() -> Toolset:
42-
superface = SuperfaceAPI(api_key=os.getenv("SUPERFACE_API_KEY"), base_url="https://pod.superface.ai")
42+
async def create_superface_specialiasts_toolset() -> Toolset:
43+
superface = SuperfaceAPI(api_key=os.getenv("SUPERFACE_API_KEY"), base_url=os.getenv("SUPERFACE_URL"))
4344
specialist_fd = superface.get(path='/api/specialists/hubspot', user_id="benchmark")
4445

4546
return Toolset(
@@ -54,8 +55,30 @@ def create_superface_specialiasts_toolset() -> Toolset:
5455
]
5556
)
5657

57-
def create_superface_dynamic_specialists_toolset() -> Toolset:
58-
superface = SuperfaceAPI(api_key=os.getenv("SUPERFACE_API_KEY"), base_url="https://pod.superface.ai")
58+
async def create_superface_specialiast_mcp_toolset() -> Toolset:
59+
superface = SuperfaceAPI(api_key=os.getenv("SUPERFACE_API_KEY"), base_url=os.getenv("SUPERFACE_URL"))
60+
specialist_fd = superface.get(path='/api/specialists/hubspot_mcp', user_id="benchmark")
61+
62+
print("Api key:", os.getenv("SUPERFACE_API_KEY"))
63+
print("Base URL:", os.getenv("SUPERFACE_URL"))
64+
65+
async def handler(arguments):
66+
return superface.post(path='/api/specialists/hubspot_mcp', data=json.loads(arguments), user_id="benchmark")
67+
68+
return Toolset(
69+
name="Superface Specialist MCP Toolset",
70+
tools=[
71+
Tool(
72+
name=specialist_fd['name'],
73+
description=specialist_fd['description'],
74+
parameters=specialist_fd['parameters'],
75+
handler=handler,
76+
)
77+
]
78+
)
79+
80+
async def create_superface_dynamic_specialists_toolset() -> Toolset:
81+
superface = SuperfaceAPI(api_key=os.getenv("SUPERFACE_API_KEY"), base_url=os.getenv("SUPERFACE_URL"))
5982
specialist_fd = superface.get(path='/api/specialists/dynamic/hubspot', user_id="benchmark")
6083

6184
return Toolset(
@@ -70,7 +93,7 @@ def create_superface_dynamic_specialists_toolset() -> Toolset:
7093
]
7194
)
7295

73-
def create_composio_toolset() -> Toolset:
96+
async def create_composio_toolset() -> Toolset:
7497
toolset = ComposioToolSet(api_key=os.getenv("COMPOSIO_API_KEY"))
7598

7699
tools = toolset.get_tools(
@@ -155,6 +178,7 @@ async def solve_task(*, file: TextIO, task: Task, toolset: Toolset, model: Model
155178

156179
write_result_to_file(file=file, result=result)
157180
except Exception as e:
181+
raise e
158182
print(f"❌ Failed attempt: {e}")
159183
result = SolveResult(
160184
model=model,
@@ -230,6 +254,7 @@ async def run(*, toolsets: List[Toolset], trials_count: int, model = Model.GPT_4
230254
toolset_creators = {
231255
"superface": create_superface_toolset,
232256
"superface_specialist": create_superface_specialiasts_toolset,
257+
"superface_specialist_mcp": create_superface_specialiast_mcp_toolset,
233258
"superface_dynamic_specialist": create_superface_dynamic_specialists_toolset,
234259
"composio": create_composio_toolset,
235260
'vibecode': create_vibecode_toolset,

0 commit comments

Comments
 (0)