Tools#

This page presents all APIs and classes related to tools in WayFlow

agentspec-icon

Visit the Agent Spec API Documentation to learn more about LLMs Components.

Agent Spec - Tools API Reference

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 (str) –

  • description (str) –

  • input_descriptors (List[Property] | None) –

  • output_descriptors (List[Property] | None) –

  • parameters (Dict[str, JsonSchemaParam] | None) –

  • output (JsonSchemaParam | None) –

  • id (str | None) –

  • __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.

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:
Return type:

ServerTool

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:

ServerTool

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:

ServerTool

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:

ServerTool

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 the url_allow_list, allow_credentials and allow_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 a str it will be taken as a literal json string. Setting this parameter automatically sets the Content-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 with json_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 the requests 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 from json_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); if False 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 is False 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:

    Examples of mismatches:

    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 is True.

    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 is True.

    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#
input_descriptors: List[Property]#
json_body: Any | None#
method: str#
name: str#
num_retry_on_bad_http_request: int#
output_descriptors: List[Property]#
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.

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).