xiaohongshu
xiaohongshu
flow-convert-workflow-definition
Convert Flow SDK workflow class to Output SDK workflow() function. Use when migrating workflow.ts files from class-based to functional definitions.
Full skill instructions
This skill guides the conversion of Flow SDK workflow classes to Output SDK functional workflow definitions. Workflows orchestrate step execution and define the overall data flow.
During Migration:
workflow.ts from class-based to functional| Aspect | Flow SDK | Output SDK |
|---|---|---|
| Definition | Class with execute() method | workflow() function |
| Input/Output | TypeScript interfaces | Zod schemas |
| Activity Calls | Direct function calls | Step calls with object params |
| Error Handling | Try-catch blocks | Let errors propagate |
| Imports | @flow/sdk | @output.ai/core |
// workflow.ts
import { Workflow, WorkflowScope } from '@flow/sdk';
import { fetchUser, processData, saveResults } from './activities';
interface WorkflowInput {
userId: string;
processType: string;
}
interface WorkflowOutput {
success: boolean;
resultId: string;
}
export class DataProcessingWorkflow implements Workflow<WorkflowInput, WorkflowOutput> {
async execute( input: WorkflowInput ): Promise<WorkflowOutput> {
try {
// Get user data
const user = await fetchUser( input.userId );
// Process the data
const processed = await processData( user, input.processType );
// Save results
const result = await saveResults( processed );
return {
success: true,
resultId: result.id
};
} catch ( error ) {
throw new Error( `Workflow failed: ${error.message}` );
}
}
}
// workflow.ts
import { workflow, z } from '@output.ai/core';
import { fetchUser, processData, saveResults } from './steps.js';
const WorkflowInputSchema = z.object( {
userId: z.string(),
processType: z.string()
} );
const WorkflowOutputSchema = z.object( {
success: z.boolean(),
resultId: z.string()
} );
export default workflow( {
name: 'dataProcessing',
description: 'Process user data and save results',
inputSchema: WorkflowInputSchema,
outputSchema: WorkflowOutputSchema,
fn: async ( input ) => {
// Get user data
const user = await fetchUser( { userId: input.userId } );
// Process the data
const processed = await processData( { user, processType: input.processType } );
// Save results
const result = await saveResults( { data: processed } );
return {
success: true,
resultId: result.id
};
}
} );
Find the workflow class in workflow.ts:
grep -E "class.*Workflow" src/workflows/my-workflow/workflow.ts
Convert TypeScript interfaces to Zod schemas:
// Before: TypeScript interface
interface WorkflowInput {
userId: string;
count: number;
options?: ProcessOptions;
}
// After: Zod schema
const WorkflowInputSchema = z.object( {
userId: z.string(),
count: z.number(),
options: ProcessOptionsSchema.optional()
} );
Replace class definition with workflow() call:
// Before
export class MyWorkflow implements Workflow<Input, Output> {
async execute( input: Input ): Promise<Output> {
// ...
}
}
// After
export default workflow( {
name: 'myWorkflow',
description: 'Description of what this workflow does',
inputSchema: InputSchema,
outputSchema: OutputSchema,
fn: async ( input ) => {
// ...
}
} );
Change direct function calls to object parameter calls:
// Before (Flow SDK)
const result = await someActivity( param1, param2, param3 );
// After (Output SDK)
const result = await someStep( { param1, param2, param3 } );
Remove error handling wrappers (see flow-error-try-catch-removal):
// Before
async execute( input ) {
try {
const result = await doWork( input );
return result;
} catch ( error ) {
throw new Error( error.message );
}
}
// After
fn: async ( input ) => {
const result = await doWork( { ...input } );
return result;
}
// Before
import { Workflow, WorkflowScope } from '@flow/sdk';
import { z } from 'zod';
// After
import { workflow, z } from '@output.ai/core';
The workflow name must match the legacy name if other systems depend on it:
// Legacy system calls workflow by name 'userOnboarding'
export default workflow( {
name: 'userOnboarding', // Must match!
// ...
} );
Workflows should use export default:
// CORRECT
export default workflow( { ... } );
// WRONG
export const myWorkflow = workflow( { ... } );
Always include .js extension for local imports:
import { fetchUser, processData } from './steps.js';
import { WorkflowInputSchema } from './types.js';
Workflows can invoke other workflows directly:
// parent/workflow.ts
import { workflow, z } from '@output.ai/core';
import childWorkflow from '../child/workflow.js';
export default workflow( {
name: 'parentWorkflow',
inputSchema: z.object( { data: z.string() } ),
outputSchema: z.object( { result: z.string() } ),
fn: async ( input ) => {
// Call child workflow like a step
const childResult = await childWorkflow( { input: input.data } );
return { result: childResult.output };
}
} );
// workflow.ts
import { Workflow, WorkflowScope, FatalError } from '@flow/sdk';
import {
validateInput,
fetchUserProfile,
generateReport,
sendNotification
} from './activities';
interface ReportInput {
userId: string;
reportType: 'daily' | 'weekly' | 'monthly';
includeCharts: boolean;
}
interface ReportOutput {
reportId: string;
downloadUrl: string;
generatedAt: string;
}
export class GenerateReportWorkflow implements Workflow<ReportInput, ReportOutput> {
async execute( input: ReportInput ): Promise<ReportOutput> {
try {
// Validate input
const validated = await validateInput( input );
// Fetch user profile
const profile = await fetchUserProfile( input.userId );
// Generate the report
const report = await generateReport(
profile,
validated.reportType,
validated.includeCharts
);
// Send notification
await sendNotification( profile.email, report.id );
return {
reportId: report.id,
downloadUrl: report.url,
generatedAt: new Date().toISOString()
};
} catch ( error ) {
throw new FatalError( `Report generation failed: ${error.message}` );
}
}
}
// workflow.ts
import { workflow, z } from '@output.ai/core';
import {
validateInput,
fetchUserProfile,
generateReport,
sendNotification
} from './steps.js';
const ReportInputSchema = z.object( {
userId: z.string(),
reportType: z.enum( [ 'daily', 'weekly', 'monthly' ] ),
includeCharts: z.boolean()
} );
const ReportOutputSchema = z.object( {
reportId: z.string(),
downloadUrl: z.string(),
generatedAt: z.string()
} );
export default workflow( {
name: 'generateReport',
description: 'Generate user reports with optional charts',
inputSchema: ReportInputSchema,
outputSchema: ReportOutputSchema,
fn: async ( input ) => {
// Validate input
const validated = await validateInput( {
userId: input.userId,
reportType: input.reportType,
includeCharts: input.includeCharts
} );
// Fetch user profile
const profile = await fetchUserProfile( { userId: input.userId } );
// Generate the report
const report = await generateReport( {
profile,
reportType: validated.reportType,
includeCharts: validated.includeCharts
} );
// Send notification
await sendNotification( {
email: profile.email,
reportId: report.id
} );
return {
reportId: report.id,
downloadUrl: report.url,
generatedAt: new Date().toISOString()
};
}
} );
workflow() function@output.ai/core.js extensionexport default usedflow-convert-activities-to-steps - Step conversionflow-error-try-catch-removal - Try-catch antipatternflow-error-zod-import - Zod import issuesflow-validation-checklist - Complete validationxiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience