Skip to content

lefinepro/ocawe

Repository files navigation

Ocawe

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

Workspace Ownership

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.

Why Ocawe

  • 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

Quickstart

Run with Nix:

git clone https://github.com/lefinepro/ocawe.git
cd ocawe

nix run . -- --help
nix run . -- up caws/01-simple

Install 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 --help

Install a specific release tag:

curl -fsSL https://github.com/lefinepro/ocawe/releases/download/2026.07.00/install.sh | OCAWE_VERSION=2026.07.00 bash

Install with mise from GitHub Releases:

mise use -g "github:lefinepro/ocawe[matching=ocawe-linux,bin_path=bin,filter_bins=ocawe]@latest"
ocawe --help

Declarative 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 --help

Optional shell install:

mkdir -p ~/.local/bin
ln -sf "$PWD/build/ocawe" ~/.local/bin/ocawe
ocawe --help

If ~/.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 (default 1.13.3)
  • OCAWE_CRYSTAL_BASE_URL (default Crystal GitHub releases URL)
  • OCAWE_CRYSTAL_FORCE_BOOTSTRAP=1 (force local toolchain even if system crystal exists)
  • OCAWE_CRYSTAL_VERBOSE=1 (print toolchain version during bootstrap)

Run an example:

ocawe up caws/01-simple

Pull 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-agent

The runtime reads Cawfile from the selected workflow directory or the current directory. The port is configured there via settings do port = 4111 end.

Declarative Nix

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;
}

CLI Commands

Build and Run

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

Workflow Triggers

# 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_workflow

Workflow trigger CLI calls POST /v1/triggers/workflows/:id and sends:

  • input.<key> from key=value args (values parsed as JSON when possible)
  • input.args from positional args without ===

Trigger command mapping:

  • workflow/v1/triggers/workflows/:id
  • agent/v1/triggers/agents/:id
  • skill=/=support/v1/triggers/skills/:id
  • function=/=tool/v1/triggers/functions/:id

Use OCAWE_TRIGGER_BASE_URL or --base-url to target a non-default runtime URL.

Runtime APIs

Primary APIs

  • GET /v1/workflows
  • POST /v1/workflows/:workflowId/runs
  • GET /v1/tools
  • GET /v1/skills
  • GET /v1/agents
  • POST /v1/agents/:agentId/generate
  • GET /v1/mcp/servers
  • POST /v1/mcp/servers
  • GET /v1/mcp/catalog
  • POST /mcp

Compatibility

  • POST /v1/chat/completions
  • GET /v1/chat/completions/:completion_id
  • POST /v1/chat/completions/tasks
  • GET /v1/chat/completions/tasks/:taskId

Federation APIs

  • POST /actors/{identifier}/inbox (S2S inbound activities, signature-verified)
  • GET /actors/{identifier}/outbox
  • POST /actors/{identifier}/outbox
  • GET /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 outbox for Create(Ticket) activities
  • require HTTP Signatures for federation requests

Project Structure

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

Examples

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-agent

Each example demonstrates a specific feature:

  • 01-simple — minimal single agent setup
  • 02-multi-agent — sequential agent pipeline
  • 03-control-flowunless, 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, put steps with step["name"] result access

Cawfile Framework

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 with ocawe up and restarts on runtime reload
  • @[Model("provider")] — default model for the workflow
  • container do ... end — bundle-level container packaging; packages accepts Nix package names, flake refs, and path refs, while optional files selects what to copy into /app
  • @[Validate(Input, Output)] — input/output type validation
  • exec "...", runtime: {acp: {...}} — run an external ACP-compatible agent
  • exec "github.com/org/repo/path", runtime: {"git+https"} — clone or fast-forward pull a remote Cawfile reference over HTTPS, compile it into a cached single ocawecore binary, then run the selected workflow through that binary
  • exec "git+https://github.com/org/repo/path", runtime: {"git+https"} — explicit HTTPS form for the same remote Cawfile behavior
  • exec "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 single ocawecore binary, then run the selected workflow through that binary

API types:

  • "federation" — ForgeFed-only mode (enabled when Api::Federation::Inbox or Api::Federation::Outbox is included)
  • "classic" — default runtime APIs (/v1/*)

Writing Custom Agents

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

Development

Run Playground

cd packages/playground
pnpm install
pnpm run dev

Run Docs

cd packages/docs
pnpm install
pnpm run dev

Development Tasks (mise)

mise install
mise run cli-build
mise run up
mise run playground-build
mise run docs-build

The mise environment installs Crystal, Bun, and Lua 5.4 for local development.

Testing

crystal spec
cd packages/playground && pnpm run lint
cd packages/docs && pnpm run build

About

Workflow automation as simple as taking notes

Topics

Resources

License

Stars

9 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors