Ocawe is a Crystal-first runtime for workflow bundles, agents, tools, and skills.
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
- Crystal workflow runtime with Cawfile-based bundles (
*.acd.crorCawfile) - Agent + skill + tool discovery from workflow directories
- Voice and RAG patterns through workflow DSL
- Schema validation and guardrails in agent/workflow execution
- OpenAI-compatible chat completions endpoint support
Build CLI:
crystal build src/cli/main.cr -o build/ocaweocawe build/dev/up now auto-bootstrap Crystal when crystal is missing by downloading a platform archive into ./.tools/crystal.
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 runtime server:
ocawe upThe port is configured in Cawfile via settings { port = 4111 }.
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/completions
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 + Bun) 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 07-unified-resources/ # resource management patterns 08-model-override/ # per-agent model override 09-custom-agent/ # how to write custom agents 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 modeEach 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
- 07-unified-resources — shared resources with
@[Model]and@[Resources] - 08-model-override — per-agent model configuration
- 09-custom-agent — writing custom agents with external binaries
Framework configuration uses Cawfile (RCL format) in the workflow root.
Example Cawfile:
settings do
data.adapter = "memory"
port = 4111
end
# Federation is enabled by including Api::Federation types
struct Input
include Api::Federation::Inbox
end
struct Output
include Api::Federation::Outbox
end
@[Model("cliproxy")]
@[Validate(Input, Output)]
workflow "solver-codex" do
follow ["@coder@example.com"]
agent "codex-agent"
end
Key directives:
settings do ... end— runtime config (port, data adapter, federation)@[Model("provider")]— default model for the workflow@[Container(packages: ["pkg1"])]— container mode with Nix packages (omit packages for static build)@[Validate(Input, Output)]— input/output type validation
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: "cliproxyapi/qwen3-coder-plus"
---
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
bun install
bun run devcd packages/docs
bun install
bun run devmise run cli-build
mise run up
mise run playground-build
mise run docs-buildcrystal spec
cd packages/playground && bun run lint
cd packages/docs && bun run build