Skip to content

Commit b1983f1

Browse files
committed
Add YAML workflow language and execution
1 parent 02e4c99 commit b1983f1

9 files changed

Lines changed: 3725 additions & 132 deletions

File tree

doc/cheatsheet/en/03-tools.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,15 @@ beside the built-in ones. orangu connects; it does not launch them.
1919

2020
| Command | What it does |
2121
| --- | --- |
22-
| `[mcp.<name>]` | A service in `orangu.conf`: its URL (usually ending in `/mcp`), `timeout`, `enabled`, `required`, `enabled_tools` / `disabled_tools`. |
23-
| `approval_mode = auto` | Or `prompt` (ask per call), `writes` (ask unless the tool is read-only), `deny`. Unattended and review runs deny what needs asking. |
24-
| `/mcp` `/mcp refresh` | What is connected, disabled or failed, and how many tools each gave; reconnect and rediscover. |
25-
| `/mcp add <name> <command>` | Write a profile and connect it; `/mcp remove <name>` drops it. |
26-
| `mcp__<server>__<tool>` | How they are named, so nothing collides; `/tools` lists them. Tools only. |
22+
| `[mcp.<name>]` | A configured Streamable HTTP service; URL, filters and approval are in `orangu.conf`. |
23+
| `/mcp` `/mcp refresh` | Show and reconnect; `/mcp add` / `remove` manage one. `/tools` lists `mcp__<server>__<tool>`. |
24+
25+
## Workflow files
26+
27+
| Command | What it does |
28+
| --- | --- |
29+
| `orangu --workflow run.yaml --dry-run` / `--workflow run.yaml` | Validate every job without executing; then run the jobs in order. |
30+
| `orangu --workflow run.yaml` `status` `pause` `resume` `clear` | Run a workflow, or inspect/pause/resume/clear its saved job state. |
2731

2832
## The rest of the stack
2933

