π Your First Automation
Now that you understand the basic concepts, letβs build your first workflow step by step. This hands-on tutorial will walk you through creating a simple but complete AI automation that transforms casual meeting notes into professional format.
What Weβll Build
Weβll create a workflow that:
- Displays a form for the user to input casual meeting notes
- Waits for user input and captures their response
- Uses an LLM to transform the notes into a professional summary
- Adds the result as a chat message
This demonstrates a common interactive workflow pattern youβll use in many Loopstack automations.
Step 1: Create the Configuration File
Create a new file at ./src/config/tutorials/meeting-notes-tutorial.yaml
:
# Include required core tools
include:
- core/tools/create-chat-message.yaml
- core/tools/create-response.yaml
- core/tools/create-document.yaml
# Create a minimal root pipeline which executes the custom workflow
pipelines:
- name: meeting_notes_tutorial
title: "Tutorial 1: Meeting Notes Summarizer"
workspace: examples
type: root
sequence:
- workflow: meeting_notes_summarizer
# Create the workflow with interactive user input
workflows:
- name: meeting_notes_summarizer
title: "Meeting Notes Summarizer"
type: stateMachine
transitions:
# First transition: Display the input form
- name: render_meeting_notes_form
from: start
to: waiting_for_response
call:
- tool: create_document
arguments:
document: meeting_notes
# Second transition: Capture user input (manual trigger)
- name: create_user_response
from: waiting_for_response
to: user_response_created
when: manual
call:
- tool: create_response
arguments:
document: meeting_notes
as: USER_INPUT
# Third transition: Process the notes and create summary
- name: process_meeting_notes
from: user_response_created
to: meeting_notes_summarized
call:
- tool: llm_create_notes_summary
arguments:
raw_notes: ${ USER_INPUT.content.text }
as: SUMMARY_RESULT
- tool: create_chat_message
arguments:
role: ${ SUMMARY_RESULT.response.data.role }
content: ${ SUMMARY_RESULT.response.data.content }
# Create the custom LLM tool for summarization
tools:
- name: llm_create_notes_summary
parameters:
type: object
properties:
raw_notes:
type: string
required:
- raw_notes
additionalProperties: false
execute:
- handler: ChatCompletionsHandler
arguments:
llm:
envApiKey: OPENAI_KEY
model: gpt-4o
messages:
- role: system
content: |
You are a meeting notes summarizer. Transform these raw notes into a clear summary.
Raw Notes: {{ arguments.raw_notes }}
Create a summary with:
**Decisions:**
- What was decided
**Action Items:**
- Who needs to do what
# Define the document structure and UI
documents:
- name: meeting_notes
schema:
type: object
properties:
text:
type: string
ui:
properties:
text:
widget: textarea
buttons:
- transition: create_user_response
label: "Submit"
content:
text: |
budget: need 2 cut costs sarah said
hire new person?? --> marketing
vendor pricing - follow up needed by anna
mike's project delayed again. deadline moved - when??? next month maybe
client wants faster delivery but budget tight. can we do it?
Step 2: Understanding the Configuration
Letβs break down what each section does:
Include Section:
include:
- core/tools/create-chat-message.yaml # Built-in tool for creating chat messages
- core/tools/create-response.yaml # Built-in tool for handling user responses
- core/tools/create-document.yaml # Built-in tool for creating documents
The include section imports pre-built tools from Loopstackβs core library. This promotes code reuse and keeps your configuration clean by referencing external tool definitions instead of duplicating them in every file.
Pipeline Definition:
pipelines:
- name: meeting_notes_tutorial # Unique pipeline identifier
title: "Tutorial 1: Meeting Notes Summarizer" # Display name in Studio
workspace: tutorials # Allocate pipeline to tutorials workspace
type: root # Executable pipeline type
sequence:
- workflow: meeting_notes_summarizer # Name of the workflow to execute
Pipelines are the entry points for your automations - they define what gets executed when a user runs your automation. The root
type means this pipeline can be directly executed from the Studio interface, and it will run the specified workflow sequence.
Workflow State Machine:
workflows:
- name: meeting_notes_summarizer # Unique workflow identifier
title: "Meeting Notes Summarizer" # Display name in Studio
type: stateMachine # Workflow type
transitions:
- name: render_meeting_notes_form # First transition
from: start # Always starts from 'start'
to: waiting_for_response # Target state
call:
- tool: create_document # Create the input form
arguments:
document: meeting_notes # Reference to document definition
- name: create_user_response # Second transition
from: waiting_for_response
to: user_response_created
when: manual # Waits for user interaction
call:
- tool: create_response
arguments:
document: meeting_notes
as: USER_INPUT # Export for later use
- name: process_meeting_notes # Third transition
from: user_response_created
to: meeting_notes_summarized
call:
- tool: llm_create_notes_summary
arguments:
raw_notes: ${ USER_INPUT.content.text } # Use captured user input
as: SUMMARY_RESULT
- tool: create_chat_message # Add result to chat
arguments:
role: ${ SUMMARY_RESULT.response.data.role }
content: ${ SUMMARY_RESULT.response.data.content }
Workflows define the business logic as a state machine with transitions between different states. Each transition can call tools, move between states, and pass data forward. The manual
transition type creates breakpoints where the workflow waits for user interaction before continuing.
Custom Tool Definition:
tools:
- name: llm_create_notes_summary # Custom tool for LLM processing
parameters: # Define input parameters
type: object
properties:
raw_notes:
type: string
required:
- raw_notes
additionalProperties: false
execute:
- handler: ChatCompletionsHandler # Built-in LLM service
arguments:
llm:
envApiKey: OPENAI_KEY # Environment variable for API key
model: gpt-4o # OpenAI model to use
messages:
- role: system
content: |
You are a meeting notes summarizer. Transform these raw notes into a clear summary.
Raw Notes: {{ arguments.raw_notes }}
Create a summary with:
**Decisions:**
- What was decided
**Action Items:**
- Who needs to do what
Tools encapsulate specific functionality that can be reused across workflows. This custom tool wraps the ChatCompletionsHandler with specific parameters and prompt engineering for meeting notes summarization. The parameters section validates inputs, ensuring data integrity.
Document Definition:
documents:
- name: meeting_notes # Document identifier
schema: # JSON schema for validation
type: object
properties:
text:
type: string
ui: # UI configuration
properties:
text:
widget: textarea # Use textarea widget for input
buttons:
- transition: create_user_response # Button triggers this transition
label: "Submit"
content: # Default content
text: |
budget: need 2 cut costs sarah said
hire new person?? --> marketing
vendor pricing - follow up needed by anna
mike's project delayed again. deadline moved - when??? next month maybe
client wants faster delivery but budget tight. can we do it?
Documents define data structures and their user interface representation. The schema validates the data structure, while the UI section controls how forms are rendered in the Studio.
When you run the workflow:
- render_meeting_notes_form
- Creates and displays the input form
- Pre-populates with demo meeting notes
- create_user_response
- Waits for user to edit and submit the form
- Captures user input as
USER_INPUT
- process_meeting_notes
- Processes notes using LLM tool
- Adds result to chat
Step 3: Run Your First Workflow
- Start your development environment (if not already running):
docker compose up -d
- Start your custom application:
npm run start:dev
-
Open Loopstack Studio at http://localhost:3000Β
-
Execute the workflow:
- Navigate to the tutorials workspace
- Create a new pipeline of type βTutorial 1: Meeting Notes Summarizerβ
- The workflow will display an input form
- Edit the meeting notes as desired
- Click βSubmitβ to process the notes
- Watch the execution progress and see the formatted summary
Next Steps
Youβve successfully created your first interactive Loopstack workflow! You now understand:
- β How to structure modular YAML configurations with includes
- β Interactive state machine execution with manual transitions
- β Custom tool creation with parameter validation
- β Document-based user input handling
- β
Using built-in services like
ChatCompletionsHandler
Continue to: Core Components to learn about advanced YAML configurations, or explore Building with Loopstack for comprehensive automation patterns.