From 970b2f9d3863fa92cb0306cd9f6497e7b9f47871 Mon Sep 17 00:00:00 2001 From: Harrison Chase Date: Tue, 13 Jun 2023 10:40:49 -0700 Subject: [PATCH] convert tools to openai (#6100) --- langchain/tools/__init__.py | 2 + langchain/tools/convert_to_openai.py | 53 +++++++++++++++++++++++ tests/unit_tests/tools/test_public_api.py | 1 + 3 files changed, 56 insertions(+) create mode 100644 langchain/tools/convert_to_openai.py diff --git a/langchain/tools/__init__.py b/langchain/tools/__init__.py index 06c2a9be..4b93bb6c 100644 --- a/langchain/tools/__init__.py +++ b/langchain/tools/__init__.py @@ -9,6 +9,7 @@ from langchain.tools.azure_cognitive_services import ( from langchain.tools.base import BaseTool, StructuredTool, Tool, tool from langchain.tools.bing_search.tool import BingSearchResults, BingSearchRun from langchain.tools.brave_search.tool import BraveSearch +from langchain.tools.convert_to_openai import format_tool_to_openai_function from langchain.tools.ddg_search.tool import DuckDuckGoSearchResults, DuckDuckGoSearchRun from langchain.tools.file_management.copy import CopyFileTool from langchain.tools.file_management.delete import DeleteFileTool @@ -122,4 +123,5 @@ __all__ = [ "YouTubeSearchTool", "BraveSearch", "PubmedQueryRun", + "format_tool_to_openai_function", ] diff --git a/langchain/tools/convert_to_openai.py b/langchain/tools/convert_to_openai.py new file mode 100644 index 00000000..d780e8ab --- /dev/null +++ b/langchain/tools/convert_to_openai.py @@ -0,0 +1,53 @@ +from typing import TypedDict + +from langchain.tools import BaseTool, StructuredTool + + +class FunctionDescription(TypedDict): + """Representation of a callable function to the OpenAI API.""" + + name: str + """The name of the function.""" + description: str + """A description of the function.""" + parameters: dict + """The parameters of the function.""" + + +def format_tool_to_openai_function(tool: BaseTool) -> FunctionDescription: + """Format tool into the open AI function API.""" + if isinstance(tool, StructuredTool): + schema_ = tool.args_schema.schema() + # Bug with required missing for structured tools. + required = sorted(schema_["properties"]) # BUG WORKAROUND + return { + "name": tool.name, + "description": tool.description, + "parameters": { + "type": "object", + "properties": schema_["properties"], + "required": required, + }, + } + else: + if tool.args_schema: + parameters = tool.args_schema.schema() + else: + parameters = { + # This is a hack to get around the fact that some tools + # do not expose an args_schema, and expect an argument + # which is a string. + # And Open AI does not support an array type for the + # parameters. + "properties": { + "__arg1": {"title": "__arg1", "type": "string"}, + }, + "required": ["__arg1"], + "type": "object", + } + + return { + "name": tool.name, + "description": tool.description, + "parameters": parameters, + } diff --git a/tests/unit_tests/tools/test_public_api.py b/tests/unit_tests/tools/test_public_api.py index c57de581..f5e8d33a 100644 --- a/tests/unit_tests/tools/test_public_api.py +++ b/tests/unit_tests/tools/test_public_api.py @@ -62,6 +62,7 @@ _EXPECTED = [ "YouTubeSearchTool", "BraveSearch", "PubmedQueryRun", + "format_tool_to_openai_function", ]