4.0 KiB
4.0 KiB
Quick Reference: Action Output Formats
TL;DR
Actions can specify how their stdout should be parsed:
text(default): No parsing, raw stdout onlyjson: Parse last line as JSONyaml: Parse entire output as YAMLjsonl: Parse each line as JSON, return array
Action Definition
name: my_action
output_format: json # text | json | yaml | jsonl
output_schema:
type: object # Use 'array' for jsonl
properties:
result: { type: string }
Format Behaviors
| Format | Parses | Result | Best For |
|---|---|---|---|
text |
Nothing | null |
Simple messages, logs |
json |
Last line | Object/Value | API responses, single results |
yaml |
Entire stdout | Object/Value | Configs, nested data |
jsonl |
Each line | Array | Lists, streaming, batches |
Examples
Text (no parsing)
echo "Hello, World!"
# Result: null (stdout captured separately)
JSON (last line)
echo "Processing..."
echo '{"status": 200, "data": "success"}'
# Result: {"status": 200, "data": "success"}
YAML (entire output)
cat <<EOF
version: 1.0
settings:
enabled: true
timeout: 30
EOF
# Result: {"version": "1.0", "settings": {...}}
JSONL (each line → array)
echo '{"id": 1, "name": "Alice"}'
echo '{"id": 2, "name": "Bob"}'
echo '{"id": 3, "name": "Charlie"}'
# Result: [{"id": 1, ...}, {"id": 2, ...}, {"id": 3, ...}]
Action Script Templates
Bash + JSON
#!/bin/bash
result=$(do_work)
echo "{\"result\": \"$result\", \"status\": \"ok\"}"
Python + JSON
#!/usr/bin/env python3
import json
result = do_work()
print(json.dumps({"result": result, "status": "ok"}))
Bash + JSONL
#!/bin/bash
for item in $(ls); do
size=$(stat -f%z "$item")
echo "{\"name\": \"$item\", \"size\": $size}"
done
Python + JSONL
#!/usr/bin/env python3
import json
for item in get_items():
print(json.dumps({"id": item.id, "value": item.value}))
Common Patterns
Informational + Result (JSON)
echo "Starting process..." >&2 # Log to stderr
echo "Processing 100 items..." >&2
echo '{"processed": 100, "errors": 0}' # JSON on last line
Mixed Output (JSONL)
echo "Scanning directory..." >&2 # Non-JSON ignored
echo '{"file": "a.txt", "size": 1024}' # Valid JSON
echo "Found 2 files" >&2 # Non-JSON ignored
echo '{"file": "b.txt", "size": 2048}' # Valid JSON
Execution Result Structure
{
"exit_code": 0,
"succeeded": true,
"duration_ms": 142,
"stdout": "raw output here",
"stderr": "logs here",
"data": { /* parsed result based on output_format */ }
}
Best Practices
✅ DO
- Use
textfor simple logging/messages - Use
jsonfor structured single results - Use
jsonlfor lists and batches - Write one JSON object per line (no pretty-print)
- Log to stderr, output to stdout
- Use non-zero exit codes for failures
❌ DON'T
- Mix error messages in stdout (use stderr)
- Pretty-print JSON across multiple lines
- Assume parsing will always succeed
- Use
jsonlwithouttype: arrayin schema
Troubleshooting
No result parsed?
- Check exit code is 0
- Verify JSON is on last line (
json) - Ensure one JSON per line (
jsonl) - Check for syntax errors in output
- Parsing failures don't cause execution failure
JSONL returning empty array?
- Check each line is valid JSON
- Ensure no trailing empty lines
- Invalid lines are silently skipped
Result is null but expected data?
- Verify
output_formatmatches output - Check stdout contains expected format
- Parsing is best-effort (no errors thrown)
Database
-- Check action output format
SELECT ref, output_format FROM action WHERE ref = 'core.http_request';
-- Update action output format
UPDATE action SET output_format = 'jsonl' WHERE ref = 'mypack.myaction';