π§ Tools
Tools are the action units in Loopstack that perform the actual work within your workflows. They encapsulate specific operations like API calls, data transformations, LLM interactions, or custom business logic. Tools execute during workflow transitions and can export results for use in subsequent steps.
Tools can be Executed:
- Explicitly during workflow transitions
- Via LLM Tool Calls in agentic flows
Overview
Every tool in Loopstack follows a consistent pattern including a schema parameters
for input validation and an execution
part that defines a TypeScript service
(handler) to be called with defined arguments.
Tools can be understood as configuration βwrappersβ for underlying services (handlers).
tools:
- name: my_email_sender_tool # Unique tool identifier
description: "Sends emails via SMTP" # Optional description
parameters: # Optional input validation
type: object
properties:
recipient:
type: string
subject:
type: string
body:
type: string
required:
- recipient
- subject
- body
execute: # Execution definition
- handler: MyEmailServiceHandler # Custom Email Service to call
arguments: # Arguments passed to service
to: ${ arguments.recipient }
subject: ${ arguments.subject }
body: ${ arguments.body }
Built-in Tools
Several build-in tools provide essential workflow operations and are available out-of-the-box including:
Core Tools Examples
Creating and Retrieving Documents
# Create documents via tool call
call:
- tool: create_document
arguments:
document: my_document_name
content: ${ someData }
# Load Documents via tool call
call:
- tool: load_document
arguments:
where:
name: my_document_name
Creating UI Messages
# Create chat messages
call:
- tool: create_chat_message
arguments:
role: assistant
content: "Hello from the workflow!"
# Create plain text messages
call:
- tool: create_plain_message
arguments:
title: "Status Update"
content: "Process completed successfully"
Control Workflow paths
# Set the transition target state based on variables
call:
- tool: switch_target
arguments:
target: |
{{#if RESPONSE.success}}success_state{{else}}error_state{{/if}}
Modify the context object
# Set the transition target state based on variables
call:
- tool: set_context
arguments:
key: my_key
value: ${ RESPONSE.data.value }
Loopstack provides many more built-in, ready to use core tools. Please see section Building With Loopstack for more information.
LLM Tools Examples
Loopstack also provides built-in tools for working with Large Language Models.
LLM Completion
tools:
- name: my_llm_completion_tool
execute:
- handler: ChatCompletionHandler
arguments:
llm:
envApiKey: OPENAI_KEY
model: gpt-4o
messages:
- role: system
content: "You are a helpful assistant"
- role: user
content: ${ arguments.user_input }
Chat Messages
This tool collects all chat messages (messagesSearchTag: message
) to include them in the LLM request.
# Execute prompts using existing messages in chat
tools:
- name: my_prompt_execution_tool
execute:
- handler: ChatCompletionsHandler
arguments:
llm:
envApiKey: OPENAI_KEY
model: gpt-4o
messagesSearchTag: message
tools: # Available tools for LLM to call
- my_custom_tool
Loopstack provides many more built-in, ready to use LLM tools. Please see section Building With Loopstack for more information.
Custom Tools
You can create custom tools using exiting services (handlers). This can be useful if you want to re-use the same tool call configuration at different places of your automation.
To add additional functionality you can implement Custom Services using TypeScript and execute them with your own tool configuration.
Example:
tools:
- name: my_data_processor_tool
parameters:
type: object
properties:
input_data:
type: string
processing_type:
type: string
enum: ["transform", "validate", "enrich"]
required:
- input_data
- processing_type
execute:
- handler: CustomDataProcessorHandler
arguments:
data: ${ arguments.input_data }
type: ${ arguments.processing_type }
Using Tools in Workflows
Tools are called during workflow transitions and can export results for later use:
workflows:
- name: data_processing_workflow
type: stateMachine
transitions:
- name: processData
from: start
to: dataProcessed
call:
- tool: data_extraction_tool
arguments:
source: ${ context.document }
as: EXTRACTED_DATA # Export for later use
Tools can also be called through LLM tool calls for agent use cases. Please see our LLM Tool Calling section for more details about how to build agentic tool calling workflows.
Tool Configuration
Tool Properties
Every tool definition supports these properties:
name
: (mandatory) Unique identifier within the workspacedescription
: (optional) Human-readable description for documentationparameters
: (optional) JSON Schema for input validationexecute
: (mandatory) tools and handlers to execute
Parameter Validation
You can use JSON Schema to validate tool inputs.
Note: Using a JSON schema is not mandatory but required, if you want to use tools via agent tool calls.
tools:
- name: user_registration_tool
parameters:
type: object
properties:
email:
type: string
format: email
age:
type: integer
minimum: 18
maximum: 120
preferences:
type: object
properties:
newsletter:
type: boolean
theme:
type: string
enum: ["light", "dark"]
required:
- email
- age
additionalProperties: false
execute:
- handler: UserRegistrationHandler
arguments:
userEmail: ${ arguments.email }
userAge: ${ arguments.age }
settings: ${ arguments.preferences }
Handler Execution
The execute
section defines how the tool calls a service (handler):
execute:
- handler: MyCustomHandler # Class name
arguments: # Arguments passed to service
param1: ${ arguments.input1 } # Map tool arguments
param2: "static_value" # Use static values
param3: ${ context.variables.PREVIOUS_RESULT } # Use workflow context
Data Flow and Export
Exporting Tool Results
Use the as
property to make tool results available to subsequent operations:
call:
- tool: api_data_fetcher
arguments:
endpoint: "https://api.example.com/users"
as: API_RESPONSE # Available as ${API_RESPONSE }
- tool: data_transformer
arguments:
raw_data: ${ API_RESPONSE.response.data }
as: TRANSFORMED_DATA # Available as ${ TRANSFORMED_DATA }
Accessing Exported Data
Exported data from previous steps can be access using expressions and template variables:
Expressions
# Use in expressions
- tool: second_tool
arguments:
input: ${ FIRST_TOOL_RESULT }
# Accessing nested data
- tool: processor_tool
arguments:
user_id: ${ API_RESPONSE.response.data.user.id }
metadata: ${ API_RESPONSE.response.meta }
Template Variables
Loopstack uses template language to render text with dynamic content.
tools:
- name: order_message_generator_tool
execute:
- handler: MessageGeneratorHandler
arguments:
template: |
Hello {{ arguments.user_name }},
Order Total: {{ arguments.total }}
{{#if arguments.processed %>
Your order #{{ arguments.order_id }} has been processed.
{{/if}}
Examples
Basic LLM Completion
Create tools for AI-powered operations:
tools:
- name: content_summarizer_tool
execute:
- handler: ChatCompletionsHandler
arguments:
llm:
envApiKey: OPENAI_KEY
model: gpt-4o
temperature: 0.7
messages:
- role: system
content: |
You are a content summarizer. Create concise summaries
that capture the key points of the provided text.
- role: user
content: |
Please summarize this content:
{{ arguments.content }}
Tool-Calling Agents
Enable LLMs to use tools:
tools:
- name: ai_assistant_tool
execute:
- handler: ExecutePromptMessagesHandler
arguments:
llm:
envApiKey: OPENAI_KEY
model: gpt-4o
messagesSearchTag: message
tools: # Tools available to the LLM
- weather_lookup_tool
- calendar_scheduler_tool
- email_sender_tool
# Define tools that the LLM can call
- name: weather_lookup_tool
description: "Get current weather for a location"
parameters:
type: object
properties:
location:
type: string
description: "City name or coordinates"
required:
- location
execute:
- handler: WeatherApiServiceHandler
arguments:
location: ${ arguments.location }
Built-in Handlers
Loopstack provides several built-in handlers for common operations:
For a complete list of handlers and their parameters, see the Services Reference.
Best Practices
Tool Design Principles
Single Responsibility: Each tool should perform one specific operation or closely related set of operations.
Clear Naming: Use descriptive names that indicate the toolβs purpose (e.g., email_sender_tool
, data_validator_tool
).
Consistent Interfaces: Maintain consistent parameter naming and structure across related tools.
Error Resilience: Design tools to handle expected failure cases gracefully.
Validation: Always define parameter schemas for tools that accept user input.
Documentation: Use description fields to document parameter purposes and expected formats.
Flexibility: Design parameters to be composable and reusable across different contexts.
Next Steps
With a solid understanding of tools, you can now explore how to organize and configure your automation components effectively.