Skip to Content
DocumentationRegistryExamplesWorkflow State Example

@loopstack/workflow-state-example-workflow

A module for the Loopstack AI  automation framework.

This module provides an example workflow demonstrating how to manage state across transitions using a typed state object.

Overview

The Workflow State Example Workflow shows how to pass data through a typed state object across transitions. It demonstrates the core patterns for managing data flow in a workflow.

By using this workflow as a reference, you’ll learn how to:

  • Define a typed state interface for your workflow
  • Return updated state from transitions
  • Access state in subsequent transitions
  • Create private helper methods to transform state data

This example is useful for developers building workflows that need to store and manipulate data across transitions.

Installation

npm install @loopstack/workflow-state-example-workflow

Then register the module in your app:

import { StudioApp } from '@loopstack/common'; import { WorkflowStateExampleModule, WorkflowStateWorkflow } from '@loopstack/workflow-state-example-workflow'; @StudioApp({ title: 'Workflow State Example', workflows: [WorkflowStateWorkflow], }) @Module({ imports: [WorkflowStateExampleModule], }) export class MyAppModule {}

How It Works

Key Concepts

1. Defining Workflow State

State is defined as a typed interface and passed as the second generic to BaseWorkflow:

interface WorkflowStateState { message?: string; } @Workflow({ title: 'Workflow State', }) export class WorkflowStateWorkflow extends BaseWorkflow<Record<string, unknown>, WorkflowStateState> {

The state object is passed to each transition and persists across transitions automatically.

2. Storing Data in State

Return updated state from a transition method:

@Transition({ to: 'data_created' }) async createSomeData(state: WorkflowStateState): Promise<WorkflowStateState> { return { ...state, message: 'Hello :)' }; }

The returned state is passed to the next transition.

3. Accessing State in Later Transitions

State is available as the first parameter in any subsequent transition method:

@Transition({ from: 'data_created', to: 'end' }) async showResults(state: WorkflowStateState): Promise<unknown> { await this.documentStore.save(MessageDocument, { role: 'assistant', text: `Data from state: ${state.message}`, }); await this.documentStore.save(MessageDocument, { role: 'assistant', text: `Use workflow helper method: ${this.messageInUpperCase(state.message!)}`, }); return {}; }

4. Private Helper Methods

Define private methods to transform or process state data:

private messageInUpperCase(message: string): string { return message?.toUpperCase(); }

These are standard TypeScript methods with no decorator required. Call them from any transition using this.messageInUpperCase(...).

Complete Workflow

import { BaseWorkflow, MessageDocument, Transition, Workflow } from '@loopstack/common'; interface WorkflowStateState { message?: string; } @Workflow({ title: 'Workflow State', }) export class WorkflowStateWorkflow extends BaseWorkflow<Record<string, unknown>, WorkflowStateState> { @Transition({ to: 'data_created' }) async createSomeData(state: WorkflowStateState): Promise<WorkflowStateState> { return { ...state, message: 'Hello :)' }; } @Transition({ from: 'data_created', to: 'end' }) async showResults(state: WorkflowStateState): Promise<unknown> { await this.documentStore.save(MessageDocument, { role: 'assistant', text: `Data from state: ${state.message}`, }); await this.documentStore.save(MessageDocument, { role: 'assistant', text: `Use workflow helper method: ${this.messageInUpperCase(state.message!)}`, }); return {}; } private messageInUpperCase(message: string): string { return message?.toUpperCase(); } }

Dependencies

This workflow uses the following Loopstack modules:

  • @loopstack/common - Base classes, decorators, and MessageDocument

About

Author: Jakob Klippel 

License: MIT

Additional Resources

Last updated on