Author a workflow
On this page
Build a small greeting workflow to learn the complete authoring cycle: declare its contract, write its behavior, build it, and inspect the result. This example makes no model requests and uses no external tools.
Complete Getting started first. Run the commands below from your chosen workspace, not from inside the workflow directory.
Create the workflow files
Check existing names with stratos list. If greet is already present, use
another name consistently rather than overwrite it. For a new greet workflow:
mkdir -p .stratos/workflows/greet
Create .stratos/workflows/greet/workflow.yaml:
name: greet
shortDescription: Greet a person, optionally in uppercase.
longDescription: |
Supply a nonempty name. Set loud to true for an uppercase greeting.
Returns message; no credentials or external calls are needed.
Example input: {"name":"Ada"} returns {"message":"Hello, Ada!"}.
version: "1"
The manifest provides the discoverable name, two descriptions, and a string version.
Agent, tool, and telemetry configuration can be added here later. The default
entrypoint is workflow.ts; the manifest’s optional entrypoint field selects
another file inside the same directory.
Both descriptions must be nonblank. Keep shortDescription to one paragraph:
target 150-300 characters, with a hard limit of 400 Unicode code points.
Use longDescription for Markdown usage instructions and relevant prerequisites,
input conventions, side effects, and retry gotchas. Its hard limit is 12,000
Unicode code points, excluding schemas; 300-800 words is a target only when
needed. Simple workflows need less. Spaces and line breaks count toward limits.
Use YAML >- to fold a short description’s source lines.
Breaking migration: the old manifest description field is rejected.
Replace it with both fields and write the manual; there is no automatic split
or truncation. This does not change Zod’s field descriptions. See the
description contract.
Create .stratos/workflows/greet/workflow.ts:
import {workflow} from '@stratoscli/stratos';
import {z} from 'zod';
export default workflow({
input: z.strictObject({
name: z.string().min(1).describe('Person to greet'),
loud: z.boolean().default(false).describe('Use uppercase'),
}),
output: z.strictObject({
message: z.string().describe('The greeting'),
}),
run(input) {
const message = `Hello, ${input.name}!`;
console.info('Greeting prepared');
return {message: input.loud ? message.toUpperCase() : message};
},
});
workflow(...) connects three things. input describes accepted values;
output describes a successful result; run performs the work. Zod supplies
runtime validation and TypeScript inference from the same declarations, so
input.name is already typed as a string. Stratos also exposes these
declarations as JSON Schema for callers.
Here, name must be nonempty and an omitted loud becomes false.
z.strictObject rejects unknown fields rather than silently ignoring typos.
Both public schemas describe objects, and every field has a description.
See the schema rules for nested objects,
defaults, and JSON-compatible constraints.
Keep actions inside run. Preparation loads the module to inspect its
definition, so model requests, tool calls, and other side effects must not run
at module scope. run can be synchronous, as above, or async when it awaits
agents, tools, or child workflows.
Build and inspect the contract
stratos build greet
stratos list --json
stratos describe greet --json
The build prepares dependencies, checks types and schemas, and compiles the
workflow. Stratos supplies the compiler settings and shared SDK; do not create
a tsconfig.json or install a second workflow-local Stratos SDK. Declare other
npm dependencies in the workflow’s package.json when needed.
describe puts the workflow name, version, both descriptions, inputSchema,
and outputSchema inside its JSON result’s data field. Use
stratos schema greet --json for schemas alone. Agents select from list,
then fetch describe when the current manual/schema is not already available.
Neither inspection command invokes run, but preparation can install
dependencies, connect to MCP servers and evaluate modules. A successful build
establishes that the contract and code pass these checks, not that an arbitrary
workflow’s behavior is correct.
Run and check the result
stratos run greet --input '{"name":"Ada"}' --json
stratos run greet --input '{"name":"Ada","loud":true}' --json
The first command returns {"message":"Hello, Ada!"} in data; the second
returns {"message":"HELLO, ADA!"}. The Greeting prepared log goes to stderr
and the local run log, leaving JSON stdout available for scripts.
All JSON commands use the same envelope: success, message, and optional
data, errors, and warnings. Success exits with code 0; a failed
validation or execution exits with code 1. Without --json, run prints
the workflow’s output directly. See CLI output
for the full format.
Check a failure too. This input deliberately misspells the option and should
be rejected before run executes:
stratos run greet --input '{"name":"Ada","lodu":true}' --json
Correct the caller’s input rather than relax the contract to hide the error.
After changing workflow code, build and rerun representative cases.
describe, schema and run also rebuild automatically when required artifacts are stale.
Inspect a run
Each top-level run writes run.json, run.log, and events.jsonl under
~/.stratos/runs/, grouped by the invocation directory. This example emits
a console log but no agent events, so an empty events.jsonl is expected.
Trace export is optional and configured separately.
Use Telemetry to find the matching workspace and run, configure traces, or adjust retention. Build failures are reported by the CLI; they are not successful workflow runs.
Reuse and share the workflow
Another workflow can call greet through a generated, typed wrapper rather
than copying its implementation. Continue with
Compose workflows to greet several people
from a parent workflow.
Commit the authored manifest, TypeScript, prompts, and any dependency
manifests/lockfiles. Generated wrappers, compiled dist/ files, and installed
dependencies are local build products. Stratos adds scoped ignore rules for
them; do not commit run artifacts or credentials.
To regenerate artifacts, use stratos clean greet, then build again. Cleanup
preserves the authored files, dependencies, and credentials, and invalidates
dependent builds. It is not a command for deleting the workflow.