func_tool#

Tool is LLM’s extended capability which is one of the core design pattern of Agent. All tools can be wrapped in a FunctionTool class. This helps to standardize the tool interface and metadata to communicate with the Agent.

Functions

Classes

FunctionTool(fn[, definition])

Describing and executing a function via call with arguments.

is_running_in_event_loop() bool[source]#
class FunctionTool(fn: Callable[[...], Any] | Awaitable[Callable[[...], Any]], definition: FunctionDefinition | None = None)[source]#

Bases: Component

Describing and executing a function via call with arguments.

container for a function that orchestrates the function formatting(to LLM), parsing, and execution.

Function be used by LLM as a tool to achieve a specific task.

Features: - Supports both synchronous and asynchronous functions via call and acall. - Creates a FunctionDefinition from the function using get_fun_schema. - Executs the function with arguments.

[You can use Function and FunctionExpression as output format]

  • Please Parses the function call expression[FunctionExpression] into Function (name, args, kwargs).

  • call or acall, or use execute to execute the function.

  • via call with args and kwargs.

  • via eval without any context or sandboxing.
    • via sandboxed execute directionly using sandbox_exec.

property is_async: bool#
call(*args: Any, **kwargs: Any) FunctionOutput[source]#

Execute the function synchronously.

Example:

import time
def sync_function_1():
    time.sleep(1)
    return "Function 1 completed"

tool_1 = FunctionTool(sync_function_1)
output = tool_1.call()
async acall(*args: Any, **kwargs: Any) FunctionOutput[source]#

Execute the function asynchronously.

Need to be called in an async function or using asyncio.run.

Example:

import asyncio
async def async_function_1():
    await asyncio.sleep(1)  # Simulate async work
    return "Function 1 completed"

async def call_async_function():
    tool_1 = FunctionTool(async_function_1)
    output = await tool_1.acall()

asyncio.run(call_async_function())
execute(*args, **kwargs) FunctionOutput[source]#

Execute the function synchronously or asynchronously based on the function type.

No matter of the function type, you can run the function using both asyncio and without asyncio.

Use it with caution as it might block the event loop.

Example:

import asyncio
import time

async def async_function_1():
    await asyncio.sleep(1)
    return "Function 1 completed"

def sync_function_1():
    time.sleep(1)
    return "Function 1 completed"

async def async_function_2():
    await asyncio.sleep(2)
    return "Function 2 completed"

def sync_function_2():
    time.sleep(2)
    return "Function 2 completed"

async_tool_1 = FunctionTool(async_function_1)
sync_tool_1 = FunctionTool(sync_function_2)
async_tool_2 = FunctionTool(async_function_2)
sync_tool_2 = FunctionTool(sync_function_2)

def run_sync_and_async_mix_without_wait():
    # both sync and async tool can use execute
    # sync tool can also use call
    # takes 5 seconds (1+1+2) + overhead
    start_time = time.time()
    results = [
        async_tool_1.execute(),
        sync_tool_1.execute(),
        sync_tool_2.call(),
    ]
    end_time = time.time()
    print(f"run_sync_and_async_mix_without_wait time: {end_time - start_time}")
    return results

async def run_sync_and_async_mix():
    # both sync and async tool can use execute&to_thread
    # async tool can also use acall without to_thread
    # takes a bit over 2 seconds max(2)
    start_time = time.time()
    results = await asyncio.gather(
        async_tool_1.execute(),
        sync_tool_1.execute(),
        async_tool_2.acall(),
    )
    end_time = time.time()
    print(f"run_sync_and_async_mix time: {end_time - start_time}")
    return results

run_sync_and_async_mix_without_wait()
asyncio.run(run_sync_and_async_mix())