Unix pipes for AI workflows. Define reusable tasks and linear pipelines in one
orcha.yaml file; execute them with one command.
Orcha is a single-binary Go program, that helps developers, create their own automated DAG pipelines, with ease. Managing multiple tasks with one call! say bye to repetitve:
- file operation.
- API calls.
- HTTP requests.
Instead design your pipeline as a chad, run one command.
# orcha.yaml
tasks:
read-article:
type: file
path: "{{$input}}"
summarize:
type: ai
provider: openai
prompt: "Summarize in three bullet points:\n\n{{$input}}"
save:
type: file
operation: write
path: "./summary.txt"
content: "{{$input}}"
pipelines:
summarize-article:
steps:
- task: read-article
- task: summarize
- task: save$ export OPENAI_API_KEY=sk-...
$ orcha run summarize-article -f ./article.txt
> read-article ...
+ read-article (1ms)
> summarize ...
+ summarize (920ms)
> save ...
+ save (0ms)
-- done in 921ms
./summary.txtPick whichever ecosystem you live in — both ship the same Go engine.
# Python — thin wrapper around the single binary.
pip install orcha-dev
# Node — same wrapper for JS/TS callers
npm install orcha-devThe first time you run orcha, it downloads a small Go binary to
~/.orcha/bin/, that's compatible with the system's OS & architecture and verifies its sha256. Subsequent runs are zero-network.
Create a file called orcha.yaml:
tasks:
greet:
type: ai
provider: openai
prompt: "Say hello to {{$input}} in one sentence."
pipelines:
hi:
steps:
- task: greetThen:
export OPENAI_API_KEY=sk-...
orcha run hi -i "the world"# Run a pipeline; pretty progress on stderr, final result on stdout.
orcha run <pipeline> [-y orcha.yaml] [-i STR | -f FILE] [--json]
# Print version.
orcha versionInput precedence: -i (inline string) → -f (file content) → stdin.
--json swaps pretty progress for a JSON-line event stream — handy for piping
into jq or another tool.
from orcha import Orcha
o = Orcha("./orcha.yaml")
# Stream events as the pipeline runs.
for event in o.run("summarize-article", "./article.txt"):
print(event.type, event.task, event.elapsed_ms)
# Or get just the final output.
result = o.run_sync("summarize-article", "./article.txt")import { Orcha } from "orcha-dev";
const orcha = await Orcha.create("./orcha.yaml");
// Stream events as the pipeline runs.
for await (const event of orcha.run("summarize-article", "./article.txt")) {
console.log(event.type, event.task, event.elapsed_ms);
}
// Or get just the final output.
const result = await orcha.runToCompletion("summarize-article", "./article.txt");orcha/
├── cmd/
│ ├── orcha/ # production IPC binary (consumed by the Python SDK)
│ ├── orcha-run/ # user-facing Go CLI driver
│ └── orcha-debug/ # developer debug entry point
├── pkg/
│ ├── provider.go # Provider plugin interface (Name, DefaultModel, Complete)
│ ├── registry.go # global provider registry + env-var key resolution
│ ├── openai/ # built-in OpenAI provider (REST, no SDK dependency)
│ ├── anthropic/ # built-in Anthropic Messages provider
│ └── deepseek/ # built-in DeepSeek provider (OpenAI-compatible)
├── internal/
│ ├── parser/ # YAML loader, schema validation, type-flow check
│ ├── engine/ # executor, value types, $input/$env interpolation
│ ├── runners/ # ai, http, file task runners
│ └── ipc/ # JSON-line stdin/stdout protocol
├── python/
│ └── orcha/ # Python SDK + `orcha` shell command
├── npm/
│ ├── bin/orcha.js # Node CLI shim (mirrors the Python `orcha` script)
│ └── lib/ # JS/TS programmatic API + binary downloader
├── examples/ # sample workflows and inputs
└── tools/ # build helpers (manifest generation, etc.)
Resolved from environment variables by convention:
| Provider | Variable |
|---|---|
openai |
OPENAI_API_KEY |
anthropic |
ANTHROPIC_API_KEY |
deepseek |
DEEPSEEK_API_KEY |
| custom | ORCHA_<NAME>_API_KEY |
Providers never read env vars directly — the registry passes the key into the
provider's Complete() call. Roll your own by implementing the Provider
interface and calling providers.Register().
| Type | Required fields | Defaulted fields |
|---|---|---|
ai |
provider, prompt |
model → provider's default; system → omitted; output_type → text |
http |
url |
method → GET; output_type → text |
file |
path |
operation → read; output_type → text (read) / filepath (write) |
Outputs of step N must be compatible with the input of step N+1. The check runs at parse time:
| → text | → json | → filepath | → list | |
|---|---|---|---|---|
| text → | OK | -- | OK | -- |
| json → | OK | OK | -- | -- |
| filepath → | OK | -- | OK | -- |
| list → | OK | -- | -- | OK |
The codebase is small on purpose. The Go engine is ~1k lines, the Python SDK is ~300 lines, and the wire protocol between them is one JSON object on stdin and one JSON object per line on stdout.
Run the full test suite:
go test ./...
( cd python && python -m pytest tests/ )
( cd npm && npm test ) # requires `make build` firstOpen issues and PRs at https://github.com/ryfoo/orcha.
Orcha is released under the MIT License. See LICENSE for the full text.
Built with gopkg.in/yaml.v3 and the
Go standard library.