Skip to content

Configuration ​

GolemBot uses a single configuration file: golem.yaml in the assistant directory root.

Minimal Config ​

A working golem.yaml only needs two lines:

yaml
name: my-bot
engine: claude-code

Everything else below is optional — add fields as you need them.

Full Example ​

yaml
name: my-assistant
engine: claude-code          # cursor | claude-code | opencode | codex
model: claude-sonnet         # optional, preferred model

# Optional: bypass agent permission prompts
skipPermissions: true

# Optional: Codex runtime mode (Codex engine only)
codex:
  mode: unrestricted         # optional shorthand: unrestricted | safe
  sandbox: workspace-write   # read-only | workspace-write | danger-full-access
  approval: on-request       # untrusted | on-request | never
  search: true
  addDirs:
    - ../shared-assets

# Optional: granular agent permissions (Cursor engine only)
permissions:
  allowedPaths:
    - ./src
    - ./tests
  deniedPaths:
    - ./.env
    - ./secrets
  allowedCommands:
    - npm test
    - npm run build
  deniedCommands:
    - rm -rf *

# Optional: role/persona definition — injected into AGENTS.md as a System Instructions
# section, read by the engine once per session (not prepended to every message)
systemPrompt: |
  You are a marketing assistant named Aria. Never introduce yourself as OpenCode
  or any coding assistant. Reply in the same language the user uses.

# Optional: production hardening
timeout: 120                 # engine timeout in seconds (default: 600)
maxConcurrent: 20            # max parallel chats (default: 10)
maxQueuePerSession: 2        # max queued requests per user (default: 3)
sessionTtlDays: 14           # prune idle sessions after N days (default: 30)

# Optional: streaming message delivery for IM channels
streaming:
  mode: streaming            # buffered (default) | streaming
  showToolCalls: true        # show 🔧 tool hints in IM (default: false)

# Optional: group chat behaviour (applies to all channels)
groupChat:
  groupPolicy: mention-only  # mention-only (default) | smart | always
  historyLimit: 20           # recent messages to inject as context (default: 20)
  maxTurns: 10               # max consecutive bot replies per group (default: 10)

# Optional: scheduled tasks
tasks:
  - id: daily-standup
    name: daily-standup
    schedule: "0 9 * * 1-5"
    prompt: |
      Summarize all git commits in the last 24 hours,
      grouped by author. Flag any breaking changes.
    enabled: true
    target:
      channel: feishu
      chatId: "oc_xxxxx"

# Optional: persistent message queue (crash-safe, sequential processing)
inbox:
  enabled: true
  retentionDays: 7             # days to keep completed entries (default: 7)

# Optional: catch up on missed messages after restart
historyFetch:
  enabled: true
  pollIntervalMinutes: 15      # periodic poll interval (default: 15)
  initialLookbackMinutes: 60   # first-run lookback window (default: 60)

# Optional: route engine to a third-party LLM provider
provider:
  baseUrl: "https://openrouter.ai/api"
  apiKey: "${OPENROUTER_API_KEY}"
  model: "anthropic/claude-sonnet-4"
  models:                            # per-engine overrides
    codex: "openai/gpt-4.1-mini"

# Optional: IM channel configuration
channels:
  feishu:
    appId: ${FEISHU_APP_ID}
    appSecret: ${FEISHU_APP_SECRET}
    # Optional: set to lark for Lark global tenants
    # domain: lark
    # Optional: WebSocket pong timeout in seconds
    # pingTimeout: 30
  dingtalk:
    clientId: ${DINGTALK_CLIENT_ID}
    clientSecret: ${DINGTALK_CLIENT_SECRET}
  wecom:
    botId: ${WECOM_BOT_ID}
    secret: ${WECOM_SECRET}

# Optional: gateway service configuration
gateway:
  port: 3000
  host: 127.0.0.1
  token: ${GOLEM_TOKEN}

Fields ​

Required ​

FieldTypeDescription
namestringAssistant name
enginestringEngine type: cursor, claude-code, opencode, or codex

