Tool Interactivity

Tool Interactivity

AgentScript allows you to create interactive tools that can pause execution and wait for user input or approval. This is useful for implementing human-in-the-loop workflows.

How to Create Interactive Tools

  1. Define an Interaction Schema: Use the interaction property in defineTool to define the schema for the expected user input
  2. Return a State: In the handler function, return a state object that contains information about the tool call and the message to display to the user
  3. Use toolChatAction: Use the toolChatAction function to create an action button that will trigger the interact function
  4. Implement the interact Function: Implement the interact function to handle the user input and continue the execution

Example

import { defineTool, toolChatAction } from 'agentscript-ai/core';
import * as s from 'agentscript-ai/schema';
 
const approvalTool = defineTool({
    name: 'approvalTool',
    description: 'A tool that requires user approval.',
    input: {
        message: s.string(),
    },
    interaction: s.object({
        props: {
            approved: s.boolean(),
        },
    }),
    state: s.object({
        props: {
            messageId: s.string(),
        },
    }),
    handler: async ({ input, agent, call }) => {
        const message = await chat.postMessage({
            channelId: agent.channelId,
            threadId: agent.threadId,
            blocks: [
                `Do you approve this message: ${input.message}?`,
                {
                    type: 'actions',
                    elements: [
                        {
                            type: 'button',
                            text: 'Approve',
                            style: 'primary',
                            ...toolChatAction({
                                stateId: agent.id,
                                call,
                                params: { approved: true },
                            }),
                        },
                        {
                            type: 'button',
                            text: 'Reject',
                            style: 'danger',
                            ...toolChatAction({
                                stateId: agent.id,
                                call,
                                params: { approved: false },
                            }),
                        },
                    ],
                },
            ],
        });
 
        return {
            state: {
                messageId: message.messageId,
            },
            requireResponse: true,
        };
    },
    interact: async ({ interaction, state, call, agent }) => {
        if (interaction.approved) {
            await chat.updateMessage({
                channelId: agent.channelId,
                threadId: agent.threadId,
                messageId: state.messageId,
                blocks: [`Message approved!`],
            });
        } else {
            await chat.updateMessage({
                channelId: agent.channelId,
                threadId: agent.threadId,
                messageId: state.messageId,
                blocks: [`Message rejected!`],
            });
        }
    },
});

Key Points

  • requireResponse: Set this to true in the handler to pause execution and wait for user interaction
  • toolChatAction: Use this function to create action buttons that trigger the interact function
  • interact: Implement this function to handle user input and continue the agent's execution
  • State: Use the tool's state to store information about the tool call and the message that was sent to the user