diff --git a/helpers/tools.ts b/helpers/tools.ts index 2f7bb75ddf606a6729bf5e0f4828f79f4c18e500..70ee87723b5eceaa4ab5c4e66e5d6bda3514c492 100644 --- a/helpers/tools.ts +++ b/helpers/tools.ts @@ -118,8 +118,8 @@ export const supportedTools: Tool[] = [ ], }, { - display: "OpenAPI", - name: "openapi.OpenAPIToolSpec", + display: "OpenAPI action", + name: "openapi_action.OpenAPIActionToolSpec", dependencies: [ { name: "llama-index-tools-openapi", @@ -129,35 +129,21 @@ export const supportedTools: Tool[] = [ name: "jsonschema", version: "^4.22.0", }, - ], - config: { - url: "The URL of the OpenAPI schema", - }, - supportedFrameworks: ["fastapi"], - type: ToolType.LLAMAHUB, - envVars: [ { - name: TOOL_SYSTEM_PROMPT_ENV_VAR, - description: "System prompt for openapi tool.", - value: `You can use the provided OpenAPI schema to see the available endpoints to make requests with the HTTP Request tool.`, + name: "llama-index-tools-requests", + version: "0.1.3", }, ], - }, - { - display: "HTTP Request", - name: "requests.RequestsToolSpec", - dependencies: [], - supportedFrameworks: ["fastapi"], - type: ToolType.LLAMAHUB, config: { - domain_headers: - "A mapping of domain to its headers. Example: example.com: {}", + openapi_uri: "The URL or file path of the OpenAPI schema", }, + supportedFrameworks: ["fastapi"], + type: ToolType.LOCAL, envVars: [ { name: TOOL_SYSTEM_PROMPT_ENV_VAR, - description: "System prompt for openapi tool.", - value: `You can make HTTP requests to the provided domain.`, + description: "System prompt for openapi action tool.", + value: `You are an OpenAPI action agent. You help users to make requests to the provided OpenAPI schema.`, }, ], }, diff --git a/templates/components/engines/python/agent/tools/openapi_action.py b/templates/components/engines/python/agent/tools/openapi_action.py new file mode 100644 index 0000000000000000000000000000000000000000..d47fa6652ad54a801fc701d4a34629031501e28e --- /dev/null +++ b/templates/components/engines/python/agent/tools/openapi_action.py @@ -0,0 +1,59 @@ +import inspect +from typing import Dict, List, Tuple +from llama_index.tools.openapi import OpenAPIToolSpec +from llama_index.tools.requests import RequestsToolSpec + + +class OpenAPIActionToolSpec(OpenAPIToolSpec, RequestsToolSpec): + """ + A combination of OpenAPI and Requests tool specs that can parse OpenAPI specs and make requests. + + openapi_uri: str: The file path or URL to the OpenAPI spec. + domain_headers: dict: Whitelist domains and the headers to use. + """ + + spec_functions = OpenAPIToolSpec.spec_functions + RequestsToolSpec.spec_functions + + def __init__(self, openapi_uri: str, domain_headers: dict = {}, **kwargs): + # Load the OpenAPI spec + openapi_spec, servers = self.load_openapi_spec(openapi_uri) + + # Add the servers to the domain headers if they are not already present + for server in servers: + if server not in domain_headers: + domain_headers[server] = {} + + OpenAPIToolSpec.__init__(self, spec=openapi_spec) + RequestsToolSpec.__init__(self, domain_headers) + + @staticmethod + def load_openapi_spec(uri: str) -> Tuple[Dict, List[str]]: + """ + Load an OpenAPI spec from a URI. + + Args: + uri (str): A file path or URL to the OpenAPI spec. + + Returns: + List[Document]: A list of Document objects. + """ + import yaml + from urllib.parse import urlparse + + if uri.startswith("http"): + import requests + + response = requests.get(uri).text + spec = yaml.safe_load(response) + elif uri.startswith("file"): + filepath = uri[7:] # Remove the 'file://' scheme + with open(filepath, "r") as file: + spec = yaml.safe_load(file) + else: + raise ValueError( + "Could not initialize OpenAPIActionToolSpec because invalid OpenAPI URI provided. " + "Only HTTP and file path are supported." + ) + # Add the servers to the whitelist + servers = [urlparse(server["url"]).netloc for server in spec.get("servers", [])] + return spec, servers