@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-workflowThen 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, andMessageDocument
About
Author: Jakob Klippel
License: MIT
Additional Resources
- Loopstack Documentation
- Getting Started with Loopstack
- Find more Loopstack examples in the Loopstack Registry