Tools#
This page presents all APIs and classes related to tools in WayFlow
Tip
Click the button above ↑ to visit the Agent Spec Documentation
Client Tool#
- class wayflowcore.tools.clienttools.ClientTool(name, description, input_descriptors=None, output_descriptors=None, parameters=None, output=None, id=None, __metadata_info__=None)#
Contains the description of a tool, including its name, documentation and schema of its arguments. Instead of being run in the server, calling this tool will actually yield to the client for them to compute the result, and post it back to continue execution.
- Parameters:
- name#
name of the tool
- description#
description of the tool
- Type:
str
- input_descriptors#
list of properties describing the inputs of the tool.
- output_descriptors#
list of properties describing the outputs of the tool.
If there is a single output descriptor, the tool needs to just return the value. If there are several output descriptors, the tool needs to return a dict of all expected values.
If no output descriptor is passed, or if a single output descriptor is passed without a name, the output will be automatically be named
Tool.DEFAULT_TOOL_NAME
.
Examples
>>> from wayflowcore.tools import ClientTool >>> from wayflowcore.property import FloatProperty >>> addition_client_tool = ClientTool( ... name="add_numbers", ... description="Simply adds two numbers", ... input_descriptors=[ ... FloatProperty(name="a", description="the first number", default_value=0), ... FloatProperty(name="b", description="the second number"), ... ], ... )
- property might_yield: bool#
Server Tool#
- class wayflowcore.tools.servertools.ServerTool(name, description, func, input_descriptors=None, output_descriptors=None, parameters=None, output=None, id=None, _cpu_bounded=False, __metadata_info__=None)#
Contains the description and callable of a tool, including its name, documentation and schema of its arguments. This tool is executed on the server side, with the provided callable.
- Parameters:
name (str) –
description (str) –
func (Callable[[...], Any]) –
input_descriptors (List[Property] | None) –
output_descriptors (List[Property] | None) –
parameters (Dict[str, JsonSchemaParam] | None) –
output (JsonSchemaParam | None) –
id (str | None) –
_cpu_bounded (bool) –
__metadata_info__ (Dict[str, Any] | None) –
- name#
name of the tool
- description#
description of the tool
- Type:
str
- input_descriptors#
list of properties describing the inputs of the tool.
- output_descriptors#
list of properties describing the outputs of the tool.
If there is a single output descriptor, the tool needs to just return the value. If there are several output descriptors, the tool needs to return a dict of all expected values.
If no output descriptor is passed, or if a single output descriptor is passed without a name, the output will be automatically be named
Tool.DEFAULT_TOOL_NAME
.
- func#
tool callable
- Type:
Callable
Examples
>>> from wayflowcore.tools import ServerTool >>> from wayflowcore.property import FloatProperty
>>> def add_tool(arg1, arg2): ... return arg1 + arg2
>>> addition_client_tool = ServerTool( ... name="add_tool", ... description="Simply adds two numbers", ... input_descriptors=[ ... FloatProperty(name="a", description="the first number", default_value= 0.0), ... FloatProperty(name="b", description="the second number"), ... ], ... output_descriptors=[FloatProperty()], ... func=add_tool, ... )
You can also write tools with several outputs. Make sure the tool returns a dict with the appropriate names and types, and specify the
output_descriptors
:>>> from typing import Any, Dict >>> from wayflowcore.property import StringProperty, IntegerProperty >>> def some_func(a: int, b: str) -> Dict[str, Any]: ... return {'renamed_a': a, 'renamed_b': b} # keys and types of values need to correspond to output_descriptors >>> tool = ServerTool( ... name='my_tool', ... description='some description', ... input_descriptors=[ ... IntegerProperty(name='a'), ... StringProperty(name='b'), ... ], ... output_descriptors=[ ... IntegerProperty(name='renamed_a'), ... StringProperty(name='renamed_b'), ... ], ... func=some_func, ... )
- classmethod from_any(tool, **kwargs)#
- Parameters:
tool (ServerTool | Flow | Step | DescribedFlow | Any) –
kwargs (Any) –
- Return type:
- classmethod from_flow(flow, flow_name, flow_description, flow_output=None)#
Converts a flow into a server-side tool that will be executed on the server.
- Parameters:
flow (Flow) – The flow to be executed as the tool
flow_name (str) – The name given to the flow to be used as the tool name
flow_description (str) – The description to be used as description of the tool
flow_output (List[str] | str | None) – Optional list of flow outputs to collect. By default will collect all flow outputs, otherwise will only collect the outputs which names are specified in this argument.
- Raises:
ValueError – If the input flow is a potentially-yielding flow (conversion to
ServerTool
is not supported).- Return type:
- classmethod from_langchain(tool)#
Converts a usual Langchain tool into a server-side tool that will be executed on the server.
- Parameters:
tool (Any) – langchain tool to convert
- Return type:
- classmethod from_step(step, step_name, step_description, step_output=None)#
Converts a step into a server-side tool that will be executed on the server.
- Parameters:
step (Step) – The step to be executed as the tool
step_name (str) – The name given to the step to be used as the tool name
step_description (str) – The description to be used as description of the tool
step_output (List[str] | str | None) – Optional list of flow outputs to collect. By default will collect all flow outputs, otherwise will only collect the outputs which names are specified in this argument.
- Raises:
ValueError – If the input step is a potentially-yielding step (conversion to
ServerTool
is not supported).- Return type:
- run(*args, **kwargs)#
Runs the tool in a synchronous manner, no matter the synchronous or asynchronous aspect of its func attribute.
- Parameters:
args (Any) –
kwargs (Any) –
- Return type:
Any
- async run_async(*args, **kwargs)#
Runs the tool in an asynchronous manner, no matter the synchronous or asynchronous aspect of its func attribute. If func is synchronous, it will run in an anyio worker thread.
- Parameters:
args (Any) –
kwargs (Any) –
- Return type:
Any
Remote Tool#
- class wayflowcore.tools.remotetools.RemoteTool(*, url, method, name=None, description=None, json_body=None, data=None, params=None, headers=None, cookies=None, output_jq_query=None, ignore_bad_http_requests=False, num_retry_on_bad_http_request=3, input_descriptors=None, output_descriptors=None, allow_insecure_http=False, url_allow_list=None, allow_credentials=True, allow_fragments=True, default_ports={'http': 80, 'https': 443}, id=None, tool_name=None, tool_description=None, __metadata_info__=None)#
A Remote tool is a ServerTool that performs a web request.
Caution
Since the Agent can generate arguments (url, method, json_body, data, params, headers, cookies) or parts of these arguments in the respective Jinja templates, this can impose a security risk of information leakage and enable specific attack vectors like automated DDOS attacks. Please use
RemoteTool
responsibly and ensure that only valid URLs can be given as arguments or that no sensitive information is used for any of these arguments by the agent. Please use theurl_allow_list
,allow_credentials
andallow_fragments
parameters to control which URLs are treated as valid.- Parameters:
name (str) – The name of the tool
description (str) – The description of the tool. This text is passed in prompt of LLMs to guide the usage of the tool
url (str) – Url to call. Can be templated using jinja templates.
method (str) – HTTP method to call. Common methods are: GET, OPTIONS, HEAD, POST, PUT, PATCH, or DELETE. Can be templated using jinja templates.
json_body (Any | None) –
A json-serializable object that will automatically be converted to json and sent as a body. Cannot be used in combination with
data
. Can be templated using jinja templates.Note
Special case: if the
json_body
is astr
it will be taken as a literal json string. Setting this parameter automatically sets theContent-Type: application/json
header.Warning
The
json_body
parameter is only relevant for http methods that allow bodies, e.g. POST, PUT, PATCH.data (Dict[Any, Any] | List[Tuple[Any, Any]] | str | bytes | None) –
Raw data that will be sent in the body. Semantics of this are the same as in the
requests
library. Cannot be used in combination withjson_body
. Can be templated using jinja templates.Warning
The
data
parameter is only relevant for http methods that allow bodies, e.g. POST, PUT, PATCH.params (Dict[Any, Any] | List[Tuple[Any, Any]] | str | bytes | None) – Data to send as query-parameters (i.e. the
?foo=bar&gnu=gna
part of queries) Semantics of this are the same as in therequests
library. Can be templated using jinja templates.headers (Dict[str, str] | None) –
Explicitly set headers. Can be templated using jinja templates.
Note
This will override any of the implicitly set headers (e.g.
Content-Type
fromjson_body
).cookies (Dict[str, str] | None) – Cookies to transmit. Can be templated using jinja templates.
output_jq_query (str | None) – A jq query to extract some data from the json response. If left to None, the whole response is returned
ignore_bad_http_requests (bool) – If
True
, don’t throw an exception when query results in a bad status code (e.g. 4xx, 5xx); ifFalse
throws an exception.num_retry_on_bad_http_request (int) – Number of times to retry a failed http request before continuing (depending on the
ignore_bad_http_requests
setting above).allow_insecure_http (bool) – If
True
, allows url to have a unsecured non-ssl http scheme. Default isFalse
and throws a ValueError if url is unsecure.url_allow_list (List[str] | None) –
- A list of URLs that any request URL is matched against.
If there is at least one entry in the allow list that the requested URL matches, the request is considered allowed.
We consider URLs following the generic-URL syntax as defined in RFC 1808:
<scheme>://<net_loc>/<path>;<params>?<query>#<fragment>
Matching is done according to the following rules:
URL scheme must match exactly
URL authority (net_loc) must match exactly
URL path must prefix match the path given by the entry in the allow list
We do not support matching against specific params, fragments or query elements of the URLs.
Examples of matches:
URL: “https://example.com/page”, allow_list: [”https://example.com”]
URL: “https://specific.com/path/and/more”, allow_list: [”https://specific.com/path”]
Examples of mismatches:
URL: “http://someurl.example.com”, allow_list: [”http://other.example.com”]
URL: “http://someurl.example.com/endpoint”, allow_list: [”http://”] (results in a validation error)
Can be used to restrict requests to a set of allowed urls.
allow_credentials (bool) –
Whether to allow URLs containing credentials. If set to
False
, requested URLs and those in the allow list containing credentials will be rejected. Default isTrue
.Example of a URL containing credentials: “https://user:pass@example.com/”
allow_fragments (bool) –
Whether to allow fragments in requested URLs and in entries in the allow list. If set to
False
, fragments will not be allowed. Default isTrue
.We consider URLs following the generic-URL syntax as defined in RFC 1808:
<scheme>://<net_loc>/<path>;<params>?<query>#<fragment>
default_ports (Dict[str, int]) – A dictionary containing default schemes and their respective ports. These ports will be removed from URLs requested or from entries in the allow list during URL normalization. Default is
{'http': 80, 'https': 443}
.input_descriptors (List[Property]) –
output_descriptors (List[Property]) –
id (str | None) –
tool_name (str | None) –
tool_description (str | None) –
__metadata_info__ (Dict[str, Any] | None) –
Examples
Below is an example of a remote tool that is configured to update the value of a field on a Jira ticket
>>> from wayflowcore.property import StringProperty >>> from wayflowcore.tools.remotetools import RemoteTool >>> >>> JIRA_API_BASE_URL = "https://yourjirainstance.yourdomain.com" >>> JIRA_ACCESS_TOKEN = "your_secret_access_token" >>> >>> record_incident_root_cause_tool = RemoteTool( ... tool_name="record_incident_root_cause_tool", ... tool_description="Updates the root cause of an incident in Jira", ... url=JIRA_API_BASE_URL+"/rest/api/2/issue/{{jira_issue_id}}", ... input_descriptors=[ ... StringProperty(name="jira_issue_id", description="The ID of the Jira issue to update"), ... StringProperty( ... name="root_cause", description="The root cause description to be recorded" ... ), ... ], ... method="PUT", ... json_body={"fields": {"customfield_12602": "{{root_cause}}"}}, ... headers={ ... "Authorization": f"Bearer {JIRA_ACCESS_TOKEN}", ... "Content-Type": "application/json", ... }, ... url_allow_list=[JIRA_API_BASE_URL] ... )
You can then give the tool to either an Agent or to a ToolExecutionStep to be used in a Flow. Additionally, you can test the tool in isolation by invoking it as below:
record_incident_root_cause_tool.func( jira_issue_id="test-ticket", root_cause="this is the root cause" )
- allow_credentials: bool#
- allow_fragments: bool#
- allow_insecure_http: bool#
- cookies: Dict[str, str] | None#
- data: Dict[Any, Any] | List[Tuple[Any, Any]] | str | bytes | None#
- default_ports: Dict[str, int]#
- description: str#
- headers: Dict[str, str] | None#
- ignore_bad_http_requests: bool#
- json_body: Any | None#
- method: str#
- name: str#
- num_retry_on_bad_http_request: int#
- output_jq_query: str | None#
- params: Dict[Any, Any] | List[Tuple[Any, Any]] | str | bytes | None#
- url: str#
- url_allow_list: List[str] | None#
MCP Tool#
Model Context Protocol (MCP) is an open protocol that standardizes how applications provide context to LLMs.
- class wayflowcore.mcp.MCPTool(name, client_transport, description=None, input_descriptors=None, output_descriptors=None, _validate_server_exists=True, _validate_tool_exist_on_server=True, __metadata_info__=None, id=None)#
Class to represent a MCP tool exposed by a MCP server to a ServerTool.
- Parameters:
name (str) –
client_transport (ClientTransport) –
description (str) –
input_descriptors (List[Property] | None) –
output_descriptors (List[Property] | None) –
_validate_server_exists (bool) –
_validate_tool_exist_on_server (bool) –
__metadata_info__ (Dict[str, Any] | None) –
id (str | None) –
- client_transport: ClientTransport#
Transport to use for establishing and managing connections to the MCP server.
- class wayflowcore.mcp.MCPToolBox(id=<factory>, client_transport=<factory>, tool_filter=None, _validate_mcp_client_transport=True, *, __metadata_info__=<factory>, name='', description=None)#
Class to dynamically expose a list of tools from a MCP Server.
- Parameters:
id (str) –
client_transport (ClientTransport) –
tool_filter (List[str | Tool] | None) –
_validate_mcp_client_transport (dataclasses.InitVar[bool]) –
__metadata_info__ (Dict[str, Any]) –
name (str) –
description (str | None) –
- client_transport: ClientTransport#
Transport to use for establishing and managing connections to the MCP server.
- get_tools()#
Return the list of tools exposed by the
MCPToolBox
.Will be called at every iteration in the execution loop of agentic components.
- Return type:
Sequence[ServerTool]
- async get_tools_async()#
Return the list of tools exposed by the
ToolBox
in an asynchronous manner.Will be called at every iteration in the execution loop of agentic components.
- Return type:
Sequence[ServerTool]
- tool_filter: List[str | Tool] | None = None#
Optional filter to select specific tools.
If None, exposes all tools from the MCP server.
Specifying a tool name (
str
) indicates that a tool of the given name is expected from the MCP server.- Specifying a tool signature (
Tool
) validate the presence and signature of the specified tool in the MCP Server. The name of the MCP tool should match the name of the tool from the MCP Server.
Specifying a non-empty description will override the remote tool description.
Input descriptors can be provided with description of each input. The names and types should match the remote tool schema.
- Specifying a tool signature (
- class wayflowcore.mcp.SessionParameters(read_timeout_seconds=60)#
Keyword arguments for the MCP ClientSession constructor.
- Parameters:
read_timeout_seconds (float) –
- read_timeout_seconds: float = 60#
How long, in seconds, to wait for a network read before aborting the operation. Adjust this to suit your network latency, slow clients or servers, or to enforce stricter timeouts for high-throughput scenarios.
- wayflowcore.mcp.enable_mcp_without_auth()#
Helper function to enable the use of client transport without authentication.
Warning
This method should only be used in prototyping.
Example
>>> from wayflowcore.mcp import enable_mcp_without_auth, MCPToolBox, SSETransport >>> enable_mcp_without_auth() >>> transport = SSETransport( ... url="https://localhost:8443/sse", ... ) >>> mcp_toolbox = MCPToolBox(client_transport=transport)
- Return type:
None
- class wayflowcore.mcp.ClientTransport(__metadata_info__=None, id=None)#
Base class for different MCP client transport mechanisms.
A Transport is responsible for establishing and managing connections to an MCP server, and providing a ClientSession within an async context.
- Parameters:
__metadata_info__ (Dict[str, Any] | None) –
id (str | None) –
- class wayflowcore.mcp.StdioTransport(command=<factory>, args=<factory>, env=None, cwd=None, encoding='utf-8', encoding_error_handler='strict', session_parameters=<factory>, *, id=<factory>, __metadata_info__=<factory>)#
Base transport for connecting to an MCP server via subprocess with stdio.
This is a base class that can be subclassed for specific command-based transports like Python, Node, Uvx, etc.
Note
The stdio transport is the recommended mechanism when the MCP server is launched as a local subprocess by the client application. This approach is ideal for scenarios where the server runs on the same machine as the client.
For more information, visit https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#stdio
- Parameters:
command (str) –
args (List[str]) –
env (Dict[str, str] | None) –
cwd (str | None) –
encoding (str) –
encoding_error_handler (Literal['strict', 'ignore', 'replace']) –
session_parameters (SessionParameters) –
id (str) –
__metadata_info__ (Dict[str, Any]) –
- args: List[str]#
Command line arguments to pass to the executable.
- command: str#
The executable to run to start the server.
- cwd: str | None = None#
The working directory to use when spawning the process.
- encoding: str = 'utf-8'#
The text encoding used when sending/receiving messages to the server. Defaults to utf-8.
- encoding_error_handler: Literal['strict', 'ignore', 'replace'] = 'strict'#
The text encoding error handler.
See https://docs.python.org/3/library/codecs.html#codec-base-classes for explanations of possible values.
- env: Dict[str, str] | None = None#
The environment to use when spawning the process.
If not specified, the result of get_default_environment() will be used.
- session_parameters: SessionParameters#
Arguments for the MCP session.
- class wayflowcore.mcp.SSETransport(url=<factory>, headers=None, timeout=5, sse_read_timeout=300, auth=None, follow_redirects=True, session_parameters=<factory>, *, id=<factory>, __metadata_info__=<factory>)#
Transport implementation that connects to an MCP server via Server-Sent Events.
Warning
This transport should be used for prototyping only. For production, please use a transport that supports mTLS.
Examples
>>> from wayflowcore.mcp import SSETransport >>> transport = SSETransport(url="https://server/sse")
- Parameters:
url (str) –
headers (Dict[str, str] | None) –
timeout (float) –
sse_read_timeout (float) –
auth (OAuthClientProvider | None) –
follow_redirects (bool) –
session_parameters (SessionParameters) –
id (str) –
__metadata_info__ (Dict[str, Any]) –
- class wayflowcore.mcp.SSEmTLSTransport(url=<factory>, headers=None, timeout=5, sse_read_timeout=300, auth=None, follow_redirects=True, session_parameters=<factory>, key_file=<factory>, cert_file=<factory>, ssl_ca_cert=<factory>, check_hostname=False, *, id=<factory>, __metadata_info__=<factory>)#
Transport layer for SSE with mTLS (mutual Transport Layer Security).
This transport establishes a secure, mutually authenticated TLS connection to the MCP server using client certificates. Production deployments MUST use this transport to ensure both client and server identities are verified.
Notes
Users MUST provide a valid client certificate (PEM format) and private key.
Users MUST provide (or trust) the correct certificate authority (CA) for the server they’re connecting to.
The client certificate/key and CA certificate paths can be managed via secrets, config files, or secure environment variables in any production system.
Executors should ensure that these files are rotated and managed securely.
Examples
>>> from wayflowcore.mcp import SSEmTLSTransport >>> mtls = SSEmTLSTransport( ... url="https://server/sse", ... key_file="/etc/certs/client.key", ... cert_file="/etc/certs/client.pem", ... ssl_ca_cert="/etc/certs/ca.pem" ... ) >>> # To pass a Bearer token, use the headers argument: >>> mtls_2 = SSEmTLSTransport( ... url="https://server/sse", ... key_file="...", ... cert_file="...", ... ssl_ca_cert="...", ... headers={"Authorization": "Bearer <token>"} ... )
- Parameters:
url (str) –
headers (Dict[str, str] | None) –
timeout (float) –
sse_read_timeout (float) –
auth (OAuthClientProvider | None) –
follow_redirects (bool) –
session_parameters (SessionParameters) –
key_file (str) –
cert_file (str) –
ssl_ca_cert (str) –
check_hostname (bool) –
id (str) –
__metadata_info__ (Dict[str, Any]) –
- class wayflowcore.mcp.StreamableHTTPTransport(url=<factory>, headers=None, timeout=5, sse_read_timeout=300, auth=None, follow_redirects=True, session_parameters=<factory>, *, id=<factory>, __metadata_info__=<factory>)#
Transport implementation that connects to an MCP server via Streamable HTTP. This transport is the recommended option when connecting to a remote MCP server.
Warning
This transport should be used for prototyping only. For production, please use a transport that supports mTLS.
Examples
>>> from wayflowcore.mcp import StreamableHTTPTransport >>> transport = StreamableHTTPTransport(url="https://server/mcp")
- Parameters:
url (str) –
headers (Dict[str, str] | None) –
timeout (float) –
sse_read_timeout (float) –
auth (OAuthClientProvider | None) –
follow_redirects (bool) –
session_parameters (SessionParameters) –
id (str) –
__metadata_info__ (Dict[str, Any]) –
- class wayflowcore.mcp.StreamableHTTPmTLSTransport(url=<factory>, headers=None, timeout=5, sse_read_timeout=300, auth=None, follow_redirects=True, session_parameters=<factory>, key_file=<factory>, cert_file=<factory>, ssl_ca_cert=<factory>, check_hostname=False, *, id=<factory>, __metadata_info__=<factory>)#
Transport layer for streamable HTTP with mTLS (mutual Transport Layer Security).
This transport establishes a secure, mutually authenticated TLS connection to the MCP server using client certificates. Production deployments MUST use this transport to ensure both client and server identities are verified.
Notes
Users MUST provide a valid client certificate (PEM format) and private key.
Users MUST provide (or trust) the correct certificate authority (CA) for the server they’re connecting to.
The client certificate/key and CA certificate paths can be managed via secrets, config files, or secure environment variables in any production system.
Executors should ensure that these files are rotated and managed securely.
Examples
>>> from wayflowcore.mcp import StreamableHTTPmTLSTransport >>> mtls = StreamableHTTPmTLSTransport( ... url="https://server/mcp", ... key_file="/etc/certs/client.key", ... cert_file="/etc/certs/client.pem", ... ssl_ca_cert="/etc/certs/ca.pem" ... ) >>> # To pass a Bearer token, use the headers argument: >>> mtls_2 = StreamableHTTPmTLSTransport( ... url="https://server/mcp", ... key_file="...", ... cert_file="...", ... ssl_ca_cert="...", ... headers={"Authorization": "Bearer <token>"} ... )
- Parameters:
url (str) –
headers (Dict[str, str] | None) –
timeout (float) –
sse_read_timeout (float) –
auth (OAuthClientProvider | None) –
follow_redirects (bool) –
session_parameters (SessionParameters) –
key_file (str) –
cert_file (str) –
ssl_ca_cert (str) –
check_hostname (bool) –
id (str) –
__metadata_info__ (Dict[str, Any]) –
Tool decorator#
- wayflowcore.tools.toolhelpers.tool(*args, description_mode=DescriptionMode.INFER_FROM_SIGNATURE, output_descriptors=None)#
Make tools out of callables, can be used as a decorator or as a wrapper.
- Parameters:
*args (str | Callable[[...], Any]) – The optional name and callable to convert to a
ServerTool
. See the example section for common usage patterns.description_mode (Literal[<DescriptionMode.INFER_FROM_SIGNATURE: 'infer_from_signature'>, <DescriptionMode.ONLY_DOCSTRING: 'only_docstring'>, <DescriptionMode.EXTRACT_FROM_DOCSTRING: 'extract_from_docstring'>]) –
Determines how parameter descriptions are set:
”infer_from_signature”: Extracted from the function signature.
”only_docstring”: Parameter descriptions are left empty; the full description is in the tool docstring.
”extract_from_docstring”: Parameter descriptions are parsed from the function’s docstring. Currently not supported.
Defaults to “infer_from_signature”.
output_descriptors (List[Property] | None) – list of properties to describe the tool outputs. Needed in case of tools with several outputs.
Returns – The decorated/wrapper callable as a
ServerTool
.
- Return type:
ServerTool | Callable[[Callable[[…], Any]], ServerTool]
Examples
The
tool
helper can be used as a decorator:>>> from wayflowcore.tools import tool >>> @tool ... def my_callable() -> str: ... """Callable description""" ... return ""
Tools can be renamed:
>>> @tool("my_renamed_tool") ... def my_callable() -> str: ... """Callable description""" ... return ""
The
tool
helper can automatically infer a tool input/output schema:>>> from typing import Annotated >>> @tool ... def my_callable(param1: Annotated[int, "param1 description"] = 2) -> int: ... """Callable description""" ... return 0
The user can also specify not to infer the parameter descriptions (when they are in the docstring):
>>> @tool(description_mode="only_docstring") ... def my_callable(param1: int = 2) -> int: ... """Callable description ... Parameters ... ---------- ... param1: ... Description of my parameter 1. ... """ ... return 0
The
tool
helper can also be used as a wrapper:>>> def my_callable() -> str: ... """Callable description""" ... return "" ... >>> my_tool = tool(my_callable)
Use the
tool
helper as a wrapper to create stateful tools (tools that modifiy the internal state of the object):>>> class MyClass: ... def my_callable( ... self, param1: Annotated[int, "param1 description"] = 2 ... ) -> Annotated[int, "output description"]: ... """Callable description""" ... return 0 ... >>> my_object = MyClass() >>> my_stateful_tool = tool(my_object.my_callable)
Use the
output_descriptors
argument to make tools with several outputs:>>> from typing import Dict, Union >>> from wayflowcore.property import StringProperty, IntegerProperty >>> @tool(output_descriptors=[StringProperty(name='output1'), IntegerProperty(name='output2')]) ... def my_callable() -> Dict[str, Union[str, int]]: ... """Callable to return some outputs""" ... return {'output1': 'some_output', 'output2': 2}
Notes
When creating tools, follow these guidelines to optimize tool calling performance with Agents:
Choose descriptive names: Select clear and concise names for your tools to facilitate understanding when using them in Agents.
Write precise descriptions: Provide precise descriptions for your tools, including information about their purpose, inputs, outputs, and any relevant constraints or assumptions.
Use type annotations: Annotate function parameters and return types with precise types to enable automatic schema inference and improve code readability.
Specify return types: Always specify the return type of your tool to ensure clarity (mandatory).