Skip to content

Commit f883679

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

11 files changed

Lines changed: 3693 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 --check-workflow run.yaml` / `--workflow run.yaml` | Validate every job without executing; then run the jobs in order. |
30+
| `orangu -w DIR loop status` `pause` `resume` `clear` | Inspect, pause, continue, or cancel a workflow loop. |
2731

2832
## The rest of the stack
2933

doc/manual/en/40-terminal.md

Lines changed: 58 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+
| | `--check-workflow 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. |
@@ -47,6 +49,60 @@ Two groups of commands are refused rather than run, with a message saying which
4749

4850
`/export` covers the targets that are computed at export time: `pr`, `statistics`, and `duplicates`. `console`, `review`, and `auto review` export what an interactive session accumulated, and report that there is nothing to export.
4951

52+
### YAML workflows
53+
54+
`--workflow FILE` is a thin, ordered YAML layer over the same commands, natural-language prompts, skills, and tools used by one-shot mode. Orangu validates and expands the complete file before the first job starts. Jobs run in declaration order and stop at the first failure; prompts within one job share a conversation.
55+
56+
```yaml
57+
orangu:
58+
version: 1
59+
variables:
60+
upstream: /home/me/Upstream
61+
jobs:
62+
- job: pgagroal
63+
workspace: /home/me/PostgreSQL/pgagroal
64+
- job: orangu
65+
workspace: /home/me/Company/orangu
66+
role: code
67+
functions:
68+
export_pr:
69+
- command: /export pr
70+
move_pdf:
71+
- command: /shell mv ${job}-pr.pdf ${upstream}/
72+
main:
73+
- approved: ${upstream}
74+
- call: export_pr
75+
- call: move_pdf
76+
```
77+
78+
`role` may be set globally or per job and defaults to `all`. `${job}` is the current job key; top-level and per-job variables use the same `${name}` form. A job's workspace is a strict path boundary. An existing absolute path supplied through a variable must have an earlier `approved` step before a command can use it outside that workspace.
79+
80+
The boundary has the same meaning as it does elsewhere in Orangu: file and directory tools reject absolute paths and `..` paths that leave the workspace, and a tool's `cwd` must remain inside it. `approved` is an explicit workflow-language opt-in for passing a variable-derived external path to a command; it does not widen those tool roots. `/shell` explicitly invokes the user's platform shell and is therefore not an operating-system sandbox. The validator checks external paths supplied through variables, while literal shell syntax retains `/shell`'s existing semantics.
81+
82+
A function or `main` may also contain the bounded code-and-review `loop` step described in the next chapter. Top-level and job variables are expanded in its objective, duration or goal, checks, and rubric:
83+
84+
```yaml
85+
functions:
86+
improve_parser:
87+
- loop:
88+
objective: Fix ${job}'s parser without changing its public API.
89+
stop:
90+
type: goal
91+
condition: All parser tests pass and review finds no regression.
92+
review:
93+
checks:
94+
- cargo test
95+
rubric:
96+
- correctness
97+
- backward compatibility
98+
main:
99+
- call: improve_parser
100+
```
101+
102+
`stop.type` is `turns` with a positive `count`, `time` with a duration using `s`, `m`, `h`, or `d`, or `goal` with a reviewer-verifiable `condition`. A workflow loop uses the job's workspace and resolved role. Its saved state is the same state exposed by `orangu loop status`, `pause`, `resume`, and `clear`, so an interrupted workflow loop remains manageable from the CLI.
103+
104+
Run `orangu --check-workflow FILE` first when editing a workflow. It checks YAML structure, variables, function calls and recursion, roles, workspaces, approvals, and every job without contacting an LLM server. Explicit slash commands are also checked before execution: the name must be a built-in command or a skill discovered in that job's workspace, required arguments must be present, and commands that need the interactive terminal are refused. Relative workspace paths are resolved from the workflow file's directory.
105+
50106
### Quiet mode
51107

52108
`-q` prints nothing on success — no answer, no command output, no diagnostics — and leaves the exit code as the whole result. A failure still prints on stderr and exits non-zero, so `-q` can silence a success without ever hiding a problem:
@@ -56,7 +112,7 @@ orangu -q -p "/export pr" # writes the PDF, says nothing
56112
echo $? # 0, or 1 with the reason on stderr
57113
```
58114

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.
115+
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`, `--workflow`, and `--check-workflow`. 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.
60116

61117
`-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.
62118

doc/manual/en/45-workflows.md

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
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 --check-workflow export-prs.yaml
13+
orangu --workflow export-prs.yaml
14+
```
15+
16+
`--check-workflow` 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 loop
204+
205+
Loop progress is stored in Orangu's workspace cache rather than in the
206+
repository. The same lifecycle commands inspect or control a loop started by a
207+
workflow:
208+
209+
```text
210+
orangu --workspace /path/to/project loop status
211+
orangu --workspace /path/to/project loop pause
212+
orangu --workspace /path/to/project loop resume
213+
orangu --workspace /path/to/project loop clear
214+
```
215+
216+
`status` reports the objective, policy, iteration count, active time, and most
217+
recent review. `pause` stops at the next safe phase boundary. `resume`
218+
continues a paused or failed loop with its saved review feedback. `clear`
219+
cancels the saved state so another loop may start. A per-workspace lock prevents
220+
two loops from running against the same checkout simultaneously.
221+
222+
## Operational behavior
223+
224+
- `-q` suppresses successful workflow output. Failures still write to stderr
225+
and return a non-zero exit status.
226+
- A loop can modify its workspace but does not commit, push, or open a pull
227+
request unless an explicit workflow command does so.
228+
- Review evidence is bounded before it is sent to the model. Truncation is
229+
marked rather than silently treated as complete evidence.
230+
- Saved loop state is control metadata, not a persisted model conversation.

0 commit comments

Comments
 (0)