@output.ai/cli 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -8
- package/dist/api/generated/api.d.ts +66 -0
- package/dist/api/generated/api.js +26 -0
- package/dist/assets/docker/docker-compose-dev.yml +9 -2
- package/dist/commands/workflow/runs/list.d.ts +14 -0
- package/dist/commands/workflow/runs/list.js +104 -0
- package/dist/services/coding_agents.js +180 -8
- package/dist/services/coding_agents.spec.js +54 -11
- package/dist/services/workflow_runs.d.ts +14 -0
- package/dist/services/workflow_runs.js +24 -0
- package/dist/templates/agent_instructions/AGENTS.md.template +13 -7
- package/dist/templates/agent_instructions/agents/{context_fetcher.md.template → workflow_context_fetcher.md.template} +1 -1
- package/dist/templates/agent_instructions/agents/workflow_debugger.md.template +98 -0
- package/dist/templates/agent_instructions/agents/workflow_planner.md.template +3 -3
- package/dist/templates/agent_instructions/agents/{prompt_writer.md.template → workflow_prompt_writer.md.template} +1 -1
- package/dist/templates/agent_instructions/agents/workflow_quality.md.template +2 -2
- package/dist/templates/agent_instructions/commands/build_workflow.md.template +2 -2
- package/dist/templates/agent_instructions/commands/debug_workflow.md.template +198 -0
- package/dist/templates/agent_instructions/commands/plan_workflow.md.template +2 -2
- package/dist/templates/agent_instructions/skills/output-error-direct-io/SKILL.md.template +249 -0
- package/dist/templates/agent_instructions/skills/output-error-http-client/SKILL.md.template +298 -0
- package/dist/templates/agent_instructions/skills/output-error-missing-schemas/SKILL.md.template +265 -0
- package/dist/templates/agent_instructions/skills/output-error-nondeterminism/SKILL.md.template +252 -0
- package/dist/templates/agent_instructions/skills/output-error-try-catch/SKILL.md.template +226 -0
- package/dist/templates/agent_instructions/skills/output-error-zod-import/SKILL.md.template +209 -0
- package/dist/templates/agent_instructions/skills/output-services-check/SKILL.md.template +128 -0
- package/dist/templates/agent_instructions/skills/output-workflow-list/SKILL.md.template +117 -0
- package/dist/templates/agent_instructions/skills/output-workflow-result/SKILL.md.template +199 -0
- package/dist/templates/agent_instructions/skills/output-workflow-run/SKILL.md.template +228 -0
- package/dist/templates/agent_instructions/skills/output-workflow-runs-list/SKILL.md.template +141 -0
- package/dist/templates/agent_instructions/skills/output-workflow-start/SKILL.md.template +201 -0
- package/dist/templates/agent_instructions/skills/output-workflow-status/SKILL.md.template +151 -0
- package/dist/templates/agent_instructions/skills/output-workflow-stop/SKILL.md.template +164 -0
- package/dist/templates/agent_instructions/skills/output-workflow-trace/SKILL.md.template +134 -0
- package/dist/templates/project/README.md.template +1 -1
- package/dist/templates/project/package.json.template +3 -2
- package/dist/utils/date_formatter.d.ts +15 -0
- package/dist/utils/date_formatter.js +31 -1
- package/package.json +1 -1
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow runs service for fetching workflow run data from the API
|
|
3
|
+
*/
|
|
4
|
+
import { getWorkflowRuns } from '#api/generated/api.js';
|
|
5
|
+
export async function fetchWorkflowRuns(options = {}) {
|
|
6
|
+
const params = {};
|
|
7
|
+
if (options.limit) {
|
|
8
|
+
params.limit = options.limit;
|
|
9
|
+
}
|
|
10
|
+
if (options.workflowType) {
|
|
11
|
+
params.workflowType = options.workflowType;
|
|
12
|
+
}
|
|
13
|
+
const response = await getWorkflowRuns(params);
|
|
14
|
+
if (!response) {
|
|
15
|
+
throw new Error('Failed to connect to API server. Is it running?');
|
|
16
|
+
}
|
|
17
|
+
if (!response.data) {
|
|
18
|
+
throw new Error('API returned invalid response (missing data)');
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
runs: response.data.runs || [],
|
|
22
|
+
count: response.data.count || 0
|
|
23
|
+
};
|
|
24
|
+
}
|
|
@@ -205,15 +205,21 @@ throw new FatalError('Critical failure - do not retry');
|
|
|
205
205
|
throw new ValidationError('Invalid input format');
|
|
206
206
|
```
|
|
207
207
|
|
|
208
|
-
##
|
|
208
|
+
## Sub-Agents
|
|
209
209
|
|
|
210
210
|
For workflow planning and implementation:
|
|
211
|
-
- `.claude/agents/workflow_planner.md` - Workflow architecture specialist
|
|
212
|
-
- `.claude/agents/workflow_quality.md` - Workflow quality and best practices specialist
|
|
213
|
-
- `.claude/agents/
|
|
214
|
-
- `.claude/agents/
|
|
215
|
-
- `.claude/
|
|
216
|
-
|
|
211
|
+
- workflow-planner: `.claude/agents/workflow_planner.md` - Workflow architecture specialist
|
|
212
|
+
- workflow-quality: `.claude/agents/workflow_quality.md` - Workflow quality and best practices specialist
|
|
213
|
+
- workflow-prompt-writer: `.claude/agents/workflow_prompt_writer.md` - Prompt file creation and review specialist
|
|
214
|
+
- workflow-context-fetcher: `.claude/agents/workflow_context_fetcher.md` - Efficient context retrieval (used by other agents)
|
|
215
|
+
- workflow-debugger: `.claude/agents/workflow_debugger.md` - Workflow debugging specialist
|
|
216
|
+
|
|
217
|
+
## Commands
|
|
218
|
+
|
|
219
|
+
For workflow planning and implementation:
|
|
220
|
+
- /plan_workflow: `.claude/commands/plan_workflow.md` - Planning command
|
|
221
|
+
- /build_workflow: `.claude/commands/build_workflow.md` - Implementation command
|
|
222
|
+
- /debug_workflow: `.claude/commands/debug_workflow.md` - Debugging command
|
|
217
223
|
|
|
218
224
|
## Configuration
|
|
219
225
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: context-fetcher
|
|
2
|
+
name: workflow-context-fetcher
|
|
3
3
|
description: Use proactively to retrieve and extract relevant information from Output SDK project documentation files. Checks if content is already in context before returning.
|
|
4
4
|
tools: Read, Grep, Glob
|
|
5
5
|
model: haiku
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: workflow-debugger
|
|
3
|
+
description: Use this agent when you need to debug Output SDK workflows in local development. Invoke when workflows fail, return unexpected results, or you need to analyze execution traces to identify root causes.
|
|
4
|
+
model: opus
|
|
5
|
+
color: yellow
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Output SDK Workflow Debugger Agent
|
|
9
|
+
|
|
10
|
+
## Identity
|
|
11
|
+
|
|
12
|
+
You are an Output SDK debugging expert who specializes in diagnosing and resolving workflow execution issues in local development environments. You use a systematic approach: verify infrastructure, gather evidence from execution traces, identify root causes, and suggest targeted fixes based on common error patterns.
|
|
13
|
+
|
|
14
|
+
## Context Retrieval
|
|
15
|
+
|
|
16
|
+
Use the `workflow-quality` subagent for:
|
|
17
|
+
- **Code Quality Guidance**: Import conventions, determinism rules, step boundaries
|
|
18
|
+
- **Best Practices**: Schema definitions, retry policies, error handling
|
|
19
|
+
- **Common Pitfalls**: Known issues and their solutions
|
|
20
|
+
|
|
21
|
+
Use the `workflow-context-fetcher` subagent for:
|
|
22
|
+
- **Project Structure**: Find workflow files in `src/workflows/*/`
|
|
23
|
+
- **Existing Patterns**: Examine similar implementations for comparison
|
|
24
|
+
|
|
25
|
+
## CLI Commands for Debugging
|
|
26
|
+
|
|
27
|
+
For detailed command usage, Claude will automatically invoke the relevant skill.
|
|
28
|
+
|
|
29
|
+
### Quick Reference
|
|
30
|
+
|
|
31
|
+
| Command | Purpose |
|
|
32
|
+
|---------|---------|
|
|
33
|
+
| `output dev` | Start development services |
|
|
34
|
+
| `output workflow list` | List available workflows |
|
|
35
|
+
| `output workflow runs list` | List execution history |
|
|
36
|
+
| `output workflow run` | Execute synchronously |
|
|
37
|
+
| `output workflow start` | Start asynchronously |
|
|
38
|
+
| `output workflow status` | Check execution status |
|
|
39
|
+
| `output workflow result` | Get execution result |
|
|
40
|
+
| `output workflow stop` | Stop running workflow |
|
|
41
|
+
| `output workflow debug` | Analyze execution trace |
|
|
42
|
+
|
|
43
|
+
## Temporal UI
|
|
44
|
+
|
|
45
|
+
For visual workflow inspection and detailed execution timelines, access the Temporal Web UI at:
|
|
46
|
+
|
|
47
|
+
**http://localhost:8080**
|
|
48
|
+
|
|
49
|
+
The Temporal UI provides real-time visibility into workflow executions, event history, and task queues.
|
|
50
|
+
|
|
51
|
+
## Systematic Debugging Approach
|
|
52
|
+
|
|
53
|
+
### Step 1: Verify Infrastructure
|
|
54
|
+
Confirm Docker containers are running and services are active.
|
|
55
|
+
- **Skill**: `output-services-check`
|
|
56
|
+
|
|
57
|
+
### Step 2: Gather Evidence
|
|
58
|
+
List recent runs and identify the failing workflow ID.
|
|
59
|
+
- **Skills**: `output-workflow-runs-list`, `output-workflow-trace`
|
|
60
|
+
|
|
61
|
+
### Step 3: Analyze Trace
|
|
62
|
+
Examine the trace for error messages, failed steps, and I/O data.
|
|
63
|
+
- **Skill**: `output-workflow-trace`
|
|
64
|
+
|
|
65
|
+
### Step 4: Apply Fix
|
|
66
|
+
Match error symptoms to solutions and verify the fix.
|
|
67
|
+
- **Skills**: `output-error-*` (matched by symptoms)
|
|
68
|
+
|
|
69
|
+
## Example Interaction
|
|
70
|
+
|
|
71
|
+
**User**: "My workflow is failing but I don't know why. The run ID is abc123."
|
|
72
|
+
|
|
73
|
+
**Agent**: Let me help you debug this workflow. First, let's get the execution trace:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
output workflow debug abc123 --format json
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
This will show us exactly where the workflow failed and what error occurred. While I analyze the trace, you can also check the Temporal UI at http://localhost:8080 for a visual timeline of the execution.
|
|
80
|
+
|
|
81
|
+
**User**: "The trace shows an error about incompatible schemas in step 'processData'."
|
|
82
|
+
|
|
83
|
+
**Agent**: This is likely the Zod import source issue. Check your step file - you're probably importing `z` from `zod` instead of `@output.ai/core`. These create different schema instances that aren't compatible.
|
|
84
|
+
|
|
85
|
+
Change:
|
|
86
|
+
```typescript
|
|
87
|
+
import { z } from 'zod';
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
To:
|
|
91
|
+
```typescript
|
|
92
|
+
import { z } from '@output.ai/core';
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
After making this change, run the workflow again with `output workflow run <workflowName>` to verify the fix.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
*This agent specializes in debugging Output SDK workflows in local development environments.*
|
|
@@ -14,12 +14,12 @@ You are a Output SDK workflow planning specialist who follows structured XML-bas
|
|
|
14
14
|
Your workflow planning follows the structured process defined in `/plan_workflow` command with explicit numbered steps and validation checkpoints.
|
|
15
15
|
|
|
16
16
|
### Context Retrieval
|
|
17
|
-
Use the `context-fetcher` subagent to retrieve documentation only if not already in context:
|
|
17
|
+
Use the `workflow-context-fetcher` subagent to retrieve documentation only if not already in context:
|
|
18
18
|
- **Pre-Flight**: `.outputai/meta/pre_flight.md` - validation rules and smart defaults
|
|
19
19
|
- **Post-Flight**: `.outputai/meta/post_flight.md` - completion checklist
|
|
20
20
|
- **Existing Patterns**: `src/workflows/*/workflow.ts` - similar workflow patterns
|
|
21
21
|
|
|
22
|
-
Use the `prompt-writer` subagent for:
|
|
22
|
+
Use the `workflow-prompt-writer` subagent for:
|
|
23
23
|
- Creating and reviewing `.prompt` files
|
|
24
24
|
- Liquid.js template syntax guidance
|
|
25
25
|
- Provider/model configuration
|
|
@@ -64,7 +64,7 @@ Only request clarification for:
|
|
|
64
64
|
- Specify workerModule service usage
|
|
65
65
|
|
|
66
66
|
### 🏗️ Step 5-6: Prompt & Orchestration Planning
|
|
67
|
-
- Design LLM prompts with template variables (delegate to `prompt-writer` subagent for implementation)
|
|
67
|
+
- Design LLM prompts with template variables (delegate to `workflow-prompt-writer` subagent for implementation)
|
|
68
68
|
- Define workflow execution logic step-by-step
|
|
69
69
|
- Plan conditional logic and data flow
|
|
70
70
|
- Generate TypeScript code templates
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: prompt-writer
|
|
2
|
+
name: workflow-prompt-writer
|
|
3
3
|
description: Use this agent when writing, reviewing, or debugging LLM prompt files (.prompt). Specializes in Liquid.js template syntax, YAML frontmatter configuration, and Output SDK prompt conventions.
|
|
4
4
|
tools: Read, Write, Edit, Grep, Glob
|
|
5
5
|
model: sonnet
|
|
@@ -13,11 +13,11 @@ You are an Output SDK implementation expert who ensures workflow code follows be
|
|
|
13
13
|
|
|
14
14
|
## Context Retrieval
|
|
15
15
|
|
|
16
|
-
Use the `context-fetcher` subagent to efficiently retrieve:
|
|
16
|
+
Use the `workflow-context-fetcher` subagent to efficiently retrieve:
|
|
17
17
|
- **Existing Patterns**: Find similar implementations in `src/workflows/*/`
|
|
18
18
|
- **Project Conventions**: Check `.outputai/AGENTS.md` for project-specific rules
|
|
19
19
|
|
|
20
|
-
Use the `prompt-writer` subagent for:
|
|
20
|
+
Use the `workflow-prompt-writer` subagent for:
|
|
21
21
|
- Creating new `.prompt` files
|
|
22
22
|
- Reviewing or debugging prompt template syntax
|
|
23
23
|
- Understanding Liquid.js syntax and YAML frontmatter
|
|
@@ -25,7 +25,7 @@ Implement the workflow described in the plan document, following Output SDK patt
|
|
|
25
25
|
|
|
26
26
|
<process_flow>
|
|
27
27
|
|
|
28
|
-
<step number="1" name="plan_analysis" subagent="context-fetcher">
|
|
28
|
+
<step number="1" name="plan_analysis" subagent="workflow-context-fetcher">
|
|
29
29
|
|
|
30
30
|
### Step 1: Plan Analysis
|
|
31
31
|
|
|
@@ -122,7 +122,7 @@ export const stepName = step( {
|
|
|
122
122
|
|
|
123
123
|
</step>
|
|
124
124
|
|
|
125
|
-
<step number="4" name="prompt_templates" subagent="prompt-writer">
|
|
125
|
+
<step number="4" name="prompt_templates" subagent="workflow-prompt-writer">
|
|
126
126
|
|
|
127
127
|
### Step 4: Prompt Templates (if needed)
|
|
128
128
|
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
---
|
|
2
|
+
argument-hint: [problem-description-and-optional-workflow-id]
|
|
3
|
+
description: Debug Output SDK workflow issues
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
model: claude-opus-4-1
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Your task is to systematically debug an Output SDK workflow issue in a local development environment.
|
|
9
|
+
|
|
10
|
+
The first argument is a textual description of the problem you're experiencing. If you have a specific workflow ID, include it in your description.
|
|
11
|
+
|
|
12
|
+
Use the todo tool to track your progress through the debugging process.
|
|
13
|
+
|
|
14
|
+
# Debugging Process
|
|
15
|
+
|
|
16
|
+
## Overview
|
|
17
|
+
|
|
18
|
+
Follow a systematic approach to identify and resolve workflow execution issues: verify infrastructure, gather evidence, analyze traces, and apply targeted fixes.
|
|
19
|
+
|
|
20
|
+
<pre_flight_check>
|
|
21
|
+
EXECUTE: @.outputai/instructions/meta/pre_flight.md
|
|
22
|
+
</pre_flight_check>
|
|
23
|
+
|
|
24
|
+
<process_flow>
|
|
25
|
+
|
|
26
|
+
<step number="1" name="verify_services">
|
|
27
|
+
|
|
28
|
+
### Step 1: Verify Services Running
|
|
29
|
+
|
|
30
|
+
Before debugging, confirm that all required services are operational. The `output-services-check` skill provides comprehensive guidance.
|
|
31
|
+
|
|
32
|
+
<verification_commands>
|
|
33
|
+
```bash
|
|
34
|
+
# Check Docker containers are running
|
|
35
|
+
docker ps | grep output
|
|
36
|
+
|
|
37
|
+
# Verify Output services respond
|
|
38
|
+
curl -s http://localhost:3001/health || echo "API not responding"
|
|
39
|
+
|
|
40
|
+
# Check Temporal UI is accessible
|
|
41
|
+
curl -s http://localhost:8080 > /dev/null && echo "Temporal UI accessible" || echo "Temporal UI not accessible"
|
|
42
|
+
```
|
|
43
|
+
</verification_commands>
|
|
44
|
+
|
|
45
|
+
<decision_tree>
|
|
46
|
+
IF docker_not_running:
|
|
47
|
+
RUN: docker compose up -d
|
|
48
|
+
WAIT: for services to start (30-60 seconds)
|
|
49
|
+
IF output_dev_not_running:
|
|
50
|
+
RUN: output dev
|
|
51
|
+
WAIT: for services to initialize
|
|
52
|
+
IF all_services_running:
|
|
53
|
+
PROCEED: to step 2
|
|
54
|
+
</decision_tree>
|
|
55
|
+
|
|
56
|
+
**Expected State**:
|
|
57
|
+
- Docker containers for `output` are running
|
|
58
|
+
- API server responds at `http://localhost:3001`
|
|
59
|
+
- Temporal UI accessible at `http://localhost:8080`
|
|
60
|
+
|
|
61
|
+
</step>
|
|
62
|
+
|
|
63
|
+
<step number="2" name="list_workflow_runs">
|
|
64
|
+
|
|
65
|
+
### Step 2: List Workflow Runs
|
|
66
|
+
|
|
67
|
+
Identify the failing workflow execution by listing recent runs. The `output-workflow-runs-list` skill provides detailed filtering guidance.
|
|
68
|
+
|
|
69
|
+
<list_commands>
|
|
70
|
+
```bash
|
|
71
|
+
# List all recent workflow runs
|
|
72
|
+
output workflow runs list
|
|
73
|
+
|
|
74
|
+
# Filter by specific workflow type (if known)
|
|
75
|
+
output workflow runs list <workflowName>
|
|
76
|
+
|
|
77
|
+
# Get detailed JSON output for analysis
|
|
78
|
+
output workflow runs list --format json
|
|
79
|
+
|
|
80
|
+
# Limit results to most recent
|
|
81
|
+
output workflow runs list --limit 10
|
|
82
|
+
```
|
|
83
|
+
</list_commands>
|
|
84
|
+
|
|
85
|
+
<identification_criteria>
|
|
86
|
+
Look for:
|
|
87
|
+
- Status: FAILED or TERMINATED
|
|
88
|
+
- Recent timestamp matching when the issue occurred
|
|
89
|
+
- Workflow type matching the problem description
|
|
90
|
+
</identification_criteria>
|
|
91
|
+
|
|
92
|
+
<decision_tree>
|
|
93
|
+
IF user_provided_workflow_id:
|
|
94
|
+
USE: provided workflow ID
|
|
95
|
+
PROCEED: to step 3
|
|
96
|
+
IF failed_runs_found:
|
|
97
|
+
SELECT: most recent failed run
|
|
98
|
+
NOTE: workflow ID from output
|
|
99
|
+
PROCEED: to step 3
|
|
100
|
+
IF no_runs_found:
|
|
101
|
+
CHECK: workflow exists with `output workflow list`
|
|
102
|
+
IF workflow_not_found:
|
|
103
|
+
REPORT: workflow doesn't exist
|
|
104
|
+
SUGGEST: verify workflow name and location
|
|
105
|
+
ELSE:
|
|
106
|
+
SUGGEST: run the workflow with `output workflow run <name>`
|
|
107
|
+
</decision_tree>
|
|
108
|
+
|
|
109
|
+
</step>
|
|
110
|
+
|
|
111
|
+
<step number="3" name="debug_workflow" subagent="workflow-debugger">
|
|
112
|
+
|
|
113
|
+
### Step 3: Debug Specific Workflow
|
|
114
|
+
|
|
115
|
+
Retrieve and analyze the execution trace for the identified workflow. The `output-workflow-trace` skill provides analysis techniques.
|
|
116
|
+
|
|
117
|
+
<debug_commands>
|
|
118
|
+
```bash
|
|
119
|
+
# Display execution trace (text format)
|
|
120
|
+
output workflow debug <workflowId>
|
|
121
|
+
|
|
122
|
+
# Display full untruncated trace (JSON format) - recommended for detailed analysis
|
|
123
|
+
output workflow debug <workflowId> --format json
|
|
124
|
+
```
|
|
125
|
+
</debug_commands>
|
|
126
|
+
|
|
127
|
+
**Tip**: Use `--format json` for complete trace data without truncation.
|
|
128
|
+
|
|
129
|
+
<analysis_checklist>
|
|
130
|
+
1. Identify which step failed
|
|
131
|
+
2. Examine the error message and stack trace
|
|
132
|
+
3. Check input data passed to the failing step
|
|
133
|
+
4. Check output data from preceding steps
|
|
134
|
+
5. Look for patterns matching common error types
|
|
135
|
+
</analysis_checklist>
|
|
136
|
+
|
|
137
|
+
<temporal_ui_guidance>
|
|
138
|
+
For visual workflow inspection, open the Temporal Web UI at **http://localhost:8080**:
|
|
139
|
+
- Find your workflow execution by ID
|
|
140
|
+
- View the event history timeline
|
|
141
|
+
- Inspect individual step inputs and outputs
|
|
142
|
+
</temporal_ui_guidance>
|
|
143
|
+
|
|
144
|
+
</step>
|
|
145
|
+
|
|
146
|
+
<step number="4" name="suggest_fixes" subagent="workflow-quality">
|
|
147
|
+
|
|
148
|
+
### Step 4: Suggest Fixes
|
|
149
|
+
|
|
150
|
+
Based on the trace analysis, identify the error pattern and suggest targeted fixes. Claude will invoke the relevant error skill based on symptoms.
|
|
151
|
+
|
|
152
|
+
<error_matching>
|
|
153
|
+
|
|
154
|
+
| Symptom | Skill |
|
|
155
|
+
|---------|-------|
|
|
156
|
+
| "incompatible schema" errors, type errors | `output-error-zod-import` |
|
|
157
|
+
| Replay failures, inconsistent results | `output-error-nondeterminism` |
|
|
158
|
+
| Retries not working, errors swallowed | `output-error-try-catch` |
|
|
159
|
+
| Type errors, undefined properties at step boundaries | `output-error-missing-schemas` |
|
|
160
|
+
| Workflow hangs, determinism errors | `output-error-direct-io` |
|
|
161
|
+
| Untraced requests, axios errors | `output-error-http-client` |
|
|
162
|
+
|
|
163
|
+
</error_matching>
|
|
164
|
+
|
|
165
|
+
<decision_tree>
|
|
166
|
+
IF error_matches_known_pattern:
|
|
167
|
+
INVOKE: relevant error skill for detailed fix
|
|
168
|
+
ELSE:
|
|
169
|
+
CONSULT: workflow-quality subagent for additional patterns
|
|
170
|
+
SUGGEST: Manual trace inspection in Temporal UI
|
|
171
|
+
</decision_tree>
|
|
172
|
+
|
|
173
|
+
<verification>
|
|
174
|
+
After applying fix:
|
|
175
|
+
```bash
|
|
176
|
+
# Re-run the workflow to verify
|
|
177
|
+
output workflow run <workflowName> <input>
|
|
178
|
+
|
|
179
|
+
# Or start asynchronously and check result
|
|
180
|
+
output workflow start <workflowName> <input>
|
|
181
|
+
output workflow status <workflowId>
|
|
182
|
+
output workflow result <workflowId>
|
|
183
|
+
```
|
|
184
|
+
</verification>
|
|
185
|
+
|
|
186
|
+
</step>
|
|
187
|
+
|
|
188
|
+
</process_flow>
|
|
189
|
+
|
|
190
|
+
<post_flight_check>
|
|
191
|
+
EXECUTE: @.outputai/instructions/meta/post_flight.md
|
|
192
|
+
</post_flight_check>
|
|
193
|
+
|
|
194
|
+
---- START ----
|
|
195
|
+
|
|
196
|
+
Problem Description and Optional Workflow ID:
|
|
197
|
+
|
|
198
|
+
$ARGUMENTS
|
|
@@ -25,7 +25,7 @@ Generate detailed specifications for implementation of a new workflow.
|
|
|
25
25
|
|
|
26
26
|
<process_flow>
|
|
27
27
|
|
|
28
|
-
<step number="1" name="context_gathering" subagent="context-fetcher">
|
|
28
|
+
<step number="1" name="context_gathering" subagent="workflow-context-fetcher">
|
|
29
29
|
|
|
30
30
|
### Step 1: Context Gathering
|
|
31
31
|
|
|
@@ -130,7 +130,7 @@ export const sumValues = step( {
|
|
|
130
130
|
|
|
131
131
|
</step>
|
|
132
132
|
|
|
133
|
-
<step number="5" name="prompt_engineering" subagent="prompt-writer">
|
|
133
|
+
<step number="5" name="prompt_engineering" subagent="workflow-prompt-writer">
|
|
134
134
|
|
|
135
135
|
### Step 5: Prompt Engineering
|
|
136
136
|
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: output-error-direct-io
|
|
3
|
+
description: Fix direct I/O in Output SDK workflow functions. Use when workflow hangs, returns undefined, shows "workflow must be deterministic" errors, or when HTTP/API calls are made directly in workflow code.
|
|
4
|
+
allowed-tools: [Bash, Read]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Fix Direct I/O in Workflow Functions
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
This skill helps diagnose and fix a critical error pattern where I/O operations (HTTP calls, database queries, file operations) are performed directly in workflow functions instead of in steps. This violates Temporal's determinism requirements.
|
|
12
|
+
|
|
13
|
+
## When to Use This Skill
|
|
14
|
+
|
|
15
|
+
You're seeing:
|
|
16
|
+
- Workflow hangs indefinitely
|
|
17
|
+
- Undefined or empty responses
|
|
18
|
+
- "workflow must be deterministic" errors
|
|
19
|
+
- Network operations failing silently
|
|
20
|
+
- Timeouts without clear cause
|
|
21
|
+
|
|
22
|
+
## Root Cause
|
|
23
|
+
|
|
24
|
+
Workflow functions must be **deterministic** - they should only orchestrate steps, not perform I/O directly. When you make HTTP calls, database queries, or any external operations directly in a workflow function:
|
|
25
|
+
|
|
26
|
+
1. **Hangs**: The workflow may hang because I/O isn't properly handled
|
|
27
|
+
2. **Determinism violations**: Temporal replays workflows, and I/O results differ
|
|
28
|
+
3. **No retry logic**: Direct calls bypass Output SDK's retry mechanisms
|
|
29
|
+
4. **No tracing**: Operations aren't recorded in the workflow trace
|
|
30
|
+
|
|
31
|
+
## Symptoms
|
|
32
|
+
|
|
33
|
+
### Direct fetch/axios in Workflow
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
// WRONG: I/O directly in workflow
|
|
37
|
+
export default workflow({
|
|
38
|
+
fn: async (input) => {
|
|
39
|
+
const response = await fetch('https://api.example.com/data'); // BAD!
|
|
40
|
+
const data = await response.json();
|
|
41
|
+
return { data };
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Direct Database Calls
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
// WRONG: Database I/O in workflow
|
|
50
|
+
export default workflow({
|
|
51
|
+
fn: async (input) => {
|
|
52
|
+
const user = await db.users.findById(input.userId); // BAD!
|
|
53
|
+
return { user };
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### File System Operations
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
// WRONG: File I/O in workflow
|
|
62
|
+
import fs from 'fs/promises';
|
|
63
|
+
|
|
64
|
+
export default workflow({
|
|
65
|
+
fn: async (input) => {
|
|
66
|
+
const data = await fs.readFile(input.path, 'utf-8'); // BAD!
|
|
67
|
+
return { data };
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Solution
|
|
73
|
+
|
|
74
|
+
Move ALL I/O operations to step functions. Steps are designed to handle non-deterministic operations.
|
|
75
|
+
|
|
76
|
+
### Before (Wrong)
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
export default workflow({
|
|
80
|
+
fn: async (input) => {
|
|
81
|
+
const response = await fetch('https://api.example.com/data');
|
|
82
|
+
const data = await response.json();
|
|
83
|
+
return { data };
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### After (Correct)
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
import { z, step, workflow } from '@output.ai/core';
|
|
92
|
+
import { httpClient } from '@output.ai/http';
|
|
93
|
+
|
|
94
|
+
// Create a step for the I/O operation
|
|
95
|
+
export const fetchData = step({
|
|
96
|
+
name: 'fetchData',
|
|
97
|
+
inputSchema: z.object({
|
|
98
|
+
endpoint: z.string(),
|
|
99
|
+
}),
|
|
100
|
+
outputSchema: z.object({
|
|
101
|
+
data: z.unknown(),
|
|
102
|
+
}),
|
|
103
|
+
fn: async (input) => {
|
|
104
|
+
const client = httpClient({ prefixUrl: 'https://api.example.com' });
|
|
105
|
+
const data = await client.get(input.endpoint).json();
|
|
106
|
+
return { data };
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// Workflow only orchestrates steps
|
|
111
|
+
export default workflow({
|
|
112
|
+
inputSchema: z.object({}),
|
|
113
|
+
outputSchema: z.object({ data: z.unknown() }),
|
|
114
|
+
fn: async (input) => {
|
|
115
|
+
const result = await fetchData({ endpoint: 'data' });
|
|
116
|
+
return result;
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Complete Example: Database Operation
|
|
122
|
+
|
|
123
|
+
### Before (Wrong)
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
export default workflow({
|
|
127
|
+
fn: async (input) => {
|
|
128
|
+
const user = await prisma.user.findUnique({
|
|
129
|
+
where: { id: input.userId }
|
|
130
|
+
});
|
|
131
|
+
const orders = await prisma.order.findMany({
|
|
132
|
+
where: { userId: input.userId }
|
|
133
|
+
});
|
|
134
|
+
return { user, orders };
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### After (Correct)
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
import { z, step, workflow } from '@output.ai/core';
|
|
143
|
+
import { prisma } from '../lib/db';
|
|
144
|
+
|
|
145
|
+
export const fetchUser = step({
|
|
146
|
+
name: 'fetchUser',
|
|
147
|
+
inputSchema: z.object({ userId: z.string() }),
|
|
148
|
+
outputSchema: z.object({
|
|
149
|
+
user: z.object({
|
|
150
|
+
id: z.string(),
|
|
151
|
+
name: z.string(),
|
|
152
|
+
email: z.string(),
|
|
153
|
+
}).nullable(),
|
|
154
|
+
}),
|
|
155
|
+
fn: async (input) => {
|
|
156
|
+
const user = await prisma.user.findUnique({
|
|
157
|
+
where: { id: input.userId }
|
|
158
|
+
});
|
|
159
|
+
return { user };
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
export const fetchOrders = step({
|
|
164
|
+
name: 'fetchOrders',
|
|
165
|
+
inputSchema: z.object({ userId: z.string() }),
|
|
166
|
+
outputSchema: z.object({
|
|
167
|
+
orders: z.array(z.object({
|
|
168
|
+
id: z.string(),
|
|
169
|
+
total: z.number(),
|
|
170
|
+
})),
|
|
171
|
+
}),
|
|
172
|
+
fn: async (input) => {
|
|
173
|
+
const orders = await prisma.order.findMany({
|
|
174
|
+
where: { userId: input.userId }
|
|
175
|
+
});
|
|
176
|
+
return { orders };
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
export default workflow({
|
|
181
|
+
inputSchema: z.object({ userId: z.string() }),
|
|
182
|
+
outputSchema: z.object({
|
|
183
|
+
user: z.unknown(),
|
|
184
|
+
orders: z.array(z.unknown()),
|
|
185
|
+
}),
|
|
186
|
+
fn: async (input) => {
|
|
187
|
+
const { user } = await fetchUser({ userId: input.userId });
|
|
188
|
+
const { orders } = await fetchOrders({ userId: input.userId });
|
|
189
|
+
return { user, orders };
|
|
190
|
+
},
|
|
191
|
+
});
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Finding Direct I/O in Workflows
|
|
195
|
+
|
|
196
|
+
Search for common I/O patterns in workflow files:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
# Find fetch calls
|
|
200
|
+
grep -rn "await fetch" src/workflows/
|
|
201
|
+
|
|
202
|
+
# Find axios calls
|
|
203
|
+
grep -rn "axios\." src/workflows/
|
|
204
|
+
|
|
205
|
+
# Find database operations
|
|
206
|
+
grep -rn "prisma\.\|db\.\|mongoose\." src/workflows/
|
|
207
|
+
|
|
208
|
+
# Find file system operations
|
|
209
|
+
grep -rn "fs\.\|readFile\|writeFile" src/workflows/
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Then review each match to see if it's in a workflow function vs a step function.
|
|
213
|
+
|
|
214
|
+
## What CAN Be in Workflow Functions
|
|
215
|
+
|
|
216
|
+
Workflow functions should contain:
|
|
217
|
+
- **Step calls**: `await myStep(input)`
|
|
218
|
+
- **Orchestration logic**: conditionals, loops (over step calls)
|
|
219
|
+
- **Data transformation**: Pure functions on step results
|
|
220
|
+
- **Constants**: Static values and configuration
|
|
221
|
+
|
|
222
|
+
Workflow functions should NOT contain:
|
|
223
|
+
- HTTP/API calls
|
|
224
|
+
- Database operations
|
|
225
|
+
- File system operations
|
|
226
|
+
- External service calls
|
|
227
|
+
- Anything that talks to the network or filesystem
|
|
228
|
+
|
|
229
|
+
## Verification
|
|
230
|
+
|
|
231
|
+
After moving I/O to steps:
|
|
232
|
+
|
|
233
|
+
1. **Run the workflow**: `output workflow run <name> '<input>'`
|
|
234
|
+
2. **Check the trace**: `output workflow debug <id> --format json`
|
|
235
|
+
3. **Verify steps appear**: Look for your I/O steps in the trace
|
|
236
|
+
4. **Confirm no errors**: No determinism warnings or hangs
|
|
237
|
+
|
|
238
|
+
## Benefits of Steps for I/O
|
|
239
|
+
|
|
240
|
+
1. **Retry logic**: Steps can be retried on failure
|
|
241
|
+
2. **Tracing**: I/O operations appear in workflow traces
|
|
242
|
+
3. **Timeouts**: Steps can have individual timeouts
|
|
243
|
+
4. **Determinism**: Replays use recorded results
|
|
244
|
+
5. **Debugging**: Clear visibility into what happened
|
|
245
|
+
|
|
246
|
+
## Related Issues
|
|
247
|
+
|
|
248
|
+
- For HTTP client best practices, see `output-error-http-client`
|
|
249
|
+
- For non-determinism from other causes, see `output-error-nondeterminism`
|