doc/manual/en/40-terminal.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ The sync runs in the background so it never delays startup. Its progress and res
2222
| `-a` | `--all` | Reopen the workspace tabs that were open at the end of the last run. |
2323
| `-t` | `--theme` | Apply a theme to the terminal interface for this run. Built-in names and paths to `.theme` files are accepted. |
2424
| `-p` | `--prompt` | Run a single prompt or command and exit — no terminal UI and no session on disk. See One-shot mode below. |
25-
| `-q` | `--quiet` | Print nothing on success — the exit code is the result. Applies to the modes that print and exit (`-p`, `-l`, `-s`). |
25+
| | `--workflow FILE` | Validate and execute every job in a YAML workflow. |
26+
| | `--dry-run FILE` | Validate a YAML workflow completely without executing it or loading configuration. |
27+
| `-q` | `--quiet` | Print nothing on success — the exit code is the result. Applies to the modes that print and exit, including workflows. |
2628
| `-l` | `--list` | List all stored sessions as a `SESSION WORKSPACE BRANCH DATE` table and exit. |
2729
| `-i` | `--init` | Interactively create `~/.orangu/orangu.conf` and exit (see the Configuration chapter). |
2830
| `-s` | `--shell-completions` | Print the shell completion script for the detected shell (`$SHELL`; bash, zsh, or fish) and exit. |
@@ -56,7 +58,7 @@ orangu -q -p "/export pr" # writes the PDF, says nothing
5658
echo $? # 0, or 1 with the reason on stderr
5759
```
5860

59-
That is what makes it suit a crontab or a `~/.orangu/schedule` job: silent until the day it fails. It applies to the modes that print and exit — `-p`, `-l`, and `-s`. Combining it with `-i` or with the terminal interface is an error rather than a no-op, since neither has diagnostics to separate from its output.
61+
That is what makes it suit a crontab or a `~/.orangu/schedule` job: silent until the day it fails. It applies to the modes that print and exit — `-p`, `-l`, `-s`, and `--workflow` (including `--dry-run`). Combining it with `-i` or with the terminal interface is an error rather than a no-op, since neither has diagnostics to separate from its output.
6062

6163
`-t`/`--theme` is the other way round: a theme paints the interface — including the terminal's own background and foreground — so it takes effect only when there is an interface. A one-shot ignores it rather than repainting the terminal it printed into.
6264

doc/manual/en/45-workflows.md

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
\newpage
2+
3+
# Workflow files
4+
5+
A workflow file describes a set of jobs and the ordered Orangu operations to
6+
run in each workspace. It is a thin YAML layer over the same slash commands,
7+
natural-language prompts, skills, and tools available through `orangu -p`.
8+
9+
Validate the complete file before starting it:
10+
11+
```text
12+
orangu --workflow export-prs.yaml --dry-run
13+
orangu --workflow export-prs.yaml
14+
```
15+
16+
`--workflow --dry-run` loads no model configuration and executes nothing. It checks
17+
every job, workspace, variable, function call, approval, loop definition, and
18+
explicit slash command. `--workflow` performs the same preflight before it
19+
loads configuration or starts the first job.
20+
21+
## Complete file
22+
23+
The following workflow runs `/export pr` in two projects and collects both
24+
PDFs in one explicitly approved directory:
25+
26+
```yaml
27+
orangu:
28+
version: 1
29+
role: all
30+
variables:
31+
upstream: /home/me/Upstream
32+
jobs:
33+
- job: pgagroal
34+
workspace: /home/me/PostgreSQL/pgagroal
35+
- job: orangu
36+
workspace: /home/me/Company/orangu
37+
functions:
38+
export_pr:
39+
- command: /export pr
40+
move_pdf:
41+
- command: /shell mv ${job}-pr.pdf ${upstream}/
42+
main:
43+
- approved: ${upstream}
44+
- call: export_pr
45+
- call: move_pdf
46+
```
47+
48+
The root key is `orangu`. `version` is required and is currently `1`. `jobs`
49+
and `main` must both be non-empty. Unknown keys are errors rather than ignored
50+
configuration.
51+
52+
## Jobs, roles, and conversations
53+
54+
Each `jobs` entry requires a unique `job` name and an existing `workspace`
55+
directory. Jobs run sequentially in declaration order and stop at the first
56+
failure. The complete `main` sequence runs once for every job, with `${job}`
57+
set to that job's name.
58+
59+
`role` may be declared once under `orangu` or overridden by a job. It defaults
60+
to `all`; the other v1 values are `code`, `review`, `explorer`, and
61+
`embeddings`. When the configured endpoint is an Orangu coordinator, the role
62+
is sent to it for routing. Otherwise Orangu selects a configured server with
63+
that role, falling back to the default server.
64+
65+
Command steps that reach the model share one conversation within their job.
66+
The next job starts a separate conversation in its own workspace.
67+
68+
## Variables
69+
70+
Top-level `variables` apply to every job. A job may add variables or override a
71+
top-level value:
72+
73+
```yaml
74+
variables:
75+
profile: release
76+
jobs:
77+
- job: server
78+
workspace: server
79+
variables:
80+
profile: debug
81+
```
82+
83+
Values may be strings, integers, floating-point numbers, or booleans and are
84+
inserted with `${name}`. Variables may refer to other variables. `${job}` is
85+
reserved for the current job name and cannot be redefined. Undefined,
86+
recursive, malformed, or unterminated references fail validation.
87+
88+
## Functions and execution order
89+
90+
`functions` contains named, reusable lists of steps. A `call` expands a
91+
function at that exact position, so `main` is the single unambiguous execution
92+
order:
93+
94+
```yaml
95+
functions:
96+
build:
97+
- command: /build release
98+
explain:
99+
- command: Explain any build warnings and fix actionable ones.
100+
main:
101+
- call: build
102+
- call: explain
103+
```
104+
105+
Functions may call other functions. Unknown calls and direct or indirect
106+
recursion are validation errors. Function and variable names start with a
107+
letter or underscore and contain only letters, digits, and underscores.
108+
109+
## Step types
110+
111+
Version 1 has four explicit step types. A step contains exactly one of them.
112+
113+
### `command`
114+
115+
The value is offered to Orangu's existing dispatcher:
116+
117+
```yaml
118+
main:
119+
- command: /status
120+
- command: /code-review authentication
121+
- command: Investigate the failing authentication test and fix it.
122+
```
123+
124+
A built-in slash command runs locally, a workspace skill expands into a model
125+
prompt, and other text is a natural-language model prompt. Preflight rejects
126+
unknown slash commands, missing required arguments, and commands that require
127+
the interactive terminal or persistent terminal session.
128+
129+
### `call`
130+
131+
`call` inserts a named function's steps. Expansion happens separately for each
132+
job, after its variables and `${job}` have been resolved.
133+
134+
### `approved`
135+
136+
An external path supplied through a variable requires an earlier `approved`
137+
step. One path or a list of paths may be approved:
138+
139+
```yaml
140+
main:
141+
- approved:
142+
- ${reports}
143+
- ${archives}
144+
- command: /shell mv report.pdf ${reports}/
145+
```
146+
147+
Approved paths must already exist. Approval is ordered: placing it after the
148+
command does not authorize that command. It is an explicit workflow-language
149+
opt-in for passing a variable-derived external path; it does not widen the
150+
roots of Orangu's file tools.
151+
152+
File and directory tools reject absolute, `..`, and symlinked paths that leave
153+
the job workspace, and a tool's `cwd` must remain inside it. `/shell` explicitly
154+
invokes the user's platform shell and is not an operating-system sandbox.
155+
Literal shell syntax therefore retains the existing `/shell` semantics.
156+
157+
### `loop`
158+
159+
A loop repeats a tool-enabled work phase followed by an independent,
160+
tool-free review phase:
161+
162+
```yaml
163+
functions:
164+
improve_parser:
165+
- loop:
166+
objective: Fix ${job}'s parser without changing its public API.
167+
stop:
168+
type: goal
169+
condition: All parser tests pass and review finds no regression.
170+
review:
171+
checks:
172+
- cargo test
173+
rubric:
174+
- correctness
175+
- backward compatibility
176+
main:
177+
- call: improve_parser
178+
```
179+
180+
Every iteration gives the worker the objective and the previous review. After
181+
the work phase, Orangu runs the configured checks in the job workspace. The
182+
reviewer receives the worker report, check results, and branch diff, but no
183+
tools. Its response becomes feedback for the next iteration.
184+
185+
Each loop has exactly one stopping policy:
186+
187+
| `stop.type` | Required field | Meaning |
188+
| --- | --- | --- |
189+
| `turns` | `count` | Stop after a positive number of complete iterations. |
190+
| `time` | `duration` | Stop at a safe boundary after active time such as `30m` or `2h`. |
191+
| `goal` | `condition` | Continue until the reviewer verifies the stated condition. |
192+
193+
Durations use `s`, `m`, `h`, or `d`. Orangu never interrupts a tool call or
194+
review response merely because the duration has elapsed. For a goal loop, the
195+
reviewer must end with the exact standalone line `LOOP_COMPLETE: yes`; an
196+
inline mention or optimistic wording does not complete it.
197+
198+
`review.checks` and `review.rubric` are optional lists. Variables are expanded
199+
in the objective, stop value, checks, and rubric. The default rubric covers
200+
correctness, regressions, tests, and maintainability; listed entries add
201+
workflow-specific criteria.
202+
203+
## Managing a workflow
204+
205+
Loop progress is stored in Orangu's workspace cache rather than in the
206+
repository. The workflow file supplies the jobs and their workspaces; append a
207+
lifecycle action after the file to inspect or control the saved loop for every
208+
job:
209+
210+
```text
211+
orangu --workflow /path/to/workflow.yml status
212+
orangu --workflow /path/to/workflow.yml pause
213+
orangu --workflow /path/to/workflow.yml resume
214+
orangu --workflow /path/to/workflow.yml clear
215+
```
216+
217+
`status` reports the objective, policy, iteration count, active time, and most
218+
recent review for each job. `pause` stops an active loop at its next safe phase
219+
boundary. `resume` continues a paused or failed loop with its saved review
220+
feedback. `clear` cancels saved state so another loop may start. A
221+
per-workspace lock prevents two loops from running against the same checkout
222+
simultaneously.
223+
224+
## Operational behavior
225+
226+
- `-q` suppresses successful workflow output. Failures still write to stderr
227+
and return a non-zero exit status.
228+
- A loop can modify its workspace but does not commit, push, or open a pull
229+
request unless an explicit workflow command does so.
230+
- Review evidence is bounded before it is sent to the model. Truncation is
231+
marked rather than silently treated as complete evidence.
232+
- Saved loop state is control metadata, not a persisted model conversation.

0 commit comments

Comments
 (0)