createWorkflow
Creates a new workflow instance with injected conversation primitives.
Overview​
createWorkflow
is the main factory function for creating workflows. It sets up dedicated conversation primitives (manager, context, history) that are automatically injected into all workflow steps.
Import​
import { createWorkflow } from "@mrck-labs/grid-workflows";
Function Signature​
function createWorkflow(config?: WorkflowConfig): Workflow
Parameters​
config (optional)​
- Type:
WorkflowConfig
- Properties:
name
(optional): Workflow name for identification- Type:
string
- Type:
description
(optional): Workflow description- Type:
string
- Type:
managerOptions
(optional): Options for the conversation manager- Type:
object
- Properties:
historyOptions
: Options for conversation historysystemPrompt
: Initial system promptmaxMessages
: Maximum message limit
contextOptions
: Options for conversation context
- Type:
Return Type: Workflow​
Methods​
step​
step(name: string): StepBuilder
Define a new workflow step with the given name.
Parameters:
name
: Unique identifier for the step
Returns: StepBuilder for configuring the step
run​
run<T = any>(initialStep: string, input?: any): Promise<WorkflowResult<T>>
Execute the workflow starting from the specified step.
Parameters:
initialStep
: Name of the first step to executeinput
(optional): Initial input data
Returns: Promise resolving to WorkflowResult containing:
finalResult
: The output from the last executed stepexecutedSteps
: Array of step names that were executedstate
: Final workflow statehistory
: Conversation messagesduration
: Total execution time in milliseconds
suspend​
suspend(): Promise<WorkflowCheckpoint>
Suspend the workflow execution and get a checkpoint.
Returns: Checkpoint containing current state, history, and progress
resume​
resume(checkpoint: WorkflowCheckpoint): Promise<void>
Resume workflow execution from a checkpoint.
Parameters:
checkpoint
: Previously saved checkpoint
primitives​
primitives: {
manager: ConversationManager;
context: ConversationContext;
history: ConversationHistory;
}
Direct access to the underlying conversation primitives.
Examples​
Basic Workflow​
const workflow = createWorkflow();
workflow
.step('start')
.function(async (input) => {
console.log('Starting workflow with:', input);
return { processed: true, data: input };
})
.then(() => 'finish');
workflow
.step('finish')
.function(async (input) => {
console.log('Finishing with:', input);
return { complete: true };
});
const result = await workflow.run('start', { message: 'Hello' });
With System Prompt​
const workflow = createWorkflow({
name: 'Support Workflow',
description: 'Handles customer support requests',
managerOptions: {
historyOptions: {
systemPrompt: 'You are a helpful support assistant',
maxMessages: 100
}
}
});
Accessing Primitives in Steps​
workflow
.step('process')
.function(async (input, { manager, context, history }) => {
// Use conversation manager
await manager.addUserMessage(input.message);
// Update context state
await context.updateState('processed', true);
await context.updateState('timestamp', Date.now());
// Check history
const messageCount = history.getMessages().length;
console.log(`Total messages: ${messageCount}`);
return { processed: true };
});
LLM Steps​
const agent = createConfigurableAgent({
// ... agent configuration
});
workflow
.step('analyze')
.llm(agent)
.then(response => {
// Route based on LLM response
if (response.includes('urgent')) return 'handleUrgent';
return 'handleNormal';
});
Conditional Branching​
workflow
.step('categorize')
.function(async (input) => {
const category = analyzeInput(input);
return { category, originalInput: input };
})
.then(result => {
switch (result.category) {
case 'technical': return 'technicalSupport';
case 'billing': return 'billingSupport';
case 'general': return 'generalSupport';
default: return 'unknownCategory';
}
});
Error Handling​
try {
const result = await workflow.run('start', input);
console.log('Success:', result);
} catch (error) {
console.error('Workflow failed:', error);
// Check which step failed
const checkpoint = await workflow.suspend();
console.log('Failed at step:', checkpoint.currentStep);
}
Suspend and Resume​
// Start workflow
const workflow = createWorkflow();
// ... define steps ...
// Execute partially
await workflow.run('start', input);
// Suspend execution
const checkpoint = await workflow.suspend();
// Save checkpoint (e.g., to database)
await saveCheckpoint(checkpoint);
// Later... restore and continue
const savedCheckpoint = await loadCheckpoint();
await workflow.resume(savedCheckpoint);
// Continue execution
const result = await workflow.run(savedCheckpoint.currentStep, savedInput);
Best Practices​
- Use descriptive step names - Makes debugging and tracing easier
- Keep steps focused - Each step should do one thing well
- Handle errors gracefully - Use try-catch in function steps
- Leverage context - Store intermediate results in context
- Use transitions wisely - Make routing logic clear and testable
TypeScript Types​
interface WorkflowConfig {
name?: string;
description?: string;
managerOptions?: {
historyOptions?: {
systemPrompt?: string;
maxMessages?: number;
};
contextOptions?: any;
};
}
interface WorkflowResult<T = any> {
finalResult: T;
executedSteps: string[];
state: Record<string, any>;
history: ChatMessage[];
duration: number;
}
interface WorkflowCheckpoint {
currentStep: string | null;
state: Record<string, any>;
history: ChatMessage[];
executedSteps: string[];
}
Related APIs​
- Step Builders - Building workflow steps
- Workflow Types - Complete type definitions
- ConversationManager - Underlying manager
- ConversationContext - State management