Ocawe is a Crystal-first framework and runtime for Cawfile workflow bundles, agents, tools, skills, and OpenAI-compatible workflow execution.
Licenses: 0BSD (LICENSE).
It includes:
- A production-oriented HTTP runtime server
- A Svelte playground for workflows, tools, skills, and agent chat
- VitePress docs with a custom
/playground/route
Ocawe owns the workflow runtime framework and example Cawfiles. Deployment
library code, CI workflows, host modules, and Lefinepro production pipeline
packaging live outside this repository, primarily in sireng/ and the root
lefinepro workspace.
- Cawfile-first workflow framework with root-level multi-workflow bundles
@[Service]workflows that start with the runtime for tunnels, daemons, and watchers- Agent + skill + tool discovery from workflow directories
- Voice and RAG patterns through workflow DSL
- ACP execution for external agents through
exec ..., runtime: {acp: {...}} - Schema validation and guardrails in agent/workflow execution
- OpenAI-compatible chat completions, retrieval, and async task endpoints
Run with Nix:
git clone https://github.com/lefinepro/ocawe.git
cd ocawe
nix run . -- --help
nix run . -- up caws/01-simpleInstall with Nix:
nix profile install github:lefinepro/ocawe
ocawe --help
OCAWE_EXAMPLES="$(nix path-info github:lefinepro/ocawe#ocawe)/share/ocawe/caws"
ocawe up "$OCAWE_EXAMPLES/01-simple"The Nix package includes the CLI/runtime dependencies used by the distribution,
including Crystal build inputs, Git, Node.js, Ruby, SQLite, and Lua 5.4. It also
installs example Cawfiles and helper scripts under share/ocawe.
Install from GitHub Releases:
curl -fsSL https://github.com/lefinepro/ocawe/releases/latest/download/install.sh | bash
ocawe --helpInstall a specific release tag:
curl -fsSL https://github.com/lefinepro/ocawe/releases/download/2026.07.00/install.sh | OCAWE_VERSION=2026.07.00 bashInstall with mise from GitHub Releases:
mise use -g "github:lefinepro/ocawe[matching=ocawe-linux,bin_path=bin,filter_bins=ocawe]@latest"
ocawe --helpDeclarative mise.toml:
[tools]
"github:lefinepro/ocawe" = { version = "latest", matching = "ocawe-linux", bin_path = "bin", filter_bins = "ocawe" }Install CLI from source without Nix:
# Uses system Crystal if present; otherwise downloads Crystal into ./.tools/crystal.
source scripts/bootstrap-crystal.sh
crystal build src/cli/main.cr -o build/ocawe
./build/ocawe --helpOptional shell install:
mkdir -p ~/.local/bin
ln -sf "$PWD/build/ocawe" ~/.local/bin/ocawe
ocawe --helpIf ~/.local/bin is not in PATH, add it in your shell profile.
The bootstrap script downloads a platform Crystal archive into ./.tools/crystal
only when crystal is missing.
You can control bootstrap with env vars:
OCAWE_CRYSTAL_VERSION(default1.13.3)OCAWE_CRYSTAL_BASE_URL(default Crystal GitHub releases URL)OCAWE_CRYSTAL_FORCE_BOOTSTRAP=1(force local toolchain even if systemcrystalexists)OCAWE_CRYSTAL_VERBOSE=1(print toolchain version during bootstrap)
Run an example:
ocawe up caws/01-simplePull a remote Cawfile workflow:
ocawe pull git+https://github.com/lefinepro/ocawe/caws/10-acp-agent
ocawe pull git+ssh://github.com/lefinepro/ocawe/caws/10-acp-agentThe runtime reads Cawfile from the selected workflow directory or the current
directory. The port is configured there via settings do port = 4111 end.
Use Ocawe as a flake input:
{
inputs.ocawe.url = "github:lefinepro/ocawe";
outputs = { nixpkgs, ocawe, ... }: {
nixosConfigurations.host = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
ocawe.nixosModules.default
{
services.ocawe = {
enable = true;
port = 4111;
};
}
];
};
};
}By default the NixOS module declaratively installs packaged examples by linking
services.ocawe.workflowsRoot to ${package}/share/ocawe/caws when the path
does not already exist. Disable that with services.ocawe.installExamples =
false when you manage the workflows directory yourself.
Use the overlay:
{
nixpkgs.overlays = [ inputs.ocawe.overlays.default ];
environment.systemPackages = [ pkgs.ocawe ];
}Use with Home Manager:
{
imports = [ inputs.ocawe.homeManagerModules.default ];
programs.ocawe.enable = true;
}ocawe build --release
ocawe dev --port 4111
ocawe up # reads port from Cawfile
ocawe up caws/01-simple # run specific workflow
ocawe up -d caws/01-simple # background mode# explicit workflow trigger by id
ocawe workflow solver task=deploy env=prod
# agent/function/tool/skill/support triggers
ocawe agent code-reviewer --prompt "review this patch"
ocawe tool project_healthcheck
ocawe support onboarding-check
# alias executable style (workflow id from executable name)
ln -sf ./build/ocawe /usr/local/bin/ocawe_example_workflow
ocawe_example_workflowWorkflow trigger CLI calls POST /v1/triggers/workflows/:id and sends:
input.<key>fromkey=valueargs (values parsed as JSON when possible)input.argsfrom positional args without ===
Trigger command mapping:
workflow→/v1/triggers/workflows/:idagent→/v1/triggers/agents/:idskill=/=support→/v1/triggers/skills/:idfunction=/=tool→/v1/triggers/functions/:id
Use OCAWE_TRIGGER_BASE_URL or --base-url to target a non-default runtime URL.
GET /v1/workflowsPOST /v1/workflows/:workflowId/runsGET /v1/toolsGET /v1/skillsGET /v1/agentsPOST /v1/agents/:agentId/generateGET /v1/mcp/serversPOST /v1/mcp/serversGET /v1/mcp/catalogPOST /mcp
POST /v1/chat/completionsGET /v1/chat/completions/:completion_idPOST /v1/chat/completions/tasksGET /v1/chat/completions/tasks/:taskId
POST /actors/{identifier}/inbox(S2S inbound activities, signature-verified)GET /actors/{identifier}/outboxPOST /actors/{identifier}/outboxGET /federation/metadata(reported capabilities + supported FEPs from FEDERATION.md)GET /FEDERATION.md(repo interoperability manifest)
S2S ticket ingestion mode:
- follow remote actor and poll remote
outboxforCreate(Ticket)activities - require HTTP Signatures for federation requests
src/ cli/ # ocawe CLI (build/dev/up) framework/ # runtime framework + HTTP endpoints packages/ playground/ # Svelte playground (Vite + pnpm/Node.js) docs/ # VitePress docs and static playground route caws/ # workflow bundle examples 01-simple/ # minimal single agent 02-multi-agent/ # sequential agent pipeline 03-control-flow/ # if/else, parallel, while, until 04-rag-assistant/ # retrieval-augmented generation 05-voice-pipeline/ # voice transcription + synthesis 06-full-suite/ # all features combined, including container and service workflows 09-custom-agent/ # how to write custom agents 10-acp-agent/ # ACP-compatible external agent execution 11-git-https-pull/ # pull remote Cawfile bundles with git+https 12-api-nodes/ # HTTP API steps and step["name"] result access spec/ # Crystal specs
See caws/ directory for complete examples with Cawfile format.
Run any example:
ocawe up caws/01-simple
ocawe up -d caws/02-multi-agent # background mode
ocawe pull git+https://github.com/lefinepro/ocawe/caws/10-acp-agentEach example demonstrates a specific feature:
- 01-simple — minimal single agent setup
- 02-multi-agent — sequential agent pipeline
- 03-control-flow —
unless,if/else,parallel,while,until - 04-rag-assistant — RAG with vector store
- 05-voice-pipeline — voice transcription and synthesis
- 06-full-suite — all features combined, including container packaging and multiple
@[Service]workflows - 09-custom-agent — writing custom agents with external binaries
- 10-acp-agent — ACP-compatible external agent execution
- 11-git-https-pull — pulling remote Cawfile bundles with
git+https - 12-api-nodes — HTTP
get,post,putsteps withstep["name"]result access
Framework configuration uses Cawfile in the workflow root. A root Cawfile
can define runtime settings, Crystal structs, annotations, and multiple
workflow blocks. Directory-local Cawfile files are preferred for bundles;
*.acd.cr files are still supported as legacy/single-workflow fallback.
Example Cawfile:
settings do
port = 4111
datasets.adapter = "sqlite"
end
container do
packages = ["git", "curl"]
files = ["agents", "skills", "tools"]
end
# Federation is enabled by including Api::Federation types
struct Input
include Api::Federation::Inbox
end
struct Output
include Api::Federation::Outbox
end
@[Model("openai/gpt-4.1-mini")]
@[Validate(Input, Output)]
workflow "solver-codex" do
follow ["@coder@example.com"]
agent "codex-agent"
end
@[Service]
workflow "agent-tunnel" do
exec "localtunnel", runtime: {shell: "bash"}
end
workflow "codex-acp" do
exec "codex",
runtime: {acp: {command: "codex", args: ["--server"]}}
end
workflow "remote-acp" do
exec "github.com/lefinepro/ocawe/caws/10-acp-agent", runtime: {"git+https"}
end
workflow "remote-acp-ssh" do
exec "git+ssh://github.com/lefinepro/ocawe/caws/10-acp-agent/10-acp-agent", runtime: {"git+ssh"}
end
Key directives:
settings do ... end— runtime config (port, datasets adapter, federation)@[Service]— workflow starts withocawe upand restarts on runtime reload@[Model("provider")]— default model for the workflowcontainer do ... end— bundle-level container packaging;packagesaccepts Nix package names, flake refs, and path refs, while optionalfilesselects what to copy into/app@[Validate(Input, Output)]— input/output type validationexec "...", runtime: {acp: {...}}— run an external ACP-compatible agentexec "github.com/org/repo/path", runtime: {"git+https"}— clone or fast-forward pull a remote Cawfile reference over HTTPS, compile it into a cached singleocawecorebinary, then run the selected workflow through that binaryexec "git+https://github.com/org/repo/path", runtime: {"git+https"}— explicit HTTPS form for the same remote Cawfile behaviorexec "git+ssh://github.com/org/repo/path/workflow", runtime: {"git+ssh"}— clone or fast-forward pull a remote Cawfile reference over SSH, compile it into a cached singleocawecorebinary, then run the selected workflow through that binary
API types:
"federation"— ForgeFed-only mode (enabled whenApi::Federation::InboxorApi::Federation::Outboxis included)"classic"— default runtime APIs (/v1/*)
Agents are defined via markdown files with frontmatter:
---
name: "My Coder"
description: "Custom agent"
model: "openai/gpt-4.1-mini"
---
You are a helpful assistant.See caws/09-custom-agent for a complete example.
Installing external agents:
- OpenCode:
npm install -g @anthropic/opencode - Claude Code:
npm install -g @anthropic-ai/claude-code - Qwen Code:
pip install qwen-code
cd packages/playground
pnpm install
pnpm run devcd packages/docs
pnpm install
pnpm run devmise install
mise run cli-build
mise run up
mise run playground-build
mise run docs-buildThe mise environment installs Crystal, Bun, and Lua 5.4 for local development.
crystal spec
cd packages/playground && pnpm run lint
cd packages/docs && pnpm run build