Create step functions in steps.ts for Output SDK workflows. Use when implementing I/O operations, error handling, HTTP requests, or LLM calls.
Installation
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Create step functions in steps.ts for Output SDK workflows. Use when implementing I/O operations, error handling, HTTP requests, or LLM calls.
allowed-tools
["Read","Write","Edit"]
Creating Step Functions
Overview
This skill documents how to create step functions in steps.ts for Output SDK workflows. Steps are where all I/O operations happen - HTTP requests, LLM calls, database operations, file system access, etc.
When to Use This Skill
Implementing I/O operations for a workflow
Adding HTTP client integrations
Implementing LLM-powered steps
Handling errors with FatalError and ValidationError
Creating reusable step components
File Organization
Option 1: Flat File (Default)
For smaller workflows, use a single steps.ts file:
src/workflows/{workflow-name}/
├── workflow.ts
├── steps.ts # All steps in one file
├── types.ts
└── ...
Option 2: Folder-Based (Large workflows)
For larger workflows with many steps, use a steps/ folder:
// CORRECT - Import from @outputai/coreimport { step, z, FatalError, ValidationError } from'@outputai/core';
// WRONG - Never import z from zodimport { z } from'zod';
HTTP Client Import
// CORRECT - Use @outputai/http wrapperimport { httpClient } from'@outputai/http';
// WRONG - Never use axios directlyimport axios from'axios';
Related Skill: output-error-http-client
LLM Client Import
// CORRECT - Use @outputai/llm wrapperimport { generateText, Output } from'@outputai/llm';
// WRONG - Never call LLM providers directlyimportOpenAIfrom'openai';
// Good - focused stepexportconst fetchUserData = step({
name: 'fetchUserData',
description: 'Fetch user data from the API',
// ...
});
// Avoid - step doing too muchexportconst fetchAndProcessAndSaveUserData = step({
name: 'fetchAndProcessAndSaveUserData',
// ...
});
2. Clear Error Messages
// Good - specific error messagethrownewFatalError(`Invalid API key for service: ${serviceName}`);
// Avoid - generic error messagethrownewFatalError('Error occurred');
3. Validate Input Early
fn: async (input) => {
// Validate earlyif (!input.url.startsWith('https://')) {
thrownewFatalError('URL must use HTTPS protocol');
}
// Then proceed with operationconst response = await httpClientInstance.get(input.url);
// ...
}
Verification Checklist
step, z, FatalError, ValidationError imported from @outputai/core
httpClient imported from @outputai/http (not axios)
generateText and Output imported from @outputai/llm (not direct provider)
Structured output uses Output.object() with .describe() (not .min()/.max()) on number schemas
All imports use .js extension
Named exports used for each step
Each step has name, description, inputSchema, outputSchema, fn
FatalError used for non-retryable failures
ValidationError used for retryable failures
No bare try-catch blocks that swallow errors
Steps only import allowed dependencies (local files, shared code)
No imports of other steps, evaluators, or workflows
Related Skills
output-dev-workflow-function - Orchestrating steps in workflow.ts
output-dev-evaluator-function - Using steps in evaluator functions