Skills beddel
git clone https://github.com/openclaw/skills
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/botanarede/beddel" ~/.claude/skills/openclaw-skills-beddel && rm -rf "$T"
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.openclaw/skills && cp -r "$T/skills/botanarede/beddel" ~/.openclaw/skills/openclaw-skills-beddel && rm -rf "$T"
skills/botanarede/beddel/SKILL.mdBeddel
Declarative YAML workflow engine for AI pipelines — run multi-step LLM chains with branching, guardrails, retry, and observability out of the box.
Prerequisites
- Python 3.11+ (
)python3.11 --version - pip for Python 3.11 (
)python3.11 -m pip --version - An LLM API key — any LiteLLM-supported provider works. Gemini recommended:
export GEMINI_API_KEY="your-key"
Installation
python3.11 -m pip install "beddel[all]" beddel version
Note: System Python may be 3.10. Always use
explicitly.python3.11
Quick Start
- Write a workflow file
:hello.yaml
id: hello name: Hello World input_schema: topic: { type: str, required: true } steps: - id: greet primitive: llm config: model: gemini/gemini-2.0-flash prompt: "Write a one-sentence greeting about $input.topic" max_tokens: 50
- Run it:
beddel run hello.yaml -i topic="AI agents" --json-output
Tool Integration (OpenClaw Plugin)
The
beddel tool is available via the OpenClaw plugin @botanarede/beddel:
openclaw plugins install @botanarede/beddel
Once installed, the agent can invoke
beddel with actions: run, validate, list-primitives.
The bundled example
examples/setup-beddel.yaml automates this installation — see Bundled Example below.
CLI Reference
| Command | Description |
|---|---|
| Execute a workflow |
| Validate YAML syntax and schema |
| Show available primitives |
| Serve workflow as HTTP endpoint |
| Print installed version |
Core Concepts
A workflow is a YAML file with an
id, name, optional input_schema, and a list of steps. Each step declares a primitive (the unit of work) and a config (primitive-specific parameters).
Steps execute sequentially. Each step's output is available to subsequent steps via
$stepResult.<step_id>.<path>.
See
references/ for full schema documentation.
Primitives
| Primitive | Purpose |
|---|---|
| Single-turn LLM call with streaming support |
| Multi-turn conversation with message history |
| Template-based output rendering (JSON, Markdown, text) |
| Data validation with strategies: raise, return_errors, correct, delegate |
| Nested workflow invocation with depth tracking |
| External function call — is built-in |
| Unified adapter for external agent delegation |
Execution Strategies
Each step can declare an
execution_strategy to control error handling:
| Strategy | Behavior |
|---|---|
| Stop workflow on error (default) |
| Log error, continue to next step |
| Retry with exponential backoff and jitter |
| Execute an alternative step on failure |
| Delegate error recovery to agent judgment |
Variable Resolution
| Namespace | Example | Source |
|---|---|---|
| | Runtime inputs () |
| | Previous step outputs |
| | Environment variables |
Key paths for step results:
- tool steps:
,$stepResult.<id>.result.stdout.result.exit_code - llm steps:
$stepResult.<id>.content - guardrail steps:
,$stepResult.<id>.data.<field>.valid
Bundled Example: setup-beddel
This workflow checks whether the
@botanarede/beddel OpenClaw plugin is installed and installs it if needed. It demonstrates 3 of the 7 primitives: tool, guardrail, and conditional execution via if.
id: setup-beddel name: Beddel Plugin Setup description: Install or update the @botanarede/beddel OpenClaw plugin and verify it loads. steps: - id: check_plugin primitive: tool config: tool: shell_exec arguments: cmd: "python3.11 -c \"import subprocess,json,re;r=subprocess.run(['openclaw','plugins','list'],capture_output=True,text=True);has=bool(re.search(r'beddel',r.stdout));loaded=bool(re.search(r'beddel.*loaded',r.stdout));print(json.dumps({'action':'OK'if loaded else'REINSTALL'if has else'INSTALL'}))\"" - id: validate_check primitive: guardrail config: data: "$stepResult.check_plugin.result.stdout" schema: fields: action: { type: str, required: true } strategy: correct - id: install_plugin primitive: tool config: tool: shell_exec arguments: cmd: "openclaw plugins install @botanarede/beddel" timeout: 120 if: "$stepResult.validate_check.data.action != 'OK'" - id: verify primitive: tool config: tool: shell_exec arguments: cmd: "openclaw plugins info beddel"
What each step demonstrates
| Step | Primitive | Feature |
|---|---|---|
| | Deterministic check via — outputs JSON without LLM |
| | strategy — parses JSON string, strips markdown fences, validates schema |
| | Conditional execution () — skips when plugin already loaded. for network ops |
| | Post-install verification |
Run it:
beddel run examples/setup-beddel.yaml --json-output
Security & Privacy
- Secrets: Use
variables — never hardcode API keys in workflow YAML$env.* - shell_exec: Runs with
(no shell injection). Commands are split viashell=False
. Shell operators (shlex.split()
,|
,&&
) are sanitized in beddel 0.1.1+> - Subprocess sandbox: Default timeout 60s, max stdout 1MB per stream, configurable per step
External Endpoints
| Endpoint | When | Purpose |
|---|---|---|
LLM provider API (e.g. ) | , , (delegate) steps | Model inference |
PyPI () | Installation only | Package download |
npm registry () | Plugin install step | Plugin download |
Trust Statement
Beddel executes user-defined YAML workflows. It does not phone home, collect telemetry by default, or transmit data beyond the configured LLM provider endpoints. OpenTelemetry export is opt-in.
Observability
Beddel emits OpenTelemetry spans for every workflow and step execution:
— root span per workflow runbeddel.workflow.execute
— child span per stepbeddel.step.<primitive>
attributes on LLM steps (prompt/completion tokens)gen_ai.usage.*
Enable with any OTel-compatible collector via standard
OTEL_* environment variables.
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
| Tool not found | Ensure tool name is (built-in). Custom tools need |
| Unresolvable variable | Check step id spelling and result path. Tool results use , LLM uses |
| Guardrail validation failed | Check schema field types. Use for JSON string inputs |
| Wrong Python version | Install Python 3.11+. System Python may be 3.10 |
Step shows | condition was false or | Expected behavior — downstream steps should handle SKIPPED values |
Advanced: Python SDK
from beddel import WorkflowExecutor, VariableResolver resolver = VariableResolver() resolver.register_namespace("secrets", lambda path, ctx: get_secret(path)) executor = WorkflowExecutor(resolver=resolver) result = await executor.execute(workflow, {"topic": "AI"})
For FastAPI integration:
beddel serve -w workflow.yaml --port 8000
References
Additional documentation in
references/ (loaded on demand):
— Complete YAML schemaworkflow-format.md
— All 7 primitives with full config optionsprimitives.md
— 5 strategies with examplesexecution-strategies.md
— Namespaces, custom resolvers, error handlingvariable-resolution.md