Passer au contenu principal

Référence de configuration

Référence de configuration principale pour ~/.openclaw/openclaw.json. Pour une vue d’ensemble orientée tâches, consultez Configuration. Cette page couvre les principales surfaces de configuration d’OpenClaw et renvoie vers d’autres pages lorsqu’un sous-système possède sa propre référence plus détaillée. Elle n’essaie pas d’intégrer sur une seule page chaque catalogue de commandes appartenant à un canal/plugin ni chaque réglage avancé de mémoire/QMD. Source de vérité du code :
  • openclaw config schema affiche le schéma JSON actif utilisé pour la validation et l’interface Control UI, avec les métadonnées groupées/plugin/canal fusionnées lorsqu’elles sont disponibles
  • config.schema.lookup renvoie un nœud de schéma limité à un chemin pour les outils d’exploration détaillée
  • pnpm config:docs:check / pnpm config:docs:gen valident le hachage de référence des documents de configuration par rapport à la surface actuelle du schéma
Références détaillées dédiées :
  • Référence de configuration de la mémoire pour agents.defaults.memorySearch.*, memory.qmd.*, memory.citations et la configuration de rêverie sous plugins.entries.memory-core.config.dreaming
  • Commandes Slash pour le catalogue actuel des commandes intégrées + groupées
  • pages du canal/plugin propriétaire pour les surfaces de commandes spécifiques au canal
Le format de configuration est JSON5 (commentaires + virgules finales autorisés). Tous les champs sont facultatifs — OpenClaw utilise des valeurs par défaut sûres lorsqu’ils sont omis.

Canaux

Chaque canal démarre automatiquement lorsque sa section de configuration existe (sauf si enabled: false).

Accès aux messages privés et aux groupes

Tous les canaux prennent en charge des politiques pour les messages privés et pour les groupes :
Politique DMComportement
pairing (par défaut)Les expéditeurs inconnus reçoivent un code d’appairage à usage unique ; le propriétaire doit l’approuver
allowlistSeuls les expéditeurs dans allowFrom (ou le magasin d’autorisations appairées)
openAutoriser tous les messages privés entrants (nécessite allowFrom: ["*"])
disabledIgnorer tous les messages privés entrants
Politique de groupeComportement
allowlist (par défaut)Seuls les groupes correspondant à la liste d’autorisations configurée
openContourner les listes d’autorisations de groupe (le filtrage par mention s’applique toujours)
disabledBloquer tous les messages de groupe/salon
channels.defaults.groupPolicy définit la valeur par défaut lorsque groupPolicy d’un fournisseur n’est pas défini. Les codes d’appairage expirent après 1 heure. Les demandes d’appairage DM en attente sont limitées à 3 par canal. Si un bloc fournisseur est entièrement absent (channels.<provider> absent), la politique de groupe d’exécution revient à allowlist (échec sécurisé) avec un avertissement au démarrage.

Remplacements de modèle par canal

Utilisez channels.modelByChannel pour épingler des ID de canal spécifiques à un modèle. Les valeurs acceptent provider/model ou des alias de modèle configurés. Le mapping de canal s’applique lorsqu’une session n’a pas déjà de remplacement de modèle (par exemple défini via /model).
{
  channels: {
    modelByChannel: {
      discord: {
        "123456789012345678": "anthropic/claude-opus-4-6",
      },
      slack: {
        C1234567890: "openai/gpt-4.1",
      },
      telegram: {
        "-1001234567890": "openai/gpt-4.1-mini",
        "-1001234567890:topic:99": "anthropic/claude-sonnet-4-6",
      },
    },
  },
}

Valeurs par défaut des canaux et heartbeat

Utilisez channels.defaults pour le comportement partagé de politique de groupe et de heartbeat entre les fournisseurs :
{
  channels: {
    defaults: {
      groupPolicy: "allowlist", // open | allowlist | disabled
      contextVisibility: "all", // all | allowlist | allowlist_quote
      heartbeat: {
        showOk: false,
        showAlerts: true,
        useIndicator: true,
      },
    },
  },
}
  • channels.defaults.groupPolicy : politique de groupe de repli lorsqu’un groupPolicy au niveau fournisseur n’est pas défini.
  • channels.defaults.contextVisibility : mode de visibilité du contexte supplémentaire par défaut pour tous les canaux. Valeurs : all (par défaut, inclure tout le contexte cité/de fil/d’historique), allowlist (inclure uniquement le contexte des expéditeurs autorisés), allowlist_quote (identique à allowlist mais conserve le contexte explicite de citation/réponse). Remplacement par canal : channels.<channel>.contextVisibility.
  • channels.defaults.heartbeat.showOk : inclure les états de canal sains dans la sortie du heartbeat.
  • channels.defaults.heartbeat.showAlerts : inclure les états dégradés/en erreur dans la sortie du heartbeat.
  • channels.defaults.heartbeat.useIndicator : afficher une sortie de heartbeat compacte de type indicateur.

WhatsApp

WhatsApp s’exécute via le canal web de la passerelle (Baileys Web). Il démarre automatiquement lorsqu’une session liée existe.
{
  channels: {
    whatsapp: {
      dmPolicy: "pairing", // pairing | allowlist | open | disabled
      allowFrom: ["+15555550123", "+447700900123"],
      textChunkLimit: 4000,
      chunkMode: "length", // length | newline
      mediaMaxMb: 50,
      sendReadReceipts: true, // coches bleues (false en mode auto-discussion)
      groups: {
        "*": { requireMention: true },
      },
      groupPolicy: "allowlist",
      groupAllowFrom: ["+15551234567"],
    },
  },
  web: {
    enabled: true,
    heartbeatSeconds: 60,
    reconnect: {
      initialMs: 2000,
      maxMs: 120000,
      factor: 1.4,
      jitter: 0.2,
      maxAttempts: 0,
    },
  },
}
{
  channels: {
    whatsapp: {
      accounts: {
        default: {},
        personal: {},
        biz: {
          // authDir: "~/.openclaw/credentials/whatsapp/biz",
        },
      },
    },
  },
}
  • Les commandes sortantes utilisent par défaut le compte default s’il est présent ; sinon, le premier ID de compte configuré (trié).
  • channels.whatsapp.defaultAccount facultatif remplace ce choix du compte par défaut lorsqu’il correspond à un ID de compte configuré.
  • L’ancien répertoire d’authentification Baileys à compte unique est migré par openclaw doctor vers whatsapp/default.
  • Remplacements par compte : channels.whatsapp.accounts.<id>.sendReadReceipts, channels.whatsapp.accounts.<id>.dmPolicy, channels.whatsapp.accounts.<id>.allowFrom.

Telegram

{
  channels: {
    telegram: {
      enabled: true,
      botToken: "your-bot-token",
      dmPolicy: "pairing",
      allowFrom: ["tg:123456789"],
      groups: {
        "*": { requireMention: true },
        "-1001234567890": {
          allowFrom: ["@admin"],
          systemPrompt: "Keep answers brief.",
          topics: {
            "99": {
              requireMention: false,
              skills: ["search"],
              systemPrompt: "Stay on topic.",
            },
          },
        },
      },
      customCommands: [
        { command: "backup", description: "Git backup" },
        { command: "generate", description: "Create an image" },
      ],
      historyLimit: 50,
      replyToMode: "first", // off | first | all | batched
      linkPreview: true,
      streaming: "partial", // off | partial | block | progress (default: off; opt in explicitly to avoid preview-edit rate limits)
      actions: { reactions: true, sendMessage: true },
      reactionNotifications: "own", // off | own | all
      mediaMaxMb: 100,
      retry: {
        attempts: 3,
        minDelayMs: 400,
        maxDelayMs: 30000,
        jitter: 0.1,
      },
      network: {
        autoSelectFamily: true,
        dnsResultOrder: "ipv4first",
      },
      proxy: "socks5://localhost:9050",
      webhookUrl: "https://example.com/telegram-webhook",
      webhookSecret: "secret",
      webhookPath: "/telegram-webhook",
    },
  },
}
  • Jeton du bot : channels.telegram.botToken ou channels.telegram.tokenFile (fichier ordinaire uniquement ; les liens symboliques sont rejetés), avec TELEGRAM_BOT_TOKEN comme solution de repli pour le compte par défaut.
  • channels.telegram.defaultAccount facultatif remplace la sélection du compte par défaut lorsqu’il correspond à un ID de compte configuré.
  • Dans les configurations multi-comptes (2 ID de compte ou plus), définissez un compte par défaut explicite (channels.telegram.defaultAccount ou channels.telegram.accounts.default) pour éviter le routage de repli ; openclaw doctor avertit lorsque cela est manquant ou invalide.
  • configWrites: false bloque les écritures de configuration initiées par Telegram (migrations d’ID de supergroupe, /config set|unset).
  • Les entrées bindings[] de niveau supérieur avec type: "acp" configurent des liaisons ACP persistantes pour les sujets de forum (utilisez le format canonique chatId:topic:topicId dans match.peer.id). La sémantique des champs est partagée dans Agents ACP.
  • Les aperçus de flux Telegram utilisent sendMessage + editMessageText (fonctionne dans les conversations directes et de groupe).
  • Politique de nouvelle tentative : voir Politique de nouvelle tentative.

Discord

