Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Configuration

Bento reads two config layers when the daemon starts:

  • .bento/daemon.yaml — daemon-wide settings (database, ports, defaults, tunnel)
  • .bento/pipelines/*.yaml — one file per pipeline definition

Both files are created by bento init. Runtime state (PID, logs, workspaces) lives under ~/.bento/<name>/ and is never committed.

Environment variables are expanded with ${VAR} syntax in both files.


daemon.yaml

# Daemon identity — used for launchd/systemd service name and log dir
name: bento
 
logging:
  level: info          # error | warn | info | debug
 
database:
  url: postgresql://bento:bento@localhost:8421/bento
 
# Global defaults applied to every pipeline unless overridden
defaults:
  limits:
    max_concurrent: 2
  guardrails:
    timeout: 300       # seconds before an agent run is killed
    max_tokens: 50000
 
# The orchestrator decides which agent/model handles a given workload
orchestrator:
  runtime: claude
  model: claude-opus-4-6
 
# Named repo shortcuts — used in pipeline prompts via {{repo.*}}
repos:
  my-project:
    url: acme/my-project   # GitHub owner/repo
    branch: main
    issue_tracker: github
 
webhooks:
  host: 127.0.0.1
  port: 7890
  secret: ${GITHUB_WEBHOOK_SECRET}
 
# Optional: expose the webhook port via a public tunnel at startup.
# See Public Access for Cloudflare and Tailscale options.
# tunnel:
#   provider: cloudflare
#   mode: quick
 
queue:
  concurrency: 2
  retry:
    attempts: 1
  circuit_breaker:
    failure_threshold: 3
 
# Optional: override the sandbox backend (auto-detected by default)
# sandboxes:
#   backend: docker
 
# Knowledge retrieval — inject relevant source context into agent prompts
pipeline:
  retrieve:
    topK: 20

Field reference

FieldDefaultDescription
namebentoService identifier; sets the launchd/systemd unit name and ~/.bento/<name>/ path
logging.levelinfoLog verbosity: error, warn, info, debug
database.urlPostgreSQL connection string
defaults.limits.max_concurrentMax simultaneous agent runs across all pipelines
defaults.guardrails.timeoutSeconds before a run is killed (pipeline can override)
defaults.guardrails.max_tokensToken budget per run
orchestrator.runtimeclaudeRuntime used for orchestration decisions
orchestrator.modelModel override for the orchestrator
webhooks.host127.0.0.1Bind address
webhooks.port7890Bind port
webhooks.secretGitHub webhook secret for HMAC verification
queue.concurrencyParallel jobs the queue worker runs
queue.retry.attempts1Retry count on job failure
queue.circuit_breaker.failure_thresholdFailures before the circuit opens
pipeline.retrieve.topKNumber of source chunks injected per prompt (requires qmd)

Pipeline files

Each file under .bento/pipelines/ defines one pipeline. The filename is cosmetic; the name: field (or the filename stem if omitted) is the pipeline's identity.

Webhook trigger

name: pr-review
 
trigger:
  github:
    - pull_request.opened
    - pull_request.synchronize
 
agent: reviewer
 
prompt: |
  Review PR #{{event.pull_request.number}} ("{{event.pull_request.title}}")
  on {{event.repository.full_name}}, opened by @{{event.pull_request.user.login}},
  for merge readiness.
 
guardrails:
  timeout: 900       # override the daemon default for this pipeline

Schedule trigger

trigger:
  schedule: "*/5 * * * *"   # standard cron expression
 
agent: heartbeat
prompt: |
  Reply with exactly the word "pong" and nothing else.
 
sandbox:
  backend: docker    # override sandbox for this pipeline
 
guardrails:
  read_only: true
  timeout: 60
 
options:
  stateless: true    # skip injecting/accumulating run notes
 
orchestrator: false  # bypass orchestrator for trivial tasks

Trigger sources

See Triggers for the full reference — event string formats, filter syntax, cron expressions, and prompt template variables.

Pipeline field reference

FieldDefaultDescription
namefilename stemPipeline identifier
triggerOne or more trigger sources (required)
agentAgent persona to use (agents/<name>/SOUL.md)
promptPrompt template; {{event.*}} expands from the webhook payload
guardrails.timeoutdaemon defaultSeconds before the run is killed
guardrails.max_tokensdaemon defaultToken budget
guardrails.read_onlyfalseRestrict agent to read-only file operations
sandbox.backendauto-detectedOverride sandbox: docker, podman, daytona, just-bash
options.statelessfalseSkip cross-run note injection/accumulation
orchestratortrueSet to false to bypass orchestrator routing

Auth tokens

Bearer tokens are managed via the CLI and stored in the daemon's database. See Authentication.

# daemon.yaml — static token config (alternative to CLI-issued tokens)
auth:
  tokens:
    - id: cli-prod
      secret: ${BENTO_TOKEN_CLI}
      scopes: ["pipelines:*", "agents:*"]
    - id: ci-runner
      secret: ${BENTO_TOKEN_CI}
      scopes: ["pipelines:review"]