Build explainable, replayable, and memory-aware workflows with Motia and Mem0.
MDWR combines workflow orchestration with operational decision memory to create workflows that:
- Remember every decision and why it was made
- Explain decisions automatically (compile-time enforced)
- Learn from past decisions and outcomes
- Replay with different policies or memory-informed insights
The SDK includes production-ready features:
- Middleware System: Authentication, validation, logging, retry, and memory middleware
- Type Safety: Full TypeScript support with Zod validation
- Error Handling: Automatic retries with exponential backoff
- State Management: Cross-step state management utilities
- Event System: Event-driven communication between workflows
- Memory Integration: Automatic memory search and storage
- Observability: Built-in logging and monitoring hooks
See ROBUST_SDK.md for comprehensive documentation.
MDWR uses:
- Motia as the backend runtime (event-driven, long-running)
- Mem0 as the memory layer (decision storage and similarity search)
- Redis for local memory storage (via Docker)
Developer SDK → MDWR Control Plane → Motia Runtime + Mem0/Redis
- Node.js 18+ and npm
- Python 3.9+ and pip
- Docker and Docker Compose
docker-compose up -d redisVerify Redis is running:
docker exec mdwr-redis redis-cli ping
# Should return: PONGTypeScript SDK:
cd packages/mdwr-sdk
npm install
npm run build
cd ../..Python SDK:
cd packages/mdwr
pip install -e .
cd ../..npx mdwr initThis creates:
mdwr.config.json- Configurationworkflows/- Your workflows directoryworkflows/example.ts- Example workflow
Navigate to the motia-atlas directory (your working Motia project):
cd motia-atlas
npm install
npm run devMotia Workbench will be available at http://localhost:3000.
Create a workflow in workflows/refund.ts:
import { Workflow } from "@mdwr/sdk";
const refundWorkflow = Workflow.create("refund_v1")
.step("evaluate_risk", async (ctx) => {
// Query memory for similar decisions
const insights = await ctx.memory.similar({
situation: "refund_decision",
context: {
amount: ctx.input.amount,
userTier: ctx.input.userTier || "standard"
}
});
let decision = "approve";
let reason = "Standard approval";
let confidence = 0.8;
// Use historical insights
if (insights.length > 0) {
const best = insights[0];
if (best.outcome?.success) {
decision = best.decision.decision;
reason = `Based on similar decision: ${best.decision.reason}`;
confidence = Math.min(0.95, (best.decision.confidence || 0.8) + 0.1);
}
}
// Business logic
if (ctx.input.amount > 1000) {
decision = "manual_review";
reason = "High amount requires review";
confidence = 0.9;
}
return {
decision,
reason,
confidence,
metadata: {
similarDecisions: insights.length
}
};
}, true) // decision_required = true
.step("issue_refund", async (ctx) => {
if (ctx.state.evaluate_risk?.decision !== "approve") {
return {
decision: "skip",
reason: "Not approved in risk evaluation",
confidence: 1.0
};
}
console.log(`Refunding $${ctx.input.amount} to user ${ctx.input.userId}`);
return {
decision: "completed",
reason: "Refund issued successfully",
confidence: 1.0
};
}, true);
export default refundWorkflow;Deploy the workflow:
npx ts-node scripts/deploy.tsThis generates Motia steps in motia-atlas/src/refund_v1/ directory.
npx ts-node scripts/execute.ts refund_v1Or test via Motia Workbench at http://localhost:3000:
- See workflow diagram
- Test API endpoints
- View logs and state in real-time
Every decision is automatically stored with:
- Decision and reason
- Confidence score
- Full context snapshot
- Eventual outcome (async)
Every step that requires a decision must return:
{
decision: string;
reason: string;
confidence?: number;
metadata?: object;
}This is enforced at compile time (TypeScript) or runtime (Python with Pydantic).
Query similar historical decisions:
const insights = await ctx.memory.similar({
situation: "refund_decision",
context: { amount: 120, userTier: "gold" }
});// Exact replay
await execution.replay({ mode: "exact" });
// Policy-aware replay
await execution.replay({
mode: "policy-aware",
overrides: { policyVersion: "v3" }
});
// Memory-informed replay
await execution.replay({ mode: "memory-informed" });Motia-Atlas/
├── motia-atlas/ # Working Motia project
│ ├── src/ # Motia steps (auto-generated by MDWR)
│ │ └── refund_v1/ # Workflow steps
│ ├── motia.config.ts # Motia configuration
│ └── package.json
├── packages/
│ ├── mdwr-sdk/ # TypeScript SDK
│ └── mdwr/ # Python SDK
├── workflows/ # Your MDWR workflows
├── scripts/ # Deployment and execution scripts
├── docker-compose.yml # Redis setup
└── README.md # This file
MDWR workflows are automatically converted to Motia Steps and deployed to motia-atlas/src/:
- Entry Step: API endpoint (
/workflows/{id}/execute) - Workflow Steps: Event-driven steps with subscribe/emit
- State Management: Uses Motia's
state.get(groupId, key)andstate.set(groupId, key, value) - Auto-Discovery: Steps placed in
motia-atlas/src/{workflow}/directory - Workbench: Visual debugging at
http://localhost:3000
- Define Workflow: Create workflow in
workflows/using MDWR SDK - Deploy: Run
npx ts-node scripts/deploy.tsto generate Motia steps - Auto-Discovery: Motia automatically discovers steps from
motia-atlas/src/ - Execute: Steps run through Motia's event system
- Debug: Use Motia Workbench to visualize and debug
MDWR generates Motia-compliant steps:
TypeScript Step:
import type { ApiRouteConfig, Handlers } from 'motia';
export const config: ApiRouteConfig = {
name: 'RefundV1Entry',
type: 'api',
path: '/workflows/refund_v1/execute',
method: 'POST',
emits: ['refund_v1.started'],
flows: ['refund_v1-flow']
};
export const handler: Handlers['RefundV1Entry'] = async (_, { emit, logger, state }) => {
// MDWR-generated handler
};Python Step:
config = {
"name": "RefundV1EvaluateRisk",
"type": "event",
"subscribes": ["refund_v1.started"],
"emits": ["refund_v1.evaluate_risk.completed"],
"flows": ["refund_v1-flow"]
}
async def handler(input_data, context):
# MDWR-generated handlerimport { Workflow } from "@mdwr/sdk";
const workflow = Workflow.create("my_workflow_v1")
.step("step1", async (ctx) => {
const insights = await ctx.memory.similar({
situation: "my_decision",
context: ctx.input
});
return {
decision: "proceed",
reason: "Based on historical patterns",
confidence: 0.85
};
}, true);
await workflow.deploy();
const execution = await workflow.execute({ userId: "u123" });from mdwr import Workflow
workflow = Workflow.create("my_workflow_v1")
@workflow.step("step1", decision_required=True)
async def step1(ctx):
insights = await ctx.memory.similar(
situation="my_decision",
context=ctx.input
)
return {
"decision": "proceed",
"reason": "Based on historical patterns",
"confidence": 0.85
}
await workflow.deploy()
execution = await workflow.execute({"userId": "u123"})Default configuration uses mock memory - no setup required:
{
"memory": {
"provider": "mock",
"collection": "mdwr_decisions"
}
}- Get Mem0 API key from https://mem0.ai
- Update
mdwr.config.json:{ "memory": { "provider": "mem0", "collection": "mdwr_decisions" } } - Set environment variable:
export MEM0_API_KEY=your-key
-
Start Services:
# Terminal 1: Redis docker-compose up redis # Terminal 2: Motia (in motia-atlas directory) cd motia-atlas npm run dev
-
Create Workflow:
- Define workflow in
workflows/directory - Use TypeScript or Python
- Define workflow in
-
Deploy:
npx ts-node scripts/deploy.ts
-
Test:
- Use Motia Workbench at
http://localhost:3000 - Or execute programmatically:
npx ts-node scripts/execute.ts workflow_name
- Use Motia Workbench at
- Semantic Replay: Advanced similarity matching with outcome awareness
- Outcome Tracking: Link outcomes to decisions
- Memory-Based Branching: Dynamic branching based on historical decisions
- Anomaly Detection: Detect decision deviations from patterns
- AI-Assisted Decisions: AI-powered decision making with memory context
- Memory Optimization: Cleanup, deduplication, compression
- Policy Simulation: Test policies, compare versions, optimize parameters
See packages/mdwr-sdk/src/ for implementation details.
# Check if Redis is running
docker-compose ps
# Check Redis logs
docker-compose logs redis
# Restart Redis
docker-compose restart redis# Ensure you're in motia-atlas directory
cd motia-atlas
# Check if dependencies are installed
npm install
# Start Motia
npm run dev- Check Motia is running (
http://localhost:3000) - Verify workflow syntax is correct
- Check
motia-atlas/src/directory for generated steps - Review console for errors
- In development, mock memory is used automatically
- For production, configure Mem0 API key
- Check
mdwr.config.jsonfor memory provider setting
# Motia (configured in motia-atlas/motia.config.ts)
REDIS_HOST=localhost
REDIS_PORT=6379
# Mem0 (for production)
MEM0_API_KEY=your-mem0-key
# MDWR
MDWR_ENV=development
MDWR_MEMORY_PROVIDER=mock{
"workflows": [],
"memory": {
"provider": "mock",
"collection": "mdwr_decisions"
}
}Workflow.create(id: string, version?: string): Workflow
workflow.step(name: string, handler: StepHandler, decisionRequired?: boolean): Workflow
workflow.execute(input: any): Promise<Execution>
workflow.deploy(): Promise<void>execution.pause(reason: string): Promise<void>
execution.resume(resumeData?: Record<string, any>): Promise<void>
execution.replay(options: ReplayOptions): Promise<Execution>
execution.getState(): Record<string, any>
execution.getStepResults(): Map<string, StepDecision>ctx.memory.similar(params: {
situation: string;
context?: Record<string, any>;
crossWorkflow?: string[];
}): Promise<MemoryInsight[]>
ctx.memory.query(params: {
workflowId?: string;
stepName?: string;
decision?: string;
limit?: number;
}): Promise<StoredDecision[]>Comprehensive examples in examples/ directory. View all examples on GitHub.
Simple 3-step workflow demonstrating MDWR fundamentals:
import { Workflow } from "@mdwr/sdk";
const basicWorkflow = Workflow.create("basic_v1")
.step("validate_input", async (ctx) => {
const { userId, amount } = ctx.input;
if (!userId || !amount) {
return {
decision: "reject",
reason: "Missing required fields",
confidence: 1.0
};
}
return {
decision: "approve",
reason: "Input validation passed",
confidence: 1.0
};
}, true)
.step("process_data", async (ctx) => {
if (ctx.state.validate_input?.decision !== "approve") {
return { decision: "skip", reason: "...", confidence: 1.0 };
}
return {
decision: "completed",
reason: "Processing completed",
confidence: 1.0
};
}, true);
export default basicWorkflow;View full example: examples/basic-workflow.ts
E-commerce refund with memory integration:
import { Workflow } from "@mdwr/sdk";
const refundWorkflow = Workflow.create("refund_v1")
.step("evaluate_risk", async (ctx) => {
// Query memory for similar decisions
const insights = await ctx.memory.similar({
situation: "refund_decision",
context: {
amount: ctx.input.amount,
userTier: ctx.input.userTier
}
});
let decision = "approve";
let reason = "Standard approval";
// Use historical insights
if (insights.length > 0) {
const best = insights[0];
if (best.outcome?.success) {
decision = best.decision.decision;
reason = `Based on similar decision: ${best.decision.reason}`;
}
}
// Business logic
if (ctx.input.amount > 1000) {
decision = "manual_review";
reason = "High amount requires review";
}
return { decision, reason, confidence: 0.9 };
}, true)
.step("issue_refund", async (ctx) => {
if (ctx.state.evaluate_risk?.decision !== "approve") {
return { decision: "skip", reason: "Not approved", confidence: 1.0 };
}
return { decision: "completed", reason: "Refund issued", confidence: 1.0 };
}, true);
export default refundWorkflow;View full example: examples/refund-workflow.ts
- Basic Workflow (
basic-workflow.ts/basic-workflow.py) - Learning fundamentals - Refund Workflow (
refund-workflow.ts/refund-workflow.py) - Memory integration - Approval Workflow (
approval-workflow.ts) - Multi-level approvals - Order Processing (
order-processing.ts) - E-commerce fulfillment - Content Moderation (
content-moderation.ts) - AI/ML decisions - Replay Examples (
replay-examples.ts) - Replay modes
# Deploy all workflows
npx ts-node scripts/deploy.ts
# Execute specific workflow
npx ts-node scripts/execute.ts refund_v1
# View in Motia Workbench
cd motia-atlas && npm run dev
# Open http://localhost:3000See examples/README.md for detailed guide.
- Documentation Site - Full documentation (Astro)
- Planning.md - Full design specification
cd docs
npm install
npm run devVisit http://localhost:4321 to view the documentation.
MIT