BaseTool#

Overview#

BaseTool is the base type for individual tools, responsible for recording specific tool function interfaces, parsing function parameters, providing the tool schema definition, maintaining the tool’s internal state, and other basic functions. It is the basic tool unit managed by ToolManager.

Characteristics#

  • Tool invocation capability: Tools can be invoked via __call__.

  • Tool State Management: When calling a tool, if the tool itself has an inner_state parameter, the state managed by BaseTool will be filled into the tool’s input parameters. Tool state also supports export and reload.

  • Streaming Message Management: When calling a tool, if the tool itself has a stream_writer parameter, it will fill the StreamWriter into the tool’s input parameters to receive the streaming messages output by the tool.

Note

In the EvoFabric framework, the internal state of a tool essentially refers to the input parameters required by the tool. The key distinction between this parameter and ordinary parameters is that the parameter’s value only needs to be initialized once; subsequent tool invocations no longer require explicit input, but instead rely on the parameter’s updated value from the previous invocation.

Tool Call & Get ToolSchema#

from evofabric.core.tool import BaseTool
import asyncio

async def main():
    # The core of the tool is a Python function
    def add(a: float, b: float):
        "add two numbers"
        return a + b

    # Initialize BaseTool
    new_tool = BaseTool(
        name='add',
        description='add two float numbers.',
        func=add
    )

    # Get tool schema
    tool_schema = new_tool.get_tool_schema()
    print(tool_schema)

    # Call BaseTool
    ans = await new_tool(a=1, b=2)
    print(ans)

asyncio.run(main())

Stateful Tool Call#

from evofabric.core.tool import BaseTool
import asyncio
import os
from evofabric.core.typing import ToolInnerState


async def main():

    # Define the tool
    async def mycd(path: str, inner_state: ToolInnerState):
        '''
        change directory.
        '''
        new_path = os.path.join(inner_state.state['current_dir'], path)
        inner_state.state['current_dir'] = new_path
        return new_path

    # Tool internal state
    inner_state = ToolInnerState(
        state={
            "current_dir": "/xxx/xxx"
        }
    )

    # Initialize BaseTool
    new_tool = BaseTool(
        name="mycd",  # tool name
        description="change directory.",  # tool description
        func=mycd,  # core of the tool
        inner_state=inner_state,  # tool internal state
        exclude_params=["inner_state"]  # exclude inner_state (tool internal state) from tool schema
    )

    # Get BaseTool tool schema
    tool_schema = new_tool.get_tool_schema()
    print(tool_schema)  # inner_state will not appear

    # Call BaseTool
    ans = await new_tool(path="sss/")
    print(ans)  # "/xxx/xxx/sss/"

    # BaseTool internal state changes
    print(new_tool.inner_state.state['current_dir'])  # "/xxx/xxx/sss/"

    # Get BaseTool internal state
    state1 = await new_tool.dump_state()

    # Overwrite BaseTool internal state
    await new_tool.load_state(input_state=state1)

asyncio.run(main())