Optional ​

FieldTypeDefaultDescription
modelstring—Preferred model. Format varies by engine — see each engine's docs for valid values
skipPermissionsbooleantrueWhether to bypass agent permission prompts
codexobject—Codex-specific runtime options — see codex section
timeoutnumber600Engine invocation timeout in seconds. The underlying CLI process is killed and a type: 'error' event is emitted
maxConcurrentnumber10Maximum number of parallel chat() calls across all sessions
maxQueuePerSessionnumber3Maximum number of requests that can be queued per session key
sessionTtlDaysnumber30Sessions not used for this many days are pruned at next startup
systemPromptstring—Role/persona instructions injected into AGENTS.md as a ## System Instructions section. The engine reads this once as system-level context — it is not prepended to every message, so token cost stays flat across multi-turn conversations
permissionsobject—Granular agent permissions — see permissions section. Currently Cursor engine only
streamingobject—Streaming message delivery for IM channels
tasksarray—Scheduled tasks — see tasks section
channelsobject—IM channel configurations
inboxobject—Persistent message queue — see inbox section
historyFetchobject—History fetch for missed messages — see historyFetch section
oauthTokenstring—Claude Max subscription token (from claude setup-token). Claude Code engine only — see Claude Code
personaobject—Structured agent identity — see persona section
providerobject—Third-party LLM provider routing — see Provider Routing
gatewayobject—Gateway service settings

permissions ​

Granular agent access control. When configured, golembot init generates .cursor/cli.json and the Cursor engine omits --trust so the CLI enforces these rules.

Cursor only

Currently only the Cursor engine supports granular permissions via .cursor/cli.json. For other engines, this config is parsed but has no effect.

yaml
permissions:
  allowedPaths:
    - ./src
    - ./tests
  deniedPaths:
    - ./.env
    - ./secrets
  allowedCommands:
    - npm test
    - npm run build
  deniedCommands:
    - rm -rf *
FieldTypeDescription
allowedPathsstring[]Paths the agent is allowed to read/write (relative to workspace)
deniedPathsstring[]Paths the agent must not access
allowedCommandsstring[]Shell commands the agent is allowed to run
deniedCommandsstring[]Shell commands the agent must not run

All fields are optional. Empty or omitted arrays have no effect. Run golembot init after changing permissions to regenerate .cursor/cli.json.

codex ​

Codex-specific execution settings.

yaml
codex:
  mode: unrestricted
  sandbox: workspace-write
  approval: on-request
  search: false
  addDirs:
    - ../shared-assets
FieldTypeDefaultDescription
modestringunrestrictedCompatibility shorthand. unrestricted runs Codex with --dangerously-bypass-approvals-and-sandbox. safe uses --full-auto
sandboxstring—Fine-grained sandbox control: read-only, workspace-write, or danger-full-access
approvalstring—Fine-grained approval policy: untrusted, on-request, or never (passed before exec)
searchbooleanfalseEnable Codex live web search (--search, passed before exec)
addDirsstring[]—Extra writable directories passed as --add-dir (resolved relative to the workspace when not absolute)

If sandbox or approval is set, GolemBot uses explicit --sandbox / --ask-for-approval flags and does not use mode. approval and search are forwarded as top-level Codex CLI flags before exec; sandbox and addDirs remain on the exec subcommand. When only one of sandbox or approval is set, the other defaults to workspace-write / on-request.

persona ​

Structured agent identity rendered into AGENTS.md. The role field is also propagated to fleet registration, enabling multi-bot peer awareness.

yaml
persona:
  role: product analyst
FieldTypeDescription
rolestringAgent's domain role (e.g. "product analyst", "customer support", "user researcher")
displayNamestringDisplay name (defaults to name)
tonestringCommunication style (e.g. "professional", "casual")
boundariesstring[]Topics or actions the agent should decline

You can also set the role during initialization with golembot init --role "product analyst".

streaming ​

Controls how the gateway delivers messages to IM channels.

