mirror of
https://github.com/hwchase17/langchain.git
synced 2025-07-18 18:53:10 +00:00
core[patch]: convert_to_openai_tool Anthropic support (#27591)
This commit is contained in:
parent
217de4e6a6
commit
968dccee04
@ -883,8 +883,6 @@ def convert_to_openai_messages(
|
|||||||
) -> Union[dict, list[dict]]:
|
) -> Union[dict, list[dict]]:
|
||||||
"""Convert LangChain messages into OpenAI message dicts.
|
"""Convert LangChain messages into OpenAI message dicts.
|
||||||
|
|
||||||
.. versionadded:: 0.3.11
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
messages: Message-like object or iterable of objects whose contents are
|
messages: Message-like object or iterable of objects whose contents are
|
||||||
in OpenAI, Anthropic, Bedrock Converse, or VertexAI formats.
|
in OpenAI, Anthropic, Bedrock Converse, or VertexAI formats.
|
||||||
@ -937,6 +935,8 @@ def convert_to_openai_messages(
|
|||||||
# {'role': 'assistant', 'content': 'thats nice'}
|
# {'role': 'assistant', 'content': 'thats nice'}
|
||||||
# ]
|
# ]
|
||||||
|
|
||||||
|
.. versionadded:: 0.3.11
|
||||||
|
|
||||||
""" # noqa: E501
|
""" # noqa: E501
|
||||||
if text_format not in ("string", "block"):
|
if text_format not in ("string", "block"):
|
||||||
err = f"Unrecognized {text_format=}, expected one of 'string' or 'block'."
|
err = f"Unrecognized {text_format=}, expected one of 'string' or 'block'."
|
||||||
|
@ -336,30 +336,32 @@ def convert_to_openai_function(
|
|||||||
strict: Optional[bool] = None,
|
strict: Optional[bool] = None,
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
"""Convert a raw function/class to an OpenAI function.
|
"""Convert a raw function/class to an OpenAI function.
|
||||||
|
|
||||||
.. versionchanged:: 0.2.29
|
|
||||||
|
|
||||||
``strict`` arg added.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
function:
|
function:
|
||||||
A dictionary, Pydantic BaseModel class, TypedDict class, a LangChain
|
A dictionary, Pydantic BaseModel class, TypedDict class, a LangChain
|
||||||
Tool object, or a Python function. If a dictionary is passed in, it is
|
Tool object, or a Python function. If a dictionary is passed in, it is
|
||||||
assumed to already be a valid OpenAI function or a JSON schema with
|
assumed to already be a valid OpenAI function, a JSON schema with
|
||||||
top-level 'title' and 'description' keys specified.
|
top-level 'title' and 'description' keys specified, or an Anthropic format
|
||||||
|
tool.
|
||||||
strict:
|
strict:
|
||||||
If True, model output is guaranteed to exactly match the JSON Schema
|
If True, model output is guaranteed to exactly match the JSON Schema
|
||||||
provided in the function definition. If None, ``strict`` argument will not
|
provided in the function definition. If None, ``strict`` argument will not
|
||||||
be included in function definition.
|
be included in function definition.
|
||||||
|
|
||||||
.. versionadded:: 0.2.29
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A dict version of the passed in function which is compatible with the OpenAI
|
A dict version of the passed in function which is compatible with the OpenAI
|
||||||
function-calling API.
|
function-calling API.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
ValueError: If function is not in a supported format.
|
ValueError: If function is not in a supported format.
|
||||||
|
|
||||||
|
.. versionchanged:: 0.2.29
|
||||||
|
|
||||||
|
``strict`` arg added.
|
||||||
|
|
||||||
|
.. versionchanged:: 0.3.13
|
||||||
|
|
||||||
|
Support for Anthropic format tools added.
|
||||||
"""
|
"""
|
||||||
from langchain_core.tools import BaseTool
|
from langchain_core.tools import BaseTool
|
||||||
|
|
||||||
@ -378,6 +380,15 @@ def convert_to_openai_function(
|
|||||||
"description": function.pop("description"),
|
"description": function.pop("description"),
|
||||||
"parameters": function,
|
"parameters": function,
|
||||||
}
|
}
|
||||||
|
# an Anthropic format tool
|
||||||
|
elif isinstance(function, dict) and all(
|
||||||
|
k in function for k in ("name", "description", "input_schema")
|
||||||
|
):
|
||||||
|
oai_function = {
|
||||||
|
"name": function["name"],
|
||||||
|
"description": function["description"],
|
||||||
|
"parameters": function["input_schema"],
|
||||||
|
}
|
||||||
elif isinstance(function, type) and is_basemodel_subclass(function):
|
elif isinstance(function, type) and is_basemodel_subclass(function):
|
||||||
oai_function = cast(dict, convert_pydantic_to_openai_function(function))
|
oai_function = cast(dict, convert_pydantic_to_openai_function(function))
|
||||||
elif is_typeddict(function):
|
elif is_typeddict(function):
|
||||||
@ -414,34 +425,35 @@ def convert_to_openai_tool(
|
|||||||
*,
|
*,
|
||||||
strict: Optional[bool] = None,
|
strict: Optional[bool] = None,
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
"""Convert a raw function/class to an OpenAI tool.
|
"""Convert a tool-like object to an OpenAI tool schema.
|
||||||
|
|
||||||
.. versionchanged:: 0.2.29
|
|
||||||
|
|
||||||
``strict`` arg added.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
tool:
|
tool:
|
||||||
Either a dictionary, a pydantic.BaseModel class, Python function, or
|
Either a dictionary, a pydantic.BaseModel class, Python function, or
|
||||||
BaseTool. If a dictionary is passed in, it is assumed to already be a valid
|
BaseTool. If a dictionary is passed in, it is assumed to already be a valid
|
||||||
OpenAI tool, OpenAI function, or a JSON schema with top-level 'title' and
|
OpenAI tool, OpenAI function, a JSON schema with top-level 'title' and
|
||||||
'description' keys specified.
|
'description' keys specified, or an Anthropic format tool.
|
||||||
strict:
|
strict:
|
||||||
If True, model output is guaranteed to exactly match the JSON Schema
|
If True, model output is guaranteed to exactly match the JSON Schema
|
||||||
provided in the function definition. If None, ``strict`` argument will not
|
provided in the function definition. If None, ``strict`` argument will not
|
||||||
be included in tool definition.
|
be included in tool definition.
|
||||||
|
|
||||||
.. versionadded:: 0.2.29
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A dict version of the passed in tool which is compatible with the
|
A dict version of the passed in tool which is compatible with the
|
||||||
OpenAI tool-calling API.
|
OpenAI tool-calling API.
|
||||||
|
|
||||||
|
.. versionchanged:: 0.2.29
|
||||||
|
|
||||||
|
``strict`` arg added.
|
||||||
|
|
||||||
|
.. versionchanged:: 0.3.13
|
||||||
|
|
||||||
|
Support for Anthropic format tools added.
|
||||||
"""
|
"""
|
||||||
if isinstance(tool, dict) and tool.get("type") == "function" and "function" in tool:
|
if isinstance(tool, dict) and tool.get("type") == "function" and "function" in tool:
|
||||||
return tool
|
return tool
|
||||||
oai_function = convert_to_openai_function(tool, strict=strict)
|
oai_function = convert_to_openai_function(tool, strict=strict)
|
||||||
oai_tool: dict[str, Any] = {"type": "function", "function": oai_function}
|
return {"type": "function", "function": oai_function}
|
||||||
return oai_tool
|
|
||||||
|
|
||||||
|
|
||||||
def tool_example_to_messages(
|
def tool_example_to_messages(
|
||||||
|
@ -210,6 +210,26 @@ def json_schema() -> dict:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def anthropic_tool() -> dict:
|
||||||
|
return {
|
||||||
|
"name": "dummy_function",
|
||||||
|
"description": "dummy function",
|
||||||
|
"input_schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"arg1": {"description": "foo", "type": "integer"},
|
||||||
|
"arg2": {
|
||||||
|
"description": "one of 'bar', 'baz'",
|
||||||
|
"enum": ["bar", "baz"],
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"required": ["arg1", "arg2"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class Dummy:
|
class Dummy:
|
||||||
def dummy_function(self, arg1: int, arg2: Literal["bar", "baz"]) -> None:
|
def dummy_function(self, arg1: int, arg2: Literal["bar", "baz"]) -> None:
|
||||||
"""dummy function
|
"""dummy function
|
||||||
@ -237,6 +257,7 @@ def test_convert_to_openai_function(
|
|||||||
dummy_structured_tool: StructuredTool,
|
dummy_structured_tool: StructuredTool,
|
||||||
dummy_tool: BaseTool,
|
dummy_tool: BaseTool,
|
||||||
json_schema: dict,
|
json_schema: dict,
|
||||||
|
anthropic_tool: dict,
|
||||||
annotated_function: Callable,
|
annotated_function: Callable,
|
||||||
dummy_pydantic: type[BaseModel],
|
dummy_pydantic: type[BaseModel],
|
||||||
runnable: Runnable,
|
runnable: Runnable,
|
||||||
@ -268,6 +289,7 @@ def test_convert_to_openai_function(
|
|||||||
dummy_structured_tool,
|
dummy_structured_tool,
|
||||||
dummy_tool,
|
dummy_tool,
|
||||||
json_schema,
|
json_schema,
|
||||||
|
anthropic_tool,
|
||||||
expected,
|
expected,
|
||||||
Dummy.dummy_function,
|
Dummy.dummy_function,
|
||||||
DummyWithClassMethod.dummy_function,
|
DummyWithClassMethod.dummy_function,
|
||||||
|
Loading…
Reference in New Issue
Block a user