Configuration Examples
Examples below are aligned with the current config schema. For the exhaustive reference and per-field notes, see Configuration.Quick start
Absolute minimum
Copy
{
agent: {
workspace: '~/.datzi/workspace'
},
channels: {
whatsapp: {
allowFrom: ['+15555550123']
}
}
}
~/.datzi/datzi.json and you can DM the bot from that number.
Recommended starter
Copy
{
identity: {
name: 'Clawd',
theme: 'helpful assistant',
emoji: '🦞'
},
agent: {
workspace: '~/.datzi/workspace',
model: {
primary: 'ollama/qwen3-coder:14b'
}
},
channels: {
whatsapp: {
allowFrom: ['+15555550123'],
groups: {
'*': {
requireMention: true
}
}
}
}
}
Expanded example (major options)
JSON5 lets you use comments and trailing commas. Regular JSON works too.
Copy
{
// Environment + shell
env: {
vars: {
GROQ_API_KEY: 'gsk-...'
},
shellEnv: {
enabled: true,
timeoutMs: 15000
}
},
// Auth profile metadata (Ollama needs no auth - no profiles required)
auth: {
profiles: {},
order: {}
},
// Identity
identity: {
name: 'Samantha',
theme: 'helpful sloth',
emoji: '🦥'
},
// Logging
logging: {
level: 'info',
file: '/tmp/datzi/datzi.log',
consoleLevel: 'info',
consoleStyle: 'pretty',
redactSensitive: 'tools'
},
// Message formatting
messages: {
messagePrefix: '[datzi]',
responsePrefix: '>',
ackReaction: '👀',
ackReactionScope: 'group-mentions'
},
// Routing + queue
routing: {
groupChat: {
mentionPatterns: ['@datzi', 'datzi'],
historyLimit: 50
},
queue: {
mode: 'collect',
debounceMs: 1000,
cap: 20,
drop: 'summarize',
byChannel: {
whatsapp: 'collect',
telegram: 'collect',
discord: 'collect',
slack: 'collect',
signal: 'collect',
imessage: 'collect',
webchat: 'collect'
}
}
},
// Tooling
tools: {
media: {
audio: {
enabled: true,
maxBytes: 20971520,
models: [
{
provider: 'openai',
model: 'gpt-4o-mini-transcribe'
}
// Optional CLI fallback (Whisper binary):
// { type: "cli", command: "whisper", args: ["--model", "base", "{{MediaPath}}"] }
],
timeoutSeconds: 120
},
video: {
enabled: true,
maxBytes: 52428800,
models: [
{
provider: 'google',
model: 'gemini-3-flash-preview'
}
]
}
}
},
// Session behavior
session: {
scope: 'per-sender',
reset: {
mode: 'daily',
atHour: 4,
idleMinutes: 60
},
resetByChannel: {
discord: {
mode: 'idle',
idleMinutes: 10080
}
},
resetTriggers: ['/new', '/reset'],
store: '~/.datzi/agents/default/sessions/sessions.json',
maintenance: {
mode: 'warn',
pruneAfter: '30d',
maxEntries: 500,
rotateBytes: '10mb'
},
typingIntervalSeconds: 5,
sendPolicy: {
default: 'allow',
rules: [
{
action: 'deny',
match: {
channel: 'discord',
chatType: 'group'
}
}
]
}
},
// Channels
channels: {
whatsapp: {
dmPolicy: 'pairing',
allowFrom: ['+15555550123'],
groupPolicy: 'allowlist',
groupAllowFrom: ['+15555550123'],
groups: {
'*': {
requireMention: true
}
}
},
telegram: {
enabled: true,
botToken: 'YOUR_TELEGRAM_BOT_TOKEN',
allowFrom: ['123456789'],
groupPolicy: 'allowlist',
groupAllowFrom: ['123456789'],
groups: {
'*': {
requireMention: true
}
}
},
discord: {
enabled: true,
token: 'YOUR_DISCORD_BOT_TOKEN',
dm: {
enabled: true,
allowFrom: ['steipete']
},
guilds: {
'123456789012345678': {
slug: 'friends-of-datzi',
requireMention: false,
channels: {
general: {
allow: true
},
help: {
allow: true,
requireMention: true
}
}
}
}
},
slack: {
enabled: true,
botToken: 'xoxb-REPLACE_ME',
appToken: 'xapp-REPLACE_ME',
channels: {
'#general': {
allow: true,
requireMention: true
}
},
dm: {
enabled: true,
allowFrom: ['U123']
},
slashCommand: {
enabled: true,
name: 'datzi',
sessionPrefix: 'slack:slash',
ephemeral: true
}
}
},
// Agent runtime
agents: {
defaults: {
workspace: '~/.datzi/workspace',
userTimezone: 'America/Chicago',
model: {
primary: 'ollama/qwen3-coder:14b',
fallbacks: ['ollama/qwen3-coder:32b', 'ollama/deepseek-r1:32b']
},
imageModel: {
primary: 'ollama/qwen3-coder:14b'
},
models: {
'ollama/qwen3-coder:32b': {
alias: 'opus'
},
'ollama/qwen3-coder:14b': {
alias: 'sonnet'
},
'ollama/deepseek-r1:32b': {
alias: 'gpt'
}
},
thinkingDefault: 'low',
verboseDefault: 'off',
elevatedDefault: 'on',
blockStreamingDefault: 'off',
blockStreamingBreak: 'text_end',
blockStreamingChunk: {
minChars: 800,
maxChars: 1200,
breakPreference: 'paragraph'
},
blockStreamingCoalesce: {
idleMs: 1000
},
humanDelay: {
mode: 'natural'
},
timeoutSeconds: 600,
mediaMaxMb: 5,
typingIntervalSeconds: 5,
maxConcurrent: 3,
heartbeat: {
every: '30m',
model: 'ollama/qwen3-coder:14b',
target: 'last',
to: '+15555550123',
prompt: 'HEARTBEAT',
ackMaxChars: 300
},
memorySearch: {
provider: 'gemini',
model: 'gemini-embedding-001',
remote: {
apiKey: '${GEMINI_API_KEY}'
},
extraPaths: ['../team-docs', '/srv/shared-notes']
},
sandbox: {
mode: 'non-main',
perSession: true,
workspaceRoot: '~/.datzi/sandboxes',
docker: {
image: 'datzi-sandbox:bookworm-slim',
workdir: '/workspace',
readOnlyRoot: true,
tmpfs: ['/tmp', '/var/tmp', '/run'],
network: 'none',
user: '1000:1000'
},
browser: {
enabled: false
}
}
}
},
tools: {
allow: ['exec', 'process', 'read', 'write', 'edit', 'apply_patch'],
deny: ['browser', 'canvas'],
exec: {
backgroundMs: 10000,
timeoutSec: 1800,
cleanupMs: 1800000
},
elevated: {
enabled: true,
allowFrom: {
whatsapp: ['+15555550123'],
telegram: ['123456789'],
discord: ['steipete'],
slack: ['U123'],
signal: ['+15555550123'],
imessage: ['user@example.com'],
webchat: ['session:demo']
}
}
},
// Custom model providers
models: {
mode: 'merge',
providers: {
'custom-proxy': {
baseUrl: 'http://localhost:4000/v1',
apiKey: 'LITELLM_KEY',
api: 'openai-responses',
authHeader: true,
headers: {
'X-Proxy-Region': 'us-west'
},
models: [
{
id: 'llama-3.1-8b',
name: 'Llama 3.1 8B',
api: 'openai-responses',
reasoning: false,
input: ['text'],
cost: {
input: 0,
output: 0,
cacheRead: 0,
cacheWrite: 0
},
contextWindow: 128000,
maxTokens: 32000
}
]
}
}
},
// Cron jobs
cron: {
enabled: true,
store: '~/.datzi/cron/cron.json',
maxConcurrentRuns: 2,
sessionRetention: '24h'
},
// Webhooks
hooks: {
enabled: true,
path: '/hooks',
token: 'shared-secret',
presets: ['gmail'],
transformsDir: '~/.datzi/hooks/transforms',
mappings: [
{
id: 'gmail-hook',
match: {
path: 'gmail'
},
action: 'agent',
wakeMode: 'now',
name: 'Gmail',
sessionKey: 'hook:gmail:{{messages[0].id}}',
messageTemplate: 'From: {{messages[0].from}}\nSubject: {{messages[0].subject}}',
textTemplate: '{{messages[0].snippet}}',
deliver: true,
channel: 'last',
to: '+15555550123',
thinking: 'low',
timeoutSeconds: 300,
transform: {
module: 'gmail.js',
export: 'transformGmail'
}
}
],
gmail: {
account: 'datzi@gmail.com',
label: 'INBOX',
topic: 'projects/<project-id>/topics/gog-gmail-watch',
subscription: 'gog-gmail-watch-push',
pushToken: 'shared-push-token',
hookUrl: 'http://127.0.0.1:18789/hooks/gmail',
includeBody: true,
maxBytes: 20000,
renewEveryMinutes: 720,
serve: {
bind: '127.0.0.1',
port: 8788,
path: '/'
},
tailscale: {
mode: 'funnel',
path: '/gmail-pubsub'
}
}
},
// Gateway + networking
gateway: {
mode: 'local',
port: 18789,
bind: 'loopback',
controlUi: {
enabled: true,
basePath: '/datzi'
},
auth: {
mode: 'token',
token: 'gateway-token',
allowTailscale: true
},
tailscale: {
mode: 'serve',
resetOnExit: false
},
remote: {
url: 'ws://gateway.tailnet:18789',
token: 'remote-token'
},
reload: {
mode: 'hybrid',
debounceMs: 300
}
},
skills: {
allowBundled: ['gemini', 'peekaboo'],
load: {
extraDirs: ['~/Projects/agent-scripts/skills']
},
install: {
preferBrew: true,
nodeManager: 'npm'
},
entries: {
'nano-banana-pro': {
enabled: true,
apiKey: 'GEMINI_KEY_HERE',
env: {}
},
peekaboo: {
enabled: true
}
}
}
}
Common patterns
Multi-platform setup
Copy
{
agent: {
workspace: '~/.datzi/workspace'
},
channels: {
whatsapp: {
allowFrom: ['+15555550123']
},
telegram: {
enabled: true,
botToken: 'YOUR_TOKEN',
allowFrom: ['123456789']
},
discord: {
enabled: true,
token: 'YOUR_TOKEN',
dm: {
allowFrom: ['yourname']
}
}
}
}
Secure DM mode (shared inbox / multi-user DMs)
If more than one person can DM your bot (multiple entries inallowFrom, pairing approvals for multiple people, or
dmPolicy: "open"), enable secure DM mode so DMs from different senders don’t share one context by default:
Copy
{
// Secure DM mode (recommended for multi-user or sensitive DM agents)
session: {
dmScope: 'per-channel-peer'
},
channels: {
// Example: WhatsApp multi-user inbox
whatsapp: {
dmPolicy: 'allowlist',
allowFrom: ['+15555550123', '+15555550124']
},
// Example: Discord multi-user inbox
discord: {
enabled: true,
token: 'YOUR_DISCORD_BOT_TOKEN',
dm: {
enabled: true,
allowFrom: ['alice', 'bob']
}
}
}
}
Ollama with model fallback
Copy
{
// No auth needed for Ollama
agent: {
workspace: '~/.datzi/workspace',
model: {
primary: 'ollama/qwen3-coder:14b',
fallbacks: ['ollama/qwen3-coder:32b']
}
}
}
Ollama primary + MiniMax fallback
Copy
{
// No auth needed for Ollama
models: {
providers: {
minimax: {
apiKey: '${MINIMAX_API_KEY}'
}
}
},
agent: {
workspace: '~/.datzi/workspace',
model: {
primary: 'ollama/qwen3-coder:32b',
fallbacks: ['minimax/MiniMax-M2.1']
}
}
}
Work bot (restricted access)
Copy
{
identity: {
name: 'WorkBot',
theme: 'professional assistant'
},
agent: {
workspace: '~/work-datzi',
elevated: {
enabled: false
}
},
channels: {
slack: {
enabled: true,
botToken: 'xoxb-...',
channels: {
'#engineering': {
allow: true,
requireMention: true
},
'#general': {
allow: true,
requireMention: true
}
}
}
}
}
Local models only
Copy
{
agent: {
workspace: '~/.datzi/workspace',
model: {
primary: 'lmstudio/minimax-m2.1-gs32'
}
},
models: {
mode: 'merge',
providers: {
lmstudio: {
baseUrl: 'http://127.0.0.1:1234/v1',
apiKey: 'lmstudio',
api: 'openai-responses',
models: [
{
id: 'minimax-m2.1-gs32',
name: 'MiniMax M2.1 GS32',
reasoning: false,
input: ['text'],
cost: {
input: 0,
output: 0,
cacheRead: 0,
cacheWrite: 0
},
contextWindow: 196608,
maxTokens: 8192
}
]
}
}
}
}
Tips
- If you set
dmPolicy: "open", the matchingallowFromlist must include"*". - Provider IDs differ (phone numbers, user IDs, channel IDs). Use the provider docs to confirm the format.
- Optional sections to add later:
web,browser,ui,discovery,canvasHost,talk,signal,imessage. - See Providers and Troubleshooting for deeper setup notes.
