config dict you hand to bindufy() is the whole settings surface. Four keys are required (three at the top level plus deployment.expose). The rest have defaults that work for localhost, and env-var overrides for when you ship.
The required keys
The top-level validator checks three fields. A fourth,deployment.expose, is required by the deployment builder (bindufy.py:332) once deployment is present.
Miss
author, name, or deployment.url and the config validator raises ConfigError: '<field>' is a required field in the agent configuration. with an example config attached. Miss deployment.expose (when a deployment block is present) and the deployment builder raises ValueError: Missing required config field(s): deployment.expose — different error class, different message format.
The keys you’ll actually touch
Everything below has a sensible default (taken fromConfigValidator.DEFAULTS).
You override when you care.
Storage and scheduler — set these via env
Putting database credentials in a Python dict is how secrets end up in git. The env-enricher fills these in for you whenstorage / scheduler aren’t already in the config dict.
STORAGE_TYPE=postgres but DATABASE_URL is unset (same for SCHEDULER_TYPE=redis / REDIS_URL) — no silent fallback to memory.
Local dev: leave both unset, you get in-memory. Production: set both, you get persistence and distributed task queues. Same bindufy(config, handler) either way.
Deeper guides: Storage, Scheduler.
Auth, payments, and the rest
These are off by default. Turn them on when you need them — each one has its own page that goes deeper than this reference should.
The pattern is consistent: feature lives in
config if it’s about agent identity or behavior, in env vars if it’s about infrastructure or secrets.
The “okay show me everything” example
Most production agents look something like this:What you can’t put in here
config is for static settings. If you’re trying to:
- pass dynamic state per request → use the handler’s
messagesarg - share data between handler invocations → use Storage, not module-level globals
- override behavior at runtime → you probably want a skill, not a config key
bindu/penguin/config_validator.py under a name we forgot to document. The other half it’s a real feature gap and we want to know.