FieldTypeDefaultDescription
modestringbufferedbuffered — accumulate the full reply and send once. streaming — send text incrementally at paragraph boundaries and tool call events
showToolCallsbooleanfalseWhen true, send a 🔧 toolName... hint to the chat each time the agent invokes a tool

In buffered mode (default), the bot waits until the agent finishes and sends one complete message. In streaming mode, the bot flushes text to IM at semantic boundaries:

  • Paragraph breaks (\n\n) — completed paragraphs are sent immediately
  • Tool calls — accumulated text is flushed before the tool hint
  • Done — any remaining text is flushed

Streaming mode provides faster visual feedback for long, multi-step agent responses.

yaml
streaming:
  mode: streaming
  showToolCalls: true

channels ​

Configure one or more IM platforms. Only configured channels are started by the gateway.

groupChat ​

Controls how the bot participates in group chats — response policies, @mention handling, quote reply, and group memory.

yaml
groupChat:
  groupPolicy: smart     # mention-only (default) | smart | always
  historyLimit: 30       # inject last 30 messages as context (default: 20)
  maxTurns: 5            # stop after 5 consecutive bot replies (default: 10)

See Group Chat for full details on policies, mention handling, quote reply, and group memory.

tasks ​

Define scheduled tasks that run automatically on a cron schedule. Each task sends a prompt to the engine and (optionally) delivers the result to an IM channel.

yaml
tasks:
  - id: daily-standup
    name: daily-standup
    schedule: "0 9 * * 1-5"
    prompt: |
      Summarize all git commits in the last 24 hours,
      grouped by author. Flag any breaking changes.
    enabled: true
    target:
      channel: feishu
      chatId: "oc_xxxxx"

See Scheduled Tasks for full configuration reference, schedule formats, management commands, and use case examples.

Conversation History ​

GolemBot automatically records conversations and restores context when sessions are lost. No configuration needed. See Memory for details.

provider ​

Route any engine to a third-party LLM API. See Provider Routing for full documentation.

FieldTypeDescription
baseUrlstringProvider API endpoint
apiKeystringAPI key (supports ${ENV_VAR} placeholders)
modelstringDefault model for all engines
modelsobjectPer-engine model overrides (key = engine name)
fallbackobjectSecondary provider config — GolemBot switches to this after consecutive failures. Same fields as provider (except nested fallback is ignored)
failoverThresholdnumberConsecutive errors before activating fallback (default: 3)

gateway ​

FieldTypeDefaultDescription
portnumber3000HTTP service port
hoststring127.0.0.1Bind address
tokenstring—Bearer token for HTTP API authentication

inbox ​

Persistent message queue — messages survive crashes and are consumed sequentially.

yaml
inbox:
  enabled: true          # default: false
  retentionDays: 7       # days to keep completed entries

historyFetch ​

Catch up on missed messages after restart with intelligent triage.

yaml
historyFetch:
  enabled: true
  pollIntervalMinutes: 15
  initialLookbackMinutes: 60

See Inbox & History Fetch for full details on crash recovery, smart triage, platform support, and deduplication.

Environment Variable Placeholders ​

Sensitive fields support ${ENV_VAR} syntax. At load time, GolemBot resolves these against process.env.

yaml
gateway:
  token: ${GOLEM_TOKEN}    # resolved from process.env.GOLEM_TOKEN

This works for all string values within channels and gateway blocks. Use a .env file alongside golem.yaml — the CLI auto-loads .env from the working directory at startup.

.env Example ​

sh
FEISHU_APP_ID=cli_xxxxxxxxxx
FEISHU_APP_SECRET=xxxxxxxxxx
GOLEM_TOKEN=my-secret-token
ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxx

TIP

Add .env to .gitignore and commit .env.example (without real values) for sharing.

Model Names by Engine ​

The model value format is different for each engine:

