Skip to content
Back to skills

Output Dev Workflow Function

ASecurity

Create workflow.ts files for Output SDK workflows. Use when defining workflow functions, orchestrating steps, or fixing workflow structure issues.

  • 440 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added May 27, 2026
data-aitypescriptgodebuggingrefactoringapidatabase

Works with

  • api

Security analysis

A100/100

Scanned May 27, 2026

npx -y skills add growthxai/output --skill output-dev-workflow-function --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Output Dev Workflow Function?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Output Dev Workflow Function
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/growthxai-output-dev-workflow-function/badge)](https://www.skillsdirectory.com/skills/growthxai-output-dev-workflow-function)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
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

```typescript
// CORRECT - Import from @outputai/core
import { workflow, z } from '@outputai/core';

// WRONG - Never import z from zod
import { z } from 'zod';
```

### 2. ES Module Imports

All imports MUST use `.js` extension:

```typescript
// CORRECT
import { stepName } from './steps.js';
import { WorkflowInputSchema } from './types.js';

// WRONG - Missing .js extension
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.

```typescript
// WRONG - Direct I/O in workflow
export default workflow( {
  // ...
  fn: async input => {
    const response = await fetch( 'https://api.example.com' ); // NEVER do this!
    return response.json();
  }
} );

// CORRECT - Delegate I/O to steps
export default workflow( {
  // ...
  fn: async input => {
    const result = await fetchDataStep( input ); // Steps handle I/O
    return result;
  }
} );
```

**Related Skill**: `output-error-nondeterminism`

## Basic Structure

```typescript
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( { /* output shape */ } ),
  fn: async ( input ): Promise<WorkflowOutput> => {
    // Orchestrate step calls
    const result = await stepOne( input );
    const final = await stepTwo( result );
    return final;
  }
} );
```

## Required Properties

### name (string)
Unique identifier for the workflow. Use camelCase.

```typescript
name: 'contentUtilsImageInfographicNano'
```

### description (string)
Human-readable description of the workflow's purpose.

```typescript
description: 'Generate high-quality infographic images using AI-powered ideation'
```

### inputSchema (Zod schema)
Schema for validating workflow input. Import from `types.ts`.

```typescript
inputSchema: WorkflowInputSchema
```

**Related Skill**: `output-dev-types-file`

### outputSchema (Zod schema)
Schema for validating workflow output.

```typescript
outputSchema: z.object( {
  results: z.array( z.string() ),
  metadata: z.object( {
    processedAt: z.string()
  } )
} )
```

### fn (async function)
The workflow execution function. Must be deterministic.

```typescript
fn: async ( input ): Promise<WorkflowOutput> => {
  // Step orchestration only - no direct I/O
  const result = await processStep( input );
  return result;
}
```

## Complete Example

Based on a real workflow (`image_infographic_nano`):

```typescript
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> => {
    // Pre-process input (pure function - OK in workflow)
    const input = {
      ...rawInput,
      referenceImageUrls: normalizeReferenceImageUrls( rawInput.referenceImageUrls )
    };

    // Conditional step execution
    if ( input.referenceImageUrls && input.referenceImageUrls.length > 0 ) {
      await validateReferenceImages( {
        referenceImageUrls: input.referenceImageUrls as string[]
      } );
    }

    // Sequential step execution
    const ideas = await generateImageIdeas( {
      content: input.content,
      numberOfIdeas: input.numberOfIdeas,
      colorPalette: input.colorPalette,
      artDirection: input.artDirection
    } );

    // Parallel step execution
    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:

```typescript
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:

```typescript
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:

```typescript
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:

```typescript
fn: async input => {
  const results = await Promise.all(
    input.items.map( item => processItem( { item } ) )
  );
  return { processedItems: results };
}
```

### Pipeline Pattern

Chain multiple transformations:

```typescript
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

- [ ] `workflow` and `z` imported from `@outputai/core`
- [ ] All imports use `.js` extension
- [ ] Default export used for the workflow
- [ ] `name` is camelCase and unique
- [ ] `description` clearly explains the workflow
- [ ] `inputSchema` imported from `types.ts`
- [ ] `outputSchema` matches actual return type
- [ ] `fn` is deterministic (no direct I/O)
- [ ] All I/O delegated to step functions
- [ ] Code follows style conventions (see output-dev-code-style)

## 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
- `output-dev-code-style`

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.