mirror of https://github.com/microsoft/autogen.git
* Remove isinstance check from FunctionTool (#3987) * Move __init__ Args to class docstring --------- Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
This commit is contained in:
parent
f40336fda1
commit
eca8a95c61
|
@ -59,6 +59,13 @@
|
||||||
"print(code_execution_tool.return_value_as_string(result))"
|
"print(code_execution_tool.return_value_as_string(result))"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": []
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
|
@ -82,6 +89,11 @@
|
||||||
"To create a custom function tool, you just need to create a Python function\n",
|
"To create a custom function tool, you just need to create a Python function\n",
|
||||||
"and use the {py:class}`~autogen_core.components.tools.FunctionTool` class to wrap it.\n",
|
"and use the {py:class}`~autogen_core.components.tools.FunctionTool` class to wrap it.\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
"The {py:class}`~autogen_core.components.tools.FunctionTool` class uses descriptions and type annotations\n",
|
||||||
|
"to inform the LLM when and how to use a given function. The description provides context\n",
|
||||||
|
"about the function’s purpose and intended use cases, while type annotations inform the LLM about\n",
|
||||||
|
"the expected parameters and return type.\n",
|
||||||
|
"\n",
|
||||||
"For example, a simple tool to obtain the stock price of a company might look like this:"
|
"For example, a simple tool to obtain the stock price of a company might look like this:"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -296,7 +308,7 @@
|
||||||
"name": "python",
|
"name": "python",
|
||||||
"nbconvert_exporter": "python",
|
"nbconvert_exporter": "python",
|
||||||
"pygments_lexer": "ipython3",
|
"pygments_lexer": "ipython3",
|
||||||
"version": "3.11.9"
|
"version": "3.12.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nbformat": 4,
|
"nbformat": 4,
|
||||||
|
|
|
@ -13,6 +13,52 @@ from ._base import BaseTool
|
||||||
|
|
||||||
|
|
||||||
class FunctionTool(BaseTool[BaseModel, BaseModel]):
|
class FunctionTool(BaseTool[BaseModel, BaseModel]):
|
||||||
|
"""
|
||||||
|
Create custom tools by wrapping standard Python functions.
|
||||||
|
|
||||||
|
`FunctionTool` offers an interface for executing Python functions either asynchronously or synchronously.
|
||||||
|
Each function must include type annotations for all parameters and its return type. These annotations
|
||||||
|
enable `FunctionTool` to generate a schema necessary for input validation, serialization, and for informing
|
||||||
|
the LLM about expected parameters. When the LLM prepares a function call, it leverages this schema to
|
||||||
|
generate arguments that align with the function's specifications.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
It is the user's responsibility to verify that the tool's output type matches the expected type.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
func (Callable[..., ReturnT | Awaitable[ReturnT]]): The function to wrap and expose as a tool.
|
||||||
|
description (str): A description to inform the model of the function's purpose, specifying what
|
||||||
|
it does and the context in which it should be called.
|
||||||
|
name (str, optional): An optional custom name for the tool. Defaults to
|
||||||
|
the function's original name if not provided.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
import random
|
||||||
|
from autogen_core.base import CancellationToken
|
||||||
|
from autogen_core.components.tools import FunctionTool
|
||||||
|
from typing_extensions import Annotated
|
||||||
|
|
||||||
|
|
||||||
|
async def get_stock_price(ticker: str, date: Annotated[str, "Date in YYYY/MM/DD"]) -> float:
|
||||||
|
# Simulates a stock price retrieval by returning a random float within a specified range.
|
||||||
|
return random.uniform(10, 200)
|
||||||
|
|
||||||
|
|
||||||
|
# Initialize a FunctionTool instance for retrieving stock prices.
|
||||||
|
stock_price_tool = FunctionTool(get_stock_price, description="Fetch the stock price for a given ticker.")
|
||||||
|
|
||||||
|
# Execute the tool with cancellation support.
|
||||||
|
cancellation_token = CancellationToken()
|
||||||
|
result = await stock_price_tool.run_json({"ticker": "AAPL", "date": "2021/01/01"}, cancellation_token)
|
||||||
|
|
||||||
|
# Output the result as a formatted string.
|
||||||
|
print(stock_price_tool.return_value_as_string(result))
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, func: Callable[..., Any], description: str, name: str | None = None) -> None:
|
def __init__(self, func: Callable[..., Any], description: str, name: str | None = None) -> None:
|
||||||
self._func = func
|
self._func = func
|
||||||
signature = get_typed_signature(func)
|
signature = get_typed_signature(func)
|
||||||
|
@ -46,6 +92,4 @@ class FunctionTool(BaseTool[BaseModel, BaseModel]):
|
||||||
cancellation_token.link_future(future)
|
cancellation_token.link_future(future)
|
||||||
result = await future
|
result = await future
|
||||||
|
|
||||||
if not isinstance(result, self.return_type()):
|
|
||||||
raise ValueError(f"Expected return type {self.return_type()}, got {type(result)}")
|
|
||||||
return result
|
return result
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import inspect
|
import inspect
|
||||||
from typing import Annotated
|
from typing import Annotated, List
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from autogen_core.base import CancellationToken
|
from autogen_core.base import CancellationToken
|
||||||
|
@ -324,3 +324,15 @@ def test_convert_tools_accepts_both_tool_and_schema() -> None:
|
||||||
|
|
||||||
assert len(converted_tool_schema) == 2
|
assert len(converted_tool_schema) == 2
|
||||||
assert converted_tool_schema[0] == converted_tool_schema[1]
|
assert converted_tool_schema[0] == converted_tool_schema[1]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_func_tool_return_list() -> None:
|
||||||
|
def my_function() -> List[int]:
|
||||||
|
return [1, 2]
|
||||||
|
|
||||||
|
tool = FunctionTool(my_function, description="Function tool.")
|
||||||
|
result = await tool.run_json({}, CancellationToken())
|
||||||
|
assert isinstance(result, list)
|
||||||
|
assert result == [1, 2]
|
||||||
|
assert tool.return_value_as_string(result) == "[1, 2]"
|
||||||
|
|
Loading…
Reference in New Issue