| name | output-dev-workflow-function |
| description | Create workflow.ts files for Output SDK workflows. Use when defining workflow functions, orchestrating steps, or fixing workflow structure issues. |
| allowed-tools | ["Read","Write","Edit"] |
Creating workflow.ts Files
Overview
This skill documents how to create workflow.ts files for Output SDK workflows. The workflow file contains the main orchestration logic that coordinates step execution.
When to Use This Skill
- Creating a new workflow's main definition
- Understanding workflow structure requirements
- Debugging workflow orchestration issues
- Refactoring existing workflow logic
Critical Rules
1. Import Pattern
import { workflow, z } from '@outputai/core';
import { z } from 'zod';
2. ES Module Imports
All imports MUST use .js extension:
import { stepName } from './steps.js';
import { WorkflowInputSchema } from './types.js';
import { stepName } from './steps';
import { WorkflowInputSchema } from './types';
3. Determinism Requirement
CRITICAL: The workflow fn must be deterministic. No direct I/O operations are allowed in the workflow function.
export default workflow({
fn: async (input) => {
const response = await fetch('https://api.example.com');
return response.json();
}
});
export default workflow({
fn: async (input) => {
const result = await fetchDataStep(input);
return result;
}
});
Related Skill: output-error-nondeterminism
Basic Structure
import { workflow, z } from '@outputai/core';
import { stepOne, stepTwo } from './steps.js';
import { WorkflowInputSchema, WorkflowOutput } from './types.js';
export default workflow({
name: 'workflowName',
description: 'Brief description of what the workflow does',
inputSchema: WorkflowInputSchema,
outputSchema: z.object({ }),
fn: async (input): Promise<WorkflowOutput> => {
const result = await stepOne(input);
const final = await stepTwo(result);
return final;
}
});
Required Properties
name (string)
Unique identifier for the workflow. Use camelCase.
name: 'contentUtilsImageInfographicNano'
description (string)
Human-readable description of the workflow's purpose.
description: 'Generate high-quality infographic images using AI-powered ideation'
inputSchema (Zod schema)
Schema for validating workflow input. Import from types.ts.
inputSchema: WorkflowInputSchema
Related Skill: output-dev-types-file
outputSchema (Zod schema)
Schema for validating workflow output.
outputSchema: z.object({
results: z.array(z.string()),
metadata: z.object({
processedAt: z.string()
})
})
fn (async function)
The workflow execution function. Must be deterministic.
fn: async (input): Promise<WorkflowOutput> => {
const result = await processStep(input);
return result;
}
Complete Example
Based on a real workflow (image_infographic_nano):
import { workflow, z } from '@outputai/core';
import {
generateImageIdeas,
generateImages,
validateReferenceImages
} from './steps.js';
import {
WorkflowInput,
WorkflowInputSchema,
WorkflowOutput
} from './types.js';
import { normalizeReferenceImageUrls } from './utils.js';
export default workflow({
name: 'contentUtilsImageInfographicNano',
description: 'Generate high-quality infographic images using Google Gemini 3 Pro Image model with AI-powered ideation',
inputSchema: WorkflowInputSchema,
outputSchema: z.array(z.string()),
fn: async (rawInput: WorkflowInput): Promise<WorkflowOutput> => {
const input = {
...rawInput,
referenceImageUrls: normalizeReferenceImageUrls(rawInput.referenceImageUrls)
};
if (input.referenceImageUrls && input.referenceImageUrls.length > 0) {
await validateReferenceImages({
referenceImageUrls: input.referenceImageUrls as string[]
});
}
const ideas = await generateImageIdeas({
content: input.content,
numberOfIdeas: input.numberOfIdeas,
colorPalette: input.colorPalette,
artDirection: input.artDirection
});
const generations = await Promise.all(
ideas.map(idea =>
generateImages({
input: {
referenceImageUrls: input.referenceImageUrls,
aspectRatio: input.aspectRatio,
resolution: input.resolution,
numberOfGenerations: input.numberOfGenerations,
storageNamespace: input.storageNamespace
},
prompt: idea
})
)
);
return generations.flat();
}
});
Orchestration Patterns
Sequential Execution
Execute steps one after another:
fn: async (input) => {
const step1Result = await stepOne(input);
const step2Result = await stepTwo(step1Result);
const step3Result = await stepThree(step2Result);
return step3Result;
}
Parallel Execution
Execute independent steps concurrently:
fn: async (input) => {
const [resultA, resultB, resultC] = await Promise.all([
stepA(input),
stepB(input),
stepC(input)
]);
return { resultA, resultB, resultC };
}
Conditional Execution
Execute steps based on conditions:
fn: async (input) => {
if (input.includeImages) {
await processImages(input);
}
const result = input.mode === 'fast'
? await quickProcess(input)
: await detailedProcess(input);
return result;
}
Fan-Out Pattern
Process multiple items in parallel:
fn: async (input) => {
const results = await Promise.all(
input.items.map(item => processItem({ item }))
);
return { processedItems: results };
}
Pipeline Pattern
Chain multiple transformations:
fn: async (input) => {
const extracted = await extractData(input);
const transformed = await transformData(extracted);
const validated = await validateData(transformed);
const enriched = await enrichData(validated);
return enriched;
}
What is Allowed in Workflow fn
Allowed (Deterministic Operations)
- Calling step functions
- Pure data transformations
- Conditional logic based on input
- Array operations (map, filter, reduce)
- Object destructuring and construction
- Promise.all for parallel steps
- Control flow (if/else, loops)
NOT Allowed (Non-Deterministic Operations)
- HTTP requests (use steps)
- Database queries (use steps)
- File system operations (use steps)
- Random number generation
- Current date/time access
- Environment variable access
- Any external service calls
Verification Checklist
Related Skills
output-dev-step-function - Creating step functions that handle I/O
output-dev-evaluator-function - Using steps in evaluator functions
output-dev-types-file - Defining input/output schemas
output-dev-folder-structure - Where workflow.ts belongs
output-error-nondeterminism - Fixing determinism violations
output-error-zod-import - Fixing schema import issues