2025-04-16 10:00:22 +08:00
|
|
|
import json
|
|
|
|
|
|
|
|
from agentpress.tool import Tool, ToolResult, openapi_schema, xml_schema
|
2025-04-17 01:23:28 +08:00
|
|
|
from agent.tools.data_providers.LinkedinProvider import LinkedinProvider
|
|
|
|
from agent.tools.data_providers.YahooFinanceProvider import YahooFinanceProvider
|
|
|
|
from agent.tools.data_providers.AmazonProvider import AmazonProvider
|
2025-04-17 01:53:28 +08:00
|
|
|
from agent.tools.data_providers.ZillowProvider import ZillowProvider
|
2025-04-17 02:10:13 +08:00
|
|
|
from agent.tools.data_providers.TwitterProvider import TwitterProvider
|
2025-04-16 10:00:22 +08:00
|
|
|
|
2025-04-17 01:23:28 +08:00
|
|
|
class DataProvidersTool(Tool):
|
|
|
|
"""Tool for making requests to various data providers."""
|
2025-04-16 10:00:22 +08:00
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
super().__init__()
|
|
|
|
|
2025-04-17 01:23:28 +08:00
|
|
|
self.register_data_providers = {
|
|
|
|
"linkedin": LinkedinProvider(),
|
|
|
|
"yahoo_finance": YahooFinanceProvider(),
|
2025-04-17 01:53:28 +08:00
|
|
|
"amazon": AmazonProvider(),
|
2025-04-17 02:10:13 +08:00
|
|
|
"zillow": ZillowProvider(),
|
|
|
|
"twitter": TwitterProvider()
|
2025-04-16 10:00:22 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
@openapi_schema({
|
|
|
|
"type": "function",
|
|
|
|
"function": {
|
2025-04-17 01:23:28 +08:00
|
|
|
"name": "get_data_provider_endpoints",
|
|
|
|
"description": "Get available endpoints for a specific data provider",
|
2025-04-16 10:00:22 +08:00
|
|
|
"parameters": {
|
|
|
|
"type": "object",
|
|
|
|
"properties": {
|
|
|
|
"service_name": {
|
|
|
|
"type": "string",
|
2025-04-17 02:10:13 +08:00
|
|
|
"description": "The name of the data provider (e.g., 'linkedin', 'twitter', 'zillow', 'amazon', 'yahoo_finance')"
|
2025-04-16 10:00:22 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
"required": ["service_name"]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
@xml_schema(
|
2025-04-17 01:23:28 +08:00
|
|
|
tag_name="get-data-provider-endpoints",
|
2025-04-16 10:00:22 +08:00
|
|
|
mappings=[
|
|
|
|
{"param_name": "service_name", "node_type": "attribute", "path": "."}
|
|
|
|
],
|
|
|
|
example='''
|
|
|
|
<!--
|
2025-04-17 01:23:28 +08:00
|
|
|
The get-data-provider-endpoints tool returns available endpoints for a specific data provider.
|
2025-04-16 10:00:22 +08:00
|
|
|
Use this tool when you need to discover what endpoints are available.
|
|
|
|
-->
|
|
|
|
|
|
|
|
<!-- Example to get LinkedIn API endpoints -->
|
2025-04-17 01:23:28 +08:00
|
|
|
<get-data-provider-endpoints service_name="linkedin">
|
|
|
|
</get-data-provider-endpoints>
|
2025-04-16 10:00:22 +08:00
|
|
|
'''
|
|
|
|
)
|
2025-04-17 01:23:28 +08:00
|
|
|
async def get_data_provider_endpoints(
|
2025-04-16 10:00:22 +08:00
|
|
|
self,
|
|
|
|
service_name: str
|
|
|
|
) -> ToolResult:
|
|
|
|
"""
|
2025-04-17 01:23:28 +08:00
|
|
|
Get available endpoints for a specific data provider.
|
2025-04-16 10:00:22 +08:00
|
|
|
|
|
|
|
Parameters:
|
2025-04-17 01:23:28 +08:00
|
|
|
- service_name: The name of the data provider (e.g., 'linkedin')
|
2025-04-16 10:00:22 +08:00
|
|
|
"""
|
|
|
|
try:
|
|
|
|
if not service_name:
|
2025-04-17 01:23:28 +08:00
|
|
|
return self.fail_response("Data provider name is required.")
|
2025-04-16 10:00:22 +08:00
|
|
|
|
2025-04-17 01:23:28 +08:00
|
|
|
if service_name not in self.register_data_providers:
|
|
|
|
return self.fail_response(f"Data provider '{service_name}' not found. Available data providers: {list(self.register_data_providers.keys())}")
|
2025-04-16 10:00:22 +08:00
|
|
|
|
2025-04-17 01:23:28 +08:00
|
|
|
endpoints = self.register_data_providers[service_name].get_endpoints()
|
2025-04-16 10:00:22 +08:00
|
|
|
return self.success_response(endpoints)
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
error_message = str(e)
|
2025-04-17 01:23:28 +08:00
|
|
|
simplified_message = f"Error getting data provider endpoints: {error_message[:200]}"
|
2025-04-16 10:00:22 +08:00
|
|
|
if len(error_message) > 200:
|
|
|
|
simplified_message += "..."
|
|
|
|
return self.fail_response(simplified_message)
|
|
|
|
|
|
|
|
@openapi_schema({
|
|
|
|
"type": "function",
|
|
|
|
"function": {
|
2025-04-17 01:23:28 +08:00
|
|
|
"name": "execute_data_provider_call",
|
|
|
|
"description": "Execute a call to a specific data provider endpoint",
|
2025-04-16 10:00:22 +08:00
|
|
|
"parameters": {
|
|
|
|
"type": "object",
|
|
|
|
"properties": {
|
|
|
|
"service_name": {
|
|
|
|
"type": "string",
|
|
|
|
"description": "The name of the API service (e.g., 'linkedin')"
|
|
|
|
},
|
|
|
|
"route": {
|
|
|
|
"type": "string",
|
|
|
|
"description": "The key of the endpoint to call"
|
|
|
|
},
|
|
|
|
"payload": {
|
|
|
|
"type": "object",
|
|
|
|
"description": "The payload to send with the API call"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"required": ["service_name", "route"]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
@xml_schema(
|
2025-04-17 01:23:28 +08:00
|
|
|
tag_name="execute-data-provider-call",
|
2025-04-16 10:00:22 +08:00
|
|
|
mappings=[
|
|
|
|
{"param_name": "service_name", "node_type": "attribute", "path": "service_name"},
|
|
|
|
{"param_name": "route", "node_type": "attribute", "path": "route"},
|
|
|
|
{"param_name": "payload", "node_type": "content", "path": "."}
|
|
|
|
],
|
|
|
|
example='''
|
|
|
|
<!--
|
2025-04-17 01:23:28 +08:00
|
|
|
The execute-data-provider-call tool makes a request to a specific data provider endpoint.
|
|
|
|
Use this tool when you need to call an data provider endpoint with specific parameters.
|
|
|
|
The route must be a valid endpoint key obtained from get-data-provider-endpoints tool!!
|
2025-04-16 10:00:22 +08:00
|
|
|
-->
|
|
|
|
|
|
|
|
<!-- Example to call linkedIn service with the specific route person -->
|
2025-04-17 01:23:28 +08:00
|
|
|
<execute-data-provider-call service_name="linkedin" route="person">
|
2025-04-16 10:00:22 +08:00
|
|
|
{"link": "https://www.linkedin.com/in/johndoe/"}
|
2025-04-17 01:23:28 +08:00
|
|
|
</execute-data-provider-call>
|
2025-04-16 10:00:22 +08:00
|
|
|
'''
|
|
|
|
)
|
2025-04-17 01:23:28 +08:00
|
|
|
async def execute_data_provider_call(
|
2025-04-16 10:00:22 +08:00
|
|
|
self,
|
|
|
|
service_name: str,
|
|
|
|
route: str,
|
|
|
|
payload: str # this actually a json string
|
|
|
|
) -> ToolResult:
|
|
|
|
"""
|
2025-04-17 01:23:28 +08:00
|
|
|
Execute a call to a specific data provider endpoint.
|
2025-04-16 10:00:22 +08:00
|
|
|
|
|
|
|
Parameters:
|
2025-04-17 01:23:28 +08:00
|
|
|
- service_name: The name of the data provider (e.g., 'linkedin')
|
2025-04-16 10:00:22 +08:00
|
|
|
- route: The key of the endpoint to call
|
2025-04-17 01:23:28 +08:00
|
|
|
- payload: The payload to send with the data provider call
|
2025-04-16 10:00:22 +08:00
|
|
|
"""
|
|
|
|
try:
|
|
|
|
payload = json.loads(payload)
|
|
|
|
|
|
|
|
if not service_name:
|
|
|
|
return self.fail_response("service_name is required.")
|
|
|
|
|
|
|
|
if not route:
|
|
|
|
return self.fail_response("route is required.")
|
|
|
|
|
2025-04-17 01:23:28 +08:00
|
|
|
if service_name not in self.register_data_providers:
|
|
|
|
return self.fail_response(f"API '{service_name}' not found. Available APIs: {list(self.register_data_providers.keys())}")
|
2025-04-16 10:00:22 +08:00
|
|
|
|
2025-04-17 01:23:28 +08:00
|
|
|
data_provider = self.register_data_providers[service_name]
|
2025-04-16 10:00:22 +08:00
|
|
|
if route == service_name:
|
|
|
|
return self.fail_response(f"route '{route}' is the same as service_name '{service_name}'. YOU FUCKING IDIOT!")
|
|
|
|
|
2025-04-17 01:23:28 +08:00
|
|
|
if route not in data_provider.get_endpoints().keys():
|
|
|
|
return self.fail_response(f"Endpoint '{route}' not found in {service_name} data provider.")
|
2025-04-16 10:00:22 +08:00
|
|
|
|
|
|
|
|
2025-04-17 01:23:28 +08:00
|
|
|
result = data_provider.call_endpoint(route, payload)
|
2025-04-16 10:00:22 +08:00
|
|
|
return self.success_response(result)
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
error_message = str(e)
|
|
|
|
print(error_message)
|
2025-04-17 01:23:28 +08:00
|
|
|
simplified_message = f"Error executing data provider call: {error_message[:200]}"
|
2025-04-16 10:00:22 +08:00
|
|
|
if len(error_message) > 200:
|
|
|
|
simplified_message += "..."
|
|
|
|
return self.fail_response(simplified_message)
|