EngineFormatExampleWhere to find values
cursorCursor model namesonnet-4.6Cursor → Settings → Models
claude-codeAnthropic model IDclaude-sonnet-4-6claude models
opencodeprovider/modelanthropic/claude-sonnet-4-5opencode models
codexOpenAI model namecodex-mini-latestcodex models

See the individual engine pages for full model tables and runtime override syntax.

Full Example ​

yaml
name: my-bot
engine: claude-code

groupChat:
  groupPolicy: smart
  historyLimit: 30
  maxTurns: 5

inbox:
  enabled: true
  retentionDays: 7

historyFetch:
  enabled: true
  pollIntervalMinutes: 15
  initialLookbackMinutes: 60

channels:
  slack:
    botToken: ${SLACK_BOT_TOKEN}
    appToken: ${SLACK_APP_TOKEN}

gateway:
  port: 3000
  token: ${GOLEM_TOKEN}

Dashboard Configuration Panel ​

When running golembot gateway, the web dashboard includes a Configuration Panel that displays all golem.yaml settings and supports inline editing — hover over a value, click the pencil button (✎), modify, and save. Changes are written to golem.yaml immediately.

For full details on the dashboard, inline editing workflow, and hot-reload vs restart behavior, see Dashboard.

Skills Are Not Configured ​

Skills are not declared in golem.yaml. The skills/ directory is the single source of truth — whatever skill directories exist, those capabilities are loaded. See Skills.

GolemConfig TypeScript Type ​

typescript
interface GolemConfig {
  name: string;
  engine: string;
  model?: string;
  skipPermissions?: boolean;
  codex?: {
    mode?: 'safe' | 'unrestricted';
    sandbox?: 'read-only' | 'workspace-write' | 'danger-full-access';
    approval?: 'untrusted' | 'on-request' | 'never';
    search?: boolean;
    addDirs?: string[];
  };
  timeout?: number;             // seconds, default 600
  maxConcurrent?: number;       // default 10
  maxQueuePerSession?: number;  // default 3
  sessionTtlDays?: number;      // default 30
  systemPrompt?: string;
  permissions?: {
    allowedPaths?: string[];
    deniedPaths?: string[];
    allowedCommands?: string[];
    deniedCommands?: string[];
  };
  streaming?: {
    mode?: 'buffered' | 'streaming';  // default: 'buffered'
    showToolCalls?: boolean;          // default: false
  };
  groupChat?: {
    groupPolicy?: 'mention-only' | 'smart' | 'always';  // default: 'mention-only'
    historyLimit?: number;   // default: 20
    maxTurns?: number;       // default: 10
  };
  tasks?: Array<{
    id: string;
    name: string;
    schedule: string;
    prompt: string;
    enabled?: boolean;       // default: true
    target?: {
      channel: string;
      chatId: string;
    };
  }>;
  channels?: {
    feishu?: { appId: string; appSecret: string; domain?: string; pingTimeout?: number };
    dingtalk?: { clientId: string; clientSecret: string };
    wecom?: {
      botId: string; secret: string; websocketUrl?: string;
    };
    slack?: { botToken: string; appToken: string };
    telegram?: { botToken: string };
    discord?: { botToken: string; botName?: string };
    // Custom adapter: any key with _adapter field
    [key: string]: { _adapter: string; [k: string]: unknown } | undefined;
  };
  inbox?: {
    enabled?: boolean;           // default: false
    retentionDays?: number;      // default: 7
  };
  historyFetch?: {
    enabled?: boolean;           // default: false
    pollIntervalMinutes?: number;    // default: 15
    initialLookbackMinutes?: number; // default: 60
  };
  provider?: {
    baseUrl?: string;
    apiKey?: string;
    model?: string;
    models?: Record<string, string>;
    fallback?: {                 // secondary provider for automatic failover
      baseUrl?: string;
      apiKey?: string;
      model?: string;
    };
    failoverThreshold?: number;  // default: 3
  };
  oauthToken?: string;           // Claude Max setup-token (claude-code engine only)
  gateway?: {
    port?: number;
    host?: string;
    token?: string;
  };
}

Released under the MIT License.