Skip to main content

Tools

Introduction

Alongside Workers, Tools are a fundamental building block of the Agent First Organization framework and responsible for the "execution" of the tasks and its subtasks. Tools are the unstructured counterpart to Workers, with a flexible input and output (contrary to Workers with a MessageState input and output). Powered through the SlotFilling mechanism, the framework handles the translation between MessageState and the specified parameter and return values, allowing smoother development of custom methods and integration of API.

Implementation

Technical Details

Tools could be thought of as a Worker-wrapped method that has the framework translate values to and from MessageStates.

Unlike Workers, there are no BaseWorker equivalent for Tools as it is designed to be unstructured. Instead, Tools could be easily created from any method through @register-tool decorator. To turn a method into a tool, just add a @register-tool decorator on the method declaration with 4 parameters: description, slots, outputs, isComplete.

Parameters

Description

description is a string that describes what the Tools does and what tasks is meant to handle. This is used by the Generator to assign the right tool for the tool when generating the TaskGraph.

Example include:
 "Adds two numbers and returns the sum"
 "Searches the database for shows given descriptions"
 "Add items to cart with line ids"

Slots

Slots are the frameworks approach to extract values from the conversations. Slots are used in a tooling context to extract the parameters values from the conversation. Each parameter should have a corresponding slot. Through specifying the parameter's name, type, description, prompt, required, the framework would can extract the necessary information from the conversation.

name
A string representing the name of the parameter, this should be the parameter name.

Examples: 'x', 'show_name', 'ids'

type: A string representing the type of data.

Examples: 'int', 'str', 'list'

enum: The candidate values for the slot. This is used to aid the slotfilling verifier to check if the extracted value is valid.

Examples: 'int', 'str'

description: A string describing the parameter. This will be used to aid the extraction component of slotfilling. Adding examples often help the slotfilling.

Examples
 "Name of the show, such as 'Hamilton'"
 "list of (item_id, quantity) tuples of Items to remove to the cart such as [('41552094527601', 5), ('41552094494833', 10)]."

prompt: A string representing the prompt if parameter required but not found

Examples
 "Please provide the name of the show"

required: A boolean representing if the parameter is required. If required and a value could not be extracted, the prompt would be returned for the value

verified: A boolean representing whether the extracted parameter need verification from user. If need verification from user, then set as False, means haven't been verified. If not, set as True, means it has been verified.

Example Slots

[
{
"name": "cart_id",
"type": "str",
"description": "Cart ID to add items to, such as '2938501948327'",
"prompt": "",
"required": True,
"verified": True
},
{
"name": "item_ids",
"type": "list",
"items": "tuples"
"description": "list of (item_id, quantity) tuples of Items to add to the cart such as [('41552094527601', 5), ('41552094494833', 10)].",
"prompt": "",
"required": True,
"verified": True
}
]

Outputs

Outputs describes the expected return value of the method and aids the framework to contextualize the output of the tool for further Taskgraph decisions. Outputs are similar to slots except without prompt or required attributes.

Example

[{
"name": "user_id",
"type": "string",
"description": "The user id of the user. such as '13573257450893'.",
}]

isComplete

isComplete is a boolean method that takes in all the possible return values from the tool and returns True if the tool is "completed" or False if the tool failed to complete and will have to return this step. This method allows developers to customize the tool to acknowledge error messages and success conditions. This is often a lambda function for succinctness.

Always Complete

lambda x: return True

Error Messages

lambda x: return x not in ERROR_MSGS

Not None

lambda x: return x is not None

Examples

Decorator

@register_tool(
"Add items to cart",
[
{
"name": "cart_id",
"type": "str",
"description": "Cart ID to add items to, such as '2938501948327'",
"prompt": "",
"required": True,
"verified": True
},
{
"name": "item_ids",
"type": "list",
"items": "tuples"
"description": "list of (item_id, quantity) tuples of Items to add to the cart such as [('41552094527601', 5), ('41552094494833', 10)].",
"prompt": "",
"required": True,
"verified": True
}
],
[{
"name": "cart",
"type": "dict",
"description": "The cart information after adding, such as {'id': 'sample_cart', 'items': {'41552094527601': 5, '41552094494833': 10\}\}.",
}],
lambda x: x is not None and x not in ERROR_MSGS
)

Custom Tool

import ast

@register_tool(
"Calculates and return the function output of mathematical query.",
[{
"name": "expression",
"type": "string",
"description": "valid math expression extracted from the user message expressed with only numerical digits and these special characters ['(', ')', '+', '-', '*', '/', '%', '^'], like '21 * 2'",
"prompt": "Could you please provide the mathematical expression?",
"required": True
}],
[{
"name": "result",
"type": "float",
"value": "",
"description": "result of evaluated mathematical expression like 42",
}],
lambda x: isinstance(x, (int, float, complex)) and not isinstance(x, bool)
)
def calculator(expression):
py_expression = expression.replace("^", "**")
return ast.eval(py_expression)

Convert Existing Method into a Tool

from ast import eval as calculate

register_tool(
"Calculates and return the function output of mathematical query.",
[{
"name": "expression",
"type": "string",
"description": "valid math expression extracted from the user message expressed with only numerical digits and these special characters ['(', ')', '+', '-', '*', '/', '%', '^'], like '21 * 2'",
"prompt": "Could you please provide the mathematical expression?",
"required": True
}],
[{
"name": "result",
"type": "float",
"value": "",
"description": "result of evaluated mathematical expression like 42",
}],
lambda x: isinstance(x, (int, float, complex)) and not isinstance(x, bool)
)(
calculate
)