{
  channels: {
    discord: {
      enabled: true,
      token: "your-bot-token",
      mediaMaxMb: 100,
      allowBots: false,
      actions: {
        reactions: true,
        stickers: true,
        polls: true,
        permissions: true,
        messages: true,
        threads: true,
        pins: true,
        search: true,
        memberInfo: true,
        roleInfo: true,
        roles: false,
        channelInfo: true,
        voiceStatus: true,
        events: true,
        moderation: false,
      },
      replyToMode: "off", // off | first | all | batched
      dmPolicy: "pairing",
      allowFrom: ["1234567890", "123456789012345678"],
      dm: { enabled: true, groupEnabled: false, groupChannels: ["openclaw-dm"] },
      guilds: {
        "123456789012345678": {
          slug: "friends-of-openclaw",
          requireMention: false,
          ignoreOtherMentions: true,
          reactionNotifications: "own",
          users: ["987654321098765432"],
          channels: {
            general: { allow: true },
            help: {
              allow: true,
              requireMention: true,
              users: ["987654321098765432"],
              skills: ["docs"],
              systemPrompt: "Short answers only.",
            },
          },
        },
      },
      historyLimit: 20,
      textChunkLimit: 2000,
      chunkMode: "length", // length | newline
      streaming: "off", // off | partial | block | progress (progress maps to partial on Discord)
      maxLinesPerMessage: 17,
      ui: {
        components: {
          accentColor: "#5865F2",
        },
      },
      threadBindings: {
        enabled: true,
        idleHours: 24,
        maxAgeHours: 0,
        spawnSubagentSessions: false, // opt-in for sessions_spawn({ thread: true })
      },
      voice: {
        enabled: true,
        autoJoin: [
          {
            guildId: "123456789012345678",
            channelId: "234567890123456789",
          },
        ],
        daveEncryption: true,
        decryptionFailureTolerance: 24,
        tts: {
          provider: "openai",
          openai: { voice: "alloy" },
        },
      },
      execApprovals: {
        enabled: "auto", // true | false | "auto"
        approvers: ["987654321098765432"],
        agentFilter: ["default"],
        sessionFilter: ["discord:"],
        target: "dm", // dm | channel | both
        cleanupAfterResolve: false,
      },
      retry: {
        attempts: 3,
        minDelayMs: 500,
        maxDelayMs: 30000,
        jitter: 0.1,
      },
    },
  },
}
  • Jeton : channels.discord.token, avec DISCORD_BOT_TOKEN comme solution de repli pour le compte par défaut.
  • Les appels sortants directs qui fournissent un token Discord explicite utilisent ce jeton pour l’appel ; les paramètres de nouvelle tentative/politique du compte proviennent toujours du compte sélectionné dans l’instantané d’exécution actif.
  • channels.discord.defaultAccount facultatif remplace la sélection du compte par défaut lorsqu’il correspond à un ID de compte configuré.
  • Utilisez user:<id> (DM) ou channel:<id> (canal de serveur) pour les cibles de livraison ; les ID numériques seuls sont rejetés.
  • Les slugs de serveur sont en minuscules avec les espaces remplacés par - ; les clés de canal utilisent le nom slugifié (sans #). Préférez les ID de serveur.
  • Les messages rédigés par des bots sont ignorés par défaut. allowBots: true les active ; utilisez allowBots: "mentions" pour n’accepter que les messages de bots qui mentionnent le bot (les propres messages restent filtrés).
  • channels.discord.guilds.<id>.ignoreOtherMentions (et les remplacements de canal) supprime les messages qui mentionnent un autre utilisateur ou rôle mais pas le bot (à l’exclusion de @everyone/@here).
  • maxLinesPerMessage (17 par défaut) découpe les messages hauts même lorsqu’ils font moins de 2000 caractères.
  • channels.discord.threadBindings contrôle le routage lié aux fils Discord :
    • enabled : remplacement Discord pour les fonctionnalités de session liées aux fils (/focus, /unfocus, /agents, /session idle, /session max-age, et la livraison/le routage liés)
    • idleHours : remplacement Discord pour le retrait automatique du focus après inactivité, en heures (0 désactive)
    • maxAgeHours : remplacement Discord pour l’âge maximal strict, en heures (0 désactive)
    • spawnSubagentSessions : option d’activation pour la création/liaison automatique de fil par sessions_spawn({ thread: true })
  • Les entrées bindings[] de niveau supérieur avec type: "acp" configurent des liaisons ACP persistantes pour les canaux et les fils (utilisez l’ID du canal/fil dans match.peer.id). La sémantique des champs est partagée dans Agents ACP.
  • channels.discord.ui.components.accentColor définit la couleur d’accentuation pour les conteneurs Discord components v2.
  • channels.discord.voice active les conversations dans les canaux vocaux Discord ainsi que les remplacements facultatifs d’auto-jonction + TTS.
  • channels.discord.voice.daveEncryption et channels.discord.voice.decryptionFailureTolerance sont transmis aux options DAVE de @discordjs/voice (true et 24 par défaut).
  • OpenClaw tente en outre une récupération de réception vocale en quittant puis en rejoignant à nouveau une session vocale après des échecs de déchiffrement répétés.
  • channels.discord.streaming est la clé canonique du mode de flux. Les anciennes valeurs booléennes streamMode et streaming sont migrées automatiquement.
  • channels.discord.autoPresence mappe la disponibilité d’exécution à la présence du bot (healthy => online, degraded => idle, exhausted => dnd) et autorise des remplacements facultatifs du texte de statut.
  • channels.discord.dangerouslyAllowNameMatching réactive la correspondance par nom/tag modifiable (mode de compatibilité de dernier recours).
  • channels.discord.execApprovals : livraison native Discord des approbations d’exécution et autorisation des approbateurs.
    • enabled : true, false ou "auto" (par défaut). En mode auto, les approbations d’exécution s’activent lorsque des approbateurs peuvent être résolus depuis approvers ou commands.ownerAllowFrom.
    • approvers : ID d’utilisateurs Discord autorisés à approuver des demandes d’exécution. Utilise commands.ownerAllowFrom comme solution de repli si omis.
    • agentFilter : liste d’autorisations facultative d’ID d’agent. Omettez-la pour transférer les approbations pour tous les agents.
    • sessionFilter : motifs facultatifs de clé de session (sous-chaîne ou regex).
    • target : emplacement d’envoi des invites d’approbation. "dm" (par défaut) les envoie aux DM des approbateurs, "channel" les envoie au canal d’origine, "both" les envoie aux deux. Lorsque la cible inclut "channel", les boutons ne sont utilisables que par les approbateurs résolus.
    • cleanupAfterResolve : lorsqu’il vaut true, supprime les DM d’approbation après approbation, refus ou expiration.
Modes de notification de réaction : off (aucun), own (messages du bot, par défaut), all (tous les messages), allowlist (depuis guilds.<id>.users sur tous les messages).

Google Chat

{
  channels: {
    googlechat: {
      enabled: true,
      serviceAccountFile: "/path/to/service-account.json",
      audienceType: "app-url", // app-url | project-number
      audience: "https://gateway.example.com/googlechat",
      webhookPath: "/googlechat",
      botUser: "users/1234567890",
      dm: {
        enabled: true,
        policy: "pairing",
        allowFrom: ["users/1234567890"],
      },
      groupPolicy: "allowlist",
      groups: {
        "spaces/AAAA": { allow: true, requireMention: true },
      },
      actions: { reactions: true },
      typingIndicator: "message",
      mediaMaxMb: 20,
    },
  },
}
  • JSON du compte de service : en ligne (serviceAccount) ou basé sur un fichier (serviceAccountFile).
  • SecretRef du compte de service est également pris en charge (serviceAccountRef).
  • Solutions de repli d’environnement : GOOGLE_CHAT_SERVICE_ACCOUNT ou GOOGLE_CHAT_SERVICE_ACCOUNT_FILE.
  • Utilisez spaces/<spaceId> ou users/<userId> pour les cibles de livraison.
  • channels.googlechat.dangerouslyAllowNameMatching réactive la correspondance par principal e-mail modifiable (mode de compatibilité de dernier recours).

Slack

{
  channels: {
    slack: {
      enabled: true,
      botToken: "xoxb-...",
      appToken: "xapp-...",
      dmPolicy: "pairing",
      allowFrom: ["U123", "U456", "*"],
      dm: { enabled: true, groupEnabled: false, groupChannels: ["G123"] },
      channels: {
        C123: { allow: true, requireMention: true, allowBots: false },
        "#general": {
          allow: true,
          requireMention: true,
          allowBots: false,
          users: ["U123"],
          skills: ["docs"],
          systemPrompt: "Short answers only.",
        },
      },
      historyLimit: 50,
      allowBots: false,
      reactionNotifications: "own",
      reactionAllowlist: ["U123"],
      replyToMode: "off", // off | first | all | batched
      thread: {
        historyScope: "thread", // thread | channel
        inheritParent: false,
      },
      actions: {
        reactions: true,
        messages: true,
        pins: true,
        memberInfo: true,
        emojiList: true,
      },
      slashCommand: {
        enabled: true,
        name: "openclaw",
        sessionPrefix: "slack:slash",
        ephemeral: true,
      },
      typingReaction: "hourglass_flowing_sand",
      textChunkLimit: 4000,
      chunkMode: "length",
      streaming: {
        mode: "partial", // off | partial | block | progress
        nativeTransport: true, // use Slack native streaming API when mode=partial
      },
      mediaMaxMb: 20,
      execApprovals: {
        enabled: "auto", // true | false | "auto"
        approvers: ["U123"],
        agentFilter: ["default"],
        sessionFilter: ["slack:"],
        target: "dm", // dm | channel | both
      },
    },
  },
}
  • Le mode socket nécessite botToken et appToken (SLACK_BOT_TOKEN + SLACK_APP_TOKEN pour la solution de repli d’environnement du compte par défaut).
  • Le mode HTTP nécessite botToken plus signingSecret (à la racine ou par compte).
  • botToken, appToken, signingSecret et userToken acceptent des chaînes en texte brut ou des objets SecretRef.
  • Les instantanés de compte Slack exposent des champs de source/état par identifiant comme botTokenSource, botTokenStatus, appTokenStatus et, en mode HTTP, signingSecretStatus. configured_unavailable signifie que le compte est configuré via SecretRef, mais que le chemin de commande/d’exécution actuel n’a pas pu résoudre la valeur secrète.
  • configWrites: false bloque les écritures de configuration initiées par Slack.
  • channels.slack.defaultAccount facultatif remplace la sélection du compte par défaut lorsqu’il correspond à un ID de compte configuré.
  • channels.slack.streaming.mode est la clé canonique du mode de flux Slack. channels.slack.streaming.nativeTransport contrôle le transport de flux natif de Slack. Les anciennes valeurs streamMode, booléennes streaming et nativeStreaming sont migrées automatiquement.
  • Utilisez user:<id> (DM) ou channel:<id> pour les cibles de livraison.
Modes de notification de réaction : off, own (par défaut), all, allowlist (depuis reactionAllowlist). Isolation des sessions de fil : thread.historyScope est par fil (par défaut) ou partagé à l’échelle du canal. thread.inheritParent copie la transcription du canal parent vers les nouveaux fils.
  • Le flux natif Slack ainsi que l’état de fil Slack de type assistant « is typing… » nécessitent une cible de réponse dans un fil. Les DM de niveau supérieur restent hors fil par défaut ; ils utilisent donc typingReaction ou la livraison normale au lieu de l’aperçu de style fil.
  • typingReaction ajoute une réaction temporaire au message Slack entrant pendant l’exécution d’une réponse, puis la supprime à la fin. Utilisez un shortcode d’emoji Slack tel que "hourglass_flowing_sand".
  • channels.slack.execApprovals : livraison native Slack des approbations d’exécution et autorisation des approbateurs. Même schéma que Discord : enabled (true/false/"auto"), approvers (ID d’utilisateurs Slack), agentFilter, sessionFilter et target ("dm", "channel" ou "both").
Groupe d’actionsPar défautRemarques
reactionsactivéRéagir + lister les réactions
messagesactivéLire/envoyer/modifier/supprimer
pinsactivéÉpingler/désépingler/lister
memberInfoactivéInformations sur le membre
emojiListactivéListe des emojis personnalisés

Mattermost

Mattermost est distribué comme plugin : openclaw plugins install @openclaw/mattermost.
{
  channels: {
    mattermost: {
      enabled: true,
      botToken: "mm-token",
      baseUrl: "https://chat.example.com",
      dmPolicy: "pairing",
      chatmode: "oncall", // oncall | onmessage | onchar
      oncharPrefixes: [">", "!"],
      groups: {
        "*": { requireMention: true },
        "team-channel-id": { requireMention: false },
      },
      commands: {
        native: true, // opt-in
        nativeSkills: true,
        callbackPath: "/api/channels/mattermost/command",
        // Optional explicit URL for reverse-proxy/public deployments
        callbackUrl: "https://gateway.example.com/api/channels/mattermost/command",
      },
      textChunkLimit: 4000,
      chunkMode: "length",
    },
  },
}
Modes de chat : oncall (répond sur @-mention, par défaut), onmessage (chaque message), onchar (messages commençant par un préfixe de déclenchement). Lorsque les commandes natives Mattermost sont activées :
  • commands.callbackPath doit être un chemin (par exemple /api/channels/mattermost/command), et non une URL complète.
  • commands.callbackUrl doit résoudre vers le point de terminaison de passerelle OpenClaw et être accessible depuis le serveur Mattermost.
  • Les rappels slash natifs sont authentifiés avec les jetons par commande renvoyés par Mattermost lors de l’enregistrement de la commande slash. Si l’enregistrement échoue ou si aucune commande n’est activée, OpenClaw rejette les rappels avec Unauthorized: invalid command token.
  • Pour les hôtes de rappel privés/tailnet/internes, Mattermost peut exiger que ServiceSettings.AllowedUntrustedInternalConnections inclue l’hôte/domaine de rappel. Utilisez des valeurs hôte/domaine, et non des URL complètes.
  • channels.mattermost.configWrites : autorise ou refuse les écritures de configuration initiées par Mattermost.
  • channels.mattermost.requireMention : exige une @mention avant de répondre dans les canaux.
  • channels.mattermost.groups.<channelId>.requireMention : remplacement par canal du filtrage par mention ("*" pour la valeur par défaut).
  • channels.mattermost.defaultAccount facultatif remplace la sélection du compte par défaut lorsqu’il correspond à un ID de compte configuré.

Signal

{
  channels: {
    signal: {
      enabled: true,
      account: "+15555550123", // optional account binding
      dmPolicy: "pairing",
      allowFrom: ["+15551234567", "uuid:123e4567-e89b-12d3-a456-426614174000"],
      configWrites: true,
      reactionNotifications: "own", // off | own | all | allowlist
      reactionAllowlist: ["+15551234567", "uuid:123e4567-e89b-12d3-a456-426614174000"],
      historyLimit: 50,
    },
  },
}
Modes de notification de réaction : off, own (par défaut), all, allowlist (depuis reactionAllowlist).
  • channels.signal.account : épingle le démarrage du canal à une identité de compte Signal spécifique.
  • channels.signal.configWrites : autorise ou refuse les écritures de configuration initiées par Signal.
  • channels.signal.defaultAccount facultatif remplace la sélection du compte par défaut lorsqu’il correspond à un ID de compte configuré.

BlueBubbles

BlueBubbles est le chemin recommandé pour iMessage (pris en charge par un plugin, configuré sous channels.bluebubbles).
{
  channels: {
    bluebubbles: {
      enabled: true,
      dmPolicy: "pairing",
      // serverUrl, password, webhookPath, group controls, and advanced actions:
      // see /channels/bluebubbles
    },
  },
}
  • Chemins de clés principaux couverts ici : channels.bluebubbles, channels.bluebubbles.dmPolicy.
  • channels.bluebubbles.defaultAccount facultatif remplace la sélection du compte par défaut lorsqu’il correspond à un ID de compte configuré.
  • Les entrées bindings[] de niveau supérieur avec type: "acp" peuvent lier des conversations BlueBubbles à des sessions ACP persistantes. Utilisez un handle BlueBubbles ou une chaîne cible (chat_id:*, chat_guid:*, chat_identifier:*) dans match.peer.id. Sémantique de champ partagée : Agents ACP.
  • La configuration complète du canal BlueBubbles est documentée dans BlueBubbles.

iMessage

OpenClaw lance imsg rpc (JSON-RPC sur stdio). Aucun démon ni port n’est requis.
{
  channels: {
    imessage: {
      enabled: true,
      cliPath: "imsg",
      dbPath: "~/Library/Messages/chat.db",
      remoteHost: "user@gateway-host",
      dmPolicy: "pairing",
      allowFrom: ["+15555550123", "user@example.com", "chat_id:123"],
      historyLimit: 50,
      includeAttachments: false,
      attachmentRoots: ["/Users/*/Library/Messages/Attachments"],
      remoteAttachmentRoots: ["/Users/*/Library/Messages/Attachments"],
      mediaMaxMb: 16,
      service: "auto",
      region: "US",
    },
  },
}
  • channels.imessage.defaultAccount facultatif remplace la sélection du compte par défaut lorsqu’il correspond à un ID de compte configuré.
  • Nécessite un accès complet au disque pour la base de données Messages.
  • Préférez les cibles chat_id:<id>. Utilisez imsg chats --limit 20 pour lister les conversations.
  • cliPath peut pointer vers un wrapper SSH ; définissez remoteHost (host ou user@host) pour la récupération SCP des pièces jointes.
  • attachmentRoots et remoteAttachmentRoots restreignent les chemins des pièces jointes entrantes (par défaut : /Users/*/Library/Messages/Attachments).
  • SCP utilise une vérification stricte des clés d’hôte ; assurez-vous donc que la clé d’hôte du relais existe déjà dans ~/.ssh/known_hosts.
  • channels.imessage.configWrites : autorise ou refuse les écritures de configuration initiées par iMessage.
  • Les entrées bindings[] de niveau supérieur avec type: "acp" peuvent lier des conversations iMessage à des sessions ACP persistantes. Utilisez un handle normalisé ou une cible de conversation explicite (chat_id:*, chat_guid:*, chat_identifier:*) dans match.peer.id. Sémantique de champ partagée : Agents ACP.
#!/usr/bin/env bash
exec ssh -T gateway-host imsg "$@"

Matrix

Matrix est pris en charge par une extension et configuré sous channels.matrix.
{
  channels: {
    matrix: {
      enabled: true,
      homeserver: "https://matrix.example.org",
      accessToken: "syt_bot_xxx",
      proxy: "http://127.0.0.1:7890",
      encryption: true,
      initialSyncLimit: 20,
      defaultAccount: "ops",
      accounts: {
        ops: {
          name: "Ops",
          userId: "@ops:example.org",
          accessToken: "syt_ops_xxx",
        },
        alerts: {
          userId: "@alerts:example.org",
          password: "secret",
          proxy: "http://127.0.0.1:7891",
        },
      },
    },
  },
}
  • L’authentification par jeton utilise accessToken ; l’authentification par mot de passe utilise userId + password.
  • channels.matrix.proxy achemine le trafic HTTP Matrix via un proxy HTTP(S) explicite. Les comptes nommés peuvent le remplacer avec channels.matrix.accounts.<id>.proxy.
  • channels.matrix.network.dangerouslyAllowPrivateNetwork autorise les homeservers privés/internes. proxy et cette activation réseau sont des contrôles indépendants.
  • channels.matrix.defaultAccount sélectionne le compte préféré dans les configurations multi-comptes.
  • channels.matrix.autoJoin vaut par défaut off, donc les salons invités et les nouvelles invitations de type DM sont ignorés jusqu’à ce que vous définissiez autoJoin: "allowlist" avec autoJoinAllowlist ou autoJoin: "always".
  • channels.matrix.execApprovals : livraison native Matrix des approbations d’exécution et autorisation des approbateurs.
    • enabled : true, false ou "auto" (par défaut). En mode auto, les approbations d’exécution s’activent lorsque des approbateurs peuvent être résolus depuis approvers ou commands.ownerAllowFrom.
    • approvers : ID d’utilisateurs Matrix (par ex. @owner:example.org) autorisés à approuver des demandes d’exécution.
    • agentFilter : liste d’autorisations facultative d’ID d’agent. Omettez-la pour transférer les approbations pour tous les agents.
    • sessionFilter : motifs facultatifs de clé de session (sous-chaîne ou regex).
    • target : emplacement d’envoi des invites d’approbation. "dm" (par défaut), "channel" (salon d’origine) ou "both".
    • Remplacements par compte : channels.matrix.accounts.<id>.execApprovals.
  • channels.matrix.dm.sessionScope contrôle la manière dont les DM Matrix sont regroupés en sessions : per-user (par défaut) partage par pair routé, tandis que per-room isole chaque salon DM.
  • Les sondes d’état Matrix et les consultations de répertoire en direct utilisent la même politique de proxy que le trafic d’exécution.
  • La configuration complète de Matrix, les règles de ciblage et les exemples d’installation sont documentés dans Matrix.

Microsoft Teams

Microsoft Teams est pris en charge par une extension et configuré sous channels.msteams.
{
  channels: {
    msteams: {
      enabled: true,
      configWrites: true,
      // appId, appPassword, tenantId, webhook, team/channel policies:
      // see /channels/msteams
    },
  },
}
  • Chemins de clés principaux couverts ici : channels.msteams, channels.msteams.configWrites.
  • La configuration complète de Teams (identifiants, webhook, politique DM/groupe, remplacements par équipe/par canal) est documentée dans Microsoft Teams.

IRC

IRC est pris en charge par une extension et configuré sous channels.irc.
{
  channels: {
    irc: {
      enabled: true,
      dmPolicy: "pairing",
      configWrites: true,
      nickserv: {
        enabled: true,
        service: "NickServ",
        password: "${IRC_NICKSERV_PASSWORD}",
        register: false,
        registerEmail: "bot@example.com",
      },
    },
  },
}
  • Chemins de clés principaux couverts ici : channels.irc, channels.irc.dmPolicy, channels.irc.configWrites, channels.irc.nickserv.*.
  • channels.irc.defaultAccount facultatif remplace la sélection du compte par défaut lorsqu’il correspond à un ID de compte configuré.
  • La configuration complète du canal IRC (hôte/port/TLS/canaux/listes d’autorisations/filtrage par mention) est documentée dans IRC.

Multi-compte (tous les canaux)

Exécutez plusieurs comptes par canal (chacun avec son propre accountId) :
{
  channels: {
    telegram: {
      accounts: {
        default: {
          name: "Primary bot",
          botToken: "123456:ABC...",
        },
        alerts: {
          name: "Alerts bot",
          botToken: "987654:XYZ...",
        },
      },
    },
  },
}
  • default est utilisé lorsque accountId est omis (CLI + routage).
  • Les jetons d’environnement s’appliquent uniquement au compte default.
  • Les paramètres de canal de base s’appliquent à tous les comptes sauf remplacement par compte.
  • Utilisez bindings[].match.accountId pour router chaque compte vers un agent différent.
  • Si vous ajoutez un compte non par défaut via openclaw channels add (ou l’intégration du canal) alors que vous utilisez encore une configuration de canal de niveau supérieur à compte unique, OpenClaw promeut d’abord les valeurs de niveau supérieur à compte unique limitées au compte dans la map de comptes du canal afin que le compte d’origine continue de fonctionner. La plupart des canaux les déplacent vers channels.<channel>.accounts.default ; Matrix peut à la place conserver une cible nommée/par défaut existante correspondante.
  • Les liaisons existantes limitées au canal (sans accountId) continuent de correspondre au compte par défaut ; les liaisons limitées au compte restent facultatives.
  • openclaw doctor --fix répare également les formes mixtes en déplaçant les valeurs de niveau supérieur à compte unique limitées au compte vers le compte promu choisi pour ce canal. La plupart des canaux utilisent accounts.default ; Matrix peut à la place conserver une cible nommée/par défaut existante correspondante.

Autres canaux d’extension

De nombreux canaux d’extension sont configurés sous la forme channels.<id> et documentés dans leurs pages de canal dédiées (par exemple Feishu, Matrix, LINE, Nostr, Zalo, Nextcloud Talk, Synology Chat et Twitch). Consultez l’index complet des canaux : Canaux.

Filtrage par mention dans les discussions de groupe

Par défaut, les messages de groupe nécessitent une mention (mention de métadonnées ou modèles regex sûrs). Cela s’applique aux discussions de groupe WhatsApp, Telegram, Discord, Google Chat et iMessage. Types de mention :
  • Mentions de métadonnées : @-mentions natives de la plateforme. Ignorées en mode auto-discussion WhatsApp.
  • Modèles de texte : modèles regex sûrs dans agents.list[].groupChat.mentionPatterns. Les modèles invalides et les répétitions imbriquées non sûres sont ignorés.
  • Le filtrage par mention n’est appliqué que lorsque la détection est possible (mentions natives ou au moins un modèle).
{
  messages: {
    groupChat: { historyLimit: 50 },
  },
  agents: {
    list: [{ id: "main", groupChat: { mentionPatterns: ["@openclaw", "openclaw"] } }],
  },
}
messages.groupChat.historyLimit définit la valeur globale par défaut. Les canaux peuvent la remplacer avec channels.<channel>.historyLimit (ou par compte). Définissez 0 pour désactiver.

Limites d’historique des DM

{
  channels: {
    telegram: {
      dmHistoryLimit: 30,
      dms: {
        "123456789": { historyLimit: 50 },
      },
    },
  },
}
Résolution : remplacement par DM → valeur par défaut du fournisseur → pas de limite (tout est conservé). Pris en charge : telegram, whatsapp, discord, slack, signal, imessage, msteams.

Mode auto-discussion

Incluez votre propre numéro dans allowFrom pour activer le mode auto-discussion (ignore les @-mentions natives, répond uniquement aux modèles de texte) :
{
  channels: {
    whatsapp: {
      allowFrom: ["+15555550123"],
      groups: { "*": { requireMention: true } },
    },
  },
  agents: {
    list: [
      {
        id: "main",
        groupChat: { mentionPatterns: ["reisponde", "@openclaw"] },
      },
    ],
  },
}

Commandes (gestion des commandes de chat)

{
  commands: {
    native: "auto", // register native commands when supported
    nativeSkills: "auto", // register native skill commands when supported
    text: true, // parse /commands in chat messages
    bash: false, // allow ! (alias: /bash)
    bashForegroundMs: 2000,
    config: false, // allow /config
    mcp: false, // allow /mcp
    plugins: false, // allow /plugins
    debug: false, // allow /debug
    restart: true, // allow /restart + gateway restart tool
    ownerAllowFrom: ["discord:123456789012345678"],
    ownerDisplay: "raw", // raw | hash
    ownerDisplaySecret: "${OWNER_ID_HASH_SECRET}",
    allowFrom: {
      "*": ["user1"],
      discord: ["user:123"],
    },
    useAccessGroups: true,
  },
}
  • Ce bloc configure les surfaces de commande. Pour le catalogue actuel des commandes intégrées + groupées, consultez Commandes Slash.
  • Cette page est une référence des clés de configuration, et non le catalogue complet des commandes. Les commandes appartenant à un canal/plugin telles que QQ Bot /bot-ping /bot-help /bot-logs, LINE /card, device-pair /pair, memory /dreaming, phone-control /phone et Talk /voice sont documentées dans leurs pages de canal/plugin ainsi que dans Commandes Slash.
  • Les commandes texte doivent être des messages autonomes avec un / initial.
  • native: "auto" active les commandes natives pour Discord/Telegram, et laisse Slack désactivé.
  • nativeSkills: "auto" active les commandes de Skills natives pour Discord/Telegram, et laisse Slack désactivé.
  • Remplacement par canal : channels.discord.commands.native (booléen ou "auto"). false efface les commandes précédemment enregistrées.
  • Remplacez l’enregistrement natif des Skills par canal avec channels.<provider>.commands.nativeSkills.
  • channels.telegram.customCommands ajoute des entrées supplémentaires au menu du bot Telegram.
  • bash: true active ! <cmd> pour le shell hôte. Nécessite tools.elevated.enabled et que l’expéditeur soit dans tools.elevated.allowFrom.<channel>.
  • config: true active /config (lit/écrit openclaw.json). Pour les clients de passerelle chat.send, les écritures persistantes /config set|unset nécessitent également operator.admin ; le /config show en lecture seule reste disponible pour les clients opérateur normaux avec portée d’écriture.
  • mcp: true active /mcp pour la configuration des serveurs MCP gérés par OpenClaw sous mcp.servers.
  • plugins: true active /plugins pour la découverte, l’installation, et les contrôles d’activation/désactivation des plugins.
  • channels.<provider>.configWrites contrôle les mutations de configuration par canal (par défaut : true).
  • Pour les canaux multi-comptes, channels.<provider>.accounts.<id>.configWrites contrôle également les écritures qui ciblent ce compte (par exemple /allowlist --config --account <id> ou /config set channels.<provider>.accounts.<id>...).
  • restart: false désactive /restart et les actions de l’outil de redémarrage de la passerelle. Par défaut : true.
  • ownerAllowFrom est la liste d’autorisations explicite du propriétaire pour les commandes/outils réservés au propriétaire. Elle est distincte de allowFrom.
  • ownerDisplay: "hash" hache les ID du propriétaire dans le prompt système. Définissez ownerDisplaySecret pour contrôler le hachage.
  • allowFrom est défini par fournisseur. Lorsqu’il est défini, c’est la seule source d’autorisation (les listes d’autorisations/appairages de canal et useAccessGroups sont ignorés).
  • useAccessGroups: false permet aux commandes de contourner les politiques de groupes d’accès lorsque allowFrom n’est pas défini.
  • Cartographie de la documentation des commandes :

Valeurs par défaut des agents

agents.defaults.workspace

Par défaut : ~/.openclaw/workspace.
{
  agents: { defaults: { workspace: "~/.openclaw/workspace" } },
}

agents.defaults.repoRoot

Racine de dépôt facultative affichée dans la ligne Runtime du prompt système. Si elle n’est pas définie, OpenClaw la détecte automatiquement en remontant depuis l’espace de travail.
{
  agents: { defaults: { repoRoot: "~/Projects/openclaw" } },
}

agents.defaults.skills

Liste d’autorisations par défaut facultative des Skills pour les agents qui ne définissent pas agents.list[].skills.
{
  agents: {
    defaults: { skills: ["github", "weather"] },
    list: [
      { id: "writer" }, // hérite de github, weather
      { id: "docs", skills: ["docs-search"] }, // remplace les valeurs par défaut
      { id: "locked-down", skills: [] }, // aucun Skills
    ],
  },
}
  • Omettez agents.defaults.skills pour des Skills non restreints par défaut.
  • Omettez agents.list[].skills pour hériter des valeurs par défaut.
  • Définissez agents.list[].skills: [] pour aucun Skills.
  • Une liste non vide dans agents.list[].skills constitue l’ensemble final pour cet agent ; elle n’est pas fusionnée avec les valeurs par défaut.

agents.defaults.skipBootstrap

Désactive la création automatique des fichiers bootstrap de l’espace de travail (AGENTS.md, SOUL.md, TOOLS.md, IDENTITY.md, USER.md, HEARTBEAT.md, BOOTSTRAP.md).
{
  agents: { defaults: { skipBootstrap: true } },
}

agents.defaults.contextInjection

Contrôle quand les fichiers bootstrap de l’espace de travail sont injectés dans le prompt système. Par défaut : "always".
  • "continuation-skip" : les tours de continuation sûrs (après une réponse d’assistant terminée) ignorent la réinjection du bootstrap de l’espace de travail, ce qui réduit la taille du prompt. Les exécutions heartbeat et les nouvelles tentatives après compactage reconstruisent toujours le contexte.
{
  agents: { defaults: { contextInjection: "continuation-skip" } },
}

agents.defaults.bootstrapMaxChars

Nombre maximal de caractères par fichier bootstrap de l’espace de travail avant troncature. Par défaut : 20000.
{
  agents: { defaults: { bootstrapMaxChars: 20000 } },
}

agents.defaults.bootstrapTotalMaxChars

Nombre total maximal de caractères injectés sur l’ensemble des fichiers bootstrap de l’espace de travail. Par défaut : 150000.
{
  agents: { defaults: { bootstrapTotalMaxChars: 150000 } },
}

agents.defaults.bootstrapPromptTruncationWarning

Contrôle le texte d’avertissement visible par l’agent lorsque le contexte bootstrap est tronqué. Par défaut : "once".
  • "off" : ne jamais injecter de texte d’avertissement dans le prompt système.
  • "once" : injecter l’avertissement une fois par signature de troncature unique (recommandé).
  • "always" : injecter l’avertissement à chaque exécution lorsqu’une troncature existe.
{
  agents: { defaults: { bootstrapPromptTruncationWarning: "once" } }, // off | once | always
}

agents.defaults.imageMaxDimensionPx

Taille maximale en pixels du plus long côté d’une image dans les blocs image de transcription/outil avant les appels fournisseur. Par défaut : 1200. Des valeurs plus faibles réduisent généralement l’utilisation de jetons de vision et la taille de la charge utile des requêtes pour les exécutions riches en captures d’écran. Des valeurs plus élevées préservent davantage de détails visuels.
{
  agents: { defaults: { imageMaxDimensionPx: 1200 } },
}

agents.defaults.userTimezone

Fuseau horaire pour le contexte du prompt système (pas pour les horodatages des messages). Utilise le fuseau horaire de l’hôte comme solution de repli.
{
  agents: { defaults: { userTimezone: "America/Chicago" } },
}

agents.defaults.timeFormat

Format de l’heure dans le prompt système. Par défaut : auto (préférence du système d’exploitation).
{
  agents: { defaults: { timeFormat: "auto" } }, // auto | 12 | 24
}

agents.defaults.model

{
  agents: {
    defaults: {
      models: {
        "anthropic/claude-opus-4-6": { alias: "opus" },
        "minimax/MiniMax-M2.7": { alias: "minimax" },
      },
      model: {
        primary: "anthropic/claude-opus-4-6",
        fallbacks: ["minimax/MiniMax-M2.7"],
      },
      imageModel: {
        primary: "openrouter/qwen/qwen-2.5-vl-72b-instruct:free",
        fallbacks: ["openrouter/google/gemini-2.0-flash-vision:free"],
      },
      imageGenerationModel: {
        primary: "openai/gpt-image-1",
        fallbacks: ["google/gemini-3.1-flash-image-preview"],
      },
      videoGenerationModel: {
        primary: "qwen/wan2.6-t2v",
        fallbacks: ["qwen/wan2.6-i2v"],
      },
      pdfModel: {
        primary: "anthropic/claude-opus-4-6",
        fallbacks: ["openai/gpt-5.4-mini"],
      },
      params: { cacheRetention: "long" }, // paramètres fournisseur globaux par défaut
      pdfMaxBytesMb: 10,
      pdfMaxPages: 20,
      thinkingDefault: "low",
      verboseDefault: "off",
      elevatedDefault: "on",
      timeoutSeconds: 600,
      mediaMaxMb: 5,
      contextTokens: 200000,
      maxConcurrent: 3,
    },
  },
}
  • model : accepte soit une chaîne ("provider/model"), soit un objet ({ primary, fallbacks }).
    • La forme chaîne définit uniquement le modèle principal.
    • La forme objet définit le modèle principal ainsi que des modèles de bascule ordonnés.
  • imageModel : accepte soit une chaîne ("provider/model"), soit un objet ({ primary, fallbacks }).
    • Utilisé par le chemin de l’outil image comme configuration de son modèle de vision.
    • Également utilisé comme routage de repli lorsque le modèle sélectionné/par défaut ne peut pas accepter d’entrée image.
  • imageGenerationModel : accepte soit une chaîne ("provider/model"), soit un objet ({ primary, fallbacks }).
    • Utilisé par la capacité partagée de génération d’images et toute future surface d’outil/plugin qui génère des images.
    • Valeurs typiques : google/gemini-3.1-flash-image-preview pour la génération d’images Gemini native, fal/fal-ai/flux/dev pour fal, ou openai/gpt-image-1 pour OpenAI Images.
    • Si vous sélectionnez directement un provider/modèle, configurez également l’authentification/la clé API du provider correspondant (par exemple GEMINI_API_KEY ou GOOGLE_API_KEY pour google/*, OPENAI_API_KEY pour openai/*, FAL_KEY pour fal/*).
    • Si omis, image_generate peut tout de même déduire une valeur par défaut de provider avec authentification. Il essaie d’abord le provider par défaut actuel, puis les autres providers de génération d’images enregistrés dans l’ordre des ID de provider.
  • musicGenerationModel : accepte soit une chaîne ("provider/model"), soit un objet ({ primary, fallbacks }).
    • Utilisé par la capacité partagée de génération musicale et l’outil intégré music_generate.
    • Valeurs typiques : google/lyria-3-clip-preview, google/lyria-3-pro-preview, ou minimax/music-2.5+.
    • Si omis, music_generate peut tout de même déduire une valeur par défaut de provider avec authentification. Il essaie d’abord le provider par défaut actuel, puis les autres providers de génération musicale enregistrés dans l’ordre des ID de provider.
    • Si vous sélectionnez directement un provider/modèle, configurez également l’authentification/la clé API du provider correspondant.
  • videoGenerationModel : accepte soit une chaîne ("provider/model"), soit un objet ({ primary, fallbacks }).
    • Utilisé par la capacité partagée de génération vidéo et l’outil intégré video_generate.
    • Valeurs typiques : qwen/wan2.6-t2v, qwen/wan2.6-i2v, qwen/wan2.6-r2v, qwen/wan2.6-r2v-flash, ou qwen/wan2.7-r2v.
    • Si omis, video_generate peut tout de même déduire une valeur par défaut de provider avec authentification. Il essaie d’abord le provider par défaut actuel, puis les autres providers de génération vidéo enregistrés dans l’ordre des ID de provider.
    • Si vous sélectionnez directement un provider/modèle, configurez également l’authentification/la clé API du provider correspondant.
    • Le provider groupé de génération vidéo Qwen prend en charge jusqu’à 1 vidéo de sortie, 1 image d’entrée, 4 vidéos d’entrée, une durée de 10 secondes, ainsi que les options de niveau provider size, aspectRatio, resolution, audio et watermark.
  • pdfModel : accepte soit une chaîne ("provider/model"), soit un objet ({ primary, fallbacks }).
    • Utilisé par l’outil pdf pour le routage du modèle.
    • Si omis, l’outil PDF se replie sur imageModel, puis sur le modèle de session/par défaut résolu.
  • pdfMaxBytesMb : limite de taille PDF par défaut pour l’outil pdf lorsque maxBytesMb n’est pas transmis au moment de l’appel.
  • pdfMaxPages : nombre maximal de pages par défaut pris en compte par le mode de repli d’extraction dans l’outil pdf.
  • verboseDefault : niveau détaillé par défaut pour les agents. Valeurs : "off", "on", "full". Par défaut : "off".
  • elevatedDefault : niveau de sortie élevée par défaut pour les agents. Valeurs : "off", "on", "ask", "full". Par défaut : "on".
  • model.primary : format provider/model (par ex. openai/gpt-5.4). Si vous omettez le provider, OpenClaw essaie d’abord un alias, puis une correspondance unique de provider configuré pour cet ID de modèle exact, et seulement ensuite revient au provider par défaut configuré (comportement de compatibilité obsolète, donc préférez provider/model explicite). Si ce provider n’expose plus le modèle par défaut configuré, OpenClaw se replie sur le premier provider/modèle configuré au lieu d’exposer une valeur par défaut obsolète d’un provider supprimé.
  • models : catalogue de modèles configuré et liste d’autorisations pour /model. Chaque entrée peut inclure alias (raccourci) et params (spécifiques au provider, par exemple temperature, maxTokens, cacheRetention, context1m).
  • params : paramètres provider globaux par défaut appliqués à tous les modèles. Définis dans agents.defaults.params (par ex. { cacheRetention: "long" }).
  • Priorité de fusion de params (configuration) : agents.defaults.params (base globale) est remplacé par agents.defaults.models["provider/model"].params (par modèle), puis agents.list[].params (ID d’agent correspondant) remplace par clé. Consultez Mise en cache des prompts pour plus de détails.
  • Les outils d’écriture de configuration qui mutent ces champs (par exemple /models set, /models set-image et les commandes d’ajout/suppression de repli) enregistrent la forme objet canonique et préservent les listes de repli existantes lorsque c’est possible.
  • maxConcurrent : nombre maximal d’exécutions d’agent parallèles entre les sessions (chaque session reste sérialisée). Par défaut : 4.
Alias raccourcis intégrés (s’appliquent uniquement lorsque le modèle est dans agents.defaults.models) :
AliasModèle
opusanthropic/claude-opus-4-6
sonnetanthropic/claude-sonnet-4-6
gptopenai/gpt-5.4
gpt-miniopenai/gpt-5.4-mini
gpt-nanoopenai/gpt-5.4-nano
geminigoogle/gemini-3.1-pro-preview
gemini-flashgoogle/gemini-3-flash-preview
gemini-flash-litegoogle/gemini-3.1-flash-lite-preview
Vos alias configurés ont toujours priorité sur les valeurs par défaut. Les modèles Z.AI GLM-4.x activent automatiquement le mode réflexion, sauf si vous définissez --thinking off ou si vous définissez vous-même agents.defaults.models["zai/<model>"].params.thinking. Les modèles Z.AI activent tool_stream par défaut pour le streaming des appels d’outils. Définissez agents.defaults.models["zai/<model>"].params.tool_stream sur false pour le désactiver. Les modèles Anthropic Claude 4.6 utilisent par défaut la réflexion adaptive lorsqu’aucun niveau de réflexion explicite n’est défini.

agents.defaults.cliBackends

Backends CLI facultatifs pour les exécutions de repli texte uniquement (sans appels d’outils). Utiles comme sauvegarde lorsque les providers d’API échouent.
{
  agents: {
    defaults: {
      cliBackends: {
        "codex-cli": {
          command: "/opt/homebrew/bin/codex",
        },
        "my-cli": {
          command: "my-cli",
          args: ["--json"],
          output: "json",
          modelArg: "--model",
          sessionArg: "--session",
          sessionMode: "existing",
          systemPromptArg: "--system",
          systemPromptWhen: "first",
          imageArg: "--image",
          imageMode: "repeat",
        },
      },
    },
  },
}
  • Les backends CLI sont orientés texte ; les outils sont toujours désactivés.
  • Les sessions sont prises en charge lorsque sessionArg est défini.
  • Le passage d’image est pris en charge lorsque imageArg accepte des chemins de fichier.

agents.defaults.systemPromptOverride

Remplace l’intégralité du prompt système assemblé par OpenClaw par une chaîne fixe. À définir au niveau par défaut (agents.defaults.systemPromptOverride) ou par agent (agents.list[].systemPromptOverride). Les valeurs par agent ont priorité ; une valeur vide ou contenant uniquement des espaces est ignorée. Utile pour des expériences contrôlées sur les prompts.
{
  agents: {
    defaults: {
      systemPromptOverride: "You are a helpful assistant.",
    },
  },
}

agents.defaults.heartbeat

Exécutions heartbeat périodiques.
{
  agents: {
    defaults: {
      heartbeat: {
        every: "30m", // 0m disables
        model: "openai/gpt-5.4-mini",
        includeReasoning: false,
        includeSystemPromptSection: true, // default: true; false omits the Heartbeat section from the system prompt
        lightContext: false, // default: false; true keeps only HEARTBEAT.md from workspace bootstrap files
        isolatedSession: false, // default: false; true runs each heartbeat in a fresh session (no conversation history)
        session: "main",
        to: "+15555550123",
        directPolicy: "allow", // allow (default) | block
        target: "none", // default: none | options: last | whatsapp | telegram | discord | ...
        prompt: "Read HEARTBEAT.md if it exists...",
        ackMaxChars: 300,
        suppressToolErrorWarnings: false,
      },
    },
  },
}
  • every : chaîne de durée (ms/s/m/h). Par défaut : 30m (authentification par clé API) ou 1h (authentification OAuth). Définissez 0m pour désactiver.
  • includeSystemPromptSection : lorsque false, omet la section Heartbeat du prompt système et ignore l’injection de HEARTBEAT.md dans le contexte bootstrap. Par défaut : true.
  • suppressToolErrorWarnings : lorsque true, supprime les charges utiles d’avertissement d’erreur d’outil pendant les exécutions heartbeat.
  • directPolicy : politique de livraison directe/DM. allow (par défaut) autorise la livraison à cible directe. block supprime la livraison à cible directe et émet reason=dm-blocked.
  • lightContext : lorsque true, les exécutions heartbeat utilisent un contexte bootstrap léger et ne conservent que HEARTBEAT.md parmi les fichiers bootstrap de l’espace de travail.
  • isolatedSession : lorsque true, chaque exécution heartbeat se fait dans une session fraîche sans historique de conversation préalable. Même schéma d’isolation que le cron sessionTarget: "isolated". Réduit le coût en jetons par heartbeat d’environ 100K à environ 2-5K jetons.
  • Par agent : définissez agents.list[].heartbeat. Lorsqu’un agent quelconque définit heartbeat, seuls ces agents exécutent des heartbeats.
  • Les heartbeats exécutent des tours d’agent complets — des intervalles plus courts consomment plus de jetons.

agents.defaults.compaction

{
  agents: {
    defaults: {
      compaction: {
        mode: "safeguard", // default | safeguard
        provider: "my-provider", // id of a registered compaction provider plugin (optional)
        timeoutSeconds: 900,
        reserveTokensFloor: 24000,
        identifierPolicy: "strict", // strict | off | custom
        identifierInstructions: "Preserve deployment IDs, ticket IDs, and host:port pairs exactly.", // used when identifierPolicy=custom
        postCompactionSections: ["Session Startup", "Red Lines"], // [] disables reinjection
        model: "openrouter/anthropic/claude-sonnet-4-6", // optional compaction-only model override
        notifyUser: true, // send a brief notice when compaction starts (default: false)
        memoryFlush: {
          enabled: true,
          softThresholdTokens: 6000,
          systemPrompt: "Session nearing compaction. Store durable memories now.",
          prompt: "Write any lasting notes to memory/YYYY-MM-DD.md; reply with the exact silent token NO_REPLY if nothing to store.",
        },
      },
    },
  },
}
  • mode : default ou safeguard (résumés par blocs pour les longs historiques). Voir Compaction.
  • provider : ID d’un plugin provider de compaction enregistré. Lorsqu’il est défini, le summarize() du provider est appelé à la place du résumé LLM intégré. Revient à l’implémentation intégrée en cas d’échec. Définir un provider force mode: "safeguard". Voir Compaction.
  • timeoutSeconds : nombre maximal de secondes autorisé pour une seule opération de compaction avant qu’OpenClaw l’abandonne. Par défaut : 900.
  • identifierPolicy : strict (par défaut), off ou custom. strict ajoute en préambule les consignes intégrées de conservation des identifiants opaques pendant le résumé de compaction.
  • identifierInstructions : texte personnalisé facultatif de préservation des identifiants, utilisé lorsque identifierPolicy=custom.
  • postCompactionSections : noms facultatifs de sections H2/H3 de AGENTS.md à réinjecter après compaction. Par défaut : ["Session Startup", "Red Lines"] ; définissez [] pour désactiver la réinjection. Lorsqu’il n’est pas défini ou qu’il est explicitement défini sur cette paire par défaut, les anciens titres Every Session/Safety sont également acceptés comme solution de repli héritée.
  • model : remplacement facultatif provider/model-id pour le résumé de compaction uniquement. Utilisez-le lorsque la session principale doit conserver un modèle mais que les résumés de compaction doivent s’exécuter sur un autre ; lorsqu’il n’est pas défini, la compaction utilise le modèle principal de la session.
  • notifyUser : lorsque true, envoie un bref avis à l’utilisateur au démarrage de la compaction (par exemple « Compactage du contexte… »). Désactivé par défaut pour garder la compaction silencieuse.
  • memoryFlush : tour agentique silencieux avant l’auto-compaction pour stocker des souvenirs durables. Ignoré lorsque l’espace de travail est en lecture seule.

agents.defaults.contextPruning

Élague les anciens résultats d’outil du contexte en mémoire avant l’envoi au LLM. Ne modifie pas l’historique de session sur disque.
{
  agents: {
    defaults: {
      contextPruning: {
        mode: "cache-ttl", // off | cache-ttl
        ttl: "1h", // duration (ms/s/m/h), default unit: minutes
        keepLastAssistants: 3,
        softTrimRatio: 0.3,
        hardClearRatio: 0.5,
        minPrunableToolChars: 50000,
        softTrim: { maxChars: 4000, headChars: 1500, tailChars: 1500 },
        hardClear: { enabled: true, placeholder: "[Old tool result content cleared]" },
        tools: { deny: ["browser", "canvas"] },
      },
    },
  },
}
  • mode: "cache-ttl" active les passes d’élagage.
  • ttl contrôle à quelle fréquence l’élagage peut se réexécuter (après le dernier accès au cache).
  • L’élagage réduit d’abord partiellement les résultats d’outil surdimensionnés, puis efface complètement les résultats d’outil plus anciens si nécessaire.
Réduction partielle conserve le début + la fin et insère ... au milieu.Effacement complet remplace l’intégralité du résultat d’outil par l’espace réservé.Remarques :
  • Les blocs image ne sont jamais réduits/effacés.
  • Les ratios sont basés sur les caractères (approximatifs), pas sur des comptes exacts de jetons.
  • S’il existe moins de keepLastAssistants messages assistant, l’élagage est ignoré.
Consultez Élagage de session pour les détails du comportement.

Streaming par blocs

{
  agents: {
    defaults: {
      blockStreamingDefault: "off", // on | off
      blockStreamingBreak: "text_end", // text_end | message_end
      blockStreamingChunk: { minChars: 800, maxChars: 1200 },
      blockStreamingCoalesce: { idleMs: 1000 },
      humanDelay: { mode: "natural" }, // off | natural | custom (use minMs/maxMs)
    },
  },
}
  • Les canaux autres que Telegram nécessitent *.blockStreaming: true explicite pour activer les réponses par blocs.
  • Remplacements par canal : channels.<channel>.blockStreamingCoalesce (et variantes par compte). Signal/Slack/Discord/Google Chat utilisent par défaut minChars: 1500.
  • humanDelay : pause aléatoire entre les réponses par blocs. natural = 800–2500 ms. Remplacement par agent : agents.list[].humanDelay.
Consultez Streaming pour le comportement et les détails du découpage.

Indicateurs de saisie

{
  agents: {
    defaults: {
      typingMode: "instant", // never | instant | thinking | message
      typingIntervalSeconds: 6,
    },
  },
}
  • Valeurs par défaut : instant pour les conversations directes/mentions, message pour les discussions de groupe sans mention.
  • Remplacements par session : session.typingMode, session.typingIntervalSeconds.
Consultez Indicateurs de saisie.

agents.defaults.sandbox

Sandboxing facultatif pour l’agent intégré. Consultez Sandboxing pour le guide complet.
{
  agents: {
    defaults: {
      sandbox: {
        mode: "non-main", // off | non-main | all
        backend: "docker", // docker | ssh | openshell
        scope: "agent", // session | agent | shared
        workspaceAccess: "none", // none | ro | rw
        workspaceRoot: "~/.openclaw/sandboxes",
        docker: {
          image: "openclaw-sandbox:bookworm-slim",
          containerPrefix: "openclaw-sbx-",
          workdir: "/workspace",
          readOnlyRoot: true,
          tmpfs: ["/tmp", "/var/tmp", "/run"],
          network: "none",
          user: "1000:1000",
          capDrop: ["ALL"],
          env: { LANG: "C.UTF-8" },
          setupCommand: "apt-get update && apt-get install -y git curl jq",
          pidsLimit: 256,
          memory: "1g",
          memorySwap: "2g",
          cpus: 1,
          ulimits: {
            nofile: { soft: 1024, hard: 2048 },
            nproc: 256,
          },
          seccompProfile: "/path/to/seccomp.json",
          apparmorProfile: "openclaw-sandbox",
          dns: ["1.1.1.1", "8.8.8.8"],
          extraHosts: ["internal.service:10.0.0.5"],
          binds: ["/home/user/source:/source:rw"],
        },
        ssh: {
          target: "user@gateway-host:22",
          command: "ssh",
          workspaceRoot: "/tmp/openclaw-sandboxes",
          strictHostKeyChecking: true,
          updateHostKeys: true,
          identityFile: "~/.ssh/id_ed25519",
          certificateFile: "~/.ssh/id_ed25519-cert.pub",
          knownHostsFile: "~/.ssh/known_hosts",
          // SecretRefs / inline contents also supported:
          // identityData: { source: "env", provider: "default", id: "SSH_IDENTITY" },
          // certificateData: { source: "env", provider: "default", id: "SSH_CERTIFICATE" },
          // knownHostsData: { source: "env", provider: "default", id: "SSH_KNOWN_HOSTS" },
        },
        browser: {
          enabled: false,
          image: "openclaw-sandbox-browser:bookworm-slim",
          network: "openclaw-sandbox-browser",
          cdpPort: 9222,
          cdpSourceRange: "172.21.0.1/32",
          vncPort: 5900,
          noVncPort: 6080,
          headless: false,
          enableNoVnc: true,
          allowHostControl: false,
          autoStart: true,
          autoStartTimeoutMs: 12000,
        },
        prune: {
          idleHours: 24,
          maxAgeDays: 7,
        },
      },
    },
  },
  tools: {
    sandbox: {
      tools: {
        allow: [
          "exec",
          "process",
          "read",
          "write",
          "edit",
          "apply_patch",
          "sessions_list",
          "sessions_history",
          "sessions_send",
          "sessions_spawn",
          "session_status",
        ],
        deny: ["browser", "canvas", "nodes", "cron", "discord", "gateway"],
      },
    },
  },
}
Backend :
  • docker : environnement Docker local (par défaut)
  • ssh : environnement distant générique via SSH
  • openshell : environnement OpenShell
Lorsque backend: "openshell" est sélectionné, les paramètres spécifiques à l’environnement sont déplacés vers plugins.entries.openshell.config.Configuration du backend SSH :
  • target : cible SSH au format user@host[:port]
  • command : commande du client SSH (par défaut : ssh)
  • workspaceRoot : racine distante absolue utilisée pour les espaces de travail par portée
  • identityFile / certificateFile / knownHostsFile : fichiers locaux existants transmis à OpenSSH
  • identityData / certificateData / knownHostsData : contenus en ligne ou SecretRefs qu’OpenClaw matérialise en fichiers temporaires à l’exécution
  • strictHostKeyChecking / updateHostKeys : options de politique de clé d’hôte OpenSSH
Priorité d’authentification SSH :
  • identityData a priorité sur identityFile
  • certificateData a priorité sur certificateFile
  • knownHostsData a priorité sur knownHostsFile
  • Les valeurs *Data basées sur SecretRef sont résolues à partir de l’instantané actif de l’environnement des secrets avant le démarrage de la session sandbox
Comportement du backend SSH :
  • initialise l’espace de travail distant une fois après création ou recréation
  • conserve ensuite l’espace de travail SSH distant comme référence canonique
  • achemine exec, les outils de fichier et les chemins média via SSH
  • ne synchronise pas automatiquement les modifications distantes vers l’hôte
  • ne prend pas en charge les conteneurs de navigateur sandbox
Accès à l’espace de travail :
  • none : espace de travail sandbox par portée sous ~/.openclaw/sandboxes
  • ro : espace de travail sandbox dans /workspace, espace de travail agent monté en lecture seule dans /agent
  • rw : espace de travail agent monté en lecture/écriture dans /workspace
Portée :
  • session : conteneur + espace de travail par session
  • agent : un conteneur + espace de travail par agent (par défaut)
  • shared : conteneur et espace de travail partagés (pas d’isolation inter-sessions)
Configuration du plugin OpenShell :
{
  plugins: {
    entries: {
      openshell: {
        enabled: true,
        config: {
          mode: "mirror", // mirror | remote
          from: "openclaw",
          remoteWorkspaceDir: "/sandbox",
          remoteAgentWorkspaceDir: "/agent",
          gateway: "lab", // optional
          gatewayEndpoint: "https://lab.example", // optional
          policy: "strict", // optional OpenShell policy id
          providers: ["openai"], // optional
          autoProviders: true,
          timeoutSeconds: 120,
        },
      },
    },
  },
}
Mode OpenShell :
  • mirror : initialise le distant à partir du local avant exec, resynchronise après exec ; l’espace de travail local reste canonique
  • remote : initialise le distant une fois à la création du sandbox, puis conserve l’espace de travail distant comme canonique
En mode remote, les modifications locales sur l’hôte effectuées en dehors d’OpenClaw ne sont pas automatiquement synchronisées dans le sandbox après l’étape d’initialisation. Le transport se fait via SSH vers le sandbox OpenShell, mais le plugin gère le cycle de vie du sandbox et la synchronisation miroir facultative.setupCommand s’exécute une fois après la création du conteneur (via sh -lc). Nécessite une sortie réseau, une racine inscriptible et un utilisateur root.Les conteneurs utilisent par défaut network: "none" — définissez "bridge" (ou un réseau bridge personnalisé) si l’agent a besoin d’un accès sortant. "host" est bloqué. "container:<id>" est bloqué par défaut sauf si vous définissez explicitement sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true (mode de dernier recours).Les pièces jointes entrantes sont placées dans media/inbound/* dans l’espace de travail actif.docker.binds monte des répertoires hôte supplémentaires ; les montages globaux et par agent sont fusionnés.Navigateur sandboxé (sandbox.browser.enabled) : Chromium + CDP dans un conteneur. L’URL noVNC est injectée dans le prompt système. Ne nécessite pas browser.enabled dans openclaw.json. L’accès observateur noVNC utilise par défaut l’authentification VNC et OpenClaw émet une URL à jeton de courte durée (au lieu d’exposer le mot de passe dans l’URL partagée).
  • allowHostControl: false (par défaut) empêche les sessions sandboxées de cibler le navigateur hôte.
  • network vaut par défaut openclaw-sandbox-browser (réseau bridge dédié). Définissez bridge uniquement lorsque vous voulez explicitement une connectivité bridge globale.
  • cdpSourceRange limite facultativement l’entrée CDP à la périphérie du conteneur à une plage CIDR (par exemple 172.21.0.1/32).
  • sandbox.browser.binds monte des répertoires hôte supplémentaires uniquement dans le conteneur du navigateur sandbox. Lorsqu’il est défini (y compris []), il remplace docker.binds pour le conteneur du navigateur.
  • Les valeurs de lancement par défaut sont définies dans scripts/sandbox-browser-entrypoint.sh et ajustées pour les hôtes conteneurisés :
    • --remote-debugging-address=127.0.0.1
    • --remote-debugging-port=<derived from OPENCLAW_BROWSER_CDP_PORT>
    • --user-data-dir=${HOME}/.chrome
    • --no-first-run
    • --no-default-browser-check
    • --disable-3d-apis
    • --disable-gpu
    • --disable-software-rasterizer
    • --disable-dev-shm-usage
    • --disable-background-networking
    • --disable-features=TranslateUI
    • --disable-breakpad
    • --disable-crash-reporter
    • --renderer-process-limit=2
    • --no-zygote
    • --metrics-recording-only
    • --disable-extensions (activé par défaut)
    • --disable-3d-apis, --disable-software-rasterizer et --disable-gpu sont activés par défaut et peuvent être désactivés avec OPENCLAW_BROWSER_DISABLE_GRAPHICS_FLAGS=0 si l’utilisation de WebGL/3D l’exige.
    • OPENCLAW_BROWSER_DISABLE_EXTENSIONS=0 réactive les extensions si votre flux de travail en dépend.
    • --renderer-process-limit=2 peut être modifié avec OPENCLAW_BROWSER_RENDERER_PROCESS_LIMIT=<N> ; définissez 0 pour utiliser la limite de processus par défaut de Chromium.
    • ainsi que --no-sandbox et --disable-setuid-sandbox lorsque noSandbox est activé.
    • Les valeurs par défaut sont la base de l’image conteneur ; utilisez une image de navigateur personnalisée avec un point d’entrée personnalisé pour modifier les valeurs par défaut du conteneur.
Le sandboxing du navigateur et sandbox.docker.binds sont propres à Docker. Construire les images :
scripts/sandbox-setup.sh           # image principale du sandbox
scripts/sandbox-browser-setup.sh   # image navigateur facultative

agents.list (remplacements par agent)

{
  agents: {
    list: [
      {
        id: "main",
        default: true,
        name: "Main Agent",
        workspace: "~/.openclaw/workspace",
        agentDir: "~/.openclaw/agents/main/agent",
        model: "anthropic/claude-opus-4-6", // or { primary, fallbacks }
        thinkingDefault: "high", // per-agent thinking level override
        reasoningDefault: "on", // per-agent reasoning visibility override
        fastModeDefault: false, // per-agent fast mode override
        params: { cacheRetention: "none" }, // overrides matching defaults.models params by key
        skills: ["docs-search"], // replaces agents.defaults.skills when set
        identity: {
          name: "Samantha",
          theme: "helpful sloth",
          emoji: "🦥",
          avatar: "avatars/samantha.png",
        },
        groupChat: { mentionPatterns: ["@openclaw"] },
        sandbox: { mode: "off" },
        runtime: {
          type: "acp",
          acp: {
            agent: "codex",
            backend: "acpx",
            mode: "persistent",
            cwd: "/workspace/openclaw",
          },
        },
        subagents: { allowAgents: ["*"] },
        tools: {
          profile: "coding",
          allow: ["browser"],
          deny: ["canvas"],
          elevated: { enabled: true },
        },
      },
    ],
  },
}
  • id : ID d’agent stable (obligatoire).
  • default : lorsque plusieurs sont définis, le premier l’emporte (un avertissement est journalisé). Si aucun n’est défini, la première entrée de la liste est l’agent par défaut.
  • model : la forme chaîne remplace uniquement primary ; la forme objet { primary, fallbacks } remplace les deux ([] désactive les replis globaux). Les tâches cron qui ne remplacent que primary héritent toujours des replis par défaut, sauf si vous définissez fallbacks: [].
  • params : paramètres de flux par agent fusionnés au-dessus de l’entrée de modèle sélectionnée dans agents.defaults.models. Utilisez-les pour des remplacements spécifiques à l’agent comme cacheRetention, temperature ou maxTokens sans dupliquer tout le catalogue de modèles.
  • skills : liste d’autorisations facultative des Skills par agent. Si elle est omise, l’agent hérite de agents.defaults.skills lorsqu’elle est définie ; une liste explicite remplace les valeurs par défaut au lieu d’être fusionnée, et [] signifie aucun Skills.
  • thinkingDefault : niveau de réflexion facultatif par défaut par agent (off | minimal | low | medium | high | xhigh | adaptive). Remplace agents.defaults.thinkingDefault pour cet agent lorsqu’aucun remplacement par message ou par session n’est défini.
  • reasoningDefault : visibilité facultative du raisonnement par défaut par agent (on | off | stream). S’applique lorsqu’aucun remplacement de raisonnement par message ou par session n’est défini.
  • fastModeDefault : valeur par défaut facultative par agent pour le mode rapide (true | false). S’applique lorsqu’aucun remplacement de mode rapide par message ou par session n’est défini.
  • runtime : descripteur d’exécution facultatif par agent. Utilisez type: "acp" avec les valeurs par défaut de runtime.acp (agent, backend, mode, cwd) lorsque l’agent doit utiliser par défaut des sessions de harnais ACP.
  • identity.avatar : chemin relatif à l’espace de travail, URL http(s) ou URI data:.
  • identity dérive des valeurs par défaut : ackReaction à partir de emoji, mentionPatterns à partir de name/emoji.
  • subagents.allowAgents : liste d’autorisations des ID d’agent pour sessions_spawn (["*"] = n’importe lequel ; par défaut : même agent uniquement).
  • Garde-fou d’héritage du sandbox : si la session demandeuse est sandboxée, sessions_spawn rejette les cibles qui s’exécuteraient sans sandbox.
  • subagents.requireAgentId : lorsqu’il vaut true, bloque les appels sessions_spawn qui omettent agentId (force une sélection de profil explicite ; par défaut : false).

Routage multi-agent

Exécutez plusieurs agents isolés dans une seule Gateway. Consultez Multi-Agent.
{
  agents: {
    list: [
      { id: "home", default: true, workspace: "~/.openclaw/workspace-home" },
      { id: "work", workspace: "~/.openclaw/workspace-work" },
    ],
  },
  bindings: [
    { agentId: "home", match: { channel: "whatsapp", accountId: "personal" } },
    { agentId: "work", match: { channel: "whatsapp", accountId: "biz" } },
  ],
}

Champs de correspondance des liaisons

  • type (facultatif) : route pour le routage normal (type absent = route par défaut), acp pour les liaisons persistantes de conversation ACP.
  • match.channel (obligatoire)
  • match.accountId (facultatif ; * = n’importe quel compte ; omis = compte par défaut)
  • match.peer (facultatif ; { kind: direct|group|channel, id })
  • match.guildId / match.teamId (facultatif ; spécifique au canal)
  • acp (facultatif ; uniquement pour les entrées type: "acp") : { mode, label, cwd, backend }
Ordre de correspondance déterministe :
  1. match.peer
  2. match.guildId
  3. match.teamId
  4. match.accountId (exact, sans pair/serveur/équipe)
  5. match.accountId: "*" (à l’échelle du canal)
  6. Agent par défaut
Dans chaque niveau, la première entrée bindings correspondante l’emporte. Pour les entrées type: "acp", OpenClaw résout par identité exacte de conversation (match.channel + compte + match.peer.id) et n’utilise pas l’ordre de niveau de liaison de routage ci-dessus.

Profils d’accès par agent

{
  agents: {
    list: [
      {
        id: "personal",
        workspace: "~/.openclaw/workspace-personal",
        sandbox: { mode: "off" },
      },
    ],
  },
}
{
  agents: {
    list: [
      {
        id: "family",
        workspace: "~/.openclaw/workspace-family",
        sandbox: { mode: "all", scope: "agent", workspaceAccess: "ro" },
        tools: {
          allow: [
            "read",
            "sessions_list",
            "sessions_history",
            "sessions_send",
            "sessions_spawn",
            "session_status",
          ],
          deny: ["write", "edit", "apply_patch", "exec", "process", "browser"],
        },
      },
    ],
  },
}
{
  agents: {
    list: [
      {
        id: "public",
        workspace: "~/.openclaw/workspace-public",
        sandbox: { mode: "all", scope: "agent", workspaceAccess: "none" },
        tools: {
          allow: [
            "sessions_list",
            "sessions_history",
            "sessions_send",
            "sessions_spawn",
            "session_status",
            "whatsapp",
            "telegram",
            "slack",
            "discord",
            "gateway",
          ],
          deny: [
            "read",
            "write",
            "edit",
            "apply_patch",
            "exec",
            "process",
            "browser",
            "canvas",
            "nodes",
            "cron",
            "gateway",
            "image",
          ],
        },
      },
    ],
  },
}
Consultez Sandbox multi-agent et outils pour les détails de priorité.

Session

{
  session: {
    scope: "per-sender",
    dmScope: "main", // main | per-peer | per-channel-peer | per-account-channel-peer
    identityLinks: {
      alice: ["telegram:123456789", "discord:987654321012345678"],
    },
    reset: {
      mode: "daily", // daily | idle
      atHour: 4,
      idleMinutes: 60,
    },
    resetByType: {
      thread: { mode: "daily", atHour: 4 },
      direct: { mode: "idle", idleMinutes: 240 },
      group: { mode: "idle", idleMinutes: 120 },
    },
    resetTriggers: ["/new", "/reset"],
    store: "~/.openclaw/agents/{agentId}/sessions/sessions.json",
    parentForkMaxTokens: 100000, // skip parent-thread fork above this token count (0 disables)
    maintenance: {
      mode: "warn", // warn | enforce
      pruneAfter: "30d",
      maxEntries: 500,
      rotateBytes: "10mb",
      resetArchiveRetention: "30d", // duration or false
      maxDiskBytes: "500mb", // optional hard budget
      highWaterBytes: "400mb", // optional cleanup target
    },
    threadBindings: {
      enabled: true,
      idleHours: 24, // default inactivity auto-unfocus in hours (`0` disables)
      maxAgeHours: 0, // default hard max age in hours (`0` disables)
    },
    mainKey: "main", // legacy (runtime always uses "main")
    agentToAgent: { maxPingPongTurns: 5 },
    sendPolicy: {
      rules: [{ action: "deny", match: { channel: "discord", chatType: "group" } }],
      default: "allow",
    },
  },
}
  • scope : stratégie de regroupement de session de base pour les contextes de discussion de groupe.
    • per-sender (par défaut) : chaque expéditeur obtient une session isolée dans un contexte de canal.
    • global : tous les participants d’un contexte de canal partagent une seule session (à utiliser uniquement lorsqu’un contexte partagé est souhaité).
  • dmScope : manière dont les DM sont regroupés.
    • main : tous les DM partagent la session principale.
    • per-peer : isolation par ID d’expéditeur entre les canaux.
    • per-channel-peer : isolation par canal + expéditeur (recommandé pour les boîtes de réception multi-utilisateurs).
    • per-account-channel-peer : isolation par compte + canal + expéditeur (recommandé pour le multi-compte).
  • identityLinks : mappe les ID canoniques aux pairs préfixés par fournisseur pour le partage de session inter-canaux.
  • reset : politique de réinitialisation principale. daily réinitialise à atHour en heure locale ; idle réinitialise après idleMinutes. Lorsque les deux sont configurés, celui qui expire en premier l’emporte.
  • resetByType : remplacements par type (direct, group, thread). L’ancien dm est accepté comme alias de direct.
  • parentForkMaxTokens : nombre maximal de totalTokens de la session parente autorisé lors de la création d’une session de fil dérivée (par défaut 100000).
    • Si le totalTokens parent est supérieur à cette valeur, OpenClaw démarre une nouvelle session de fil au lieu d’hériter de l’historique de transcription parent.
    • Définissez 0 pour désactiver cette protection et toujours autoriser la dérivation depuis le parent.
  • mainKey : champ hérité. L’exécution utilise toujours "main" pour le compartiment principal de discussion directe.
  • agentToAgent.maxPingPongTurns : nombre maximal de tours de réponse en retour entre agents lors des échanges agent-à-agent (entier, plage : 05). 0 désactive l’enchaînement ping-pong.
  • sendPolicy : correspondance par channel, chatType (direct|group|channel, avec l’ancien alias dm), keyPrefix ou rawKeyPrefix. Le premier refus l’emporte.
  • maintenance : contrôles de nettoyage + rétention du magasin de sessions.
    • mode : warn émet uniquement des avertissements ; enforce applique le nettoyage.
    • pruneAfter : seuil d’ancienneté pour les entrées obsolètes (par défaut 30d).
    • maxEntries : nombre maximal d’entrées dans sessions.json (par défaut 500).
    • rotateBytes : fait tourner sessions.json lorsqu’il dépasse cette taille (par défaut 10mb).
    • resetArchiveRetention : rétention des archives de transcription *.reset.<timestamp>. Utilise par défaut pruneAfter ; définissez false pour désactiver.
    • maxDiskBytes : budget disque facultatif du répertoire des sessions. En mode warn, il journalise des avertissements ; en mode enforce, il supprime d’abord les artefacts/sessions les plus anciens.
    • highWaterBytes : cible facultative après nettoyage du budget. Utilise par défaut 80% de maxDiskBytes.
  • threadBindings : valeurs globales par défaut pour les fonctionnalités de session liées aux fils.
    • enabled : commutateur maître par défaut (les fournisseurs peuvent remplacer ; Discord utilise channels.discord.threadBindings.enabled)
    • idleHours : retrait automatique du focus par défaut après inactivité, en heures (0 désactive ; les fournisseurs peuvent remplacer)
    • maxAgeHours : âge maximal strict par défaut, en heures (0 désactive ; les fournisseurs peuvent remplacer)

Messages

{
  messages: {
    responsePrefix: "🦞", // or "auto"
    ackReaction: "👀",
    ackReactionScope: "group-mentions", // group-mentions | group-all | direct | all
    removeAckAfterReply: false,
    queue: {
      mode: "collect", // steer | followup | collect | steer-backlog | steer+backlog | queue | interrupt
      debounceMs: 1000,
      cap: 20,
      drop: "summarize", // old | new | summarize
      byChannel: {
        whatsapp: "collect",
        telegram: "collect",
      },
    },
    inbound: {
      debounceMs: 2000, // 0 disables
      byChannel: {
        whatsapp: 5000,
        slack: 1500,
      },
    },
  },
}

Préfixe de réponse

Remplacements par canal/compte : channels.<channel>.responsePrefix, channels.<channel>.accounts.<id>.responsePrefix. Résolution (le plus spécifique l’emporte) : compte → canal → global. "" désactive et arrête la cascade. "auto" dérive [{identity.name}]. Variables de modèle :
VariableDescriptionExemple
{model}Nom court du modèleclaude-opus-4-6
{modelFull}Identifiant complet du modèleanthropic/claude-opus-4-6
{provider}Nom du provideranthropic
{thinkingLevel}Niveau de réflexion actuelhigh, low, off
{identity.name}Nom d’identité de l’agent(identique à "auto")
Les variables ne sont pas sensibles à la casse. {think} est un alias de {thinkingLevel}.

Réaction d’accusé de réception

  • Utilise par défaut identity.emoji de l’agent actif, sinon "👀". Définissez "" pour désactiver.
  • Remplacements par canal : channels.<channel>.ackReaction, channels.<channel>.accounts.<id>.ackReaction.
  • Ordre de résolution : compte → canal → messages.ackReaction → repli identité.
  • Portée : group-mentions (par défaut), group-all, direct, all.
  • removeAckAfterReply : supprime l’accusé de réception après réponse sur Slack, Discord et Telegram.
  • messages.statusReactions.enabled : active les réactions d’état du cycle de vie sur Slack, Discord et Telegram. Sur Slack et Discord, l’absence de valeur conserve les réactions d’état activées lorsque les réactions d’accusé de réception sont actives. Sur Telegram, définissez explicitement cette valeur à true pour activer les réactions d’état du cycle de vie.

Anti-rebond des messages entrants

Regroupe les messages texte rapides du même expéditeur en un seul tour d’agent. Les médias/pièces jointes déclenchent un envoi immédiat. Les commandes de contrôle contournent l’anti-rebond.

TTS (synthèse vocale)

{
  messages: {
    tts: {
      auto: "always", // off | always | inbound | tagged
      mode: "final", // final | all
      provider: "elevenlabs",
      summaryModel: "openai/gpt-4.1-mini",
      modelOverrides: { enabled: true },
      maxTextLength: 4000,
      timeoutMs: 30000,
      prefsPath: "~/.openclaw/settings/tts.json",
      elevenlabs: {
        apiKey: "elevenlabs_api_key",
        baseUrl: "https://api.elevenlabs.io",
        voiceId: "voice_id",
        modelId: "eleven_multilingual_v2",
        seed: 42,
        applyTextNormalization: "auto",
        languageCode: "en",
        voiceSettings: {
          stability: 0.5,
          similarityBoost: 0.75,
          style: 0.0,
          useSpeakerBoost: true,
          speed: 1.0,
        },
      },
      openai: {
        apiKey: "openai_api_key",
        baseUrl: "https://api.openai.com/v1",
        model: "gpt-4o-mini-tts",
        voice: "alloy",
      },
    },
  },
}
  • auto contrôle le mode auto-TTS par défaut : off, always, inbound ou tagged. /tts on|off peut remplacer les préférences locales, et /tts status affiche l’état effectif.
  • summaryModel remplace agents.defaults.model.primary pour le résumé automatique.
  • modelOverrides est activé par défaut ; modelOverrides.allowProvider vaut par défaut false (activation explicite).
  • Les clés API utilisent comme solution de repli ELEVENLABS_API_KEY/XI_API_KEY et OPENAI_API_KEY.
  • openai.baseUrl remplace le point de terminaison TTS OpenAI. L’ordre de résolution est : configuration, puis OPENAI_TTS_BASE_URL, puis https://api.openai.com/v1.
  • Lorsque openai.baseUrl pointe vers un point de terminaison non OpenAI, OpenClaw le traite comme un serveur TTS compatible OpenAI et assouplit la validation du modèle/de la voix.

Talk

Valeurs par défaut du mode Talk (macOS/iOS/Android).
{
  talk: {
    provider: "elevenlabs",
    providers: {
      elevenlabs: {
        voiceId: "elevenlabs_voice_id",
        voiceAliases: {
          Clawd: "EXAVITQu4vr4xnSDxMaL",
          Roger: "CwhRBWXzGAHq8TQ4Fs17",
        },
        modelId: "eleven_v3",
        outputFormat: "mp3_44100_128",
        apiKey: "elevenlabs_api_key",
      },
    },
    silenceTimeoutMs: 1500,
    interruptOnSpeech: true,
  },
}
  • talk.provider doit correspondre à une clé dans talk.providers lorsque plusieurs providers Talk sont configurés.
  • Les anciennes clés Talk plates (talk.voiceId, talk.voiceAliases, talk.modelId, talk.outputFormat, talk.apiKey) ne sont conservées que pour compatibilité et sont automatiquement migrées vers talk.providers.<provider>.
  • Les ID de voix utilisent comme solution de repli ELEVENLABS_VOICE_ID ou SAG_VOICE_ID.
  • providers.*.apiKey accepte des chaînes en texte brut ou des objets SecretRef.
  • La solution de repli ELEVENLABS_API_KEY s’applique uniquement lorsqu’aucune clé API Talk n’est configurée.
  • providers.*.voiceAliases permet aux directives Talk d’utiliser des noms conviviaux.
  • silenceTimeoutMs contrôle combien de temps le mode Talk attend après le silence de l’utilisateur avant d’envoyer la transcription. Si non défini, la fenêtre de pause par défaut de la plateforme est conservée (700 ms sur macOS et Android, 900 ms sur iOS).

Outils

Profils d’outils

tools.profile définit une liste d’autorisations de base avant tools.allow/tools.deny : L’intégration locale définit par défaut les nouvelles configurations locales sur tools.profile: "coding" lorsqu’il n’est pas défini (les profils explicites existants sont conservés).
ProfilInclut
minimalsession_status uniquement
codinggroup:fs, group:runtime, group:web, group:sessions, group:memory, cron, image, image_generate, video_generate
messaginggroup:messaging, sessions_list, sessions_history, sessions_send, session_status
fullAucune restriction (identique à non défini)

Groupes d’outils

GroupeOutils
group:runtimeexec, process, code_execution (bash est accepté comme alias de exec)
group:fsread, write, edit, apply_patch
group:sessionssessions_list, sessions_history, sessions_send, sessions_spawn, sessions_yield, subagents, session_status
group:memorymemory_search, memory_get
group:webweb_search, x_search, web_fetch
group:uibrowser, canvas
group:automationcron, gateway
group:messagingmessage
group:nodesnodes
group:agentsagents_list
group:mediaimage, image_generate, video_generate, tts
group:openclawTous les outils intégrés (exclut les plugins provider)

tools.allow / tools.deny

Politique globale d’autorisation/interdiction des outils (l’interdiction l’emporte). Insensible à la casse, prend en charge les jokers *. S’applique même lorsque le sandbox Docker est désactivé.
{
  tools: { deny: ["browser", "canvas"] },
}

tools.byProvider

Restreint davantage les outils pour des providers ou modèles spécifiques. Ordre : profil de base → profil du provider → autorisation/interdiction.
{
  tools: {
    profile: "coding",
    byProvider: {
      "google-antigravity": { profile: "minimal" },
      "openai/gpt-5.4": { allow: ["group:fs", "sessions_list"] },
    },
  },
}

tools.elevated

Contrôle l’accès exec élevé en dehors du sandbox :
{
  tools: {
    elevated: {
      enabled: true,
      allowFrom: {
        whatsapp: ["+15555550123"],
        discord: ["1234567890123", "987654321098765432"],
      },
    },
  },
}
  • Le remplacement par agent (agents.list[].tools.elevated) ne peut que restreindre davantage.
  • /elevated on|off|ask|full stocke l’état par session ; les directives en ligne s’appliquent à un seul message.
  • exec élevé contourne le sandboxing et utilise le chemin d’échappement configuré (gateway par défaut, ou node lorsque la cible exec est node).

tools.exec

{
  tools: {
    exec: {
      backgroundMs: 10000,
      timeoutSec: 1800,
      cleanupMs: 1800000,
      notifyOnExit: true,
      notifyOnExitEmptySuccess: false,
      applyPatch: {
        enabled: false,
        allowModels: ["gpt-5.4"],
      },
    },
  },
}

tools.loopDetection

Les vérifications de sécurité des boucles d’outils sont désactivées par défaut. Définissez enabled: true pour activer la détection. Les paramètres peuvent être définis globalement dans tools.loopDetection et remplacés par agent dans agents.list[].tools.loopDetection.
{
  tools: {
    loopDetection: {
      enabled: true,
      historySize: 30,
      warningThreshold: 10,
      criticalThreshold: 20,
      globalCircuitBreakerThreshold: 30,
      detectors: {
        genericRepeat: true,
        knownPollNoProgress: true,
        pingPong: true,
      },
    },
  },
}
  • historySize : historique maximal des appels d’outils conservé pour l’analyse des boucles.
  • warningThreshold : seuil de modèle répétitif sans progression pour les avertissements.
  • criticalThreshold : seuil répétitif plus élevé pour bloquer les boucles critiques.
  • globalCircuitBreakerThreshold : seuil d’arrêt dur pour toute exécution sans progression.
  • detectors.genericRepeat : avertit en cas d’appels répétés au même outil/avec les mêmes arguments.
  • detectors.knownPollNoProgress : avertit/bloque sur les outils de sondage connus (process.poll, command_status, etc.).
  • detectors.pingPong : avertit/bloque sur les modèles alternés sans progression en paire.
  • Si warningThreshold >= criticalThreshold ou criticalThreshold >= globalCircuitBreakerThreshold, la validation échoue.

tools.web

{
  tools: {
    web: {
      search: {
        enabled: true,
        apiKey: "brave_api_key", // or BRAVE_API_KEY env
        maxResults: 5,
        timeoutSeconds: 30,
        cacheTtlMinutes: 15,
      },
      fetch: {
        enabled: true,
        provider: "firecrawl", // optional; omit for auto-detect
        maxChars: 50000,
        maxCharsCap: 50000,
        maxResponseBytes: 2000000,
        timeoutSeconds: 30,
        cacheTtlMinutes: 15,
        maxRedirects: 3,
        readability: true,
        userAgent: "custom-ua",
      },
    },
  },
}

tools.media

Configure la compréhension des médias entrants (image/audio/vidéo) :
{
  tools: {
    media: {
      concurrency: 2,
      asyncCompletion: {
        directSend: false, // opt-in: send finished async music/video directly to the channel
      },
      audio: {
        enabled: true,
        maxBytes: 20971520,
        scope: {
          default: "deny",
          rules: [{ action: "allow", match: { chatType: "direct" } }],
        },
        models: [
          { provider: "openai", model: "gpt-4o-mini-transcribe" },
          { type: "cli", command: "whisper", args: ["--model", "base", "{{MediaPath}}"] },
        ],
      },
      video: {
        enabled: true,
        maxBytes: 52428800,
        models: [{ provider: "google", model: "gemini-3-flash-preview" }],
      },
    },
  },
}
Entrée provider (type: "provider" ou omis) :
  • provider : ID du provider API (openai, anthropic, google/gemini, groq, etc.)
  • model : remplacement d’ID de modèle
  • profile / preferredProfile : sélection de profil auth-profiles.json
Entrée CLI (type: "cli") :
  • command : exécutable à lancer
  • args : arguments à modèles (prend en charge {{MediaPath}}, {{Prompt}}, {{MaxChars}}, etc.)
Champs communs :
  • capabilities : liste facultative (image, audio, video). Valeurs par défaut : openai/anthropic/minimax → image, google → image+audio+video, groq → audio.
  • prompt, maxChars, maxBytes, timeoutSeconds, language : remplacements par entrée.
  • Les échecs passent à l’entrée suivante.
L’authentification du provider suit l’ordre standard : auth-profiles.json → variables d’environnement → models.providers.*.apiKey.Champs d’exécution asynchrone :
  • asyncCompletion.directSend : lorsque true, les tâches terminées asynchrones music_generate et video_generate essaient d’abord une livraison directe au canal. Par défaut : false (ancien chemin de réveil de session du demandeur/livraison par modèle).

tools.agentToAgent

{
  tools: {
    agentToAgent: {
      enabled: false,
      allow: ["home", "work"],
    },
  },
}

tools.sessions

Contrôle quelles sessions peuvent être ciblées par les outils de session (sessions_list, sessions_history, sessions_send). Par défaut : tree (session actuelle + sessions lancées par celle-ci, comme les sous-agents).
{
  tools: {
    sessions: {
      // "self" | "tree" | "agent" | "all"
      visibility: "tree",
    },
  },
}
Remarques :
  • self : uniquement la clé de session actuelle.
  • tree : session actuelle + sessions lancées par la session actuelle (sous-agents).
  • agent : toute session appartenant à l’ID d’agent actuel (peut inclure d’autres utilisateurs si vous exécutez des sessions par expéditeur sous le même ID d’agent).
  • all : toute session. Le ciblage inter-agents nécessite toujours tools.agentToAgent.
  • Limitation sandbox : lorsque la session actuelle est sandboxée et que agents.defaults.sandbox.sessionToolsVisibility="spawned", la visibilité est forcée à tree même si tools.sessions.visibility="all".

tools.sessions_spawn

Contrôle la prise en charge des pièces jointes en ligne pour sessions_spawn.
{
  tools: {
    sessions_spawn: {
      attachments: {
        enabled: false, // opt-in: set true to allow inline file attachments
        maxTotalBytes: 5242880, // 5 MB total across all files
        maxFiles: 50,
        maxFileBytes: 1048576, // 1 MB per file
        retainOnSessionKeep: false, // keep attachments when cleanup="keep"
      },
    },
  },
}
Remarques :
  • Les pièces jointes ne sont prises en charge que pour runtime: "subagent". L’exécution ACP les rejette.
  • Les fichiers sont matérialisés dans l’espace de travail enfant sous .openclaw/attachments/<uuid>/ avec un .manifest.json.
  • Le contenu des pièces jointes est automatiquement masqué dans la persistance de la transcription.
  • Les entrées base64 sont validées avec des vérifications strictes d’alphabet/remplissage et une protection de taille avant décodage.
  • Les permissions de fichier sont 0700 pour les répertoires et 0600 pour les fichiers.
  • Le nettoyage suit la politique cleanup : delete supprime toujours les pièces jointes ; keep ne les conserve que lorsque retainOnSessionKeep: true.

tools.experimental

Indicateurs d’outils intégrés expérimentaux. Désactivés par défaut sauf si une règle d’activation automatique spécifique à l’exécution s’applique.
{
  tools: {
    experimental: {
      planTool: true, // enable experimental update_plan
    },
  },
}
Remarques :
  • planTool : active l’outil structuré update_plan pour le suivi des travaux non triviaux à plusieurs étapes.
  • Par défaut : false pour les providers non OpenAI. Les exécutions OpenAI et OpenAI Codex l’activent automatiquement lorsqu’il n’est pas défini ; définissez false pour désactiver cette activation automatique.
  • Lorsqu’il est activé, le prompt système ajoute aussi des consignes d’utilisation afin que le modèle ne l’utilise que pour des travaux substantiels et conserve au plus une étape in_progress.

agents.defaults.subagents

{
  agents: {
    defaults: {
      subagents: {
        allowAgents: ["research"],
        model: "minimax/MiniMax-M2.7",
        maxConcurrent: 8,
        runTimeoutSeconds: 900,
        archiveAfterMinutes: 60,
      },
    },
  },
}
  • model : modèle par défaut pour les sous-agents lancés. S’il est omis, les sous-agents héritent du modèle de l’appelant.
  • allowAgents : liste d’autorisations par défaut des ID d’agent cibles pour sessions_spawn lorsque l’agent demandeur ne définit pas son propre subagents.allowAgents (["*"] = n’importe lequel ; par défaut : même agent uniquement).
  • runTimeoutSeconds : délai d’expiration par défaut (secondes) pour sessions_spawn lorsque l’appel d’outil omet runTimeoutSeconds. 0 signifie aucun délai.
  • Politique d’outils par sous-agent : tools.subagents.tools.allow / tools.subagents.tools.deny.

Providers personnalisés et URL de base

OpenClaw utilise le catalogue de modèles intégré. Ajoutez des providers personnalisés via models.providers dans la configuration ou ~/.openclaw/agents/<agentId>/agent/models.json.
{
  models: {
    mode: "merge", // merge (default) | replace
    providers: {
      "custom-proxy": {
        baseUrl: "http://localhost:4000/v1",
        apiKey: "LITELLM_KEY",
        api: "openai-completions", // openai-completions | openai-responses | anthropic-messages | google-generative-ai
        models: [
          {
            id: "llama-3.1-8b",
            name: "Llama 3.1 8B",
            reasoning: false,
            input: ["text"],
            cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
            contextWindow: 128000,
            contextTokens: 96000,
            maxTokens: 32000,
          },
        ],
      },
    },
  },
}
  • Utilisez authHeader: true + headers pour des besoins d’authentification personnalisés.
  • Remplacez la racine de configuration de l’agent avec OPENCLAW_AGENT_DIR (ou PI_CODING_AGENT_DIR, alias hérité de variable d’environnement).
  • Priorité de fusion pour les ID de provider correspondants :
    • Les valeurs baseUrl non vides de models.json de l’agent l’emportent.
    • Les valeurs apiKey non vides de l’agent l’emportent uniquement lorsque ce provider n’est pas géré par SecretRef dans le contexte actuel de configuration/profil d’authentification.
    • Les valeurs apiKey de provider gérées par SecretRef sont actualisées à partir des marqueurs source (ENV_VAR_NAME pour les références env, secretref-managed pour les références fichier/exec) au lieu de persister les secrets résolus.
    • Les valeurs d’en-tête de provider gérées par SecretRef sont actualisées à partir des marqueurs source (secretref-env:ENV_VAR_NAME pour les références env, secretref-managed pour les références fichier/exec).
    • Les valeurs apiKey/baseUrl d’agent vides ou absentes se replient sur models.providers dans la configuration.
    • Les valeurs contextWindow/maxTokens des modèles correspondants utilisent la valeur la plus élevée entre la configuration explicite et les valeurs implicites du catalogue.
    • contextTokens des modèles correspondants conserve une limite d’exécution explicite lorsqu’elle est présente ; utilisez-la pour limiter le contexte effectif sans modifier les métadonnées natives du modèle.
    • Utilisez models.mode: "replace" lorsque vous voulez que la configuration réécrive entièrement models.json.
    • La persistance des marqueurs est gouvernée par la source : les marqueurs sont écrits à partir de l’instantané actif de la configuration source (pré-résolution), et non à partir des valeurs secrètes résolues à l’exécution.

Détails des champs de provider

  • models.mode : comportement du catalogue de providers (merge ou replace).
  • models.providers : map de providers personnalisés indexée par ID de provider.
  • models.providers.*.api : adaptateur de requête (openai-completions, openai-responses, anthropic-messages, google-generative-ai, etc.).
  • models.providers.*.apiKey : identifiant du provider (préférez SecretRef/la substitution via l’environnement).
  • models.providers.*.auth : stratégie d’authentification (api-key, token, oauth, aws-sdk).
  • models.providers.*.injectNumCtxForOpenAICompat : pour Ollama + openai-completions, injecte options.num_ctx dans les requêtes (par défaut : true).
  • models.providers.*.authHeader : force le transport des identifiants dans l’en-tête Authorization lorsque nécessaire.
  • models.providers.*.baseUrl : URL de base de l’API amont.
  • models.providers.*.headers : en-têtes statiques supplémentaires pour le routage proxy/locataire.
  • models.providers.*.request : remplacements de transport pour les requêtes HTTP du provider de modèles.
    • request.headers : en-têtes supplémentaires (fusionnés avec les valeurs par défaut du provider). Les valeurs acceptent SecretRef.
    • request.auth : remplacement de stratégie d’authentification. Modes : "provider-default" (utilise l’authentification intégrée du provider), "authorization-bearer" (avec token), "header" (avec headerName, value, prefix facultatif).
    • request.proxy : remplacement du proxy HTTP. Modes : "env-proxy" (utilise les variables d’environnement HTTP_PROXY/HTTPS_PROXY), "explicit-proxy" (avec url). Les deux modes acceptent un sous-objet facultatif tls.
    • request.tls : remplacement TLS pour les connexions directes. Champs : ca, cert, key, passphrase (acceptent tous SecretRef), serverName, insecureSkipVerify.
    • request.allowPrivateNetwork : lorsque true, autorise HTTPS vers baseUrl lorsque DNS se résout vers des plages privées, CGNAT ou similaires, via la protection de récupération HTTP du provider (activation explicite par l’opérateur pour des points de terminaison compatibles OpenAI auto-hébergés de confiance). WebSocket utilise le même request pour les en-têtes/TLS, mais pas cette protection SSRF de récupération. Par défaut false.
  • models.providers.*.models : entrées explicites du catalogue de modèles du provider.
  • models.providers.*.models.*.contextWindow : métadonnées de fenêtre de contexte native du modèle.
  • models.providers.*.models.*.contextTokens : plafond de contexte d’exécution facultatif. Utilisez-le lorsque vous voulez un budget de contexte effectif plus petit que le contextWindow natif du modèle.
  • models.providers.*.models.*.compat.supportsDeveloperRole : indice de compatibilité facultatif. Pour api: "openai-completions" avec un baseUrl non natif non vide (hôte différent de api.openai.com), OpenClaw force cette valeur à false à l’exécution. Un baseUrl vide/omis conserve le comportement OpenAI par défaut.
  • models.providers.*.models.*.compat.requiresStringContent : indice de compatibilité facultatif pour les points de terminaison de chat compatibles OpenAI limités aux chaînes. Lorsque true, OpenClaw aplatie les tableaux purement textuels messages[].content en chaînes simples avant d’envoyer la requête.
  • plugins.entries.amazon-bedrock.config.discovery : racine des paramètres d’auto-détection Bedrock.
  • plugins.entries.amazon-bedrock.config.discovery.enabled : active/désactive la détection implicite.
  • plugins.entries.amazon-bedrock.config.discovery.region : région AWS pour la détection.
  • plugins.entries.amazon-bedrock.config.discovery.providerFilter : filtre facultatif d’ID de provider pour une détection ciblée.
  • plugins.entries.amazon-bedrock.config.discovery.refreshInterval : intervalle d’interrogation pour l’actualisation de la détection.
  • plugins.entries.amazon-bedrock.config.discovery.defaultContextWindow : fenêtre de contexte de repli pour les modèles détectés.
  • plugins.entries.amazon-bedrock.config.discovery.defaultMaxTokens : nombre maximal de jetons de sortie de repli pour les modèles détectés.

Exemples de providers

{
  env: { CEREBRAS_API_KEY: "sk-..." },
  agents: {
    defaults: {
      model: {
        primary: "cerebras/zai-glm-4.7",
        fallbacks: ["cerebras/zai-glm-4.6"],
      },
      models: {
        "cerebras/zai-glm-4.7": { alias: "GLM 4.7 (Cerebras)" },
        "cerebras/zai-glm-4.6": { alias: "GLM 4.6 (Cerebras)" },
      },
    },
  },
  models: {
    mode: "merge",
    providers: {
      cerebras: {
        baseUrl: "https://api.cerebras.ai/v1",
        apiKey: "${CEREBRAS_API_KEY}",
        api: "openai-completions",
        models: [
          { id: "zai-glm-4.7", name: "GLM 4.7 (Cerebras)" },
          { id: "zai-glm-4.6", name: "GLM 4.6 (Cerebras)" },
        ],
      },
    },
  },
}
Utilisez cerebras/zai-glm-4.7 pour Cerebras ; zai/glm-4.7 pour Z.AI direct.
{
  agents: {
    defaults: {
      model: { primary: "opencode/claude-opus-4-6" },
      models: { "opencode/claude-opus-4-6": { alias: "Opus" } },
    },
  },
}
Définissez OPENCODE_API_KEY (ou OPENCODE_ZEN_API_KEY). Utilisez les références opencode/... pour le catalogue Zen ou les références opencode-go/... pour le catalogue Go. Raccourci : openclaw onboard --auth-choice opencode-zen ou openclaw onboard --auth-choice opencode-go.
{
  agents: {
    defaults: {
      model: { primary: "zai/glm-4.7" },
      models: { "zai/glm-4.7": {} },
    },
  },
}
Définissez ZAI_API_KEY. z.ai/* et z-ai/* sont des alias acceptés. Raccourci : openclaw onboard --auth-choice zai-api-key.
  • Point de terminaison général : https://api.z.ai/api/paas/v4
  • Point de terminaison de code (par défaut) : https://api.z.ai/api/coding/paas/v4
  • Pour le point de terminaison général, définissez un provider personnalisé avec le remplacement de l’URL de base.
{
  env: { MOONSHOT_API_KEY: "sk-..." },
  agents: {
    defaults: {
      model: { primary: "moonshot/kimi-k2.5" },
      models: { "moonshot/kimi-k2.5": { alias: "Kimi K2.5" } },
    },
  },
  models: {
    mode: "merge",
    providers: {
      moonshot: {
        baseUrl: "https://api.moonshot.ai/v1",
        apiKey: "${MOONSHOT_API_KEY}",
        api: "openai-completions",
        models: [
          {
            id: "kimi-k2.5",
            name: "Kimi K2.5",
            reasoning: false,
            input: ["text", "image"],
            cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
            contextWindow: 262144,
            maxTokens: 262144,
          },
        ],
      },
    },
  },
}
Pour le point de terminaison Chine : baseUrl: "https://api.moonshot.cn/v1" ou openclaw onboard --auth-choice moonshot-api-key-cn.Les points de terminaison Moonshot natifs annoncent une compatibilité d’utilisation du streaming sur le transport partagé openai-completions, et OpenClaw s’appuie là-dessus selon les capacités du point de terminaison plutôt que sur le seul ID de provider intégré.
{
  env: { KIMI_API_KEY: "sk-..." },
  agents: {
    defaults: {
      model: { primary: "kimi/kimi-code" },
      models: { "kimi/kimi-code": { alias: "Kimi Code" } },
    },
  },
}
Compatible Anthropic, provider intégré. Raccourci : openclaw onboard --auth-choice kimi-code-api-key.
{
  env: { SYNTHETIC_API_KEY: "sk-..." },
  agents: {
    defaults: {
      model: { primary: "synthetic/hf:MiniMaxAI/MiniMax-M2.5" },
      models: { "synthetic/hf:MiniMaxAI/MiniMax-M2.5": { alias: "MiniMax M2.5" } },
    },
  },
  models: {
    mode: "merge",
    providers: {
      synthetic: {
        baseUrl: "https://api.synthetic.new/anthropic",
        apiKey: "${SYNTHETIC_API_KEY}",
        api: "anthropic-messages",
        models: [
          {
            id: "hf:MiniMaxAI/MiniMax-M2.5",
            name: "MiniMax M2.5",
            reasoning: true,
            input: ["text"],
            cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
            contextWindow: 192000,
            maxTokens: 65536,
          },
        ],
      },
    },
  },
}
L’URL de base doit omettre /v1 (le client Anthropic l’ajoute). Raccourci : openclaw onboard --auth-choice synthetic-api-key.
{
  agents: {
    defaults: {
      model: { primary: "minimax/MiniMax-M2.7" },
      models: {
        "minimax/MiniMax-M2.7": { alias: "Minimax" },
      },
    },
  },
  models: {
    mode: "merge",
    providers: {
      minimax: {
        baseUrl: "https://api.minimax.io/anthropic",
        apiKey: "${MINIMAX_API_KEY}",
        api: "anthropic-messages",
        models: [
          {
            id: "MiniMax-M2.7",
            name: "MiniMax M2.7",
            reasoning: true,
            input: ["text", "image"],
            cost: { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0.375 },
            contextWindow: 204800,
            maxTokens: 131072,
          },
        ],
      },
    },
  },
}
Définissez MINIMAX_API_KEY. Raccourcis : openclaw onboard --auth-choice minimax-global-api ou openclaw onboard --auth-choice minimax-cn-api. Le catalogue de modèles utilise par défaut uniquement M2.7. Sur le chemin de streaming compatible Anthropic, OpenClaw désactive la réflexion MiniMax par défaut sauf si vous définissez explicitement thinking vous-même. /fast on ou params.fastMode: true réécrit MiniMax-M2.7 en MiniMax-M2.7-highspeed.
Consultez Modèles locaux. En bref : exécutez un grand modèle local via l’API Responses de LM Studio sur du matériel puissant ; conservez les modèles hébergés fusionnés comme solution de repli.

Skills

{
  skills: {
    allowBundled: ["gemini", "peekaboo"],
    load: {
      extraDirs: ["~/Projects/agent-scripts/skills"],
    },
    install: {
      preferBrew: true,
      nodeManager: "npm", // npm | pnpm | yarn | bun
    },
    entries: {
      "image-lab": {
        apiKey: { source: "env", provider: "default", id: "GEMINI_API_KEY" }, // or plaintext string
        env: { GEMINI_API_KEY: "GEMINI_KEY_HERE" },
      },
      peekaboo: { enabled: true },
      sag: { enabled: false },
    },
  },
}
  • allowBundled : liste d’autorisations facultative pour les Skills groupées uniquement (les Skills gérées/d’espace de travail ne sont pas affectées).
  • load.extraDirs : racines supplémentaires de Skills partagées (priorité la plus faible).
  • install.preferBrew : lorsque true, préfère les installateurs Homebrew lorsque brew est disponible avant de revenir à d’autres types d’installateur.
  • install.nodeManager : préférence d’installateur Node pour les spécifications metadata.openclaw.install (npm | pnpm | yarn | bun).
  • entries.<skillKey>.enabled: false désactive une skill même si elle est groupée/installée.
  • entries.<skillKey>.apiKey : raccourci pratique pour les Skills qui déclarent une variable d’environnement principale (chaîne en texte brut ou objet SecretRef).

Plugins

{
  plugins: {
    enabled: true,
    allow: ["voice-call"],
    deny: [],
    load: {
      paths: ["~/Projects/oss/voice-call-extension"],
    },
    entries: {
      "voice-call": {
        enabled: true,
        hooks: {
          allowPromptInjection: false,
        },
        config: { provider: "twilio" },
      },
    },
  },
}
  • Chargés depuis ~/.openclaw/extensions, <workspace>/.openclaw/extensions, ainsi que plugins.load.paths.
  • La découverte accepte les plugins OpenClaw natifs ainsi que les bundles Codex compatibles et les bundles Claude, y compris les bundles Claude sans manifeste avec disposition par défaut.
  • Les changements de configuration nécessitent un redémarrage de la passerelle.
  • allow : liste d’autorisations facultative (seuls les plugins listés sont chargés). deny l’emporte.
  • plugins.entries.<id>.apiKey : champ pratique de clé API au niveau plugin (lorsqu’il est pris en charge par le plugin).
  • plugins.entries.<id>.env : map de variables d’environnement à portée plugin.
  • plugins.entries.<id>.hooks.allowPromptInjection : lorsque false, le cœur bloque before_prompt_build et ignore les champs hérités modifiant le prompt depuis before_agent_start, tout en préservant les anciens modelOverride et providerOverride. S’applique aux hooks de plugins natifs et aux répertoires de hooks fournis par bundle pris en charge.
  • plugins.entries.<id>.subagent.allowModelOverride : fait explicitement confiance à ce plugin pour demander des remplacements provider et model par exécution pour les exécutions de sous-agents en arrière-plan.
  • plugins.entries.<id>.subagent.allowedModels : liste d’autorisations facultative des cibles canoniques provider/model pour les remplacements de sous-agents approuvés. Utilisez "*" uniquement lorsque vous voulez délibérément autoriser n’importe quel modèle.
  • plugins.entries.<id>.config : objet de configuration défini par le plugin (validé par le schéma du plugin OpenClaw natif lorsqu’il est disponible).
  • plugins.entries.firecrawl.config.webFetch : paramètres du provider de récupération web Firecrawl.
    • apiKey : clé API Firecrawl (accepte SecretRef). Utilise comme solution de repli plugins.entries.firecrawl.config.webSearch.apiKey, l’ancien tools.web.fetch.firecrawl.apiKey, ou la variable d’environnement FIRECRAWL_API_KEY.
    • baseUrl : URL de base de l’API Firecrawl (par défaut : https://api.firecrawl.dev).
    • onlyMainContent : extrait uniquement le contenu principal des pages (par défaut : true).
    • maxAgeMs : âge maximal du cache en millisecondes (par défaut : 172800000 / 2 jours).
    • timeoutSeconds : délai d’expiration de la requête de scraping en secondes (par défaut : 60).
  • plugins.entries.xai.config.xSearch : paramètres xAI X Search (recherche web Grok).
    • enabled : active le provider X Search.
    • model : modèle Grok à utiliser pour la recherche (par exemple "grok-4-1-fast").
  • plugins.entries.memory-core.config.dreaming : paramètres de rêverie de la mémoire (expérimental). Consultez Rêverie pour les phases et les seuils.
    • enabled : commutateur maître de rêverie (par défaut false).
    • frequency : cadence cron pour chaque balayage complet de rêverie ("0 3 * * *" par défaut).
    • la politique de phase et les seuils sont des détails d’implémentation (pas des clés de configuration destinées aux utilisateurs).
  • La configuration complète de la mémoire se trouve dans Référence de configuration de la mémoire :
    • agents.defaults.memorySearch.*
    • memory.backend
    • memory.citations
    • memory.qmd.*
    • plugins.entries.memory-core.config.dreaming
  • Les plugins bundle Claude activés peuvent également contribuer des valeurs par défaut Pi intégrées depuis settings.json ; OpenClaw les applique comme paramètres d’agent assainis, et non comme patchs de configuration OpenClaw bruts.
  • plugins.slots.memory : choisissez l’ID du plugin mémoire actif, ou "none" pour désactiver les plugins mémoire.
  • plugins.slots.contextEngine : choisissez l’ID du plugin moteur de contexte actif ; vaut par défaut "legacy" sauf si vous installez et sélectionnez un autre moteur.
  • plugins.installs : métadonnées d’installation gérées par la CLI utilisées par openclaw plugins update.
    • Inclut source, spec, sourcePath, installPath, version, resolvedName, resolvedVersion, resolvedSpec, integrity, shasum, resolvedAt, installedAt.
    • Traitez plugins.installs.* comme un état géré ; préférez les commandes CLI aux modifications manuelles.
Consultez Plugins.

Browser

{
  browser: {
    enabled: true,
    evaluateEnabled: true,
    defaultProfile: "user",
    ssrfPolicy: {
      dangerouslyAllowPrivateNetwork: true, // default trusted-network mode
      // allowPrivateNetwork: true, // legacy alias
      // hostnameAllowlist: ["*.example.com", "example.com"],
      // allowedHostnames: ["localhost"],
    },
    profiles: {
      openclaw: { cdpPort: 18800, color: "#FF4500" },
      work: { cdpPort: 18801, color: "#0066CC" },
      user: { driver: "existing-session", attachOnly: true, color: "#00AA00" },
      brave: {
        driver: "existing-session",
        attachOnly: true,
        userDataDir: "~/Library/Application Support/BraveSoftware/Brave-Browser",
        color: "#FB542B",
      },
      remote: { cdpUrl: "http://10.0.0.42:9222", color: "#00AA00" },
    },
    color: "#FF4500",
    // headless: false,
    // noSandbox: false,
    // extraArgs: [],
    // executablePath: "/Applications/Brave Browser.app/Contents/MacOS/Brave Browser",
    // attachOnly: false,
  },
}
  • evaluateEnabled: false désactive act:evaluate et wait --fn.
  • ssrfPolicy.dangerouslyAllowPrivateNetwork vaut par défaut true lorsqu’il n’est pas défini (modèle réseau de confiance).
  • Définissez ssrfPolicy.dangerouslyAllowPrivateNetwork: false pour une navigation navigateur strictement publique.
  • En mode strict, les points de terminaison distants du profil CDP (profiles.*.cdpUrl) sont soumis au même blocage de réseau privé lors des vérifications d’accessibilité/découverte.
  • ssrfPolicy.allowPrivateNetwork reste pris en charge comme ancien alias.
  • En mode strict, utilisez ssrfPolicy.hostnameAllowlist et ssrfPolicy.allowedHostnames pour des exceptions explicites.
  • Les profils distants sont en mode attachement uniquement (démarrage/arrêt/réinitialisation désactivés).
  • profiles.*.cdpUrl accepte http://, https://, ws:// et wss://. Utilisez HTTP(S) lorsque vous voulez qu’OpenClaw découvre /json/version ; utilisez WS(S) lorsque votre provider vous donne une URL WebSocket DevTools directe.
  • Les profils existing-session sont propres à l’hôte et utilisent Chrome MCP au lieu de CDP.
  • Les profils existing-session peuvent définir userDataDir pour cibler un profil de navigateur basé sur Chromium spécifique comme Brave ou Edge.
  • Les profils existing-session conservent les limites actuelles du routage Chrome MCP : actions basées sur snapshot/référence au lieu d’un ciblage par sélecteur CSS, hooks d’upload d’un seul fichier, pas de remplacements de délai d’expiration de boîte de dialogue, pas de wait --load networkidle, ni responsebody, export PDF, interception de téléchargement ou actions par lot.
  • Les profils locaux gérés openclaw attribuent automatiquement cdpPort et cdpUrl ; ne définissez cdpUrl explicitement que pour un CDP distant.
  • Ordre d’auto-détection : navigateur par défaut s’il est basé sur Chromium → Chrome → Brave → Edge → Chromium → Chrome Canary.
  • Service de contrôle : loopback uniquement (port dérivé de gateway.port, par défaut 18791).
  • extraArgs ajoute des drapeaux de lancement supplémentaires au démarrage local de Chromium (par exemple --disable-gpu, dimensionnement de fenêtre ou drapeaux de débogage).

UI

{
  ui: {
    seamColor: "#FF4500",
    assistant: {
      name: "OpenClaw",
      avatar: "CB", // emoji, short text, image URL, or data URI
    },
  },
}
  • seamColor : couleur d’accentuation pour le chrome UI des applications natives (teinte de bulle du mode Talk, etc.).
  • assistant : remplacement d’identité de l’interface Control UI. Utilise comme solution de repli l’identité de l’agent actif.

Gateway

{
  gateway: {
    mode: "local", // local | remote
    port: 18789,
    bind: "loopback",
    auth: {
      mode: "token", // none | token | password | trusted-proxy
      token: "your-token",
      // password: "your-password", // or OPENCLAW_GATEWAY_PASSWORD
      // trustedProxy: { userHeader: "x-forwarded-user" }, // for mode=trusted-proxy; see /gateway/trusted-proxy-auth
      allowTailscale: true,
      rateLimit: {
        maxAttempts: 10,
        windowMs: 60000,
        lockoutMs: 300000,
        exemptLoopback: true,
      },
    },
    tailscale: {
      mode: "off", // off | serve | funnel
      resetOnExit: false,
    },
    controlUi: {
      enabled: true,
      basePath: "/openclaw",
      // root: "dist/control-ui",
      // allowedOrigins: ["https://control.example.com"], // required for non-loopback Control UI
      // dangerouslyAllowHostHeaderOriginFallback: false, // dangerous Host-header origin fallback mode
      // allowInsecureAuth: false,
      // dangerouslyDisableDeviceAuth: false,
    },
    remote: {
      url: "ws://gateway.tailnet:18789",
      transport: "ssh", // ssh | direct
      token: "your-token",
      // password: "your-password",
    },
    trustedProxies: ["10.0.0.1"],
    // Optional. Default false.
    allowRealIpFallback: false,
    tools: {
      // Additional /tools/invoke HTTP denies
      deny: ["browser"],
      // Remove tools from the default HTTP deny list
      allow: ["gateway"],
    },
    push: {
      apns: {
        relay: {
          baseUrl: "https://relay.example.com",
          timeoutMs: 10000,
        },
      },
    },
  },
}
  • mode : local (exécuter la passerelle) ou remote (se connecter à une passerelle distante). La passerelle refuse de démarrer sauf si local.
  • port : port multiplexé unique pour WS + HTTP. Priorité : --port > OPENCLAW_GATEWAY_PORT > gateway.port > 18789.
  • bind : auto, loopback (par défaut), lan (0.0.0.0), tailnet (IP Tailscale uniquement) ou custom.
  • Anciens alias de bind : utilisez les valeurs de mode bind dans gateway.bind (auto, loopback, lan, tailnet, custom), pas les alias d’hôte (0.0.0.0, 127.0.0.1, localhost, ::, ::1).
  • Remarque Docker : la valeur par défaut loopback écoute sur 127.0.0.1 dans le conteneur. Avec le réseau bridge Docker (-p 18789:18789), le trafic arrive sur eth0, donc la passerelle est inaccessible. Utilisez --network host, ou définissez bind: "lan" (ou bind: "custom" avec customBindHost: "0.0.0.0") pour écouter sur toutes les interfaces.
  • Auth : requise par défaut. Les liaisons non loopback exigent l’authentification de la passerelle. En pratique, cela signifie un jeton/mot de passe partagé ou un proxy inverse sensible à l’identité avec gateway.auth.mode: "trusted-proxy". L’assistant d’intégration génère un jeton par défaut.
  • Si gateway.auth.token et gateway.auth.password sont tous deux configurés (y compris via SecretRef), définissez explicitement gateway.auth.mode sur token ou password. Les flux de démarrage et d’installation/réparation du service échouent lorsque les deux sont configurés et que le mode n’est pas défini.
  • gateway.auth.mode: "none" : mode explicite sans authentification. À utiliser uniquement pour des configurations loopback local loopback de confiance ; cette option n’est volontairement pas proposée par les invites d’intégration.
  • gateway.auth.mode: "trusted-proxy" : délègue l’authentification à un proxy inverse sensible à l’identité et fait confiance aux en-têtes d’identité provenant de gateway.trustedProxies (voir Auth Trusted Proxy). Ce mode attend une source de proxy non loopback ; les proxies inverses loopback sur le même hôte ne satisfont pas l’authentification trusted-proxy.
  • gateway.auth.allowTailscale : lorsque true, les en-têtes d’identité Tailscale Serve peuvent satisfaire l’authentification de Control UI/WebSocket (vérifiée via tailscale whois). Les points de terminaison API HTTP n’utilisent pas cette authentification par en-tête Tailscale ; ils suivent à la place le mode d’authentification HTTP normal de la passerelle. Ce flux sans jeton suppose que l’hôte de la passerelle est de confiance. Vaut par défaut true lorsque tailscale.mode = "serve".
  • gateway.auth.rateLimit : limite facultative des échecs d’authentification. S’applique par IP client et par portée d’authentification (secret partagé et jeton d’appareil sont suivis indépendamment). Les tentatives bloquées renvoient 429 + Retry-After.
    • Sur le chemin asynchrone Tailscale Serve de Control UI, les tentatives échouées pour le même {scope, clientIp} sont sérialisées avant l’écriture de l’échec. Des tentatives concurrentes invalides du même client peuvent donc déclencher la limite dès la deuxième requête au lieu que les deux passent en course comme de simples échecs de correspondance.
    • gateway.auth.rateLimit.exemptLoopback vaut par défaut true ; définissez false lorsque vous voulez délibérément limiter aussi le trafic localhost (pour des configurations de test ou des déploiements proxy stricts).
  • Les tentatives d’authentification WS d’origine navigateur sont toujours limitées avec exemption loopback désactivée (défense en profondeur contre les attaques par force brute localhost depuis le navigateur).
  • En loopback, ces verrouillages d’origine navigateur sont isolés par valeur Origin normalisée, afin que des échecs répétés depuis une origine localhost n’entraînent pas automatiquement le verrouillage d’une origine différente.
  • tailscale.mode : serve (tailnet uniquement, liaison loopback) ou funnel (public, nécessite une authentification).
  • controlUi.allowedOrigins : liste d’autorisations explicite des origines navigateur pour les connexions WebSocket Gateway. Requise lorsque des clients navigateur sont attendus depuis des origines non loopback.
  • controlUi.dangerouslyAllowHostHeaderOriginFallback : mode dangereux qui active le repli d’origine via en-tête Host pour les déploiements qui s’appuient volontairement sur cette politique d’origine.
  • remote.transport : ssh (par défaut) ou direct (ws/wss). Pour direct, remote.url doit être ws:// ou wss://.
  • OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 : remplacement de dernier recours côté client qui autorise ws:// en clair vers des IP de réseau privé de confiance ; par défaut, le texte en clair reste limité au loopback.
  • gateway.remote.token / .password sont des champs d’identifiants du client distant. Ils ne configurent pas à eux seuls l’authentification de la passerelle.
  • gateway.push.apns.relay.baseUrl : URL HTTPS de base du relais APNs externe utilisé par les builds iOS officiels/TestFlight après publication des enregistrements reposant sur le relais vers la passerelle. Cette URL doit correspondre à l’URL du relais compilée dans le build iOS.
  • gateway.push.apns.relay.timeoutMs : délai d’expiration en millisecondes pour les envois passerelle-vers-relais. Par défaut : 10000.
  • Les enregistrements basés sur le relais sont délégués à une identité de passerelle spécifique. L’app iOS appairée récupère gateway.identity.get, inclut cette identité dans l’enregistrement du relais, et transmet à la passerelle une autorisation d’envoi limitée à cet enregistrement. Une autre passerelle ne peut pas réutiliser cet enregistrement stocké.
  • OPENCLAW_APNS_RELAY_BASE_URL / OPENCLAW_APNS_RELAY_TIMEOUT_MS : remplacements temporaires via l’environnement pour la configuration du relais ci-dessus.
  • OPENCLAW_APNS_RELAY_ALLOW_HTTP=true : échappatoire réservée au développement pour les URL de relais HTTP loopback. Les URL de relais de production doivent rester en HTTPS.
  • gateway.channelHealthCheckMinutes : intervalle du moniteur de santé des canaux, en minutes. Définissez 0 pour désactiver globalement les redémarrages du moniteur de santé. Par défaut : 5.
  • gateway.channelStaleEventThresholdMinutes : seuil de socket obsolète en minutes. Conservez cette valeur supérieure ou égale à gateway.channelHealthCheckMinutes. Par défaut : 30.
  • gateway.channelMaxRestartsPerHour : nombre maximal de redémarrages du moniteur de santé par canal/compte sur une heure glissante. Par défaut : 10.
  • channels.<provider>.healthMonitor.enabled : désactivation facultative par canal des redémarrages du moniteur de santé tout en gardant le moniteur global activé.
  • channels.<provider>.accounts.<accountId>.healthMonitor.enabled : remplacement par compte pour les canaux multi-comptes. Lorsqu’il est défini, il a priorité sur le remplacement au niveau du canal.
  • Les chemins d’appel de passerelle locale peuvent utiliser gateway.remote.* comme solution de repli uniquement lorsque gateway.auth.* n’est pas défini.
  • Si gateway.auth.token / gateway.auth.password est explicitement configuré via SecretRef et non résolu, la résolution échoue de manière sécurisée (aucune solution de repli distante ne masque cela).
  • trustedProxies : IP de proxy inverse qui terminent TLS ou injectent des en-têtes de client transféré. Listez uniquement des proxies que vous contrôlez. Les entrées loopback restent valides pour les configurations de détection locale/proxy sur le même hôte (par exemple Tailscale Serve ou un proxy inverse local), mais elles ne rendent pas les requêtes loopback admissibles à gateway.auth.mode: "trusted-proxy".
  • allowRealIpFallback : lorsque true, la passerelle accepte X-Real-IP si X-Forwarded-For est absent. Par défaut false pour un comportement d’échec sécurisé.
  • gateway.tools.deny : noms d’outils supplémentaires bloqués pour HTTP POST /tools/invoke (étend la liste d’interdiction par défaut).
  • gateway.tools.allow : supprime des noms d’outils de la liste d’interdiction HTTP par défaut.

Points de terminaison compatibles OpenAI

  • Chat Completions : désactivé par défaut. Activez-le avec gateway.http.endpoints.chatCompletions.enabled: true.
  • API Responses : gateway.http.endpoints.responses.enabled.
  • Renforcement des entrées URL pour Responses :
    • gateway.http.endpoints.responses.maxUrlParts
    • gateway.http.endpoints.responses.files.urlAllowlist
    • gateway.http.endpoints.responses.images.urlAllowlist Les listes d’autorisations vides sont traitées comme non définies ; utilisez gateway.http.endpoints.responses.files.allowUrl=false et/ou gateway.http.endpoints.responses.images.allowUrl=false pour désactiver la récupération d’URL.
  • En-tête facultatif de renforcement des réponses :
    • gateway.http.securityHeaders.strictTransportSecurity (à définir uniquement pour des origines HTTPS que vous contrôlez ; voir Auth Trusted Proxy)

Isolation multi-instance

Exécutez plusieurs passerelles sur un même hôte avec des ports et répertoires d’état uniques :
OPENCLAW_CONFIG_PATH=~/.openclaw/a.json \
OPENCLAW_STATE_DIR=~/.openclaw-a \
openclaw gateway --port 19001
Indicateurs pratiques : --dev (utilise ~/.openclaw-dev + port 19001), --profile <name> (utilise ~/.openclaw-<name>). Consultez Passerelles multiples.

gateway.tls

{
  gateway: {
    tls: {
      enabled: false,
      autoGenerate: false,
      certPath: "/etc/openclaw/tls/server.crt",
      keyPath: "/etc/openclaw/tls/server.key",
      caPath: "/etc/openclaw/tls/ca-bundle.crt",
    },
  },
}
  • enabled : active la terminaison TLS au niveau de l’écouteur de la passerelle (HTTPS/WSS) (par défaut : false).
  • autoGenerate : génère automatiquement une paire locale certificat/clé auto-signée lorsque des fichiers explicites ne sont pas configurés ; usage local/dev uniquement.
  • certPath : chemin du système de fichiers vers le fichier certificat TLS.
  • keyPath : chemin du système de fichiers vers le fichier clé privée TLS ; conservez des permissions restreintes.
  • caPath : chemin facultatif du bundle CA pour la vérification client ou des chaînes de confiance personnalisées.

gateway.reload

{
  gateway: {
    reload: {
      mode: "hybrid", // off | restart | hot | hybrid
      debounceMs: 500,
      deferralTimeoutMs: 300000,
    },
  },
}
  • mode : contrôle la manière dont les modifications de configuration sont appliquées à l’exécution.
    • "off" : ignore les modifications en direct ; les changements nécessitent un redémarrage explicite.
    • "restart" : redémarre toujours le processus de passerelle lors d’un changement de configuration.
    • "hot" : applique les changements dans le processus sans redémarrage.
    • "hybrid" (par défaut) : essaie d’abord le rechargement à chaud ; revient à un redémarrage si nécessaire.
  • debounceMs : fenêtre d’anti-rebond en ms avant l’application des changements de configuration (entier non négatif).
  • deferralTimeoutMs : temps maximal en ms pour attendre la fin des opérations en cours avant de forcer un redémarrage (par défaut : 300000 = 5 minutes).

Hooks

{
  hooks: {
    enabled: true,
    token: "shared-secret",
    path: "/hooks",
    maxBodyBytes: 262144,
    defaultSessionKey: "hook:ingress",
    allowRequestSessionKey: false,
    allowedSessionKeyPrefixes: ["hook:"],
    allowedAgentIds: ["hooks", "main"],
    presets: ["gmail"],
    transformsDir: "~/.openclaw/hooks/transforms",
    mappings: [
      {
        match: { path: "gmail" },
        action: "agent",
        agentId: "hooks",
        wakeMode: "now",
        name: "Gmail",
        sessionKey: "hook:gmail:{{messages[0].id}}",
        messageTemplate: "From: {{messages[0].from}}\nSubject: {{messages[0].subject}}\n{{messages[0].snippet}}",
        deliver: true,
        channel: "last",
        model: "openai/gpt-5.4-mini",
      },
    ],
  },
}
Auth : Authorization: Bearer <token> ou x-openclaw-token: <token>. Les jetons de hook dans la chaîne de requête sont rejetés. Remarques de validation et de sécurité :
  • hooks.enabled=true nécessite un hooks.token non vide.
  • hooks.token doit être distinct de gateway.auth.token ; réutiliser le jeton Gateway est rejeté.
  • hooks.path ne peut pas être / ; utilisez un sous-chemin dédié tel que /hooks.
  • Si hooks.allowRequestSessionKey=true, contraignez hooks.allowedSessionKeyPrefixes (par exemple ["hook:"]).
Points de terminaison :
  • POST /hooks/wake{ text, mode?: "now"|"next-heartbeat" }
  • POST /hooks/agent{ message, name?, agentId?, sessionKey?, wakeMode?, deliver?, channel?, to?, model?, thinking?, timeoutSeconds? }
    • sessionKey depuis la charge utile de la requête n’est accepté que lorsque hooks.allowRequestSessionKey=true (par défaut : false).
  • POST /hooks/<name> → résolu via hooks.mappings
  • match.path correspond au sous-chemin après /hooks (par ex. /hooks/gmailgmail).
  • match.source correspond à un champ de la charge utile pour les chemins génériques.
  • Les modèles comme {{messages[0].subject}} lisent depuis la charge utile.
  • transform peut pointer vers un module JS/TS renvoyant une action de hook.
    • transform.module doit être un chemin relatif et rester dans hooks.transformsDir (les chemins absolus et la traversée sont rejetés).
  • agentId route vers un agent spécifique ; les ID inconnus se replient sur l’agent par défaut.
  • allowedAgentIds : restreint le routage explicite (* ou omis = tout autoriser, [] = tout refuser).
  • defaultSessionKey : clé de session fixe facultative pour les exécutions d’agent hook sans sessionKey explicite.
  • allowRequestSessionKey : autorise les appelants /hooks/agent à définir sessionKey (par défaut : false).
  • allowedSessionKeyPrefixes : liste d’autorisations facultative de préfixes pour les valeurs explicites de sessionKey (requête + mapping), par ex. ["hook:"].
  • deliver: true envoie la réponse finale à un canal ; channel vaut par défaut last.
  • model remplace le LLM pour cette exécution de hook (doit être autorisé si un catalogue de modèles est défini).

Intégration Gmail

{
  hooks: {
    gmail: {
      account: "openclaw@gmail.com",
      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" },
      model: "openrouter/meta-llama/llama-3.3-70b-instruct:free",
      thinking: "off",
    },
  },
}
  • La Gateway démarre automatiquement gog gmail watch serve au démarrage lorsqu’il est configuré. Définissez OPENCLAW_SKIP_GMAIL_WATCHER=1 pour le désactiver.
  • N’exécutez pas un gog gmail watch serve séparé en parallèle de la Gateway.

Hôte Canvas

{
  canvasHost: {
    root: "~/.openclaw/workspace/canvas",
    liveReload: true,
    // enabled: false, // or OPENCLAW_SKIP_CANVAS_HOST=1
  },
}
  • Sert le HTML/CSS/JS modifiable par l’agent et A2UI sur HTTP sous le port Gateway :
    • http://<gateway-host>:<gateway.port>/__openclaw__/canvas/
    • http://<gateway-host>:<gateway.port>/__openclaw__/a2ui/
  • Local uniquement : conservez gateway.bind: "loopback" (par défaut).
  • Liaisons non loopback : les routes canvas nécessitent l’authentification Gateway (token/password/trusted-proxy), comme les autres surfaces HTTP Gateway.
  • Les WebViews Node n’envoient généralement pas d’en-têtes d’authentification ; après qu’un nœud est appairé et connecté, la Gateway annonce des URL de capacité limitées au nœud pour l’accès canvas/A2UI.
  • Les URL de capacité sont liées à la session WS active du nœud et expirent rapidement. Aucun repli basé sur IP n’est utilisé.
  • Injecte un client de rechargement à chaud dans le HTML servi.
  • Crée automatiquement un index.html de démarrage lorsqu’il est vide.
  • Sert également A2UI à /__openclaw__/a2ui/.
  • Les changements nécessitent un redémarrage de la passerelle.
  • Désactivez le rechargement à chaud pour les grands répertoires ou les erreurs EMFILE.

Découverte

mDNS (Bonjour)

{
  discovery: {
    mdns: {
      mode: "minimal", // minimal | full | off
    },
  },
}
  • minimal (par défaut) : omet cliPath + sshPort des enregistrements TXT.
  • full : inclut cliPath + sshPort.
  • Le nom d’hôte vaut par défaut openclaw. Remplacez-le avec OPENCLAW_MDNS_HOSTNAME.

Wide-area (DNS-SD)

{
  discovery: {
    wideArea: { enabled: true },
  },
}
Écrit une zone DNS-SD unicast sous ~/.openclaw/dns/. Pour la découverte inter-réseaux, associez-la à un serveur DNS (CoreDNS recommandé) + le split DNS Tailscale. Installation : openclaw dns setup --apply.

Environnement

env (variables d’environnement en ligne)

{
  env: {
    OPENROUTER_API_KEY: "sk-or-...",
    vars: {
      GROQ_API_KEY: "gsk-...",
    },
    shellEnv: {
      enabled: true,
      timeoutMs: 15000,
    },
  },
}
  • Les variables d’environnement en ligne ne sont appliquées que si l’environnement du processus ne contient pas déjà la clé.
  • Fichiers .env : .env du répertoire courant + ~/.openclaw/.env (aucun des deux ne remplace les variables existantes).
  • shellEnv : importe les clés attendues manquantes depuis le profil de votre shell de connexion.
  • Consultez Environnement pour l’ordre de priorité complet.

Substitution de variables d’environnement

Référencez des variables d’environnement dans n’importe quelle chaîne de configuration avec ${VAR_NAME} :
{
  gateway: {
    auth: { token: "${OPENCLAW_GATEWAY_TOKEN}" },
  },
}
  • Seuls les noms en majuscules sont pris en charge : [A-Z_][A-Z0-9_]*.
  • Les variables manquantes/vides déclenchent une erreur au chargement de la configuration.
  • Échappez avec $${VAR} pour obtenir un littéral ${VAR}.
  • Fonctionne avec $include.

Secrets

Les références de secret sont additives : les valeurs en texte brut continuent de fonctionner.

SecretRef

Utilisez une seule forme d’objet :
{ source: "env" | "file" | "exec", provider: "default", id: "..." }
Validation :
  • motif provider : ^[a-z][a-z0-9_-]{0,63}$
  • motif source: "env" pour id : ^[A-Z][A-Z0-9_]{0,127}$
  • source: "file" id : pointeur JSON absolu (par exemple "/providers/openai/apiKey")
  • motif source: "exec" pour id : ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}$
  • les id source: "exec" ne doivent pas contenir de segments de chemin . ou .. séparés par / (par exemple a/../b est rejeté)

Surface d’identifiants prise en charge

  • Matrice canonique : Surface d’identifiants SecretRef
  • secrets apply cible les chemins d’identifiants pris en charge dans openclaw.json.
  • Les références auth-profiles.json sont incluses dans la résolution à l’exécution et dans la couverture d’audit.

Configuration des providers de secrets

{
  secrets: {
    providers: {
      default: { source: "env" }, // optional explicit env provider
      filemain: {
        source: "file",
        path: "~/.openclaw/secrets.json",
        mode: "json",
        timeoutMs: 5000,
      },
      vault: {
        source: "exec",
        command: "/usr/local/bin/openclaw-vault-resolver",
        passEnv: ["PATH", "VAULT_ADDR"],
      },
    },
    defaults: {
      env: "default",
      file: "filemain",
      exec: "vault",
    },
  },
}
Remarques :
  • Le provider file prend en charge mode: "json" et mode: "singleValue" (id doit être "value" en mode singleValue).
  • Le provider exec exige un chemin command absolu et utilise des charges utiles de protocole sur stdin/stdout.
  • Par défaut, les chemins de commande symlink sont rejetés. Définissez allowSymlinkCommand: true pour autoriser les chemins symlink tout en validant le chemin cible résolu.
  • Si trustedDirs est configuré, la vérification de répertoire de confiance s’applique au chemin cible résolu.
  • L’environnement enfant de exec est minimal par défaut ; transmettez explicitement les variables nécessaires avec passEnv.
  • Les références de secret sont résolues au moment de l’activation dans un instantané en mémoire, puis les chemins de requête lisent uniquement cet instantané.
  • Le filtrage de surface active s’applique pendant l’activation : les références non résolues sur des surfaces activées font échouer le démarrage/rechargement, tandis que les surfaces inactives sont ignorées avec des diagnostics.

Stockage de l’authentification

{
  auth: {
    profiles: {
      "anthropic:default": { provider: "anthropic", mode: "api_key" },
      "anthropic:work": { provider: "anthropic", mode: "api_key" },
      "openai-codex:personal": { provider: "openai-codex", mode: "oauth" },
    },
    order: {
      anthropic: ["anthropic:default", "anthropic:work"],
      "openai-codex": ["openai-codex:personal"],
    },
  },
}
  • Les profils par agent sont stockés dans <agentDir>/auth-profiles.json.
  • auth-profiles.json prend en charge les références au niveau valeur (keyRef pour api_key, tokenRef pour token) pour les modes d’identifiants statiques.
  • Les profils en mode OAuth (auth.profiles.<id>.mode = "oauth") ne prennent pas en charge les identifiants de profil d’authentification basés sur SecretRef.
  • Les identifiants statiques d’exécution proviennent d’instantanés résolus en mémoire ; les anciennes entrées statiques auth.json sont nettoyées lorsqu’elles sont détectées.
  • Les anciennes importations OAuth proviennent de ~/.openclaw/credentials/oauth.json.
  • Consultez OAuth.
  • Comportement de l’exécution des secrets et outils audit/configure/apply : Gestion des secrets.

auth.cooldowns

{
  auth: {
    cooldowns: {
      billingBackoffHours: 5,
      billingBackoffHoursByProvider: { anthropic: 3, openai: 8 },
      billingMaxHours: 24,
      authPermanentBackoffMinutes: 10,
      authPermanentMaxMinutes: 60,
      failureWindowHours: 24,
      overloadedProfileRotations: 1,
      overloadedBackoffMs: 0,
      rateLimitedProfileRotations: 1,
    },
  },
}
  • billingBackoffHours : temporisation de base en heures lorsqu’un profil échoue en raison de véritables erreurs de facturation/crédit insuffisant (par défaut : 5). Un texte explicite lié à la facturation peut toujours arriver ici même sur des réponses 401/403, mais les moteurs de correspondance de texte spécifiques au provider restent limités au provider qui les possède (par exemple OpenRouter Key limit exceeded). Les messages HTTP 402 de fenêtre d’utilisation ou de limite de dépense organisation/espace de travail pouvant être réessayés restent dans le chemin rate_limit.
  • billingBackoffHoursByProvider : remplacements facultatifs par provider pour les heures de temporisation liées à la facturation.
  • billingMaxHours : plafond en heures pour la croissance exponentielle de la temporisation liée à la facturation (par défaut : 24).
  • authPermanentBackoffMinutes : temporisation de base en minutes pour les échecs auth_permanent à forte confiance (par défaut : 10).
  • authPermanentMaxMinutes : plafond en minutes pour la croissance de la temporisation auth_permanent (par défaut : 60).
  • failureWindowHours : fenêtre glissante en heures utilisée pour les compteurs de temporisation (par défaut : 24).
  • overloadedProfileRotations : nombre maximal de rotations de profil d’authentification chez le même provider pour les erreurs de surcharge avant de passer au modèle de repli (par défaut : 1). Les formes de provider occupé telles que ModelNotReadyException arrivent ici.
  • overloadedBackoffMs : délai fixe avant de réessayer une rotation de provider/profil surchargé (par défaut : 0).
  • rateLimitedProfileRotations : nombre maximal de rotations de profil d’authentification chez le même provider pour les erreurs de limitation de débit avant de passer au modèle de repli (par défaut : 1). Cette catégorie de limitation de débit inclut des textes de provider tels que Too many concurrent requests, ThrottlingException, concurrency limit reached, workers_ai ... quota limit exceeded et resource exhausted.

Journalisation

{
  logging: {
    level: "info",
    file: "/tmp/openclaw/openclaw.log",
    consoleLevel: "info",
    consoleStyle: "pretty", // pretty | compact | json
    redactSensitive: "tools", // off | tools
    redactPatterns: ["\\bTOKEN\\b\\s*[=:]\\s*([\"']?)([^\\s\"']+)\\1"],
  },
}
  • Fichier journal par défaut : /tmp/openclaw/openclaw-YYYY-MM-DD.log.
  • Définissez logging.file pour un chemin stable.
  • consoleLevel passe à debug avec --verbose.
  • maxFileBytes : taille maximale du fichier journal en octets avant suppression des écritures (entier positif ; par défaut : 524288000 = 500 Mo). Utilisez une rotation externe des journaux pour les déploiements de production.

Diagnostics

{
  diagnostics: {
    enabled: true,
    flags: ["telegram.*"],
    stuckSessionWarnMs: 30000,

    otel: {
      enabled: false,
      endpoint: "https://otel-collector.example.com:4318",
      protocol: "http/protobuf", // http/protobuf | grpc
      headers: { "x-tenant-id": "my-org" },
      serviceName: "openclaw-gateway",
      traces: true,
      metrics: true,
      logs: false,
      sampleRate: 1.0,
      flushIntervalMs: 5000,
    },

    cacheTrace: {
      enabled: false,
      filePath: "~/.openclaw/logs/cache-trace.jsonl",
      includeMessages: true,
      includePrompt: true,
      includeSystem: true,
    },
  },
}
  • enabled : commutateur maître de la sortie d’instrumentation (par défaut : true).
  • flags : tableau de chaînes de drapeaux activant une sortie de journal ciblée (prend en charge des jokers comme "telegram.*" ou "*").
  • stuckSessionWarnMs : seuil d’ancienneté en ms pour émettre des avertissements de session bloquée tant qu’une session reste à l’état de traitement.
  • otel.enabled : active le pipeline d’export OpenTelemetry (par défaut : false).
  • otel.endpoint : URL du collecteur pour l’export OTel.
  • otel.protocol : "http/protobuf" (par défaut) ou "grpc".
  • otel.headers : en-têtes de métadonnées HTTP/gRPC supplémentaires envoyés avec les requêtes d’export OTel.
  • otel.serviceName : nom du service pour les attributs de ressource.
  • otel.traces / otel.metrics / otel.logs : active l’export des traces, des métriques ou des journaux.
  • otel.sampleRate : taux d’échantillonnage des traces 01.
  • otel.flushIntervalMs : intervalle périodique de vidage de télémétrie en ms.
  • cacheTrace.enabled : journalise les instantanés de trace du cache pour les exécutions intégrées (par défaut : false).
  • cacheTrace.filePath : chemin de sortie pour le JSONL de trace du cache (par défaut : $OPENCLAW_STATE_DIR/logs/cache-trace.jsonl).
  • cacheTrace.includeMessages / includePrompt / includeSystem : contrôle ce qui est inclus dans la sortie de trace du cache (tous à true par défaut).

Mise à jour

{
  update: {
    channel: "stable", // stable | beta | dev
    checkOnStart: true,

    auto: {
      enabled: false,
      stableDelayHours: 6,
      stableJitterHours: 12,
      betaCheckIntervalHours: 1,
    },
  },
}
  • channel : canal de publication pour les installations npm/git — "stable", "beta" ou "dev".
  • checkOnStart : vérifie les mises à jour npm au démarrage de la passerelle (par défaut : true).
  • auto.enabled : active la mise à jour automatique en arrière-plan pour les installations de paquets (par défaut : false).
  • auto.stableDelayHours : délai minimal en heures avant application automatique sur le canal stable (par défaut : 6 ; max : 168).
  • auto.stableJitterHours : fenêtre supplémentaire d’étalement du déploiement du canal stable en heures (par défaut : 12 ; max : 168).
  • auto.betaCheckIntervalHours : fréquence d’exécution des vérifications du canal bêta en heures (par défaut : 1 ; max : 24).

ACP

{
  acp: {
    enabled: false,
    dispatch: { enabled: true },
    backend: "acpx",
    defaultAgent: "main",
    allowedAgents: ["main", "ops"],
    maxConcurrentSessions: 10,

    stream: {
      coalesceIdleMs: 50,
      maxChunkChars: 1000,
      repeatSuppression: true,
      deliveryMode: "live", // live | final_only
      hiddenBoundarySeparator: "paragraph", // none | space | newline | paragraph
      maxOutputChars: 50000,
      maxSessionUpdateChars: 500,
    },

    runtime: {
      ttlMinutes: 30,
    },
  },
}
  • enabled : garde-fou global de fonctionnalité ACP (par défaut : false).
  • dispatch.enabled : garde-fou indépendant pour la distribution des tours de session ACP (par défaut : true). Définissez false pour garder les commandes ACP disponibles tout en bloquant l’exécution.
  • backend : ID du backend d’exécution ACP par défaut (doit correspondre à un plugin d’exécution ACP enregistré).
  • defaultAgent : ID d’agent ACP de repli lorsque les lancements ne spécifient pas de cible explicite.
  • allowedAgents : liste d’autorisations des ID d’agent autorisés pour les sessions d’exécution ACP ; vide signifie aucune restriction supplémentaire.
  • maxConcurrentSessions : nombre maximal de sessions ACP actives simultanément.
  • stream.coalesceIdleMs : fenêtre de vidage en veille en ms pour le texte diffusé.
  • stream.maxChunkChars : taille maximale d’un bloc avant division de la projection du bloc diffusé.
  • stream.repeatSuppression : supprime les lignes répétées d’état/d’outil par tour (par défaut : true).
  • stream.deliveryMode : "live" diffuse progressivement ; "final_only" met en tampon jusqu’aux événements terminaux du tour.
  • stream.hiddenBoundarySeparator : séparateur avant le texte visible après des événements d’outil masqués (par défaut : "paragraph").
  • stream.maxOutputChars : nombre maximal de caractères de sortie assistant projetés par tour ACP.
  • stream.maxSessionUpdateChars : nombre maximal de caractères pour les lignes d’état/mise à jour ACP projetées.
  • stream.tagVisibility : enregistrement des noms de balises avec remplacements booléens de visibilité pour les événements diffusés.
  • runtime.ttlMinutes : TTL d’inactivité en minutes pour les workers de session ACP avant éligibilité au nettoyage.
  • runtime.installCommand : commande d’installation facultative à exécuter lors de l’amorçage d’un environnement d’exécution ACP.

CLI

{
  cli: {
    banner: {
      taglineMode: "off", // random | default | off
    },
  },
}
  • cli.banner.taglineMode contrôle le style de slogan de la bannière :
    • "random" (par défaut) : slogans rotatifs humoristiques/de saison.
    • "default" : slogan neutre fixe (All your chats, one OpenClaw.).
    • "off" : aucun texte de slogan (le titre/version de la bannière est toujours affiché).
  • Pour masquer toute la bannière (pas seulement les slogans), définissez la variable d’environnement OPENCLAW_HIDE_BANNER=1.

Assistant

Métadonnées écrites par les flux guidés d’installation de la CLI (onboard, configure, doctor) :
{
  wizard: {
    lastRunAt: "2026-01-01T00:00:00.000Z",
    lastRunVersion: "2026.1.4",
    lastRunCommit: "abc1234",
    lastRunCommand: "configure",
    lastRunMode: "local",
  },
}

Identité

Consultez les champs d’identité de agents.list sous Valeurs par défaut des agents.

Bridge (hérité, supprimé)

Les builds actuels n’incluent plus le bridge TCP. Les nœuds se connectent via le WebSocket Gateway. Les clés bridge.* ne font plus partie du schéma de configuration (la validation échoue tant qu’elles ne sont pas supprimées ; openclaw doctor --fix peut retirer les clés inconnues).
{
  "bridge": {
    "enabled": true,
    "port": 18790,
    "bind": "tailnet",
    "tls": {
      "enabled": true,
      "autoGenerate": true
    }
  }
}

Cron

{
  cron: {
    enabled: true,
    maxConcurrentRuns: 2,
    webhook: "https://example.invalid/legacy", // solution de repli obsolète pour les tâches stockées notify:true
    webhookToken: "replace-with-dedicated-token", // jeton bearer facultatif pour l’authentification webhook sortante
    sessionRetention: "24h", // chaîne de durée ou false
    runLog: {
      maxBytes: "2mb", // 2_000_000 octets par défaut
      keepLines: 2000, // 2000 par défaut
    },
  },
}
  • sessionRetention : durée de conservation des sessions d’exécution cron isolées terminées avant élagage depuis sessions.json. Contrôle également le nettoyage des transcriptions cron supprimées archivées. Par défaut : 24h ; définissez false pour désactiver.
  • runLog.maxBytes : taille maximale par fichier journal d’exécution (cron/runs/<jobId>.jsonl) avant élagage. Par défaut : 2_000_000 octets.
  • runLog.keepLines : lignes les plus récentes conservées lorsque l’élagage du journal d’exécution est déclenché. Par défaut : 2000.
  • webhookToken : jeton bearer utilisé pour la livraison POST webhook cron (delivery.mode = "webhook"), si omis aucun en-tête d’authentification n’est envoyé.
  • webhook : URL webhook héritée obsolète de repli (http/https), utilisée uniquement pour les tâches stockées qui ont encore notify: true.

cron.retry

{
  cron: {
    retry: {
      maxAttempts: 3,
      backoffMs: [30000, 60000, 300000],
      retryOn: ["rate_limit", "overloaded", "network", "timeout", "server_error"],
    },
  },
}
  • maxAttempts : nombre maximal de nouvelles tentatives pour les tâches ponctuelles sur erreurs transitoires (par défaut : 3 ; plage : 010).
  • backoffMs : tableau de délais de temporisation en ms pour chaque tentative de reprise (par défaut : [30000, 60000, 300000] ; 1 à 10 entrées).
  • retryOn : types d’erreurs qui déclenchent des nouvelles tentatives — "rate_limit", "overloaded", "network", "timeout", "server_error". Omettez-le pour réessayer tous les types transitoires.
S’applique uniquement aux tâches cron ponctuelles. Les tâches récurrentes utilisent une gestion des échecs distincte.

cron.failureAlert

{
  cron: {
    failureAlert: {
      enabled: false,
      after: 3,
      cooldownMs: 3600000,
      mode: "announce",
      accountId: "main",
    },
  },
}
  • enabled : active les alertes d’échec pour les tâches cron (par défaut : false).
  • after : nombre d’échecs consécutifs avant déclenchement d’une alerte (entier positif, min : 1).
  • cooldownMs : nombre minimal de millisecondes entre des alertes répétées pour une même tâche (entier non négatif).
  • mode : mode de livraison — "announce" envoie via un message de canal ; "webhook" publie vers le webhook configuré.
  • accountId : ID facultatif de compte ou de canal pour limiter la livraison des alertes.

cron.failureDestination

{
  cron: {
    failureDestination: {
      mode: "announce",
      channel: "last",
      to: "channel:C1234567890",
      accountId: "main",
    },
  },
}
  • Destination par défaut des notifications d’échec cron pour l’ensemble des tâches.
  • mode : "announce" ou "webhook" ; vaut par défaut "announce" lorsqu’il y a suffisamment de données cibles.
  • channel : remplacement de canal pour la livraison announce. "last" réutilise le dernier canal de livraison connu.
  • to : cible announce explicite ou URL webhook. Requis pour le mode webhook.
  • accountId : remplacement facultatif de compte pour la livraison.
  • delivery.failureDestination par tâche remplace cette valeur globale par défaut.
  • Lorsqu’aucune destination d’échec globale ou par tâche n’est définie, les tâches qui livrent déjà via announce reviennent à cette cible announce principale en cas d’échec.
  • delivery.failureDestination n’est pris en charge que pour les tâches sessionTarget="isolated" sauf si le delivery.mode principal de la tâche vaut "webhook".
Consultez Tâches Cron. Les exécutions cron isolées sont suivies comme tâches d’arrière-plan.

Variables de modèle média

Espaces réservés de modèle développés dans tools.media.models[].args :
VariableDescription
{{Body}}Corps complet du message entrant
{{RawBody}}Corps brut (sans historique/enveloppes d’expéditeur)
{{BodyStripped}}Corps avec les mentions de groupe retirées
{{From}}Identifiant de l’expéditeur
{{To}}Identifiant de destination
{{MessageSid}}ID du message du canal
{{SessionId}}UUID de la session actuelle
{{IsNewSession}}"true" lorsqu’une nouvelle session est créée
{{MediaUrl}}pseudo-URL du média entrant
{{MediaPath}}chemin local du média
{{MediaType}}type de média (image/audio/document/…)
{{Transcript}}transcription audio
{{Prompt}}prompt média résolu pour les entrées CLI
{{MaxChars}}nombre maximal de caractères de sortie résolu pour les entrées CLI
{{ChatType}}"direct" ou "group"
{{GroupSubject}}sujet du groupe (au mieux)
{{GroupMembers}}aperçu des membres du groupe (au mieux)
{{SenderName}}nom d’affichage de l’expéditeur (au mieux)
{{SenderE164}}numéro de téléphone de l’expéditeur (au mieux)
{{Provider}}indice de provider (whatsapp, telegram, discord, etc.)

Inclusions de configuration ($include)

Divisez la configuration en plusieurs fichiers :
// ~/.openclaw/openclaw.json
{
  gateway: { port: 18789 },
  agents: { $include: "./agents.json5" },
  broadcast: {
    $include: ["./clients/mueller.json5", "./clients/schmidt.json5"],
  },
}
Comportement de fusion :
  • Fichier unique : remplace l’objet contenant.
  • Tableau de fichiers : fusion profonde dans l’ordre (les derniers remplacent les précédents).
  • Clés sœurs : fusionnées après les inclusions (remplacent les valeurs incluses).
  • Inclusions imbriquées : jusqu’à 10 niveaux de profondeur.
  • Chemins : résolus relativement au fichier incluant, mais doivent rester dans le répertoire de configuration de niveau supérieur (dirname de openclaw.json). Les formes absolues/../ sont autorisées uniquement si elles se résolvent toujours à l’intérieur de cette limite.
  • Erreurs : messages clairs pour les fichiers manquants, erreurs d’analyse et inclusions circulaires.

Related: Configuration · Configuration Examples · Doctor