@markiearnold/flow-machine
v4.3.15
Published
A self-contained flow machine framework for React - completely unstyled for maximum flexibility
Maintainers
Readme
Flow Machine
Enterprise-grade conversational UI framework for React that makes building complex, multi-step user interactions simple and intuitive.
Complete Documentation | 🚀 Quick Start | 🎨 Styling Guide | 🔧 API Reference
🔗 Links
- Coded Example using FlowUI: https://flow-machine-example.vercel.app/
- Documentation: https://markiearnold.github.io/flow-machine
- Assistant-UI Integration: https://markiearnold.github.io/flow-machine/guides/assistant-ui-integration
Features
- Flow Management: Create and manage conversational flows with ease
- Pre-built Components: Ready-to-use React components for chat interfaces
- Templates: Pre-configured flow templates for common use cases
- A/B Testing: Built-in A/B testing framework for flow optimization
- Customizable UI: Flexible styling and theming options
- Responsive Design: Mobile-friendly components that adapt to different screen sizes
- TypeScript Support: Full TypeScript support with type definitions
- Assistant-UI Integration: Seamless integration with assistant-ui for hybrid chat/flow experiences
- Intent Routing: Map natural language intents to specific flows
- Tool Registry: Shared tools between chat and flows with enhanced error handling
- Flow Handoffs: Smart suggestions for next actions when flows complete
- Observability: Built-in analytics and monitoring for flow execution
Installation
npm install @markiearnold/flow-machineQuick Start
Simple Usage
import React from "react";
import {FlowUI, useFlowMachine, createFlow} from "@markiearnold/flow-machine";
function App() {
const config = createFlow({
flowId: "my-flow",
startId: "welcome",
})
.step({
id: "welcome",
prompt: "Welcome! How can I help you today?",
suggestions: [
{label: "Get started", value: "start"},
{label: "Learn more", value: "learn"},
{label: "Contact support", value: "support"},
],
next: (ctx) => {
if (ctx.lastInput === "start") return "get-started";
if (ctx.lastInput === "learn") return "learn-more";
return "contact-support";
},
})
.step({
id: "get-started",
prompt: "Great! Let's get you started with our platform.",
suggestions: [
{label: "Next step", value: "next"},
{label: "Go back", value: "back"},
],
next: (ctx) => {
if (ctx.lastInput === "back") return "welcome";
return null; // End flow
},
})
.build();
const machine = useFlowMachine(config);
return (
<FlowUI
machine={machine}
title="My Flow App"
subtitle="Interactive conversation flow"
/>
);
}With Provider (Recommended)
import React from "react";
import {FlowUI, FlowProvider, createFlow} from "@markiearnold/flow-machine";
function App() {
const config = createFlow({
flowId: "my-flow",
startId: "welcome",
})
.step({
id: "welcome",
prompt: "Welcome! How can I help you today?",
suggestions: [
{label: "Get started", value: "start"},
{label: "Learn more", value: "learn"},
{label: "Contact support", value: "support"},
],
next: () => null, // End flow
})
.build();
return (
<FlowProvider config={config}>
<FlowUI title="My Flow App" subtitle="Interactive conversation flow" />
</FlowProvider>
);
}Core Components
FlowUI
The main interactive component that provides the complete flow interface.
import {FlowUI} from "@markiearnold/flow-machine";
<FlowUI
machine={machine}
title="My App"
subtitle="Interactive flow"
showProgress={true}
theme="light"
/>;FlowProvider
Context provider for better state management and sharing flow state across components.
import {FlowProvider, FlowUI, createFlow} from "@markiearnold/flow-machine";
function App() {
const config = createFlow({
flowId: "my-flow",
startId: "welcome",
})
.step({
id: "welcome",
prompt: "Welcome! How can I help you today?",
suggestions: [
{label: "Get started", value: "start"},
{label: "Learn more", value: "learn"},
{label: "Contact support", value: "support"},
],
next: () => null,
})
.withValidation(false) // Disable validation warnings
.build();
return (
<FlowProvider config={config}>
<FlowUI title="My Flow App" subtitle="Interactive conversation flow" />
</FlowProvider>
);
}
export default App;FlowChat
A standalone chat component for displaying conversations.
import React from "react";
import {FlowChat, useFlowMachine, createFlow} from "@markiearnold/flow-machine";
function ChatApp() {
const config = createFlow({
flowId: "chat-flow",
startId: "welcome",
})
.step({
id: "welcome",
prompt: "Hello! How can I help?",
suggestions: [
{label: "Get help", value: "help"},
{label: "Learn more", value: "learn"},
],
next: () => null,
})
.build();
const machine = useFlowMachine(config);
return <FlowChat machine={machine} />;
}FlowInspector
Development tool for debugging flow states and transitions.
import React from "react";
import {
FlowInspector,
useFlowMachine,
createFlow,
} from "@markiearnold/flow-machine";
function DebugApp() {
const config = createFlow({
flowId: "debug-flow",
startId: "welcome",
})
.step({
id: "welcome",
prompt: "Hello! This is a debug flow.",
suggestions: [{label: "Continue", value: "continue"}],
next: () => null,
})
.build();
const machine = useFlowMachine(config);
return <FlowInspector machine={machine} />;
}Assistant-UI Integration
Flow-machine now seamlessly integrates with assistant-ui to create powerful hybrid chat/flow experiences. This integration provides the best of both worlds: structured, deterministic flows and flexible, natural language chat.
Quick Integration
import {useAssistant} from "assistant-ui";
import {
MessageBridge,
createBridgeConfig,
IntentRouter,
ToolRegistry,
} from "@markiearnold/flow-machine";
function App() {
// Create flow-machine configuration
const bridgeConfig = createBridgeConfig({
assistantId: "my-assistant",
sessionId: "session-123",
intentRouter: new IntentRouter({
mappings: {
book_appointment: {
id: "appointment-flow",
seed: (params) => ({
service: params?.service,
date: params?.date,
}),
},
},
}),
toolRegistry: new ToolRegistry(),
});
const bridge = new MessageBridge(bridgeConfig);
// Assistant-UI configuration
const assistant = useAssistant({
api: "/api/assistant",
onMessage: async (message) => {
const result = await bridge.processAssistantMessage(message);
if (result.flowStarted) {
return {
role: "assistant",
content: `Starting ${result.flowId}...`,
suggestions: ["Get help", "Start over"],
};
}
return result.response;
},
});
return (
<div>
<assistant-ui-chat assistant={assistant} />
</div>
);
}Key Features
- Intent Routing: Map natural language intents to specific flows
- Tool Registry: Shared tools between chat and flows with enhanced error handling
- Flow Handoffs: Smart suggestions for next actions when flows complete
- Chat Steps: Embed chat interfaces within flows for hybrid experiences
- Observability: Built-in analytics and monitoring for flow execution
- Message Bridge: Seamless communication between assistant-ui and flow-machine
Learn More
- Integration Guide: Complete setup and configuration
- Recipes: Practical examples for common use cases
- Examples: Comprehensive code examples
- Migration Guide: Migrate from pure assistant-ui
Flow Management
Creating Flows
import {createFlow, createSimpleFlow} from "@markiearnold/flow-machine";
// Simple flow (automatically generates next functions)
const simpleFlow = createSimpleFlow("simple-flow", [
{id: "step1", prompt: "Hello!"},
{id: "step2", prompt: "How are you?"},
]);
// Advanced flow with custom logic using fluent API
const advancedFlow = createFlow({
flowId: "advanced-flow",
startId: "welcome",
})
.step({
id: "welcome",
prompt: "Welcome to our service!",
suggestions: [
{label: "Get started", value: "start"},
{label: "Learn more", value: "learn"},
],
onEnter: (context) => {
console.log("Entered welcome step");
},
next: (ctx) => {
if (ctx.lastInput === "start") return "get-started";
if (ctx.lastInput === "learn") return "learn-more";
return null;
},
})
.step({
id: "get-started",
prompt: "Let's get you started!",
next: () => null,
})
.build();Flow Templates
import React from "react";
import {useTemplate, FlowUI} from "@markiearnold/flow-machine";
function OnboardingFlow() {
// useTemplate returns the flow machine state directly
const flowMachine = useTemplate("user-onboarding", {
companyName: "Acme Corp",
features: ["Feature 1", "Feature 2"],
});
return <FlowUI machine={flowMachine} />;
}Disabling Validation Warnings
Flow Machine provides helpful validation warnings to help you build better flows. To disable these warnings:
With Flow Builder API:
const flow = createFlow({
flowId: "my-flow",
startId: "welcome",
})
.step({...})
.withValidation(false) // Disable validation warnings
.build();
const machine = useFlowMachine(flow);With direct useFlowMachine:
const machine = useFlowMachine({
...flow,
validateFlow: false, // Disable validation warnings
});Common warnings:
NO_VALIDATION: Steps that accept input but have no validation functionUNREACHABLE_STEPS: Steps that cannot be reached from the start stepCIRCULAR_DEPENDENCIES: Steps with circular dependency chains
A/B Testing
import React from "react";
import {
useABTest,
useABTestManager,
ABTestBuilder,
} from "@markiearnold/flow-machine";
function TestFlow() {
// Create A/B test manager
const {manager} = useABTestManager();
// Create and register a test
const test = new ABTestBuilder("welcome-message")
.setName("Welcome Message Test")
.addVariation("A", "Welcome!")
.addVariation("B", "Hello there!")
.setTraffic(50, "equal")
.build();
// Register the test
React.useEffect(() => {
manager.registerTest(test);
}, [manager, test]);
// Use the test
const testResult = useABTest({
userId: "user-123",
testId: "welcome-message",
manager,
});
return (
<div>
<p>{testResult.variation?.content || "Loading..."}</p>
</div>
);
}Customization
Styling
All components support custom CSS classes and styling:
<FlowUI
machine={machine}
chatClassName="custom-chat-styles"
className="custom-ui-styles"
/>Custom Widgets
Add custom components to your flow:
<FlowUI machine={machine} customWidget={<MyCustomComponent />} />Production-Ready Features
📱 Mobile Detection
Basic mobile device detection for responsive layouts:
import {useIsMobile} from "@markiearnold/flow-machine";
function ResponsiveComponent() {
const isMobile = useIsMobile();
return <div>{isMobile ? <MobileLayout /> : <DesktopLayout />}</div>;
}Available Features:
✅ Mobile device detection (
useIsMobilehook)✅ Responsive breakpoint detection (768px)
✅ Screen size monitoring
✅ Retry logic for failed operations
API Reference
useFlowMachine
The main hook for managing flow state.
import {useFlowMachine, createFlow} from "@markiearnold/flow-machine";
const config = createFlow({
flowId: "my-flow",
startId: "welcome",
})
.step({
id: "welcome",
prompt: "Hello!",
next: () => null,
})
.build();
const machine = useFlowMachine(config);Flow Templates
import {useTemplate} from "@markiearnold/flow-machine";
// useTemplate returns the flow machine state directly
const flowMachine = useTemplate("user-onboarding", {
companyName: "Acme Corp",
features: ["Feature 1", "Feature 2"],
});A/B Testing
import {
useABTest,
useABTestManager,
ABTestBuilder,
} from "@markiearnold/flow-machine";
// Create test manager
const {manager} = useABTestManager();
// Create test
const test = new ABTestBuilder("welcome-message")
.setName("Welcome Message Test")
.addVariation("A", "Welcome!")
.addVariation("B", "Hello there!")
.setTraffic(50, "equal")
.build();
// Use test
const testResult = useABTest({
userId: "user-123",
testId: "welcome-message",
manager,
});Development
Building
npm run buildDevelopment Mode
npm run devType Checking
npm run type-checkTesting
npm run test # Run all tests
npm run test:watch # Run tests in watch mode
npm run test:coverage # Run tests with coverage
npm run test:integration # Run integration tests📚 Documentation
Documentation is available in the /docs folder and includes:
- Getting Started - Installation and basic usage
- API Reference - Complete API documentation
- Examples - Real-world usage examples
- Advanced Features - A/B testing, templates, analytics, and more
Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Documentation Development
To work on documentation:
npm run docs:dev # Start docs dev server
npm run docs:build # Build documentation
npm run docs:serve # Serve built documentation
npm run docs:deploy # Deploy to GitHub PagesLicense
This project is licensed under the MIT License - see the LICENSE file for details.
💬 Community & Support
- 📖 Documentation - Available in the
/docsfolder - 🐛 Bug Reports - Report issues on GitHub
- 💡 Feature Requests - Suggest improvements on GitHub
- 📦 npm Package - Install from npm
- ⭐ GitHub Repository - Source code and examples
Made with ❤️ for the React community. Star the repo if it helps you build amazing conversational UIs! 🌟
